fs: fix stack overflow in fs.readdirSync

Previously, fs.readdirSync calls the function returned by
env->push_values_to_array_function() in batch and check the returned
Maybe right away in C++, which can lead to assertions if the call stack
already reaches the maximum size. This patch fixes that by returning
early the call fails so the stack overflow error will be properly
thrown into JS land.

PR-URL: https://github.com/nodejs/node/pull/18647
Fixes: https://github.com/nodejs/node/issues/18645
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
Joyee Cheung 2018-02-09 01:22:37 +08:00 committed by Ruben Bridgewater
parent df2f4ad22b
commit c5c9515c1b
No known key found for this signature in database
GPG Key ID: F07496B3EB3C1762
2 changed files with 27 additions and 3 deletions

View File

@ -1132,14 +1132,20 @@ static void ReadDir(const FunctionCallbackInfo<Value>& args) {
name_v[name_idx++] = filename.ToLocalChecked();
if (name_idx >= arraysize(name_v)) {
fn->Call(env->context(), names, name_idx, name_v)
.ToLocalChecked();
MaybeLocal<Value> ret = fn->Call(env->context(), names, name_idx,
name_v);
if (ret.IsEmpty()) {
return;
}
name_idx = 0;
}
}
if (name_idx > 0) {
fn->Call(env->context(), names, name_idx, name_v).ToLocalChecked();
MaybeLocal<Value> ret = fn->Call(env->context(), names, name_idx, name_v);
if (ret.IsEmpty()) {
return;
}
}
args.GetReturnValue().Set(names);

View File

@ -0,0 +1,18 @@
'use strict';
const common = require('../common');
const fs = require('fs');
function recurse() {
fs.readdirSync('.');
recurse();
}
common.expectsError(
() => recurse(),
{
type: RangeError,
message: 'Maximum call stack size exceeded'
}
);