From 8dc4469e4d6c0230f5764da0915e0a59a1ae8aa6 Mon Sep 17 00:00:00 2001 From: Jianchun Xu Date: Wed, 17 May 2017 16:26:52 -0700 Subject: [PATCH 1/8] [CVE-2017-8522] TypeHandler invalid index reuse may cause buffer overrun Update unordered SimpleDictionaryTypeHandler deleted index chain terminator when growing from small to big index. --- Build/Chakra.Build.props | 5 +++++ Build/Common.Build.props | 2 +- lib/Common/CommonDefines.h | 7 +++++++ .../Types/SimpleDictionaryTypeHandler.cpp | 3 ++- .../SimpleDictionaryUnorderedTypeHandler.h | 20 ++++++++++++++++++- 5 files changed, 34 insertions(+), 3 deletions(-) diff --git a/Build/Chakra.Build.props b/Build/Chakra.Build.props index 860fcef3c84..1536b7f06e8 100644 --- a/Build/Chakra.Build.props +++ b/Build/Chakra.Build.props @@ -16,6 +16,7 @@ %(PreprocessorDefinitions); + _CHAKRACOREBUILD; _WIN32_WINNT=$(Win32_WinNTVersion); WINVER=$(Win32_WinNTVersion); WIN32_LEAN_AND_MEAN=1 @@ -52,6 +53,10 @@ Disabled + + %(PreprocessorDefinitions);_CHAKRACOREBUILD + + %(AdditionalOptions) /DEBUGTYPE:CV,FIXUP diff --git a/Build/Common.Build.props b/Build/Common.Build.props index 45606495eff..78565ce6372 100644 --- a/Build/Common.Build.props +++ b/Build/Common.Build.props @@ -31,7 +31,7 @@ %(AdditionalOptions) -sal_local - %(PreprocessorDefinitions);_CHAKRACOREBUILD;NOMINMAX;USE_EDGEMODE_JSRT + %(PreprocessorDefinitions);NOMINMAX;USE_EDGEMODE_JSRT %(PreprocessorDefinitions);COM_STDMETHOD_CAN_THROW diff --git a/lib/Common/CommonDefines.h b/lib/Common/CommonDefines.h index b96ed6151ba..b87d0c2852a 100644 --- a/lib/Common/CommonDefines.h +++ b/lib/Common/CommonDefines.h @@ -8,6 +8,13 @@ #include "Warnings.h" #include "ChakraCoreVersion.h" +#if defined(NTBUILD) && defined(_CHAKRACOREBUILD) +#error NTBUILD and _CHAKRACOREBUILD cannot be both defined +#endif +#if !defined(NTBUILD) && !defined(_CHAKRACOREBUILD) +#error Either NTBUILD or _CHAKRACOREBUILD must be defined +#endif + //---------------------------------------------------------------------------------------------------- // Default debug/fretest/release flags values // - Set the default values of debug/fretest/release flags if it is not set by the command line diff --git a/lib/Runtime/Types/SimpleDictionaryTypeHandler.cpp b/lib/Runtime/Types/SimpleDictionaryTypeHandler.cpp index a37b1fc9f87..068e175380c 100644 --- a/lib/Runtime/Types/SimpleDictionaryTypeHandler.cpp +++ b/lib/Runtime/Types/SimpleDictionaryTypeHandler.cpp @@ -563,7 +563,7 @@ namespace Js if(isUnordered) { - newTypeHandler->CopyUnorderedStateFrom(*AsUnordered()); + newTypeHandler->CopyUnorderedStateFrom(*AsUnordered(), instance); } else { @@ -2685,6 +2685,7 @@ namespace Js ->AddProperty(instance, propertyKey, value, attributes, info, flags, possibleSideEffects); } + // CONSIDER: Do this after TryReuseDeletedPropertyIndex. If we can reuse slots, no need to grow right now. if (this->GetSlotCapacity() <= nextPropertyIndex) { if (this->GetSlotCapacity() >= MaxPropertyIndexSize) diff --git a/lib/Runtime/Types/SimpleDictionaryUnorderedTypeHandler.h b/lib/Runtime/Types/SimpleDictionaryUnorderedTypeHandler.h index 3a33587147e..9a384cfe0fb 100644 --- a/lib/Runtime/Types/SimpleDictionaryUnorderedTypeHandler.h +++ b/lib/Runtime/Types/SimpleDictionaryUnorderedTypeHandler.h @@ -43,12 +43,30 @@ namespace Js private: template - void CopyUnorderedStateFrom(const SimpleDictionaryUnorderedTypeHandler &other) + void CopyUnorderedStateFrom(const SimpleDictionaryUnorderedTypeHandler &other, + DynamicObject *const object) { CompileAssert(sizeof(TPropertyIndex) >= sizeof(OtherTPropertyIndex)); if (other.deletedPropertyIndex != PropertyIndexRanges::NoSlots) { deletedPropertyIndex = other.deletedPropertyIndex; + + // If terminator values are different, walk to end of chain and update terminator value + if ((int)PropertyIndexRanges::NoSlots != (int)PropertyIndexRanges::NoSlots) + { + OtherTPropertyIndex cur = other.deletedPropertyIndex; + for (;;) + { + OtherTPropertyIndex next = static_cast(TaggedInt::ToInt32(object->GetSlot(cur))); + if (next == PropertyIndexRanges::NoSlots) + { + this->SetSlotUnchecked(object, cur, TaggedInt::ToVarUnchecked(PropertyIndexRanges::NoSlots)); + break; + } + + cur = next; + } + } } } From 886a64c39c7e1f5337918465a517d4f4d0e88143 Mon Sep 17 00:00:00 2001 From: Paul Leathers Date: Thu, 18 May 2017 17:25:31 -0700 Subject: [PATCH 2/8] [CVE-2017-8518] Use protected add operations when computing the length of a new frame display. --- lib/Runtime/Language/JavascriptOperators.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Runtime/Language/JavascriptOperators.cpp b/lib/Runtime/Language/JavascriptOperators.cpp index d695460e2c9..40bf3ba4a09 100644 --- a/lib/Runtime/Language/JavascriptOperators.cpp +++ b/lib/Runtime/Language/JavascriptOperators.cpp @@ -6435,7 +6435,7 @@ namespace Js aParent = CrossSite::MarshalVar(scriptContext, aParent); if (i == length) { - length += 8; + length = UInt16Math::Add(length, 8); FrameDisplay * tmp = RecyclerNewPlus(scriptContext->GetRecycler(), length * sizeof(void*), FrameDisplay, length); js_memcpy_s((char*)tmp + tmp->GetOffsetOfScopes(), tmp->GetLength() * sizeof(void *), (char*)pDisplay + pDisplay->GetOffsetOfScopes(), pDisplay->GetLength() * sizeof(void*)); pDisplay = tmp; @@ -6493,10 +6493,10 @@ namespace Js FrameDisplay *pDisplay = nullptr; FrameDisplay *envDisplay = (FrameDisplay*)argEnv; - uint16 length = envDisplay->GetLength() + 1; + uint16 length = UInt16Math::Add(envDisplay->GetLength(), 1); pDisplay = RecyclerNewPlus(scriptContext->GetRecycler(), length * sizeof(void*), FrameDisplay, length); - for (int j = 0; j < length - 1; j++) + for (uint16 j = 0; j < length - 1; j++) { pDisplay->SetItem(j + 1, envDisplay->GetItem(j)); } From b4f28f09d15beb167ac424afb5498e2ea99b8c2b Mon Sep 17 00:00:00 2001 From: Paul Leathers Date: Sat, 29 Apr 2017 12:03:01 -0700 Subject: [PATCH 3/8] [CVE-2017-8524] Force addition of a data slot to the property descriptor when a global let/const property is added and a same-named global getter/setter already exists. --- lib/Runtime/Types/DictionaryPropertyDescriptor.h | 6 +++++- test/LetConst/rlexe.xml | 5 +++++ test/LetConst/shadowedsetter.js | 13 +++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 test/LetConst/shadowedsetter.js diff --git a/lib/Runtime/Types/DictionaryPropertyDescriptor.h b/lib/Runtime/Types/DictionaryPropertyDescriptor.h index f72f1743147..58e39388607 100644 --- a/lib/Runtime/Types/DictionaryPropertyDescriptor.h +++ b/lib/Runtime/Types/DictionaryPropertyDescriptor.h @@ -154,6 +154,10 @@ namespace Js if (this->IsAccessor) { Assert(this->Data == NoSlots); + if (addingLetConstGlobal) + { + this->Data = nextPropertyIndex++; + } } else if (addingLetConstGlobal) { @@ -165,7 +169,7 @@ namespace Js this->Getter = nextPropertyIndex++; } this->Attributes |= PropertyLetConstGlobal; - Assert(GetDataPropertyIndex() != NoSlots); + Assert((addingLetConstGlobal ? GetDataPropertyIndex() : GetDataPropertyIndex()) != NoSlots); } template diff --git a/test/LetConst/rlexe.xml b/test/LetConst/rlexe.xml index cf2430fd1ff..a68c9604227 100644 --- a/test/LetConst/rlexe.xml +++ b/test/LetConst/rlexe.xml @@ -379,4 +379,9 @@ -args summary -endargs + + + shadowedsetter.js + + diff --git a/test/LetConst/shadowedsetter.js b/test/LetConst/shadowedsetter.js new file mode 100644 index 00000000000..a38d132b25b --- /dev/null +++ b/test/LetConst/shadowedsetter.js @@ -0,0 +1,13 @@ +evaluate = WScript.LoadScript; + +__defineSetter__("x", function () { }); + +evaluate(` + let x = 'let'; + Object.defineProperty(this, "x", { value: + 0xdec0 }) + if (x === 'let' && this.x === 57024) + { + WScript.Echo('pass'); + } +`); From cd60f3b5c35592006caae7730760a7980857990c Mon Sep 17 00:00:00 2001 From: Paul Leathers Date: Wed, 3 May 2017 18:18:12 -0700 Subject: [PATCH 4/8] [CVE-2017-8548] In the case of a write to a typed array, the JIT emits inline code to do a bounds check. If the check fails, we convert the source value and jump to the end of the operation. But if the store should bail out on implicit calls, then we need to check for implicit calls caused by the conversion as well as the store itself. --- lib/Backend/Lower.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/Backend/Lower.cpp b/lib/Backend/Lower.cpp index 2fbeee00a0a..559a5719225 100644 --- a/lib/Backend/Lower.cpp +++ b/lib/Backend/Lower.cpp @@ -15889,10 +15889,22 @@ Lowerer::GenerateFastElemIIntIndexCommon( // For typed array, call ToNumber before we fallThrough. if (instr->GetSrc1()->GetType() == TyVar && !instr->GetSrc1()->GetValueType().IsPrimitive()) { + // Enter an ophelper block + IR::LabelInstr * opHelper = IR::LabelInstr::New(Js::OpCode::Label, this->m_func, true); + instr->InsertBefore(opHelper); + IR::Instr *toNumberInstr = IR::Instr::New(Js::OpCode::Call, this->m_func); toNumberInstr->SetSrc1(instr->GetSrc1()); instr->InsertBefore(toNumberInstr); + if (BailOutInfo::IsBailOutOnImplicitCalls(bailOutKind)) + { + // Bail out if this conversion triggers implicit calls. + toNumberInstr = toNumberInstr->ConvertToBailOutInstr(instr->GetBailOutInfo(), bailOutKind); + IR::Instr * instrShare = instr->ShareBailOut(); + LowerBailTarget(instrShare); + } + LowerUnaryHelperMem(toNumberInstr, IR::HelperOp_ConvNumber_Full); } InsertBranch(Js::OpCode::Br, labelFallthrough, instr); //Jump to fallThrough From dd3e73bfecb44bd6a7f47f0be33d82960d4ff352 Mon Sep 17 00:00:00 2001 From: Michael Holman Date: Wed, 24 May 2017 17:47:25 -0700 Subject: [PATCH 5/8] [CVE-2017-8520] ensure that ServerScriptContext is unregistered before freeing --- lib/JITServer/JITServer.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/JITServer/JITServer.cpp b/lib/JITServer/JITServer.cpp index de2d2acb62e..6598a9e3a0c 100644 --- a/lib/JITServer/JITServer.cpp +++ b/lib/JITServer/JITServer.cpp @@ -422,11 +422,15 @@ ServerCleanupScriptContext( return RPC_S_INVALID_ARG; } + if (!scriptContextInfo->IsClosed()) + { + scriptContextInfo->Close(); + ServerContextManager::UnRegisterScriptContext(scriptContextInfo); + } // This tells the run-time, when it is marshalling the out // parameters, that the context handle has been closed normally. *scriptContextInfoAddress = nullptr; - Assert(scriptContextInfo->IsClosed()); HeapDelete(scriptContextInfo); return S_OK; From 320547aabee3866c01c1cf9139eb1b264e3b9ad6 Mon Sep 17 00:00:00 2001 From: Rajat Dua Date: Wed, 7 Jun 2017 16:46:53 -0700 Subject: [PATCH 6/8] [CVE-2017-0228] Reallocate the last segment of a sparse array as a non-leaf, if necessary, before attempting to reverse the segment linked list --- lib/Runtime/Library/JavascriptArray.cpp | 46 ++++++++++++++----------- lib/Runtime/Library/JavascriptArray.h | 4 ++- lib/Runtime/Library/JavascriptArray.inl | 12 +++++-- 3 files changed, 38 insertions(+), 24 deletions(-) diff --git a/lib/Runtime/Library/JavascriptArray.cpp b/lib/Runtime/Library/JavascriptArray.cpp index 66d8d027f8d..616dc1da9b9 100644 --- a/lib/Runtime/Library/JavascriptArray.cpp +++ b/lib/Runtime/Library/JavascriptArray.cpp @@ -5253,16 +5253,28 @@ namespace Js if (hasInlineSegment) { - SparseArraySegmentBase* headSegBase = array->head; - SparseArraySegment* headSeg = (SparseArraySegment*)headSegBase; + SparseArraySegment* newHeadSeg = array->ReallocNonLeafSegment((SparseArraySegment*)PointerValue(array->head), array->head->next); + array->head = newHeadSeg; + } + } - AnalysisAssert(headSeg); - SparseArraySegment* newHeadSeg = SparseArraySegment::template AllocateSegmentImpl(recycler, - headSeg->left, headSeg->length, headSeg->size, headSeg->next); + template + void JavascriptArray::ReallocateNonLeafLastSegmentIfLeaf(JavascriptArray * arr, Recycler * recycler) + { + Assert(arr->head && arr->head->next); // Doesn't make sense to reallocate a leaf last segment as a non-leaf if its not going to point to any other segments. - newHeadSeg = SparseArraySegment::CopySegment(recycler, newHeadSeg, headSeg->left, headSeg, headSeg->left, headSeg->length); - newHeadSeg->next = headSeg->next; - array->head = newHeadSeg; + // TODO: Consider utilizing lastUsedSegment once we fix CopyHeadIfInlinedHeadSegment in that respect. + SparseArraySegmentBase *lastSeg = nullptr; + SparseArraySegmentBase *seg = arr->head; + while (seg) + { + lastSeg = seg; + seg = seg->next; + } + + if (SparseArraySegmentBase::IsLeafSegment(lastSeg, recycler)) + { + arr->ReallocNonLeafSegment((SparseArraySegment*)lastSeg, lastSeg->next, true /*forceNonLeaf*/); } } @@ -5369,6 +5381,8 @@ namespace Js bool isIntArray = false; bool isFloatArray = false; + pArr->ClearSegmentMap(); // Just dump the segment map on reverse + if (JavascriptNativeIntArray::Is(pArr)) { isIntArray = true; @@ -5386,10 +5400,12 @@ namespace Js if (isIntArray) { CopyHeadIfInlinedHeadSegment(pArr, recycler); + ReallocateNonLeafLastSegmentIfLeaf(pArr, recycler); } else if (isFloatArray) { CopyHeadIfInlinedHeadSegment(pArr, recycler); + ReallocateNonLeafLastSegmentIfLeaf(pArr, recycler); } else { @@ -5437,24 +5453,14 @@ namespace Js } pArr->head = prevSeg; - - // Just dump the segment map on reverse - pArr->ClearSegmentMap(); + pArr->InvalidateLastUsedSegment(); // lastUsedSegment might be 0-length and discarded above if (isIntArray) { - if (pArr->head && pArr->head->next && SparseArraySegmentBase::IsLeafSegment(pArr->head, recycler)) - { - pArr->ReallocNonLeafSegment(SparseArraySegment::From(pArr->head), pArr->head->next); - } pArr->EnsureHeadStartsFromZero(recycler); } else if (isFloatArray) { - if (pArr->head && pArr->head->next && SparseArraySegmentBase::IsLeafSegment(pArr->head, recycler)) - { - pArr->ReallocNonLeafSegment(SparseArraySegment::From(pArr->head), pArr->head->next); - } pArr->EnsureHeadStartsFromZero(recycler); } else @@ -5462,8 +5468,6 @@ namespace Js pArr->EnsureHeadStartsFromZero(recycler); } - pArr->InvalidateLastUsedSegment(); // lastUsedSegment might be 0-length and discarded above - #ifdef VALIDATE_ARRAY pArr->ValidateArray(); #endif diff --git a/lib/Runtime/Library/JavascriptArray.h b/lib/Runtime/Library/JavascriptArray.h index fb3abcf91ba..2c10134ca8e 100644 --- a/lib/Runtime/Library/JavascriptArray.h +++ b/lib/Runtime/Library/JavascriptArray.h @@ -417,7 +417,7 @@ namespace Js JavascriptArray(JavascriptArray * instance, bool boxHead); template inline void LinkSegments(SparseArraySegment* prev, SparseArraySegment* current); - template inline SparseArraySegment* ReallocNonLeafSegment(SparseArraySegment* seg, SparseArraySegmentBase* nextSeg); + template inline SparseArraySegment* ReallocNonLeafSegment(SparseArraySegment* seg, SparseArraySegmentBase* nextSeg, bool forceNonLeaf = false); void TryAddToSegmentMap(Recycler* recycler, SparseArraySegmentBase* seg); private: @@ -575,6 +575,8 @@ namespace Js template static void CopyHeadIfInlinedHeadSegment(JavascriptArray *array, Recycler *recycler); + template + static void ReallocateNonLeafLastSegmentIfLeaf(JavascriptArray * arr, Recycler * recycler); template static void ArraySpliceHelper(JavascriptArray* pNewArr, JavascriptArray* pArr, uint32 start, uint32 deleteLen, diff --git a/lib/Runtime/Library/JavascriptArray.inl b/lib/Runtime/Library/JavascriptArray.inl index c96dd527eb4..667a6a8f2c6 100644 --- a/lib/Runtime/Library/JavascriptArray.inl +++ b/lib/Runtime/Library/JavascriptArray.inl @@ -95,7 +95,7 @@ namespace Js } template - inline SparseArraySegment* JavascriptArray::ReallocNonLeafSegment(SparseArraySegment *seg, SparseArraySegmentBase* nextSeg) + inline SparseArraySegment* JavascriptArray::ReallocNonLeafSegment(SparseArraySegment *seg, SparseArraySegmentBase* nextSeg, bool forceNonLeaf) { // Find the segment prior to seg. SparseArraySegmentBase *prior = nullptr; @@ -106,8 +106,16 @@ namespace Js Assert(prior->next); } } + SparseArraySegment *newSeg = nullptr; Recycler *recycler = this->GetScriptContext()->GetRecycler(); - SparseArraySegment *newSeg = SparseArraySegment::AllocateSegment(recycler, seg->left, seg->length, nextSeg); + if (forceNonLeaf) + { + newSeg = SparseArraySegment::AllocateSegmentImpl(recycler, seg->left, seg->length, nextSeg); + } + else + { + newSeg = SparseArraySegment::AllocateSegment(recycler, seg->left, seg->length, nextSeg); + } CopyArray(newSeg->elements, seg->length, seg->elements, seg->length); LinkSegmentsCommon(prior, newSeg); From bb95963a4ae8ab95bcb7ef5726d817945aba5d34 Mon Sep 17 00:00:00 2001 From: Meghana Gupta Date: Thu, 8 Jun 2017 12:03:32 -0700 Subject: [PATCH 7/8] [CVE-2017-8499] Fix expanding rest arguments during inlining --- lib/Backend/Inline.cpp | 48 +++++++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/lib/Backend/Inline.cpp b/lib/Backend/Inline.cpp index a155c12ddd3..d720c65c85d 100644 --- a/lib/Backend/Inline.cpp +++ b/lib/Backend/Inline.cpp @@ -4674,16 +4674,22 @@ Inline::MapFormals(Func *inlinee, { break; } + + int excess; + uint restFuncFormalCount = 0; if (instr->m_func != inlinee) { - // this can happen only when we are inlining a function which has inlined an apply call with the arguments object - formalCount = instr->m_func->GetJITFunctionBody()->GetInParamsCount(); + restFuncFormalCount = instr->m_func->GetJITFunctionBody()->GetInParamsCount(); + Assert(restFuncFormalCount < 1 << 24); // 24 bits for arg count (see CallInfo.h) + excess = actualCount - restFuncFormalCount; + } + else + { + excess = actualCount - formalCount; } - IR::Opnd *restDst = instr->GetDst(); Assert(actualCount < 1 << 24 && formalCount < 1 << 24); // 24 bits for arg count (see CallInfo.h) - int excess = actualCount - formalCount; if (excess < 0) { @@ -4701,11 +4707,37 @@ Inline::MapFormals(Func *inlinee, IR::Instr *newArrInstr = IR::Instr::New(Js::OpCode::NewScArray, restDst, IR::IntConstOpnd::New(excess, TyUint32, inlinee), inlinee); instr->InsertBefore(newArrInstr); - for (uint i = formalCount; i < actualCount; ++i) + if (instr->m_func != inlinee) { - IR::IndirOpnd *arrayLocOpnd = IR::IndirOpnd::New(restDst->AsRegOpnd(), i - formalCount, TyVar, inlinee); - IR::Instr *stElemInstr = IR::Instr::New(Js::OpCode::StElemC, arrayLocOpnd, argOutsExtra[i]->GetBytecodeArgOutCapture()->GetDst(), inlinee); - instr->InsertBefore(stElemInstr); + uint index = 0; + for (uint i = restFuncFormalCount; i < min(actualCount, formalCount); ++i) + { + IR::IndirOpnd *arrayLocOpnd = IR::IndirOpnd::New(restDst->AsRegOpnd(), index, TyVar, inlinee); + IR::Instr *stElemInstr = IR::Instr::New(Js::OpCode::StElemC, arrayLocOpnd, argOuts[i]->GetBytecodeArgOutCapture()->GetDst(), inlinee); + instr->InsertBefore(stElemInstr); + index++; + } + for (uint i = max(formalCount, restFuncFormalCount); i < actualCount; ++i) + { + IR::IndirOpnd *arrayLocOpnd = IR::IndirOpnd::New(restDst->AsRegOpnd(), index, TyVar, inlinee); + IR::Instr *stElemInstr = IR::Instr::New(Js::OpCode::StElemC, arrayLocOpnd, argOutsExtra[i]->GetBytecodeArgOutCapture()->GetDst(), inlinee); + instr->InsertBefore(stElemInstr); + index++; + } + AssertMsg(index == (uint)excess, "Incorrect rest args built"); + if (index != (uint)excess) + { + throw Js::OperationAbortedException(); + } + } + else + { + for (uint i = formalCount; i < actualCount; ++i) + { + IR::IndirOpnd *arrayLocOpnd = IR::IndirOpnd::New(restDst->AsRegOpnd(), i - formalCount, TyVar, inlinee); + IR::Instr *stElemInstr = IR::Instr::New(Js::OpCode::StElemC, arrayLocOpnd, argOutsExtra[i]->GetBytecodeArgOutCapture()->GetDst(), inlinee); + instr->InsertBefore(stElemInstr); + } } instr->Remove(); From 86b66eefa6e4a339351562fb65bcac30dc96062c Mon Sep 17 00:00:00 2001 From: Jianchun Xu Date: Thu, 15 Jun 2017 10:06:26 -0700 Subject: [PATCH 8/8] fix some 17-06 build breaks and CI copyright check failure --- lib/Common/CommonDefines.h | 7 ------- lib/Runtime/Library/JavascriptArray.cpp | 2 ++ lib/Runtime/Library/JavascriptArray.inl | 2 +- test/LetConst/shadowedsetter.js | 5 +++++ 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/Common/CommonDefines.h b/lib/Common/CommonDefines.h index b87d0c2852a..b96ed6151ba 100644 --- a/lib/Common/CommonDefines.h +++ b/lib/Common/CommonDefines.h @@ -8,13 +8,6 @@ #include "Warnings.h" #include "ChakraCoreVersion.h" -#if defined(NTBUILD) && defined(_CHAKRACOREBUILD) -#error NTBUILD and _CHAKRACOREBUILD cannot be both defined -#endif -#if !defined(NTBUILD) && !defined(_CHAKRACOREBUILD) -#error Either NTBUILD or _CHAKRACOREBUILD must be defined -#endif - //---------------------------------------------------------------------------------------------------- // Default debug/fretest/release flags values // - Set the default values of debug/fretest/release flags if it is not set by the command line diff --git a/lib/Runtime/Library/JavascriptArray.cpp b/lib/Runtime/Library/JavascriptArray.cpp index 616dc1da9b9..4b36b5448a1 100644 --- a/lib/Runtime/Library/JavascriptArray.cpp +++ b/lib/Runtime/Library/JavascriptArray.cpp @@ -5253,6 +5253,7 @@ namespace Js if (hasInlineSegment) { + AnalysisAssert(array->head); SparseArraySegment* newHeadSeg = array->ReallocNonLeafSegment((SparseArraySegment*)PointerValue(array->head), array->head->next); array->head = newHeadSeg; } @@ -5274,6 +5275,7 @@ namespace Js if (SparseArraySegmentBase::IsLeafSegment(lastSeg, recycler)) { + AnalysisAssert(lastSeg); arr->ReallocNonLeafSegment((SparseArraySegment*)lastSeg, lastSeg->next, true /*forceNonLeaf*/); } } diff --git a/lib/Runtime/Library/JavascriptArray.inl b/lib/Runtime/Library/JavascriptArray.inl index 667a6a8f2c6..e80880503ed 100644 --- a/lib/Runtime/Library/JavascriptArray.inl +++ b/lib/Runtime/Library/JavascriptArray.inl @@ -110,7 +110,7 @@ namespace Js Recycler *recycler = this->GetScriptContext()->GetRecycler(); if (forceNonLeaf) { - newSeg = SparseArraySegment::AllocateSegmentImpl(recycler, seg->left, seg->length, nextSeg); + newSeg = SparseArraySegment::template AllocateSegmentImpl(recycler, seg->left, seg->length, nextSeg); } else { diff --git a/test/LetConst/shadowedsetter.js b/test/LetConst/shadowedsetter.js index a38d132b25b..34259e26f20 100644 --- a/test/LetConst/shadowedsetter.js +++ b/test/LetConst/shadowedsetter.js @@ -1,3 +1,8 @@ +//------------------------------------------------------------------------------------------------------- +// Copyright (C) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. +//------------------------------------------------------------------------------------------------------- + evaluate = WScript.LoadScript; __defineSetter__("x", function () { });