mirror of
https://github.com/electron/electron.git
synced 2026-01-07 22:54:25 -05:00
* chore: bump chromium in DEPS to 143.0.7469.0 * 7021651: [//gpu] Fold handle creation into D3DImageBackingFactory Refs https://chromium-review.googlesource.com/c/chromium/src/+/7021651 * 7013047: Fix various C++23 build errors in //chrome Refs https://chromium-review.googlesource.com/c/chromium/src/+/7013047 * 7010850: [//ui] Port screen_mac.mm's calls to DisplayColorSpaces Refs https://chromium-review.googlesource.com/c/chromium/src/+/7010850 * 7007933: Remove superfluous mojom includes in //content/public headers Refs https://chromium-review.googlesource.com/c/chromium/src/+/7007933 * 7023196: Trim os_crypt/sync visibility list Refs https://chromium-review.googlesource.com/c/chromium/src/+/7023196 * 7008912: Remove GURL::*_piece() method Refs https://chromium-review.googlesource.com/c/chromium/src/+/7008912 * 7003989: Add wrapper struct for CopyFromSurface output Refs https://chromium-review.googlesource.com/c/chromium/src/+/7003989 * 7017889: [MemoryPressureListener] Remove type aliases Refs https://chromium-review.googlesource.com/c/chromium/src/+/7017889 * 7027780: Delete viz::ResourceSizes Refs https://chromium-review.googlesource.com/c/chromium/src/+/7027780 Refs https://chromium-review.googlesource.com/c/chromium/src/+/6989572 * 6495189: [api] Delete old String::Write* APIs Refs https://chromium-review.googlesource.com/c/v8/v8/+/6495189 * chore: update patches * chore: run script/gen-libc++-filenames.js --------- Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com> Co-authored-by: David Sanders <dsanders11@ucsbalum.com>
277 lines
10 KiB
Diff
277 lines
10 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Chengzhong Wu <cwu631@bloomberg.net>
|
|
Date: Fri, 29 Aug 2025 23:41:00 +0100
|
|
Subject: src: migrate WriteOneByte to WriteOneByteV2
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
PR-URL: https://github.com/nodejs/node/pull/59634
|
|
Fixes: https://github.com/nodejs/node/issues/59555
|
|
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
|
|
Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de>
|
|
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
|
|
Reviewed-By: Darshan Sen <raisinten@gmail.com>
|
|
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
|
|
|
|
diff --git a/src/node_buffer.cc b/src/node_buffer.cc
|
|
index ae73e6743879f32f08b4f6f8c546c587de71d2f3..be93e60f851c6c144fdd19f810e0a44cf3845bce 100644
|
|
--- a/src/node_buffer.cc
|
|
+++ b/src/node_buffer.cc
|
|
@@ -1033,8 +1033,11 @@ void IndexOfString(const FunctionCallbackInfo<Value>& args) {
|
|
if (needle_data == nullptr) {
|
|
return args.GetReturnValue().Set(-1);
|
|
}
|
|
- needle->WriteOneByte(
|
|
- isolate, needle_data, 0, needle_length, String::NO_NULL_TERMINATION);
|
|
+ StringBytes::Write(isolate,
|
|
+ reinterpret_cast<char*>(needle_data),
|
|
+ needle_length,
|
|
+ needle,
|
|
+ enc);
|
|
|
|
result = nbytes::SearchString(reinterpret_cast<const uint8_t*>(haystack),
|
|
haystack_length,
|
|
@@ -1288,11 +1291,7 @@ static void Btoa(const FunctionCallbackInfo<Value>& args) {
|
|
simdutf::binary_to_base64(ext->data(), ext->length(), buffer.out());
|
|
} else if (input->IsOneByte()) {
|
|
MaybeStackBuffer<uint8_t> stack_buf(input->Length());
|
|
- input->WriteOneByte(env->isolate(),
|
|
- stack_buf.out(),
|
|
- 0,
|
|
- input->Length(),
|
|
- String::NO_NULL_TERMINATION);
|
|
+ input->WriteOneByteV2(env->isolate(), 0, input->Length(), stack_buf.out());
|
|
|
|
size_t expected_length =
|
|
simdutf::base64_length_from_binary(input->Length());
|
|
@@ -1348,11 +1347,8 @@ static void Atob(const FunctionCallbackInfo<Value>& args) {
|
|
ext->data(), ext->length(), buffer.out(), simdutf::base64_default);
|
|
} else if (input->IsOneByte()) {
|
|
MaybeStackBuffer<uint8_t> stack_buf(input->Length());
|
|
- input->WriteOneByte(args.GetIsolate(),
|
|
- stack_buf.out(),
|
|
- 0,
|
|
- input->Length(),
|
|
- String::NO_NULL_TERMINATION);
|
|
+ input->WriteOneByteV2(
|
|
+ args.GetIsolate(), 0, input->Length(), stack_buf.out());
|
|
const char* data = reinterpret_cast<const char*>(*stack_buf);
|
|
size_t expected_length =
|
|
simdutf::maximal_binary_length_from_base64(data, input->Length());
|
|
diff --git a/src/node_http2.cc b/src/node_http2.cc
|
|
index 8237c9b7d325dd925ae8798d7795fcd94eeb13d0..27a0db87e1f7f75336ecaa044e7cd66a9a5e87a4 100644
|
|
--- a/src/node_http2.cc
|
|
+++ b/src/node_http2.cc
|
|
@@ -485,13 +485,10 @@ Origins::Origins(
|
|
|
|
CHECK_LE(origin_contents + origin_string_len,
|
|
static_cast<char*>(bs_->Data()) + bs_->ByteLength());
|
|
- CHECK_EQ(origin_string->WriteOneByte(
|
|
- env->isolate(),
|
|
- reinterpret_cast<uint8_t*>(origin_contents),
|
|
- 0,
|
|
- origin_string_len,
|
|
- String::NO_NULL_TERMINATION),
|
|
- origin_string_len);
|
|
+ origin_string->WriteOneByteV2(env->isolate(),
|
|
+ 0,
|
|
+ origin_string_len,
|
|
+ reinterpret_cast<uint8_t*>(origin_contents));
|
|
|
|
size_t n = 0;
|
|
char* p;
|
|
@@ -3183,8 +3180,8 @@ void Http2Session::AltSvc(const FunctionCallbackInfo<Value>& args) {
|
|
if (origin_str.IsEmpty() || value_str.IsEmpty())
|
|
return;
|
|
|
|
- size_t origin_len = origin_str->Length();
|
|
- size_t value_len = value_str->Length();
|
|
+ int origin_len = origin_str->Length();
|
|
+ int value_len = value_str->Length();
|
|
|
|
CHECK_LE(origin_len + value_len, 16382); // Max permitted for ALTSVC
|
|
// Verify that origin len != 0 if stream id == 0, or
|
|
@@ -3193,8 +3190,13 @@ void Http2Session::AltSvc(const FunctionCallbackInfo<Value>& args) {
|
|
|
|
MaybeStackBuffer<uint8_t> origin(origin_len);
|
|
MaybeStackBuffer<uint8_t> value(value_len);
|
|
- origin_str->WriteOneByte(env->isolate(), *origin);
|
|
- value_str->WriteOneByte(env->isolate(), *value);
|
|
+ origin_str->WriteOneByteV2(env->isolate(),
|
|
+ 0,
|
|
+ origin_len,
|
|
+ *origin,
|
|
+ String::WriteFlags::kNullTerminate);
|
|
+ value_str->WriteOneByteV2(
|
|
+ env->isolate(), 0, value_len, *value, String::WriteFlags::kNullTerminate);
|
|
|
|
session->AltSvc(id, *origin, origin_len, *value, value_len);
|
|
}
|
|
diff --git a/src/node_http_common-inl.h b/src/node_http_common-inl.h
|
|
index dba1a5e051b3e03c435ba3885b3fe2d04ea8ca9e..46984dba907fffb836d62b9c6e6b325a0ba504dd 100644
|
|
--- a/src/node_http_common-inl.h
|
|
+++ b/src/node_http_common-inl.h
|
|
@@ -2,9 +2,11 @@
|
|
#define SRC_NODE_HTTP_COMMON_INL_H_
|
|
|
|
#include "node_http_common.h"
|
|
+
|
|
+#include "env-inl.h"
|
|
#include "node.h"
|
|
#include "node_mem-inl.h"
|
|
-#include "env-inl.h"
|
|
+#include "string_bytes.h"
|
|
#include "v8.h"
|
|
|
|
#include <algorithm>
|
|
@@ -37,13 +39,12 @@ NgHeaders<T>::NgHeaders(Environment* env, v8::Local<v8::Array> headers) {
|
|
nv_t* const nva = reinterpret_cast<nv_t*>(start);
|
|
|
|
CHECK_LE(header_contents + header_string_len, *buf_ + buf_.length());
|
|
- CHECK_EQ(header_string.As<v8::String>()->WriteOneByte(
|
|
- env->isolate(),
|
|
- reinterpret_cast<uint8_t*>(header_contents),
|
|
- 0,
|
|
- header_string_len,
|
|
- v8::String::NO_NULL_TERMINATION),
|
|
- header_string_len);
|
|
+ CHECK_EQ(StringBytes::Write(env->isolate(),
|
|
+ header_contents,
|
|
+ header_string_len,
|
|
+ header_string.As<v8::String>(),
|
|
+ LATIN1),
|
|
+ static_cast<size_t>(header_string_len));
|
|
|
|
size_t n = 0;
|
|
char* p;
|
|
diff --git a/src/string_bytes.cc b/src/string_bytes.cc
|
|
index b02e9c5d14c2438d30b16f977c4e8a76bb23479d..71381f8fdc341cf2bac34028eb10df30fd9306b9 100644
|
|
--- a/src/string_bytes.cc
|
|
+++ b/src/string_bytes.cc
|
|
@@ -249,11 +249,13 @@ size_t StringBytes::Write(Isolate* isolate,
|
|
nbytes = std::min(buflen, static_cast<size_t>(input_view.length()));
|
|
memcpy(buf, input_view.data8(), nbytes);
|
|
} else {
|
|
- uint8_t* const dst = reinterpret_cast<uint8_t*>(buf);
|
|
- const int flags = String::HINT_MANY_WRITES_EXPECTED |
|
|
- String::NO_NULL_TERMINATION |
|
|
- String::REPLACE_INVALID_UTF8;
|
|
- nbytes = str->WriteOneByte(isolate, dst, 0, buflen, flags);
|
|
+ nbytes = std::min(buflen, static_cast<size_t>(input_view.length()));
|
|
+ // Do not use v8::String::WriteOneByteV2 as it asserts the string to be
|
|
+ // a one byte string. For compatibility, convert the uint16_t to uint8_t
|
|
+ // even though this may loose accuracy.
|
|
+ for (size_t i = 0; i < nbytes; i++) {
|
|
+ buf[i] = static_cast<uint8_t>(input_view.data16()[i]);
|
|
+ }
|
|
}
|
|
break;
|
|
|
|
diff --git a/test/cctest/test_string_bytes.cc b/test/cctest/test_string_bytes.cc
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..bc308918680bb153dbbda8b18dcb24d129f14833
|
|
--- /dev/null
|
|
+++ b/test/cctest/test_string_bytes.cc
|
|
@@ -0,0 +1,100 @@
|
|
+#include "gtest/gtest.h"
|
|
+#include "node.h"
|
|
+#include "node_test_fixture.h"
|
|
+#include "string_bytes.h"
|
|
+#include "util-inl.h"
|
|
+
|
|
+using node::MaybeStackBuffer;
|
|
+using node::StringBytes;
|
|
+using v8::HandleScope;
|
|
+using v8::Local;
|
|
+using v8::Maybe;
|
|
+using v8::String;
|
|
+
|
|
+class StringBytesTest : public EnvironmentTestFixture {};
|
|
+
|
|
+// Data "Hello, ÆÊÎÖÿ"
|
|
+static const char latin1_data[] = "Hello, \xC6\xCA\xCE\xD6\xFF";
|
|
+static const char utf8_data[] = "Hello, ÆÊÎÖÿ";
|
|
+
|
|
+TEST_F(StringBytesTest, WriteLatin1WithOneByteString) {
|
|
+ const HandleScope handle_scope(isolate_);
|
|
+ const Argv argv;
|
|
+ Env env_{handle_scope, argv};
|
|
+
|
|
+ Local<String> one_byte_str =
|
|
+ String::NewFromOneByte(isolate_,
|
|
+ reinterpret_cast<const uint8_t*>(latin1_data))
|
|
+ .ToLocalChecked();
|
|
+
|
|
+ Maybe<size_t> size_maybe =
|
|
+ StringBytes::StorageSize(isolate_, one_byte_str, node::LATIN1);
|
|
+
|
|
+ ASSERT_TRUE(size_maybe.IsJust());
|
|
+ size_t size = size_maybe.FromJust();
|
|
+ ASSERT_EQ(size, 12u);
|
|
+
|
|
+ MaybeStackBuffer<char> buf;
|
|
+ size_t written = StringBytes::Write(
|
|
+ isolate_, buf.out(), buf.capacity(), one_byte_str, node::LATIN1);
|
|
+ ASSERT_EQ(written, 12u);
|
|
+
|
|
+ // Null-terminate the buffer and compare the contents.
|
|
+ buf.SetLength(13);
|
|
+ buf[12] = '\0';
|
|
+ ASSERT_STREQ(latin1_data, buf.out());
|
|
+}
|
|
+
|
|
+TEST_F(StringBytesTest, WriteLatin1WithUtf8String) {
|
|
+ const HandleScope handle_scope(isolate_);
|
|
+ const Argv argv;
|
|
+ Env env_{handle_scope, argv};
|
|
+
|
|
+ Local<String> utf8_str =
|
|
+ String::NewFromUtf8(isolate_, utf8_data).ToLocalChecked();
|
|
+
|
|
+ Maybe<size_t> size_maybe =
|
|
+ StringBytes::StorageSize(isolate_, utf8_str, node::LATIN1);
|
|
+
|
|
+ ASSERT_TRUE(size_maybe.IsJust());
|
|
+ size_t size = size_maybe.FromJust();
|
|
+ ASSERT_EQ(size, 12u);
|
|
+
|
|
+ MaybeStackBuffer<char> buf;
|
|
+ size_t written = StringBytes::Write(
|
|
+ isolate_, buf.out(), buf.capacity(), utf8_str, node::LATIN1);
|
|
+ ASSERT_EQ(written, 12u);
|
|
+
|
|
+ // Null-terminate the buffer and compare the contents.
|
|
+ buf.SetLength(13);
|
|
+ buf[12] = '\0';
|
|
+ ASSERT_STREQ(latin1_data, buf.out());
|
|
+}
|
|
+
|
|
+// Verify that StringBytes::Write converts two-byte characters to one-byte
|
|
+// characters, even if there is no valid one-byte representation.
|
|
+TEST_F(StringBytesTest, WriteLatin1WithInvalidChar) {
|
|
+ const HandleScope handle_scope(isolate_);
|
|
+ const Argv argv;
|
|
+ Env env_{handle_scope, argv};
|
|
+
|
|
+ Local<String> utf8_str =
|
|
+ String::NewFromUtf8(isolate_, "Hello, 世界").ToLocalChecked();
|
|
+
|
|
+ Maybe<size_t> size_maybe =
|
|
+ StringBytes::StorageSize(isolate_, utf8_str, node::LATIN1);
|
|
+
|
|
+ ASSERT_TRUE(size_maybe.IsJust());
|
|
+ size_t size = size_maybe.FromJust();
|
|
+ ASSERT_EQ(size, 9u);
|
|
+
|
|
+ MaybeStackBuffer<char> buf;
|
|
+ size_t written = StringBytes::Write(
|
|
+ isolate_, buf.out(), buf.capacity(), utf8_str, node::LATIN1);
|
|
+ ASSERT_EQ(written, 9u);
|
|
+
|
|
+ // Null-terminate the buffer and compare the contents.
|
|
+ buf.SetLength(10);
|
|
+ buf[9] = '\0';
|
|
+ ASSERT_STREQ("Hello, \x16\x4C", buf.out());
|
|
+}
|