Skip to content

Commit a2214ca

Browse files
fix: prevent RangeError when using large Buffers (#6961)
1 parent 6161947 commit a2214ca

2 files changed

Lines changed: 70 additions & 0 deletions

File tree

lib/utils.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,27 @@ const isPlainObject = (val) => {
136136
return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(toStringTag in val) && !(iterator in val);
137137
}
138138

139+
/**
140+
* Determine if a value is an empty object (safely handles Buffers)
141+
*
142+
* @param {*} val The value to test
143+
*
144+
* @returns {boolean} True if value is an empty object, otherwise false
145+
*/
146+
const isEmptyObject = (val) => {
147+
// Early return for non-objects or Buffers to prevent RangeError
148+
if (!isObject(val) || isBuffer(val)) {
149+
return false;
150+
}
151+
152+
try {
153+
return Object.keys(val).length === 0 && Object.getPrototypeOf(val) === Object.prototype;
154+
} catch (e) {
155+
// Fallback for any other objects that might cause RangeError with Object.keys()
156+
return false;
157+
}
158+
}
159+
139160
/**
140161
* Determine if a value is a Date
141162
*
@@ -258,6 +279,11 @@ function forEach(obj, fn, {allOwnKeys = false} = {}) {
258279
fn.call(null, obj[i], i, obj);
259280
}
260281
} else {
282+
// Buffer check
283+
if (isBuffer(obj)) {
284+
return;
285+
}
286+
261287
// Iterate over object keys
262288
const keys = allOwnKeys ? Object.getOwnPropertyNames(obj) : Object.keys(obj);
263289
const len = keys.length;
@@ -271,6 +297,10 @@ function forEach(obj, fn, {allOwnKeys = false} = {}) {
271297
}
272298

273299
function findKey(obj, key) {
300+
if (isBuffer(obj)){
301+
return null;
302+
}
303+
274304
key = key.toLowerCase();
275305
const keys = Object.keys(obj);
276306
let i = keys.length;
@@ -624,6 +654,11 @@ const toJSONObject = (obj) => {
624654
return;
625655
}
626656

657+
//Buffer check
658+
if (isBuffer(source)) {
659+
return source;
660+
}
661+
627662
if(!('toJSON' in source)) {
628663
stack[i] = source;
629664
const target = isArray(source) ? [] : {};
@@ -695,6 +730,7 @@ export default {
695730
isBoolean,
696731
isObject,
697732
isPlainObject,
733+
isEmptyObject,
698734
isReadableStream,
699735
isRequest,
700736
isResponse,

test/unit/utils/utils.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,38 @@ describe('utils', function (){
8080
assert.strictEqual(JSON.stringify(jsonObject), JSON.stringify({x: 1, y:2, obj: {ok: 1}}))
8181
});
8282
});
83+
84+
describe('Buffer RangeError Fix', function () {
85+
it('should handle large Buffer in isEmptyObject without RangeError', function () {
86+
// Create a big buffer that used to cause the error
87+
const largeBuffer = Buffer.alloc(1024 * 1024 * 200); // 200MB
88+
89+
// This used to throw: RangeError: Invalid array length
90+
// Now it should work fine
91+
const result = utils.isEmptyObject(largeBuffer);
92+
93+
// Buffer should not be considered an empty object
94+
assert.strictEqual(result, false);
95+
});
96+
97+
it('should handle large Buffer in forEach without RangeError', function () {
98+
const largeBuffer = Buffer.alloc(1024 * 1024 * 200); // 200MB
99+
let count = 0;
100+
101+
// This should skip the buffer (not iterate through it)
102+
utils.forEach(largeBuffer, () => count++);
103+
104+
// Count should be 0 because forEach skips Buffers
105+
assert.strictEqual(count, 0);
106+
});
107+
108+
it('should handle large Buffer in findKey without RangeError', function () {
109+
const largeBuffer = Buffer.alloc(1024 * 1024 * 200); // 200MB
110+
111+
// Should return null for Buffers
112+
const result = utils.findKey(largeBuffer, 'test');
113+
114+
assert.strictEqual(result, null);
115+
});
116+
});
83117
});

0 commit comments

Comments
 (0)