diff options
author | 2023-02-05 06:17:21 -0800 | |
---|---|---|
committer | 2023-02-05 06:17:21 -0800 | |
commit | 864913684558466f8517de9d474180a6bc19915c (patch) | |
tree | 363ba440cc027052934d1ea5acdbfa34ad9279aa | |
parent | e8fe6dd2f8720303bd730742879cb7c00ea38b56 (diff) | |
download | bun-864913684558466f8517de9d474180a6bc19915c.tar.gz bun-864913684558466f8517de9d474180a6bc19915c.tar.zst bun-864913684558466f8517de9d474180a6bc19915c.zip |
`substringSharingImpl` allocates, do not use
-rw-r--r-- | src/bun.js/bindings/JSBuffer.cpp | 5 | ||||
-rw-r--r-- | src/bun.js/bindings/JSBufferEncodingType.cpp | 79 |
2 files changed, 27 insertions, 57 deletions
diff --git a/src/bun.js/bindings/JSBuffer.cpp b/src/bun.js/bindings/JSBuffer.cpp index c985a7505..a6c735af7 100644 --- a/src/bun.js/bindings/JSBuffer.cpp +++ b/src/bun.js/bindings/JSBuffer.cpp @@ -729,7 +729,10 @@ static inline JSC::EncodedJSValue jsBufferConstructorFunction_concatBody(JSC::JS static inline JSC::EncodedJSValue jsBufferConstructorFunction_isEncodingBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame) { auto& vm = JSC::getVM(lexicalGlobalObject); - auto encoding_ = callFrame->argument(0).toString(lexicalGlobalObject); + auto* encoding_ = callFrame->argument(0).toStringOrNull(lexicalGlobalObject); + if (!encoding_) + return JSValue::encode(jsBoolean(false)); + std::optional<BufferEncodingType> encoded = parseEnumeration<BufferEncodingType>(*lexicalGlobalObject, encoding_); return JSValue::encode(jsBoolean(!!encoded)); } diff --git a/src/bun.js/bindings/JSBufferEncodingType.cpp b/src/bun.js/bindings/JSBufferEncodingType.cpp index d65e90d2b..8d99dd4db 100644 --- a/src/bun.js/bindings/JSBufferEncodingType.cpp +++ b/src/bun.js/bindings/JSBufferEncodingType.cpp @@ -30,19 +30,21 @@ namespace WebCore { using namespace JSC; +static const NeverDestroyed<String> values[] = { + MAKE_STATIC_STRING_IMPL("utf8"), + MAKE_STATIC_STRING_IMPL("ucs2"), + MAKE_STATIC_STRING_IMPL("utf16le"), + MAKE_STATIC_STRING_IMPL("latin1"), + MAKE_STATIC_STRING_IMPL("ascii"), + MAKE_STATIC_STRING_IMPL("base64"), + MAKE_STATIC_STRING_IMPL("base64url"), + MAKE_STATIC_STRING_IMPL("hex"), + MAKE_STATIC_STRING_IMPL("buffer"), +}; + String convertEnumerationToString(BufferEncodingType enumerationValue) { - static const NeverDestroyed<String> values[] = { - MAKE_STATIC_STRING_IMPL("utf8"), - MAKE_STATIC_STRING_IMPL("ucs2"), - MAKE_STATIC_STRING_IMPL("utf16le"), - MAKE_STATIC_STRING_IMPL("latin1"), - MAKE_STATIC_STRING_IMPL("ascii"), - MAKE_STATIC_STRING_IMPL("base64"), - MAKE_STATIC_STRING_IMPL("base64url"), - MAKE_STATIC_STRING_IMPL("hex"), - MAKE_STATIC_STRING_IMPL("buffer"), - }; + ASSERT(static_cast<size_t>(enumerationValue) < std::size(values)); return values[static_cast<size_t>(enumerationValue)]; } @@ -55,9 +57,9 @@ template<> JSString* convertEnumerationToJS(JSGlobalObject& lexicalGlobalObject, // this function is mostly copied from node template<> std::optional<BufferEncodingType> parseEnumeration<BufferEncodingType>(JSGlobalObject& lexicalGlobalObject, JSValue value) { - - JSC::JSString* str = value.toStringOrNull(&lexicalGlobalObject); - if (!str) + // caller must check if value is a string + JSC::JSString* str = asString(value); + if (UNLIKELY(!str)) return std::nullopt; auto encoding = str->value(&lexicalGlobalObject); @@ -75,21 +77,7 @@ template<> std::optional<BufferEncodingType> parseEnumeration<BufferEncodingType switch (encoding[0]) { case 'u': - case 'U': - // utf8, utf16le - if (encoding[1] == 't' && encoding[2] == 'f') { - // Skip `-` - const size_t skip = encoding[3] == '-' ? 4 : 3; - if (encoding[skip] == '8' && encoding[skip + 1] == '\0') - return BufferEncodingType::utf8; - if (WTF::equalIgnoringASCIICase(encoding.substringSharingImpl(skip, 5), "16le"_s)) - return BufferEncodingType::ucs2; - // ucs2 - } else if (encoding[1] == 'c' && encoding[2] == 's') { - const size_t skip = encoding[3] == '-' ? 4 : 3; - if (encoding[skip] == '2' && encoding[skip + 1] == '\0') - return BufferEncodingType::ucs2; - } + case 'U': { if (WTF::equalIgnoringASCIICase(encoding, "utf8"_s)) return BufferEncodingType::utf8; if (WTF::equalIgnoringASCIICase(encoding, "utf-8"_s)) @@ -103,35 +91,17 @@ template<> std::optional<BufferEncodingType> parseEnumeration<BufferEncodingType if (WTF::equalIgnoringASCIICase(encoding, "utf-16le"_s)) return BufferEncodingType::ucs2; break; + } case 'l': - case 'L': - // latin1 - if (encoding[1] == 'a') { - if (WTF::equalIgnoringASCIICase(encoding.substringSharingImpl(2, 4), "tin1"_s)) - return BufferEncodingType::latin1; - } + case 'L': { if (WTF::equalIgnoringASCIICase(encoding, "latin1"_s)) return BufferEncodingType::latin1; break; + } case 'b': - case 'B': - // binary is a deprecated alias of latin1 - if (encoding[1] == 'i') { - if (WTF::equalIgnoringASCIICase(encoding.substringSharingImpl(2, 5), "nary"_s)) - return BufferEncodingType::latin1; - // buffer - } else if (encoding[1] == 'u') { - if (WTF::equalIgnoringASCIICase(encoding.substringSharingImpl(2, 5), "ffer"_s)) - return BufferEncodingType::buffer; - // base64 - } else if (encoding[1] == 'a') { - if (WTF::equalIgnoringASCIICase(encoding.substringSharingImpl(2, 5), "se64"_s)) - return BufferEncodingType::base64; - if (WTF::equalIgnoringASCIICase(encoding.substringSharingImpl(2, 8), "se64url"_s)) - return BufferEncodingType::base64url; - } + case 'B': { if (WTF::equalIgnoringASCIICase(encoding, "binary"_s)) return BufferEncodingType::latin1; // BINARY is a deprecated alias of LATIN1. if (WTF::equalIgnoringASCIICase(encoding, "buffer"_s)) @@ -141,15 +111,12 @@ template<> std::optional<BufferEncodingType> parseEnumeration<BufferEncodingType if (WTF::equalIgnoringASCIICase(encoding, "base64url"_s)) return BufferEncodingType::base64url; break; + } case 'a': case 'A': // ascii - if (encoding[1] == 's') { - if (WTF::equalIgnoringASCIICase(encoding.substringSharingImpl(2, 3), "cii"_s)) - return BufferEncodingType::ascii; - } - if (WTF::equalIgnoringASCIICase(encoding, "ascii"_s)) + if (WTF::equalLettersIgnoringASCIICase(encoding, "ascii"_s)) return BufferEncodingType::ascii; break; |