mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-10-27 08:37:58 +03:00
Update third-party dependencies for security fixes and validate on Linux and Windows
Replace the libzip 0.10 fork with upstream 1.12.1. Only zip.h's zipconf.h include is patched; hand-written config.h/zipconf.h replace CMake's feature checks, and the platform file backends live in posix/ and win32/. Port Zip to the current libzip API: read-only opens use ZIP_RDONLY, which handles UTF-8 paths on Windows, so the fdopen workaround is gone. Remove the ZIP bounded-open mode and the ZipProvider entry and metadata limits; archives are limited only by the format and libzip. 65,536-entry InfoZIP archives now open. Update Mbed TLS to 3.6.7, libvorbis to 1.3.7, Monocypher to 4.0.3 and simdutf to 9.2.1, retaining eepp's Mbed TLS configuration (PSA and TLS 1.3 stay disabled) and the reduced simdutf feature set. Add TLS certificate/hostname, Vorbis encoder and ZIP range regression tests. Fix SFTP watch channels on Linux: efsw-agent now exits immediately on EOF (efsw 0712eec), and a refused agent channel is retried briefly instead of disabling native watching on the host for five minutes. Start the SFTP test sshd without PerSourcePenalties on OpenSSH < 9.8, so the integration tests run on Ubuntu 24.04. CI installs OpenSSH and requires them. Fix GCC builds on Linux AArch64 (mojoAL NEON target attributes, the physics example's signed bitmap) anation. Keep a NanoSVG libFuzzer target and CI. Record the updates, checksums and retained patches in the security audit and inventory.
This commit is contained in:
@@ -24,7 +24,8 @@ jobs:
|
||||
sudo apt update
|
||||
sudo apt install -y gcc-13 g++-13 wget mesa-utils xvfb xauth gdb zstd \
|
||||
weston xdotool imagemagick \
|
||||
python3-gi gir1.2-atspi-2.0 at-spi2-core dbus-x11
|
||||
python3-gi gir1.2-atspi-2.0 at-spi2-core dbus-x11 \
|
||||
openssh-server openssh-client netcat-openbsd clang
|
||||
bash projects/linux/scripts/install_sdl3.sh --keep-build
|
||||
wget https://cdn.ensoft.dev/eepp-assets/premake-5.0.0-beta6-linux.tar.gz
|
||||
tar xvzf premake-5.0.0-beta6-linux.tar.gz
|
||||
@@ -95,9 +96,24 @@ jobs:
|
||||
SDL_AUDIODRIVER: dummy
|
||||
SDL_AUDIO_DRIVER: dummy
|
||||
ALSOFT_DRIVERS: "null"
|
||||
# The SFTP integration tests start a loopback sshd; fail instead of silently skipping.
|
||||
EEPP_REQUIRE_SFTP_TESTS: "1"
|
||||
run: |
|
||||
cd projects/scripts
|
||||
bash ./run_gdb_tests.sh
|
||||
- name: NanoSVG Fuzzing
|
||||
# The vendored NanoSVG fork carries local security patches and has no upstream fuzzing.
|
||||
if: ${{ !cancelled() && steps.build.outcome == 'success' }}
|
||||
timeout-minutes: 10
|
||||
run: |
|
||||
./premake5 --disable-static-build --with-debug-symbols --with-backend=SDL3 --with-security-fuzz gmake
|
||||
make -C make/linux -e config=release_x86_64 CC=clang CXX=clang++ eepp-fuzz-nanosvg -j$(nproc)
|
||||
# New inputs go to the output folder so the committed seeds stay unchanged; crash
|
||||
# reproducers are uploaded with the other test output.
|
||||
mkdir -p bin/unit_tests/output/fuzz-nanosvg/corpus
|
||||
bin/security/eepp-fuzz-nanosvg -max_total_time=60 -max_len=8192 \
|
||||
-artifact_prefix=bin/unit_tests/output/fuzz-nanosvg/ \
|
||||
bin/unit_tests/output/fuzz-nanosvg/corpus src/tests/security/corpus/nanosvg
|
||||
- name: Native X11 Drag and Drop Tests
|
||||
timeout-minutes: 5
|
||||
shell: bash
|
||||
|
||||
@@ -73,6 +73,7 @@ ecode.dmg
|
||||
/.cache/
|
||||
/compile_commands.json
|
||||
/bin/benchmarks*
|
||||
/bin/security*
|
||||
/bin/unit_tests/eepp*
|
||||
/bin/unit_tests/lib*
|
||||
/bin/unit_tests/output/*
|
||||
|
||||
@@ -517,15 +517,13 @@ I/O scheduler's mount isolation and timeouts.
|
||||
Only `file://` backing archives are supported initially. Password-protected entries and unsupported
|
||||
compression methods report `Unsupported`. ZIP symlink attributes are not followed: their stored
|
||||
data is exposed as a regular file. Unsafe names (absolute paths, traversal components, backslashes
|
||||
or drive/stream colons) are excluded. Indexes are limited to 262,144 entries including implicit
|
||||
directories and a conservative 64 MiB metadata budget covering libzip's decoded directory,
|
||||
nodes, stored paths and container growth. Oversized central directories are rejected before
|
||||
decoding; budget violations return `InvalidOperation`. At most eight indexes are cached;
|
||||
or drive/stream colons) are excluded. Indexes have no fixed entry limit beyond what the ZIP
|
||||
format and libzip support; their memory grows with the size of the central directory.
|
||||
Inconsistent central directories return `InvalidOperation`. At most eight indexes are cached;
|
||||
existing handles can retain older indexes.
|
||||
|
||||
Legacy InfoZIP archives whose 16-bit entry count wraps to zero with a nonempty central directory
|
||||
(for example, exactly 65,536 entries) are intentionally rejected as inconsistent. A zero count is
|
||||
accepted only for an empty central directory.
|
||||
Legacy InfoZIP archives without ZIP64 records, whose 16-bit entry count wraps past 65,535, are
|
||||
read using the central directory size; the recovered count must match the entries present.
|
||||
|
||||
In eefm, Enter or double-click on a local `.zip`, `.jar`, `.apk` or `.epub` file enters it
|
||||
(extensions are case-insensitive). These ZIP-based formats share `ZipProvider` and `zip://` locations.
|
||||
|
||||
@@ -20,29 +20,34 @@ release has not been established.
|
||||
| libssh2 | 1.11.1 plus local crypto integration | **1.11.2_DEV**, pinned to upstream `6e7b2076a6ced2230968b27ee7c1abb77fe5a88d` | Refreshed the complete imported library source, preserving eepp's build configuration, classic Mbed TLS APIs and Monocypher integration. This is an unreleased snapshot, not a 1.11.2 release. |
|
||||
| libpng | 1.6.37 | **1.6.59** | Imported upstream library sources, architecture implementations and the release's prebuilt configuration without source patches. |
|
||||
| NanoSVG | Modified FLTK-derived snapshot | Same snapshot plus manual security fixes | Patched the reported arc conversion, fixed-point conversion/advancement and stroke tessellation issues while retaining local style/currentColor behavior. |
|
||||
| libzip | 0.10 plus local hardening | **1.12.1** | Replaced the fork with the upstream release; only an include-path patch remains. `Zip` uses the current API. ZIP browsing limits were removed. |
|
||||
| Mbed TLS | 3.6.0 | **3.6.7** (LTS) | Library and headers match the release; eepp's `mbedtls_config.h` block is retained (PSA crypto, TLS 1.3 and weak algorithms remain disabled). |
|
||||
| libvorbis | 1.3.6 | **1.3.7** | Includes the CVE-2018-10393 encoder bounds fix and the channel validation changes; all imported files match the release. |
|
||||
| Monocypher | 4.0.2 | **4.0.3** | Fixes the compiler-dependent Ed25519 signing timing leak; imported sources match the release. |
|
||||
| simdutf | 9.2.0 | **9.2.1** | Regenerated amalgamation with the same UTF-8/UTF-32-only feature set; Base64 stays disabled. |
|
||||
|
||||
The release unit-test target builds with the required macOS script. The final full
|
||||
native release suite passed **2,124 tests**, including all **34 SFTP integration tests**
|
||||
against isolated loopback SSH servers and all **6 focused security tests**. The
|
||||
security cases cover five NanoSVG numeric/style regressions and RGB/RGBA palette
|
||||
decoding with 17-pixel rows. Both palette Neon functions are linked into the test
|
||||
executable on this ARM64 host.
|
||||
Validation of the complete working tree:
|
||||
|
||||
The full suite includes PNG color-font loading/rendering, image loading and SVG UI
|
||||
coverage. No cross-platform build, optional OpenSSL-backend build or sanitizer/fuzz
|
||||
campaign was performed. Passing functional tests does not establish absence of all
|
||||
malformed-input vulnerabilities.
|
||||
- macOS ARM64: the full native release suite passed all 2,128 tests, including the SFTP
|
||||
integration tests against loopback SSH servers and the PNG, NanoSVG, ZIP, TLS and Vorbis
|
||||
security tests.
|
||||
- Linux ARM64 (Ubuntu 24.04, GCC 13, SDL 3.4.10, Docker): the release build succeeded and the
|
||||
headless suite passed 2,139 of 2,140 tests with all SFTP tests required; one font test
|
||||
skipped for lack of a font with a non-normal stretch.
|
||||
- Windows x86_64 (MinGW-w64 GCC 13 cross-build, Wine 7.7): the unit tests build and all ZIP
|
||||
tests pass; the full suite under Wine was not conclusive (file-watch, long-path and headless
|
||||
UI failures not reproduced on real Windows).
|
||||
- ASan/UBSan libFuzzer runs: ZIP (300 s, 3.39 M inputs) and NanoSVG, without findings. The
|
||||
Linux CI job now fuzzes NanoSVG for 60 s and requires the SFTP tests to run.
|
||||
|
||||
Not run: Linux x86_64, Android, Emscripten and the optional OpenSSL backend. Passing
|
||||
functional tests does not establish absence of all malformed-input vulnerabilities.
|
||||
|
||||
## Remaining cleanup order
|
||||
|
||||
| Order | Component | Current source | Action | Reason and qualification |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| 1 | libzip | 0.10 plus local hardening | Resolve residual arithmetic checks; plan a modern libzip migration | Local changes address one old CVE, but other unchecked arithmetic remains. Bounded VFS opens and the public unrestricted ZIP API have different exposure. |
|
||||
| 2 | Mbed TLS | 3.6.0 | Upgrade within LTS to 3.6.7 | Substantial security backlog. Many high-scoring findings require unused APIs, a TLS server role, unusual compiler behavior, or deployment conditions. Do not characterize the ordinary eepp HTTPS client as a confirmed RCE. |
|
||||
| 3 | libvorbis | 1.3.6 | Upgrade to 1.3.7 | The CVE-2018-10393 encoder bounds fix is absent; eepp includes an encoder. |
|
||||
| 4 | Bundled SDL2 source | 2.0.12 | Reconcile Android source with the newer SDL2 pin | Old source has high-severity surface/blit issues; an application exploit path was not established. |
|
||||
| 5 | simdutf | 9.2.0 | Update to at least 9.2.1 | High upstream advisory affects Base64 APIs that eepp does not currently call. |
|
||||
| 6 | Monocypher | 4.0.2 | Update to 4.0.3 | Compiler-dependent EdDSA/Ed25519 timing fix. Signing is used by our SSH backend; no high CVE for that issue was established. |
|
||||
| 1 | Bundled SDL2 source | 2.0.12 | Reconcile Android source with the newer SDL2 pin | Old source has high-severity surface/blit issues; an application exploit path was not established. |
|
||||
|
||||
Orders indicate engineering priority for this repository, not a new CVSS score.
|
||||
Targets are releases verified during the initial audit; check upstream again before
|
||||
@@ -144,46 +149,84 @@ These findings concern numeric undefined behavior and availability. The original
|
||||
reports include sanitizer-triggered termination; neither the initial audit nor this
|
||||
remediation establishes an eepp RCE or a deterministic release-build crash.
|
||||
|
||||
## Remaining findings
|
||||
### libzip
|
||||
|
||||
### libzip: old release with meaningful local changes
|
||||
Replaced the 0.10 fork with [libzip 1.12.1](https://github.com/nih-at/libzip/releases/tag/v1.12.1)
|
||||
(`libzip-1.12.1.tar.xz`, SHA-256
|
||||
`c40062022a1963c80573d48f6070792297cecd7c6bffe3aefcac0d8b9bee8913`, matching the GitHub
|
||||
release digest). [`README.eepp.md`](../../src/thirdparty/libzip/README.eepp.md) records the
|
||||
imported sources, the hand-written `config.h`/`zipconf.h` that replace CMake, the generated
|
||||
error table and the retained patches.
|
||||
|
||||
[`zipconf.h`](../../src/thirdparty/libzip/zipconf.h) says 0.10, but the source is not
|
||||
an unmodified 0.10 release. In particular:
|
||||
The initial audit's open questions about the old code no longer apply:
|
||||
|
||||
- CVE-2012-1162's zero-entry allocation/write condition is guarded in
|
||||
[`zip_open.c`](../../src/thirdparty/libzip/zip_open.c), and the empty-directory
|
||||
case returns before the original `do` loop. Do not list this as unpatched.
|
||||
- CVE-2017-12858's upstream fix removes a second free of a `zip_buffer` in
|
||||
`_zip_dirent_process_winzip_aes()` failure handling. That machinery is absent
|
||||
here. A scanner's version-only match is insufficient. ZIP64 advisory
|
||||
CVE-2017-14107 likewise targets code not present in this old implementation.
|
||||
- The allocation bounds check associated with CVE-2015-2331 is absent from
|
||||
`_zip_cdir_new()`, and `_zip_cdir_grow()` also multiplies without an allocation
|
||||
overflow check. Exact reachability depends on entry-count handling and platform
|
||||
size; the initial count here is only 16-bit, so this is not a reproduced CVE.
|
||||
- The expression `cd->offset + cd->size` still adds two `unsigned int` fields
|
||||
before checking the end of the directory. This is the family of offset/size
|
||||
arithmetic covered by CVE-2012-1163 (legacy CVSS 2.0 6.8). It warrants a focused
|
||||
review even though it falls below this audit's nominal high threshold.
|
||||
- The `cd->offset + cd->size` addition (CVE-2012-1163 family) and the unchecked
|
||||
`_zip_cdir_new()`/`_zip_cdir_grow()` multiplications (CVE-2015-2331 family) are gone. 1.12.1
|
||||
reads 64-bit EOCD fields through bounds-checked buffers, rejects wrapping offsets and sizes,
|
||||
rejects ZIP64 entry counts larger than the directory can hold, and grows arrays through
|
||||
overflow-checked `ZIP_REALLOC`.
|
||||
- The signed-shift undefined behavior that a sanitizer run found in the old `_zip_read4()`, and the
|
||||
entry-capacity update made before `realloc()` succeeded, existed only in the old fork. No
|
||||
uncommitted fixes to 0.10 were kept.
|
||||
- CVE-2017-12858 and CVE-2017-14107 are fixed upstream. 1.12.1 also includes the later
|
||||
hardening listed in the [security history](https://libzip.org/security/).
|
||||
|
||||
The VFS path uses `OpenMode::ReadOnlyBounded` / `ZIP_LIMIT_METADATA`, which constrains
|
||||
large directories. The ordinary public `Zip::open()` uses `zip_open(..., 0, ...)`.
|
||||
Do not apply the VFS mitigation to every caller.
|
||||
The only source patch is `zip.h` including `"zipconf.h"` instead of `<zipconf.h>`.
|
||||
|
||||
Sources: [libzip security history](https://libzip.org/security/),
|
||||
[CVE-2015-2331 allocation fix](https://github.com/php/php-src/commit/ef8fc4b53d92fbfcd8ef1abbd6f2f5fe2c4a11e5),
|
||||
[CVE-2017-12858 actual fix](https://github.com/nih-at/libzip/commit/2217022b7d1142738656d891e00b3d2d9179b796).
|
||||
The verified current upstream release is 1.12.1. Migration needs work on our
|
||||
custom APIs, file-descriptor ownership, metadata limits and build integration;
|
||||
it is not a drop-in replacement for the current fork.
|
||||
The old fork's `ZIP_LIMIT_METADATA` bounded open, and the VFS `ZipProvider` limits of 262,144
|
||||
entries and a 64 MiB metadata budget, were removed at the maintainer's direction. ZIP browsing
|
||||
now accepts whatever the format and libzip support. libzip bounds the entry count by the
|
||||
central directory size, so index memory grows with the archive: about 300 bytes per typical
|
||||
entry, and roughly 10× the directory size for a crafted directory of empty extra fields.
|
||||
`ArchiveProvider` (libarchive) still has its own 262,144-entry / 64 MiB limits.
|
||||
|
||||
### Mbed TLS: upgrade, with precise exposure accounting
|
||||
`Zip` now opens read-only mode with `zip_open(ZIP_RDONLY)`. libzip converts UTF-8 paths to
|
||||
wide paths on Windows, so the `fopenUtf8`/`dup`/`zip_fdopen` ownership workaround was removed,
|
||||
and `ReadWrite` opens gain Unicode support on Windows. Deprecated calls were replaced by
|
||||
`zip_file_add`, `zip_get_error`, `zip_error_strerror` and `zip_discard`. The old 0.10
|
||||
Windows `rename()` workaround is superseded by upstream's Win32 backend. bzip2, xz, zstd and
|
||||
WinZip AES remain disabled, as they were in 0.10. On Windows, `advapi32` is now linked for
|
||||
upstream's random-number and ACL code.
|
||||
|
||||
Default TLS backend is selected in `premake5.lua`; OpenSSL is optional.
|
||||
[`build_info.h`](../../src/thirdparty/mbedtls/include/mbedtls/build_info.h)
|
||||
identifies 3.6.0. The [3.6.7 LTS release](https://github.com/Mbed-TLS/mbedtls/releases/tag/mbedtls-3.6.7)
|
||||
is the verified update target, avoiding a simultaneous 4.x migration.
|
||||
InfoZIP archives whose 16-bit count wraps (for example, exactly 65,536 entries) now open,
|
||||
and libzip recovers the count from the directory size; the old fork rejected them because it
|
||||
could not decode them safely.
|
||||
|
||||
Validation:
|
||||
[`zip_security_tests.cpp`](../../src/tests/unit_tests/zip_security_tests.cpp) covers wrapped and
|
||||
high-bit 32-bit ranges, 64-bit offset/size wrapping, and ZIP64 counts at 2^32 and 2^32−1 (which
|
||||
wrap a 32-bit allocation). A 300 s ASan/UBSan libFuzzer run of a temporary ZIP target, through
|
||||
the public `zip_open_from_source()` API, executed 3.39 M inputs without a finding. That target was
|
||||
then removed: libzip is now unmodified apart from one include line, and upstream maintains
|
||||
OSS-Fuzz harnesses. The NanoSVG target remains, because the local fork has no upstream fuzzing;
|
||||
the Linux CI job fuzzes it for 60 s on every run.
|
||||
|
||||
- macOS ARM64: the full native release suite passed all 2,128 tests.
|
||||
- Linux ARM64 (Ubuntu 24.04, GCC 13, SDL 3.4.10, in Docker): the release build and the full
|
||||
headless suite passed 2,139 of 2,140 tests, with all SFTP integration tests required and
|
||||
run; one font test skipped for lack of a font with a non-normal stretch.
|
||||
- Windows x86_64 (MinGW-w64 GCC 13 cross-build, run under Wine 7.7): libzip builds without
|
||||
warnings and all 21 ZIP tests pass. The full suite under Wine is not conclusive: file-watch,
|
||||
long-path and headless UI tests failed or crashed in ways not yet reproduced on real Windows.
|
||||
- Linux x86_64, Android and Emscripten builds of the new configuration were not run.
|
||||
|
||||
### Mbed TLS
|
||||
|
||||
Updated from 3.6.0 to the [3.6.7 LTS release](https://github.com/Mbed-TLS/mbedtls/releases/tag/mbedtls-3.6.7)
|
||||
(`mbedtls-3.6.7.tar.bz2`, SHA-256
|
||||
`a7e8bcbec0e6f761b4af24f25677626b35f762f68eef79c08677a363212d11f6`), avoiding a simultaneous
|
||||
4.x migration. Every imported library source and header matches the release except
|
||||
`include/mbedtls/mbedtls_config.h`, whose trailing eepp block is retained: weak key exchanges,
|
||||
DES and DHM disabled, deprecated APIs removed, AESCE limited to AArch64 Linux, and
|
||||
`MBEDTLS_PSA_CRYPTO_C`, `MBEDTLS_SSL_PROTO_TLS1_3` and LMS disabled. The release's PSA
|
||||
sources are present again (3.6.0's import had deleted them as unused); with PSA disabled they
|
||||
compile to empty objects. They are kept deliberately: TLS 1.3 in Mbed TLS 3.6 requires PSA, and
|
||||
enabling it is planned as a separate migration. The libssh2 classic-API adapter is unchanged.
|
||||
|
||||
The default TLS backend is selected in `premake5.lua`; OpenSSL is optional and was not
|
||||
built in this validation. [`tls_security_tests.cpp`](../../src/tests/unit_tests/tls_security_tests.cpp)
|
||||
connects to a loopback OpenSSL `s_server` (TLS 1.2), and checks that a trusted certificate is
|
||||
accepted while a wrong host name and an untrusted certificate are rejected.
|
||||
|
||||
The ordinary [`MbedTLSSocket`](../../src/eepp/network/ssl/backend/mbedtls/mbedtlssocket.cpp)
|
||||
is a stream TLS client. It sets the hostname, uses certificate verification when
|
||||
@@ -207,7 +250,7 @@ matches, not a claim they all affect that client:
|
||||
| CVE-2026-49300 | Malformed certificate interpreted as a CA. Upstream's exploit scenario requires accepting untrusted certificates through a different validator/trust-registration process; such a workflow was not found here. |
|
||||
| CVE-2026-50580 | TLS 1.2 ECDHE-PSK client with oversized configured PSK identity. No PSK configuration calls found. |
|
||||
| CVE-2026-50579 | Reused PKCS7 context; no PKCS7 caller found. |
|
||||
| CVE-2026-50713 | Introduced in 3.6.3; 3.6.0 is outside the affected interval. DTLS also differs from the eepp stream TLS path. |
|
||||
| CVE-2026-50713 | Introduced in 3.6.3, after the old 3.6.0, and fixed in 3.6.7 (DTLS renegotiation with `badmac_limit`). DTLS also differs from the eepp stream TLS path. |
|
||||
|
||||
Advisory definitions and fixes: [official security index](https://mbed-tls.readthedocs.io/en/latest/security-advisories/).
|
||||
The individual documents were read from the official `Mbed-TLS/mbedtls-docs`
|
||||
@@ -215,25 +258,24 @@ source archive, including issues whose NVD descriptions omit configuration detai
|
||||
The [AESNI advisory](https://mbed-tls.readthedocs.io/en/latest/security-advisories/mbedtls-security-advisory-2025-06-1/)
|
||||
is particularly useful when assessing x86 distribution builds.
|
||||
|
||||
Several additional low/medium fixes apply to this old TLS baseline. Keeping 3.6.0
|
||||
because an individual high-CVE precondition is absent would leave that backlog.
|
||||
An upgrade is recommended, but the distinctions above should remain in the record.
|
||||
Advisory definitions and fixes: [official security index](https://mbed-tls.readthedocs.io/en/latest/security-advisories/).
|
||||
The individual documents were read from the official `Mbed-TLS/mbedtls-docs`
|
||||
source archive, including issues whose NVD descriptions omit configuration details.
|
||||
The [AESNI advisory](https://mbed-tls.readthedocs.io/en/latest/security-advisories/mbedtls-security-advisory-2025-06-1/)
|
||||
is particularly useful when assessing x86 distribution builds. 3.6.7 also clears the low and
|
||||
medium fixes accumulated since 3.6.0.
|
||||
|
||||
### libvorbis: encoder update
|
||||
### libvorbis
|
||||
|
||||
[`lib/info.c`](../../src/thirdparty/libvorbis/lib/info.c) identifies 1.3.6.
|
||||
[`lib/psy.c`](../../src/thirdparty/libvorbis/lib/psy.c) still lacks the loop/index
|
||||
bounds added for CVE-2018-10393 (CVSS 3.1 7.5). This was verified by comparing the
|
||||
local file with the official 1.3.7 archive.
|
||||
[`SoundFileWriterOgg`](../../src/eepp/audio/soundfilewriterogg.cpp) configures the
|
||||
Vorbis encoder with the supplied sample rate/channel count and invokes its analysis
|
||||
pipeline. The relevant issue is encoding unusual low sample rates, not ordinary
|
||||
playback of every Ogg file. Upgrade to 1.3.7 and test those input conditions.
|
||||
|
||||
CVE-2018-10392 is another version match involving channel validation; its precise
|
||||
caller conditions were not reproduced. Include the upstream channel-validation
|
||||
changes in the refresh.
|
||||
Source: [upstream 1.3.7 changelog](https://github.com/xiph/vorbis/blob/v1.3.7/CHANGES).
|
||||
Updated from 1.3.6 to [1.3.7](https://github.com/xiph/vorbis/blob/v1.3.7/CHANGES)
|
||||
(`libvorbis-1.3.7.tar.xz`, SHA-256
|
||||
`b33cc4934322bcbf6efcbacf49e3ca01aadbea4114ec9589d1b1e9d20f72954b`). All imported files match
|
||||
the release, including the CVE-2018-10393 loop/index bounds in `lib/psy.c` and the
|
||||
CVE-2018-10392 channel validation. The standalone tool sources that eepp removed earlier
|
||||
(`tone.c`, `barkmel.c`) remain excluded. [`SoundFileWriterOgg`](../../src/eepp/audio/soundfilewriterogg.cpp)
|
||||
drives the encoder; [`vorbis_security_tests.cpp`](../../src/tests/unit_tests/vorbis_security_tests.cpp)
|
||||
encodes and decodes mono and stereo at 1 Hz to 44.1 kHz and checks that invalid rates and
|
||||
channel counts are rejected.
|
||||
|
||||
## High findings whose current eepp API conditions were not found
|
||||
|
||||
@@ -269,18 +311,16 @@ Sources: [Cairo advisory](https://github.com/harfbuzz/harfbuzz/security/advisori
|
||||
|
||||
### simdutf and Monocypher
|
||||
|
||||
simdutf 9.2.0 is within the high
|
||||
simdutf was updated from 9.2.0 to 9.2.1, which fixes the high
|
||||
[GHSA-pw55-7mm7-cvhh](https://github.com/simdutf/simdutf/security/advisories/GHSA-pw55-7mm7-cvhh)
|
||||
range. It affects Base64 decoding into exactly sized output buffers, and is fixed
|
||||
in 9.2.1. eepp uses Unicode conversion/counting functions; no affected Base64
|
||||
consumer was found. The related LASX Latin-1 issue is also fixed in 9.2.1, but those
|
||||
conversion functions were not found among current callers. Neither advisory had a
|
||||
CVE assigned when checked.
|
||||
Base64 issue and the related LASX Latin-1 issue. eepp vendors a regenerated amalgamation
|
||||
limited to UTF-8 and UTF-32, as before; Base64 and Latin-1 support are not compiled, so
|
||||
neither advisory was reachable.
|
||||
|
||||
Monocypher 4.0.3 fixes an EdDSA/Ed25519 timing leak in 4.0.2 and earlier with certain
|
||||
compiler/options combinations. Our SSH integration does sign using Ed25519, so
|
||||
update it during the SSH refresh. No high-scored CVE was found for that particular
|
||||
issue. Sources: [known bugs](https://monocypher.org/bugs),
|
||||
Monocypher was updated from 4.0.2 to 4.0.3, which fixes the compiler-dependent EdDSA/Ed25519
|
||||
timing leak. Our SSH integration signs with Ed25519, so this was relevant. The imported
|
||||
`monocypher.{c,h}` and `monocypher-ed25519.{c,h}` match the release. Sources:
|
||||
[known bugs](https://monocypher.org/bugs),
|
||||
[4.0.3 release](https://github.com/LoupVaillant/Monocypher/releases/tag/4.0.3).
|
||||
|
||||
### SDL version selection
|
||||
@@ -350,15 +390,15 @@ and establish a verified tag/commit before calling a future update routine.
|
||||
| libogg | 1.3.3 | Screened | [framing.c](../../src/thirdparty/libogg/src/framing.c) |
|
||||
| libpng | 1.6.59 | Fixed | [png.h](../../src/thirdparty/libpng/png.h) |
|
||||
| libssh2 | 1.11.2_DEV @ 6e7b2076 + local integration | Fixed | [libssh2.h](../../src/thirdparty/libssh2/include/libssh2.h) |
|
||||
| libvorbis | 1.3.6 | Upgrade | [info.c](../../src/thirdparty/libvorbis/lib/info.c) |
|
||||
| libvorbis | 1.3.7 | Fixed | [info.c](../../src/thirdparty/libvorbis/lib/info.c) |
|
||||
| libwebp | 1.5.0 | Screened | [vp8i_dec.h](../../src/thirdparty/libwebp/src/dec/vp8i_dec.h) |
|
||||
| libyaml | 0.2.5 | Screened | [config.h](../../src/thirdparty/libyaml/src/config.h) |
|
||||
| libzip | 0.10 + local hardening | Review | [zipconf.h](../../src/thirdparty/libzip/zipconf.h) |
|
||||
| mbedtls | 3.6.0 | Upgrade | [build_info.h](../../src/thirdparty/mbedtls/include/mbedtls/build_info.h) |
|
||||
| libzip | 1.12.1 | Fixed | [zipconf.h](../../src/thirdparty/libzip/zipconf.h) |
|
||||
| mbedtls | 3.6.7 | Fixed | [build_info.h](../../src/thirdparty/mbedtls/include/mbedtls/build_info.h) |
|
||||
| md4c | Unversioned/patched snapshot | Snapshot | [md4c.c](../../src/thirdparty/md4c/md4c.c) |
|
||||
| mojoAL | 2.0.1 | Screened | [mojoal.c](../../src/thirdparty/mojoAL/mojoal.c) |
|
||||
| mojoAL-SDL3 | 2.9.9 | Screened | [mojoal.c](../../src/thirdparty/mojoAL-SDL3/mojoal.c) |
|
||||
| monocypher | 4.0.2 | Maintenance | [monocypher.h](../../src/thirdparty/monocypher/monocypher.h) |
|
||||
| monocypher | 4.0.3 | Fixed | [monocypher.h](../../src/thirdparty/monocypher/monocypher.h) |
|
||||
| nanosvg | Snapshot + 2026-10-25 security patches | Fixed | [nanosvg.h](../../src/thirdparty/nanosvg/nanosvg.h) |
|
||||
| nlohmann | 3.12.0 | Screened | [json.hpp](../../src/thirdparty/nlohmann/json.hpp) |
|
||||
| oniguruma | 6.9.10 | Screened | [oniguruma.h](../../src/thirdparty/oniguruma/oniguruma.h) |
|
||||
@@ -367,7 +407,7 @@ and establish a verified tag/commit before calling a future update routine.
|
||||
| pugixml | 1.12 | Screened | [pugixml.hpp](../../src/thirdparty/pugixml/pugixml.hpp) |
|
||||
| SDL2 | 2.0.12 | Conditional | [SDL_version.h](../../src/thirdparty/SDL2/include/SDL_version.h) |
|
||||
| SheenBidi | 2.9.0 | Screened | [SBVersion.h](../../src/thirdparty/SheenBidi/Headers/SheenBidi/SBVersion.h) |
|
||||
| simdutf | 9.2.0 | Maintenance | [simdutf.h](../../src/thirdparty/simdutf/simdutf.h) |
|
||||
| simdutf | 9.2.1 (UTF-8/UTF-32 build) | Fixed | [simdutf.h](../../src/thirdparty/simdutf/simdutf.h) |
|
||||
| SOIL2 | 1.3.0 snapshot | Screened | [SOIL2.h](../../src/thirdparty/SOIL2/src/SOIL2/SOIL2.h) |
|
||||
| subprocess | Unversioned/patched snapshot | Snapshot | [subprocess.h](../../src/thirdparty/subprocess/subprocess.h) |
|
||||
| tabulate | 1.5.0 | Screened | [tabulate.hpp](../../src/thirdparty/tabulate/tabulate.hpp) |
|
||||
@@ -457,16 +497,10 @@ Coverage gaps that remain explicit:
|
||||
|
||||
## Remaining implementation batches
|
||||
|
||||
1. **ZIP follow-up:** resolve arithmetic questions in the current fork, then decide
|
||||
between focused security backports and migration to modern libzip. Preserve
|
||||
bounded-open behavior and ownership semantics during migration.
|
||||
2. **Cryptography maintenance:** Mbed TLS 3.6.7 and Monocypher 4.0.3, validating HTTP,
|
||||
certificate checks, SSH keys, session lifetime and backend compatibility. Retain
|
||||
the libssh2 classic API adapter unless PSA/threading migration is deliberate.
|
||||
3. **Audio/platform maintenance:** Vorbis 1.3.7 and Android SDL source reconciliation.
|
||||
4. **Small exposure-reducing updates:** simdutf >=9.2.1 and PCRE2 10.49. Establish
|
||||
verified provenance for the remaining snapshot-only imports.
|
||||
5. Replace the libssh2 development snapshot with a security-fixed stable release
|
||||
1. **Platform maintenance:** reconcile the Android SDL2 source with the newer SDL2 pin.
|
||||
2. **Small exposure-reducing updates:** PCRE2 10.49. Establish verified provenance for the
|
||||
remaining snapshot-only imports.
|
||||
3. Replace the libssh2 development snapshot with a security-fixed stable release
|
||||
when one is available, retaining the recorded integration patches.
|
||||
|
||||
For subsequent updates, record the upstream release/commit and retained patches
|
||||
|
||||
@@ -305,14 +305,26 @@
|
||||
{
|
||||
"name": "libvorbis",
|
||||
"path": "src/thirdparty/libvorbis",
|
||||
"version": "1.3.6",
|
||||
"version": "1.3.7",
|
||||
"version_evidence": "src/thirdparty/libvorbis/lib/info.c",
|
||||
"upstream": "https://github.com/xiph/vorbis",
|
||||
"assessment": "upgrade",
|
||||
"notes": "Encoder CVE-2018-10393 fix is absent in psy.c. Upgrade to 1.3.7; assess encoder input conditions.",
|
||||
"assessment": "fixed",
|
||||
"notes": "All imported include/ and lib/ files match the 1.3.7 release; standalone tool sources stay excluded. Encoder low-sample-rate and invalid-setup regression test added.",
|
||||
"source_revision": "1116575774d174fc1e79fbb0e1458319be0af548",
|
||||
"source_revision_kind": "last eepp commit touching directory",
|
||||
"source_fingerprint_sha256": "a070982556e996e0cb19ed9d3e1723700779db6e278e29cb9ae4ed1ef5bd7e35"
|
||||
"source_fingerprint_sha256": "c12284fba99ae046b5113ca8e1b3ae385e1cd10061008b60be7d2d911530619d",
|
||||
"baseline_source_fingerprint_sha256": "a070982556e996e0cb19ed9d3e1723700779db6e278e29cb9ae4ed1ef5bd7e35",
|
||||
"upstream_tag": "v1.3.7",
|
||||
"retained_patches": [
|
||||
".clang-format"
|
||||
],
|
||||
"resolved_advisories": [
|
||||
"CVE-2018-10393",
|
||||
"CVE-2018-10392"
|
||||
],
|
||||
"working_tree_modified": true,
|
||||
"updated_at": "2026-10-25",
|
||||
"upstream_archive_sha256": "b33cc4934322bcbf6efcbacf49e3ca01aadbea4114ec9589d1b1e9d20f72954b"
|
||||
},
|
||||
{
|
||||
"name": "libwebp",
|
||||
@@ -341,26 +353,72 @@
|
||||
{
|
||||
"name": "libzip",
|
||||
"path": "src/thirdparty/libzip",
|
||||
"version": "0.10 + local hardening",
|
||||
"version": "1.12.1",
|
||||
"version_evidence": "src/thirdparty/libzip/zipconf.h",
|
||||
"upstream": "https://libzip.org/",
|
||||
"assessment": "review",
|
||||
"notes": "CVE-2012-1162 guarded locally. Old offset/size arithmetic and allocation checks still need work; modern libzip migration needs API/build review.",
|
||||
"assessment": "fixed",
|
||||
"notes": "Replaced the 0.10 fork with upstream lib/ sources; hand-written config.h/zipconf.h, generated zip_err_str.c. Old offset/size and allocation arithmetic is gone. Only zip.h's zipconf.h include is patched. The fork's ZIP_LIMIT_METADATA bounded open and the VFS ZIP limits were removed at the maintainer's direction. bzip2/xz/zstd/WinZip AES not built.",
|
||||
"source_revision": "a94a6f5f7ed694cabe344c6227357db6e94cfecd",
|
||||
"source_revision_kind": "last eepp commit touching directory",
|
||||
"source_fingerprint_sha256": "fe27084b4570a8471912c9244187f0c508e37565b3662a93cb1ca9d16a3612e8"
|
||||
"source_fingerprint_sha256": "29220266a16ee1fd0c4663f10bc321876ea1bca5f1d3a1cb50457c81e2df4559",
|
||||
"baseline_source_fingerprint_sha256": "fe27084b4570a8471912c9244187f0c508e37565b3662a93cb1ca9d16a3612e8",
|
||||
"upstream_tag": "v1.12.1",
|
||||
"retained_patches": [
|
||||
"zip.h",
|
||||
"zip_err_str.c",
|
||||
"config.h",
|
||||
"zipconf.h",
|
||||
"README.eepp.md",
|
||||
".clang-format"
|
||||
],
|
||||
"resolved_advisories": [
|
||||
"CVE-2012-1163",
|
||||
"CVE-2015-2331",
|
||||
"CVE-2017-12858",
|
||||
"CVE-2017-14107"
|
||||
],
|
||||
"working_tree_modified": true,
|
||||
"updated_at": "2026-10-25",
|
||||
"upstream_archive_sha256": "c40062022a1963c80573d48f6070792297cecd7c6bffe3aefcac0d8b9bee8913"
|
||||
},
|
||||
{
|
||||
"name": "mbedtls",
|
||||
"path": "src/thirdparty/mbedtls",
|
||||
"version": "3.6.0",
|
||||
"version": "3.6.7",
|
||||
"version_evidence": "src/thirdparty/mbedtls/include/mbedtls/build_info.h",
|
||||
"upstream": "https://github.com/Mbed-TLS/mbedtls",
|
||||
"assessment": "upgrade",
|
||||
"notes": "Upgrade within LTS to 3.6.7. Multiple advisories have API, compiler, protocol-role or deployment preconditions; no blanket remote-RCE claim for eepp TLS client.",
|
||||
"assessment": "fixed",
|
||||
"notes": "Library sources and headers match the 3.6.7 LTS release except include/mbedtls/mbedtls_config.h, whose eepp block is retained (PSA crypto, TLS 1.3, LMS and weak key exchanges disabled). Restored PSA sources compile to empty objects. TLS client trust/hostname test added.",
|
||||
"source_revision": "1576fa7eb1c1664135326850c0fcf9f4d694d0b9",
|
||||
"source_revision_kind": "last eepp commit touching directory",
|
||||
"source_fingerprint_sha256": "d4ef114cebeaf7a0ebada30fc7cfb6469cb3b32fdee3bff1f064d20141aab764"
|
||||
"source_fingerprint_sha256": "54c9b453ec73b73dfd413a07a457e0383c1ced78d20919f2e0f0d5ff51d4ca14",
|
||||
"baseline_source_fingerprint_sha256": "d4ef114cebeaf7a0ebada30fc7cfb6469cb3b32fdee3bff1f064d20141aab764",
|
||||
"upstream_tag": "mbedtls-3.6.7",
|
||||
"retained_patches": [
|
||||
"include/mbedtls/mbedtls_config.h",
|
||||
".clang-format"
|
||||
],
|
||||
"resolved_advisories": [
|
||||
"CVE-2024-45158",
|
||||
"CVE-2024-45159",
|
||||
"CVE-2024-49195",
|
||||
"CVE-2025-47917",
|
||||
"CVE-2025-48965",
|
||||
"CVE-2025-52496",
|
||||
"CVE-2026-25833",
|
||||
"CVE-2026-25835",
|
||||
"CVE-2026-34872",
|
||||
"CVE-2026-34873",
|
||||
"CVE-2026-34874",
|
||||
"CVE-2026-34875",
|
||||
"CVE-2026-34876",
|
||||
"CVE-2026-49300",
|
||||
"CVE-2026-50579",
|
||||
"CVE-2026-50580"
|
||||
],
|
||||
"working_tree_modified": true,
|
||||
"updated_at": "2026-10-25",
|
||||
"upstream_archive_sha256": "a7e8bcbec0e6f761b4af24f25677626b35f762f68eef79c08677a363212d11f6"
|
||||
},
|
||||
{
|
||||
"name": "md4c",
|
||||
@@ -401,14 +459,23 @@
|
||||
{
|
||||
"name": "monocypher",
|
||||
"path": "src/thirdparty/monocypher",
|
||||
"version": "4.0.2",
|
||||
"version": "4.0.3",
|
||||
"version_evidence": "src/thirdparty/monocypher/monocypher.h",
|
||||
"upstream": "https://monocypher.org/",
|
||||
"assessment": "maintenance",
|
||||
"notes": "4.0.3 fixes compiler-dependent Ed25519/EdDSA timing leakage. Used for libssh2 Ed25519 signing and X25519; no high CVE assigned to this issue found.",
|
||||
"assessment": "fixed",
|
||||
"notes": "monocypher.{c,h} and monocypher-ed25519.{c,h} match the 4.0.3 release, fixing the compiler-dependent Ed25519 signing timing leak used by the SSH backend.",
|
||||
"source_revision": "88675a7c84b0785295d55a96477a8c046cc9f34c",
|
||||
"source_revision_kind": "last eepp commit touching directory",
|
||||
"source_fingerprint_sha256": "0061c4d2f475444b87289c62c9821de09c13b683f6b3cf01a594f9cd8fc80d6e"
|
||||
"source_fingerprint_sha256": "6b1c995a9faa61f3f3222b1c2636a26b40e2ae6ced9208db54ba2d215568eb7c",
|
||||
"baseline_source_fingerprint_sha256": "0061c4d2f475444b87289c62c9821de09c13b683f6b3cf01a594f9cd8fc80d6e",
|
||||
"upstream_tag": "4.0.3",
|
||||
"retained_patches": [
|
||||
"README.eepp.md",
|
||||
".clang-format"
|
||||
],
|
||||
"working_tree_modified": true,
|
||||
"updated_at": "2026-10-25",
|
||||
"upstream_archive_sha256": "8cc9bc341a66249016db9bd70e9142d8d0aef9945973744b1ac05dbc55d8ee66"
|
||||
},
|
||||
{
|
||||
"name": "nanosvg",
|
||||
@@ -522,14 +589,26 @@
|
||||
{
|
||||
"name": "simdutf",
|
||||
"path": "src/thirdparty/simdutf",
|
||||
"version": "9.2.0",
|
||||
"version": "9.2.1",
|
||||
"version_evidence": "src/thirdparty/simdutf/simdutf.h",
|
||||
"upstream": "https://github.com/simdutf/simdutf",
|
||||
"assessment": "maintenance",
|
||||
"notes": "High GHSA-pw55-7mm7-cvhh is fixed in 9.2.1, but eepp does not call the affected Base64 APIs. Recommend >=9.2.1.",
|
||||
"assessment": "fixed",
|
||||
"notes": "Regenerated 9.2.1 amalgamation limited to UTF-8 and UTF-32, the same feature set as before; Base64 and Latin-1 are not compiled, so GHSA-pw55-7mm7-cvhh was not reachable.",
|
||||
"source_revision": "e2174aa04482cace8d416ac2bc960e9e9b724f54",
|
||||
"source_revision_kind": "last eepp commit touching directory",
|
||||
"source_fingerprint_sha256": "485a6b6e2b917237612bc99005cc0fba40504b8e5931a8aa91db6d2a3a126b49"
|
||||
"source_fingerprint_sha256": "3bb0cd4013f8067968c4b40d43d0d915b3858f1c7c992db036679eefca8c7b95",
|
||||
"baseline_source_fingerprint_sha256": "485a6b6e2b917237612bc99005cc0fba40504b8e5931a8aa91db6d2a3a126b49",
|
||||
"upstream_tag": "v9.2.1",
|
||||
"retained_patches": [
|
||||
"simdutf.h",
|
||||
"simdutf.cpp",
|
||||
".clang-format"
|
||||
],
|
||||
"resolved_advisories": [
|
||||
"GHSA-pw55-7mm7-cvhh"
|
||||
],
|
||||
"working_tree_modified": true,
|
||||
"updated_at": "2026-10-25"
|
||||
},
|
||||
{
|
||||
"name": "SOIL2",
|
||||
|
||||
@@ -8,9 +8,8 @@ struct zip;
|
||||
|
||||
namespace EE { namespace System {
|
||||
|
||||
/** ZIP archive reader/writer and optional resource pack. Use Zip(false) and
|
||||
* OpenMode::ReadOnlyBounded for untrusted standalone browsing. Entry streams borrow the archive
|
||||
* and must be destroyed before it.
|
||||
/** ZIP archive reader/writer and optional resource pack. Use Zip(false) and OpenMode::ReadOnly
|
||||
* for standalone browsing. Entry streams borrow the archive and must be destroyed before it.
|
||||
* Serialize access to an archive and its streams when sharing them between threads. */
|
||||
class EE_API Zip : public Pack {
|
||||
public:
|
||||
@@ -23,13 +22,7 @@ class EE_API Zip : public Pack {
|
||||
Uint32 crc{ 0 };
|
||||
};
|
||||
|
||||
enum class OpenMode : Uint8 {
|
||||
ReadOnly,
|
||||
ReadWrite,
|
||||
/** Read-only with a 64 MiB metadata allocation bound, checked before decoding the
|
||||
* central directory. Suitable for untrusted archive browsing. */
|
||||
ReadOnlyBounded
|
||||
};
|
||||
enum class OpenMode : Uint8 { ReadOnly, ReadWrite };
|
||||
|
||||
enum class Error : Uint8 {
|
||||
None,
|
||||
@@ -54,15 +47,11 @@ class EE_API Zip : public Pack {
|
||||
* use create() explicitly. */
|
||||
bool open( const std::string& path );
|
||||
|
||||
/** ReadOnly supports Unicode native paths and cannot modify or create an archive. */
|
||||
/** Paths are UTF-8 on every platform. Read-only modes cannot modify or create an archive. */
|
||||
bool open( const std::string& path, OpenMode mode );
|
||||
|
||||
Uint64 entryCount() const;
|
||||
|
||||
/** Conservative decoded central-directory memory estimate, including allocation slack.
|
||||
* This excludes decompressed file data and indexes built by the caller. */
|
||||
Uint64 metadataSize() const;
|
||||
|
||||
bool entry( Uint64 index, Entry& result );
|
||||
|
||||
/** Opens an entry without extracting it into memory. Backward seeks replay the prefix;
|
||||
@@ -138,8 +127,6 @@ class EE_API Zip : public Pack {
|
||||
struct zip* getZip();
|
||||
|
||||
private:
|
||||
bool openReadOnly( const std::string& path );
|
||||
|
||||
void setError( int code, int systemCode = 0 );
|
||||
|
||||
bool writable();
|
||||
|
||||
+26
-9
@@ -163,6 +163,7 @@ if _OPTIONS.platform then
|
||||
premake.gcc.platforms['Native'] = premake.gcc.platforms[_OPTIONS.platform]
|
||||
end
|
||||
|
||||
newoption { trigger = "with-security-fuzz", description = "Build the standalone NanoSVG libFuzzer target with ASan and UBSan (Clang required)." }
|
||||
newoption { trigger = "with-openssl", description = "Enables OpenSSL support ( and disables mbedtls backend )." }
|
||||
newoption { trigger = "with-dynamic-freetype", description = "Dynamic link against freetype." }
|
||||
newoption { trigger = "with-static-eepp", description = "Force to build the demos and tests with eepp compiled statically" }
|
||||
@@ -393,7 +394,6 @@ function build_base_configuration( package_name )
|
||||
end
|
||||
|
||||
if is_vs() then
|
||||
includedirs { "src/thirdparty/libzip/vs" }
|
||||
buildoptions { "/utf-8" }
|
||||
end
|
||||
|
||||
@@ -729,11 +729,11 @@ function generate_os_links()
|
||||
table.insert( os_links, "dl" )
|
||||
end
|
||||
elseif os.is_real("windows") then
|
||||
multiple_insert( os_links, { "opengl32", "glu32", "gdi32", "ws2_32", "winmm", "ole32", "oleaut32", "uuid", "shell32", "shlwapi", "dwrite", "uiautomationcore", "comctl32" } )
|
||||
multiple_insert( os_links, { "opengl32", "glu32", "gdi32", "ws2_32", "winmm", "ole32", "oleaut32", "uuid", "shell32", "shlwapi", "dwrite", "uiautomationcore", "comctl32", "advapi32" } )
|
||||
elseif os.is_real("mingw32") then
|
||||
multiple_insert( os_links, { "opengl32", "glu32", "gdi32", "ws2_32", "winmm", "ole32", "oleaut32", "uuid", "shell32", "shlwapi", "dwrite", "uiautomationcore", "comctl32" } )
|
||||
multiple_insert( os_links, { "opengl32", "glu32", "gdi32", "ws2_32", "winmm", "ole32", "oleaut32", "uuid", "shell32", "shlwapi", "dwrite", "uiautomationcore", "comctl32", "advapi32" } )
|
||||
elseif os.is_real("mingw64") then
|
||||
multiple_insert( os_links, { "opengl32", "glu32", "gdi32", "ws2_32", "winmm", "ole32", "oleaut32", "uuid", "shell32", "shlwapi", "dwrite", "uiautomationcore", "comctl32" } )
|
||||
multiple_insert( os_links, { "opengl32", "glu32", "gdi32", "ws2_32", "winmm", "ole32", "oleaut32", "uuid", "shell32", "shlwapi", "dwrite", "uiautomationcore", "comctl32", "advapi32" } )
|
||||
elseif os.is_real("macosx") then
|
||||
multiple_insert( os_links, { "eepp-macos-helper-static", "Cocoa.framework", "OpenGL.framework", "CoreFoundation.framework", "CoreServices.framework", "CoreText.framework" } )
|
||||
elseif os.is_real("bsd") then
|
||||
@@ -1221,10 +1221,6 @@ function build_eepp( build_name )
|
||||
|
||||
add_static_links()
|
||||
|
||||
if is_vs() then
|
||||
includedirs { "src/thirdparty/libzip/vs" }
|
||||
end
|
||||
|
||||
if not is_vs() then
|
||||
buildoptions{ "-std=c++20" }
|
||||
else
|
||||
@@ -1388,7 +1384,12 @@ solution "eepp"
|
||||
language "C"
|
||||
set_targetdir("libs/" .. os.get_real() .. "/thirdparty/")
|
||||
files { "src/thirdparty/libzip/*.c" }
|
||||
includedirs { "src/thirdparty/zlib" }
|
||||
if os.is_real("windows") or os.is_real("mingw32") or os.is_real("mingw64") then
|
||||
files { "src/thirdparty/libzip/win32/*.c" }
|
||||
else
|
||||
files { "src/thirdparty/libzip/posix/*.c" }
|
||||
end
|
||||
includedirs { "src/thirdparty/libzip", "src/thirdparty/zlib" }
|
||||
build_base_configuration( "libzip" )
|
||||
|
||||
project "libpng-static"
|
||||
@@ -2389,6 +2390,22 @@ solution "eepp"
|
||||
configuration {}
|
||||
end
|
||||
|
||||
-- Self-contained target instruments the vendored NanoSVG fork without reusing production archives.
|
||||
if _OPTIONS["with-security-fuzz"] then
|
||||
project "eepp-fuzz-nanosvg"
|
||||
kind "ConsoleApp"
|
||||
language "C++"
|
||||
configuration {}
|
||||
targetdir "bin/security"
|
||||
targetname "eepp-fuzz-nanosvg"
|
||||
objdir "obj/security-fuzz/nanosvg"
|
||||
includedirs { "src/thirdparty" }
|
||||
files { "src/tests/security/fuzz_nanosvg.cpp" }
|
||||
buildoptions { "-g", "-O1", "-fno-omit-frame-pointer",
|
||||
"-fsanitize=fuzzer,address,undefined", "-fno-sanitize-recover=all" }
|
||||
linkoptions { "-fsanitize=fuzzer,address,undefined" }
|
||||
end
|
||||
|
||||
if os.isfile("external_projects.lua") then
|
||||
dofile("external_projects.lua")
|
||||
end
|
||||
|
||||
+25
-5
@@ -19,6 +19,7 @@ if true or premake_is_previous_to_beta8() then
|
||||
require "premake.premake-ninja.ninja"
|
||||
end
|
||||
|
||||
newoption { trigger = "with-security-fuzz", description = "Build the standalone NanoSVG libFuzzer target with ASan and UBSan (Clang required)." }
|
||||
newoption { trigger = "with-openssl", description = "Enables OpenSSL support ( and disables mbedtls backend )." }
|
||||
newoption { trigger = "with-dynamic-freetype", description = "Dynamic link against freetype." }
|
||||
newoption { trigger = "with-static-eepp", description = "Force to build the demos and tests with eepp compiled statically" }
|
||||
@@ -402,7 +403,6 @@ function build_base_configuration( package_name )
|
||||
buildoptions { "-Wall" }
|
||||
|
||||
filter "action:vs*"
|
||||
incdirs { "src/thirdparty/libzip/vs" }
|
||||
buildoptions { "/utf-8" }
|
||||
|
||||
filter "system:emscripten"
|
||||
@@ -685,9 +685,9 @@ function generate_os_links()
|
||||
table.insert( os_links, "dl" )
|
||||
end
|
||||
elseif os.istarget("windows") then
|
||||
multiple_insert( os_links, { "opengl32", "glu32", "gdi32", "ws2_32", "winmm", "ole32", "oleaut32", "uuid", "shell32", "shlwapi", "dwrite", "uiautomationcore", "comctl32" } )
|
||||
multiple_insert( os_links, { "opengl32", "glu32", "gdi32", "ws2_32", "winmm", "ole32", "oleaut32", "uuid", "shell32", "shlwapi", "dwrite", "uiautomationcore", "comctl32", "advapi32" } )
|
||||
elseif os.istarget("mingw32") then
|
||||
multiple_insert( os_links, { "opengl32", "glu32", "gdi32", "ws2_32", "winmm", "ole32", "oleaut32", "uuid", "shell32", "shlwapi", "dwrite", "uiautomationcore", "comctl32" } )
|
||||
multiple_insert( os_links, { "opengl32", "glu32", "gdi32", "ws2_32", "winmm", "ole32", "oleaut32", "uuid", "shell32", "shlwapi", "dwrite", "uiautomationcore", "comctl32", "advapi32" } )
|
||||
elseif os.istarget("macosx") then
|
||||
multiple_insert( os_links, { "eepp-macos-helper-static", "Cocoa.framework", "OpenGL.framework", "CoreFoundation.framework", "CoreServices.framework", "CoreText.framework" } )
|
||||
elseif os.istarget("bsd") then
|
||||
@@ -1220,7 +1220,6 @@ function build_eepp( build_name )
|
||||
incdirs { get_sdl_arm64_cross_tools_path() .. "/include/" }
|
||||
|
||||
filter "action:vs*"
|
||||
incdirs { "src/thirdparty/libzip/vs" }
|
||||
buildoptions{ "/std:c++20", "/utf-8", "/bigobj", "/Zc:preprocessor" }
|
||||
|
||||
filter { "action:export-compile-commands", "system:macosx" }
|
||||
@@ -1419,9 +1418,14 @@ workspace "eepp"
|
||||
kind "StaticLib"
|
||||
language "C"
|
||||
files { "src/thirdparty/libzip/*.c" }
|
||||
incdirs { "src/thirdparty/zlib" }
|
||||
incdirs { "src/thirdparty/libzip", "src/thirdparty/zlib" }
|
||||
build_base_configuration( "libzip" )
|
||||
target_dir_thirdparty()
|
||||
filter "system:windows"
|
||||
files { "src/thirdparty/libzip/win32/*.c" }
|
||||
filter "system:not windows"
|
||||
files { "src/thirdparty/libzip/posix/*.c" }
|
||||
filter {}
|
||||
|
||||
project "libpng-static"
|
||||
kind "StaticLib"
|
||||
@@ -2397,6 +2401,22 @@ workspace "eepp"
|
||||
filter {}
|
||||
end
|
||||
|
||||
-- Self-contained target instruments the vendored NanoSVG fork without reusing production archives.
|
||||
if _OPTIONS["with-security-fuzz"] then
|
||||
project "eepp-fuzz-nanosvg"
|
||||
kind "ConsoleApp"
|
||||
language "C++"
|
||||
filter {}
|
||||
targetdir "bin/security"
|
||||
targetname "eepp-fuzz-nanosvg"
|
||||
objdir "obj/security-fuzz/nanosvg"
|
||||
incdirs { "src/thirdparty" }
|
||||
files { "src/tests/security/fuzz_nanosvg.cpp" }
|
||||
buildoptions { "-g", "-O1", "-fno-omit-frame-pointer",
|
||||
"-fsanitize=fuzzer,address,undefined", "-fno-sanitize-recover=all" }
|
||||
linkoptions { "-fsanitize=fuzzer,address,undefined" }
|
||||
end
|
||||
|
||||
if os.isfile("external_projects.lua") then
|
||||
dofile("external_projects.lua")
|
||||
end
|
||||
|
||||
@@ -76,7 +76,6 @@ LOCAL_CFLAGS := $(EEPP_C_FLAGS)
|
||||
CODE_SRCS := \
|
||||
../thirdparty/SOIL2/src/SOIL2/*.c \
|
||||
../thirdparty/zlib/*.c \
|
||||
../thirdparty/libzip/*.c \
|
||||
../thirdparty/jpeg-compressor/*.cpp \
|
||||
../thirdparty/imageresampler/*.cpp \
|
||||
../thirdparty/pugixml/*.cpp \
|
||||
@@ -116,7 +115,7 @@ LOCAL_C_INCLUDES := $(EEPP_C_INCLUDES)
|
||||
|
||||
LOCAL_SRC_FILES := $(foreach F, $(CODE_SRCS), $(addprefix $(dir $(F)),$(notdir $(wildcard $(LOCAL_PATH)/$(F)))))
|
||||
|
||||
LOCAL_STATIC_LIBRARIES := simdutf freetype libpng libwebp md4c pcre2 oniguruma harfbuzz sheenbidi gumbo-parser brotli
|
||||
LOCAL_STATIC_LIBRARIES := simdutf freetype libpng libzip libwebp md4c pcre2 oniguruma harfbuzz sheenbidi gumbo-parser brotli
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := SDL2
|
||||
|
||||
@@ -203,6 +202,26 @@ LOCAL_SRC_FILES := $(foreach F, $(LIBPNG_SRCS), $(addprefix $(dir $(F)),$(notd
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
#*************** LIBPNG ***************
|
||||
|
||||
#*************** LIBZIP ***************
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_PATH := $(EEPP_THIRD_PARTY_PATH)
|
||||
|
||||
LOCAL_MODULE := libzip
|
||||
|
||||
LIBZIP_SRCS := \
|
||||
libzip/*.c \
|
||||
libzip/posix/*.c
|
||||
|
||||
# Kept out of the eepp module: libzip's config.h and compat.h must not shadow other headers.
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/libzip/ $(LOCAL_PATH)/zlib/
|
||||
LOCAL_CFLAGS := -Os
|
||||
|
||||
LOCAL_SRC_FILES := $(foreach F, $(LIBZIP_SRCS), $(addprefix $(dir $(F)),$(notdir $(wildcard $(LOCAL_PATH)/$(F)))))
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
#*************** LIBZIP ***************
|
||||
|
||||
#*************** LIBWEBP ***************
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
|
||||
+16
-2
@@ -1,13 +1,24 @@
|
||||
#!/bin/sh
|
||||
cd $(dirname "$0")
|
||||
|
||||
CRYPTO_OPTION=
|
||||
FUZZ_OPTION=
|
||||
for arg do
|
||||
shift
|
||||
case "$arg" in
|
||||
--with-openssl) CRYPTO_OPTION=--with-openssl ;;
|
||||
--with-security-fuzz) FUZZ_OPTION=--with-security-fuzz ;;
|
||||
*) set -- "$@" "$arg" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
USE_ARCH=
|
||||
if command -v premake4 &> /dev/null
|
||||
then
|
||||
premake4 --file=../../premake4.lua --use-frameworks --disable-static-build gmake
|
||||
premake4 --file=../../premake4.lua --use-frameworks --disable-static-build ${CRYPTO_OPTION:+$CRYPTO_OPTION} ${FUZZ_OPTION:+$FUZZ_OPTION} gmake || exit 1
|
||||
elif command -v premake5 &> /dev/null
|
||||
then
|
||||
premake5 --file=../../premake5.lua --use-frameworks --disable-static-build gmake
|
||||
premake5 --file=../../premake5.lua --use-frameworks --disable-static-build ${CRYPTO_OPTION:+$CRYPTO_OPTION} ${FUZZ_OPTION:+$FUZZ_OPTION} gmake || exit 1
|
||||
USE_ARCH=arm64/
|
||||
else
|
||||
echo "Neither premake5 nor premake4 is available. Please install one."
|
||||
@@ -25,4 +36,7 @@ if ! [ "$JOBS" -gt 0 ] 2>/dev/null; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -n "$FUZZ_OPTION" ]; then
|
||||
set -- "$@" "CC=${CC:-clang}" "CXX=${CXX:-clang++}"
|
||||
fi
|
||||
make -j"$JOBS" "$@"
|
||||
|
||||
@@ -3,6 +3,8 @@ cd $(dirname "$0")
|
||||
|
||||
BACKEND=SDL2
|
||||
DEBUG_SYMBOLS=
|
||||
FUZZ_OPTION=
|
||||
CRYPTO_OPTION=
|
||||
for arg do
|
||||
shift
|
||||
case "$arg" in
|
||||
@@ -10,6 +12,8 @@ for arg do
|
||||
--backend=SDL3|--backend=sdl3) BACKEND=SDL3 ;;
|
||||
--backend=*) echo "Unsupported backend: ${arg#*=}" >&2; exit 1 ;;
|
||||
--with-debug-symbols) DEBUG_SYMBOLS=--with-debug-symbols ;;
|
||||
--with-openssl) CRYPTO_OPTION=--with-openssl ;;
|
||||
--with-security-fuzz) FUZZ_OPTION=--with-security-fuzz ;;
|
||||
*) set -- "$@" "$arg" ;;
|
||||
esac
|
||||
done
|
||||
@@ -17,10 +21,10 @@ done
|
||||
USE_ARCH=
|
||||
if command -v premake4 &> /dev/null
|
||||
then
|
||||
premake4 --file=../../premake4.lua --disable-static-build --with-backend="$BACKEND" ${DEBUG_SYMBOLS:+$DEBUG_SYMBOLS} gmake || exit 1
|
||||
premake4 --file=../../premake4.lua --disable-static-build --with-backend="$BACKEND" ${DEBUG_SYMBOLS:+$DEBUG_SYMBOLS} ${CRYPTO_OPTION:+$CRYPTO_OPTION} ${FUZZ_OPTION:+$FUZZ_OPTION} gmake || exit 1
|
||||
elif command -v premake5 &> /dev/null
|
||||
then
|
||||
premake5 --file=../../premake5.lua --disable-static-build --with-backend="$BACKEND" ${DEBUG_SYMBOLS:+$DEBUG_SYMBOLS} gmake || exit 1
|
||||
premake5 --file=../../premake5.lua --disable-static-build --with-backend="$BACKEND" ${DEBUG_SYMBOLS:+$DEBUG_SYMBOLS} ${CRYPTO_OPTION:+$CRYPTO_OPTION} ${FUZZ_OPTION:+$FUZZ_OPTION} gmake || exit 1
|
||||
USE_ARCH=arm64
|
||||
else
|
||||
echo "Neither premake5 nor premake4 is available. Please install one."
|
||||
@@ -38,4 +42,8 @@ if ! [ "$JOBS" -gt 0 ] 2>/dev/null; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -n "$FUZZ_OPTION" ]; then
|
||||
# Apple Clang does not ship libFuzzer; callers may select an LLVM installation.
|
||||
set -- "$@" "CC=${CC:-clang}" "CXX=${CXX:-clang++}"
|
||||
fi
|
||||
make -j"$JOBS" "$@"
|
||||
|
||||
+25
-79
@@ -8,12 +8,6 @@
|
||||
#include <libzip/zip.h>
|
||||
#include <limits>
|
||||
|
||||
#if EE_PLATFORM == EE_PLATFORM_WIN
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
namespace EE { namespace System {
|
||||
|
||||
Zip* Zip::New() {
|
||||
@@ -56,16 +50,13 @@ bool Zip::open( const std::string& path, OpenMode mode ) {
|
||||
mError = Error::None;
|
||||
mErrorMessage.clear();
|
||||
mOpenMode = mode;
|
||||
if ( mode != OpenMode::ReadWrite ) {
|
||||
if ( !openReadOnly( path ) )
|
||||
return false;
|
||||
} else {
|
||||
int error = ZIP_ER_OK;
|
||||
mZip = zip_open( path.c_str(), 0, &error );
|
||||
if ( !mZip ) {
|
||||
setError( error, errno );
|
||||
return false;
|
||||
}
|
||||
// libzip opens UTF-8 paths as wide paths on Windows.
|
||||
int error = ZIP_ER_OK;
|
||||
mZip = zip_open( path.c_str(), mode == OpenMode::ReadOnly ? ZIP_RDONLY : 0, &error );
|
||||
if ( !mZip ) {
|
||||
// zip_open() reports the system error or inconsistency detail through errno.
|
||||
setError( error, errno );
|
||||
return false;
|
||||
}
|
||||
mZipPath = path;
|
||||
mIsOpen = true;
|
||||
@@ -76,14 +67,11 @@ bool Zip::open( const std::string& path, OpenMode mode ) {
|
||||
bool Zip::close() {
|
||||
if ( mZip ) {
|
||||
// zip_close() writes the pending changes. When that fails the archive is left allocated
|
||||
// (and unchanged on disk): release it and report the failure.
|
||||
// (and unchanged on disk): release it without writing and report the failure.
|
||||
bool written = zip_close( mZip ) == 0;
|
||||
|
||||
if ( !written ) {
|
||||
// Without pending changes zip_close() only frees the archive.
|
||||
zip_unchange_all( mZip );
|
||||
zip_close( mZip );
|
||||
}
|
||||
if ( !written )
|
||||
zip_discard( mZip );
|
||||
|
||||
mIsOpen = false;
|
||||
|
||||
@@ -115,8 +103,7 @@ bool Zip::addFile( const Uint8* data, const Uint32& dataSize, const std::string&
|
||||
struct zip_source* zs = zip_source_buffer( mZip, (const void*)data, dataSize, 0 );
|
||||
|
||||
if ( NULL != zs ) {
|
||||
Int32 Result = (Int32)zip_add( mZip, inpack.c_str(), zs );
|
||||
if ( Result < 0 ) {
|
||||
if ( zip_file_add( mZip, inpack.c_str(), zs, ZIP_FL_ENC_GUESS ) < 0 ) {
|
||||
zip_source_free( zs );
|
||||
return false;
|
||||
}
|
||||
@@ -228,7 +215,7 @@ bool Zip::extractStream( IOStream& stream, Uint8* data, size_t size ) {
|
||||
|
||||
Int32 Zip::exists( const std::string& path ) {
|
||||
if ( isOpen() )
|
||||
return zip_name_locate( mZip, path.c_str(), 0 );
|
||||
return static_cast<Int32>( zip_name_locate( mZip, path.c_str(), 0 ) );
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -262,54 +249,11 @@ zip* Zip::getZip() {
|
||||
return mZip;
|
||||
}
|
||||
|
||||
bool Zip::openReadOnly( const std::string& path ) {
|
||||
// fopenUtf8 preserves Windows Unicode paths. zip_fdopen consumes a duplicated descriptor,
|
||||
// so the FILE owned here can always be closed normally.
|
||||
FILE* file = FileSystem::fopenUtf8( path, "rb" );
|
||||
if ( !file ) {
|
||||
setError( errno == ENOENT ? ZIP_ER_NOENT : ZIP_ER_OPEN, errno );
|
||||
return false;
|
||||
}
|
||||
#if EE_PLATFORM == EE_PLATFORM_WIN
|
||||
int descriptor = _dup( _fileno( file ) );
|
||||
#else
|
||||
int descriptor = dup( fileno( file ) );
|
||||
#endif
|
||||
const int duplicateError = errno;
|
||||
std::fclose( file );
|
||||
if ( descriptor < 0 ) {
|
||||
setError( ZIP_ER_OPEN, duplicateError );
|
||||
return false;
|
||||
}
|
||||
int error = ZIP_ER_OK;
|
||||
mZip = zip_fdopen( descriptor, mOpenMode == OpenMode::ReadOnlyBounded ? ZIP_LIMIT_METADATA : 0,
|
||||
&error );
|
||||
if ( !mZip ) {
|
||||
// This vendored libzip consumes descriptor after fdopen succeeds. Only its two early
|
||||
// ZIP_ER_OPEN failures (dup/fdopen) leave it for the caller to close.
|
||||
const int systemError = errno;
|
||||
if ( error == ZIP_ER_OPEN ) {
|
||||
#if EE_PLATFORM == EE_PLATFORM_WIN
|
||||
_close( descriptor );
|
||||
#else
|
||||
::close( descriptor );
|
||||
#endif
|
||||
}
|
||||
setError( error, systemError );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Uint64 Zip::entryCount() const {
|
||||
if ( !mZip )
|
||||
return 0;
|
||||
const auto count = zip_get_num_entries( mZip, 0 );
|
||||
return count == std::numeric_limits<Uint64>::max() ? 0 : count;
|
||||
}
|
||||
|
||||
Uint64 Zip::metadataSize() const {
|
||||
return mZip ? zip_get_metadata_size( mZip ) : 0;
|
||||
return count < 0 ? 0 : static_cast<Uint64>( count );
|
||||
}
|
||||
|
||||
bool Zip::entry( Uint64 index, Entry& result ) {
|
||||
@@ -339,32 +283,34 @@ std::unique_ptr<IOStream> Zip::openStream( Uint64 index ) {
|
||||
}
|
||||
auto stream = std::make_unique<IOStreamZip>( this, index );
|
||||
if ( !stream->isOpen() ) {
|
||||
int code = 0;
|
||||
int systemCode = 0;
|
||||
zip_error_get( mZip, &code, &systemCode );
|
||||
setError( code, systemCode );
|
||||
const zip_error_t* error = zip_get_error( mZip );
|
||||
setError( zip_error_code_zip( error ), zip_error_code_system( error ) );
|
||||
return {};
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
void Zip::setError( int code, int systemCode ) {
|
||||
zip_error_t error;
|
||||
zip_error_init( &error );
|
||||
zip_error_set( &error, code, systemCode );
|
||||
if ( code == ZIP_ER_NOENT )
|
||||
mError = Error::NotFound;
|
||||
else if ( zip_error_get_sys_type( code ) == ZIP_ET_SYS &&
|
||||
else if ( zip_error_system_type( &error ) == ZIP_ET_SYS &&
|
||||
( systemCode == EACCES || systemCode == EPERM ) )
|
||||
mError = Error::PermissionDenied;
|
||||
else if ( code == ZIP_ER_NOZIP || code == ZIP_ER_INCONS || code == ZIP_ER_EOF ||
|
||||
code == ZIP_ER_METADATA )
|
||||
code == ZIP_ER_TRUNCATED_ZIP || code == ZIP_ER_COMPRESSED_DATA ||
|
||||
code == ZIP_ER_DATA_LENGTH )
|
||||
mError = Error::InvalidArchive;
|
||||
else if ( code == ZIP_ER_COMPNOTSUPP || code == ZIP_ER_MULTIDISK ||
|
||||
code == ZIP_ER_ENCRNOTSUPP || code == ZIP_ER_NOPASSWD || code == ZIP_ER_WRONGPASSWD )
|
||||
code == ZIP_ER_ENCRNOTSUPP || code == ZIP_ER_NOPASSWD || code == ZIP_ER_WRONGPASSWD ||
|
||||
code == ZIP_ER_OPNOTSUPP )
|
||||
mError = Error::Unsupported;
|
||||
else
|
||||
mError = Error::IO;
|
||||
char message[256];
|
||||
zip_error_to_str( message, sizeof( message ), code, systemCode );
|
||||
mErrorMessage = message;
|
||||
mErrorMessage = zip_error_strerror( &error );
|
||||
zip_error_fini( &error );
|
||||
}
|
||||
|
||||
bool Zip::writable() {
|
||||
|
||||
@@ -54,7 +54,8 @@ static const int image_width = 188;
|
||||
static const int image_height = 35;
|
||||
static const int image_row_length = 24;
|
||||
|
||||
static const char image_bitmap[] = {
|
||||
// Signed explicitly: the bitmap uses negative literals, and char is unsigned on AArch64 Linux.
|
||||
static const signed char image_bitmap[] = {
|
||||
15, -16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 7, -64, 15, 63, -32, -2, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, -64, 15, 127, -125, -1,
|
||||
|
||||
@@ -23,8 +23,6 @@ constexpr ProviderCapabilities
|
||||
static_cast<Uint32>( VFSCapability::Seek ) |
|
||||
static_cast<Uint32>( VFSCapability::CaseSensitive ) );
|
||||
constexpr Uint64 NoEntry = std::numeric_limits<Uint64>::max();
|
||||
constexpr size_t MaxEntries = 262144;
|
||||
constexpr size_t MaxMetadata = 64 * 1024 * 1024;
|
||||
|
||||
VFSError readOnly( const URI& uri ) {
|
||||
return VFSError( VFSErrorCode::ReadOnly, uri, "ZIP archives are read-only" );
|
||||
@@ -87,15 +85,10 @@ struct ZipArchive {
|
||||
|
||||
VFSResult<void> index( Zip& reader, const URI& uri, const CancellationToken& token ) {
|
||||
const auto count = reader.entryCount();
|
||||
if ( count > MaxEntries )
|
||||
return Err(
|
||||
VFSError( VFSErrorCode::InvalidOperation, uri, "ZIP has too many entries" ) );
|
||||
const Uint64 libraryMetadata = reader.metadataSize();
|
||||
if ( libraryMetadata > MaxMetadata ) {
|
||||
return Err(
|
||||
VFSError( VFSErrorCode::InvalidOperation, uri, "ZIP metadata budget exceeded" ) );
|
||||
}
|
||||
size_t budget = MaxMetadata - static_cast<size_t>( libraryMetadata );
|
||||
// libzip bounds the count by the central directory size. Implicit directories can add
|
||||
// nodes beyond it; reserving the explicit ones avoids repeated growth of large indexes.
|
||||
nodes.reserve( static_cast<size_t>( count ) + 1 );
|
||||
paths.reserve( static_cast<size_t>( count ) + 1 );
|
||||
nodes.push_back( { info( "/", true ), {}, NoEntry } );
|
||||
paths.emplace( "", 0 );
|
||||
Zip::Entry metadata;
|
||||
@@ -122,14 +115,6 @@ struct ZipArchive {
|
||||
auto found = paths.find( path );
|
||||
size_t node;
|
||||
if ( found == paths.end() ) {
|
||||
// Include the node/name, full path-map key, child index, hash buckets and
|
||||
// allocator/vector growth slack before retaining any of those allocations.
|
||||
const size_t cost = 2 * ( sizeof( ZipNode ) + path.size() + end - start + 128 );
|
||||
if ( nodes.size() >= MaxEntries || cost > budget ) {
|
||||
return Err( VFSError( VFSErrorCode::InvalidOperation, uri,
|
||||
"ZIP metadata budget exceeded" ) );
|
||||
}
|
||||
budget -= cost;
|
||||
node = nodes.size();
|
||||
paths.emplace( std::move( path ), node );
|
||||
nodes[parent].children.push_back( node );
|
||||
@@ -376,7 +361,7 @@ class ZipProviderImpl : public std::enable_shared_from_this<ZipProviderImpl> {
|
||||
std::string_view( reinterpret_cast<const char*>( revision.data() ), revision.size() ) );
|
||||
archive->route = scheduler->resolvedRouteFor( path, true );
|
||||
Zip reader( false );
|
||||
if ( !reader.open( path, Zip::OpenMode::ReadOnlyBounded ) )
|
||||
if ( !reader.open( path, Zip::OpenMode::ReadOnly ) )
|
||||
return Err( readerError( reader, uri ) );
|
||||
auto indexed = archive->index( reader, uri, token );
|
||||
if ( !indexed )
|
||||
@@ -498,7 +483,7 @@ VFSTask<FileHandle> ZipProvider::open( const URI& uri, const OpenOptions& option
|
||||
if ( info.info.type == FileType::Directory )
|
||||
return Err( VFSError( VFSErrorCode::IsDirectory, uri ) );
|
||||
auto reader = std::make_unique<Zip>( false );
|
||||
if ( !reader->open( archive->path, Zip::OpenMode::ReadOnlyBounded ) )
|
||||
if ( !reader->open( archive->path, Zip::OpenMode::ReadOnly ) )
|
||||
return Err( readerError( *reader, uri ) );
|
||||
auto current =
|
||||
LocalProvider::statSync( URI::fromFSPath( archive->path ), archive->path, true );
|
||||
|
||||
@@ -31,6 +31,8 @@ struct RemoteWatch {
|
||||
Uint32 retries{ 0 };
|
||||
Mode mode{ Mode::Establishing };
|
||||
bool established{ false };
|
||||
/** Agent channel refusals retried since the last confirmed watch. */
|
||||
Uint8 channelRetries{ 0 };
|
||||
};
|
||||
|
||||
class RemoteWatchBackendImpl;
|
||||
@@ -51,6 +53,9 @@ class AgentClient : public SSHChannelPump, public std::enable_shared_from_this<A
|
||||
|
||||
State state() const { return mState.load(); }
|
||||
|
||||
/** The server refused the exec channel itself, so the agent was never started. */
|
||||
bool channelRefused() const { return mChannelRefused.load(); }
|
||||
|
||||
const std::shared_ptr<SSHConnection>& connection() const { return mConnection; }
|
||||
|
||||
/** Opens the exec channel (serialized on the connection queue) and starts the handshake. */
|
||||
@@ -94,6 +99,7 @@ class AgentClient : public SSHChannelPump, public std::enable_shared_from_this<A
|
||||
std::vector<uint8_t> mOut;
|
||||
std::string mStderr;
|
||||
std::atomic<State> mState{ State::Starting };
|
||||
std::atomic<bool> mChannelRefused{ false };
|
||||
bool mHello{ false };
|
||||
bool mPumping{ false };
|
||||
};
|
||||
@@ -156,6 +162,12 @@ class RemoteWatchBackendImpl : public std::enable_shared_from_this<RemoteWatchBa
|
||||
|
||||
static constexpr Uint32 MaxReconnectDelaySeconds = 30;
|
||||
|
||||
/** A refused agent channel is retried this many times, doubling the delay, before that watch
|
||||
* polls. Abandoned watches free their channels once their agents exit, within milliseconds. */
|
||||
static constexpr Uint8 MaxChannelRetries = 3;
|
||||
|
||||
static constexpr std::chrono::milliseconds ChannelRetryDelay{ 25 };
|
||||
|
||||
RemoteWatchBackendImpl( std::shared_ptr<SFTPProviderImpl> provider, VirtualFileSystem& vfs,
|
||||
Time establishmentTimeout ) :
|
||||
mProvider( provider ),
|
||||
@@ -252,13 +264,17 @@ class RemoteWatchBackendImpl : public std::enable_shared_from_this<RemoteWatchBa
|
||||
void agentDead( const std::shared_ptr<AgentClient>& client, bool wasReady,
|
||||
const std::string& reason ) {
|
||||
std::vector<std::shared_ptr<RemoteWatch>> affected;
|
||||
const bool usable = client->connection()->isUsable();
|
||||
// A refused channel on a usable session (its session limit is full) says nothing about
|
||||
// whether the agent is installed.
|
||||
const bool refused = usable && client->channelRefused();
|
||||
{
|
||||
std::lock_guard<std::mutex> lock( mMutex );
|
||||
auto it = mAgents.find( client->key() );
|
||||
if ( it != mAgents.end() && it->second.agent == client ) {
|
||||
it->second.agent.reset();
|
||||
it->second.lastError = reason;
|
||||
if ( !wasReady && client->connection()->isUsable() ) {
|
||||
if ( !wasReady && usable && !refused ) {
|
||||
// The SSH session is fine but the agent never answered: not installed or
|
||||
// not runnable on that host.
|
||||
it->second.unavailableUntil = std::chrono::steady_clock::now() + UnavailableFor;
|
||||
@@ -271,9 +287,11 @@ class RemoteWatchBackendImpl : public std::enable_shared_from_this<RemoteWatchBa
|
||||
}
|
||||
}
|
||||
}
|
||||
bool agentMissing = !wasReady && client->connection()->isUsable();
|
||||
bool agentMissing = !wasReady && usable && !refused;
|
||||
for ( auto& watch : affected ) {
|
||||
if ( agentMissing ) {
|
||||
if ( refused ) {
|
||||
retryRefusedChannel( watch );
|
||||
} else if ( agentMissing ) {
|
||||
usePolling( watch );
|
||||
} else {
|
||||
{
|
||||
@@ -302,6 +320,7 @@ class RemoteWatchBackendImpl : public std::enable_shared_from_this<RemoteWatchBa
|
||||
watch->mode = RemoteWatch::Mode::Agent;
|
||||
watch->established = true;
|
||||
watch->retries = 0;
|
||||
watch->channelRetries = 0;
|
||||
}
|
||||
if ( auto sink = watch->sink.lock() ) {
|
||||
sink->setStatus( generic ? WatchStatus::Polling : WatchStatus::Active );
|
||||
@@ -472,6 +491,36 @@ class RemoteWatchBackendImpl : public std::enable_shared_from_this<RemoteWatchBa
|
||||
} );
|
||||
}
|
||||
|
||||
/** Retries briefly within the establishment window, then polls only this watch. The host is
|
||||
* not marked unavailable, so later watches use the agent again. */
|
||||
void retryRefusedChannel( const std::shared_ptr<RemoteWatch>& watch ) {
|
||||
Uint8 attempt;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock( mMutex );
|
||||
if ( watch->mode == RemoteWatch::Mode::Closed )
|
||||
return;
|
||||
attempt = watch->channelRetries++;
|
||||
}
|
||||
if ( attempt >= MaxChannelRetries ) {
|
||||
usePolling( watch );
|
||||
return;
|
||||
}
|
||||
std::weak_ptr<RemoteWatchBackendImpl> weak = weak_from_this();
|
||||
std::weak_ptr<RemoteWatch> weakWatch = watch;
|
||||
mRunner.runAfter( ChannelRetryDelay * ( 1 << attempt ), [weak, weakWatch] {
|
||||
auto self = weak.lock();
|
||||
auto watch = weakWatch.lock();
|
||||
if ( !self || !watch )
|
||||
return;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock( self->mMutex );
|
||||
if ( watch->mode == RemoteWatch::Mode::Closed )
|
||||
return;
|
||||
}
|
||||
self->establish( watch );
|
||||
} );
|
||||
}
|
||||
|
||||
void scheduleRetry( const std::shared_ptr<RemoteWatch>& watch ) {
|
||||
Uint32 retries;
|
||||
{
|
||||
@@ -631,6 +680,7 @@ void AgentClient::start( const std::string& command ) {
|
||||
if ( !self->mChannel ) {
|
||||
if ( libssh2_session_last_errno( c.session() ) == LIBSSH2_ERROR_EAGAIN )
|
||||
return std::nullopt;
|
||||
self->mChannelRefused = true;
|
||||
return VFSResult<void>(
|
||||
Err( c.lastError( URI(), "efsw-agent: could not open a channel" ) ) );
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<svg width="16" height="16"><path d="M1 1 A57.1E2857 3 0 0 1 12 12 L1 12 Z"/></svg>
|
||||
|
After Width: | Height: | Size: 83 B |
@@ -0,0 +1 @@
|
||||
<svg width="16" height="16"><path d="M-3e7 0 L-3e7 16 L-4e7 8 Z"/></svg>
|
||||
|
After Width: | Height: | Size: 72 B |
@@ -0,0 +1 @@
|
||||
<svg width="16" height="16"><path stroke="red" stroke-width="10662107277" stroke-linecap="round" d="M1 1 L12 12"/></svg>
|
||||
|
After Width: | Height: | Size: 120 B |
@@ -0,0 +1 @@
|
||||
<svg width="16" height="16"><rect x="2" y="2" width="12" height="12" fill="red"/></svg>
|
||||
|
After Width: | Height: | Size: 87 B |
@@ -0,0 +1,26 @@
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
#define NANOSVG_IMPLEMENTATION
|
||||
#define NANOSVGRAST_IMPLEMENTATION
|
||||
#include <nanosvg/nanosvg.h>
|
||||
#include <nanosvg/nanosvgrast.h>
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput( const uint8_t* data, size_t size ) {
|
||||
if ( size > 8192 )
|
||||
return 0;
|
||||
char input[8193];
|
||||
std::memcpy( input, data, size );
|
||||
input[size] = '\0';
|
||||
NSVGimage* image = nsvgParse( input, "px", 96, 0xFFFFFFFF );
|
||||
if ( !image )
|
||||
return 0;
|
||||
NSVGrasterizer* rasterizer = nsvgCreateRasterizer();
|
||||
if ( rasterizer ) {
|
||||
unsigned char pixels[32 * 32 * 4];
|
||||
nsvgRasterize( rasterizer, image, 0, 0, 1, pixels, 32, 32, 32 * 4 );
|
||||
nsvgDeleteRasterizer( rasterizer );
|
||||
}
|
||||
nsvgDelete( image );
|
||||
return 0;
|
||||
}
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <array>
|
||||
#include <condition_variable>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <eepp/system/base64.hpp>
|
||||
#include <eepp/system/process.hpp>
|
||||
#include <eepp/vfs/path.hpp>
|
||||
@@ -50,6 +51,11 @@ class TestSSHServer {
|
||||
|
||||
bool available() const { return mAvailable; }
|
||||
|
||||
static bool required() {
|
||||
const char* value = std::getenv( "EEPP_REQUIRE_SFTP_TESTS" );
|
||||
return value && std::strcmp( value, "1" ) == 0;
|
||||
}
|
||||
|
||||
const std::string& skipReason() const { return mSkipReason; }
|
||||
|
||||
const std::string& dir() const { return mDir; }
|
||||
@@ -158,6 +164,13 @@ class TestSSHServer {
|
||||
FileSystem::fileRemove( mDir + "id_ed25519_nopub.pub" );
|
||||
FileSystem::fileWrite( mDir + "authorized_keys", std::string_view( authorized ) );
|
||||
|
||||
// Tests fail authentication on purpose; OpenSSH >= 9.8 would otherwise penalize (refuse)
|
||||
// the loopback source afterwards. Older servers reject the option and refuse to start.
|
||||
const std::string probe = mDir + "sshd_penalties_probe";
|
||||
FileSystem::fileWrite( probe, std::string_view( "HostKey " + mDir +
|
||||
"host_ed25519\nPerSourcePenalties no\n" ) );
|
||||
const bool penalties = run( sshd, { "-t", "-f", probe } );
|
||||
|
||||
std::string user = SSHConfigContext::system( "x" ).localUser;
|
||||
for ( int attempt = 0; attempt < 5 && !mServer; ++attempt ) {
|
||||
mPort =
|
||||
@@ -188,10 +201,8 @@ class TestSSHServer {
|
||||
"AllowTcpForwarding yes\n"
|
||||
"Subsystem sftp internal-sftp" +
|
||||
( mDisablePosixRename ? " -P posix-rename\n" : "\n" ) +
|
||||
"LogLevel ERROR\n"
|
||||
// Tests fail authentication on purpose; OpenSSH >= 9.8 would
|
||||
// otherwise penalize (refuse) the loopback source afterwards.
|
||||
"PerSourcePenalties no\n";
|
||||
"LogLevel ERROR\n" +
|
||||
( penalties ? "PerSourcePenalties no\n" : "" );
|
||||
FileSystem::fileWrite( mDir + "sshd_config", std::string_view( config ) );
|
||||
auto server = std::make_unique<Process>();
|
||||
if ( !server->create( sshd, { "-D", "-e", "-f", mDir + "sshd_config" } ) )
|
||||
@@ -410,7 +421,8 @@ class BlackholeProxy {
|
||||
auto& server = TestSSHServer::instance(); \
|
||||
if ( !server.available() ) { \
|
||||
printf( " SFTP integration test skipped: %s\n", server.skipReason().c_str() ); \
|
||||
return; \
|
||||
ASSERT_FALSE( TestSSHServer::required() ); \
|
||||
UTEST_SKIP( "Local SSH server is unavailable" ); \
|
||||
}
|
||||
|
||||
class FixedVerifier : public SSHHostKeyVerifier {
|
||||
@@ -657,6 +669,7 @@ UTEST( SFTP, differentVerifiedPeersSupportCrossServerTransfers ) {
|
||||
auto& other = TestSSHServer::independent();
|
||||
if ( !other.available() ) {
|
||||
printf( " Independent SSH server unavailable: %s\n", other.skipReason().c_str() );
|
||||
ASSERT_FALSE( TestSSHServer::required() );
|
||||
UTEST_SKIP( "Independent SSH server is unavailable" );
|
||||
}
|
||||
TempDir configDir;
|
||||
@@ -707,7 +720,8 @@ UTEST( SFTP, replacementWithoutPosixRenamePreservesBothFiles ) {
|
||||
auto& server = TestSSHServer::withoutPosixRename();
|
||||
if ( !server.available() ) {
|
||||
printf( " SFTP integration test skipped: %s\n", server.skipReason().c_str() );
|
||||
return;
|
||||
ASSERT_FALSE( TestSSHServer::required() );
|
||||
UTEST_SKIP( "Local SSH server is unavailable" );
|
||||
}
|
||||
VirtualFileSystem vfs;
|
||||
auto sftp = server.provider();
|
||||
|
||||
@@ -94,8 +94,10 @@ UTEST( TextFormat, autodetectProject ) {
|
||||
auto files = FileSystem::filesInfoGetInPath( folder, false, true, true, true );
|
||||
for ( const auto& file : files ) {
|
||||
if ( file.isDirectory() ) {
|
||||
// Downloaded SDL SDKs contain platform binaries outside this source scan.
|
||||
if ( !LuaPattern::hasMatches( file.getFileName(), "^SDL[23]%-%d+%.%d+%.%d+$" ) )
|
||||
// Downloaded SDL SDKs contain platform binaries outside this source scan. Fuzz
|
||||
// corpora hold deliberately malformed inputs of any encoding.
|
||||
if ( !LuaPattern::hasMatches( file.getFileName(), "^SDL[23]%-%d+%.%d+%.%d+$" ) &&
|
||||
file.getFileName() != "corpus" )
|
||||
checkFolder( file.getFilepath() );
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
#include "utest.hpp"
|
||||
#include "vfs_test_utils.hpp"
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <eepp/network/ssl/sslsocket.hpp>
|
||||
#include <eepp/network/tcplistener.hpp>
|
||||
#include <eepp/system/process.hpp>
|
||||
#include <eepp/system/sys.hpp>
|
||||
#include <thread>
|
||||
|
||||
using namespace EE;
|
||||
using namespace EE::Network;
|
||||
using namespace EE::System;
|
||||
|
||||
namespace {
|
||||
|
||||
class LocalTLSServer {
|
||||
public:
|
||||
LocalTLSServer() {
|
||||
const std::string openssl = Sys::which( "openssl" );
|
||||
if ( openssl.empty() )
|
||||
return;
|
||||
mCertificate = mDirectory.path + "server.pem";
|
||||
mOtherCertificate = mDirectory.path + "other.pem";
|
||||
const std::string key = mDirectory.path + "server.key";
|
||||
if ( !generate( openssl, mCertificate, key ) ||
|
||||
!generate( openssl, mOtherCertificate, mDirectory.path + "other.key" ) )
|
||||
return;
|
||||
TcpListener reservation;
|
||||
if ( reservation.listen( Socket::AnyPort, IpAddress::LocalHost ) != Socket::Done )
|
||||
return;
|
||||
mPort = reservation.getLocalPort();
|
||||
reservation.close();
|
||||
if ( !mProcess.create(
|
||||
openssl, { "s_server", "-accept", "127.0.0.1:" + String::toString( mPort ),
|
||||
"-cert", mCertificate, "-key", key, "-www", "-quiet", "-tls1_2" } ) )
|
||||
return;
|
||||
for ( int attempt = 0; attempt < 100; ++attempt ) {
|
||||
TcpSocket probe;
|
||||
if ( probe.connect( IpAddress::LocalHost, mPort, Milliseconds( 50 ) ) ==
|
||||
Socket::Done ) {
|
||||
mAvailable = true;
|
||||
break;
|
||||
}
|
||||
std::this_thread::sleep_for( std::chrono::milliseconds( 20 ) );
|
||||
}
|
||||
}
|
||||
|
||||
~LocalTLSServer() { mProcess.kill(); }
|
||||
|
||||
bool available() const { return mAvailable; }
|
||||
|
||||
unsigned short port() const { return mPort; }
|
||||
|
||||
const std::string& certificate() const { return mCertificate; }
|
||||
|
||||
const std::string& otherCertificate() const { return mOtherCertificate; }
|
||||
|
||||
private:
|
||||
static bool generate( const std::string& openssl, const std::string& certificate,
|
||||
const std::string& key ) {
|
||||
Process process;
|
||||
if ( !process.create( openssl, { "req", "-x509", "-newkey", "rsa:2048", "-nodes", "-sha256",
|
||||
"-days", "1", "-subj", "/CN=localhost", "-addext",
|
||||
"subjectAltName=DNS:localhost", "-keyout", key, "-out",
|
||||
certificate } ) )
|
||||
return false;
|
||||
int code = -1;
|
||||
process.join( &code );
|
||||
return code == 0;
|
||||
}
|
||||
|
||||
vfstest::TempDir mDirectory;
|
||||
Process mProcess;
|
||||
std::string mCertificate;
|
||||
std::string mOtherCertificate;
|
||||
unsigned short mPort{ 0 };
|
||||
bool mAvailable{ false };
|
||||
};
|
||||
|
||||
class TLSCertificateScope {
|
||||
public:
|
||||
TLSCertificateScope() : mOriginal( SSL::SSLSocket::CertificatesPath ) { SSL::SSLSocket::end(); }
|
||||
|
||||
~TLSCertificateScope() {
|
||||
SSL::SSLSocket::end();
|
||||
SSL::SSLSocket::CertificatesPath = std::move( mOriginal );
|
||||
}
|
||||
|
||||
static std::unique_ptr<SSL::SSLSocket> socket( const std::string& certificate,
|
||||
const std::string& hostname ) {
|
||||
SSL::SSLSocket::end();
|
||||
SSL::SSLSocket::CertificatesPath = certificate;
|
||||
return std::unique_ptr<SSL::SSLSocket>( SSL::SSLSocket::New( hostname, true, true ) );
|
||||
}
|
||||
|
||||
private:
|
||||
std::string mOriginal;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
UTEST( TLSSecurity, HTTPSAcceptsTrustedPeerAndRejectsWrongHostAndUntrustedCertificate ) {
|
||||
if ( !SSL::SSLSocket::isSupported() )
|
||||
UTEST_SKIP( "TLS backend disabled" );
|
||||
LocalTLSServer server;
|
||||
if ( !server.available() ) {
|
||||
const char* required = std::getenv( "EEPP_REQUIRE_TLS_TESTS" );
|
||||
ASSERT_FALSE_MSG( required && std::strcmp( required, "1" ) == 0,
|
||||
"Could not start the required loopback OpenSSL TLS server" );
|
||||
UTEST_SKIP( "OpenSSL CLI with req -addext and s_server is required" );
|
||||
}
|
||||
TLSCertificateScope trust;
|
||||
{
|
||||
auto socket = TLSCertificateScope::socket( server.certificate(), "localhost" );
|
||||
ASSERT_EQ( socket->connect( IpAddress::LocalHost, server.port(), Seconds( 5 ) ),
|
||||
Socket::Done );
|
||||
const char request[] = "GET / HTTP/1.0\r\nHost: localhost\r\n\r\n";
|
||||
ASSERT_EQ( socket->send( request, sizeof( request ) - 1 ), Socket::Done );
|
||||
char response[1024];
|
||||
size_t received = 0;
|
||||
ASSERT_EQ( socket->receive( response, sizeof( response ), received ), Socket::Done );
|
||||
ASSERT_GE( received, 5u );
|
||||
EXPECT_EQ( std::memcmp( response, "HTTP/", 5 ), 0 );
|
||||
}
|
||||
{
|
||||
auto socket = TLSCertificateScope::socket( server.certificate(), "wrong.invalid" );
|
||||
EXPECT_NE( socket->connect( IpAddress::LocalHost, server.port(), Seconds( 5 ) ),
|
||||
Socket::Done );
|
||||
}
|
||||
{
|
||||
auto socket = TLSCertificateScope::socket( server.otherCertificate(), "localhost" );
|
||||
EXPECT_NE( socket->connect( IpAddress::LocalHost, server.port(), Seconds( 5 ) ),
|
||||
Socket::Done );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#include "utest.hpp"
|
||||
#include "vfs_test_utils.hpp"
|
||||
#include <array>
|
||||
#include <eepp/audio/inputsoundfile.hpp>
|
||||
#include <eepp/audio/outputsoundfile.hpp>
|
||||
|
||||
using namespace EE;
|
||||
using namespace EE::Audio;
|
||||
|
||||
UTEST( VorbisSecurity, EncoderHandlesLowSampleRatesAndRejectsInvalidSetup ) {
|
||||
vfstest::TempDir temp;
|
||||
std::array<Int16, 512> samples{};
|
||||
for ( unsigned channels : { 1u, 2u } ) {
|
||||
for ( unsigned rate : { 1u, 1000u, 4000u, 8000u, 22050u, 44100u } ) {
|
||||
const std::string path = temp.path + "encoded.ogg";
|
||||
bool opened;
|
||||
{
|
||||
OutputSoundFile output;
|
||||
opened = output.openFromFile( path, rate, channels );
|
||||
if ( opened )
|
||||
output.write( samples.data(), samples.size() );
|
||||
}
|
||||
if ( rate >= 8000 )
|
||||
EXPECT_TRUE( opened );
|
||||
if ( opened ) {
|
||||
InputSoundFile input;
|
||||
ASSERT_TRUE( input.openFromFile( path ) );
|
||||
EXPECT_EQ( input.getSampleRate(), rate );
|
||||
EXPECT_EQ( input.getChannelCount(), channels );
|
||||
EXPECT_EQ( input.read( samples.data(), samples.size() ), samples.size() );
|
||||
}
|
||||
}
|
||||
}
|
||||
OutputSoundFile output;
|
||||
EXPECT_FALSE( output.openFromFile( temp.path + "invalid.ogg", 0, 1 ) );
|
||||
EXPECT_FALSE( output.openFromFile( temp.path + "invalid.ogg", 44100, 0 ) );
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
#include "utest.hpp"
|
||||
#include "vfs_test_utils.hpp"
|
||||
#include <eepp/system/zip.hpp>
|
||||
#include <initializer_list>
|
||||
|
||||
using namespace EE;
|
||||
using namespace EE::System;
|
||||
|
||||
namespace {
|
||||
|
||||
void put( std::string& bytes, size_t offset, Uint64 value, size_t width ) {
|
||||
for ( size_t i = 0; i < width; ++i )
|
||||
bytes[offset + i] = static_cast<char>( value >> ( i * 8 ) );
|
||||
}
|
||||
|
||||
// A ZIP64 end record at offset 0 followed by its locator and a classic end record whose
|
||||
// fields defer to it. Only the declared directory range and entry count vary.
|
||||
std::string zip64EndRecords( Uint64 offset, Uint64 size, Uint64 count ) {
|
||||
std::string bytes( 56 + 20 + 22, '\0' );
|
||||
put( bytes, 0, 0x06064b50, 4 );
|
||||
put( bytes, 4, 44, 8 );
|
||||
put( bytes, 12, 45, 2 );
|
||||
put( bytes, 14, 45, 2 );
|
||||
put( bytes, 24, count, 8 );
|
||||
put( bytes, 32, count, 8 );
|
||||
put( bytes, 40, size, 8 );
|
||||
put( bytes, 48, offset, 8 );
|
||||
put( bytes, 56, 0x07064b50, 4 );
|
||||
put( bytes, 64, 0, 8 );
|
||||
put( bytes, 72, 1, 4 );
|
||||
put( bytes, 76, 0x06054b50, 4 );
|
||||
put( bytes, 84, 0xffff, 2 );
|
||||
put( bytes, 86, 0xffff, 2 );
|
||||
put( bytes, 88, 0xffffffff, 4 );
|
||||
put( bytes, 92, 0xffffffff, 4 );
|
||||
return bytes;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
UTEST( ZipSecurity, WrappedDirectoryRangesAreRejectedInEveryOpenMode ) {
|
||||
vfstest::TempDir temp;
|
||||
const std::string path = temp.path + "wrapped.zip";
|
||||
// High-bit offsets and sizes also cover sign handling of 32-bit fields.
|
||||
for ( auto range : { std::pair<Uint32, Uint32>{ 0xfffffff0u, 0x30u },
|
||||
{ 0x80000000u, 0x80000030u },
|
||||
{ 23u, 46u },
|
||||
{ 0u, 45u } } ) {
|
||||
std::string bytes( 22, '\0' );
|
||||
put( bytes, 0, 0x06054b50, 4 );
|
||||
put( bytes, 8, 1, 2 );
|
||||
put( bytes, 10, 1, 2 );
|
||||
put( bytes, 12, range.second, 4 );
|
||||
put( bytes, 16, range.first, 4 );
|
||||
ASSERT_TRUE( FileSystem::fileWrite( path, std::string_view( bytes ) ) );
|
||||
Zip archive( false );
|
||||
for ( auto mode : { Zip::OpenMode::ReadOnly, Zip::OpenMode::ReadWrite } ) {
|
||||
EXPECT_FALSE( archive.open( path, mode ) );
|
||||
EXPECT_EQ( archive.error(), Zip::Error::InvalidArchive );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UTEST( ZipSecurity, Zip64RangesAndCountsCannotWrapOrOverAllocate ) {
|
||||
vfstest::TempDir temp;
|
||||
const std::string path = temp.path + "zip64.zip";
|
||||
struct Case {
|
||||
Uint64 offset;
|
||||
Uint64 size;
|
||||
Uint64 count;
|
||||
};
|
||||
// 64-bit offset + size wraps, offsets past the signed seek range, entry counts that wrap
|
||||
// a 32-bit allocation size, and a directory that cannot fit before the end record.
|
||||
for ( const Case& value :
|
||||
{ Case{ 0xffffffffffffff00ull, 0x200, 1 }, Case{ 0x8000000000000000ull, 0x10, 0 },
|
||||
Case{ 0, 46, 0x100000000ull }, Case{ 0, 46, 0xffffffffull },
|
||||
Case{ 0, 0xffffffffffffffffull, 1 } } ) {
|
||||
const std::string bytes = zip64EndRecords( value.offset, value.size, value.count );
|
||||
ASSERT_TRUE( FileSystem::fileWrite( path, std::string_view( bytes ) ) );
|
||||
Zip archive( false );
|
||||
for ( auto mode : { Zip::OpenMode::ReadOnly, Zip::OpenMode::ReadWrite } ) {
|
||||
EXPECT_FALSE( archive.open( path, mode ) );
|
||||
EXPECT_NE( archive.error(), Zip::Error::None );
|
||||
EXPECT_EQ( archive.entryCount(), 0u );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -143,21 +143,24 @@ UTEST( ZipProvider, listsImplicitAndEmptyDirectoriesWithMetadata ) {
|
||||
EXPECT_TRUE( waitFor( handle.close() ).hasValue() );
|
||||
}
|
||||
|
||||
UTEST( ZipProvider, aggregateMetadataBudgetBoundsDeepIndexes ) {
|
||||
UTEST( ZipProvider, deepAndManyEntryIndexesAreListed ) {
|
||||
TempDir temp;
|
||||
const std::string path = temp.path + "deep.zip";
|
||||
std::string nested;
|
||||
for ( int i = 0; i < 64; ++i )
|
||||
nested += std::string( 60, 'd' ) + '/';
|
||||
ASSERT_TRUE( makeEmptyZip( path, 512, [&nested]( Uint16 i ) {
|
||||
return std::to_string( i ) + '/' + nested + "file";
|
||||
} ) );
|
||||
ASSERT_TRUE( makeEmptyZip(
|
||||
path, 4, [&nested]( Uint16 i ) { return std::to_string( i ) + '/' + nested + "file"; } ) );
|
||||
VirtualFileSystem vfs;
|
||||
// Every implicit directory of the 64-level paths is indexed.
|
||||
auto listed = waitFor( vfs.listAll( ZipProvider::makeURI( URI::fromFSPath( path ) ) ) );
|
||||
ASSERT_FALSE( listed );
|
||||
EXPECT_EQ( VFSErrorCode::InvalidOperation, listed.error().code );
|
||||
EXPECT_TRUE( listed.error().message.find( "metadata budget" ) != std::string::npos );
|
||||
// A normal many-entry archive stays well below the budget and remains usable after failure.
|
||||
ASSERT_TRUE( listed );
|
||||
EXPECT_EQ( 4u, listed.value().size() );
|
||||
auto leaf = waitFor( vfs.listAll( ZipProvider::makeURI(
|
||||
URI::fromFSPath( path ), "/3/" + nested.substr( 0, nested.size() - 1 ) ) ) );
|
||||
ASSERT_TRUE( leaf );
|
||||
ASSERT_EQ( 1u, leaf.value().size() );
|
||||
EXPECT_STDSTREQ( "file", leaf.value()[0].name );
|
||||
const std::string normal = temp.path + "many.zip";
|
||||
ASSERT_TRUE(
|
||||
makeEmptyZip( normal, 1024, []( Uint16 i ) { return "dir/file" + std::to_string( i ); } ) );
|
||||
@@ -169,49 +172,55 @@ UTEST( ZipProvider, aggregateMetadataBudgetBoundsDeepIndexes ) {
|
||||
|
||||
UTEST( ZipProvider, malformedCentralDirectoriesAreRejectedBeforeAllocation ) {
|
||||
TempDir temp;
|
||||
// A tiny EOCD claims a huge directory. The bounded reader rejects its declared metadata
|
||||
// before allocating its entry array or attempting to decode any names/comments/extra fields.
|
||||
std::array<Uint8, 22> eocd{};
|
||||
// A tiny EOCD claims a huge directory starting at a central-directory signature. It is
|
||||
// rejected because the directory cannot fit before the end record, before allocating its
|
||||
// entry array or decoding any names/comments/extra fields.
|
||||
std::array<Uint8, 26> eocd{};
|
||||
eocd[0] = 'P';
|
||||
eocd[1] = 'K';
|
||||
eocd[2] = 5;
|
||||
eocd[3] = 6;
|
||||
eocd[8] = eocd[9] = eocd[10] = eocd[11] = 255;
|
||||
eocd[15] = 4; // 64 MiB of encoded metadata, before decoded objects/allocation slack.
|
||||
eocd[2] = 1;
|
||||
eocd[3] = 2;
|
||||
eocd[4] = 'P';
|
||||
eocd[5] = 'K';
|
||||
eocd[6] = 5;
|
||||
eocd[7] = 6;
|
||||
eocd[12] = eocd[13] = eocd[14] = eocd[15] = 255;
|
||||
eocd[19] = 4; // 64 MiB of encoded metadata.
|
||||
const std::string path = temp.path + "oversized.zip";
|
||||
ASSERT_TRUE( FileSystem::fileWrite( path, eocd.data(), eocd.size() ) );
|
||||
Zip reader( false );
|
||||
EXPECT_FALSE( reader.open( path, Zip::OpenMode::ReadOnlyBounded ) );
|
||||
EXPECT_FALSE( reader.open( path, Zip::OpenMode::ReadOnly ) );
|
||||
EXPECT_EQ( Zip::Error::InvalidArchive, reader.error() );
|
||||
EXPECT_TRUE( reader.errorMessage().find( "metadata budget" ) != std::string::npos );
|
||||
VirtualFileSystem vfs;
|
||||
auto listed = waitFor( vfs.listAll( ZipProvider::makeURI( URI::fromFSPath( path ) ) ) );
|
||||
EXPECT_EQ( VFSErrorCode::InvalidOperation, codeOf( listed ) );
|
||||
// An empty-directory count must not allow a nonempty directory to be decoded into
|
||||
// storage allocated for zero entries.
|
||||
// A zero count with a nonempty directory is read as a wrapped InfoZIP count, which must
|
||||
// then match the entries actually present.
|
||||
const std::string inconsistent = temp.path + "inconsistent.zip";
|
||||
ASSERT_TRUE( makeEmptyZip( inconsistent, 1, []( Uint16 ) { return std::string( "file" ); } ) );
|
||||
std::string bytes;
|
||||
ASSERT_TRUE( FileSystem::fileGet( inconsistent, bytes ) );
|
||||
std::fill_n( bytes.end() - 14, 4, '\0' );
|
||||
ASSERT_TRUE( FileSystem::fileWrite( inconsistent, std::string_view( bytes ) ) );
|
||||
EXPECT_FALSE( reader.open( inconsistent, Zip::OpenMode::ReadOnlyBounded ) );
|
||||
EXPECT_FALSE( reader.open( inconsistent, Zip::OpenMode::ReadOnly ) );
|
||||
EXPECT_EQ( Zip::Error::InvalidArchive, reader.error() );
|
||||
}
|
||||
|
||||
UTEST( ZipProvider, wrappedZeroInfoZipCountIsIntentionallyRejected ) {
|
||||
UTEST( ZipProvider, wrappedZeroInfoZipCountIsRecovered ) {
|
||||
TempDir temp;
|
||||
const std::string path = temp.path + "wrapped-zero.zip";
|
||||
// The fixture writes all 65,536 headers, but its two 16-bit EOCD counts wrap to zero.
|
||||
// libzip recovers the InfoZIP count from the directory size.
|
||||
ASSERT_TRUE(
|
||||
makeEmptyZip( path, 65536, []( Uint32 i ) { return "file" + std::to_string( i ); } ) );
|
||||
Zip reader( false );
|
||||
for ( auto mode : { Zip::OpenMode::ReadOnly, Zip::OpenMode::ReadOnlyBounded } ) {
|
||||
EXPECT_FALSE( reader.open( path, mode ) );
|
||||
EXPECT_EQ( Zip::Error::InvalidArchive, reader.error() );
|
||||
}
|
||||
ASSERT_TRUE( reader.open( path, Zip::OpenMode::ReadOnly ) );
|
||||
EXPECT_EQ( 65536u, reader.entryCount() );
|
||||
ASSERT_TRUE( reader.close() );
|
||||
VirtualFileSystem vfs;
|
||||
EXPECT_FALSE( waitFor( vfs.listAll( ZipProvider::makeURI( URI::fromFSPath( path ) ) ) ) );
|
||||
auto listed = waitFor( vfs.listAll( ZipProvider::makeURI( URI::fromFSPath( path ) ) ) );
|
||||
ASSERT_TRUE( listed );
|
||||
EXPECT_EQ( 65536u, listed.value().size() );
|
||||
}
|
||||
|
||||
UTEST( ZipProvider, streamingReadsSeekBackwardsAndCopyAcrossProviders ) {
|
||||
|
||||
Vendored
+1
-1
Submodule src/thirdparty/efsw updated: 58a105f56a...0712eec278
+3
@@ -0,0 +1,3 @@
|
||||
# Preserve upstream formatting and preprocessor continuations.
|
||||
DisableFormat: true
|
||||
SortIncludes: Never
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+11
-11
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
@@ -115,14 +115,14 @@ typedef struct OggVorbis_File {
|
||||
ogg_sync_state oy;
|
||||
|
||||
/* If the FILE handle isn't seekable (eg, a pipe), only the current
|
||||
stream appears */
|
||||
stream appears */
|
||||
int links;
|
||||
ogg_int64_t *offsets;
|
||||
ogg_int64_t *dataoffsets;
|
||||
long *serialnos;
|
||||
ogg_int64_t *pcmlengths; /* overloaded to maintain binary
|
||||
compatibility; x2 size, stores both
|
||||
beginning and end values */
|
||||
compatibility; x2 size, stores both
|
||||
beginning and end values */
|
||||
vorbis_info *vi;
|
||||
vorbis_comment *vc;
|
||||
|
||||
@@ -136,7 +136,7 @@ typedef struct OggVorbis_File {
|
||||
double samptrack;
|
||||
|
||||
ogg_stream_state os; /* take physical pages, weld into a logical
|
||||
stream of packets */
|
||||
stream of packets */
|
||||
vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
|
||||
vorbis_block vb; /* local working space for packet->PCM decode */
|
||||
|
||||
@@ -149,11 +149,11 @@ extern int ov_clear(OggVorbis_File *vf);
|
||||
extern int ov_fopen(const char *path,OggVorbis_File *vf);
|
||||
extern int ov_open(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes);
|
||||
extern int ov_open_callbacks(void *datasource, OggVorbis_File *vf,
|
||||
const char *initial, long ibytes, ov_callbacks callbacks);
|
||||
const char *initial, long ibytes, ov_callbacks callbacks);
|
||||
|
||||
extern int ov_test(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes);
|
||||
extern int ov_test_callbacks(void *datasource, OggVorbis_File *vf,
|
||||
const char *initial, long ibytes, ov_callbacks callbacks);
|
||||
const char *initial, long ibytes, ov_callbacks callbacks);
|
||||
extern int ov_test_open(OggVorbis_File *vf);
|
||||
|
||||
extern long ov_bitrate(OggVorbis_File *vf,int i);
|
||||
@@ -186,12 +186,12 @@ extern vorbis_info *ov_info(OggVorbis_File *vf,int link);
|
||||
extern vorbis_comment *ov_comment(OggVorbis_File *vf,int link);
|
||||
|
||||
extern long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int samples,
|
||||
int *bitstream);
|
||||
int *bitstream);
|
||||
extern long ov_read_filter(OggVorbis_File *vf,char *buffer,int length,
|
||||
int bigendianp,int word,int sgned,int *bitstream,
|
||||
void (*filter)(float **pcm,long channels,long samples,void *filter_param),void *filter_param);
|
||||
int bigendianp,int word,int sgned,int *bitstream,
|
||||
void (*filter)(float **pcm,long channels,long samples,void *filter_param),void *filter_param);
|
||||
extern long ov_read(OggVorbis_File *vf,char *buffer,int length,
|
||||
int bigendianp,int word,int sgned,int *bitstream);
|
||||
int bigendianp,int word,int sgned,int *bitstream);
|
||||
extern int ov_crosslap(OggVorbis_File *vf1,OggVorbis_File *vf2);
|
||||
|
||||
extern int ov_halfrate(OggVorbis_File *vf,int flag);
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
*
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
Vendored
+15
-7
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <ogg/ogg.h>
|
||||
#include "vorbis/codec.h"
|
||||
#include "codec_internal.h"
|
||||
@@ -30,8 +29,8 @@
|
||||
#include "misc.h"
|
||||
#include "os.h"
|
||||
|
||||
#define GENERAL_VENDOR_STRING "Xiph.Org libVorbis 1.3.6"
|
||||
#define ENCODE_VENDOR_STRING "Xiph.Org libVorbis I 20180316 (Now 100% fewer shells)"
|
||||
#define GENERAL_VENDOR_STRING "Xiph.Org libVorbis 1.3.7"
|
||||
#define ENCODE_VENDOR_STRING "Xiph.Org libVorbis I 20200704 (Reducing Environment)"
|
||||
|
||||
/* helpers */
|
||||
static void _v_writestring(oggpack_buffer *o,const char *s, int bytes){
|
||||
@@ -47,6 +46,10 @@ static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){
|
||||
}
|
||||
}
|
||||
|
||||
static int _v_toupper(int c) {
|
||||
return (c >= 'a' && c <= 'z') ? (c & ~('a' - 'A')) : c;
|
||||
}
|
||||
|
||||
void vorbis_comment_init(vorbis_comment *vc){
|
||||
memset(vc,0,sizeof(*vc));
|
||||
}
|
||||
@@ -78,7 +81,7 @@ void vorbis_comment_add_tag(vorbis_comment *vc, const char *tag, const char *con
|
||||
static int tagcompare(const char *s1, const char *s2, int n){
|
||||
int c=0;
|
||||
while(c < n){
|
||||
if(toupper(s1[c]) != toupper(s2[c]))
|
||||
if(_v_toupper(s1[c]) != _v_toupper(s2[c]))
|
||||
return !0;
|
||||
c++;
|
||||
}
|
||||
@@ -203,6 +206,7 @@ void vorbis_info_clear(vorbis_info *vi){
|
||||
|
||||
static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){
|
||||
codec_setup_info *ci=vi->codec_setup;
|
||||
int bs;
|
||||
if(!ci)return(OV_EFAULT);
|
||||
|
||||
vi->version=oggpack_read(opb,32);
|
||||
@@ -215,8 +219,12 @@ static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){
|
||||
vi->bitrate_nominal=(ogg_int32_t)oggpack_read(opb,32);
|
||||
vi->bitrate_lower=(ogg_int32_t)oggpack_read(opb,32);
|
||||
|
||||
ci->blocksizes[0]=1<<oggpack_read(opb,4);
|
||||
ci->blocksizes[1]=1<<oggpack_read(opb,4);
|
||||
bs = oggpack_read(opb,4);
|
||||
if(bs<0)goto err_out;
|
||||
ci->blocksizes[0]=1<<bs;
|
||||
bs = oggpack_read(opb,4);
|
||||
if(bs<0)goto err_out;
|
||||
ci->blocksizes[1]=1<<bs;
|
||||
|
||||
if(vi->rate<1)goto err_out;
|
||||
if(vi->channels<1)goto err_out;
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
Vendored
+3
-2
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
@@ -15,9 +15,10 @@
|
||||
The LSP generation code is taken (with minimal modification and a
|
||||
few bugfixes) from "On the Computation of the LSP Frequencies" by
|
||||
Joseph Rothweiler (see http://www.rothweiler.us for contact info).
|
||||
|
||||
The paper is available at:
|
||||
|
||||
http://www.myown1.com/joe/lsf
|
||||
https://web.archive.org/web/20110810174000/http://home.myfairpoint.net/vzenxj75/myown1/joe/lsf/index.html
|
||||
|
||||
********************************************************************/
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
Vendored
+6
-7
@@ -8,7 +8,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
@@ -60,7 +60,7 @@ void *_alloca(size_t size);
|
||||
# define FAST_HYPOT hypot
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif /* _V_IFDEFJAIL_H_ */
|
||||
|
||||
#ifdef HAVE_ALLOCA_H
|
||||
# include <alloca.h>
|
||||
@@ -80,7 +80,7 @@ void *_alloca(size_t size);
|
||||
|
||||
|
||||
/* Special i386 GCC implementation */
|
||||
#if defined(__i386__) && defined(__GNUC__) && !defined(__BEOS__)
|
||||
#if defined(__i386__) && defined(__GNUC__) && !defined(__BEOS__) && !defined(__SSE2_MATH__)
|
||||
# define VORBIS_FPU_CONTROL
|
||||
/* both GCC and MSVC are kinda stupid about rounding/casting to int.
|
||||
Because of encapsulation constraints (GCC can't see inside the asm
|
||||
@@ -119,8 +119,7 @@ static inline int vorbis_ftoi(double f){ /* yes, double! Otherwise,
|
||||
|
||||
/* MSVC inline assembly. 32 bit only; inline ASM isn't implemented in the
|
||||
* 64 bit compiler and doesn't work on arm. */
|
||||
#if defined(_MSC_VER) && !defined(_WIN64) && \
|
||||
!defined(_WIN32_WCE) && !defined(_M_ARM)
|
||||
#if defined(_MSC_VER) && defined(_M_IX86) && !defined(_WIN32_WCE)
|
||||
# define VORBIS_FPU_CONTROL
|
||||
|
||||
typedef ogg_int16_t vorbis_fpu_control;
|
||||
@@ -147,7 +146,7 @@ static __inline void vorbis_fpu_restore(vorbis_fpu_control fpu){
|
||||
|
||||
/* Optimized code path for x86_64 builds. Uses SSE2 intrinsics. This can be
|
||||
done safely because all x86_64 CPUs supports SSE2. */
|
||||
#if (defined(_MSC_VER) && defined(_WIN64) && defined (_M_X64)) || (defined(__GNUC__) && defined (__x86_64__))
|
||||
#if (defined(_MSC_VER) && defined(_M_X64)) || (defined(__GNUC__) && defined (__SSE2_MATH__))
|
||||
# define VORBIS_FPU_CONTROL
|
||||
|
||||
typedef ogg_int16_t vorbis_fpu_control;
|
||||
@@ -174,7 +173,7 @@ static __inline void vorbis_fpu_restore(vorbis_fpu_control fpu){
|
||||
|
||||
typedef int vorbis_fpu_control;
|
||||
|
||||
static int vorbis_ftoi(double f){
|
||||
STIN int vorbis_ftoi(double f){
|
||||
/* Note: MSVC and GCC (at least on some systems) round towards zero, thus,
|
||||
the floor() call is required to ensure correct roudning of
|
||||
negative numbers */
|
||||
|
||||
Vendored
+15
-11
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
@@ -599,11 +599,12 @@ static void bark_noise_hybridmp(int n,const long *b,
|
||||
XY[i] = tXY;
|
||||
}
|
||||
|
||||
for (i = 0, x = 0.f;; i++, x += 1.f) {
|
||||
for (i = 0, x = 0.f; i < n; i++, x += 1.f) {
|
||||
|
||||
lo = b[i] >> 16;
|
||||
if( lo>=0 ) break;
|
||||
hi = b[i] & 0xffff;
|
||||
if( lo>=0 || -lo>=n ) break;
|
||||
if( hi>=n ) break;
|
||||
|
||||
tN = N[hi] + N[-lo];
|
||||
tX = X[hi] - X[-lo];
|
||||
@@ -615,17 +616,17 @@ static void bark_noise_hybridmp(int n,const long *b,
|
||||
B = tN * tXY - tX * tY;
|
||||
D = tN * tXX - tX * tX;
|
||||
R = (A + x * B) / D;
|
||||
if (R < 0.f)
|
||||
R = 0.f;
|
||||
if (R < 0.f) R = 0.f;
|
||||
|
||||
noise[i] = R - offset;
|
||||
}
|
||||
|
||||
for ( ;; i++, x += 1.f) {
|
||||
for ( ; i < n; i++, x += 1.f) {
|
||||
|
||||
lo = b[i] >> 16;
|
||||
hi = b[i] & 0xffff;
|
||||
if(hi>=n)break;
|
||||
if( lo<0 || lo>=n ) break;
|
||||
if( hi>=n ) break;
|
||||
|
||||
tN = N[hi] - N[lo];
|
||||
tX = X[hi] - X[lo];
|
||||
@@ -641,6 +642,7 @@ static void bark_noise_hybridmp(int n,const long *b,
|
||||
|
||||
noise[i] = R - offset;
|
||||
}
|
||||
|
||||
for ( ; i < n; i++, x += 1.f) {
|
||||
|
||||
R = (A + x * B) / D;
|
||||
@@ -651,10 +653,11 @@ static void bark_noise_hybridmp(int n,const long *b,
|
||||
|
||||
if (fixed <= 0) return;
|
||||
|
||||
for (i = 0, x = 0.f;; i++, x += 1.f) {
|
||||
for (i = 0, x = 0.f; i < n; i++, x += 1.f) {
|
||||
hi = i + fixed / 2;
|
||||
lo = hi - fixed;
|
||||
if(lo>=0)break;
|
||||
if ( hi>=n ) break;
|
||||
if ( lo>=0 ) break;
|
||||
|
||||
tN = N[hi] + N[-lo];
|
||||
tX = X[hi] - X[-lo];
|
||||
@@ -670,11 +673,12 @@ static void bark_noise_hybridmp(int n,const long *b,
|
||||
|
||||
if (R - offset < noise[i]) noise[i] = R - offset;
|
||||
}
|
||||
for ( ;; i++, x += 1.f) {
|
||||
for ( ; i < n; i++, x += 1.f) {
|
||||
|
||||
hi = i + fixed / 2;
|
||||
lo = hi - fixed;
|
||||
if(hi>=n)break;
|
||||
if ( hi>=n ) break;
|
||||
if ( lo<0 ) break;
|
||||
|
||||
tN = N[hi] - N[lo];
|
||||
tX = X[hi] - X[lo];
|
||||
|
||||
Vendored
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
Vendored
+1
-4
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
@@ -30,9 +30,6 @@
|
||||
#include "misc.h"
|
||||
#include "os.h"
|
||||
|
||||
//#define TRAIN_RES 1
|
||||
//#define TRAIN_RESAUX 1
|
||||
|
||||
#if defined(TRAIN_RES) || defined (TRAIN_RESAUX)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+13
-4
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
@@ -50,7 +50,7 @@ long _float32_pack(float val){
|
||||
sign=0x80000000;
|
||||
val= -val;
|
||||
}
|
||||
exp= floor(log(val)/log(2.f)+.001); //+epsilon
|
||||
exp= floor(log(val)/log(2.f)+.001); /* +epsilon */
|
||||
mant=rint(ldexp(val,(VQ_FMAN-1)-exp));
|
||||
exp=(exp+VQ_FEXP_BIAS)<<VQ_FMAN;
|
||||
|
||||
@@ -62,7 +62,15 @@ float _float32_unpack(long val){
|
||||
int sign=val&0x80000000;
|
||||
long exp =(val&0x7fe00000L)>>VQ_FMAN;
|
||||
if(sign)mant= -mant;
|
||||
return(ldexp(mant,exp-(VQ_FMAN-1)-VQ_FEXP_BIAS));
|
||||
exp=exp-(VQ_FMAN-1)-VQ_FEXP_BIAS;
|
||||
/* clamp excessive exponent values */
|
||||
if (exp>63){
|
||||
exp=63;
|
||||
}
|
||||
if (exp<-63){
|
||||
exp=-63;
|
||||
}
|
||||
return(ldexp(mant,exp));
|
||||
}
|
||||
|
||||
/* given a list of word lengths, generate a list of codewords. Works
|
||||
@@ -294,7 +302,7 @@ int vorbis_book_init_encode(codebook *c,const static_codebook *s){
|
||||
c->used_entries=s->entries;
|
||||
c->dim=s->dim;
|
||||
c->codelist=_make_words(s->lengthlist,s->entries,0);
|
||||
//c->valuelist=_book_unquantize(s,s->entries,NULL);
|
||||
/* c->valuelist=_book_unquantize(s,s->entries,NULL); */
|
||||
c->quantvals=_book_maptype1_quantvals(s);
|
||||
c->minval=(int)rint(_float32_unpack(s->q_min));
|
||||
c->delta=(int)rint(_float32_unpack(s->q_delta));
|
||||
@@ -573,6 +581,7 @@ void run_test(static_codebook *b,float *comp){
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
free(out);
|
||||
}
|
||||
|
||||
int main(){
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+3
-2
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
@@ -684,6 +684,7 @@ int vorbis_encode_setup_init(vorbis_info *vi){
|
||||
highlevel_encode_setup *hi=&ci->hi;
|
||||
|
||||
if(ci==NULL)return(OV_EINVAL);
|
||||
if(vi->channels<1||vi->channels>255)return(OV_EINVAL);
|
||||
if(!hi->impulse_block_p)i0=1;
|
||||
|
||||
/* too low/high an ATH floater is nonsensical, but doesn't break anything */
|
||||
@@ -1210,7 +1211,7 @@ int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg){
|
||||
hi->req,
|
||||
hi->managed,
|
||||
&new_base);
|
||||
if(!hi->setup)return OV_EIMPL;
|
||||
if(!new_template)return OV_EIMPL;
|
||||
hi->setup=new_template;
|
||||
hi->base_setting=new_base;
|
||||
vorbis_encode_setup_setting(vi,vi->channels,vi->rate);
|
||||
|
||||
+14
-11
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
@@ -264,6 +264,10 @@ static ogg_int64_t _get_prev_page_serial(OggVorbis_File *vf, ogg_int64_t begin,
|
||||
}
|
||||
}
|
||||
}
|
||||
/*We started from the beginning of the stream and found nothing.
|
||||
This should be impossible unless the contents of the stream changed out
|
||||
from under us after we read from it.*/
|
||||
if(!begin&&vf->offset<0)return OV_EBADLINK;
|
||||
}
|
||||
|
||||
/* we're not interested in the page... just the serialno and granpos. */
|
||||
@@ -1230,7 +1234,6 @@ double ov_time_total(OggVorbis_File *vf,int i){
|
||||
|
||||
int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
|
||||
ogg_stream_state work_os;
|
||||
int ret;
|
||||
|
||||
if(vf->ready_state<OPENED)return(OV_EINVAL);
|
||||
if(!vf->seekable)
|
||||
@@ -1253,8 +1256,12 @@ int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
|
||||
vf->current_serialno); /* must set serialno */
|
||||
vorbis_synthesis_restart(&vf->vd);
|
||||
|
||||
ret=_seek_helper(vf,pos);
|
||||
if(ret)goto seek_error;
|
||||
if(_seek_helper(vf,pos)) {
|
||||
/* dump the machine so we're in a known state */
|
||||
vf->pcm_offset=-1;
|
||||
_decode_clear(vf);
|
||||
return OV_EBADLINK;
|
||||
}
|
||||
|
||||
/* we need to make sure the pcm_offset is set, but we don't want to
|
||||
advance the raw cursor past good packets just to get to the first
|
||||
@@ -1388,13 +1395,6 @@ int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
|
||||
vf->bittrack=0.f;
|
||||
vf->samptrack=0.f;
|
||||
return(0);
|
||||
|
||||
seek_error:
|
||||
/* dump the machine so we're in a known state */
|
||||
vf->pcm_offset=-1;
|
||||
ogg_stream_clear(&work_os);
|
||||
_decode_clear(vf);
|
||||
return OV_EBADLINK;
|
||||
}
|
||||
|
||||
/* Page granularity seek (faster than sample granularity because we
|
||||
@@ -1964,6 +1964,7 @@ long ov_read_filter(OggVorbis_File *vf,char *buffer,int length,
|
||||
long samples;
|
||||
|
||||
if(vf->ready_state<OPENED)return(OV_EINVAL);
|
||||
if(word<=0)return(OV_EINVAL);
|
||||
|
||||
while(1){
|
||||
if(vf->ready_state==INITSET){
|
||||
@@ -1989,6 +1990,8 @@ long ov_read_filter(OggVorbis_File *vf,char *buffer,int length,
|
||||
long channels=ov_info(vf,-1)->channels;
|
||||
long bytespersample=word * channels;
|
||||
vorbis_fpu_control fpu;
|
||||
|
||||
if(channels<1||channels>255)return(OV_EINVAL);
|
||||
if(samples>length/bytespersample)samples=length/bytespersample;
|
||||
|
||||
if(samples <= 0)
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
|
||||
* *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* by the Xiph.Org Foundation https://xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
|
||||
Vendored
+31
@@ -0,0 +1,31 @@
|
||||
Copyright (C) 1999-2026 Dieter Baron and Thomas Klausner
|
||||
|
||||
The authors can be contacted at <info@libzip.org>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
Vendored
+28
@@ -0,0 +1,28 @@
|
||||
# libzip 1.12.1
|
||||
|
||||
Source: `lib/` of the libzip 1.12.1 release (https://libzip.org,
|
||||
`libzip-1.12.1.tar.xz`, SHA-256
|
||||
`c40062022a1963c80573d48f6070792297cecd7c6bffe3aefcac0d8b9bee8913`), BSD-3-Clause, see `LICENSE`.
|
||||
|
||||
Only the sources upstream's `lib/CMakeLists.txt` builds for deflate/store archives are imported.
|
||||
bzip2, xz, zstd and WinZip AES (`HAVE_CRYPTO`) support are not built; traditional PKWARE
|
||||
encryption is. The platform file and random backends are split into `posix/` and `win32/` so
|
||||
build scripts can select them by directory; they require `src/thirdparty/libzip` on the
|
||||
include path.
|
||||
|
||||
## Generated and eepp files
|
||||
|
||||
- `config.h` and `zipconf.h` replace the files CMake generates; they hold the feature checks for
|
||||
every eepp platform. `ZIP_STATIC` is always defined.
|
||||
- `zip_err_str.c` is generated from `zip.h` and `zipint.h` with upstream's
|
||||
`cmake/GenerateZipErrorStrings.cmake`. Regenerate it when updating:
|
||||
`cmake -DPROJECT_SOURCE_DIR=<dir with lib/zip.h and lib/zipint.h> -DCMAKE_CURRENT_BINARY_DIR=<out> -P GenerateZipErrorStrings.cmake`.
|
||||
|
||||
## Local patches
|
||||
|
||||
Every other imported file is unmodified.
|
||||
|
||||
- `zip.h` includes `"zipconf.h"` instead of `<zipconf.h>` (marked `eepp:`), so eepp includes
|
||||
`<libzip/zip.h>` without adding `src/thirdparty/libzip` to every project's include path.
|
||||
|
||||
When updating, re-apply this patch and regenerate `zip_err_str.c`.
|
||||
Vendored
+271
@@ -0,0 +1,271 @@
|
||||
#ifndef _HAD_LIBZIP_COMPAT_H
|
||||
#define _HAD_LIBZIP_COMPAT_H
|
||||
|
||||
/*
|
||||
compat.h -- compatibility defines.
|
||||
Copyright (C) 1999-2025 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <info@libzip.org>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* to have *_MAX definitions for all types when compiling with g++ */
|
||||
#define __STDC_LIMIT_MACROS
|
||||
|
||||
/* to have ISO C secure library functions */
|
||||
#define __STDC_WANT_LIB_EXT1__ 1
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef ZIP_EXTERN
|
||||
#ifndef ZIP_STATIC
|
||||
#define ZIP_EXTERN __declspec(dllexport)
|
||||
#endif
|
||||
#endif
|
||||
/* for dup(), close(), etc. */
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDBOOL_H
|
||||
#include <stdbool.h>
|
||||
#else
|
||||
typedef char bool;
|
||||
#define true 1
|
||||
#define false 0
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
/* at least MinGW does not provide EOPNOTSUPP, see
|
||||
* http://sourceforge.net/p/mingw/bugs/263/
|
||||
*/
|
||||
#ifndef EOPNOTSUPP
|
||||
#define EOPNOTSUPP EINVAL
|
||||
#endif
|
||||
|
||||
/* at least MinGW does not provide EOVERFLOW, see
|
||||
* http://sourceforge.net/p/mingw/bugs/242/
|
||||
*/
|
||||
#ifndef EOVERFLOW
|
||||
#define EOVERFLOW EFBIG
|
||||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
/* not supported on at least Windows */
|
||||
#ifndef O_CLOEXEC
|
||||
#define O_CLOEXEC 0
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#if defined(HAVE__CLOSE)
|
||||
#define close _close
|
||||
#endif
|
||||
#if defined(HAVE__DUP)
|
||||
#define dup _dup
|
||||
#endif
|
||||
/* crashes reported when using fdopen instead of _fdopen on Windows/Visual Studio 10/Win64 */
|
||||
#if defined(HAVE__FDOPEN)
|
||||
#define fdopen _fdopen
|
||||
#endif
|
||||
#if !defined(HAVE_FILENO) && defined(HAVE__FILENO)
|
||||
#define fileno _fileno
|
||||
#endif
|
||||
#if !defined(HAVE_SNPRINTF) && defined(HAVE__SNPRINTF)
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
#if !defined(HAVE__SNWPRINTF_S)
|
||||
#define _snwprintf_s(buf, bufsz, len, fmt, ...) (_snwprintf((buf), (len), (fmt), __VA_ARGS__))
|
||||
#endif
|
||||
#if defined(HAVE__STRDUP)
|
||||
#if !defined(HAVE_STRDUP) || defined(_WIN32)
|
||||
#undef strdup
|
||||
#define strdup _strdup
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(HAVE__SETMODE) && defined(HAVE_SETMODE)
|
||||
#define _setmode setmode
|
||||
#endif
|
||||
#if !defined(HAVE_STRTOLL) && defined(HAVE__STRTOI64)
|
||||
#define strtoll _strtoi64
|
||||
#endif
|
||||
#if !defined(HAVE_STRTOULL) && defined(HAVE__STRTOUI64)
|
||||
#define strtoull _strtoui64
|
||||
#endif
|
||||
#if defined(HAVE__UNLINK)
|
||||
#define unlink _unlink
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(HAVE__FSEEKI64) && defined(HAVE__FSTAT64) && defined(HAVE__FTELLI64)
|
||||
/* Windows API using int64 */
|
||||
typedef zip_int64_t zip_off_t;
|
||||
typedef struct _stat64 zip_os_stat_t;
|
||||
#define zip_os_stat _stat64
|
||||
#define zip_os_fstat _fstat64
|
||||
#define zip_os_fseek _fseeki64
|
||||
#define zip_os_ftell _ftelli64
|
||||
#define ZIP_FSEEK_MAX ZIP_INT64_MAX
|
||||
#define ZIP_FSEEK_MIN ZIP_INT64_MIN
|
||||
#else
|
||||
|
||||
/* Normal API */
|
||||
typedef struct stat zip_os_stat_t;
|
||||
#define zip_os_fstat fstat
|
||||
#define zip_os_stat stat
|
||||
|
||||
#if defined(HAVE_FTELLO) && defined(HAVE_FSEEKO)
|
||||
/* Using off_t */
|
||||
typedef off_t zip_off_t;
|
||||
#if SIZEOF_OFF_T == 8
|
||||
#define ZIP_OFF_MAX ZIP_INT64_MAX
|
||||
#define ZIP_OFF_MIN ZIP_INT64_MIN
|
||||
#elif SIZEOF_OFF_T == 4
|
||||
#define ZIP_OFF_MAX ZIP_INT32_MAX
|
||||
#define ZIP_OFF_MIN ZIP_INT32_MIN
|
||||
#elif SIZEOF_OFF_T == 2
|
||||
#define ZIP_OFF_MAX ZIP_INT16_MAX
|
||||
#define ZIP_OFF_MIN ZIP_INT16_MIN
|
||||
#else
|
||||
#error unsupported size of off_t
|
||||
#endif
|
||||
|
||||
#define ZIP_FSEEK_MAX ZIP_OFF_MAX
|
||||
#define ZIP_FSEEK_MIN ZIP_OFF_MIN
|
||||
|
||||
#define zip_os_fseek fseeko
|
||||
#define zip_os_ftell ftello
|
||||
#else
|
||||
|
||||
/* Using long */
|
||||
typedef long zip_off_t;
|
||||
#include <limits.h>
|
||||
#define ZIP_FSEEK_MAX LONG_MAX
|
||||
#define ZIP_FSEEK_MIN LONG_MIN
|
||||
|
||||
#define zip_os_fseek fseek
|
||||
#define zip_os_ftell ftell
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FTELLO
|
||||
#define ftello(s) ((long)ftell((s)))
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_LOCALTIME_S
|
||||
#ifdef _WIN32
|
||||
/* Windows is incompatible to the C11 standard, hurray! */
|
||||
#define zip_localtime(t, tm) (localtime_s((tm), (t)) == 0 ? tm : NULL)
|
||||
#else
|
||||
#define zip_localtime localtime_s
|
||||
#endif
|
||||
#else
|
||||
#ifdef HAVE_LOCALTIME_R
|
||||
#define zip_localtime localtime_r
|
||||
#else
|
||||
#define zip_localtime(t, tm) (localtime(t))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_MEMCPY_S
|
||||
#define memcpy_s(dest, destsz, src, count) (memcpy((dest), (src), (count)) == NULL)
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SNPRINTF_S
|
||||
#ifdef HAVE__SNPRINTF_S
|
||||
#define snprintf_s(buf, bufsz, fmt, ...) (_snprintf_s((buf), (bufsz), (bufsz), (fmt), __VA_ARGS__))
|
||||
#else
|
||||
#define snprintf_s snprintf
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_STRCASECMP)
|
||||
#if defined(HAVE__STRICMP)
|
||||
#define strcasecmp _stricmp
|
||||
#elif defined(HAVE_STRICMP)
|
||||
#define strcasecmp stricmp
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRNCPY_S
|
||||
#define strncpy_s(dest, destsz, src, count) (strncpy((dest), (src), (count)), 0)
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRERROR_S
|
||||
#define strerrorlen_s(errnum) (strlen(strerror(errnum)))
|
||||
#define strerror_s(buf, bufsz, errnum) ((void)strncpy_s((buf), (bufsz), strerror(errnum), (bufsz)), (buf)[(bufsz) - 1] = '\0', strerrorlen_s(errnum) >= (bufsz))
|
||||
#else
|
||||
#ifndef HAVE_STRERRORLEN_S
|
||||
#define strerrorlen_s(errnum) 8192
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
#if SIZEOF_SIZE_T == 8
|
||||
#define SIZE_MAX ZIP_INT64_MAX
|
||||
#elif SIZEOF_SIZE_T == 4
|
||||
#define SIZE_MAX ZIP_INT32_MAX
|
||||
#elif SIZEOF_SIZE_T == 2
|
||||
#define SIZE_MAX ZIP_INT16_MAX
|
||||
#else
|
||||
#error unsupported size of size_t
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef PRId64
|
||||
#ifdef _MSC_VER
|
||||
#define PRId64 "I64d"
|
||||
#else
|
||||
#define PRId64 "lld"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef PRIu64
|
||||
#ifdef _MSC_VER
|
||||
#define PRIu64 "I64u"
|
||||
#else
|
||||
#define PRIu64 "llu"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef S_ISDIR
|
||||
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
|
||||
#ifndef S_ISREG
|
||||
#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
|
||||
#endif
|
||||
|
||||
#endif /* compat.h */
|
||||
Vendored
+101
-21
@@ -1,27 +1,107 @@
|
||||
#ifndef ZIP_HAD_CONFIG_H
|
||||
#define ZIP_HAD_CONFIG_H
|
||||
|
||||
#if !defined( __WIN32__ ) && !defined( _WIN32 )
|
||||
|
||||
#define HAVE_MKSTEMP
|
||||
#define HAVE_FSEEKO
|
||||
#define HAVE_FTELLO
|
||||
|
||||
#else
|
||||
|
||||
/* eepp: rename() cannot replace an existing file on Windows, which made every zip_close()
|
||||
of an existing archive fail. zipint.h then uses MoveFileExA(MOVEFILE_REPLACE_EXISTING). */
|
||||
#define HAVE_MOVEFILEEXA
|
||||
|
||||
#ifndef HAD_CONFIG_H
|
||||
#define HAD_CONFIG_H
|
||||
#ifndef _HAD_ZIPCONF_H
|
||||
#include "zipconf.h"
|
||||
#endif
|
||||
|
||||
#if (!defined (_MSCVER) && !defined (_MSC_VER))
|
||||
#ifndef ZIP_HAVE_UNISTD_H
|
||||
#define ZIP_HAVE_UNISTD_H
|
||||
#endif
|
||||
/* eepp: hand-written replacement for the CMake feature checks in config.h.in.
|
||||
Only deflate/store and traditional PKWARE encryption are built: bzip2, xz,
|
||||
zstd and WinZip AES (HAVE_CRYPTO) are disabled. Platform file backends live
|
||||
in posix/ and win32/. */
|
||||
|
||||
#define ENABLE_FDOPEN
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#define HAVE__CLOSE
|
||||
#define HAVE__DUP
|
||||
#define HAVE__FDOPEN
|
||||
#define HAVE__FILENO
|
||||
#define HAVE__FSEEKI64
|
||||
#define HAVE__FSTAT64
|
||||
#define HAVE__FTELLI64
|
||||
#define HAVE__SETMODE
|
||||
#define HAVE__SNPRINTF
|
||||
#define HAVE__STRDUP
|
||||
#define HAVE__STRICMP
|
||||
#define HAVE__STRTOI64
|
||||
#define HAVE__STRTOUI64
|
||||
#define HAVE__UNLINK
|
||||
#define HAVE_GETSECURITYINFO
|
||||
#define HAVE_SNPRINTF
|
||||
#define HAVE_STRTOLL
|
||||
#define HAVE_STRTOULL
|
||||
|
||||
/* MSVC and MinGW-w64 (MINGW_HAS_SECURE_API, on by default) both declare these. compat.h would
|
||||
otherwise define replacement macros that break MinGW's own declarations. */
|
||||
#define HAVE__SNPRINTF_S
|
||||
#define HAVE__SNWPRINTF_S
|
||||
#define HAVE_LOCALTIME_S
|
||||
#define HAVE_MEMCPY_S
|
||||
#define HAVE_STRERROR_S
|
||||
#define HAVE_STRNCPY_S
|
||||
|
||||
#ifndef _MSC_VER
|
||||
/* MinGW declares ftello; libzip still uses _fseeki64/_ftelli64 on Windows. */
|
||||
#define HAVE_FTELLO
|
||||
/* MSVC defines DWORD_MAX in intsafe.h; MinGW-w64 headers do not (win32/ named source). */
|
||||
#ifndef DWORD_MAX
|
||||
#define DWORD_MAX 0xffffffffUL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#else /* POSIX */
|
||||
|
||||
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) \
|
||||
|| defined(__DragonFly__) || defined(__ANDROID__)
|
||||
#define HAVE_ARC4RANDOM
|
||||
#endif
|
||||
|
||||
#define HAVE_FILENO
|
||||
#define HAVE_FSEEKO
|
||||
#define HAVE_FTELLO
|
||||
#define HAVE_LOCALTIME_R
|
||||
#define HAVE_RANDOM
|
||||
#define HAVE_SNPRINTF
|
||||
#define HAVE_STRCASECMP
|
||||
#define HAVE_STRDUP
|
||||
#define HAVE_STRINGS_H
|
||||
#define HAVE_STRTOLL
|
||||
#define HAVE_STRTOULL
|
||||
#ifndef HAVE_UNISTD_H
|
||||
#define HAVE_UNISTD_H
|
||||
#endif
|
||||
|
||||
/* off_t is 64-bit on these platforms regardless of _FILE_OFFSET_BITS. */
|
||||
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) \
|
||||
|| defined(__DragonFly__) || defined(__HAIKU__) || defined(__EMSCRIPTEN__) || defined(__LP64__) \
|
||||
|| defined(_LP64) || (defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64)
|
||||
#define SIZEOF_OFF_T 8
|
||||
#else
|
||||
#define SIZEOF_OFF_T 4
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
/* Fails to compile if the off_t guess above is wrong for a new target. */
|
||||
typedef char zip_eepp_off_t_size_check[sizeof(off_t) == SIZEOF_OFF_T ? 1 : -1];
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#define HAVE_STDBOOL_H
|
||||
|
||||
#if defined(__SIZEOF_SIZE_T__)
|
||||
#define SIZEOF_SIZE_T __SIZEOF_SIZE_T__
|
||||
#elif defined(_WIN64)
|
||||
#define SIZEOF_SIZE_T 8
|
||||
#else
|
||||
#define SIZEOF_SIZE_T 4
|
||||
#endif
|
||||
|
||||
#define PACKAGE "libzip"
|
||||
#define VERSION "0.10"
|
||||
#define VERSION "1.12.1"
|
||||
|
||||
#endif
|
||||
#endif /* HAD_CONFIG_H */
|
||||
|
||||
Vendored
-166
@@ -1,166 +0,0 @@
|
||||
/* Adapted from NetBSB libc by Dieter Baron */
|
||||
|
||||
/* NetBSD: gettemp.c,v 1.13 2003/12/05 00:57:36 uebayasi Exp */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1987, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
#if ( defined (_MSCVER) || defined (_MSC_VER) )
|
||||
typedef int pid_t;
|
||||
|
||||
# define _IFMT 0170000 // type of file
|
||||
# define _IFDIR 0040000 // directory
|
||||
# define S_ISDIR(m) (((m)&_IFMT) == _IFDIR)
|
||||
#endif
|
||||
|
||||
#if !defined( __WIN32__ ) && !defined( _WIN32 )
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined( _WIN32 )
|
||||
#include <process.h>
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
int
|
||||
_zip_mkstemp(char *path)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
int ret;
|
||||
ret = _creat(_mktemp(path), _S_IREAD|_S_IWRITE);
|
||||
if (ret == -1) {
|
||||
return 0;
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
int fd;
|
||||
char *start, *trv;
|
||||
struct stat sbuf;
|
||||
pid_t pid;
|
||||
|
||||
/* To guarantee multiple calls generate unique names even if
|
||||
the file is not created. 676 different possibilities with 7
|
||||
or more X's, 26 with 6 or less. */
|
||||
static char xtra[2] = "aa";
|
||||
int xcnt = 0;
|
||||
|
||||
pid = getpid();
|
||||
|
||||
/* Move to end of path and count trailing X's. */
|
||||
for (trv = path; *trv; ++trv)
|
||||
if (*trv == 'X')
|
||||
xcnt++;
|
||||
else
|
||||
xcnt = 0;
|
||||
|
||||
/* Use at least one from xtra. Use 2 if more than 6 X's. */
|
||||
if (*(trv - 1) == 'X')
|
||||
*--trv = xtra[0];
|
||||
if (xcnt > 6 && *(trv - 1) == 'X')
|
||||
*--trv = xtra[1];
|
||||
|
||||
/* Set remaining X's to pid digits with 0's to the left. */
|
||||
while (*--trv == 'X') {
|
||||
*trv = (pid % 10) + '0';
|
||||
pid /= 10;
|
||||
}
|
||||
|
||||
/* update xtra for next call. */
|
||||
if (xtra[0] != 'z')
|
||||
xtra[0]++;
|
||||
else {
|
||||
xtra[0] = 'a';
|
||||
if (xtra[1] != 'z')
|
||||
xtra[1]++;
|
||||
else
|
||||
xtra[1] = 'a';
|
||||
}
|
||||
|
||||
/*
|
||||
* check the target directory; if you have six X's and it
|
||||
* doesn't exist this runs for a *very* long time.
|
||||
*/
|
||||
for (start = trv + 1;; --trv) {
|
||||
if (trv <= path)
|
||||
break;
|
||||
if (*trv == '/') {
|
||||
*trv = '\0';
|
||||
if (stat(path, &sbuf))
|
||||
return (0);
|
||||
if (!S_ISDIR(sbuf.st_mode)) {
|
||||
errno = ENOTDIR;
|
||||
return (0);
|
||||
}
|
||||
*trv = '/';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if ((fd=open(path, O_CREAT|O_EXCL|O_RDWR|O_BINARY, 0600)) >= 0)
|
||||
return (fd);
|
||||
if (errno != EEXIST)
|
||||
return (0);
|
||||
|
||||
/* tricky little algorithm for backward compatibility */
|
||||
for (trv = start;;) {
|
||||
if (!*trv)
|
||||
return (0);
|
||||
if (*trv == 'z')
|
||||
*trv++ = 'a';
|
||||
else {
|
||||
if (isdigit((unsigned char)*trv))
|
||||
*trv = 'a';
|
||||
else
|
||||
++*trv;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
#endif
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user