fix(string): reject oversized len in JS_NewStringUTF16#1486
Open
andreasrosdal wants to merge 1 commit into
Open
fix(string): reject oversized len in JS_NewStringUTF16#1486andreasrosdal wants to merge 1 commit into
andreasrosdal wants to merge 1 commit into
Conversation
The C API took a size_t len but passed it to js_alloc_string, whose length parameter is int. With len > INT_MAX (e.g. INT_MAX + 1), the cast truncated the value, producing either a tiny or negative-sized allocation while the subsequent memcpy(str16(str), buf, len * 2) wrote the full size_t length — heap overflow on misuse from C. Reject len > JS_STRING_LEN_MAX before allocating, matching the existing guard in JS_NewStringLen. Test: api-test now calls JS_NewStringUTF16(ctx, NULL, INT_MAX + 1) and asserts JS_IsException + the "invalid string length" error. Before the fix, the same call segfaults (or is caught by ASan as a heap-buffer-overflow).
bnoordhuis
approved these changes
May 17, 2026
Contributor
bnoordhuis
left a comment
There was a problem hiding this comment.
LGTM modulo 2 comments (comments about comments, in fact.)
Comment on lines
+4413
to
+4417
| /* Without this clamp, a size_t length just above INT_MAX would truncate | ||
| when passed to js_alloc_string (whose length parameter is int). The | ||
| resulting allocation is tiny or negative-shifted, while the subsequent | ||
| memcpy(str16(str), buf, len * 2) writes the full len*2 bytes — heap | ||
| overflow. The sibling JS_NewStringLen has the same guard. */ |
Contributor
There was a problem hiding this comment.
Kind of a superfluous comment. It also has that AI vibe to it.
Suggested change
| /* Without this clamp, a size_t length just above INT_MAX would truncate | |
| when passed to js_alloc_string (whose length parameter is int). The | |
| resulting allocation is tiny or negative-shifted, while the subsequent | |
| memcpy(str16(str), buf, len * 2) writes the full len*2 bytes — heap | |
| overflow. The sibling JS_NewStringLen has the same guard. */ |
Comment on lines
+490
to
+497
| /* Oversized length: must throw RangeError, not corrupt the heap. | ||
| Before the fix, len > INT_MAX was truncated when passed to | ||
| js_alloc_string(int), producing a tiny allocation that the | ||
| subsequent memcpy(..., len * 2) overflowed. Pre-fix: ASan | ||
| reports heap-buffer-overflow or process aborts. Post-fix: | ||
| returns an exception. We don't materialise a multi-GB buffer | ||
| here — JS_NewStringUTF16 must reject the length *before* | ||
| reading from buf. */ |
Contributor
There was a problem hiding this comment.
Ditto:
Suggested change
| /* Oversized length: must throw RangeError, not corrupt the heap. | |
| Before the fix, len > INT_MAX was truncated when passed to | |
| js_alloc_string(int), producing a tiny allocation that the | |
| subsequent memcpy(..., len * 2) overflowed. Pre-fix: ASan | |
| reports heap-buffer-overflow or process aborts. Post-fix: | |
| returns an exception. We don't materialise a multi-GB buffer | |
| here — JS_NewStringUTF16 must reject the length *before* | |
| reading from buf. */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The C API took a size_t len but passed it to js_alloc_string, whose length parameter is int. With len > INT_MAX (e.g. INT_MAX + 1), the cast truncated the value, producing either a tiny or negative-sized allocation while the subsequent memcpy(str16(str), buf, len * 2) wrote the full size_t length — heap overflow on misuse from C.
Reject len > JS_STRING_LEN_MAX before allocating, matching the existing guard in JS_NewStringLen.
Test: api-test now calls JS_NewStringUTF16(ctx, NULL, INT_MAX + 1) and asserts JS_IsException + the "invalid string length" error. Before the fix, the same call segfaults (or is caught by ASan as a heap-buffer-overflow).