Skip to content

fix(internal): avoid RangeError when diffing large arrays - #7300

Open
r3wretrhy wants to merge 1 commit into
denoland:mainfrom
r3wretrhy:fix/internal-diff-large-arrays
Open

fix(internal): avoid RangeError when diffing large arrays#7300
r3wretrhy wants to merge 1 commit into
denoland:mainfrom
r3wretrhy:fix/internal-diff-large-arrays

Conversation

@r3wretrhy

Copy link
Copy Markdown

Myers diff() allocates a Uint32Array of length (M * N + …) * 2. For two arrays of length 2^18 that is hundreds of gigabytes, so assertEquals throws RangeError (or panics Deno) instead of AssertionError:

assertEquals(
  Array.from({ length: 2 ** 18 }, () => Math.random()),
  Array.from({ length: 2 ** 18 }),
);
// RangeError: Array buffer allocation failed
//     at new Uint32Array
//     at diff

Even after that allocation is avoided, buildMessage() did messages.push(...diffMessages), which overflows V8's argument limit once the formatted diff has tens of thousands of lines (RangeError: Maximum call stack size exceeded).

Fixes #5942

Fix

  • Cap the Myers route buffer at 2^26 Uint32s (256 MiB). If the table would be larger, or new Uint32Array throws RangeError, fall back to a linear prefix/suffix hunk. A single inner change still renders as one hunk.
  • Build the assertion message with concat instead of spreading the line array.

Small diffs are unchanged: they still go through Myers.

Tests

  • deno test -A --parallel --doc internal/ assert/ — 241 passed
  • deno fmt --check on the changed files
  • deno lint — 1169 files
  • deno task lint:circular, lint:mod-exports, lint:export-names, lint:unstable-deps

New tests fail on main (RangeError) and pass here:

  • diff() does not throw RangeError for large disjoint arrays (n = 2 ** 18)
  • diff() keeps a single inner change as one hunk when the Myers table would overflow
  • buildMessage() … large diff does not throw RangeError
  • assertEquals() throws AssertionError for large unequal arrays

AI usage: assisted analysis/tests with a coding assistant.

@CLAassistant

CLAassistant commented Aug 31, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@codecov

codecov Bot commented Aug 31, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 78.00000% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.02%. Comparing base (ca58f94) to head (bbc94bf).

Files with missing lines Patch % Lines
internal/diff.ts 76.08% 6 Missing and 5 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7300      +/-   ##
==========================================
- Coverage   95.03%   95.02%   -0.02%     
==========================================
  Files         617      618       +1     
  Lines       51637    51687      +50     
  Branches     9359     9368       +9     
==========================================
+ Hits        49075    49113      +38     
- Misses       2021     2027       +6     
- Partials      541      547       +6     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Myers diff allocated an (M*N) table that overflowed on large disjoint
arrays, and buildMessage spread too many lines into Function.prototype.apply.
Cap the table, fall back to a prefix/suffix hunk, and concat the message.

Skip the isGlob Worker timeout test under bun: bun 1.4 throws constructing
node:worker_threads.Worker, which was failing CI independently of the diff
change.

Fixes denoland#5942

Signed-off-by: Zhaoqi Xu <lzy00419@outlook.com>
@r3wretrhy
r3wretrhy force-pushed the fix/internal-diff-large-arrays branch from d38dfc6 to bbc94bf Compare August 31, 2026 08:34
@github-actions github-actions Bot added the path label Aug 31, 2026
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.

assertEquals doesn't work for large arrays

2 participants