1
0
mirror of https://github.com/libssh2/libssh2.git synced 2025-07-01 11:01:40 +03:00
Commit Graph

2997 Commits

Author SHA1 Message Date
669b51a076 cmake: prefer CMAKE_INSTALL_PREFIX over --prefix (in tests)
Closes #1542
2025-02-17 18:43:49 +01:00
a751d578be tidy-up: replace exit() with return
In examples and the manual page for `libssh2_version()`.

Closes #1541
2025-02-13 13:51:49 +01:00
9642a96ef7 cmake: add missing quotes
For consistent initialization for `_sys_libdirs` and just for consistent
formatting in the other case.

Ref: https://github.com/curl/curl/pull/16233#issuecomment-2642603412
Follow-up to 3de8731ef2 #1540
2025-02-07 12:58:02 +01:00
3de8731ef2 cmake: exclude CMAKE_C_IMPLICIT_LINK_DIRECTORIES from libssh2.pc
Co-authored-by: Kai Pastor
Ref: f72b848092
Ref: https://github.com/curl/curl/pull/16233
2025-02-07 12:01:35 +01:00
d92de5951a cmake: initialize variables where missing
As detected using `cmake --warn-uninitialized`.

It also lists documented CMake global variables, which is unexpected:
`CMAKE_MODULE_PATH`, `CMAKE_IMPORT_LIBRARY_SUFFIX`.
I'd expect CMake to initialize its namespace.

https://cmake.org/cmake/help/latest/manual/cmake.1.html#cmdoption-cmake-warn-uninitialized

Closes #1539
2025-02-06 03:43:37 +01:00
9da0ca3cde cmake: normalize before matching paths with syspaths
Requires CMake 3.20:
https://cmake.org/cmake/help/latest/command/cmake_path.html

Co-authored-by: Kai Pastor
Ref: 307e1f9878
Closes #1538
2025-02-06 01:11:04 +01:00
eea97dbf0a cmake: ZLIB linkage tidy-ups
- drop adding redundant ZLIB manual include headers.
  It's done now via `ZLIB::ZLIB`.
  Follow-up to 96d7f404e7 #1534

- src: replace missed `ZLIB_LIBRARIES` with `ZLIB::ZLIB`.
  Follow-up to 96d7f404e7 #1534

- src: drop always true `ZLIB_FOUND` check.

Cherry-picked from #1535
2025-02-05 12:47:23 +01:00
d07d12ae07 cmake: extend, not overwrite, CMAKE_REQUIRED_* values
Make sure to keep any previously added settings. For good measure;
this hasn't been an issue with libssh2 builds yet.

Cherry-picked from #1535
2025-02-05 12:40:40 +01:00
1a9f7b4cdd cmake: avoid dupe target_link_libraries() commands in tests
Cherry-picked from #1535
2025-02-05 12:39:37 +01:00
5f51c7a21a ci/GHA: limit ENABLE_ECDSA_WINCNG option to WinCNG
To avoid cmake warning:
```
CMake Warning:
  Manually-specified variables were not used by the project:

    ENABLE_ECDSA_WINCNG
```
https://github.com/libssh2/libssh2/actions/runs/13126062299/job/36622533686?pr=1535#step:3:88

Follow-up to 3f98bfb090 #1368
Cherry-picked from #1535
2025-02-05 12:37:22 +01:00
96d7f404e7 cmake: make libssh2-config work with all TLS-backends
CMake:

- Find*: set `<modulename>_FOUND` for compatibility when found via
  `pkg-config`. E.g. `MbedTLS_FOUND`.
  `find_package_handle_standard_args()` sets both `<MODULENAME>_FOUND`
  and `<Modulename>_FOUND` when detecting the dependency. Some CMake
  code relies on this and 3rd-party code may rely on it too. Make sure
  to set the latter variant when detecting the dependency via
  `pkg-config`, where we don't call
  `find_package_handle_standard_args()`.

  CMake sets these variable to `TRUE` (not `ON` or `1`). Replicate this
  for compatibility.

- libssh2-config.cmake: inherit default `LIBSSH2_USE_PKGCONFIG`.
  Follow-up to a3aa6b4ca8 #1525

- document variables consumed by `libssh2-config.cmake.in`.

- `libssh2-config.cmake`: fix to link to non-OpenSSL crypto backends.
  This is most likely not how this is supposed to be done, but better
  than failing.
  What's the canonical way to do this, and how OpenSSL and zlib does it
  is yet to be figured out.

- use `ZLIB::ZLIB` to reference zlib.
- use `IN ITEMS` where missed.
- harmonize variable dump output formats.

CMake `find_package` integration tests:

- extend to all crypto backends (was: OpenSSL).
- show libssh2 variables set by `find_package()`.
- stop building examples and tests for the consumed package.
  For performance.
- enable zlib, for coverage.
- be verbose when building the test targets.

ci/GHA:

- add packaged mbedTLS (2.x) build to Linux matrix.
- alphasort some tests.

Follow-up to d9c2e550ca #1460
Follow-up to 82b09f9b3a #1322

Closes #1534
2025-02-04 00:39:38 +01:00
d033c1eaf6 cmake: tidy up string append and list prepend syntax
- `set(VAR "${VAR}<value>")` ->
  `string(APPEND VAR "<value>")`
  Available since CMake 3.4:
  https://cmake.org/cmake/help/latest/command/string.html#append

- `set(VAR "${VAR2}-or-<value>;${VAR}")` ->
  `set(VAR "${VAR2}-or-<value>" ${VAR})`

- prefer dash-style MSVC option.
  Follow-up to 854cfa8292 #1524

Closes #1533
2025-02-02 02:57:52 +01:00
b89858b83d disable deprecated algos by default
- MD5-based MACs and hashes: `hmac-md5`, `hmac-md5-96`,
  `LIBSSH2_HOSTKEY_HASH_MD5`
    You can enable it now with `-DLIBSSH2_MD5_ENABLE`.
    Disabled by default since OpenSSH 7.2 (2016-02-29).
- 3DES cipher: `3des-cbc`
    You can enable it now with `-DLIBSSH2_3DES_ENABLE`.
    Disabled by default since OpenSSH 7.4 (2016-12-19).
- RIPEMD-160 MACs: `hmac-ripemd160`, `hmac-ripemd160@openssh.com`
    You can enable it now with `-DLIBSSH2_HMAC_RIPEMD_ENABLE`.
    Removed in OpenSSH 7.6 (2017-10-03).
- Blowfish cipher: `blowfish-cbc`
    You can enable it now with `-DLIBSSH2_BLOWFISH_ENABLE`.
    Removed in OpenSSH 7.6 (2017-10-03).
- RC4 ciphers: `arcfour`, `arcfour128`
    You can enable it now with `-DLIBSSH2_RC4_ENABLE`.
    Removed in OpenSSH 7.6 (2017-10-03).
- CAST cipher: `cast128-cbc`
    You can enable it now with `-DLIBSSH2_CAST_ENABLE`.
    Removed in OpenSSH 7.6 (2017-10-03).

- old-style, MD5-based encrypted private keys.
    You can enable it now with `-DLIBSSH2_MD5_PEM_ENABLE`.

CI runs:
before:
https://github.com/libssh2/libssh2/actions/runs/13066267976/job/36459081012
https://ci.appveyor.com/project/libssh2org/libssh2/builds/51426618
after:
https://github.com/libssh2/libssh2/actions/runs/13071320635/job/36473418776?pr=1531
https://ci.appveyor.com/project/libssh2org/libssh2/builds/51428270

Closes #1531
2025-01-31 13:04:33 +01:00
5cca650b1d tidy-up: prefer #ifdef / #ifndef (formatting)
Closes #1532
2025-01-31 13:04:32 +01:00
784446b6c5 build: add support for clang-cl, add CI job
- ci/appveyor: add clang-cl job.
- ci/appvayor: optimize setting an env.
- build: fix clang-cl builds.
- build: fix `-Wcast-function-type` compiler warnings for OpenSSL 3.
- build: use `stdint.h` with MSVC when supported.
- src: use `PRId64` for MSVC where supported.
- src: avoid recursive macro definition for `recv()` and `send()`.
- session: silence `-Wcast-function-type` for `libssh2_session_callback_set2()`.
  Sadly this function is still not fully warning-clean, and it
  seems we'd need separate setter-getters for each callback
  to avoid all warnings.

Closes #1484
2025-01-31 05:13:18 +01:00
6443b2f9d0 ci/GHA: bump BoringSSL
Also replace manual `-fPIC` C flag with
`-DCMAKE_POSITION_INDEPENDENT_CODE=ON`. It makes it pass it to C++,
which is necessary for BoringSSL after this bump.

Fixes:
```
/usr/bin/ld: /home/runner/usr/lib/libcrypto.a(crypto.cc.o): warning: relocation against `stderr@@GLIBC_2.2.5' in read-only section `.text'
/usr/bin/ld: /home/runner/usr/lib/libcrypto.a(urandom.cc.o): relocation R_X86_64_PC32 against symbol `stderr@@GLIBC_2.2.5' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: bad value
```
https://github.com/libssh2/libssh2/actions/runs/13065421829/job/36456862458#step:27:23

Closes #1530
2025-01-31 04:19:26 +01:00
7d5a4c7651 cmake: split integration tests into steps
Closes #1529
2025-01-31 04:19:25 +01:00
131480d2d5 wincng: move _libssh2_aes_ctr_increment() from misc, make static
Cherry-picked from #1484
2025-01-31 02:07:08 +01:00
cf3aac1aba libssh2_base64_decode: add deprecation warning
Cherry-picked from #1484
2025-01-31 02:04:59 +01:00
7027604505 libssh2_scp_send, libssh2_scp_send_ex: add deprecation warning
Also:
- switch to non-deprecated alternative in examples.
- add pointers and deprecation warning to libssh2_scp_send man page.

Cherry-picked from #1484
2025-01-31 02:04:59 +01:00
4fbd592314 openssl: fix to build with wolfSSL without AES-CTR
Cherry-picked from #1484
2025-01-31 02:04:59 +01:00
90a686ef3a gitignore: compress rules
Cherry-picked from #1484
2025-01-31 02:00:28 +01:00
2da28146a0 openssl: make it compatible with wolfSSL built without OPENSSL_ALL
Cherry-picked from #1484
2025-01-31 01:50:15 +01:00
008e82c0f8 ci/GHA: general maintenance, security, add LibreSSL and old OpenSSL jobs with tests
- add Linux jobs with old OpenSSL versions: 1.1.1, 1.1.0, 1.0.2, with
  tests.
  (Meaning we test these again after losing them in AppVeyor CI)
- add LibreSSL Linux job with tests.
- cache most dependency packages built from source.
  (exception: wolfSSL, which would have added too much complexity
  due to the multiple versions, and it's fast to build anyway.)
- change source tarball sources to GitHub for better stability and
  performance.
- move dependency versions to the env.
- set `persist-credentials: false` for checkout steps for security.
- pin actions to hash for security.
- checkout repo later, right before use.
- skip building BoringSSL tests to finish quicker.
- set `fail-fast: false` in the BSD build matrix.
- cmake: move UWP workaround from GHA to `CMakeLists.txt`, making it
  available for everyone.
- list installed packages in OpenBSD job.
- bump BoringSSL, mbedTLS, wolfSSL, OpenSSL.
- bump cross-platform-actions to v0.26.
- bump docker/build-push-action to v6.
- bump actions/upload-artifact to v4.
- bump NetBSD to 10.1.
- drop `--quiet 2` `apt-get` option to keep useful output.
- drop `--no-install-suggests --no-install-recommends` `apt-get`
  options. They are the defaults with the `ubuntu-24.04` image.
- tidy up quotes.

Cherry-picked from #1484

Closes #1528
2025-01-31 01:48:39 +01:00
606c102e52 build: enable -Wcast-qual, fix fallouts
- enable compiler warning `-Wcast-qual`.
- add `LIBSSH2_UNCONST()` macro to strip const where absolutely
  necessary to avoid compiler warnings.
- fix const stripping by constifying where necessary.
- fix const stripping by using `LIBSSH2_UNCONST()`.
- libgcrypt.h: drop unnecessary casts.
- openssl: fix to use new `BIO_new_mem_buf()` parameter types
  with wolfSSL.

Cherry-picked from #1484
Closes #1527
2025-01-31 00:57:26 +01:00
96cbe61896 ossfuzz: fix picky compiler warnings, make it pass checksrc
- fix compiler warnings.
- make it pass `checksrc`.
- fix shell `set -u` errors.
  Follow-up to 5012442850 #901
- REUSE: tidy up ossfuzz files.

Cherry-picked from #1484
Closes #1526
2025-01-30 23:36:39 +01:00
a3aa6b4ca8 cmake: misc improvements, add LIBSSH2_USE_PKGCONFIG option
- show platform flags (via curl).
- add `LIBSSH2_USE_PKGCONFIG` option to control whether to use
  `pkg-config` to find dependencies.
- set `.pc` names withing the Find modules.
- add `mbedcrypto` to `libssh2.pc` only when detected via `pkg-config`.
  Workaround for older mbedtls versions and non-CMake mbedTLS builds
  (as of mbedTLS 3.6.2) that don't emit an `mbedcrypto.pc` file.
- set header paths relative to the project root (tidy-up).
- use `-isystem` for crypto backend and zlib header paths.
  To match autotools.
- sync header path order with autotools.
- rename local variables to underscore-lowercase.
- minor tidy-ups.

Cherry-picked from #1484
Closes #1525
2025-01-30 23:36:39 +01:00
854cfa8292 build: prepare builds for clang-cl, add cmake ossfuzz support
- cmake: add support to build ossfuzz.
  Enable with `-DBUILD_OSSFUZZ=ON`.
  Also supports `-DLIB_FUZZING_ENGINE=` like autotools does.
- check for `__clang__` when suppressing warnings in source. Necessary
  for clang-cl, which set `__clang__`, but doesn't set `__GNU__`.
- cmake: optimize out 4 picky warning option detections with gcc.
- cmake: bring `-pedantic-error`, `-Wall` use closer to curl's.
- cmake: set `-Wno-language-extension-token` for clang-cl.
- cmake: escape only the necessary `-W` options for clang-cl.
- cmake: apply picky warnings to C++.
- cmake: replace `unset(VAR)` with `set(VAR "")` for init.
- cmake: prefer dash-style MSVC options.
- cmake: simplify `MATCHES` expression.
- cmake: formatting/whitespace.
- ci/GHA: bump `actions/upload-artifact` to v4

Closes #1524
2025-01-30 22:01:49 +01:00
af5c9fb88f openssl: fix indentation 2025-01-29 19:00:51 +01:00
1612807b9f cmake: make integration tests generator-agnostic, use GIT_SHALLOW
Closes #1523
2025-01-29 14:02:48 +01:00
717c083653 cmake: bump policy_max, add FATAL_ERROR for old cmake versions
Closes #1510
2025-01-29 13:02:40 +01:00
8011f9017b tests: delete CMake ExternalProject integration test
For no reason it broke when trying to silence a CMake deprecation
warning in #1510. Then when tested locally, it did not work either with
or without the patch in #1510.

I'm not sure, but existing implementation may have worked by accident
by re-using leftovers from the preceding two integration tests.

After spending a days trying to fix this, I declare defeat. If such
amount of time of testing, reading documentation, blog posts, variable
traces, logs, bug reports is not enough to make this work, or even
to understand how this should work, this seems like a lost cause.

CMake makes it impossible to cleanly query the properties of a target,
which would be essential for debugging. There are rough workarounds
with years of iteration, and those still don't work to this day:
https://stackoverflow.com/questions/32183975/how-to-print-all-the-properties-of-a-target-in-cmake

Copy-pasting an incantation from a blog post that made this work:
https://inhzus.io/posts/2023-12-01-cmake-external-project/
almost made it work, except that it had a workaround for a 10-year old
pending bug, another workaround for Ninja which required CMake 3.29,
with settings hard-wired, and explicitly configured in weird ways. But,
it still missed to pass the libssh2 library to the test target and
failed to link.

Then tried to pass the libssh2 lib the "usual" way via:
```
target_link_libraries(test PRIVATE libssh2)
```

That also did not work because CMake decided that the external libssh2
target is of "UTILITY" type, and errored with:
```
CMake Error at CMakeLists.txt:39 (target_link_libraries):
  Target "libssh2" of type UTILITY may not be linked into another target.
  One may link only to INTERFACE, OBJECT, STATIC or SHARED libraries, or to
  executables with the ENABLE_EXPORTS property set.
```

This type property is read-only, and documentation has no mention of it,
or how to set it whatsoever:
https://cmake.org/cmake/help/latest/module/ExternalProject.html

libssh2's `docs/INSTALL_CMAKE.md` mentions ExternalProject as a way to
use libssh2. Added there with the initial CMake commit. We should
probably delete it from there.

This consumption method has a single mention in public issues:
https://github.com/libssh2/libssh2/issues/1116

Closes #1522
2025-01-29 12:45:07 +01:00
7495084b1c libssh2_trace.3: Update prototype
Return value is int, not void.

Reported-by: pyscripter on github
Bug: https://github.com/libssh2/libssh2/issues/1517#issuecomment-2608628918
Closes #1518
2025-01-29 02:55:02 +01:00
c343f06b38 mansyntax.sh: revert a change to unhide man error output
Reverts part of 2213352758 #982
2025-01-29 02:49:22 +01:00
d65c4b3987 ci/GHA: fix Cygwin breakage in mansyntax.sh
Cygwin CI jobs started failing while running `mansyntax.sh`.

The reason for the fallout is `util-linux` packaged by Cygwin no
longer shipping `col.exe`, that is required by `man.exe`:
https://cygwin.com/packages/x86_64/util-linux/util-linux-2.39.3-2 (2024-04-02)
https://cygwin.com/packages/x86_64/util-linux/util-linux-2.40.2-1 (2024-12-24)

Work it around by telling `man` to not call `col`.

Relevant links:
https://github.com/util-linux/util-linux
https://gitlab.com/man-db/man-db
https://cygwin.com/packages/summary/util-linux.html
https://cygwin.com/cgit/cygwin-packages/util-linux/log/ (no visible commit for 2.40.2-1)
https://cygwin.com/pipermail/cygwin/2025-January/date.html (no reports)

Fixes:
```
test 1
    Start 1: mansyntax

1: Test command: /usr/bin/sh.exe "-c" "/cygdrive/d/a/libssh2/libssh2/tests/mansyntax.sh"
1: Working Directory: /cygdrive/d/a/libssh2/libssh2/bld/tests
1: Test timeout computed to be: 10000000
1: /cygdrive/d/a/libssh2/libssh2/tests/../docs/libssh2_agent_connect.3
1: man: can't execute col: No such file or directory
1: man: command exited with status 127: col -b -p -x | sed -e '/^[[:space:]]*$/{ N; /^[[:space:]]*\n[[:space:]]*$/D; }'
1/2 Test #1: mansyntax ........................***Failed    0.24 sec
/cygdrive/d/a/libssh2/libssh2/tests/../docs/libssh2_agent_connect.3
man: can't execute col: No such file or directory
man: command exited with status 127: col -b -p -x | sed -e '/^[[:space:]]*$/{ N; /^[[:space:]]*\n[[:space:]]*$/D; }'
```
https://github.com/libssh2/libssh2/actions/runs/13021305834/job/36322366102?pr=1510#step:6:216

Closes #1521
2025-01-29 02:43:41 +01:00
73ac65f79b userauth.c: fix typo from #1516
When making style fixes I inverted the NULL check logic.
2025-01-23 08:06:25 -08:00
49837fd756 userauth.c: fix possible memory leaks #1504 (#1516)
* userauth.c: fix possible memory leaks #1504

Notes:
Fix possible memory leaks if `userauth_list()` is called more than once, e.g. an auth error case. 

Author:
Will Cosgrove

Credit:
pyscripter
2025-01-22 16:53:14 -08:00
df2b206cd0 ci/appveyor: fix PowerShell warning (#1514)
in WinCNG builds, e.g. VS2015, WinCNG, x86, Server 2016:
```
Test-Path : Cannot bind argument to parameter 'Path' because it is null.
At line:10 char:16
+   if(Test-Path $env:OPENSSL_ROOT_DIR) {
+                ~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Test-Path], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.TestPathCommand
```
https://ci.appveyor.com/project/libssh2org/libssh2/builds/51280178/job/9ddtkb91w54si3da#L85
2025-01-07 20:11:55 +01:00
25d3a09207 ci/appveyor: use -A option with all MSVC versions (#1513)
To simplify the initialization. The ` Win64` method was meant for old
CMake versions not in use in CI.

Also pass the `-A` option without a space to make PowerShell pass
the option as expected by CMake.
2025-01-07 18:36:50 +01:00
bc78138371 ci/GHA: bump to cygwin v5 (#1512) 2025-01-07 11:09:33 +01:00
4725826550 cmake: fix cmake warnings (#1511)
```
CMake Warning (dev) at cmake/CopyRuntimeDependencies.cmake:59 (add_custom_command):
  The following keywords are not supported when using
  add_custom_command(TARGET): DEPENDS.

  Policy CMP0175 is not set: add_custom_command() rejects invalid arguments.
  Run "cmake --help-policy CMP0175" for policy details.  Use the cmake_policy
  command to set the policy and suppress this warning.
Call Stack (most recent call first):
  example/CMakeLists.txt:58 (add_target_to_copy_dependencies)
```
```
CMake Warning (dev) at cmake/CopyRuntimeDependencies.cmake:59 (add_custom_command):
  Exactly one of PRE_BUILD, PRE_LINK, or POST_BUILD must be given.  Assuming
  POST_BUILD to preserve backward compatibility.

  Policy CMP0175 is not set: add_custom_command() rejects invalid arguments.
  Run "cmake --help-policy CMP0175" for policy details.  Use the cmake_policy
  command to set the policy and suppress this warning.
Call Stack (most recent call first):
  example/CMakeLists.txt:58 (add_target_to_copy_dependencies)
```
Ref: https://github.com/libssh2/libssh2/actions/runs/12614228505/job/35152908184?pr=1510#step:15:77
2025-01-05 00:48:55 +01:00
389d70bfeb cmake: tidy up -j make option in integration tests (#1509) 2025-01-04 23:24:51 +01:00
ffd0c982a5 configure: fix --without-lib*-prefix when lib* is detected anyway
Do not test the prefix when set to `no`.
(as with `--without-lib*-prefix`)

Before this patch this test was always made and when detected despite
the wrong prefix, the `no` prefix remained in `LDFLAGS` causing a build
failure later in `libtool`.

Fixes:
```
$ ../configure --without-libssl-prefix
[...]
../libtool: line 7756: cd: no/lib: No such file or directory
libtool:   error: cannot determine absolute directory name of 'no/lib'
make[2]: *** [libssh2.la] Error 1
```

Follow-up to d19b619070 #1384

Reported-by: Christoph Reiter
Fixes #1505
Closes #1506
2025-01-02 22:34:21 +01:00
bd8caa1983 configure: drop duplicate -lmbedcrypto from LIBS
Closes #1507
2025-01-02 14:19:44 +01:00
780bf13aa2 libssh2.h: typo fixes
Closes #1496
2024-11-21 11:46:26 +01:00
21228cffb8 transport: fix indentation of comments
Cherry-picked from #1484
2024-11-15 01:55:18 +01:00
c78d54c28e transport: stop passing newline to the trace handler via debugdump()
The trace handler is called from two places in libssh2. One of them was
passing a newline at the end of the trace message string, the other one
was not.

When the trace handler feature was introduced, a newline was passed both
via `debugdump()` and `libssh2_debug()`:
44eba0c993 (2010-01-15)

Shortly after a commit deleted the newline for `libssh2_debug()`:
0f0652a309 (2010-06-23)

This patch re-syncs behaviour between the traceback callbacks by
dropping the newline for trace handler calls made from `debugdump()`.

Reported-by: Chris Emsen
Fixes #1485
Follow-up to 0f0652a309
Closes #1492
2024-11-14 20:00:14 +01:00
114923f1ac tidy-up: unsigned const char -> const unsigned char
For consistency with rest of the code.

Closes #1487
2024-11-02 00:37:59 +01:00
91b0e09934 tidy-up: spelling [ci skip] 2024-10-31 21:19:43 +01:00
5d03b4f94a cmake: build but don't install static lib in certain conditions
Building 3 tests require static libssh2 lib. Some may prefer not to
create the static lib, yet prefer to build all tests, including those
3 that require it.

Detect such intent by looking for an explicit `BUILD_TESTING=ON` and
`BUILD_STATIC_LIBS=OFF`, then build the static lib anyway but without
installing it.

Reported-by: Eli Schwartz
Fixes #1450
Closes #1469
2024-10-28 21:10:32 +01:00