diff options
author | 2023-07-27 04:27:09 -0700 | |
---|---|---|
committer | 2023-07-27 04:27:09 -0700 | |
commit | 704ee133923a4e28bd51bc95b56eb54d50424c17 (patch) | |
tree | 3f4068d3a0d777a2a712739bf24a7e4e499f5cb0 /src/bun.js/bindings/BunString.cpp | |
parent | d7aebc2222daa293dc41c4fb9e230f1848cea3ad (diff) | |
download | bun-704ee133923a4e28bd51bc95b56eb54d50424c17.tar.gz bun-704ee133923a4e28bd51bc95b56eb54d50424c17.tar.zst bun-704ee133923a4e28bd51bc95b56eb54d50424c17.zip |
Make readdir() async, fix crash in large directory trees (#3838)
* Fix unsafe GC behavior on large arrays returned by fs
* Fix crash in large arrays of strings
* async readdir
* Add tests for large number of files returned by readdir
* Move this down
* Fix encoding edgecase in path.join
* Async stat & lstat
* add test
---------
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
Diffstat (limited to 'src/bun.js/bindings/BunString.cpp')
-rw-r--r-- | src/bun.js/bindings/BunString.cpp | 50 |
1 files changed, 33 insertions, 17 deletions
diff --git a/src/bun.js/bindings/BunString.cpp b/src/bun.js/bindings/BunString.cpp index 714f10080..e044730c4 100644 --- a/src/bun.js/bindings/BunString.cpp +++ b/src/bun.js/bindings/BunString.cpp @@ -256,31 +256,47 @@ extern "C" EncodedJSValue BunString__createArray( auto& vm = globalObject->vm(); auto throwScope = DECLARE_THROW_SCOPE(vm); - // We must do this or Bun.gc(true) in a loop creating large arrays of strings will crash due to GC'ing. - MarkedArgumentBuffer arguments; - JSC::ObjectInitializationScope scope(vm); - GCDeferralContext context(vm); - - arguments.fill(length, [&](JSC::JSValue* value) { - const BunString* end = ptr + length; - while (ptr != end) { - *value++ = Bun::toJS(globalObject, *ptr++); - } - }); + if (length < 64) { + // We must do this or Bun.gc(true) in a loop creating large arrays of strings will crash due to GC'ing. + MarkedArgumentBuffer arguments; + + arguments.fill(length, [&](JSC::JSValue* value) { + const BunString* end = ptr + length; + while (ptr != end) { + *value++ = Bun::toJS(globalObject, *ptr++); + } + }); + + JSC::ObjectInitializationScope scope(vm); + GCDeferralContext context(vm); - if (JSC::JSArray* array = JSC::JSArray::tryCreateUninitializedRestricted( + JSC::JSArray* array = JSC::JSArray::tryCreateUninitializedRestricted( scope, globalObject->arrayStructureForIndexingTypeDuringAllocation(JSC::ArrayWithContiguous), - length)) { + length); + + if (array) { + for (size_t i = 0; i < length; ++i) { + array->initializeIndex(scope, i, arguments.at(i)); + } + return JSValue::encode(array); + } + + JSC::throwOutOfMemoryError(globalObject, throwScope); + RELEASE_AND_RETURN(throwScope, JSValue::encode(JSC::JSValue())); + } else { + JSC::JSArray* array = constructEmptyArray(globalObject, nullptr, length); + if (!array) { + JSC::throwOutOfMemoryError(globalObject, throwScope); + RELEASE_AND_RETURN(throwScope, JSValue::encode(JSC::JSValue())); + } for (size_t i = 0; i < length; ++i) { - array->initializeIndex(scope, i, arguments.at(i)); + array->putDirectIndex(globalObject, i, Bun::toJS(globalObject, *ptr++)); } + return JSValue::encode(array); } - - JSC::throwOutOfMemoryError(globalObject, throwScope); - RELEASE_AND_RETURN(throwScope, JSValue::encode(JSC::JSValue())); } extern "C" void BunString__toWTFString(BunString* bunString) |