Skip to content
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

RangeError thrown, not passed in callback #156

Closed
dominique-pfister opened this issue Apr 12, 2024 · 4 comments
Closed

RangeError thrown, not passed in callback #156

dominique-pfister opened this issue Apr 12, 2024 · 4 comments

Comments

@dominique-pfister
Copy link

dominique-pfister commented Apr 12, 2024

I have a sample zip file that is too short, and it causes a RangeError in node's Buffer.copy which is unhandled.

From the gist of the corrupted file with a size of 2MB, I created a test with node 18:

const yauzl = require('yauzl');
const buffer = Buffer.alloc(65577);
buffer.fill(Buffer.from([
  0x50, 0x4b, 0x05, 0x06,
  0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x1b, 0x00,
  0xf6, 0x06, 0x00, 0x00, 0x1c, 0x2a, 0x25, 0x00,
  0x00, 0x00,
]), 65555);

yauzl.fromBuffer(buffer, {}, (err, zipfile) => {
  if (err) {
    console.error(err);
    return;
  }
  console.log(zipfile);
});

it crashes with:

node:buffer:227
      throw new ERR_OUT_OF_RANGE('sourceStart', `>= 0 && <= ${source.length}`, sourceStart);
      ^

RangeError [ERR_OUT_OF_RANGE]: The value of "sourceStart" is out of range. It must be >= 0 && <= 65577. Received 2435612
    at new NodeError (node:internal/errors:405:5)
    at _copy (node:buffer:227:13)
    at Buffer.copy (node:buffer:821:12)
    at BufferSlicer.read (./yauzl/fd-slicer.js:201:15)
    at readAndAssertNoEof (./yauzl/index.js:700:10)
    at ZipFile._readEntry (./yauzl/index.js:255:3)
    at new ZipFile (./yauzl/index.js:220:31)
    at ./yauzl/index.js:185:29
    at ./yauzl/index.js:705:5
    at Immediate.<anonymous> (./yauzl/fd-slicer.js:203:5) {
  code: 'ERR_OUT_OF_RANGE'
}

This could only be caught, with a:

process.on('uncaughtException', ...)

which is not an option for us, as this code is called by an AWS service.

@dominique-pfister
Copy link
Author

dominique-pfister commented Apr 12, 2024

The code causing the exception is in BufferSlicer.prototype.read, where loading the first entry ends up invoking Buffer.copy with arguments (Buffer(46), 0, 2435612, 2435658) on a Buffer of size 65577:

yauzl/fd-slicer.js

Lines 197 to 204 in 6fbfef9

BufferSlicer.prototype.read = function(buffer, offset, length, position, callback) {
var end = position + length;
var delta = end - this.buffer.length;
var written = (delta > 0) ? delta : length;
this.buffer.copy(buffer, offset, position, end);
setImmediate(function() {
callback(null, written);
});

It could either validate the arguments and invoke callback with a RangeError itself, or catch the RangeError thrown by Buffer.copy and pass this in the callback.

@thejoshwolfe
Copy link
Owner

great test case! i've reproduced the problem and i'm working on a fix.

@thejoshwolfe
Copy link
Owner

The fix is included in version 3.1.3!

@dominique-pfister
Copy link
Author

checked with my corrupted 2MB file, works like a charm! thanks a lot 🙏

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

No branches or pull requests

2 participants