]> git.kaiwu.me - njs.git/commitdiff
DataView: fix copy-on-write in set methods
authorDmitry Volyntsev <xeioex@nginx.com>
Fri, 30 Oct 2026 01:50:51 +0000 (18:50 -0700)
committerDmitry Volyntsev <xeioexception@gmail.com>
Mon, 2 Nov 2026 14:42:35 +0000 (06:42 -0800)
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
src/test/njs_unit_test.c

index d0b86d722140fe7a7daf7131eb06a338bbc3f046..356872d58a6787517d3ec828f82bda021885c2df 100644 (file)
@@ -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) {
index f0258738bc56d92a599d485dbb4ac279988fc715..1fa222511ff9940307c9482a293bba6f15338fd5 100644 (file)
@@ -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") },