src: coerce `spawnSync` args to string once · nodejs/node@06c405f
@@ -44,6 +44,7 @@ using v8::Isolate;
4444using v8::Just;
4545using v8::JustVoid;
4646using v8::Local;
47+using v8::LocalVector;
4748using v8::Maybe;
4849using v8::MaybeLocal;
4950using v8::Nothing;
@@ -1155,16 +1156,17 @@ Maybe<int> SyncProcessRunner::CopyJsStringArray(Local<Value> js_value,
11551156if (!js_value->IsArray()) return Just<int>(UV_EINVAL);
1156115711571158 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;
116111621163+ 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;
116511681166-// 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.
11701172for (uint32_t i = 0; i < length; i++) {
@@ -1173,17 +1175,19 @@ Maybe<int> SyncProcessRunner::CopyJsStringArray(Local<Value> js_value,
11731175return Nothing<int>();
11741176 }
117511771176-if (!value->IsString()) {
1178+if (value->IsString()) {
1179+ values[i] = value.As<String>();
1180+ } else {
11771181 Local<String> string;
11781182if (!value->ToString(env()->isolate()->GetCurrentContext())
1179- .ToLocal(&string) ||
1180- js_array->Set(context, i, string).IsNothing()) {
1183+ .ToLocal(&string)) {
11811184return Nothing<int>();
11821185 }
1186+ values[i] = string;
11831187 }
1184118811851189size_t maybe_size;
1186-if (!StringBytes::StorageSize(isolate, value, UTF8).To(&maybe_size)) {
1190+if (!StringBytes::StorageSize(isolate, values[i], UTF8).To(&maybe_size)) {
11871191return Nothing<int>();
11881192 }
11891193 data_size += maybe_size + 1;
@@ -1197,15 +1201,8 @@ Maybe<int> SyncProcessRunner::CopyJsStringArray(Local<Value> js_value,
1197120111981202for (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 }