Skip to content

chore: batch dependency updates and fix brace-expansion advisory - #393

Merged
agoldis merged 1 commit into
mainfrom
deps/batch-2026-07-30
Jul 30, 2026
Merged

chore: batch dependency updates and fix brace-expansion advisory#393
agoldis merged 1 commit into
mainfrom
deps/batch-2026-07-30

Conversation

@currents-codebot

@currents-codebot currents-codebot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

User description

Consolidates the mergeable Dependabot PRs into a single lockfile-consistent change and resolves the one open Dependabot alert.

Dependency updates

Supersedes #384, #385, #386, #387 — same bumps, one regenerated lockfile:

Package From To
xmlbuilder2 3.1.1 4.0.3
@release-it/conventional-changelog 10.0.1 12.0.0 (all packages)
@babel/preset-env 7.26.9 8.0.2 (examples/jest)
@typescript-eslint/parser 8.0.0 8.65.0

Security fix — GHSA-mh99-v99m-4gvg / CVE-2026-14257 (high)

The top-level bump in #382 left 9 nested copies on vulnerable 1.1.16/2.1.2, which is why alert #170 stayed open. Each major line has its own backport, so per-major overrides patch every copy without forcing a breaking jest-config major.

All 10 copies now resolve to 1.1.18 / 2.1.4 / 5.0.9.

Verification

  • npm ci succeeds — lockfile and manifests in sync
  • build 7/7, lint 2/2, types 3/3, unit tests 136/136
  • prettier --check unchanged vs main (same 7 pre-existing warnings)
  • TypeScript and prettier resolve identically to main — no incidental drift
  • xmlbuilder2 3.x vs 4.x: byte-identical JUnit XML for this codebase's usage, covering unicode, XML escaping, CDATA, and ]]> sequences
  • brace-expansion: the advisory PoC ('{a,b}'.repeat(1500)), which crashed the process with an uncatchable OOM, returns bounded output on all three major lines
  • preset-env 8: examples/jest results identical to main (the one failure is an intentional [failed] fixture)

Excluded: @babel/code-frame 8.0.0 (#383, #389)

Not included — it is a silent output regression. v8 changed column from 1-based to 0-based:

v7 column=1 -> "    | ^"
v8 column=0 -> "    | ^"     # same caret, different input

packages/jest/src/lib/error.ts:45 parses the column from a V8 stack trace, and V8 stack columns are 1-based. Feeding that to v8 shifts every code-frame caret one column right:

v7 (current)          v8 (proposed)
> 1 | throw new Er…    > 1 | throw new Er…
    |       ^              |        ^        <- off by one

The jest package has no tests, so this would have merged unnoticed. It needs a compensating column - 1, which belongs in its own reviewed change.

Suggested follow-ups

🤖 Generated with Claude Code


Generated description

Below is a concise technical summary of the changes proposed in this PR:
Batch the workspace dependency bumps across the release, lint, and example test flows, updating the affected package manifests and regenerating the lockfile. Patch brace-expansion with root overrides so packages/jest and packages/node-test-reporter resolve only fixed nested copies.

TopicDetails
Dependency updates Refresh the batched dependency versions in the root workspace, examples, and package manifests, then regenerate package-lock.json to keep everything lockfile-consistent.
Modified files (6)
  • examples/jest/package.json
  • package-lock.json
  • package.json
  • packages/cmd/package.json
  • packages/jest/package.json
  • packages/node-test-reporter/package.json
Latest Contributors(2)
UserCommitDate
agoldis@gmail.comchore: batch dependenc...July 30, 2026
agoldis@users.noreply....chore: update js-yaml,...July 26, 2026
Security patch Apply root overrides to force all brace-expansion majors onto patched releases and clear the open advisory.
Modified files (2)
  • package-lock.json
  • package.json
Latest Contributors(2)
UserCommitDate
agoldis@gmail.comchore: batch dependenc...July 30, 2026
agoldis@users.noreply....chore: update js-yaml,...July 26, 2026
Review this PR on Baz | Customize your next review

Consolidates the mergeable Dependabot PRs into a single lockfile-consistent
change, and resolves GHSA-mh99-v99m-4gvg (CVE-2026-14257).

Dependency updates (supersedes #384, #385, #386, #387):
- xmlbuilder2 3.1.1 -> 4.0.3
- @release-it/conventional-changelog 10.0.1 -> 12.0.0 (all packages)
- @babel/preset-env 7.26.9 -> 8.0.2 (examples/jest)
- @typescript-eslint/parser 8.0.0 -> 8.65.0

Security fix:
brace-expansion had 9 nested copies still on vulnerable 1.1.16/2.1.2 even
after the top-level bump in #382, which is why the alert stayed open. Each
major line has its own backport, so per-major overrides patch every copy
without forcing a breaking jest-config major.

Verified: xmlbuilder2 3.x and 4.x produce byte-identical JUnit XML for this
codebase's usage (unicode, XML escaping, CDATA, "]]>" sequences). The
advisory PoC ('{a,b}'.repeat(1500)), which crashed the process with an
uncatchable OOM, now returns bounded output on all three major lines.

Excludes @babel/code-frame 8.0.0 (#383, #389): v8 changed `column` from
1-based to 0-based. error.ts parses columns from V8 stack traces, which are
1-based, so the bump shifts every code-frame caret one column right. Needs a
compensating fix, so it is left for a separate change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • Chores
    • Updated development tooling and release automation packages.
    • Upgraded XML document-building support.
    • Updated the Jest example’s Babel preset.
    • Added version overrides for a transitive package to improve dependency consistency.

Walkthrough

Updated dependency declarations across the repository. The root manifest adds brace-expansion overrides and upgrades @typescript-eslint/parser. Package manifests upgrade @release-it/conventional-changelog; the node test reporter also upgrades xmlbuilder2. The Jest example upgrades @babel/preset-env.

Suggested reviewers: twk3

🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR does not implement the linked @babel/code-frame 8.0.0 upgrade or its required column and Node.js changes. Add the @babel/code-frame 8.0.0 manifest and lockfile updates, handle 0-based columns and Node 22.18+/24.11+ requirements, then rerun tests.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title is a valid conventional commit and matches the PR's dependency-update and advisory-fix scope.
Description check ✅ Passed The description clearly relates to the dependency consolidation and brace-expansion security fix.
Out of Scope Changes check ✅ Passed The changed manifests and overrides align with the stated dependency-consolidation and security-fix goals.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch deps/batch-2026-07-30

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed: dependency version conflict. Check your lock file or package.json.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@package.json`:
- Around line 32-37: Update the brace-expansion entries in the package.json
overrides object to patched versions newer than 1.1.18, 2.1.4, and 5.0.7,
covering every listed major version and ensuring the lockfile resolves only
non-vulnerable releases for GHSA-mh99-v99m-4gvg.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: bc70d56c-bc2c-4257-aec5-5f09b5d83ea6

📥 Commits

Reviewing files that changed from the base of the PR and between 518e5e5 and e213183.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json, !package-lock.json
📒 Files selected for processing (5)
  • examples/jest/package.json
  • package.json
  • packages/cmd/package.json
  • packages/jest/package.json
  • packages/node-test-reporter/package.json

Comment thread package.json
@currents-codebot

Copy link
Copy Markdown
Contributor Author

Thanks — I dug into this, but I don't think the finding holds. 1.1.18 and 2.1.4 are the patched releases for their major lines, so no change is needed here.

Why npm audit still flags them

The advisory declares a single range, expressed only in 5.x terms:

vulnerable_version_range: <= 5.0.7
first_patched_version:    5.0.8

It never enumerates the per-major backports. Under a literal semver read, 1.1.18 <= 5.0.7 is true, so npm audit flags every 1.x/2.x node by version comparison alone — regardless of whether the fix is actually in the code. That's what the npm audit output in the analysis is showing.

The backports do contain the fix

Both cite the CVE by name and implement exactly the bound the advisory's remediation section prescribes:

// node_modules/glob/node_modules/brace-expansion/index.js  (v1.1.18)
// (CVE-2026-14257). `EXPANSION_MAX_LENGTH` bounds the total number of
var EXPANSION_MAX_LENGTH = 4000000
var maxLength = options.maxLength == null ? EXPANSION_MAX_LENGTH : options.maxLength;
if (length + expansion.length > maxLength) return out

Identical in 2.1.4. Publish timeline confirms a coordinated backport release — the advisory landed 2026-07-24, and all three lines shipped today within 17 minutes of each other:

version published
5.0.7 (vulnerable) 2026-06-29
5.0.9 2026-07-30 10:00:32Z
2.1.4 2026-07-30 10:15:01Z
1.1.18 2026-07-30 10:17:06Z

Verified behaviourally

The advisory's own PoC — expand('{a,b}'.repeat(1500)), which kills a vulnerable process with an uncatchable OOM that try/catch cannot trap — returns bounded output on all three lines:

v1.1.18 -> PoC bounded: 2666 results in 382ms | correctness: ["a1","a2","b1","b2"]
v2.1.4  -> PoC bounded: 2666 results in 262ms | correctness: ["a1","a2","b1","b2"]
v5.0.9  -> PoC bounded: 2666 results in 256ms | correctness: ["a1","a2","b1","b2"]

The suggested fix doesn't change the result

I tested collapsing the overrides to a single "brace-expansion": "^5.0.9". npm still resolves 1.1.18 and 2.1.4 for the nested copies, because ^5.0.9 cannot satisfy dependents that require ^1.0.0/^2.0.0:

5.0.9 node_modules/brace-expansion
1.1.18 node_modules/glob/node_modules/brace-expansion      <- unchanged
2.1.4 node_modules/archiver-utils/node_modules/brace-expansion  <- unchanged

The only override that would force 5.x everywhere is one that breaks those dependents' declared ranges. The per-major form is what actually pins each line to its patched release, and it documents that intent explicitly.

Keeping the overrides as-is. Happy to revisit if the advisory is later amended with explicit 1.x/2.x ranges.

@agoldis
agoldis merged commit d9d645a into main Jul 30, 2026
8 checks passed
@agoldis
agoldis deleted the deps/batch-2026-07-30 branch July 30, 2026 19:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants