Changeset 196721 in webkit
- Timestamp:
- Feb 17, 2016 2:03:56 PM (8 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r196704 r196721 1 2016-02-17 Mark Lam <mark.lam@apple.com> 2 3 StringPrototype functions should check for exceptions after calling JSString::value(). 4 https://bugs.webkit.org/show_bug.cgi?id=154340 5 6 Reviewed by Filip Pizlo. 7 8 JSString::value() can throw an exception if the JS string is a rope and value() 9 needs to resolve the rope but encounters an OutOfMemory error. If value() is not 10 able to resolve the rope, it will return a null string (in addition to throwing 11 the exception). If StringPrototype functions do not check for exceptions after 12 calling JSString::value(), they may eventually use the returned null string and 13 crash the VM. 14 15 The fix is to add all the necessary exception checks, and do the appropriate 16 handling if needed. 17 18 Also in a few place where when an exception is detected, we return JSValue(), I 19 changed it to return jsUndefined() instead to be consistent with the rest of the 20 file. 21 22 * runtime/StringPrototype.cpp: 23 (JSC::replaceUsingRegExpSearch): 24 (JSC::stringProtoFuncMatch): 25 (JSC::stringProtoFuncSlice): 26 (JSC::stringProtoFuncSplit): 27 (JSC::stringProtoFuncLocaleCompare): 28 (JSC::stringProtoFuncBig): 29 (JSC::stringProtoFuncSmall): 30 (JSC::stringProtoFuncBlink): 31 (JSC::stringProtoFuncBold): 32 (JSC::stringProtoFuncFixed): 33 (JSC::stringProtoFuncItalics): 34 (JSC::stringProtoFuncStrike): 35 (JSC::stringProtoFuncSub): 36 (JSC::stringProtoFuncSup): 37 (JSC::stringProtoFuncFontcolor): 38 (JSC::stringProtoFuncFontsize): 39 (JSC::stringProtoFuncAnchor): 40 (JSC::stringProtoFuncLink): 41 (JSC::trimString): 42 1 43 2016-02-17 Commit Queue <commit-queue@webkit.org> 2 44 -
trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp
r196547 r196721 491 491 CallData callData; 492 492 CallType callType = getCallData(replaceValue, callData); 493 if (callType == CallTypeNone) 493 if (callType == CallTypeNone) { 494 494 replacementString = replaceValue.toString(exec)->value(exec); 495 if (exec->hadException()) 496 return JSValue::encode(jsUndefined()); 497 } 495 498 496 499 const String& source = string->value(exec); 497 500 unsigned sourceLen = source.length(); 498 501 if (exec->hadException()) 499 return JSValue::encode( JSValue());502 return JSValue::encode(jsUndefined()); 500 503 RegExpObject* regExpObject = asRegExpObject(searchValue); 501 504 RegExp* regExp = regExpObject->regExp(); … … 506 509 regExpObject->setLastIndex(exec, 0); 507 510 if (exec->hadException()) 508 return JSValue::encode( JSValue());511 return JSValue::encode(jsUndefined()); 509 512 510 513 if (callType == CallTypeNone && !replacementString.length()) … … 527 530 CachedCall cachedCall(exec, func, argCount); 528 531 if (exec->hadException()) 529 return JSValue::encode(js Null());532 return JSValue::encode(jsUndefined()); 530 533 VM* vm = &exec->vm(); 531 534 if (source.is8Bit()) { … … 556 559 replacements.append(jsResult.toString(exec)->value(exec)); 557 560 if (exec->hadException()) 558 break;561 return JSValue::encode(jsUndefined()); 559 562 560 563 lastIndex = result.end; … … 595 598 replacements.append(jsResult.toString(exec)->value(exec)); 596 599 if (exec->hadException()) 597 break;600 return JSValue::encode(jsUndefined()); 598 601 599 602 lastIndex = result.end; … … 636 639 replacements.append(call(exec, replaceValue, callType, callData, jsUndefined(), args).toString(exec)->value(exec)); 637 640 if (exec->hadException()) 638 break;641 return JSValue::encode(jsUndefined()); 639 642 } else { 640 643 int replLen = replacementString.length(); … … 991 994 regExpObject->setLastIndex(exec, 0); 992 995 if (exec->hadException()) 993 return JSValue::encode( JSValue());996 return JSValue::encode(jsUndefined()); 994 997 } 995 998 } else { … … 1000 1003 * Per ECMA 15.10.4.1, if a0 is undefined substitute the empty string. 1001 1004 */ 1002 regExp = RegExp::create(exec->vm(), a0.isUndefined() ? emptyString() : a0.toString(exec)->value(exec), NoFlags); 1005 String patternString = emptyString(); 1006 if (!a0.isUndefined()) { 1007 patternString = a0.toString(exec)->value(exec); 1008 if (exec->hadException()) 1009 return JSValue::encode(jsUndefined()); 1010 } 1011 regExp = RegExp::create(exec->vm(), patternString, NoFlags); 1003 1012 if (!regExp->isValid()) 1004 1013 return throwVMError(exec, createSyntaxError(exec, regExp->errorMessage())); … … 1043 1052 return throwVMTypeError(exec); 1044 1053 String s = thisValue.toString(exec)->value(exec); 1054 if (exec->hadException()) 1055 return JSValue::encode(jsUndefined()); 1056 1045 1057 int len = s.length(); 1046 1058 RELEASE_ASSERT(len >= 0); … … 1105 1117 // 6. Let s be the number of characters in S. 1106 1118 String input = thisValue.toString(exec)->value(exec); 1119 if (exec->hadException()) 1120 return JSValue::encode(jsUndefined()); 1121 ASSERT(!input.isNull()); 1107 1122 1108 1123 // 3. Let A be a new array created as if by the expression new Array() … … 1231 1246 } else { 1232 1247 String separator = separatorValue.toString(exec)->value(exec); 1248 if (exec->hadException()) 1249 return JSValue::encode(jsUndefined()); 1233 1250 1234 1251 // 9. If lim == 0, return A. … … 1440 1457 return throwVMTypeError(exec); 1441 1458 String s = thisValue.toString(exec)->value(exec); 1459 if (exec->hadException()) 1460 return JSValue::encode(jsUndefined()); 1442 1461 1443 1462 JSValue a0 = exec->argument(0); 1444 return JSValue::encode(jsNumber(Collator().collate(s, a0.toString(exec)->value(exec)))); 1463 String str = a0.toString(exec)->value(exec); 1464 if (exec->hadException()) 1465 return JSValue::encode(jsUndefined()); 1466 return JSValue::encode(jsNumber(Collator().collate(s, str))); 1445 1467 } 1446 1468 … … 1550 1572 return throwVMTypeError(exec); 1551 1573 String s = thisValue.toString(exec)->value(exec); 1574 if (exec->hadException()) 1575 return JSValue::encode(jsUndefined()); 1552 1576 return JSValue::encode(jsMakeNontrivialString(exec, "<big>", s, "</big>")); 1553 1577 } … … 1559 1583 return throwVMTypeError(exec); 1560 1584 String s = thisValue.toString(exec)->value(exec); 1585 if (exec->hadException()) 1586 return JSValue::encode(jsUndefined()); 1561 1587 return JSValue::encode(jsMakeNontrivialString(exec, "<small>", s, "</small>")); 1562 1588 } … … 1568 1594 return throwVMTypeError(exec); 1569 1595 String s = thisValue.toString(exec)->value(exec); 1596 if (exec->hadException()) 1597 return JSValue::encode(jsUndefined()); 1570 1598 return JSValue::encode(jsMakeNontrivialString(exec, "<blink>", s, "</blink>")); 1571 1599 } … … 1577 1605 return throwVMTypeError(exec); 1578 1606 String s = thisValue.toString(exec)->value(exec); 1607 if (exec->hadException()) 1608 return JSValue::encode(jsUndefined()); 1579 1609 return JSValue::encode(jsMakeNontrivialString(exec, "<b>", s, "</b>")); 1580 1610 } … … 1586 1616 return throwVMTypeError(exec); 1587 1617 String s = thisValue.toString(exec)->value(exec); 1618 if (exec->hadException()) 1619 return JSValue::encode(jsUndefined()); 1588 1620 return JSValue::encode(jsMakeNontrivialString(exec, "<tt>", s, "</tt>")); 1589 1621 } … … 1595 1627 return throwVMTypeError(exec); 1596 1628 String s = thisValue.toString(exec)->value(exec); 1629 if (exec->hadException()) 1630 return JSValue::encode(jsUndefined()); 1597 1631 return JSValue::encode(jsMakeNontrivialString(exec, "<i>", s, "</i>")); 1598 1632 } … … 1604 1638 return throwVMTypeError(exec); 1605 1639 String s = thisValue.toString(exec)->value(exec); 1640 if (exec->hadException()) 1641 return JSValue::encode(jsUndefined()); 1606 1642 return JSValue::encode(jsMakeNontrivialString(exec, "<strike>", s, "</strike>")); 1607 1643 } … … 1613 1649 return throwVMTypeError(exec); 1614 1650 String s = thisValue.toString(exec)->value(exec); 1651 if (exec->hadException()) 1652 return JSValue::encode(jsUndefined()); 1615 1653 return JSValue::encode(jsMakeNontrivialString(exec, "<sub>", s, "</sub>")); 1616 1654 } … … 1622 1660 return throwVMTypeError(exec); 1623 1661 String s = thisValue.toString(exec)->value(exec); 1662 if (exec->hadException()) 1663 return JSValue::encode(jsUndefined()); 1624 1664 return JSValue::encode(jsMakeNontrivialString(exec, "<sup>", s, "</sup>")); 1625 1665 } … … 1631 1671 return throwVMTypeError(exec); 1632 1672 String s = thisValue.toString(exec)->value(exec); 1673 if (exec->hadException()) 1674 return JSValue::encode(jsUndefined()); 1675 1633 1676 JSValue a0 = exec->argument(0); 1634 1677 String color = a0.toWTFString(exec); … … 1644 1687 return throwVMTypeError(exec); 1645 1688 String s = thisValue.toString(exec)->value(exec); 1689 if (exec->hadException()) 1690 return JSValue::encode(jsUndefined()); 1691 1646 1692 JSValue a0 = exec->argument(0); 1647 1693 … … 1693 1739 return throwVMTypeError(exec); 1694 1740 String s = thisValue.toString(exec)->value(exec); 1741 if (exec->hadException()) 1742 return JSValue::encode(jsUndefined()); 1743 1695 1744 JSValue a0 = exec->argument(0); 1696 1745 String anchor = a0.toWTFString(exec); … … 1706 1755 return throwVMTypeError(exec); 1707 1756 String s = thisValue.toString(exec)->value(exec); 1757 if (exec->hadException()) 1758 return JSValue::encode(jsUndefined()); 1759 1708 1760 JSValue a0 = exec->argument(0); 1709 1761 String linkText = a0.toWTFString(exec); … … 1748 1800 return throwTypeError(exec); 1749 1801 String str = thisValue.toString(exec)->value(exec); 1802 if (exec->hadException()) 1803 return jsUndefined(); 1804 1750 1805 unsigned left = 0; 1751 1806 if (trimKind & TrimLeft) {
Note: See TracChangeset
for help on using the changeset viewer.