Skip to content

Commit

Permalink
src,buffer: remove unused chars_written parameter
Browse files Browse the repository at this point in the history
This parameter was always being set to `nullptr` by its callers, either
explicitly or implicitly via the default argument. It was also buggy, as
in some cases it wouldn't be written to, potentially leaking stack
memory (see the early returns in `StringBytes::WriteUCS2`). Remove it
entirely.

PR-URL: #44092
Reviewed-By: Feng Yu <F3n67u@outlook.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Darshan Sen <raisinten@gmail.com>
  • Loading branch information
kvakil authored and juanarbol committed Oct 11, 2022
1 parent 97ad1a0 commit 28911e2
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 42 deletions.
2 changes: 1 addition & 1 deletion src/api/encoding.cc
Expand Up @@ -150,7 +150,7 @@ ssize_t DecodeWrite(Isolate* isolate,
size_t buflen,
Local<Value> val,
enum encoding encoding) {
return StringBytes::Write(isolate, buf, buflen, val, encoding, nullptr);
return StringBytes::Write(isolate, buf, buflen, val, encoding);
}

} // namespace node
16 changes: 4 additions & 12 deletions src/node_buffer.cc
Expand Up @@ -667,12 +667,8 @@ void Fill(const FunctionCallbackInfo<Value>& args) {
// Write initial String to Buffer, then use that memory to copy remainder
// of string. Correct the string length for cases like HEX where less than
// the total string length is written.
str_length = StringBytes::Write(env->isolate(),
ts_obj_data + start,
fill_length,
str_obj,
enc,
nullptr);
str_length = StringBytes::Write(
env->isolate(), ts_obj_data + start, fill_length, str_obj, enc);
}

start_fill:
Expand Down Expand Up @@ -731,12 +727,8 @@ void StringWrite(const FunctionCallbackInfo<Value>& args) {
if (max_length == 0)
return args.GetReturnValue().Set(0);

uint32_t written = StringBytes::Write(env->isolate(),
ts_obj_data + offset,
max_length,
str,
encoding,
nullptr);
uint32_t written = StringBytes::Write(
env->isolate(), ts_obj_data + offset, max_length, str, encoding);
args.GetReturnValue().Set(written);
}

Expand Down
33 changes: 8 additions & 25 deletions src/string_bytes.cc
Expand Up @@ -260,12 +260,8 @@ static size_t hex_decode(char* buf,
return i;
}

size_t StringBytes::WriteUCS2(Isolate* isolate,
char* buf,
size_t buflen,
Local<String> str,
int flags,
size_t* chars_written) {
size_t StringBytes::WriteUCS2(
Isolate* isolate, char* buf, size_t buflen, Local<String> str, int flags) {
uint16_t* const dst = reinterpret_cast<uint16_t*>(buf);

size_t max_chars = buflen / sizeof(*dst);
Expand All @@ -277,15 +273,16 @@ size_t StringBytes::WriteUCS2(Isolate* isolate,
size_t nchars;
if (aligned_dst == dst) {
nchars = str->Write(isolate, dst, 0, max_chars, flags);
*chars_written = nchars;
return nchars * sizeof(*dst);
}

CHECK_EQ(reinterpret_cast<uintptr_t>(aligned_dst) % sizeof(*dst), 0);

// Write all but the last char
max_chars = std::min(max_chars, static_cast<size_t>(str->Length()));
if (max_chars == 0) return 0;
if (max_chars == 0) {
return 0;
}
nchars = str->Write(isolate, aligned_dst, 0, max_chars - 1, flags);
CHECK_EQ(nchars, max_chars - 1);

Expand All @@ -298,23 +295,16 @@ size_t StringBytes::WriteUCS2(Isolate* isolate,
memcpy(buf + nchars * sizeof(*dst), &last, sizeof(last));
nchars++;

*chars_written = nchars;
return nchars * sizeof(*dst);
}


size_t StringBytes::Write(Isolate* isolate,
char* buf,
size_t buflen,
Local<Value> val,
enum encoding encoding,
int* chars_written) {
enum encoding encoding) {
HandleScope scope(isolate);
size_t nbytes;
int nchars;

if (chars_written == nullptr)
chars_written = &nchars;

CHECK(val->IsString() == true);
Local<String> str = val.As<String>();
Expand All @@ -334,19 +324,15 @@ size_t StringBytes::Write(Isolate* isolate,
uint8_t* const dst = reinterpret_cast<uint8_t*>(buf);
nbytes = str->WriteOneByte(isolate, dst, 0, buflen, flags);
}
*chars_written = nbytes;
break;

case BUFFER:
case UTF8:
nbytes = str->WriteUtf8(isolate, buf, buflen, chars_written, flags);
nbytes = str->WriteUtf8(isolate, buf, buflen, nullptr, flags);
break;

case UCS2: {
size_t nchars;

nbytes = WriteUCS2(isolate, buf, buflen, str, flags, &nchars);
*chars_written = static_cast<int>(nchars);
nbytes = WriteUCS2(isolate, buf, buflen, str, flags);

// Node's "ucs2" encoding wants LE character data stored in
// the Buffer, so we need to reorder on BE platforms. See
Expand All @@ -368,7 +354,6 @@ size_t StringBytes::Write(Isolate* isolate,
String::Value value(isolate, str);
nbytes = base64_decode(buf, buflen, *value, value.length());
}
*chars_written = nbytes;
break;

case HEX:
Expand All @@ -379,7 +364,6 @@ size_t StringBytes::Write(Isolate* isolate,
String::Value value(isolate, str);
nbytes = hex_decode(buf, buflen, *value, value.length());
}
*chars_written = nbytes;
break;

default:
Expand All @@ -390,7 +374,6 @@ size_t StringBytes::Write(Isolate* isolate,
return nbytes;
}


// Quick and dirty size calculation
// Will always be at least big enough, but may have some extra
// UTF8 can be as much as 3x the size, Base64 can have 1-2 extra bytes
Expand Down
6 changes: 2 additions & 4 deletions src/string_bytes.h
Expand Up @@ -75,8 +75,7 @@ class StringBytes {
char* buf,
size_t buflen,
v8::Local<v8::Value> val,
enum encoding enc,
int* chars_written = nullptr);
enum encoding enc);

// Take the bytes in the src, and turn it into a Buffer or String.
static v8::MaybeLocal<v8::Value> Encode(v8::Isolate* isolate,
Expand Down Expand Up @@ -111,8 +110,7 @@ class StringBytes {
char* buf,
size_t buflen,
v8::Local<v8::String> str,
int flags,
size_t* chars_written);
int flags);
};

} // namespace node
Expand Down

0 comments on commit 28911e2

Please sign in to comment.