]> git.kaiwu.me - njs.git/commitdiff
TextEncoder: fix copy-on-write in encodeInto()
authorDmitry Volyntsev <xeioex@nginx.com>
Fri, 30 Oct 2026 01:57:39 +0000 (18:57 -0700)
committerDmitry Volyntsev <xeioexception@gmail.com>
Mon, 2 Nov 2026 14:42:35 +0000 (06:42 -0800)
Previously, TextEncoder.prototype.encodeInto() wrote directly into the
destination buffer without making a private copy of shared data.  As a
result, encoding into 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_encoding.c
src/test/njs_unit_test.c

index b1e1d90332db5a99de38b442ae1f50e32f2c4522..6cd298ea554d2239b782bdb9fa8cb93a0f84a7a2 100644 (file)
@@ -199,8 +199,7 @@ njs_text_encoder_encode_into(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     end = start + str.length;
 
     array = njs_typed_array(dest);
-    if (njs_slow_path(njs_is_detached_buffer(array->buffer))) {
-        njs_type_error(vm, "detached buffer");
+    if (njs_slow_path(njs_typed_array_writable(vm, array) == NULL)) {
         return NJS_ERROR;
     }
 
index d47b2ee589516c01ac28081b56e6ab5e2af90cea..c4671b6be929a1648ddbe9918712ccc108dafcd3 100644 (file)
@@ -22044,6 +22044,11 @@ static njs_unit_test_t  njs_externals_test[] =
               "[b[0], new Uint8Array($r.arrayBuffer)[0]]"),
       njs_str("64,208") },
 
+    { njs_str("var b = $r.buffer;"
+              "(new TextEncoder()).encodeInto('@', b);"
+              "[b[0], $r.buffer[0]]"),
+      njs_str("64,208") },
+
     { njs_str("$r.buffer instanceof Buffer"),
       njs_str("true") },