Skip to content

Commit

Permalink
Fix max call stack issue (#99)
Browse files Browse the repository at this point in the history
* Fix issue with RangeError called on concat.apply()

When calling the flatten function with a sufficiently large array it
will throw: RangeError: Maximum call stack size exceeded

This was found when processing very large xml documents and using a //
selector in select().

This is due to the maximum argument length limit in javascript/node.
Calling apply() with a sufficiently large array will throw a RangeError.
See https://bugs.webkit.org/show_bug.cgi?id=80797 for details.

Chunk the array into chunks that are smaller than the maximum argument
list size using `slice()` and call `concat.apply()` on each chunk so
that we never get the range error.

* Argument limit issue - remove use of prototypeSlice and unnecessary use of min()

Co-authored-by: Mike Noseworthy <mike.noseworthy@gmail.com>
  • Loading branch information
JLRishe and noseworthy committed Oct 19, 2020
1 parent 2489f78 commit b62c281
Showing 1 changed file with 12 additions and 1 deletion.
13 changes: 12 additions & 1 deletion xpath.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,19 @@ var xpath = (typeof exports === 'undefined') ? {} : exports;

var prototypeConcat = Array.prototype.concat;

// .apply() fails above a certain number of arguments - https://github.com/goto100/xpath/pull/98
var MAX_ARGUMENT_LENGTH = 32767;

function flatten(arr) {
return prototypeConcat.apply([], arr);
var result = [];

for (var start = 0; start < arr.length; start += MAX_ARGUMENT_LENGTH) {
var chunk = arr.slice(start, start + MAX_ARGUMENT_LENGTH);

result = prototypeConcat.apply(result, chunk);
}

return result;
}

function assign(target, varArgs) { // .length of function is 2
Expand Down

0 comments on commit b62c281

Please sign in to comment.