mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-10-24 19:30:10 +08:00
fix(bundle): bundle Node 24.22.1, the October security release, and verify the download (#2817)
Release bundles were set to ship Node 24.21.0. The release workflow runs build-bundle.sh with no version, so the script's default decides the Node every bundle carries, and that default predates Node's October 2026 security release. v24.22.1 (2026-10-20) fixes 8 CVEs, 4 rated High (TLS, DNS, Brotli), and ships OpenSSL 3.5.9. It keeps V8 13.6.233.17, libuv 1.52.1 and module ABI 137, and it carries 24.20.0's fix for the Windows abort at exit (issue #2617). The script also never checked the Node download against the SHA-256 sums nodejs.org publishes. Fix: - The default and the usage example move to v24.22.1. The comment and a new test hold the default at 24.22.1 or later, on 24.x. - Step 1 downloads the release's SHASUMS256.txt and refuses the archive, before unpacking anything, unless its SHA-256 matches the listed one. The zip and tar.gz downloads now share that one code path (sha256sum, or shasum on macOS). - The unreleased CHANGELOG bullet for issue #2617 now names 24.22.1 and the check. BUNDLING.md describes the check. Validation (Windows 11 x64): - bundle-launcher.test.ts: 4 new tests (the version floor; a matching download is unpacked; a mismatched or unlisted one is refused before unpacking). With main's build-bundle.sh all 4 fail; with the fix the file has 7 passed and 3 POSIX-only skipped. - build-bundle.sh win32-x64 with the new default: the check passed (sha256 d2046d28...8b95fa5, as listed). The bundled node.exe is byte-identical to the official v24.22.1 one and prints v24.22.1 (OpenSSL 3.5.9). Its launchers from Git Bash, cmd and PowerShell, with no system Node on PATH, ran --version, init, status, query, callers and sync on a small TypeScript + Python fixture: all exit 0. - Node's own reproducer for the exit abort, 300 runs per mode, 4 at a time: the bundled v24.22.1 exited cleanly 300/300 in all three modes. The official v24.16.0 control aborted 299/300 with 0xC0000409 when the child ran directly. - 13 runtime-facing test files (sqlite, wasm flags, worker and stdin teardown, watcher, launcher, shim) run on the bundled node.exe: 136 passed, 22 skipped, 0 failed. Fixes #2780 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
df1cd1e185
commit
b8c3c032be
+36
-18
@@ -13,7 +13,7 @@
|
||||
# scripts/build-bundle.sh <target> [node-version]
|
||||
# target: darwin-arm64 | darwin-x64 | linux-x64 | linux-arm64
|
||||
# | win32-x64 | win32-arm64
|
||||
# node-version: e.g. v24.21.0 (default below; pin for reproducible builds)
|
||||
# node-version: e.g. v24.22.1 (default below; pin for reproducible builds)
|
||||
#
|
||||
# Output:
|
||||
# unix: release/codegraph-<target>.tar.gz (launcher: bin/codegraph)
|
||||
@@ -22,12 +22,13 @@ set -euo pipefail
|
||||
|
||||
TARGET="${1:?usage: build-bundle.sh <target> [node-version]}"
|
||||
# The release workflow passes no version, so this default is the Node every
|
||||
# release bundles. Keep it on 24.x (the CLI refuses Node 25+) and at 24.20.0 or
|
||||
# later: older 24.x releases can abort on Windows just as the process exits,
|
||||
# after its work is done, with 0xC0000409 and "Assertion failed:
|
||||
# !(handle->flags & UV_HANDLE_CLOSING), file src\win\async.c" (nodejs/node#56645,
|
||||
# fixed by nodejs/node#61999 in 24.20.0; issue #2617).
|
||||
NODE_VERSION="${2:-v24.21.0}"
|
||||
# release bundles. Keep it on 24.x (the CLI refuses Node 25+) and at 24.22.1 or
|
||||
# later. 24.22.1 is Node's October 2026 security release (issue #2780). Before
|
||||
# 24.20.0, Node 24 can abort on Windows just as the process exits, after its
|
||||
# work is done, with 0xC0000409 and "Assertion failed: !(handle->flags &
|
||||
# UV_HANDLE_CLOSING), file src\win\async.c" (nodejs/node#56645, fixed by
|
||||
# nodejs/node#61999; issue #2617).
|
||||
NODE_VERSION="${2:-v24.22.1}"
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
OUT="$ROOT/release"
|
||||
@@ -39,24 +40,41 @@ OSFAM="${TARGET%-*}" # darwin | linux | win32
|
||||
|
||||
echo "[bundle] target=${TARGET} node=${NODE_VERSION}"
|
||||
|
||||
# 1. Download + extract the official Node runtime for the target platform.
|
||||
# 1. Download + extract the official Node runtime for the target platform. The
|
||||
# archive must match the SHA-256 that nodejs.org publishes for the release
|
||||
# before anything is unpacked, so a bundle ships exactly that release's
|
||||
# official build, never a truncated or substituted download (issue #2780).
|
||||
if [ "$OSFAM" = "win32" ]; then
|
||||
NODE_DIST="node-${NODE_VERSION}-win-${ARCH}"
|
||||
NODE_URL="https://nodejs.org/dist/${NODE_VERSION}/${NODE_DIST}.zip"
|
||||
echo "[bundle] downloading ${NODE_URL}"
|
||||
curl -fsSL "$NODE_URL" -o "$WORK/node.zip"
|
||||
NODE_ARCHIVE="${NODE_DIST}.zip"
|
||||
else
|
||||
NODE_DIST="node-${NODE_VERSION}-${TARGET}"
|
||||
NODE_ARCHIVE="${NODE_DIST}.tar.gz"
|
||||
fi
|
||||
NODE_URL="https://nodejs.org/dist/${NODE_VERSION}/${NODE_ARCHIVE}"
|
||||
echo "[bundle] downloading ${NODE_URL}"
|
||||
curl -fsSL "$NODE_URL" -o "$WORK/$NODE_ARCHIVE"
|
||||
curl -fsSL "https://nodejs.org/dist/${NODE_VERSION}/SHASUMS256.txt" -o "$WORK/SHASUMS256.txt"
|
||||
EXPECTED_SHA="$(awk -v name="$NODE_ARCHIVE" '$2 == name { print $1 }' "$WORK/SHASUMS256.txt")"
|
||||
if command -v sha256sum >/dev/null 2>&1; then
|
||||
ACTUAL_SHA="$(sha256sum < "$WORK/$NODE_ARCHIVE" | cut -d' ' -f1)"
|
||||
else
|
||||
ACTUAL_SHA="$(shasum -a 256 < "$WORK/$NODE_ARCHIVE" | cut -d' ' -f1)" # macOS
|
||||
fi
|
||||
if [ -z "$EXPECTED_SHA" ] || [ "$ACTUAL_SHA" != "$EXPECTED_SHA" ]; then
|
||||
echo "[bundle] error: ${NODE_ARCHIVE} does not match the SHA-256 that nodejs.org lists for ${NODE_VERSION} (listed: ${EXPECTED_SHA:-nothing}, downloaded: ${ACTUAL_SHA})" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "[bundle] verified ${NODE_ARCHIVE} against nodejs.org's SHASUMS256.txt (sha256 ${ACTUAL_SHA})"
|
||||
if [ "$OSFAM" = "win32" ]; then
|
||||
if command -v unzip >/dev/null 2>&1; then
|
||||
unzip -q "$WORK/node.zip" -d "$WORK"
|
||||
unzip -q "$WORK/$NODE_ARCHIVE" -d "$WORK"
|
||||
else
|
||||
tar -xf "$WORK/node.zip" -C "$WORK" # bsdtar can read zip
|
||||
tar -xf "$WORK/$NODE_ARCHIVE" -C "$WORK" # bsdtar can read zip
|
||||
fi
|
||||
NODE_BIN="$WORK/${NODE_DIST}/node.exe"
|
||||
else
|
||||
NODE_DIST="node-${NODE_VERSION}-${TARGET}"
|
||||
NODE_URL="https://nodejs.org/dist/${NODE_VERSION}/${NODE_DIST}.tar.gz"
|
||||
echo "[bundle] downloading ${NODE_URL}"
|
||||
curl -fsSL "$NODE_URL" -o "$WORK/node.tar.gz"
|
||||
tar -xzf "$WORK/node.tar.gz" -C "$WORK"
|
||||
tar -xzf "$WORK/$NODE_ARCHIVE" -C "$WORK"
|
||||
NODE_BIN="$WORK/${NODE_DIST}/bin/node"
|
||||
fi
|
||||
[ -f "$NODE_BIN" ] || { echo "[bundle] error: node binary not found ($NODE_BIN)" >&2; exit 1; }
|
||||
|
||||
Reference in New Issue
Block a user