Changeset 91512 in webkit


Ignore:
Timestamp:
Jul 21, 2011, 2:58:10 PM (14 years ago)
Author:
Lucas Forschler
Message:

Merge r89614.

Location:
branches/safari-534.51-branch
Files:
4 edited
3 copied

Legend:

Unmodified
Added
Removed
  • branches/safari-534.51-branch/LayoutTests/ChangeLog

    r91511 r91512  
     12011-07-21  Lucas Forschler  <lforschler@apple.com>
     2
     3    Merged 89614.
     4
     5    2011-06-23  Gavin Barraclough  <barraclough@apple.com>
     6
     7        Reviewed by Oliver Hunt.
     8
     9        https://bugs.webkit.org/show_bug.cgi?id=61585
     10        Crash running regexp /(?:(?=g))|(?:m).{2147483648,}/
     11
     12        Add regression tests where an alterative has a size of ~2^31.
     13
     14        * fast/regex/overflow-expected.txt: Added.
     15        * fast/regex/overflow.html: Added.
     16        * fast/regex/script-tests/overflow.js: Added.
     17
    1182011-07-21  Lucas Forschler  <lforschler@apple.com>
    219
  • branches/safari-534.51-branch/Source/JavaScriptCore/ChangeLog

    r91405 r91512  
     12011-07-21  Lucas Forschler  <lforschler@apple.com>
     2
     3    Merged 89614.
     4
     5    2011-06-23  Gavin Barraclough  <barraclough@apple.com>
     6
     7        Reviewed by Oliver Hunt.
     8
     9        https://bugs.webkit.org/show_bug.cgi?id=61585
     10        Crash running regexp /(?:(?=g))|(?:m).{2147483648,}/
     11
     12        This is due to use of int instead of unsigned, bad math around
     13        the 2^31 boundary.
     14
     15        * yarr/YarrInterpreter.cpp:
     16        (JSC::Yarr::ByteCompiler::emitDisjunction):
     17            - Change some uses of int to unsigned, refactor compare logic to
     18              restrict to the range 0..2^32-1 (rather than -2^32-1..2^32-1).
     19        * yarr/YarrJIT.cpp:
     20        (JSC::Yarr::YarrGenerator::generate):
     21        (JSC::Yarr::YarrGenerator::backtrack):
     22            - Ditto.
     23
    1242011-06-20  Lucas Forschler  <lforschler@apple.com>
    225
  • branches/safari-534.51-branch/Source/JavaScriptCore/yarr/YarrInterpreter.cpp

    r87234 r91512  
    17521752
    17531753            unsigned minimumSize = alternative->m_minimumSize;
    1754             int countToCheck = minimumSize - parenthesesInputCountAlreadyChecked;
    1755 
    1756             ASSERT(countToCheck >= 0);
     1754            ASSERT(minimumSize >= parenthesesInputCountAlreadyChecked);
     1755            unsigned countToCheck = minimumSize - parenthesesInputCountAlreadyChecked;
     1756
    17571757            if (countToCheck) {
    17581758                checkInput(countToCheck);
     
    18221822
    18231823                    ASSERT(currentCountAlreadyChecked >= static_cast<unsigned>(term.inputPosition));
    1824                     int positiveInputOffset = currentCountAlreadyChecked - term.inputPosition;
    1825                     int uncheckAmount = positiveInputOffset - term.parentheses.disjunction->m_minimumSize;
    1826 
    1827                     if (uncheckAmount > 0) {
     1824                    unsigned positiveInputOffset = currentCountAlreadyChecked - static_cast<unsigned>(term.inputPosition);
     1825                    unsigned uncheckAmount = 0;
     1826                    if (positiveInputOffset > term.parentheses.disjunction->m_minimumSize) {
     1827                        uncheckAmount = positiveInputOffset - term.parentheses.disjunction->m_minimumSize;
    18281828                        uncheckInput(uncheckAmount);
    18291829                        currentCountAlreadyChecked -= uncheckAmount;
    1830                     } else
    1831                         uncheckAmount = 0;
     1830                    }
    18321831
    18331832                    atomParentheticalAssertionBegin(term.parentheses.subpatternId, term.invert(), term.frameLocation, alternativeFrameLocation);
  • branches/safari-534.51-branch/Source/JavaScriptCore/yarr/YarrJIT.cpp

    r86536 r91512  
    12091209                    // need to progress it forwards.
    12101210                    op.m_reentry = label();
    1211                     if (int delta = alternative->m_minimumSize - priorAlternative->m_minimumSize) {
    1212                         add32(Imm32(delta), index);
    1213                         if (delta > 0)
    1214                             op.m_jumps.append(jumpIfNoAvailableInput());
    1215                     }
     1211                    if (alternative->m_minimumSize > priorAlternative->m_minimumSize) {
     1212                        add32(Imm32(alternative->m_minimumSize - priorAlternative->m_minimumSize), index);
     1213                        op.m_jumps.append(jumpIfNoAvailableInput());
     1214                    } else if (priorAlternative->m_minimumSize > alternative->m_minimumSize)
     1215                        sub32(Imm32(priorAlternative->m_minimumSize - alternative->m_minimumSize), index);
    12161216                } else if (op.m_nextOp == notFound) {
    12171217                    // This is the reentry point for the End of 'once through' alternatives,
     
    15721572                    m_backtrackingState.linkTo(endOp.m_reentry, this);
    15731573                else {
    1574                     // Okay, we're going to need to loop. Calculate the delta between where the input
    1575                     // position was, and where we want it to be allowing for the fact that we need to
    1576                     // increment by 1. E.g. for the regexp /a|x/ we need to increment the position by
    1577                     // 1 between loop iterations, but for /abcd|xyz/ we need to increment by two when
    1578                     // looping from the last alternative to the first, for /a|xyz/ we need to decrement
    1579                     // by 1, and for /a|xy/ we don't need to move the input position at all.
    1580                     int deltaLastAlternativeToFirstAlternativePlusOne = (beginOp->m_alternative->m_minimumSize - alternative->m_minimumSize) + 1;
    1581 
    15821574                    // If we don't need to move the input poistion, and the pattern has a fixed size
    15831575                    // (in which case we omit the store of the start index until the pattern has matched)
    15841576                    // then we can just link the backtrack out of the last alternative straight to the
    15851577                    // head of the first alternative.
    1586                     if (!deltaLastAlternativeToFirstAlternativePlusOne && m_pattern.m_body->m_hasFixedSize)
     1578                    if (m_pattern.m_body->m_hasFixedSize
     1579                        && (alternative->m_minimumSize > beginOp->m_alternative->m_minimumSize)
     1580                        && (alternative->m_minimumSize - beginOp->m_alternative->m_minimumSize == 1))
    15871581                        m_backtrackingState.linkTo(beginOp->m_reentry, this);
    15881582                    else {
     
    16051599                        }
    16061600
    1607                         if (deltaLastAlternativeToFirstAlternativePlusOne)
    1608                             add32(Imm32(deltaLastAlternativeToFirstAlternativePlusOne), index);
    1609 
    1610                         // Loop. Since this code is only reached when we backtrack out of the last
    1611                         // alternative (and NOT linked to from the input check upon entry to the
    1612                         // last alternative) we know that there must be at least enough input as
    1613                         // required by the last alternative. As such, we only need to check if the
    1614                         // first will require more to run - if the same or less is required we can
    1615                         // unconditionally jump.
    1616                         if (deltaLastAlternativeToFirstAlternativePlusOne > 0)
    1617                             checkInput().linkTo(beginOp->m_reentry, this);
    1618                         else
     1601                        // Generate code to loop. Check whether the last alternative is longer than the
     1602                        // first (e.g. /a|xy/ or /a|xyz/).
     1603                        if (alternative->m_minimumSize > beginOp->m_alternative->m_minimumSize) {
     1604                            // We want to loop, and increment input position. If the delta is 1, it is
     1605                            // already correctly incremented, if more than one then decrement as appropriate.
     1606                            unsigned delta = alternative->m_minimumSize - beginOp->m_alternative->m_minimumSize;
     1607                            ASSERT(delta);
     1608                            if (delta != 1)
     1609                                sub32(Imm32(delta - 1), index);
    16191610                            jump(beginOp->m_reentry);
     1611                        } else {
     1612                            // If the first alternative has minimum size 0xFFFFFFFFu, then there cannot
     1613                            // be sufficent input available to handle this, so just fall through.
     1614                            unsigned delta = beginOp->m_alternative->m_minimumSize - alternative->m_minimumSize;
     1615                            if (delta != 0xFFFFFFFFu) {
     1616                                // We need to check input because we are incrementing the input.
     1617                                add32(Imm32(delta + 1), index);
     1618                                checkInput().linkTo(beginOp->m_reentry, this);
     1619                            }
     1620                        }
    16201621                    }
    16211622                }
     
    16411642                    prevOp->m_jumps.link(this);
    16421643
    1643                     int delta = nextOp->m_alternative->m_minimumSize - prevOp->m_alternative->m_minimumSize;
    1644                     if (delta)
    1645                         add32(Imm32(delta), index);
    1646 
    16471644                    // We only get here if an input check fails, it is only worth checking again
    16481645                    // if the next alternative has a minimum size less than the last.
    1649                     if (delta < 0) {
     1646                    if (prevOp->m_alternative->m_minimumSize > nextOp->m_alternative->m_minimumSize) {
    16501647                        // FIXME: if we added an extra label to YarrOp, we could avoid needing to
    16511648                        // subtract delta back out, and reduce this code. Should performance test
    16521649                        // the benefit of this.
     1650                        unsigned delta = prevOp->m_alternative->m_minimumSize - nextOp->m_alternative->m_minimumSize;
     1651                        sub32(Imm32(delta), index);
    16531652                        Jump fail = jumpIfNoAvailableInput();
    1654                         sub32(Imm32(delta), index);
     1653                        add32(Imm32(delta), index);
    16551654                        jump(nextOp->m_reentry);
    16561655                        fail.link(this);
    1657                     }
     1656                    } else if (prevOp->m_alternative->m_minimumSize < nextOp->m_alternative->m_minimumSize)
     1657                        add32(Imm32(nextOp->m_alternative->m_minimumSize - prevOp->m_alternative->m_minimumSize), index);
    16581658                    prevOp = nextOp;
    16591659                    nextOp = &m_ops[nextOp->m_nextOp];
     
    16891689                // is no point in looping if we're just going to fail all the input checks around
    16901690                // the next iteration.
    1691                 int deltaLastAlternativeToBodyMinimumPlusOne = (m_pattern.m_body->m_minimumSize + 1) - alternative->m_minimumSize;
    1692                 if (deltaLastAlternativeToBodyMinimumPlusOne)
    1693                     add32(Imm32(deltaLastAlternativeToBodyMinimumPlusOne), index);
     1691                ASSERT(alternative->m_minimumSize >= m_pattern.m_body->m_minimumSize);
     1692                if (alternative->m_minimumSize == m_pattern.m_body->m_minimumSize) {
     1693                    // If the last alternative had the same minimum size as the disjunction,
     1694                    // just simply increment input pos by 1, no adjustment based on minimum size.
     1695                    add32(Imm32(1), index);
     1696                } else {
     1697                    // If the minumum for the last alternative was one greater than than that
     1698                    // for the disjunction, we're already progressed by 1, nothing to do!
     1699                    unsigned delta = (alternative->m_minimumSize - m_pattern.m_body->m_minimumSize) - 1;
     1700                    if (delta)
     1701                        sub32(Imm32(delta), index);
     1702                }
    16941703                Jump matchFailed = jumpIfNoAvailableInput();
    16951704
     
    17071716                // for the body as a whole. If no more is needed then we dont need an additional
    17081717                // input check here - jump straight back up to the start of the first alternative.
    1709                 int deltaBodyMinimumToFirstAlternative = beginOp->m_alternative->m_minimumSize - m_pattern.m_body->m_minimumSize;
    1710                 if (!deltaBodyMinimumToFirstAlternative)
     1718                if (beginOp->m_alternative->m_minimumSize == m_pattern.m_body->m_minimumSize)
    17111719                    jump(beginOp->m_reentry);
    17121720                else {
    1713                     add32(Imm32(deltaBodyMinimumToFirstAlternative), index);
     1721                    if (beginOp->m_alternative->m_minimumSize > m_pattern.m_body->m_minimumSize)
     1722                        add32(Imm32(beginOp->m_alternative->m_minimumSize - m_pattern.m_body->m_minimumSize), index);
     1723                    else
     1724                        sub32(Imm32(m_pattern.m_body->m_minimumSize - beginOp->m_alternative->m_minimumSize), index);
    17141725                    checkInput().linkTo(beginOp->m_reentry, this);
    17151726                    jump(firstInputCheckFailed);
Note: See TracChangeset for help on using the changeset viewer.