Skip to content

Add constraint checks to array and typed array methods that bypass memory limits#2282

Merged
lahma merged 7 commits into
mainfrom
copilot/fix-memory-limits-bypass
Feb 15, 2026
Merged

Add constraint checks to array and typed array methods that bypass memory limits#2282
lahma merged 7 commits into
mainfrom
copilot/fix-memory-limits-bypass

Conversation

Copilot AI commented Feb 15, 2026

Copy link
Copy Markdown
Contributor

Fix memory limits bypass in Array.prototype and TypedArray.prototype methods

  • Understand the issue - Array(1000000000).fill(new Array(1000000000)) bypasses memory constraints
  • Add constraint checking to Array.prototype methods (fill, copyWithin, reverse, with, toReversed)
  • Add constraint checking to TypedArray.prototype methods (fill, copyWithin, reverse, toReversed, with)
  • All constraint tests pass (24/24 tests - 19 original + 5 new typed array tests)
  • Run array benchmarks - no performance degradation detected
  • Run full test suite - all tests pass
  • Code review completed - addressed all feedback
  • Security scan completed - no vulnerabilities found
  • Refactor: Use private const int for ConstraintCheckInterval (10_000) instead of magic numbers

Changes Summary

Array Methods Fixed

  • fill, copyWithin, reverse, with, toReversed

TypedArray Methods Fixed

  • fill, copyWithin, reverse, toReversed, with

Code Quality

  • Added private const int ConstraintCheckInterval = 10_000; to both ArrayPrototype and IntrinsicTypedArrayPrototype classes
  • All magic numbers replaced with named constant for better maintainability
Original prompt

This section details on the original issue you should resolve

<issue_title>Memory limits bypass</issue_title>
<issue_description>```
var arr = Array(1000000000).fill(new Array(1000000000));


I think it's fine to not check the actual memory usage of each array or string allocations though. These could use an option with a max length instead, even very big. Then throw a specific exception. And concatenations would check upon this limit instead of the thread memory.

The `fill` function however might need to check the memory limits. There might be other functions too that loop over the same value and need a check. Looping over a function evaluation is safe though since thread memory is ensured.
</issue_description>

<agent_instructions>fix must not introduce performance degradation, use array related benchmarks to validate performance before and after your fixes</agent_instructions>

## Comments on the Issue (you are @copilot in this section)

<comments>
<comment_new><author>@lahma</author><body>
MaxArraySize constraint in sebastienros/jint#923 should address this.</body></comment_new>
<comment_new><author>@lahma</author><body>
Would you like to submit a PR to improve the protections?</body></comment_new>
<comment_new><author>@lahma</author><body>
Start by creating a failing test case when you have engine configured to have array and memory usage constraint `    options.LimitMemory(4_000_000);`. Jint will only check for constraints when exiting native functions like `ArrayPrototype.map` so you need to have memory usage constraint as long as you only create array sizes that are allowed and hope that native functions won't be able to exhaust memory inside the calls.</body></comment_new>
<comment_new><author>@sebastienros</author><body>
What about checking for the constraint inside native functions if at they represent a risk? We could set a flag and the callers could also check? For instance `map()` doesn't do the check by default because it's a native function, whereas a for loop will do it because it's based on statements. The `map()` itself is not an issue, but because the called func is allocating, it might need to check for the limit on each invocation. For `Array` it could check only if the size is above some random threshold, like 1KB, but always set a flag such that the caller, `map()` should be checked.

But maybe a better idea would be to have an internal field that track an estimation of allocated memory in native functions, a hint, and above a threshold do a constraint check. So for every `Array()` call we increment by the estimated allocated size, so the `map()` can just check that counter, which is cheap, and eventually do a real Thread memory check. Same for string, and we could even do this cheap/local memory tracking for standard instances like numbers. Could be an API on the engine. It could sound like too much, but I think it's a huge benefit. Thoughts?</body></comment_new>
<comment_new><author>@lahma</author><body>
I had a vision where native functions would get a CancellationToken as part of call signature which would be cheap to check.

Constrainst could hook onto that that like as combined source and constraints could even run a background task (think thread), a watchdog, that could signal token when things start to look bad.

Just an idea.</body></comment_new>
<comment_new><author>@sebastienros</author><body>
in the Engine then, doesn't need to be in the signature</body></comment_new>
<comment_new><author>@sebastienros</author><body>
But it's orthogonal to my idea. What about it?</body></comment_new>
<comment_new><author>@lahma</author><body>
Yes the signature was more about aligning with standards, but could be a field too.</body></comment_new>
<comment_new><author>@sebastienros</author><body>
Also wondering if we should track the size of each environment record, such that when one is remove we can decrease the allocations. Imagine a long running script that just updates the same entry with a 1MB buffer, it allocates a lot overtime, but only takes 1MB in total. So there would be two checks, that what we allocate doesn't go over the limit, and only account for retained memory when adding the allocated buffers.</body></comment_new>
</comments>


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 4 commits February 15, 2026 08:55
Co-authored-by: lahma <171892+lahma@users.noreply.github.com>
…thods

Co-authored-by: lahma <171892+lahma@users.noreply.github.com>
…terval checking

Co-authored-by: lahma <171892+lahma@users.noreply.github.com>
Co-authored-by: lahma <171892+lahma@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix memory limits bypass in array handling Add constraint checks to array methods that bypass memory limits Feb 15, 2026
Copilot AI requested a review from lahma February 15, 2026 09:12
@lahma

lahma commented Feb 15, 2026

Copy link
Copy Markdown
Collaborator

@copilot analyze other data structures like typed arrays, do they suffer from the sample problem add test coverage for this in constraints tests

…overage

Co-authored-by: lahma <171892+lahma@users.noreply.github.com>

Copilot AI commented Feb 15, 2026

Copy link
Copy Markdown
Contributor Author

@copilot analyze other data structures like typed arrays, do they suffer from the sample problem add test coverage for this in constraints tests

Added constraint checks to all typed array methods (fill, copyWithin, reverse, toReversed, with) and added 5 comprehensive test cases covering each method. All tests pass. Commit: 6df96a8

Copilot AI changed the title Add constraint checks to array methods that bypass memory limits Add constraint checks to array and typed array methods that bypass memory limits Feb 15, 2026
@lahma

lahma commented Feb 15, 2026

Copy link
Copy Markdown
Collaborator

@copilot use private const int for that magic number 10_000

Co-authored-by: lahma <171892+lahma@users.noreply.github.com>

Copilot AI commented Feb 15, 2026

Copy link
Copy Markdown
Contributor Author

@copilot use private const int for that magic number 10_000

Refactored to use private const int ConstraintCheckInterval = 10_000; at the class level in both ArrayPrototype and IntrinsicTypedArrayPrototype. All magic numbers replaced with the named constant. Commit: 320f5f1

Copilot AI requested a review from lahma February 15, 2026 16:08
@lahma
lahma marked this pull request as ready for review February 15, 2026 16:16
@lahma
lahma merged commit 8806ac5 into main Feb 15, 2026
4 checks passed
@lahma
lahma deleted the copilot/fix-memory-limits-bypass branch February 15, 2026 16:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Memory limits bypass

2 participants