From 2cbac571469262c4cff05af84f35216bf483de35 Mon Sep 17 00:00:00 2001 From: Jason Orendorff Date: Fri, 4 Apr 2014 17:03:13 -0500 Subject: [PATCH] Bug 990096, part 2 - Crash on OOM for various small allocations in Yarr. r=h4writer. --- js/src/yarr/RegExpJitTables.h | 14 ++++----- js/src/yarr/YarrInterpreter.cpp | 6 ++-- js/src/yarr/YarrPattern.cpp | 12 ++++---- js/src/yarr/YarrPattern.h | 2 +- js/src/yarr/wtfbridge.h | 51 +++++++++++++++++++++++++++++++++ 5 files changed, 68 insertions(+), 17 deletions(-) diff --git a/js/src/yarr/RegExpJitTables.h b/js/src/yarr/RegExpJitTables.h index b114e7a3afe4..2dd91b1d8f6e 100644 --- a/js/src/yarr/RegExpJitTables.h +++ b/js/src/yarr/RegExpJitTables.h @@ -2632,14 +2632,14 @@ static const char _wordcharData[65536] = { CharacterClass* digitsCreate() { - CharacterClass* characterClass = js_new(); + CharacterClass* characterClass = newOrCrash(); characterClass->m_ranges.append(CharacterRange(0x30, 0x39)); return characterClass; } CharacterClass* nondigitsCreate() { - CharacterClass* characterClass = js_new(); + CharacterClass* characterClass = newOrCrash(); characterClass->m_ranges.append(CharacterRange(0x00, 0x2f)); characterClass->m_ranges.append(CharacterRange(0x3a, 0x7f)); characterClass->m_rangesUnicode.append(CharacterRange(0x0080, 0xffff)); @@ -2648,7 +2648,7 @@ CharacterClass* nondigitsCreate() CharacterClass* newlineCreate() { - CharacterClass* characterClass = js_new(); + CharacterClass* characterClass = newOrCrash(); characterClass->m_matches.append(0x0a); characterClass->m_matches.append(0x0d); characterClass->m_matchesUnicode.append(0x2028); @@ -2658,7 +2658,7 @@ CharacterClass* newlineCreate() CharacterClass* spacesCreate() { - CharacterClass* characterClass = js_new(_spacesData, false); + CharacterClass* characterClass = newOrCrash(_spacesData, false); characterClass->m_ranges.append(CharacterRange(0x09, 0x0d)); characterClass->m_matches.append(0x20); characterClass->m_matchesUnicode.append(0x00a0); @@ -2676,7 +2676,7 @@ CharacterClass* spacesCreate() CharacterClass* nonspacesCreate() { - CharacterClass* characterClass = js_new(_spacesData, true); + CharacterClass* characterClass = newOrCrash(_spacesData, true); characterClass->m_ranges.append(CharacterRange(0x00, 0x08)); characterClass->m_ranges.append(CharacterRange(0x0e, 0x1f)); characterClass->m_ranges.append(CharacterRange(0x21, 0x7f)); @@ -2695,7 +2695,7 @@ CharacterClass* nonspacesCreate() CharacterClass* nonwordcharCreate() { - CharacterClass* characterClass = js_new(_wordcharData, true); + CharacterClass* characterClass = newOrCrash(_wordcharData, true); characterClass->m_ranges.append(CharacterRange(0x00, 0x2f)); characterClass->m_ranges.append(CharacterRange(0x3a, 0x40)); characterClass->m_ranges.append(CharacterRange(0x5b, 0x5e)); @@ -2707,7 +2707,7 @@ CharacterClass* nonwordcharCreate() CharacterClass* wordcharCreate() { - CharacterClass* characterClass = js_new(_wordcharData, false); + CharacterClass* characterClass = newOrCrash(_wordcharData, false); characterClass->m_ranges.append(CharacterRange(0x30, 0x39)); characterClass->m_ranges.append(CharacterRange(0x41, 0x5a)); characterClass->m_matches.append(0x5f); diff --git a/js/src/yarr/YarrInterpreter.cpp b/js/src/yarr/YarrInterpreter.cpp index 9d2275ce6a84..f59b99699bee 100644 --- a/js/src/yarr/YarrInterpreter.cpp +++ b/js/src/yarr/YarrInterpreter.cpp @@ -1505,7 +1505,7 @@ public: emitDisjunction(m_pattern.m_body); regexEnd(); - return adoptPtr(js_new(m_bodyDisjunction.release(), m_allParenthesesInfo, Ref(m_pattern), allocator)); + return adoptPtr(newOrCrash(m_bodyDisjunction.release(), m_allParenthesesInfo, Ref(m_pattern), allocator)); } void checkInput(unsigned count) @@ -1736,7 +1736,7 @@ public: unsigned subpatternId = parenthesesBegin.atom.subpatternId; unsigned numSubpatterns = lastSubpatternId - subpatternId + 1; - ByteDisjunction* parenthesesDisjunction = js_new(numSubpatterns, callFrameSize); + ByteDisjunction* parenthesesDisjunction = newOrCrash(numSubpatterns, callFrameSize); parenthesesDisjunction->terms.reserve(endTerm - beginTerm + 1); parenthesesDisjunction->terms.append(ByteTerm::SubpatternBegin()); @@ -1800,7 +1800,7 @@ public: void regexBegin(unsigned numSubpatterns, unsigned callFrameSize, bool onceThrough) { - m_bodyDisjunction = adoptPtr(js_new(numSubpatterns, callFrameSize)); + m_bodyDisjunction = adoptPtr(newOrCrash(numSubpatterns, callFrameSize)); m_bodyDisjunction->terms.append(ByteTerm::BodyAlternativeBegin(onceThrough)); m_bodyDisjunction->terms[0].frameLocation = 0; m_currentAlternativeIndex = 0; diff --git a/js/src/yarr/YarrPattern.cpp b/js/src/yarr/YarrPattern.cpp index b44b8afd5e72..60dca3f02ab6 100644 --- a/js/src/yarr/YarrPattern.cpp +++ b/js/src/yarr/YarrPattern.cpp @@ -187,7 +187,7 @@ public: CharacterClass* charClass() { - CharacterClass* characterClass = js_new(); + CharacterClass* characterClass = newOrCrash(); characterClass->m_matches.swap(m_matches); characterClass->m_ranges.swap(m_ranges); @@ -285,7 +285,7 @@ public: , m_characterClassConstructor(pattern.m_ignoreCase) , m_invertParentheticalAssertion(false) { - m_pattern.m_body = js_new(); + m_pattern.m_body = newOrCrash(); m_alternative = m_pattern.m_body->addNewAlternative(); m_pattern.m_disjunctions.append(m_pattern.m_body); } @@ -299,7 +299,7 @@ public: m_pattern.reset(); m_characterClassConstructor.reset(); - m_pattern.m_body = js_new(); + m_pattern.m_body = newOrCrash(); m_alternative = m_pattern.m_body->addNewAlternative(); m_pattern.m_disjunctions.append(m_pattern.m_body); } @@ -411,7 +411,7 @@ public: if (capture) m_pattern.m_numSubpatterns++; - PatternDisjunction* parenthesesDisjunction = js_new(m_alternative); + PatternDisjunction* parenthesesDisjunction = newOrCrash(m_alternative); m_pattern.m_disjunctions.append(parenthesesDisjunction); m_alternative->m_terms.append(PatternTerm(PatternTerm::TypeParenthesesSubpattern, subpatternId, parenthesesDisjunction, capture, false)); m_alternative = parenthesesDisjunction->addNewAlternative(); @@ -419,7 +419,7 @@ public: void atomParentheticalAssertionBegin(bool invert = false) { - PatternDisjunction* parenthesesDisjunction = js_new(m_alternative); + PatternDisjunction* parenthesesDisjunction = newOrCrash(m_alternative); m_pattern.m_disjunctions.append(parenthesesDisjunction); m_alternative->m_terms.append(PatternTerm(PatternTerm::TypeParentheticalAssertion, m_pattern.m_numSubpatterns + 1, parenthesesDisjunction, false, invert)); m_alternative = parenthesesDisjunction->addNewAlternative(); @@ -493,7 +493,7 @@ public: PatternAlternative* alternative = disjunction->m_alternatives[alt]; if (!filterStartsWithBOL || !alternative->m_startsWithBOL) { if (!newDisjunction) { - newDisjunction = js_new(); + newDisjunction = newOrCrash(); newDisjunction->m_parent = disjunction->m_parent; } PatternAlternative* newAlternative = newDisjunction->addNewAlternative(); diff --git a/js/src/yarr/YarrPattern.h b/js/src/yarr/YarrPattern.h index 9db9cf99489d..599b2cb9c4c6 100644 --- a/js/src/yarr/YarrPattern.h +++ b/js/src/yarr/YarrPattern.h @@ -324,7 +324,7 @@ public: PatternAlternative* addNewAlternative() { - PatternAlternative* alternative = js_new(this); + PatternAlternative* alternative = newOrCrash(this); m_alternatives.append(alternative); return alternative; } diff --git a/js/src/yarr/wtfbridge.h b/js/src/yarr/wtfbridge.h index 4c100f30a2c7..0d760c9fc3a5 100644 --- a/js/src/yarr/wtfbridge.h +++ b/js/src/yarr/wtfbridge.h @@ -275,6 +275,57 @@ class JSGlobalData { */ #define UNUSED_PARAM(e) +/* + * Like SpiderMonkey's allocation templates, but with more crashing. + */ +template +T *newOrCrash() +{ + T *t = js_new(); + if (!t) + js::CrashAtUnhandlableOOM("Yarr"); + return t; +} + +template +T *newOrCrash(P1 &&p1) +{ + T *t = js_new(mozilla::Forward(p1)); + if (!t) + js::CrashAtUnhandlableOOM("Yarr"); + return t; +} + +template +T *newOrCrash(P1 &&p1, P2 &&p2) +{ + T *t = js_new(mozilla::Forward(p1), mozilla::Forward(p2)); + if (!t) + js::CrashAtUnhandlableOOM("Yarr"); + return t; +} + +template +T *newOrCrash(P1 &&p1, P2 &&p2, P3 &&p3) +{ + T *t = js_new(mozilla::Forward(p1), mozilla::Forward(p2), mozilla::Forward(p3)); + if (!t) + js::CrashAtUnhandlableOOM("Yarr"); + return t; +} + +template +T *newOrCrash(P1 &&p1, P2 &&p2, P3 &&p3, P4 &&p4) +{ + T *t = js_new(mozilla::Forward(p1), + mozilla::Forward(p2), + mozilla::Forward(p3), + mozilla::Forward(p4)); + if (!t) + js::CrashAtUnhandlableOOM("Yarr"); + return t; +} + } /* namespace Yarr */ /*