Changeset 208966 in webkit
- Timestamp:
- Nov 22, 2016 11:16:55 AM (7 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r208957 r208966 1 2016-11-22 Mark Lam <mark.lam@apple.com> 2 3 Fix exception scope verification failures in JSONObject.cpp. 4 https://bugs.webkit.org/show_bug.cgi?id=165025 5 6 Reviewed by Saam Barati. 7 8 * runtime/JSONObject.cpp: 9 (JSC::gap): 10 (JSC::Stringifier::Stringifier): 11 (JSC::Stringifier::stringify): 12 (JSC::Stringifier::toJSON): 13 (JSC::Stringifier::appendStringifiedValue): 14 (JSC::Stringifier::Holder::appendNextProperty): 15 (JSC::Walker::walk): 16 (JSC::JSONProtoFuncParse): 17 (JSC::JSONProtoFuncStringify): 18 (JSC::JSONStringify): 19 1 20 2016-11-21 Mark Lam <mark.lam@apple.com> 2 21 -
trunk/Source/JavaScriptCore/runtime/JSONObject.cpp
r208767 r208966 131 131 CallType m_replacerCallType; 132 132 CallData m_replacerCallData; 133 constString m_gap;133 String m_gap; 134 134 135 135 Vector<Holder, 16, UnsafeVectorOverflow> m_holderStack; … … 159 159 static inline String gap(ExecState* exec, JSValue space) 160 160 { 161 VM& vm = exec->vm(); 162 auto scope = DECLARE_THROW_SCOPE(vm); 163 161 164 const unsigned maxGapLength = 10; 162 165 space = unwrapBoxedPrimitive(exec, space); 166 RETURN_IF_EXCEPTION(scope, { }); 163 167 164 168 // If the space value is a number, create a gap string with that number of spaces. … … 222 226 , m_arrayReplacerPropertyNames(exec, PropertyNameMode::Strings) 223 227 , m_replacerCallType(CallType::None) 224 , m_gap(gap(exec, space.get()))225 228 { 226 229 VM& vm = exec->vm(); 227 230 auto scope = DECLARE_THROW_SCOPE(vm); 231 232 m_gap = gap(exec, space.get()); 233 if (UNLIKELY(scope.exception())) 234 return; 235 228 236 if (!m_replacer.isObject()) 229 237 return; … … 233 241 Handle<JSObject> array = m_replacer.asObject(); 234 242 unsigned length = array->get(exec, vm.propertyNames->length).toUInt32(exec); 243 if (UNLIKELY(scope.exception())) 244 return; 235 245 for (unsigned i = 0; i < length; ++i) { 236 246 JSValue name = array->get(exec, i); … … 264 274 StringBuilder result; 265 275 Holder root(Holder::RootHolder, vm, object); 266 if (appendStringifiedValue(result, value.get(), root, emptyPropertyName) != StringifySucceeded) 276 auto stringifyResult = appendStringifiedValue(result, value.get(), root, emptyPropertyName); 277 ASSERT(!scope.exception() || (stringifyResult != StringifySucceeded)); 278 if (UNLIKELY(stringifyResult != StringifySucceeded)) 267 279 return Local<Unknown>(vm, jsUndefined()); 268 RETURN_IF_EXCEPTION(scope, Local<Unknown>(vm, jsNull())); 269 280 281 scope.release(); 270 282 return Local<Unknown>(vm, jsString(m_exec, result.toString())); 271 283 } … … 281 293 JSObject* object = asObject(value); 282 294 PropertySlot slot(object, PropertySlot::InternalMethodType::Get); 283 if (!object->getPropertySlot(m_exec, vm.propertyNames->toJSON, slot)) 295 bool hasProperty = object->getPropertySlot(m_exec, vm.propertyNames->toJSON, slot); 296 ASSERT(!scope.exception() || !hasProperty); 297 if (!hasProperty) 284 298 return value; 285 299 286 300 JSValue toJSONFunction = slot.getValue(m_exec, vm.propertyNames->toJSON); 287 RETURN_IF_EXCEPTION(scope, JSValue()); 301 RETURN_IF_EXCEPTION(scope, { }); 302 scope.release(); 288 303 return toJSONImpl(value, toJSONFunction, propertyName); 289 304 } … … 388 403 while (m_holderStack.last().appendNextProperty(*this, builder)) 389 404 RETURN_IF_EXCEPTION(scope, StringifyFailed); 405 RETURN_IF_EXCEPTION(scope, StringifyFailed); 390 406 m_holderStack.removeLast(); 391 407 } while (!m_holderStack.isEmpty()); … … 458 474 m_size = asArray(m_object.get())->length(); 459 475 else { 460 m_size = m_object->get(exec, vm.propertyNames->length).toUInt32(exec); 476 JSValue value = m_object->get(exec, vm.propertyNames->length); 477 RETURN_IF_EXCEPTION(scope, false); 478 m_size = value.toUInt32(exec); 461 479 RETURN_IF_EXCEPTION(scope, false); 462 480 } … … 537 555 stringifyResult = stringifier.appendStringifiedValue(builder, value, *this, propertyName); 538 556 } 557 RETURN_IF_EXCEPTION(scope, false); 539 558 540 559 // From this point on, no access to the this pointer or to any members, because the … … 654 673 else 655 674 inValue = jsUndefined(); 656 RETURN_IF_EXCEPTION(scope, JSValue());675 RETURN_IF_EXCEPTION(scope, { }); 657 676 } 658 677 … … 667 686 JSArray* array = arrayStack.peek(); 668 687 JSValue filteredValue = callReviver(array, jsString(m_exec, String::number(indexStack.last())), outValue); 688 RETURN_IF_EXCEPTION(scope, { }); 669 689 if (filteredValue.isUndefined()) 670 690 array->methodTable(vm)->deletePropertyByIndex(array, m_exec, indexStack.last()); 671 691 else 672 692 array->putDirectIndex(m_exec, indexStack.last(), filteredValue, 0, PutDirectIndexShouldNotThrow); 673 RETURN_IF_EXCEPTION(scope, JSValue());693 RETURN_IF_EXCEPTION(scope, { }); 674 694 indexStack.last()++; 675 695 goto arrayStartVisitMember; … … 687 707 propertyStack.append(PropertyNameArray(m_exec, PropertyNameMode::Strings)); 688 708 object->methodTable(vm)->getOwnPropertyNames(object, m_exec, propertyStack.last(), EnumerationMode()); 689 RETURN_IF_EXCEPTION(scope, JSValue());709 RETURN_IF_EXCEPTION(scope, { }); 690 710 } 691 711 objectStartVisitMember: … … 709 729 710 730 // The holder may be modified by the reviver function so any lookup may throw 711 RETURN_IF_EXCEPTION(scope, JSValue());731 RETURN_IF_EXCEPTION(scope, { }); 712 732 713 733 if (inValue.isObject()) { … … 723 743 PutPropertySlot slot(object); 724 744 JSValue filteredValue = callReviver(object, jsString(m_exec, prop.string()), outValue); 745 RETURN_IF_EXCEPTION(scope, { }); 725 746 if (filteredValue.isUndefined()) 726 747 object->methodTable(vm)->deleteProperty(object, m_exec, prop); 727 748 else 728 749 object->methodTable(vm)->put(object, m_exec, prop, filteredValue, slot); 729 RETURN_IF_EXCEPTION(scope, JSValue());750 RETURN_IF_EXCEPTION(scope, { }); 730 751 indexStack.last()++; 731 752 goto objectStartVisitMember; … … 751 772 PutPropertySlot slot(finalHolder); 752 773 finalHolder->methodTable(vm)->put(finalHolder, m_exec, vm.propertyNames->emptyIdentifier, outValue, slot); 774 RETURN_IF_EXCEPTION(scope, { }); 775 scope.release(); 753 776 return callReviver(finalHolder, jsEmptyString(m_exec), outValue); 754 777 } … … 763 786 return throwVMError(exec, scope, createError(exec, ASCIILiteral("JSON.parse requires at least one parameter"))); 764 787 auto viewWithString = exec->uncheckedArgument(0).toString(exec)->viewWithUnderlyingString(*exec); 765 RETURN_IF_EXCEPTION(scope, encodedJSValue());788 RETURN_IF_EXCEPTION(scope, { }); 766 789 StringView view = viewWithString.view; 767 790 … … 771 794 LiteralParser<LChar> jsonParser(exec, view.characters8(), view.length(), StrictJSON); 772 795 unfiltered = jsonParser.tryLiteralParse(); 773 if (!unfiltered) 796 ASSERT(!scope.exception() || !unfiltered); 797 if (!unfiltered) { 798 RETURN_IF_EXCEPTION(scope, { }); 774 799 return throwVMError(exec, scope, createSyntaxError(exec, jsonParser.getErrorMessage())); 800 } 775 801 } else { 776 802 LiteralParser<UChar> jsonParser(exec, view.characters16(), view.length(), StrictJSON); 777 803 unfiltered = jsonParser.tryLiteralParse(); 778 if (!unfiltered) 804 ASSERT(!scope.exception() || !unfiltered); 805 if (!unfiltered) { 806 RETURN_IF_EXCEPTION(scope, { }); 779 807 return throwVMError(exec, scope, createSyntaxError(exec, jsonParser.getErrorMessage())); 808 } 780 809 } 781 810 … … 788 817 if (callType == CallType::None) 789 818 return JSValue::encode(unfiltered); 819 scope.release(); 790 820 return JSValue::encode(Walker(exec, Local<JSObject>(vm, asObject(function)), callType, callData).walk(unfiltered)); 791 821 } … … 803 833 Local<Unknown> replacer(vm, exec->argument(1)); 804 834 Local<Unknown> space(vm, exec->argument(2)); 805 JSValue result = Stringifier(exec, replacer, space).stringify(value).get(); 835 Stringifier stringifier(exec, replacer, space); 836 RETURN_IF_EXCEPTION(scope, { }); 837 scope.release(); 838 JSValue result = stringifier.stringify(value).get(); 806 839 return JSValue::encode(result); 807 840 } … … 825 858 String JSONStringify(ExecState* exec, JSValue value, unsigned indent) 826 859 { 827 LocalScope scope(exec->vm()); 828 Local<Unknown> result = Stringifier(exec, Local<Unknown>(exec->vm(), jsNull()), Local<Unknown>(exec->vm(), jsNumber(indent))).stringify(Local<Unknown>(exec->vm(), value)); 829 if (result.isUndefinedOrNull()) 860 VM& vm = exec->vm(); 861 auto throwScope = DECLARE_THROW_SCOPE(vm); 862 LocalScope scope(vm); 863 Stringifier stringifier(exec, Local<Unknown>(vm, jsNull()), Local<Unknown>(vm, jsNumber(indent))); 864 RETURN_IF_EXCEPTION(throwScope, { }); 865 Local<Unknown> result = stringifier.stringify(Local<Unknown>(vm, value)); 866 if (UNLIKELY(throwScope.exception()) || result.isUndefinedOrNull()) 830 867 return String(); 831 868 return result.getString(exec);
Note: See TracChangeset
for help on using the changeset viewer.