Repository: nodejs/node
File: src/string_bytes.cc (C++)

Code before:
        char* out = node::UncheckedMalloc(buflen);
        if (out == nullptr) {
          isolate->ThrowException(node::ERR_MEMORY_ALLOCATION_FAILED(isolate));
          return MaybeLocal<Value>();
        }
        nbytes::ForceAscii(buf, out, buflen);
        return ExternOneByteString::New(isolate, out, buflen);
      } else {
        return ExternOneByteString::NewFromCopy(isolate, buf, buflen);
      }

    case UTF8: {
      buflen = keep_buflen_in_range(buflen);

      // ASCII fast path
      // TODO(chalker): remove when String::NewFromUtf8 is fast enough itself
      // This is cheap compared to the benefits though
      if (!simdutf::validate_ascii_with_errors(buf, buflen).error) {
        return ExternOneByteString::NewFromCopy(isolate, buf, buflen);
      }

      if (simdutf::validate_utf8(buf, buflen)) {
        // We know that we are non-ASCII (and are unlikely Latin1), use 2-byte
        // In the most likely case of valid UTF-8, we can use this fast impl
        size_t u16size = simdutf::utf16_length_from_utf8(buf, buflen);
        uint16_t* dst = node::UncheckedMalloc<uint16_t>(u16size);
        size_t utf16len = simdutf::convert_valid_utf8_to_utf16(
            buf, buflen, reinterpret_cast<char16_t*>(dst));
        return ExternTwoByteString::New(isolate, dst, utf16len);
      }

      val =
          String::NewFromUtf8(isolate, buf, v8::NewStringType::kNormal, buflen);
      Local<String> str;
      if (!val.ToLocal(&str)) {
        isolate->ThrowException(node::ERR_STRING_TOO_LONG(isolate));
      }
      return str;
    }

    case LATIN1:
      buflen = keep_buflen_in_range(buflen);
      return ExternOneByteString::NewFromCopy(isolate, buf, buflen);

    case BASE64: {
      buflen = keep_buflen_in_range(buflen);
      size_t dlen = simdutf::base64_length_from_binary(buflen);
      char* dst = node::UncheckedMalloc(dlen);
      if (dst == nullptr) {
        isolate->ThrowException(node::ERR_MEMORY_ALLOCATION_FAILED(isolate));
        return MaybeLocal<Value>();

Review comment (suggestion):
Again, I think we need a guard here to not allocate for no reason:

```suggestion
        size_t u16size = simdutf::utf16_length_from_utf8(buf, buflen);
        if (u16size > static_cast<size_t>(v8::String::kMaxLength)) {
          isolate->ThrowException(node::ERR_STRING_TOO_LONG(isolate));
          return MaybeLocal<Value>();
        }
```

Code after:
        char* out = node::UncheckedMalloc(buflen);
        if (out == nullptr) {
          isolate->ThrowException(node::ERR_MEMORY_ALLOCATION_FAILED(isolate));
          return MaybeLocal<Value>();
        }
        nbytes::ForceAscii(buf, out, buflen);
        return ExternOneByteString::New(isolate, out, buflen);
      } else {
        return ExternOneByteString::NewFromCopy(isolate, buf, buflen);
      }

    case UTF8: {
      buflen = keep_buflen_in_range(buflen);

      // ASCII fast path
      // TODO(chalker): remove when String::NewFromUtf8 is fast enough itself
      // This is cheap compared to the benefits though
      if (!simdutf::validate_ascii_with_errors(buf, buflen).error) {
        return ExternOneByteString::NewFromCopy(isolate, buf, buflen);
      }

      if (buflen >= 32 && simdutf::validate_utf8(buf, buflen)) {
        // We know that we are non-ASCII (and are unlikely Latin1), use 2-byte
        // In the most likely case of valid UTF-8, we can use this fast impl
        // For very short input, it is slower, so we limit min size
        size_t u16size = simdutf::utf16_length_from_utf8(buf, buflen);
        if (u16size > static_cast<size_t>(v8::String::kMaxLength)) {
          isolate->ThrowException(ERR_STRING_TOO_LONG(isolate));
          return MaybeLocal<Value>();
        }
        uint16_t* dst = node::UncheckedMalloc<uint16_t>(u16size);
        if (u16size != 0 && dst == nullptr) {
          THROW_ERR_MEMORY_ALLOCATION_FAILED(isolate);
          return MaybeLocal<Value>();
        }
        size_t utf16len = simdutf::convert_valid_utf8_to_utf16(
            buf, buflen, reinterpret_cast<char16_t*>(dst));
        return ExternTwoByteString::New(isolate, dst, utf16len);
      }

      val =
          String::NewFromUtf8(isolate, buf, v8::NewStringType::kNormal, buflen);
      Local<String> str;
      if (!val.ToLocal(&str)) {
        isolate->ThrowException(node::ERR_STRING_TOO_LONG(isolate));
      }
      return str;
    }

    case LATIN1:
      buflen = keep_buflen_in_range(buflen);