From 87e2d83a53d14b4d56450628642bf3d2d8afb9d1 Mon Sep 17 00:00:00 2001 From: Dmitry Volyntsev Date: Thu, 29 Oct 2026 18:50:51 -0700 Subject: [PATCH] DataView: fix copy-on-write in set methods Previously, DataView.prototype.setXXX() wrote directly into the underlying ArrayBuffer without making a private copy of shared data. As a result, writing through a DataView over r.requestBuffer in nginx modified the request body seen by subsequent reads. Now, the buffer is made writable before the write, as is done for typed arrays. The issue was introduced in 409004cb (0.4.4). --- src/njs_typed_array.c | 6 +++++- src/test/njs_unit_test.c | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/njs_typed_array.c b/src/njs_typed_array.c index d0b86d72..356872d5 100644 --- a/src/njs_typed_array.c +++ b/src/njs_typed_array.c @@ -2603,7 +2603,11 @@ njs_data_view_prototype_set(njs_vm_t *vm, njs_value_t *args, return NJS_ERROR; } - buffer = view->buffer; + buffer = njs_typed_array_writable(vm, view); + if (njs_slow_path(buffer == NULL)) { + return NJS_ERROR; + } + u8 = &buffer->u.u8[index + view->offset]; switch (type) { diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index f0258738..1fa22251 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -22033,6 +22033,12 @@ static njs_unit_test_t njs_externals_test[] = { njs_str("new Uint8Array($r.buffer.sort().slice(0,3))"), njs_str("129,144,145") }, + { njs_str("var b = $r.buffer; " + "var v = new DataView(b.buffer, b.byteOffset);" + "v.setUint8(0, '@'.codePointAt(0));" + "[b[0], $r.buffer[0]]"), + njs_str("64,208") }, + { njs_str("$r.buffer instanceof Buffer"), njs_str("true") }, -- 2.47.3