diff --git a/build-undici-tarball.sh b/build-undici-tarball.sh new file mode 100644 index 0000000000000000000000000000000000000000..6d9760d25f95b827c4dd75eb781bcc3a4a443bef --- /dev/null +++ b/build-undici-tarball.sh @@ -0,0 +1,205 @@ +#!/usr/bin/env bash + +# ============================================================================= +# build-undici-tarball.sh +# +# 从 undici 源码构建 Node.js 所需的产物并打包为 tar.gz。 +# +# Node.js deps/undici/ 目录结构(即本脚本的产物结构): +# deps/undici/ +# ├── undici.js ← esbuild bundle,来自 undici 源码根目录的 undici-fetch.js +# └── src/ ← undici 源码的【整个根目录】内容(含 lib/、build/、docs/ 等) +# ├── lib/ +# │ └── llhttp/ ← WASM 文件输出到这里 +# ├── build/ +# ├── docs/ +# ├── package.json +# └── ... +# +# 构建流程(与官方 update-undici.sh 一致): +# 1. 从 GitHub 下载 undici v 源码 +# 2. npm install(安装 esbuild 等 devDependencies) +# 3. npm run build:node → 生成 undici-fetch.js(即 deps/undici/undici.js) +# 4. npm run build:wasm → Docker 重建 llhttp WASM,输出到 lib/llhttp/ +# 5. 打包: +# - undici-fetch.js → undici/undici.js +# - 源码整个根目录 → undici/src/ +# +# 依赖: +# - curl / tar / node / npm +# - Docker(仅 build:wasm 阶段需要,跳过时用源码中已有的 WASM) +# +# 用法: +# ./build-undici-tarball.sh [版本号] [--skip-wasm] +# +# 示例: +# ./build-undici-tarball.sh 6.24.0 # 完整构建(含 WASM) +# ./build-undici-tarball.sh 6.24.0 --skip-wasm # 跳过 WASM 重编译 +# ============================================================================= + +set -e +set -o pipefail + +# -------------------------------------------------------------------------- +# 参数处理 +# -------------------------------------------------------------------------- +UNDICI_VERSION="${1:-6.24.0}" +SKIP_WASM=false +for arg in "$@"; do + [[ "$arg" == "--skip-wasm" ]] && SKIP_WASM=true +done + +OUTPUT_FILE="undici-${UNDICI_VERSION}-nodejs.tar.gz" +GITHUB_TARBALL="https://github.com/nodejs/undici/archive/refs/tags/v${UNDICI_VERSION}.tar.gz" + +# -------------------------------------------------------------------------- +# 颜色输出 +# -------------------------------------------------------------------------- +RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m' +info() { echo -e "${BLUE}[INFO]${NC} $*"; } +success() { echo -e "${GREEN}[OK]${NC} $*"; } +warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } +error() { echo -e "${RED}[ERROR]${NC} $*" >&2; exit 1; } + +# -------------------------------------------------------------------------- +# 前置检查 +# -------------------------------------------------------------------------- +for cmd in curl tar node npm; do + command -v "$cmd" &>/dev/null || error "缺少必要工具:$cmd,请先安装。" +done + +if [[ "$SKIP_WASM" == false ]] && ! command -v docker &>/dev/null; then + warn "未找到 docker,将自动跳过 WASM 重编译(使用源码仓库中已有的 WASM 文件)。" + SKIP_WASM=true +fi + +# -------------------------------------------------------------------------- +# 主流程 +# -------------------------------------------------------------------------- +echo "" +echo "============================================================" +echo " undici 源码构建打包脚本" +echo " 目标版本 : ${UNDICI_VERSION}" +echo " 输出文件 : ${OUTPUT_FILE}" +echo " 跳过 WASM : ${SKIP_WASM}" +echo "============================================================" +echo "" + +TMPDIR=$(mktemp -d) +trap 'rm -rf "${TMPDIR}"' EXIT +info "临时目录:${TMPDIR}" + +# -------------------------------------------------------------------------- +# 1. 下载源码 +# -------------------------------------------------------------------------- +info "从 GitHub 下载 undici v${UNDICI_VERSION} 源码..." +curl -fsSL "${GITHUB_TARBALL}" -o "${TMPDIR}/undici-src.tar.gz" \ + || error "下载失败,请检查版本号 ${UNDICI_VERSION} 是否存在。" +success "下载完成。" + +info "解压源码..." +tar -xzf "${TMPDIR}/undici-src.tar.gz" -C "${TMPDIR}" +# GitHub archive 解压后目录名为 undici- +SRC_DIR="${TMPDIR}/undici-${UNDICI_VERSION}" +[[ -d "$SRC_DIR" ]] || error "解压后未找到 ${SRC_DIR},包结构异常。" +success "源码解压到:${SRC_DIR}" + +# -------------------------------------------------------------------------- +# 2. npm install +# -------------------------------------------------------------------------- +info "安装 devDependencies(含 esbuild)..." +cd "${SRC_DIR}" +npm install --prefer-offline 2>&1 | tail -5 +success "npm install 完成。" + +# -------------------------------------------------------------------------- +# 3. build:node → undici-fetch.js(对应 deps/undici/undici.js) +# -------------------------------------------------------------------------- +info "执行 npm run build:node(esbuild 打包)..." +npm run build:node +[[ -f "${SRC_DIR}/undici-fetch.js" ]] \ + || error "build:node 执行后未生成 undici-fetch.js,请检查构建日志。" +success "undici-fetch.js 生成成功($(wc -c < "${SRC_DIR}/undici-fetch.js") 字节)。" + +# -------------------------------------------------------------------------- +# 4. build:wasm → lib/llhttp/ 中的 .wasm 文件 +# (对应 deps/undici/src/lib/llhttp/) +# -------------------------------------------------------------------------- +if [[ "$SKIP_WASM" == false ]]; then + info "执行 npm run build:wasm(Docker 构建 llhttp WASM)..." + info "Docker 会将 WASM 文件输出到源码目录的 lib/llhttp/ 下..." + npm run build:wasm + WASM_COUNT=$(find "${SRC_DIR}/lib/llhttp" -name "*.wasm" 2>/dev/null | wc -l) + success "WASM 构建完成,共生成 ${WASM_COUNT} 个 .wasm 文件。" +else + warn "跳过 WASM 重编译,将使用源码仓库中已有的 WASM 文件。" + warn "(对于纯 JS 层的安全修复,通常无需重编译 WASM。)" +fi + +# -------------------------------------------------------------------------- +# 5. 整理产物目录 +# +# 产物结构对应 Node.js deps/undici/: +# undici/undici.js ← 来自 undici-fetch.js +# undici/src/ ← 来自 undici 源码【整个根目录】 +# -------------------------------------------------------------------------- +STAGING="${TMPDIR}/staging/undici" +mkdir -p "${STAGING}" + +# undici-fetch.js → undici/undici.js(对应 deps/undici/undici.js) +cp -f "${SRC_DIR}/undici-fetch.js" "${STAGING}/undici.js" +success "已复制 undici-fetch.js → undici/undici.js" + +# 源码整个根目录 → undici/src/(对应 deps/undici/src/) +# 注意:不是 SRC_DIR/src/ 子目录,而是 SRC_DIR 本身(即 undici 源码根目录) +# 排除 node_modules 和临时产物,保持与官方一致 +info "拷贝源码根目录 → undici/src/(排除 node_modules)..." +mkdir -p "${STAGING}/src" +rsync -a --exclude='node_modules' --exclude='.git' "${SRC_DIR}/" "${STAGING}/src/" \ + || { warn "rsync 不可用,尝试 cp..."; cp -r "${SRC_DIR}/." "${STAGING}/src/"; rm -rf "${STAGING}/src/node_modules" "${STAGING}/src/.git"; } + +SRC_FILES=$(find "${STAGING}/src" | wc -l) +success "源码目录拷贝完成(共 ${SRC_FILES} 个条目)。" + +# -------------------------------------------------------------------------- +# 6. 打包 +# -------------------------------------------------------------------------- +cd - > /dev/null +info "打包为 ${OUTPUT_FILE}..." +tar -czf "${OUTPUT_FILE}" -C "${TMPDIR}/staging" undici +success "打包完成:${OUTPUT_FILE}" + +# -------------------------------------------------------------------------- +# 7. 清单 + 使用说明 +# -------------------------------------------------------------------------- +echo "" +info "包顶层结构:" +# 只显示前两层,避免输出过长 +tar -tzf "${OUTPUT_FILE}" | awk -F'/' 'NF<=3' | sort -u | sed 's/^/ /' + +WASM_FILES=$(tar -tzf "${OUTPUT_FILE}" | grep '\.wasm$' || true) +echo "" +if [[ -n "$WASM_FILES" ]]; then + success "包含 WASM 文件:" + echo "$WASM_FILES" | sed 's/^/ /' +else + warn "未在产物中检测到 .wasm 文件,请确认 lib/llhttp/ 目录是否完整。" +fi + +echo "" +echo "============================================================" +success "构建完成!" +echo "" +echo " 产物文件 : $(realpath "${OUTPUT_FILE}")" +echo "" +echo " 解压后将内容覆盖到 Node.js 源码 deps/undici/ 目录:" +echo "" +echo " tar -xzf ${OUTPUT_FILE}" +echo " cp -f undici/undici.js /deps/undici/undici.js" +echo " cp -rf undici/src/ /deps/undici/src/" +echo "" +echo " 如需同时更新版本头文件:" +echo " sed -i 's/UNDICI_VERSION \".*\"/UNDICI_VERSION \"${UNDICI_VERSION}\"/' \\" +echo " /src/undici_version.h" +echo "============================================================" +echo "" diff --git a/nodejs20.spec b/nodejs20.spec index b4fdaf9b334dadab861a23d557cc168a8e74c840..930aa2435580c4f25fc31fbd208e62620d4fdf24 100644 --- a/nodejs20.spec +++ b/nodejs20.spec @@ -6,8 +6,8 @@ %global nodejs_soversion 115 %global nodejs_abi %{nodejs_soversion} %global nodejs_ver %{nodejs_major}.%{nodejs_minor}.%{nodejs_patch} -%global nodejs_rel 1%{?dist} -%global nodejs_envr %{nodejs_ver}-%{nodejs_rel} +%global nodejs_rel 2 +%global nodejs_envr %{nodejs_ver}-%{nodejs_rel}%{?dist} %global nodejs_datadir %{_datarootdir}/node-%{nodejs_major} # == Bundled Dependency Versions == @@ -71,6 +71,8 @@ # histogram_c - assumed from timestamps %global histogram_version 0.9.7 +%global undici_version 6.24.0 + %bcond_with bootstrap %bcond_without bundled_cjs_module_lexer @@ -99,7 +101,7 @@ Summary: JavaScript runtime Name: nodejs%{nodejs_major} Version: %{nodejs_ver} -Release: %{nodejs_rel} +Release: %{nodejs_rel}%{?dist} License: Apache-2.0 AND Artistic-2.0 AND BSD-2-Clause AND BSD-3-Clause AND BlueOak-1.0.0 AND CC-BY-3.0 AND CC0-1.0 AND ISC AND MIT Group: Development/Languages URL: http://nodejs.org/ @@ -109,6 +111,9 @@ Source2: btest402.js # The binary data that icu-small can use to get icu-full capability Source3: https://github.com/unicode-org/icu/releases/download/release-%{icu_major}-%{icu_minor}/icu4c-%{icu_major}_%{icu_minor}-data-bin-b.zip Source4: https://github.com/unicode-org/icu/releases/download/release-%{icu_major}-%{icu_minor}/icu4c-%{icu_major}_%{icu_minor}-data-bin-l.zip +# fixed CVEs that nodejs has not fixed +# from build-undici-tarball.sh +Source5: undici-6.24.0-nodejs.tar.gz Source200: nodejs-sources.sh Source201: npmrc.builtin.in Source202: nodejs.pc.in @@ -171,14 +176,14 @@ BuildRequires: zlib-devel %endif %if %{with bundled_cjs_module_lexer} -Provides: bundled(nodejs-cjs-module-lexer) = 1.4.1 +Provides: bundled(nodejs-cjs-module-lexer) = 2.1.0 %else BuildRequires: nodejs-cjs-module-lexer Requires: nodejs-cjs-module-lexer %endif %if %{with bundled_undici} -Provides: bundled(nodejs-undici) = 6.21.2 +Provides: bundled(nodejs-undici) = %{undici_version} %else BuildRequires: nodejs-undici Requires: nodejs-undici @@ -284,6 +289,12 @@ rm -rf deps/undici pfiles=( $(grep -rl python) ) %py3_shebang_fix ${pfiles[@]} +# fixed CVEs in undici +pushd deps +rm -rf undici +tar axvf %{SOURCE5} +popd + %build %global optflags %(echo %{optflags} | sed 's/-g /-g1 /') @@ -548,29 +559,33 @@ end %changelog -* Fri Jan 30 2026 Zhao Zhen - 20.20.0-1 +* Thu Mar 19 2026 Zhao Zhen - 20.20.0-2 +- fixed CVE-2026-1526 CVE-2026-1528 CVE-2026-2229 CVE-2026-1525 via +- upgrading undici from 6.23.0 to 6.24.0 + +* Fri Jan 30 2026 Zhao Zhen - 20.20.0-1 - fixed CVE-2025-59465 CVE-2025-55131 CVE-2026-21637 CVE-2025-59466 - CVE-2025-55132 CVE-2025-55130 -* Tue Dec 09 2025 Zhao Zhen - 20.19.6-1 +* Tue Dec 09 2025 Zhao Zhen - 20.19.6-1 - upgraded to upstream 20.19.6 -* Fri Aug 08 2025 Zhao Zhen - 20.19.2-3 +* Fri Aug 08 2025 Zhao Zhen - 20.19.2-3 - fixed an error that npm requires nodejs18 * Wed Jun 11 2025 bbrucezhang - 20.19.2-2 - Rebuilt for loongarch64 -* Mon May 26 2025 Zhao Zhen - 20.19.2-1 +* Mon May 26 2025 Zhao Zhen - 20.19.2-1 - fixed CVE-2025-23165 CVE-2025-23166 CVE-2025-23167 CVE-2025-47279 -* Mon Apr 14 2025 Zhao Zhen - 20.19.0-3 +* Mon Apr 14 2025 Zhao Zhen - 20.19.0-3 - adapt bootstrap specfile macro -* Mon Apr 14 2025 Zhao Zhen - 20.19.0-2 +* Mon Apr 14 2025 Zhao Zhen - 20.19.0-2 - fixed execute of nodejs20 by include bundled lexer.js and undici -* Fri Apr 11 2025 Zhao Zhen - 20.19.0-1 +* Fri Apr 11 2025 Zhao Zhen - 20.19.0-1 - upgraded to upstream 20.19.0 - fixed CVE-2025-23083 CVE-2025-23085 CVE-2025-23084 CVE-2025-22150 - CVE-2024-36138 CVE-2024-22020 CVE-2024-22018 CVE-2024-36137 CVE-2024-37372 diff --git a/sources b/sources index 56ce7cbe027e539d44c31b2a281a879290bde1d8..9ef9c5cbc88d390c91c56da2892af5f498360475 100644 --- a/sources +++ b/sources @@ -1,3 +1,4 @@ SHA512 (icu4c-77_1-data-bin-b.zip) = 93b4c8228a059546e7c3e337f1f837db255c0046c15f50a31a7bd20daf361174edab05b01faaac1dd4f515ca3c1f1d7fb0f61e4177eb5631833ad1450e252c4e SHA512 (icu4c-77_1-data-bin-l.zip) = 3de15bb5925956b8e51dc6724c2114a1009ec471a2241b09ae09127f1760f44d02cc29cfbeed6cbaac6ee880553ac8395c61c6043c00ddba3277233e19e6490e SHA512 (node-v20.20.0.tar.gz) = 3c6238cfb46f2ca1b77dd6150b692a6715befd2dcdbdb8b59b076d3ead05e06344ed762321995105eab34837d527d0b69119d7686038bfcc86e7ab9d0d81072d +SHA512 (undici-6.24.0-nodejs.tar.gz) = 25bd80df7c2d561bc8362a77dc304f5f3c974ba0ade53b4dccf29bcce6be50ab34005ca10c3688cd79c673afb8af80f086061ad57fb5f5e964458132714af526