Skip to content

fix #6949: prevent RangeError when using large Buffers in axios requests#6961

Merged
jasonsaayman merged 1 commit intoaxios:v1.xfrom
manishsahanidev:fix/buffer-rangeerror
Jul 15, 2025
Merged

fix #6949: prevent RangeError when using large Buffers in axios requests#6961
jasonsaayman merged 1 commit intoaxios:v1.xfrom
manishsahanidev:fix/buffer-rangeerror

Conversation

@manishsahanidev
Copy link
Contributor

Description

This PR fixes a critical RangeError that occurs when using large Buffers (>100-200MB) as request data in axios. The error was caused by calling Object.keys() on Buffer instances during configuration merging, which attempts to enumerate every byte as a key.

Problem

When axios processes large Buffer data, several utility functions would call Object.keys() on the Buffer:

// This would crash with large Buffers
function isEmptyObject(val) {
  return val && Object.keys(val).length === 0 && Object.getPrototypeOf(val) === Object.prototype;
}

Error: RangeError: Invalid array length when Buffer size exceeds ~100-200MB

Solution

Added Buffer checks to prevent Object.keys() from being called on Buffer instances in:

  • isEmptyObject() - Returns false for all Buffers (not empty objects)
  • forEach() - Skips iteration for Buffers
  • findKey() - Returns null for Buffers
  • toJSONObject() - Returns Buffer as-is without processing

Changes Made

1. Enhanced isEmptyObject function

const isEmptyObject = (val) => {
  // Early return for non-objects or Buffers to prevent RangeError
  if (!isObject(val) || isBuffer(val)) {
    return false;
  }
  
  try {
    return Object.keys(val).length === 0 && Object.getPrototypeOf(val) === Object.prototype;
  } catch (e) {
    // Fallback for any other objects that might cause RangeError with Object.keys()
    return false;
  }
}

2. Enhanced forEach function

function forEach(obj, fn, {allOwnKeys = false} = {}) {
  // ... existing code ...
  } else {
    // Buffer check to prevent RangeError
    if (isBuffer(obj)) {
      return;
    }
    // ... rest of object iteration ...
  }
}

3. Enhanced findKey function

function findKey(obj, key) {
  if (isBuffer(obj)){
    return null;
  }
  // ... rest of function ...
}

4. Enhanced toJSONObject function

const toJSONObject = (obj) => {
  const visit = (source, i) => {
    if (isObject(source)) {
      // ... existing checks ...
      
      // Buffer check to prevent RangeError
      if (isBuffer(source)) {
        return source;
      }
      
      // ... rest of processing ...
    }
    return source;
  }
  return visit(obj, 0);
}

Test Coverage

Added comprehensive tests in test/unit/utils/utils.js:

describe('Buffer RangeError Fix', function () {
  it('should handle large Buffer in isEmptyObject without RangeError', function () {
    const largeBuffer = Buffer.alloc(1024 * 1024 * 200); // 200MB
    const result = utils.isEmptyObject(largeBuffer);
    assert.strictEqual(result, false);
  });

  it('should handle large Buffer in forEach without RangeError', function () {
    const largeBuffer = Buffer.alloc(1024 * 1024 * 200); // 200MB
    let count = 0;
    utils.forEach(largeBuffer, () => count++);
    assert.strictEqual(count, 0); // Should be skipped
  });

  it('should handle large Buffer in findKey without RangeError', function () {
    const largeBuffer = Buffer.alloc(1024 * 1024 * 200); // 200MB
    const result = utils.findKey(largeBuffer, 'test');
    assert.strictEqual(result, null);
  });
});

Reproduction Case

Before (throws RangeError):

import axios from 'axios'

const buffer = Buffer.alloc(1024 * 1024 * 200) // 200 MB buffer
await axios({
  method: 'POST',
  url: 'http://localhost:8080',
  data: buffer
})
// RangeError: Invalid array length

After (works correctly):

import axios from 'axios'

const buffer = Buffer.alloc(1024 * 1024 * 200) // 200 MB buffer
await axios({
  method: 'POST',
  url: 'http://localhost:8080',  
  data: buffer
})
// ✅ Works without error

Backward Compatibility

  • ✅ No breaking changes
  • ✅ All existing functionality preserved
  • ✅ Performance impact minimal (fast Buffer checks)
  • ✅ Only affects Buffer handling behavior

Impact

This fix enables axios to handle large file uploads and binary data processing in Node.js environments without crashes, which is essential for:

  • File upload services
  • Image/video processing APIs
  • Binary data streaming
  • Large payload handling

Testing

  • ✅ All existing tests pass
  • ✅ New Buffer-specific tests added
  • ✅ Manual testing with 200MB+ Buffers
  • ✅ Integration testing with real HTTP requests

Closes #[#6949]

Screenshot 2025-07-09 123055

@jasonsaayman jasonsaayman added this to the v1.11.0 milestone Jul 10, 2025
Copy link
Member

@jasonsaayman jasonsaayman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks great to me

@jasonsaayman jasonsaayman merged commit a2214ca into axios:v1.x Jul 15, 2025
12 checks passed
@github-actions github-actions bot mentioned this pull request Jul 22, 2025
@github-actions
Copy link
Contributor

Hi, @manishsahanidev! This PR has been published in v1.11.0 release. Thank you for your contribution ❤️!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants