mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
## Summary Improve bounds checking logic in Buffer.*Write methods (utf8Write, base64urlWrite, etc.) to properly handle edge cases with non-numeric offset and length arguments, matching Node.js behavior. ## Changes - Handle non-numeric offset by converting to integer (treating invalid values as 0) - Clamp length to available buffer space instead of throwing - Reorder operations to check buffer state after argument conversion ## Node.js Compatibility This matches Node.js's C++ implementation in `node_buffer.cc`: **Offset handling via `ParseArrayIndex`** ([node_buffer.cc:211-234](https://github.com/nodejs/node/blob/main/src/node_buffer.cc#L211-L234)): ```cpp inline MUST_USE_RESULT Maybe<bool> ParseArrayIndex(Environment* env, Local<Value> arg, size_t def, size_t* ret) { if (arg->IsUndefined()) { *ret = def; return Just(true); } int64_t tmp_i; if (!arg->IntegerValue(env->context()).To(&tmp_i)) return Nothing<bool>(); // ... } ``` V8's `IntegerValue` converts non-numeric values (including NaN) to 0. **Length clamping in `SlowWriteString`** ([node_buffer.cc:1498-1502](https://github.com/nodejs/node/blob/main/src/node_buffer.cc#L1498-L1502)): ```cpp THROW_AND_RETURN_IF_OOB(ParseArrayIndex(env, args[2], 0, &offset)); THROW_AND_RETURN_IF_OOB( ParseArrayIndex(env, args[3], ts_obj_length - offset, &max_length)); max_length = std::min(ts_obj_length - offset, max_length); ``` Node.js clamps `max_length` to available buffer space rather than throwing. ## Test plan - Added regression tests for all `*Write` methods verifying proper handling of edge cases - Verified behavior matches Node.js - All 447 buffer tests pass fixes ENG-21985, fixes ENG-21863, fixes ENG-21751, fixes ENG-21984 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Bot <claude-bot@bun.sh> Co-authored-by: Claude <noreply@anthropic.com>