@@ -51,6 +51,12 @@ static bool ReportDetachedArrayBuffer(JSContext* cx) {
5151 return false ;
5252}
5353
54+ static bool ReportImmutableBuffer (JSContext* cx) {
55+ JS_ReportErrorNumberASCII (cx, GetErrorMessage, nullptr ,
56+ JSMSG_ARRAYBUFFER_IMMUTABLE);
57+ return false ;
58+ }
59+
5460static bool ReportResizedArrayBuffer (JSContext* cx) {
5561 JS_ReportErrorNumberASCII (cx, GetErrorMessage, nullptr ,
5662 JSMSG_TYPED_ARRAY_RESIZED_BOUNDS);
@@ -64,15 +70,15 @@ static bool ReportOutOfRange(JSContext* cx) {
6470 return false ;
6571}
6672
73+ enum class AccessMode { Read, Write };
74+
6775
6876
6977
7078static bool ValidateIntegerTypedArray (
71- JSContext* cx, HandleValue typedArray, bool waitable,
79+ JSContext* cx, HandleValue typedArray, bool waitable, AccessMode accessMode,
7280 MutableHandle<TypedArrayObject*> unwrappedTypedArray) {
7381
74-
75-
7682 auto * unwrapped = UnwrapAndTypeCheckValue<TypedArrayObject>(
7783 cx, typedArray, [cx]() { ReportBadArrayType (cx); });
7884 if (!unwrapped) {
@@ -83,6 +89,11 @@ static bool ValidateIntegerTypedArray(
8389 return ReportDetachedArrayBuffer (cx);
8490 }
8591
92+ if (accessMode == AccessMode::Write &&
93+ unwrapped->is <ImmutableTypedArrayObject>()) {
94+ return ReportImmutableBuffer (cx);
95+ }
96+
8697
8798 if (waitable) {
8899 switch (unwrapped->type ()) {
@@ -253,10 +264,12 @@ struct ArrayOps<uint64_t> {
253264
254265
255266template <typename Op>
256- bool AtomicAccess (JSContext* cx, HandleValue obj, HandleValue index, Op op) {
267+ static bool AtomicAccess (JSContext* cx, HandleValue obj, HandleValue index,
268+ AccessMode accessMode, Op op) {
257269
258270 Rooted<TypedArrayObject*> unwrappedTypedArray (cx);
259- if (!ValidateIntegerTypedArray (cx, obj, false , &unwrappedTypedArray)) {
271+ if (!ValidateIntegerTypedArray (cx, obj, false , accessMode,
272+ &unwrappedTypedArray)) {
260273 return false ;
261274 }
262275
@@ -326,7 +339,7 @@ static bool atomics_compareExchange(JSContext* cx, unsigned argc, Value* vp) {
326339 HandleValue index = args.get (1 );
327340
328341 return AtomicAccess (
329- cx, typedArray, index,
342+ cx, typedArray, index, AccessMode::Write,
330343 [cx, &args](auto ops, Handle<TypedArrayObject*> unwrappedTypedArray,
331344 size_t index) {
332345 using T = typename decltype (ops)::Type;
@@ -363,7 +376,7 @@ static bool atomics_load(JSContext* cx, unsigned argc, Value* vp) {
363376 HandleValue index = args.get (1 );
364377
365378 return AtomicAccess (
366- cx, typedArray, index,
379+ cx, typedArray, index, AccessMode::Read,
367380 [cx, &args](auto ops, Handle<TypedArrayObject*> unwrappedTypedArray,
368381 size_t index) {
369382 using T = typename decltype (ops)::Type;
@@ -388,7 +401,7 @@ static bool atomics_store(JSContext* cx, unsigned argc, Value* vp) {
388401 HandleValue index = args.get (1 );
389402
390403 return AtomicAccess (
391- cx, typedArray, index,
404+ cx, typedArray, index, AccessMode::Write,
392405 [cx, &args](auto ops, Handle<TypedArrayObject*> unwrappedTypedArray,
393406 size_t index) {
394407 using T = typename decltype (ops)::Type;
@@ -418,7 +431,7 @@ static bool AtomicReadModifyWrite(JSContext* cx, const CallArgs& args,
418431 HandleValue index = args.get (1 );
419432
420433 return AtomicAccess (
421- cx, typedArray, index,
434+ cx, typedArray, index, AccessMode::Write,
422435 [cx, &args, op](auto ops, Handle<TypedArrayObject*> unwrappedTypedArray,
423436 size_t index) {
424437 using T = typename decltype (ops)::Type;
@@ -1303,7 +1316,8 @@ static bool DoWait(JSContext* cx, bool isAsync, HandleValue objv,
13031316 MutableHandleValue r) {
13041317
13051318 Rooted<TypedArrayObject*> unwrappedTypedArray (cx);
1306- if (!ValidateIntegerTypedArray (cx, objv, true , &unwrappedTypedArray)) {
1319+ if (!ValidateIntegerTypedArray (cx, objv, true , AccessMode::Read,
1320+ &unwrappedTypedArray)) {
13071321 return false ;
13081322 }
13091323 MOZ_ASSERT (unwrappedTypedArray->type () == Scalar::Int32 ||
@@ -1472,7 +1486,8 @@ static bool atomics_notify(JSContext* cx, unsigned argc, Value* vp) {
14721486
14731487
14741488 Rooted<TypedArrayObject*> unwrappedTypedArray (cx);
1475- if (!ValidateIntegerTypedArray (cx, objv, true , &unwrappedTypedArray)) {
1489+ if (!ValidateIntegerTypedArray (cx, objv, true , AccessMode::Read,
1490+ &unwrappedTypedArray)) {
14761491 return false ;
14771492 }
14781493 MOZ_ASSERT (unwrappedTypedArray->type () == Scalar::Int32 ||
0 commit comments