CVE-2018-0836
Description
A memory corruption vulnerability in the scripting engine of Microsoft Edge and ChakraCore allows remote code execution via crafted content.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A memory corruption vulnerability in the scripting engine of Microsoft Edge and ChakraCore allows remote code execution via crafted content.
Vulnerability
The vulnerability is a memory corruption in the scripting engine (Chakra) of Microsoft Edge and ChakraCore on Windows 10 version 1703 and 1709 [1]. The issue occurs due to improper handling of objects in memory, specifically in the IRBuilder component where assertions were replaced with fail-fast checks to prevent out-of-bounds access [2]. Affected versions: Microsoft Edge on Windows 10 1703 and 1709, and ChakraCore prior to the fix commit b99d0dc [2].
Exploitation
An attacker can host a specially crafted website that, when visited by a victim using Microsoft Edge, triggers the memory corruption [3]. No authentication is required; the attacker only needs to convince the user to load the malicious content (e.g., via a link or embedded content). The vulnerability is remotely exploitable over the network [4].
Impact
Successful exploitation allows remote code execution in the context of the current user [1]. The attacker gains the ability to execute arbitrary code, potentially leading to full compromise of the affected system, including data theft, installation of malware, or further lateral movement.
Mitigation
Microsoft released a security update on February 13, 2018, as part of the February 2018 Patch Tuesday [3]. Users should apply the update via Windows Update. For ChakraCore, the fix is available in commit b99d0dc [2]. No workarounds are documented; the only mitigation is to install the update.
- NVD - CVE-2018-0836
- ChakraCore fix for servicing release 18-02B: CVE-2018-0836 · chakra-core/ChakraCore@b99d0dc
- Microsoft Edge Multiple Bugs Let Remote Users Execute Arbitrary Code, Obtain Potentially Sensitive Information, and Bypass Security Restrictions on the Target System
- Microsoft Edge Scripting Engine CVE-2018-0836 Remote Memory Corruption Vulnerability
AI Insight generated on May 22, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
Microsoft.ChakraCoreNuGet | < 1.8.1 | 1.8.1 |
Affected products
2- Microsoft Corporation/Microsoft Edge, ChakraCorev5Range: Microsoft Windows 10 1703 and 1709.
Patches
1b99d0dcbf5a8ChakraCore fix for servicing release 18-02B: CVE-2018-0836
9 files changed · +73 −63
lib/Backend/FlowGraph.cpp+3 −0 modified@@ -293,13 +293,15 @@ FlowGraph::Build(void) case Js::OpCode::TryCatch: if (this->catchLabelStack) { + AssertOrFailFast(!this->catchLabelStack->Empty()); this->catchLabelStack->Pop(); } break; case Js::OpCode::TryFinally: if (this->finallyLabelStack) { + AssertOrFailFast(!this->finallyLabelStack->Empty()); this->finallyLabelStack->Pop(); } break; @@ -497,6 +499,7 @@ FlowGraph::Build(void) } else if (instr->m_opcode == Js::OpCode::Finally) { + AssertOrFailFast(!this->finallyLabelStack->Empty()); this->finallyLabelStack->Pop(); } }
lib/Backend/FunctionJITTimeInfo.cpp+4 −5 modified@@ -259,7 +259,7 @@ FunctionJITTimeInfo::GetRuntimeInfo() const ObjTypeSpecFldInfo * FunctionJITTimeInfo::GetObjTypeSpecFldInfo(uint index) const { - Assert(index < GetBody()->GetInlineCacheCount()); + AssertOrFailFast(index < GetBody()->GetInlineCacheCount()); if (m_data.objTypeSpecFldInfoArray == nullptr) { return nullptr; @@ -271,7 +271,7 @@ FunctionJITTimeInfo::GetObjTypeSpecFldInfo(uint index) const ObjTypeSpecFldInfo * FunctionJITTimeInfo::GetGlobalObjTypeSpecFldInfo(uint index) const { - Assert(index < m_data.globalObjTypeSpecFldInfoCount); + AssertOrFailFast(index < m_data.globalObjTypeSpecFldInfoCount); return reinterpret_cast<ObjTypeSpecFldInfo *>(m_data.globalObjTypeSpecFldInfoArray[index]); } @@ -298,8 +298,7 @@ FunctionJITTimeInfo::GetLdFldInlinee(Js::InlineCacheIndex inlineCacheIndex) cons { return nullptr; } - Assert(inlineCacheIndex < m_data.ldFldInlineeCount); - + AssertOrFailFast(inlineCacheIndex < m_data.ldFldInlineeCount); return reinterpret_cast<const FunctionJITTimeInfo*>(m_data.ldFldInlinees[inlineCacheIndex]); } @@ -312,7 +311,7 @@ FunctionJITTimeInfo::GetInlinee(Js::ProfileId profileId) const { return nullptr; } - Assert(profileId < m_data.inlineeCount); + AssertOrFailFast(profileId < m_data.inlineeCount); auto inlinee = reinterpret_cast<const FunctionJITTimeInfo *>(m_data.inlinees[profileId]); if (inlinee == nullptr && m_data.inlineesRecursionFlags[profileId])
lib/Backend/IRBuilderAsmJs.cpp+8 −8 modified@@ -111,9 +111,7 @@ IRBuilderAsmJs::Build() offsetToInstructionCount = lastOffset + 2; } -#if DBG m_offsetToInstructionCount = offsetToInstructionCount; -#endif m_offsetToInstruction = JitAnewArrayZ(m_tempAlloc, IR::Instr *, offsetToInstructionCount); LoadNativeCodeData(); @@ -219,7 +217,7 @@ IRBuilderAsmJs::AddInstr(IR::Instr * instr, uint32 offset) m_lastInstr->InsertAfter(instr); if (offset != Js::Constants::NoByteCodeOffset) { - Assert(offset < m_offsetToInstructionCount); + AssertOrFailFast(offset < m_offsetToInstructionCount); if (m_offsetToInstruction[offset] == nullptr) { m_offsetToInstruction[offset] = instr; @@ -669,6 +667,7 @@ IRBuilderAsmJs::RegIsConstant(Js::RegSlot reg) BranchReloc * IRBuilderAsmJs::AddBranchInstr(IR::BranchInstr * branchInstr, uint32 offset, uint32 targetOffset) { + AssertOrFailFast(targetOffset <= m_func->GetJITFunctionBody()->GetByteCodeLength()); // // Loop jitting would be done only till the LoopEnd // Any branches beyond that offset are for the return statement @@ -1041,8 +1040,8 @@ IRBuilderAsmJs::CreateLabel(IR::BranchInstr * branchInstr, uint & offset) IR::Instr * targetInstr = nullptr; while (targetInstr == nullptr) { + AssertOrFailFast(offset < m_offsetToInstructionCount); targetInstr = m_offsetToInstruction[offset]; - Assert(offset < m_offsetToInstructionCount); ++offset; } @@ -1788,7 +1787,7 @@ IRBuilderAsmJs::BuildAsmCall(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::ArgSl instr->AsProfiledInstr()->u.profileId = profileId; } } - + AssertOrFailFast(!this->m_argOffsetStack->Empty()); argOffset = m_argOffsetStack->Pop(); argOffset -= MachPtr; break; @@ -1810,7 +1809,8 @@ IRBuilderAsmJs::BuildAsmCall(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::ArgSl IR::Instr * argInstr = nullptr; IR::Instr * prevInstr = instr; - for (argInstr = m_argStack->Pop(); argInstr->m_opcode != Js::OpCode::StartCall; argInstr = m_argStack->Pop()) + AssertOrFailFast(!this->m_argStack->Empty()); + for (argInstr = m_argStack->Pop(); !m_argStack->Empty() && argInstr->m_opcode != Js::OpCode::StartCall; argInstr = m_argStack->Pop()) { if (newOpcode == Js::OpCodeAsmJs::I_Call || newOpcode == Js::OpCodeAsmJs::ProfiledI_Call) { @@ -1840,10 +1840,10 @@ IRBuilderAsmJs::BuildAsmCall(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::ArgSl count++; } - Assert(argInstr->m_opcode == Js::OpCode::StartCall); + AssertOrFailFast(argInstr->m_opcode == Js::OpCode::StartCall); argInstr->SetSrc1(IR::IntConstOpnd::New(count, TyUint16, m_func)); - Assert(argOffset == 0); + AssertOrFailFast(argOffset == 0); prevInstr->SetSrc2(argInstr->GetDst()); #ifdef ENABLE_SIMDJS
lib/Backend/IRBuilderAsmJs.h+0 −2 modified@@ -252,9 +252,7 @@ class IRBuilderAsmJs JitLoopBodyData* m_jitLoopBodyData = nullptr; IRBuilderAsmJsSwitchAdapter m_switchAdapter; SwitchIRBuilder m_switchBuilder; -#if DBG uint32 m_offsetToInstructionCount; -#endif #define BUILD_LAYOUT_DEF(layout, ...) void Build##layout (Js::OpCodeAsmJs, uint32, __VA_ARGS__); #define Reg_Type Js::RegSlot
lib/Backend/IRBuilder.cpp+32 −24 modified@@ -460,9 +460,7 @@ IRBuilder::Build() this->m_loopBodyLocalsStartSlot = (Js::PropertyId)(localsOffset / sizeof(Js::Var)); } -#if DBG m_offsetToInstructionCount = offsetToInstructionCount; -#endif m_offsetToInstruction = JitAnewArrayZ(m_tempAlloc, IR::Instr *, offsetToInstructionCount); #ifdef BYTECODE_BRANCH_ISLAND @@ -820,7 +818,8 @@ IRBuilder::Build() m_lastInstr->m_opcode == Js::OpCode::RuntimeTypeError) { uint32 lastInstrOffset = m_lastInstr->GetByteCodeOffset(); - Assert(lastInstrOffset < m_offsetToInstructionCount); + + AssertOrFailFast(lastInstrOffset < m_offsetToInstructionCount); #if DBG __analysis_assume(lastInstrOffset < this->m_offsetToInstructionCount); #endif @@ -1069,7 +1068,7 @@ IRBuilder::CreateLabel(IR::BranchInstr * branchInstr, uint& offset) for (;;) { - Assert(offset < m_offsetToInstructionCount); + AssertOrFailFast(offset < m_offsetToInstructionCount); targetInstr = this->m_offsetToInstruction[offset]; if (targetInstr != nullptr) { @@ -1118,7 +1117,7 @@ IRBuilder::CreateLabel(IR::BranchInstr * branchInstr, uint& offset) void IRBuilder::InsertInstr(IR::Instr *instr, IR::Instr* insertBeforeInstr) { - Assert(insertBeforeInstr->GetByteCodeOffset() < m_offsetToInstructionCount); + AssertOrFailFast(insertBeforeInstr->GetByteCodeOffset() < m_offsetToInstructionCount); instr->SetByteCodeOffset(insertBeforeInstr); uint32 offset = insertBeforeInstr->GetByteCodeOffset(); if (m_offsetToInstruction[offset] == insertBeforeInstr) @@ -1150,7 +1149,7 @@ IRBuilder::AddInstr(IR::Instr *instr, uint32 offset) m_lastInstr->InsertAfter(instr); if (offset != Js::Constants::NoByteCodeOffset) { - Assert(offset < m_offsetToInstructionCount); + AssertOrFailFast(offset < m_offsetToInstructionCount); if (m_offsetToInstruction[offset] == nullptr) { m_offsetToInstruction[offset] = instr; @@ -1213,6 +1212,7 @@ IRBuilder::BuildIndirOpnd(IR::RegOpnd *baseReg, uint32 offset, const char16 *des IR::SymOpnd * IRBuilder::BuildFieldOpnd(Js::OpCode newOpcode, Js::RegSlot reg, Js::PropertyId propertyId, Js::PropertyIdIndexType propertyIdIndex, PropertyKind propertyKind, uint inlineCacheIndex) { + AssertOrFailFast(inlineCacheIndex < m_func->GetJITFunctionBody()->GetInlineCacheCount() || inlineCacheIndex == Js::Constants::NoInlineCacheIndex); PropertySym * propertySym = BuildFieldSym(reg, propertyId, propertyIdIndex, inlineCacheIndex, propertyKind); IR::SymOpnd * symOpnd; @@ -1798,7 +1798,8 @@ IRBuilder::BuildReg1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot R0) case Js::OpCode::Catch: if (this->handlerOffsetStack) { - Assert(this->handlerOffsetStack->Top().Second() == true); + AssertOrFailFast(!this->handlerOffsetStack->Empty()); + AssertOrFailFast(this->handlerOffsetStack->Top().Second() == true); this->handlerOffsetStack->Pop(); } dstIsCatchObject = true; @@ -6125,19 +6126,24 @@ IRBuilder::BuildProfiledCallI(Js::OpCode opcode, uint32 offset, Js::RegSlot retu if(this->m_func->GetWorkItem()->GetJITTimeInfo()) { const FunctionJITTimeInfo *inlinerData = this->m_func->GetWorkItem()->GetJITTimeInfo(); - if(!(this->IsLoopBody() && PHASE_OFF(Js::InlineInJitLoopBodyPhase, this->m_func)) && - inlinerData && inlinerData->GetInlineesBV() && (!inlinerData->GetInlineesBV()->Test(profileId) + if (!(this->IsLoopBody() && PHASE_OFF(Js::InlineInJitLoopBodyPhase, this->m_func)) + && inlinerData && inlinerData->GetInlineesBV()) + { + AssertOrFailFast(profileId < inlinerData->GetInlineesBV()->Length()); + if (!inlinerData->GetInlineesBV()->Test(profileId) #if DBG - || (PHASE_STRESS(Js::BailOnNoProfilePhase, this->m_func->GetTopFunc()) && - (CONFIG_FLAG(SkipFuncCountForBailOnNoProfile) < 0 || - this->m_func->m_callSiteCount >= (uint)CONFIG_FLAG(SkipFuncCountForBailOnNoProfile))) + || (PHASE_STRESS(Js::BailOnNoProfilePhase, this->m_func->GetTopFunc()) + && (CONFIG_FLAG(SkipFuncCountForBailOnNoProfile) < 0 + || this->m_func->m_callSiteCount >= (uint)CONFIG_FLAG(SkipFuncCountForBailOnNoProfile))) #endif - )) - { - this->InsertBailOnNoProfile(offset); - isProtectedByNoProfileBailout = true; + ) + { + this->InsertBailOnNoProfile(offset); + isProtectedByNoProfileBailout = true; + } } - else + + if (!isProtectedByNoProfileBailout) { this->callTreeHasSomeProfileInfo = true; } @@ -6398,19 +6404,20 @@ IRBuilder::BuildCallCommon(IR::Instr * instr, StackSym * symDst, Js::ArgSlot arg #endif // Link all the args of this call by creating a def/use chain through the src2. - - for (argInstr = this->m_argStack->Pop(); - argInstr && argInstr->m_opcode != Js::OpCode::StartCall; - argInstr = this->m_argStack->Pop()) + AssertOrFailFast(!m_argStack->Empty()); + for (argInstr = m_argStack->Pop(); + argInstr && !m_argStack->Empty() && argInstr->m_opcode != Js::OpCode::StartCall; + argInstr = m_argStack->Pop()) { prevInstr->SetSrc2(argInstr->GetDst()); prevInstr = argInstr; #if DBG count++; #endif } + AssertOrFailFast(argInstr->m_opcode == Js::OpCode::StartCall); - if (this->m_argStack->Empty()) + if (m_argStack->Empty()) { this->callTreeHasSomeProfileInfo = false; } @@ -6736,7 +6743,8 @@ IRBuilder::BuildEmpty(Js::OpCode newOpcode, uint32 offset) case Js::OpCode::Finally: if (this->handlerOffsetStack) { - Assert(this->handlerOffsetStack->Top().Second() == false); + AssertOrFailFast(!this->handlerOffsetStack->Empty()); + AssertOrFailFast(this->handlerOffsetStack->Top().Second() == false); this->handlerOffsetStack->Pop(); } finallyBlockLevel++; @@ -6971,7 +6979,6 @@ IRBuilder::BuildBr(Js::OpCode newOpcode, uint32 offset) IR::BranchInstr * branchInstr; const unaligned Js::OpLayoutBr *branchInsn = m_jnReader.Br(); unsigned int targetOffset = m_jnReader.GetCurrentOffset() + branchInsn->RelativeJumpOffset; - #ifdef BYTECODE_BRANCH_ISLAND bool isLongBranchIsland = (m_jnReader.PeekOp() == Js::OpCode::BrLong); if (isLongBranchIsland) @@ -7154,6 +7161,7 @@ IRBuilder::BuildBrEnvProperty(Js::OpCode newOpcode, uint32 offset) BranchReloc * IRBuilder::AddBranchInstr(IR::BranchInstr * branchInstr, uint32 offset, uint32 targetOffset) { + AssertOrFailFast(targetOffset <= m_func->GetJITFunctionBody()->GetByteCodeLength()); // // Loop jitting would be done only till the LoopEnd // Any branches beyond that offset are for the return stmt
lib/Backend/IRBuilder.h+1 −1 modified@@ -333,6 +333,7 @@ class IRBuilder Func * m_func; IR::Instr * m_lastInstr; IR::Instr ** m_offsetToInstruction; + uint32 m_offsetToInstructionCount; uint32 m_functionStartOffset; Js::ByteCodeReader m_jnReader; Js::StatementReader<Js::FunctionBody::ArenaStatementMapList> m_statementReader; @@ -363,7 +364,6 @@ class IRBuilder // used to estimate how much stack we should probe for at the // beginning of a JITted function. #if DBG - uint32 m_offsetToInstructionCount; uint32 m_callsOnStack; #endif uint32 m_argsOnStack;
lib/Backend/JITTimeFunctionBody.cpp+12 −12 modified@@ -490,7 +490,7 @@ Js::PropertyId JITTimeFunctionBody::GetPropertyIdFromCacheId(uint cacheId) const { Assert(m_bodyData.cacheIdToPropertyIdMap); - Assert(cacheId < GetInlineCacheCount()); + AssertOrFailFast(cacheId < GetInlineCacheCount()); return static_cast<Js::PropertyId>(m_bodyData.cacheIdToPropertyIdMap[cacheId]); } @@ -504,7 +504,7 @@ JITTimeFunctionBody::GetReferencedPropertyId(uint index) const uint mapIndex = index - TotalNumberOfBuiltInProperties; Assert(m_bodyData.referencedPropertyIdMap != nullptr); - Assert(mapIndex < m_bodyData.referencedPropertyIdCount); + AssertOrFailFast(mapIndex < m_bodyData.referencedPropertyIdCount); return m_bodyData.referencedPropertyIdMap[mapIndex]; } @@ -852,7 +852,7 @@ intptr_t JITTimeFunctionBody::GetConstantVar(Js::RegSlot location) const { Assert(m_bodyData.constTable != nullptr); - Assert(location < GetConstCount()); + AssertOrFailFast(location < GetConstCount()); Assert(location != 0); return static_cast<intptr_t>(m_bodyData.constTable[location - Js::FunctionBody::FirstRegSlot]); @@ -863,7 +863,7 @@ JITTimeFunctionBody::GetConstantContent(Js::RegSlot location) const { Assert(m_bodyData.constTableContent != nullptr); Assert(m_bodyData.constTableContent->content != nullptr); - Assert(location < GetConstCount()); + AssertOrFailFast(location < GetConstCount()); Assert(location != 0); JITRecyclableObject * obj = (JITRecyclableObject *)m_bodyData.constTableContent->content[location - Js::FunctionBody::FirstRegSlot]; @@ -888,7 +888,7 @@ intptr_t JITTimeFunctionBody::GetInlineCache(uint index) const { Assert(m_bodyData.inlineCaches != nullptr); - Assert(index < GetInlineCacheCount()); + AssertOrFailFast(index < GetInlineCacheCount()); #if 0 // TODO: michhol OOP JIT, add these asserts Assert(this->m_inlineCacheTypes[index] == InlineCacheTypeNone || this->m_inlineCacheTypes[index] == InlineCacheTypeInlineCache); @@ -901,7 +901,7 @@ intptr_t JITTimeFunctionBody::GetIsInstInlineCache(uint index) const { Assert(m_bodyData.inlineCaches != nullptr); - Assert(index < m_bodyData.isInstInlineCacheCount); + AssertOrFailFast(index < m_bodyData.isInstInlineCacheCount); index += GetInlineCacheCount(); #if 0 // TODO: michhol OOP JIT, add these asserts Assert(this->m_inlineCacheTypes[index] == InlineCacheTypeNone || @@ -916,7 +916,7 @@ JITTimeFunctionBody::GetConstantType(Js::RegSlot location) const { Assert(m_bodyData.constTable != nullptr); Assert(m_bodyData.constTableContent != nullptr); - Assert(location < GetConstCount()); + AssertOrFailFast(location < GetConstCount()); Assert(location != 0); auto obj = m_bodyData.constTableContent->content[location - Js::FunctionBody::FirstRegSlot]; @@ -939,7 +939,7 @@ JITTimeFunctionBody::GetConstantType(Js::RegSlot location) const intptr_t JITTimeFunctionBody::GetLiteralRegexAddr(uint index) const { - Assert(index < m_bodyData.literalRegexCount); + AssertOrFailFast(index < m_bodyData.literalRegexCount); return m_bodyData.literalRegexes[index]; } @@ -968,23 +968,23 @@ JITTimeFunctionBody::GetRootObject() const Js::FunctionInfoPtrPtr JITTimeFunctionBody::GetNestedFuncRef(uint index) const { - Assert(index < GetNestedCount()); + AssertOrFailFast(index < GetNestedCount()); Js::FunctionInfoPtrPtr baseAddr = (Js::FunctionInfoPtrPtr)m_bodyData.nestedFuncArrayAddr; return baseAddr + index; } intptr_t JITTimeFunctionBody::GetLoopHeaderAddr(uint loopNum) const { - Assert(loopNum < GetLoopCount()); + AssertOrFailFast(loopNum < GetLoopCount()); intptr_t baseAddr = m_bodyData.loopHeaderArrayAddr; return baseAddr + (loopNum * sizeof(Js::LoopHeader)); } const JITLoopHeaderIDL * JITTimeFunctionBody::GetLoopHeaderData(uint loopNum) const { - Assert(loopNum < GetLoopCount()); + AssertOrFailFast(loopNum < GetLoopCount()); return &m_bodyData.loopHeaders[loopNum]; } @@ -1021,7 +1021,7 @@ JITTimeFunctionBody::HasPropIdToFormalsMap() const bool JITTimeFunctionBody::IsRegSlotFormal(Js::RegSlot reg) const { - Assert(reg < m_bodyData.propertyIdsForRegSlotsCount); + AssertOrFailFast(reg < m_bodyData.propertyIdsForRegSlotsCount); Js::PropertyId propId = (Js::PropertyId)m_bodyData.propertyIdsForRegSlots[reg]; Js::PropertyIdArray * formalProps = GetFormalsPropIdArray(); for (uint32 i = 0; i < formalProps->count; i++)
lib/Backend/JITTimeProfileInfo.cpp+12 −10 modified@@ -141,33 +141,35 @@ JITTimeProfileInfo::InitializeJITProfileData( const Js::LdElemInfo * JITTimeProfileInfo::GetLdElemInfo(Js::ProfileId ldElemId) const { + AssertOrFailFast(ldElemId < m_profileData.profiledLdElemCount); return &(reinterpret_cast<Js::LdElemInfo*>(m_profileData.ldElemData)[ldElemId]); } const Js::StElemInfo * JITTimeProfileInfo::GetStElemInfo(Js::ProfileId stElemId) const { + AssertOrFailFast(stElemId < m_profileData.profiledStElemCount); return &(reinterpret_cast<Js::StElemInfo*>(m_profileData.stElemData)[stElemId]); } Js::ArrayCallSiteInfo * JITTimeProfileInfo::GetArrayCallSiteInfo(Js::ProfileId index) const { - Assert(index < GetProfiledArrayCallSiteCount()); + AssertOrFailFast(index < GetProfiledArrayCallSiteCount()); return &(reinterpret_cast<Js::ArrayCallSiteInfo*>(m_profileData.arrayCallSiteData)[index]); } intptr_t JITTimeProfileInfo::GetArrayCallSiteInfoAddr(Js::ProfileId index) const { - Assert(index < GetProfiledArrayCallSiteCount()); + AssertOrFailFast(index < GetProfiledArrayCallSiteCount()); return m_profileData.arrayCallSiteDataAddr + index * sizeof(ArrayCallSiteIDL); } Js::FldInfo * JITTimeProfileInfo::GetFldInfo(uint fieldAccessId) const { - Assert(fieldAccessId < GetProfiledFldCount()); + AssertOrFailFast(fieldAccessId < GetProfiledFldCount()); return &(reinterpret_cast<Js::FldInfo*>(m_profileData.fldData)[fieldAccessId]); } @@ -181,7 +183,7 @@ JITTimeProfileInfo::GetFldInfoAddr(uint fieldAccessId) const ValueType JITTimeProfileInfo::GetSlotLoad(Js::ProfileId slotLoadId) const { - Assert(slotLoadId < GetProfiledSlotCount()); + AssertOrFailFast(slotLoadId < GetProfiledSlotCount()); return reinterpret_cast<ValueType*>(m_profileData.slotData)[slotLoadId]; } @@ -197,32 +199,32 @@ JITTimeProfileInfo::GetReturnType(Js::OpCode opcode, Js::ProfileId callSiteId) c if (opcode < Js::OpCode::ProfiledReturnTypeCallI || (opcode > Js::OpCode::ProfiledReturnTypeCallIFlags && opcode < Js::OpCode::ProfiledReturnTypeCallIExtended) || opcode > Js::OpCode::ProfiledReturnTypeCallIExtendedFlags) { Assert(Js::DynamicProfileInfo::IsProfiledCallOp(opcode)); - Assert(callSiteId < GetProfiledCallSiteCount()); + AssertOrFailFast(callSiteId < GetProfiledCallSiteCount()); return GetCallSiteInfo()[callSiteId].returnType; } Assert(Js::DynamicProfileInfo::IsProfiledReturnTypeOp(opcode)); - Assert(callSiteId < GetProfiledReturnTypeCount()); + AssertOrFailFast(callSiteId < GetProfiledReturnTypeCount()); return reinterpret_cast<ValueType*>(m_profileData.returnTypeData)[callSiteId]; } ValueType JITTimeProfileInfo::GetDivProfileInfo(Js::ProfileId divideId) const { - Assert(divideId < GetProfiledDivOrRemCount()); + AssertOrFailFast(divideId < GetProfiledDivOrRemCount()); return reinterpret_cast<ValueType*>(m_profileData.divideTypeInfo)[divideId]; } ValueType JITTimeProfileInfo::GetSwitchProfileInfo(Js::ProfileId switchId) const { - Assert(switchId < GetProfiledSwitchCount()); + AssertOrFailFast(switchId < GetProfiledSwitchCount()); return reinterpret_cast<ValueType*>(m_profileData.switchTypeInfo)[switchId]; } ValueType JITTimeProfileInfo::GetParameterInfo(Js::ArgSlot index) const { - Assert(index < GetProfiledInParamsCount()); + AssertOrFailFast(index < GetProfiledInParamsCount()); return reinterpret_cast<ValueType*>(m_profileData.parameterInfo)[index]; } @@ -231,7 +233,7 @@ JITTimeProfileInfo::GetLoopImplicitCallFlags(uint loopNum) const { // TODO: michhol OOP JIT, investigate vaibility of reenabling this assert // Assert(Js::DynamicProfileInfo::EnableImplicitCallFlags(functionBody)); - Assert(loopNum < GetLoopCount()); + AssertOrFailFast(loopNum < GetLoopCount()); // Mask out the dispose implicit call. We would bailout on reentrant dispose, // but it shouldn't affect optimization.
lib/Backend/ServerScriptContext.cpp+1 −1 modified@@ -384,7 +384,7 @@ ServerScriptContext::Release() Field(Js::Var)* ServerScriptContext::GetModuleExportSlotArrayAddress(uint moduleIndex, uint slotIndex) { - Assert(m_moduleRecords.ContainsKey(moduleIndex)); + AssertOrFailFast(m_moduleRecords.ContainsKey(moduleIndex)); auto record = m_moduleRecords.Item(moduleIndex); return record->localExportSlotsAddr; }
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
8- github.com/advisories/GHSA-m8x8-5ch7-c5w9ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2018-0836ghsaADVISORY
- www.securityfocus.com/bid/102875mitrevdb-entryx_refsource_BID
- www.securitytracker.com/id/1040372mitrevdb-entryx_refsource_SECTRACK
- github.com/chakra-core/ChakraCore/commit/b99d0dcbf5a890e3f5dcdbfcec033f5c92b2bd6dghsaWEB
- portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2018-0836ghsax_refsource_CONFIRMWEB
- web.archive.org/web/20210804005206/http://www.securityfocus.com/bid/102875ghsaWEB
- web.archive.org/web/20211208072939/http://www.securitytracker.com/id/1040372ghsaWEB
News mentions
0No linked articles in our index yet.