-
-
Notifications
You must be signed in to change notification settings - Fork 132
fix(runtime): throw catchable RangeError on over-large allocations (#5067) #5103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -235,6 +235,18 @@ pub extern "C" fn js_rangeerror_new(message: *mut StringHeader) -> *mut ErrorHea | |
| unsafe { alloc_error(ERROR_KIND_RANGE_ERROR, b"RangeError", message, true) } | ||
| } | ||
|
|
||
| /// #5067 — throw a catchable `RangeError: Array buffer allocation failed` | ||
| /// (V8/Node's allocation-failure message) instead of aborting the process | ||
| /// when a user-controlled-size backing buffer cannot be allocated. Shared | ||
| /// by the Set/Map/RegExp backing-store allocators. | ||
| #[cold] | ||
| pub(crate) fn throw_allocation_failed() -> ! { | ||
| let msg = b"Array buffer allocation failed"; | ||
| let s = crate::string::js_string_from_bytes(msg.as_ptr(), msg.len() as u32); | ||
| let err = js_rangeerror_new(s); | ||
| crate::exception::js_throw(crate::value::js_nanbox_pointer(err as i64)) | ||
| } | ||
|
Comment on lines
+238
to
+248
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win Consolidate with existing The new ♻️ Recommended consolidation approachIn #[cold]
fn throw_buffer_alloc_failed() -> ! {
- let msg = b"Array buffer allocation failed";
- let s = crate::string::js_string_from_bytes(msg.as_ptr(), msg.len() as u32);
- let err = crate::error::js_rangeerror_new(s);
- crate::exception::js_throw(crate::value::js_nanbox_pointer(err as i64))
+ crate::error::throw_allocation_failed()
}Alternatively, remove 🤖 Prompt for AI Agents |
||
|
|
||
| /// Create a new ReferenceError with a message | ||
| #[no_mangle] | ||
| pub extern "C" fn js_referenceerror_new(message: *mut StringHeader) -> *mut ErrorHeader { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Handle slab allocation failures too.
This only covers the non-slab branch.
buffer_alloc_small()stillpanic!s at Line 239 when a new slab block allocation returns null, so smallBuffer.alloc(...)/Uint8Array(...)calls can still abort the process under memory pressure instead of throwing the catchableRangeError.Suggested follow-up
fn buffer_alloc_small(capacity: u32) -> *mut BufferHeader { let needed = std::mem::size_of::<BufferHeader>() + capacity as usize; // Round up to 8-byte boundary so every header is naturally aligned. let aligned = (needed + 7) & !7; SMALL_BUF_SLAB.with(|slab_ref| { let mut slab = slab_ref.borrow_mut(); if slab.current + aligned > slab.end { // Current block exhausted (or first call): allocate a fresh slab. let layout = Layout::from_size_align(SLAB_CAPACITY, 8).unwrap(); let block = unsafe { alloc(layout) }; if block.is_null() { - panic!( - "buffer: failed to allocate small-buffer slab ({} bytes)", - SLAB_CAPACITY - ); + throw_buffer_alloc_failed(); } let block_start = block as usize; let block_end = block_start + SLAB_CAPACITY;🤖 Prompt for AI Agents