VYPR
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.

PackageAffected versionsPatched versions
Microsoft.ChakraCoreNuGet
< 1.2.0.01.2.0.0

Affected products

1

Patches

1
a1fbb4f1da86

Add bounds check back to TypedArray DirectSetItem

https://github.com/chakra-core/ChakraCoreIan HallidayMay 12, 2016via ghsa
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

News mentions

0

No linked articles in our index yet.