Files
bun.sh/test/js/node/buffer-concat.test.ts
robobun cff2c2690b Refactor Buffer.concat to use spans and improve error handling (#22337)
## Summary

This PR refactors the `Buffer.concat` implementation to use modern C++
spans for safer memory operations and adds proper error handling for
oversized buffers.

## Changes

- **Use spans instead of raw pointers**: Replaced pointer arithmetic
with `typedSpan()` and `span()` methods for safer memory access
- **Add MAX_ARRAY_BUFFER_SIZE check**: Added explicit check with a
descriptive error message when attempting to create buffers larger than
JavaScriptCore's limit (4GB)
- **Improve loop logic**: Changed loop counter from `int` to `size_t`
and simplified the iteration using span sizes
- **Enhanced test coverage**: Updated tests to verify the new error
message and added comprehensive test cases for various Buffer.concat
scenarios

## Test Plan

All existing tests pass, plus added new tests:
-  Error handling for oversized buffers
-  Normal buffer concatenation
-  totalLength parameter handling (exact, larger, smaller)
-  Empty array handling
-  Single buffer handling

```bash
./build/debug/bun-debug test test/js/node/buffer-concat.test.ts
# Result: 6 pass, 0 fail
```

🤖 Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-09-02 18:49:04 -07:00

61 lines
2.0 KiB
TypeScript

import { expect, test } from "bun:test";
test("Buffer.concat throws RangeError for too large buffers", () => {
const bufferToUse = Buffer.allocUnsafe(1024 * 1024 * 64);
const buffers = new Array(1024);
for (let i = 0; i < buffers.length; i++) {
buffers[i] = bufferToUse;
}
expect(() => Buffer.concat(buffers)).toThrow(/JavaScriptCore typed arrays are currently limited to/);
});
test("Buffer.concat works with normal sized buffers", () => {
const buf1 = Buffer.from("hello");
const buf2 = Buffer.from(" ");
const buf3 = Buffer.from("world");
const result = Buffer.concat([buf1, buf2, buf3]);
expect(result.toString()).toBe("hello world");
});
test("Buffer.concat with totalLength parameter", () => {
const buf1 = Buffer.from("hello");
const buf2 = Buffer.from(" ");
const buf3 = Buffer.from("world");
// Test with exact length
const result1 = Buffer.concat([buf1, buf2, buf3], 11);
expect(result1.toString()).toBe("hello world");
// Test with larger length (should pad with zeros)
const result2 = Buffer.concat([buf1, buf2, buf3], 15);
expect(result2.length).toBe(15);
expect(result2.toString("utf8", 0, 11)).toBe("hello world");
// Test with smaller length (should truncate)
const result3 = Buffer.concat([buf1, buf2, buf3], 5);
expect(result3.toString()).toBe("hello");
});
test("Buffer.concat with empty array", () => {
const result = Buffer.concat([]);
expect(result.length).toBe(0);
});
test("Buffer.concat with single buffer", () => {
const buf = Buffer.from("test");
const result = Buffer.concat([buf]);
expect(result.toString()).toBe("test");
expect(result).not.toBe(buf); // Should be a copy
});
test("Bun.concatArrayBuffers throws OutOfMemoryError", () => {
const bufferToUse = Buffer.allocUnsafe(1024 * 1024 * 64);
const buffers = new Array(1024);
for (let i = 0; i < buffers.length; i++) {
buffers[i] = bufferToUse;
}
expect(() => Bun.concatArrayBuffers(buffers)).toThrow(/Failed to allocate/i);
});