GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — src: migrate WriteOneByte to WriteOneByteV2 by legendecas · Pull Request #59634 · nodejs/node

src: migrate WriteOneByte to WriteOneByteV2 #59634

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Sign up for GitHub

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
nodejs-github-bot merged 1 commit into nodejs:main from legendecas:v8-writeontebytev2
Aug 29, 2025

Uh oh!

There was an error while loading. Please reload this page.

Merged

src: migrate WriteOneByte to WriteOneByteV2 #59634

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
1 commit
Select commit
2249366
src: migrate WriteOneByte to WriteOneByteV2
legendecas Aug 26, 2025
File filter
Filter by extension

Clear filters
Conversations
Failed to load comments.
Loading

Uh oh!

There was an error while loading. Please reload this page.

Jump to
Jump to file
Failed to load files.
Loading

Uh oh!

There was an error while loading. Please reload this page.

Diff view
Diff view
src: migrate WriteOneByte to WriteOneByteV2
  • Loading branch information

Uh oh!

There was an error while loading. Please reload this page.

@legendecas
legendecas committed Aug 29, 2025
commit 22493662f61554ce7b70e9a258aee68a372481e9

There are no files selected for viewing

20 changes: 8 additions & 12 deletions 20 src/node_buffer.cc
Show comments
View file
Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -1037,8 +1037,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,
Expand Down Expand Up @@ -1302,11 +1305,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());
Expand Down Expand Up @@ -1362,11 +1361,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());
Expand Down
24 changes: 13 additions & 11 deletions 24 src/node_http2.cc
Show comments
View file
Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -483,13 +483,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;
Expand Down Expand Up @@ -3186,8 +3183,8 @@ void Http2Session::AltSvc(const FunctionCallbackInfo<Value>& args) {
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
Expand All @@ -3196,8 +3193,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);
}
Expand Down
17 changes: 9 additions & 8 deletions 17 src/node_http_common-inl.h
Show comments
View file
Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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;
Expand Down
12 changes: 7 additions & 5 deletions 12 src/string_bytes.cc
Show comments
View file
Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -254,11 +254,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;

Expand Down
100 changes: 100 additions & 0 deletions 100 test/cctest/test_string_bytes.cc
Show comments
View file
Open in desktop
Original file line number Diff line number Diff line change
@@ -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());
}
Add this suggestion to a batch that can be applied as a single commit. This suggestion is invalid because no changes were made to the code. Suggestions cannot be applied while the pull request is closed. Suggestions cannot be applied while viewing a subset of changes. Only one suggestion per line can be applied in a batch. Add this suggestion to a batch that can be applied as a single commit. Applying suggestions on deleted lines is not supported. You must change the existing code in this line in order to create a valid suggestion. Outdated suggestions cannot be applied. This suggestion has been applied or marked resolved. Suggestions cannot be applied from pending reviews. Suggestions cannot be applied on multi-line comments. Suggestions cannot be applied while the pull request is queued to merge. Suggestion cannot be applied right now. Please check back later.
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.