High severity7.5NVD Advisory· Published May 11, 2016· Updated May 6, 2026
CVE-2016-0193
CVE-2016-0193
Description
The Chakra JavaScript engine in Microsoft Edge allows remote attackers to execute arbitrary code or cause a denial of service (memory corruption) via a crafted web site, aka "Scripting Engine Memory Corruption Vulnerability," a different vulnerability than CVE-2016-0186 and CVE-2016-0191.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
Microsoft.ChakraCoreNuGet | < 1.2.0.0 | 1.2.0.0 |
Affected products
1Patches
1a1fbb4f1da86Add bounds check back to TypedArray DirectSetItem
5 files changed · +225 −72
lib/Runtime/Library/JavascriptArray.cpp+11 −11 modified@@ -5184,8 +5184,8 @@ namespace Js lowerExists = typedArrayBase->HasItem(lower); upperExists = typedArrayBase->HasItem(upper); - h.ThrowTypeErrorOnFailure(typedArrayBase->DirectSetItem(lower, upperValue, false)); - h.ThrowTypeErrorOnFailure(typedArrayBase->DirectSetItem(upper, lowerValue, false)); + h.ThrowTypeErrorOnFailure(typedArrayBase->DirectSetItem(lower, upperValue)); + h.ThrowTypeErrorOnFailure(typedArrayBase->DirectSetItem(upper, lowerValue)); } } else @@ -5204,21 +5204,21 @@ namespace Js { if (upperExists) { - h.ThrowTypeErrorOnFailure(typedArrayBase->DirectSetItem(lower, upperValue, false)); - h.ThrowTypeErrorOnFailure(typedArrayBase->DirectSetItem(upper, lowerValue, false)); + h.ThrowTypeErrorOnFailure(typedArrayBase->DirectSetItem(lower, upperValue)); + h.ThrowTypeErrorOnFailure(typedArrayBase->DirectSetItem(upper, lowerValue)); } else { // This will always fail for a TypedArray if lower < length h.ThrowTypeErrorOnFailure(typedArrayBase->DeleteItem(lower, PropertyOperation_ThrowIfNotExtensible)); - h.ThrowTypeErrorOnFailure(typedArrayBase->DirectSetItem(upper, lowerValue, false)); + h.ThrowTypeErrorOnFailure(typedArrayBase->DirectSetItem(upper, lowerValue)); } } else { if (upperExists) { - h.ThrowTypeErrorOnFailure(typedArrayBase->DirectSetItem(lower, upperValue, false)); + h.ThrowTypeErrorOnFailure(typedArrayBase->DirectSetItem(lower, upperValue)); // This will always fail for a TypedArray if upper < length h.ThrowTypeErrorOnFailure(typedArrayBase->DeleteItem(upper, PropertyOperation_ThrowIfNotExtensible)); } @@ -5930,7 +5930,7 @@ namespace Js // The object we got back from the constructor might not be a TypedArray. In fact, it could be any object. if (newTypedArray) { - newTypedArray->DirectSetItem(i, element, false); + newTypedArray->DirectSetItem(i, element); } else if (newArr) { @@ -8567,7 +8567,7 @@ namespace Js { Var val = typedArrayBase->DirectGetItem(fromIndex); - typedArrayBase->DirectSetItem(toIndex, val, false); + typedArrayBase->DirectSetItem(toIndex, val); } else if (pArr) { @@ -8679,7 +8679,7 @@ namespace Js { if (typedArrayBase) { - typedArrayBase->DirectSetItem(u32k, fillValue, false); + typedArrayBase->DirectSetItem(u32k, fillValue); } else if (pArr) { @@ -8934,7 +8934,7 @@ namespace Js // the normal Set path. if (newTypedArray) { - newTypedArray->DirectSetItem(k, mappedValue, false); + newTypedArray->DirectSetItem(k, mappedValue); } else if (newArr) { @@ -9824,7 +9824,7 @@ namespace Js { Var kValue = args[k + 1]; - newTypedArray->DirectSetItem(k, kValue, false); + newTypedArray->DirectSetItem(k, kValue); } } else
lib/Runtime/Library/TypedArray.cpp+177 −54 modified@@ -524,7 +524,7 @@ namespace Js } else if (GetScriptContext()->IsNumericPropertyId(propertyId, &index)) { - this->DirectSetItem(index, value, index >= GetLength()); + this->DirectSetItem(index, value); return true; } else @@ -557,8 +557,7 @@ namespace Js BOOL TypedArrayBase::SetItem(uint32 index, Var value, PropertyOperationFlags flags) { - // Skip set item if index >= GetLength() - DirectSetItem(index, value, index >= GetLength()); + DirectSetItem(index, value); return true; } @@ -829,7 +828,7 @@ namespace Js { for (uint32 i = 0; i < sourceLength; i++) { - DirectSetItem(offset + i, source->DirectGetItem(i), false); + DirectSetItem(offset + i, source->DirectGetItem(i)); } } else @@ -843,7 +842,7 @@ namespace Js } for (uint32 i = 0; i < sourceLength; i++) { - DirectSetItem(offset + i, tmpArray->DirectGetItem(i), false); + DirectSetItem(offset + i, tmpArray->DirectGetItem(i)); } } } @@ -870,7 +869,7 @@ namespace Js { itemValue = undefinedValue; } - DirectSetItem(offset + i, itemValue, false); + DirectSetItem(offset + i, itemValue); } } @@ -1479,7 +1478,7 @@ namespace Js // We're likely to have constructed a new TypedArray, but the constructor could return any object if (newTypedArrayBase) { - newTypedArrayBase->DirectSetItem(k, kValue, false); + newTypedArrayBase->DirectSetItem(k, kValue); } else if (newArr) { @@ -1557,7 +1556,7 @@ namespace Js // If constructor built a TypedArray (likely) or Array (maybe likely) we can do a more direct set operation if (newTypedArrayBase) { - newTypedArrayBase->DirectSetItem(k, kValue, false); + newTypedArrayBase->DirectSetItem(k, kValue); } else if (newArr) { @@ -1780,7 +1779,7 @@ namespace Js for (uint32 i = 0; i < captured; i++) { - newArr->DirectSetItem(i, tempList->Item(i), false); + newArr->DirectSetItem(i, tempList->Item(i)); } } else @@ -2549,9 +2548,15 @@ namespace Js // If index is not numeric, goto [[Set]] property path if (*isNumericIndex) - return DirectSetItem(indexToSet, value, skipSetItem); + { + return skipSetItem ? + DirectSetItemNoSet(indexToSet, value) : + DirectSetItem(indexToSet, value); + } else + { return TRUE; + } } // Validate the index used for typed arrays with below rules: @@ -3031,14 +3036,24 @@ namespace Js return static_cast<BoolArray*>(RecyclableObject::FromVar(aValue)); } - __inline BOOL Int8Array::DirectSetItem(__in uint32 index, __in Js::Var value, __in bool skipSetElement) + __inline BOOL Int8Array::DirectSetItem(__in uint32 index, __in Js::Var value) + { + return BaseTypedDirectSetItem(index, value, JavascriptConversion::ToInt8); + } + + __inline BOOL Int8VirtualArray::DirectSetItem(__in uint32 index, __in Js::Var value) + { + return BaseTypedDirectSetItem(index, value, JavascriptConversion::ToInt8); + } + + __inline BOOL Int8Array::DirectSetItemNoSet(__in uint32 index, __in Js::Var value) { - return BaseTypedDirectSetItem(index, value, skipSetElement, JavascriptConversion::ToInt8); + return BaseTypedDirectSetItemNoSet(index, value, JavascriptConversion::ToInt8); } - __inline BOOL Int8VirtualArray::DirectSetItem(__in uint32 index, __in Js::Var value, __in bool skipSetElement) + __inline BOOL Int8VirtualArray::DirectSetItemNoSet(__in uint32 index, __in Js::Var value) { - return BaseTypedDirectSetItem(index, value, skipSetElement, JavascriptConversion::ToInt8); + return BaseTypedDirectSetItemNoSet(index, value, JavascriptConversion::ToInt8); } __inline Var Int8Array::DirectGetItem(__in uint32 index) @@ -3051,13 +3066,22 @@ namespace Js return BaseTypedDirectGetItem(index); } - __inline BOOL Uint8Array::DirectSetItem(__in uint32 index, __in Js::Var value, __in bool skipSetElement) + __inline BOOL Uint8Array::DirectSetItem(__in uint32 index, __in Js::Var value) { - return BaseTypedDirectSetItem(index, value, skipSetElement, JavascriptConversion::ToUInt8); + return BaseTypedDirectSetItem(index, value, JavascriptConversion::ToUInt8); } - __inline BOOL Uint8VirtualArray::DirectSetItem(__in uint32 index, __in Js::Var value, __in bool skipSetElement) + __inline BOOL Uint8VirtualArray::DirectSetItem(__in uint32 index, __in Js::Var value) { - return BaseTypedDirectSetItem(index, value, skipSetElement, JavascriptConversion::ToUInt8); + return BaseTypedDirectSetItem(index, value, JavascriptConversion::ToUInt8); + } + + __inline BOOL Uint8Array::DirectSetItemNoSet(__in uint32 index, __in Js::Var value) + { + return BaseTypedDirectSetItemNoSet(index, value, JavascriptConversion::ToUInt8); + } + __inline BOOL Uint8VirtualArray::DirectSetItemNoSet(__in uint32 index, __in Js::Var value) + { + return BaseTypedDirectSetItemNoSet(index, value, JavascriptConversion::ToUInt8); } __inline Var Uint8Array::DirectGetItem(__in uint32 index) @@ -3070,39 +3094,59 @@ namespace Js } - __inline BOOL Uint8ClampedArray::DirectSetItem(__in uint32 index, __in Js::Var value, __in bool skipSetElement) + __inline BOOL Uint8ClampedArray::DirectSetItem(__in uint32 index, __in Js::Var value) { - return BaseTypedDirectSetItem(index, value, skipSetElement, JavascriptConversion::ToUInt8Clamped); + return BaseTypedDirectSetItem(index, value, JavascriptConversion::ToUInt8Clamped); + } + + __inline BOOL Uint8ClampedArray::DirectSetItemNoSet(__in uint32 index, __in Js::Var value) + { + return BaseTypedDirectSetItemNoSet(index, value, JavascriptConversion::ToUInt8Clamped); } __inline Var Uint8ClampedArray::DirectGetItem(__in uint32 index) { return BaseTypedDirectGetItem(index); } - __inline BOOL Uint8ClampedVirtualArray::DirectSetItem(__in uint32 index, __in Js::Var value, __in bool skipSetElement) + __inline BOOL Uint8ClampedVirtualArray::DirectSetItem(__in uint32 index, __in Js::Var value) { - return BaseTypedDirectSetItem(index, value, skipSetElement, JavascriptConversion::ToUInt8Clamped); + return BaseTypedDirectSetItem(index, value, JavascriptConversion::ToUInt8Clamped); + } + + __inline BOOL Uint8ClampedVirtualArray::DirectSetItemNoSet(__in uint32 index, __in Js::Var value) + { + return BaseTypedDirectSetItemNoSet(index, value, JavascriptConversion::ToUInt8Clamped); } __inline Var Uint8ClampedVirtualArray::DirectGetItem(__in uint32 index) { return BaseTypedDirectGetItem(index); } - __inline BOOL Int16Array::DirectSetItem(__in uint32 index, __in Js::Var value, __in bool skipSetElement) + __inline BOOL Int16Array::DirectSetItem(__in uint32 index, __in Js::Var value) { - return BaseTypedDirectSetItem(index, value, skipSetElement, JavascriptConversion::ToInt16); + return BaseTypedDirectSetItem(index, value, JavascriptConversion::ToInt16); + } + + __inline BOOL Int16Array::DirectSetItemNoSet(__in uint32 index, __in Js::Var value) + { + return BaseTypedDirectSetItemNoSet(index, value, JavascriptConversion::ToInt16); } __inline Var Int16Array::DirectGetItem(__in uint32 index) { return BaseTypedDirectGetItem(index); } - __inline BOOL Int16VirtualArray::DirectSetItem(__in uint32 index, __in Js::Var value, __in bool skipSetElement) + __inline BOOL Int16VirtualArray::DirectSetItem(__in uint32 index, __in Js::Var value) + { + return BaseTypedDirectSetItem(index, value, JavascriptConversion::ToInt16); + } + + __inline BOOL Int16VirtualArray::DirectSetItemNoSet(__in uint32 index, __in Js::Var value) { - return BaseTypedDirectSetItem(index, value, skipSetElement, JavascriptConversion::ToInt16); + return BaseTypedDirectSetItemNoSet(index, value, JavascriptConversion::ToInt16); } __inline Var Int16VirtualArray::DirectGetItem(__in uint32 index) @@ -3111,19 +3155,29 @@ namespace Js } - __inline BOOL Uint16Array::DirectSetItem(__in uint32 index, __in Js::Var value, __in bool skipSetElement) + __inline BOOL Uint16Array::DirectSetItem(__in uint32 index, __in Js::Var value) + { + return BaseTypedDirectSetItem(index, value, JavascriptConversion::ToUInt16); + } + + __inline BOOL Uint16Array::DirectSetItemNoSet(__in uint32 index, __in Js::Var value) { - return BaseTypedDirectSetItem(index, value, skipSetElement, JavascriptConversion::ToUInt16); + return BaseTypedDirectSetItemNoSet(index, value, JavascriptConversion::ToUInt16); } __inline Var Uint16Array::DirectGetItem(__in uint32 index) { return BaseTypedDirectGetItem(index); } - __inline BOOL Uint16VirtualArray::DirectSetItem(__in uint32 index, __in Js::Var value, __in bool skipSetElement) + __inline BOOL Uint16VirtualArray::DirectSetItem(__in uint32 index, __in Js::Var value) { - return BaseTypedDirectSetItem(index, value, skipSetElement, JavascriptConversion::ToUInt16); + return BaseTypedDirectSetItem(index, value, JavascriptConversion::ToUInt16); + } + + __inline BOOL Uint16VirtualArray::DirectSetItemNoSet(__in uint32 index, __in Js::Var value) + { + return BaseTypedDirectSetItemNoSet(index, value, JavascriptConversion::ToUInt16); } __inline Var Uint16VirtualArray::DirectGetItem(__in uint32 index) @@ -3133,19 +3187,29 @@ namespace Js - __inline BOOL Int32Array::DirectSetItem(__in uint32 index, __in Js::Var value, __in bool skipSetElement) + __inline BOOL Int32Array::DirectSetItem(__in uint32 index, __in Js::Var value) { - return BaseTypedDirectSetItem(index, value, skipSetElement, JavascriptConversion::ToInt32); + return BaseTypedDirectSetItem(index, value, JavascriptConversion::ToInt32); + } + + __inline BOOL Int32Array::DirectSetItemNoSet(__in uint32 index, __in Js::Var value) + { + return BaseTypedDirectSetItemNoSet(index, value, JavascriptConversion::ToInt32); } __inline Var Int32Array::DirectGetItem(__in uint32 index) { return BaseTypedDirectGetItem(index); } - __inline BOOL Int32VirtualArray::DirectSetItem(__in uint32 index, __in Js::Var value, __in bool skipSetElement) + __inline BOOL Int32VirtualArray::DirectSetItem(__in uint32 index, __in Js::Var value) + { + return BaseTypedDirectSetItem(index, value, JavascriptConversion::ToInt32); + } + + __inline BOOL Int32VirtualArray::DirectSetItemNoSet(__in uint32 index, __in Js::Var value) { - return BaseTypedDirectSetItem(index, value, skipSetElement, JavascriptConversion::ToInt32); + return BaseTypedDirectSetItemNoSet(index, value, JavascriptConversion::ToInt32); } __inline Var Int32VirtualArray::DirectGetItem(__in uint32 index) @@ -3154,19 +3218,29 @@ namespace Js } - __inline BOOL Uint32Array::DirectSetItem(__in uint32 index, __in Js::Var value, __in bool skipSetElement) + __inline BOOL Uint32Array::DirectSetItem(__in uint32 index, __in Js::Var value) { - return BaseTypedDirectSetItem(index, value, skipSetElement, JavascriptConversion::ToUInt32); + return BaseTypedDirectSetItem(index, value, JavascriptConversion::ToUInt32); + } + + __inline BOOL Uint32Array::DirectSetItemNoSet(__in uint32 index, __in Js::Var value) + { + return BaseTypedDirectSetItemNoSet(index, value, JavascriptConversion::ToUInt32); } __inline Var Uint32Array::DirectGetItem(__in uint32 index) { return BaseTypedDirectGetItem(index); } - __inline BOOL Uint32VirtualArray::DirectSetItem(__in uint32 index, __in Js::Var value, __in bool skipSetElement) + __inline BOOL Uint32VirtualArray::DirectSetItem(__in uint32 index, __in Js::Var value) + { + return BaseTypedDirectSetItem(index, value, JavascriptConversion::ToUInt32); + } + + __inline BOOL Uint32VirtualArray::DirectSetItemNoSet(__in uint32 index, __in Js::Var value) { - return BaseTypedDirectSetItem(index, value, skipSetElement, JavascriptConversion::ToUInt32); + return BaseTypedDirectSetItemNoSet(index, value, JavascriptConversion::ToUInt32); } __inline Var Uint32VirtualArray::DirectGetItem(__in uint32 index) @@ -3176,19 +3250,29 @@ namespace Js - __inline BOOL Float32Array::DirectSetItem(__in uint32 index, __in Js::Var value, __in bool skipSetElement) + __inline BOOL Float32Array::DirectSetItem(__in uint32 index, __in Js::Var value) { - return BaseTypedDirectSetItem(index, value, skipSetElement, JavascriptConversion::ToFloat); + return BaseTypedDirectSetItem(index, value, JavascriptConversion::ToFloat); + } + + __inline BOOL Float32Array::DirectSetItemNoSet(__in uint32 index, __in Js::Var value) + { + return BaseTypedDirectSetItemNoSet(index, value, JavascriptConversion::ToFloat); } Var Float32Array::DirectGetItem(__in uint32 index) { return TypedDirectGetItemWithCheck(index); } - __inline BOOL Float32VirtualArray::DirectSetItem(__in uint32 index, __in Js::Var value, __in bool skipSetElement) + __inline BOOL Float32VirtualArray::DirectSetItem(__in uint32 index, __in Js::Var value) + { + return BaseTypedDirectSetItem(index, value, JavascriptConversion::ToFloat); + } + + __inline BOOL Float32VirtualArray::DirectSetItemNoSet(__in uint32 index, __in Js::Var value) { - return BaseTypedDirectSetItem(index, value, skipSetElement, JavascriptConversion::ToFloat); + return BaseTypedDirectSetItemNoSet(index, value, JavascriptConversion::ToFloat); } Var Float32VirtualArray::DirectGetItem(__in uint32 index) @@ -3197,19 +3281,29 @@ namespace Js } - __inline BOOL Float64Array::DirectSetItem(__in uint32 index, __in Js::Var value, __in bool skipSetElement) + __inline BOOL Float64Array::DirectSetItem(__in uint32 index, __in Js::Var value) + { + return BaseTypedDirectSetItem(index, value, JavascriptConversion::ToNumber); + } + + __inline BOOL Float64Array::DirectSetItemNoSet(__in uint32 index, __in Js::Var value) { - return BaseTypedDirectSetItem(index, value, skipSetElement, JavascriptConversion::ToNumber); + return BaseTypedDirectSetItemNoSet(index, value, JavascriptConversion::ToNumber); } __inline Var Float64Array::DirectGetItem(__in uint32 index) { return TypedDirectGetItemWithCheck(index); } - __inline BOOL Float64VirtualArray::DirectSetItem(__in uint32 index, __in Js::Var value, __in bool skipSetElement) + __inline BOOL Float64VirtualArray::DirectSetItem(__in uint32 index, __in Js::Var value) { - return BaseTypedDirectSetItem(index, value, skipSetElement, JavascriptConversion::ToNumber); + return BaseTypedDirectSetItem(index, value, JavascriptConversion::ToNumber); + } + + __inline BOOL Float64VirtualArray::DirectSetItemNoSet(__in uint32 index, __in Js::Var value) + { + return BaseTypedDirectSetItemNoSet(index, value, JavascriptConversion::ToNumber); } __inline Var Float64VirtualArray::DirectGetItem(__in uint32 index) @@ -3218,29 +3312,44 @@ namespace Js } - __inline BOOL Int64Array::DirectSetItem(__in uint32 index, __in Js::Var value, __in bool skipSetElement) + __inline BOOL Int64Array::DirectSetItem(__in uint32 index, __in Js::Var value) { - return BaseTypedDirectSetItem(index, value, skipSetElement, JavascriptConversion::ToInt64); + return BaseTypedDirectSetItem(index, value, JavascriptConversion::ToInt64); + } + + __inline BOOL Int64Array::DirectSetItemNoSet(__in uint32 index, __in Js::Var value) + { + return BaseTypedDirectSetItemNoSet(index, value, JavascriptConversion::ToInt64); } __inline Var Int64Array::DirectGetItem(__in uint32 index) { return BaseTypedDirectGetItem(index); } - __inline BOOL Uint64Array::DirectSetItem(__in uint32 index, __in Js::Var value, __in bool skipSetElement) + __inline BOOL Uint64Array::DirectSetItem(__in uint32 index, __in Js::Var value) { - return BaseTypedDirectSetItem(index, value, skipSetElement, JavascriptConversion::ToUInt64); + return BaseTypedDirectSetItem(index, value, JavascriptConversion::ToUInt64); + } + + __inline BOOL Uint64Array::DirectSetItemNoSet(__in uint32 index, __in Js::Var value) + { + return BaseTypedDirectSetItemNoSet(index, value, JavascriptConversion::ToUInt64); } __inline Var Uint64Array::DirectGetItem(__in uint32 index) { return BaseTypedDirectGetItem(index); } - __inline BOOL BoolArray::DirectSetItem(__in uint32 index, __in Js::Var value, __in bool skipSetElement) + __inline BOOL BoolArray::DirectSetItem(__in uint32 index, __in Js::Var value) + { + return BaseTypedDirectSetItem(index, value, JavascriptConversion::ToBool); + } + + __inline BOOL BoolArray::DirectSetItemNoSet(__in uint32 index, __in Js::Var value) { - return BaseTypedDirectSetItem(index, value, skipSetElement, JavascriptConversion::ToBool); + return BaseTypedDirectSetItemNoSet(index, value, JavascriptConversion::ToBool); } __inline Var BoolArray::DirectGetItem(__in uint32 index) @@ -3297,7 +3406,7 @@ namespace Js return static_cast<CharArray*>(RecyclableObject::FromVar(aValue)); } - __inline BOOL CharArray::DirectSetItem(__in uint32 index, __in Js::Var value, __in bool skipSetElement) + __inline BOOL CharArray::DirectSetItem(__in uint32 index, __in Js::Var value) { ScriptContext* scriptContext = GetScriptContext(); // A typed array is Integer Indexed Exotic object, so doing a get translates to 9.4.5.9 IntegerIndexedElementSet @@ -3308,7 +3417,7 @@ namespace Js JavascriptError::ThrowTypeError(scriptContext, JSERR_DetachedTypedArray); } - if (skipSetElement) + if (index >= GetLength()) { return FALSE; } @@ -3329,6 +3438,20 @@ namespace Js return TRUE; } + __inline BOOL CharArray::DirectSetItemNoSet(__in uint32 index, __in Js::Var value) + { + ScriptContext* scriptContext = GetScriptContext(); + // A typed array is Integer Indexed Exotic object, so doing a get translates to 9.4.5.9 IntegerIndexedElementSet + Js::JavascriptConversion::ToString(value, scriptContext); + + if (this->IsDetachedBuffer()) + { + JavascriptError::ThrowTypeError(scriptContext, JSERR_DetachedTypedArray); + } + + return FALSE; + } + __inline Var CharArray::DirectGetItem(__in uint32 index) { // A typed array is Integer Indexed Exotic object, so doing a get translates to 9.4.5.8 IntegerIndexedElementGet
lib/Runtime/Library/TypedArray.h+23 −7 modified@@ -138,7 +138,8 @@ namespace Js static BOOL IsDetachedTypedArray(Var aValue); static HRESULT GetBuffer(Var aValue, ArrayBuffer** outBuffer, uint32* outOffset, uint32* outLength); - virtual BOOL DirectSetItem(__in uint32 index, __in Js::Var value, __in bool skipSetItem) = 0; + virtual BOOL DirectSetItem(__in uint32 index, __in Js::Var value) = 0; + virtual BOOL DirectSetItemNoSet(__in uint32 index, __in Js::Var value) = 0; virtual Var DirectGetItem(__in uint32 index) = 0; uint32 GetByteLength() const { return length * BYTES_PER_ELEMENT; } @@ -337,7 +338,6 @@ namespace Js // If we want to start copying past the length of the array, all index are no-op return true; } - if (UInt32Math::Add(newStart, newLength) > GetLength()) { newLength = GetLength() - newStart; @@ -362,7 +362,7 @@ namespace Js return TRUE; } - __inline BOOL BaseTypedDirectSetItem(__in uint32 index, __in Js::Var value, __in bool skipSetElement, TypeName (*convFunc)(Var value, ScriptContext* scriptContext)) + __inline BOOL BaseTypedDirectSetItem(__in uint32 index, __in Js::Var value, TypeName (*convFunc)(Var value, ScriptContext* scriptContext)) { // This call can potentially invoke user code, and may end up detaching the underlying array (this). // Therefore it was brought out and above the IsDetached check @@ -373,7 +373,7 @@ namespace Js JavascriptError::ThrowTypeError(GetScriptContext(), JSERR_DetachedTypedArray); } - if (skipSetElement) + if (index >= GetLength()) { return FALSE; } @@ -385,17 +385,32 @@ namespace Js typedBuffer[index] = typedValue; return TRUE; + } + + __inline BOOL BaseTypedDirectSetItemNoSet(__in uint32 index, __in Js::Var value, TypeName (*convFunc)(Var value, ScriptContext* scriptContext)) + { + // This call can potentially invoke user code, and may end up detaching the underlying array (this). + // Therefore it was brought out and above the IsDetached check + convFunc(value, GetScriptContext()); + + if (this->IsDetachedBuffer()) // 9.4.5.9 IntegerIndexedElementSet + { + JavascriptError::ThrowTypeError(GetScriptContext(), JSERR_DetachedTypedArray); } - virtual BOOL DirectSetItem(__in uint32 index, __in Js::Var value, __in bool skipSetItem) override sealed; + return FALSE; + } + + virtual BOOL DirectSetItem(__in uint32 index, __in Js::Var value) override sealed; + virtual BOOL DirectSetItemNoSet(__in uint32 index, __in Js::Var value) override sealed; virtual Var DirectGetItem(__in uint32 index) override sealed; static BOOL DirectSetItem(__in TypedArray* arr, __in uint32 index, __in Js::Var value) { AssertMsg(arr != nullptr, "Array shouldn't be nullptr."); - return arr->DirectSetItem(index, value, index >= arr->GetLength()); + return arr->DirectSetItem(index, value); } protected: @@ -440,7 +455,8 @@ namespace Js Var Subarray(uint32 begin, uint32 end); static CharArray* FromVar(Var aValue); - virtual BOOL DirectSetItem(__in uint32 index, __in Js::Var value, __in bool skipSetItem) override; + virtual BOOL DirectSetItem(__in uint32 index, __in Js::Var value) override; + virtual BOOL DirectSetItemNoSet(__in uint32 index, __in Js::Var value) override; virtual Var DirectGetItem(__in uint32 index) override; protected:
test/typedarray/bug_OS_6911900.js+9 −0 added@@ -0,0 +1,9 @@ +//------------------------------------------------------------------------------------------------------- +// Copyright (C) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. +//------------------------------------------------------------------------------------------------------- + +var ua = new Uint32Array(0x10); +ua.__proto__ = new Array(0xffffffff); +ua.fill(0x41, 0x41414141, 0x41414141 + 1); // shouldn't assert or crash +print("passed");
test/typedarray/rlexe.xml+5 −0 modified@@ -328,4 +328,9 @@ Below test fails with difference in space. Investigate the cause and re-enable t <tags>BugFix</tags> </default> </test> + <test> + <default> + <files>bug_OS_6911900.js</files> + </default> + </test> </regress-exe>
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
9- github.com/advisories/GHSA-985m-xqv8-rh79ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2016-0193ghsaADVISORY
- www.zerodayinitiative.com/advisories/ZDI-16-283nvdWEB
- docs.microsoft.com/en-us/security-updates/securitybulletins/2016/ms16-052nvdWEB
- github.com/chakra-core/ChakraCore/commit/a1fbb4f1da86a9429c7c22aa11888f7b67a232e3ghsaWEB
- web.archive.org/web/20200228012149/http://www.securityfocus.com/bid/90009ghsaWEB
- web.archive.org/web/20201024061334/http://www.securitytracker.com/id/1035821ghsaWEB
- www.securityfocus.com/bid/90009nvd
- www.securitytracker.com/id/1035821nvd
News mentions
0No linked articles in our index yet.