@@ -678,10 +678,13 @@ static v8::Local<v8::Value> MsgpackToJs(const msgpack_object* mo) {
678678}
679679
680680/*
681- * Lazy unpack: keep the msgpack zone (and the source Buffer) alive, and wrap
682- * maps/arrays as JS objects whose values are accessors. Nested containers are
683- * not converted until a property is read. toJSON / inspect.custom materialize
684- * through MsgpackToJs so JSON.stringify and util.inspect match eager unpack.
681+ * Lazy unpack: keep the msgpack zone (and a session-owned copy of the source
682+ * bytes) alive, and wrap maps/arrays as JS objects whose values are accessors.
683+ * Nested containers are not converted until a property is read. toJSON /
684+ * inspect.custom materialize through MsgpackToJs so JSON.stringify and
685+ * util.inspect match eager unpack. The copy is required because msgpack-c
686+ * aliases str/bin into the input; a Persistent on the caller's Buffer does
687+ * not survive ArrayBuffer transfer.
685688 */
686689class LazySession : public Nan ::ObjectWrap {
687690 public:
@@ -1075,6 +1078,26 @@ NAN_METHOD(Unpack) {
10751078 return Nan::ThrowError (" Encountered error unpacking buffer" );
10761079 }
10771080
1081+ /* Copy before unpack_next so via.str/via.bin alias session-owned bytes.
1082+ * Nan::Persistent on the caller's Buffer does not keep the backing store
1083+ * through structuredClone / postMessage transfer (CWE-416). */
1084+ if (UnpackLazyRequested (info)) {
1085+ /* GCOVR_EXCL_BR_START: node Buffers are smaller than UINT32_MAX. */
1086+ if (len > static_cast <size_t >(UINT32_MAX )) {
1087+ return Nan::ThrowError (" Error copying buffer" );
1088+ }
1089+ /* GCOVR_EXCL_BR_STOP */
1090+ Nan::MaybeLocal<v8::Object> copied =
1091+ Nan::CopyBuffer (data, static_cast <uint32_t >(len));
1092+ /* GCOVR_EXCL_BR_START: CopyBuffer fails only when V8 is out of memory. */
1093+ if (copied.IsEmpty ()) {
1094+ return Nan::ThrowError (" Error copying buffer" );
1095+ }
1096+ /* GCOVR_EXCL_BR_STOP */
1097+ buf = copied.ToLocalChecked ();
1098+ data = node::Buffer::Data (buf);
1099+ }
1100+
10781101 msgpack_unpacked result;
10791102 msgpack_unpacked_init (&result);
10801103 size_t off = 0 ;
0 commit comments