Skip to content

Commit 54d7d14

Browse files
authored
src: coerce spawnSync args to string once
PR-URL: #62633 Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com> Reviewed-By: Filip Skokan <panva.ip@gmail.com>
1 parent d0fa608 commit 54d7d14

File tree

2 files changed

+20
-16
lines changed

2 files changed

+20
-16
lines changed

src/spawn_sync.cc

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ using v8::Isolate;
4444
using v8::Just;
4545
using v8::JustVoid;
4646
using v8::Local;
47+
using v8::LocalVector;
4748
using v8::Maybe;
4849
using v8::MaybeLocal;
4950
using v8::Nothing;
@@ -1155,16 +1156,17 @@ Maybe<int> SyncProcessRunner::CopyJsStringArray(Local<Value> js_value,
11551156
if (!js_value->IsArray()) return Just<int>(UV_EINVAL);
11561157

11571158
Local<Context> context = env()->context();
1158-
js_array = js_value.As<Array>()->Clone().As<Array>();
1159+
js_array = js_value.As<Array>();
11591160
length = js_array->Length();
11601161
data_size = 0;
11611162

1163+
LocalVector<String> values(isolate, length);
1164+
11621165
// Index has a pointer to every string element, plus one more for a final
11631166
// null pointer.
11641167
list_size = (length + 1) * sizeof *list;
11651168

1166-
// Convert all array elements to string. Modify the js object itself if
1167-
// needed - it's okay since we cloned the original object. Also compute the
1169+
// Convert all array elements to string. Also compute the
11681170
// length of all strings, including room for a null terminator after every
11691171
// string. Align strings to cache lines.
11701172
for (uint32_t i = 0; i < length; i++) {
@@ -1173,17 +1175,19 @@ Maybe<int> SyncProcessRunner::CopyJsStringArray(Local<Value> js_value,
11731175
return Nothing<int>();
11741176
}
11751177

1176-
if (!value->IsString()) {
1178+
if (value->IsString()) {
1179+
values[i] = value.As<String>();
1180+
} else {
11771181
Local<String> string;
11781182
if (!value->ToString(env()->isolate()->GetCurrentContext())
1179-
.ToLocal(&string) ||
1180-
js_array->Set(context, i, string).IsNothing()) {
1183+
.ToLocal(&string)) {
11811184
return Nothing<int>();
11821185
}
1186+
values[i] = string;
11831187
}
11841188

11851189
size_t maybe_size;
1186-
if (!StringBytes::StorageSize(isolate, value, UTF8).To(&maybe_size)) {
1190+
if (!StringBytes::StorageSize(isolate, values[i], UTF8).To(&maybe_size)) {
11871191
return Nothing<int>();
11881192
}
11891193
data_size += maybe_size + 1;
@@ -1197,15 +1201,8 @@ Maybe<int> SyncProcessRunner::CopyJsStringArray(Local<Value> js_value,
11971201

11981202
for (uint32_t i = 0; i < length; i++) {
11991203
list[i] = buffer + data_offset;
1200-
Local<Value> value;
1201-
if (!js_array->Get(context, i).ToLocal(&value)) {
1202-
return Nothing<int>();
1203-
}
1204-
data_offset += StringBytes::Write(isolate,
1205-
buffer + data_offset,
1206-
-1,
1207-
value,
1208-
UTF8);
1204+
data_offset +=
1205+
StringBytes::Write(isolate, buffer + data_offset, -1, values[i], UTF8);
12091206
buffer[data_offset++] = '\0';
12101207
data_offset = nbytes::RoundUp(data_offset, sizeof(void*));
12111208
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
'use strict';
2+
const common = require('../common');
3+
const { spawnSync } = require('child_process');
4+
const stateful = {
5+
toString: common.mustCall(() => ';'),
6+
};
7+
spawnSync(process.execPath, ['-e', stateful], { stdio: 'ignore' });

0 commit comments

Comments
 (0)