Changeset 91512 in webkit
- Timestamp:
- Jul 21, 2011, 2:58:10 PM (14 years ago)
- Location:
- branches/safari-534.51-branch
- Files:
-
- 4 edited
- 3 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/safari-534.51-branch/LayoutTests/ChangeLog
r91511 r91512 1 2011-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 1 18 2011-07-21 Lucas Forschler <lforschler@apple.com> 2 19 -
branches/safari-534.51-branch/Source/JavaScriptCore/ChangeLog
r91405 r91512 1 2011-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 1 24 2011-06-20 Lucas Forschler <lforschler@apple.com> 2 25 -
branches/safari-534.51-branch/Source/JavaScriptCore/yarr/YarrInterpreter.cpp
r87234 r91512 1752 1752 1753 1753 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 1757 1757 if (countToCheck) { 1758 1758 checkInput(countToCheck); … … 1822 1822 1823 1823 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; 1828 1828 uncheckInput(uncheckAmount); 1829 1829 currentCountAlreadyChecked -= uncheckAmount; 1830 } else 1831 uncheckAmount = 0; 1830 } 1832 1831 1833 1832 atomParentheticalAssertionBegin(term.parentheses.subpatternId, term.invert(), term.frameLocation, alternativeFrameLocation); -
branches/safari-534.51-branch/Source/JavaScriptCore/yarr/YarrJIT.cpp
r86536 r91512 1209 1209 // need to progress it forwards. 1210 1210 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); 1216 1216 } else if (op.m_nextOp == notFound) { 1217 1217 // This is the reentry point for the End of 'once through' alternatives, … … 1572 1572 m_backtrackingState.linkTo(endOp.m_reentry, this); 1573 1573 else { 1574 // Okay, we're going to need to loop. Calculate the delta between where the input1575 // position was, and where we want it to be allowing for the fact that we need to1576 // increment by 1. E.g. for the regexp /a|x/ we need to increment the position by1577 // 1 between loop iterations, but for /abcd|xyz/ we need to increment by two when1578 // looping from the last alternative to the first, for /a|xyz/ we need to decrement1579 // 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 1582 1574 // If we don't need to move the input poistion, and the pattern has a fixed size 1583 1575 // (in which case we omit the store of the start index until the pattern has matched) 1584 1576 // then we can just link the backtrack out of the last alternative straight to the 1585 1577 // 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)) 1587 1581 m_backtrackingState.linkTo(beginOp->m_reentry, this); 1588 1582 else { … … 1605 1599 } 1606 1600 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); 1619 1610 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 } 1620 1621 } 1621 1622 } … … 1641 1642 prevOp->m_jumps.link(this); 1642 1643 1643 int delta = nextOp->m_alternative->m_minimumSize - prevOp->m_alternative->m_minimumSize;1644 if (delta)1645 add32(Imm32(delta), index);1646 1647 1644 // We only get here if an input check fails, it is only worth checking again 1648 1645 // 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) { 1650 1647 // FIXME: if we added an extra label to YarrOp, we could avoid needing to 1651 1648 // subtract delta back out, and reduce this code. Should performance test 1652 1649 // the benefit of this. 1650 unsigned delta = prevOp->m_alternative->m_minimumSize - nextOp->m_alternative->m_minimumSize; 1651 sub32(Imm32(delta), index); 1653 1652 Jump fail = jumpIfNoAvailableInput(); 1654 sub32(Imm32(delta), index);1653 add32(Imm32(delta), index); 1655 1654 jump(nextOp->m_reentry); 1656 1655 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); 1658 1658 prevOp = nextOp; 1659 1659 nextOp = &m_ops[nextOp->m_nextOp]; … … 1689 1689 // is no point in looping if we're just going to fail all the input checks around 1690 1690 // 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 } 1694 1703 Jump matchFailed = jumpIfNoAvailableInput(); 1695 1704 … … 1707 1716 // for the body as a whole. If no more is needed then we dont need an additional 1708 1717 // 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) 1711 1719 jump(beginOp->m_reentry); 1712 1720 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); 1714 1725 checkInput().linkTo(beginOp->m_reentry, this); 1715 1726 jump(firstInputCheckFailed);
Note:
See TracChangeset
for help on using the changeset viewer.