diff --git a/src/js_native_api_v8.cc b/src/js_native_api_v8.cc index ba1ab6f18511..6fbf33040c52 100644 --- a/src/js_native_api_v8.cc +++ b/src/js_native_api_v8.cc @@ -3724,8 +3724,9 @@ napi_status NAPI_CDECL napi_detach_arraybuffer(napi_env env, env, value->IsArrayBuffer(), napi_arraybuffer_expected); v8::Local it = value.As(); - RETURN_STATUS_IF_FALSE( - env, it->IsDetachable(), napi_detachable_arraybuffer_expected); + RETURN_STATUS_IF_FALSE(env, + it->IsDetachable() && !it->IsImmutable(), + napi_detachable_arraybuffer_expected); it->Detach(v8::Local()).Check(); diff --git a/test/js-native-api/test_typedarray/test-detach-immutable.js b/test/js-native-api/test_typedarray/test-detach-immutable.js new file mode 100644 index 000000000000..67402f06e3e3 --- /dev/null +++ b/test/js-native-api/test_typedarray/test-detach-immutable.js @@ -0,0 +1,25 @@ +// Flags: --js-immutable-arraybuffer +'use strict'; + +const common = require('../../common'); +const assert = require('assert'); +const binding = require(`./build/${common.buildType}/test_typedarray`); + +for (const bytes of [[1, 2, 3, 4], []]) { + const buffer = Uint8Array.from(bytes).buffer.transferToImmutable(); + const view = new Uint8Array(buffer); + + assert.throws(() => binding.Detach(view), { + name: 'Error', + message: 'A detachable arraybuffer was expected', + }); + assert.strictEqual(binding.IsDetached(buffer), false); + assert.strictEqual(buffer.immutable, true); + assert.strictEqual(view.byteLength, bytes.length); + assert.deepStrictEqual([...view], bytes); + + const mutable = Uint8Array.from(bytes); + binding.Detach(mutable); + assert.strictEqual(binding.IsDetached(mutable.buffer), true); + assert.strictEqual(mutable.byteLength, 0); +}