Changeset 208699 in webkit
- Timestamp:
- Nov 14, 2016, 11:42:41 AM (9 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r208698 r208699 1 2016-11-14 Mark Lam <mark.lam@apple.com> 2 3 Some of JSStringView::SafeView methods are not idiomatically safe for JSString to StringView conversions. 4 https://bugs.webkit.org/show_bug.cgi?id=164701 5 <rdar://problem/27462104> 6 7 Reviewed by Darin Adler. 8 9 * stress/string-prototype-charCodeAt-on-too-long-rope.js: Added. 10 1 11 2016-11-14 Mark Lam <mark.lam@apple.com> 2 12 -
trunk/Source/JavaScriptCore/ChangeLog
r208698 r208699 1 2016-11-14 Mark Lam <mark.lam@apple.com> 2 3 Some of JSStringView::SafeView methods are not idiomatically safe for JSString to StringView conversions. 4 https://bugs.webkit.org/show_bug.cgi?id=164701 5 <rdar://problem/27462104> 6 7 Reviewed by Darin Adler. 8 9 The characters8(), characters16(), and operator[] in JSString::SafeView converts 10 the underlying JSString to a StringView via get(), and then uses the StringView 11 without first checking if an exception was thrown during the conversion. This is 12 unsafe because the conversion may have failed. 13 14 Instead, we should remove these 3 convenience methods, and make the caller 15 explicitly call get() and do the appropriate exception checks before using the 16 StringView. 17 18 * runtime/JSGlobalObjectFunctions.cpp: 19 (JSC::toStringView): 20 (JSC::encode): 21 (JSC::decode): 22 (JSC::globalFuncParseInt): 23 (JSC::globalFuncEscape): 24 (JSC::globalFuncUnescape): 25 (JSC::toSafeView): Deleted. 26 * runtime/JSONObject.cpp: 27 (JSC::JSONProtoFuncParse): 28 * runtime/JSString.h: 29 (JSC::JSString::SafeView::length): 30 (JSC::JSString::SafeView::characters8): Deleted. 31 (JSC::JSString::SafeView::characters16): Deleted. 32 (JSC::JSString::SafeView::operator[]): Deleted. 33 * runtime/StringPrototype.cpp: 34 (JSC::stringProtoFuncRepeatCharacter): 35 (JSC::stringProtoFuncCharAt): 36 (JSC::stringProtoFuncCharCodeAt): 37 (JSC::stringProtoFuncNormalize): 38 1 39 2016-11-14 Mark Lam <mark.lam@apple.com> 2 40 -
trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
r208074 r208699 58 58 59 59 template<typename CallbackWhenNoException> 60 static ALWAYS_INLINE typename std::result_of<CallbackWhenNoException(JSString::SafeView&)>::type toSafeView(ExecState* exec, JSValue value, CallbackWhenNoException callback) 61 { 60 static ALWAYS_INLINE typename std::result_of<CallbackWhenNoException(StringView)>::type toStringView(ExecState* exec, JSValue value, CallbackWhenNoException callback) 61 { 62 VM& vm = exec->vm(); 63 auto scope = DECLARE_THROW_SCOPE(vm); 62 64 JSString* string = value.toStringOrNull(exec); 63 65 if (UNLIKELY(!string)) 64 66 return { }; 65 67 JSString::SafeView view = string->view(exec); 66 return callback(view); 68 StringView stringView = view.get(); 69 RETURN_IF_EXCEPTION(scope, { }); 70 return callback(stringView); 67 71 } 68 72 … … 159 163 static JSValue encode(ExecState* exec, const Bitmap<256>& doNotEscape) 160 164 { 161 return toS afeView(exec, exec->argument(0), [&] (JSString::SafeView&view) {165 return toStringView(exec, exec->argument(0), [&] (StringView view) { 162 166 if (view.is8Bit()) 163 167 return encode(exec, doNotEscape, view.characters8(), view.length()); … … 237 241 static JSValue decode(ExecState* exec, const Bitmap<256>& doNotUnescape, bool strict) 238 242 { 239 return toS afeView(exec, exec->argument(0), [&] (JSString::SafeView&view) {243 return toStringView(exec, exec->argument(0), [&] (StringView view) { 240 244 if (view.is8Bit()) 241 245 return decode(exec, view.characters8(), view.length(), doNotUnescape, strict); … … 708 712 709 713 // If ToString throws, we shouldn't call ToInt32. 710 return toS afeView(exec, value, [&] (JSString::SafeView&view) {711 return JSValue::encode(jsNumber(parseInt(view .get(), radixValue.toInt32(exec))));714 return toStringView(exec, value, [&] (StringView view) { 715 return JSValue::encode(jsNumber(parseInt(view, radixValue.toInt32(exec)))); 712 716 }); 713 717 } … … 766 770 ); 767 771 768 return JSValue::encode(toS afeView(exec, exec->argument(0), [&] (JSString::SafeView&view) {772 return JSValue::encode(toStringView(exec, exec->argument(0), [&] (StringView view) { 769 773 JSStringBuilder builder; 770 774 if (view.is8Bit()) { … … 805 809 EncodedJSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec) 806 810 { 807 return JSValue::encode(toS afeView(exec, exec->argument(0), [&] (JSString::SafeView&view) {811 return JSValue::encode(toStringView(exec, exec->argument(0), [&] (StringView view) { 808 812 StringBuilder builder; 809 813 int k = 0; -
trunk/Source/JavaScriptCore/runtime/JSONObject.cpp
r208123 r208699 764 764 JSString::SafeView source = exec->uncheckedArgument(0).toString(exec)->view(exec); 765 765 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 766 StringView view = source.get(); 767 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 766 768 767 769 JSValue unfiltered; 768 770 LocalScope localScope(vm); 769 if ( source.is8Bit()) {770 LiteralParser<LChar> jsonParser(exec, source.characters8(), source.length(), StrictJSON);771 if (view.is8Bit()) { 772 LiteralParser<LChar> jsonParser(exec, view.characters8(), view.length(), StrictJSON); 771 773 unfiltered = jsonParser.tryLiteralParse(); 772 774 if (!unfiltered) 773 775 return throwVMError(exec, scope, createSyntaxError(exec, jsonParser.getErrorMessage())); 774 776 } else { 775 LiteralParser<UChar> jsonParser(exec, source.characters16(), source.length(), StrictJSON);777 LiteralParser<UChar> jsonParser(exec, view.characters16(), view.length(), StrictJSON); 776 778 unfiltered = jsonParser.tryLiteralParse(); 777 779 if (!unfiltered) -
trunk/Source/JavaScriptCore/runtime/JSString.h
r207849 r208699 483 483 bool is8Bit() const { return m_string->is8Bit(); } 484 484 unsigned length() const { return m_string->length(); } 485 const LChar* characters8() const { return get().characters8(); }486 const UChar* characters16() const { return get().characters16(); }487 UChar operator[](unsigned index) const { return get()[index]; }488 485 489 486 private: -
trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp
r208563 r208699 792 792 EncodedJSValue JSC_HOST_CALL stringProtoFuncRepeatCharacter(ExecState* exec) 793 793 { 794 VM& vm = exec->vm(); 795 auto scope = DECLARE_THROW_SCOPE(vm); 796 794 797 // For a string which length is single, instead of creating ropes, 795 798 // allocating a sequential buffer and fill with the repeated string for efficiency. … … 803 806 RELEASE_ASSERT(repeatCountValue.isNumber()); 804 807 int32_t repeatCount; 805 { 806 VM& vm = exec->vm(); 807 auto scope = DECLARE_THROW_SCOPE(vm); 808 double value = repeatCountValue.asNumber(); 809 if (value > JSString::MaxLength) 810 return JSValue::encode(throwOutOfMemoryError(exec, scope)); 811 repeatCount = static_cast<int32_t>(value); 812 } 808 double value = repeatCountValue.asNumber(); 809 if (value > JSString::MaxLength) 810 return JSValue::encode(throwOutOfMemoryError(exec, scope)); 811 repeatCount = static_cast<int32_t>(value); 813 812 ASSERT(repeatCount >= 0); 814 813 ASSERT(!repeatCountValue.isDouble() || repeatCountValue.asDouble() == repeatCount); 815 814 816 UChar character = string->view(exec)[0]; 815 JSString::SafeView safeView = string->view(exec); 816 StringView view = safeView.get(); 817 ASSERT(view.length() == 1 && !scope.exception()); 818 UChar character = view[0]; 819 scope.release(); 817 820 if (!(character & ~0xff)) 818 821 return JSValue::encode(repeatCharacter(*exec, static_cast<LChar>(character), repeatCount)); … … 905 908 return throwVMTypeError(exec, scope); 906 909 JSString::SafeView string = thisValue.toString(exec)->view(exec); 910 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 911 StringView view = string.get(); 912 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 907 913 JSValue a0 = exec->argument(0); 908 914 if (a0.isUInt32()) { 909 915 uint32_t i = a0.asUInt32(); 910 if (i < string.length())911 return JSValue::encode(jsSingleCharacterString(exec, string[i]));916 if (i < view.length()) 917 return JSValue::encode(jsSingleCharacterString(exec, view[i])); 912 918 return JSValue::encode(jsEmptyString(exec)); 913 919 } 914 920 double dpos = a0.toInteger(exec); 915 if (dpos >= 0 && dpos < string.length())916 return JSValue::encode(jsSingleCharacterString(exec, string[static_cast<unsigned>(dpos)]));921 if (dpos >= 0 && dpos < view.length()) 922 return JSValue::encode(jsSingleCharacterString(exec, view[static_cast<unsigned>(dpos)])); 917 923 return JSValue::encode(jsEmptyString(exec)); 918 924 } … … 926 932 if (!checkObjectCoercible(thisValue)) 927 933 return throwVMTypeError(exec, scope); 928 JSString::SafeView string = thisValue.toString(exec)->view(exec); 934 JSString* jsString = thisValue.toString(exec); 935 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 936 JSString::SafeView string = jsString->view(exec); 937 StringView view = string.get(); 938 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 929 939 JSValue a0 = exec->argument(0); 930 940 if (a0.isUInt32()) { 931 941 uint32_t i = a0.asUInt32(); 932 if (i < string.length())933 return JSValue::encode(jsNumber( string[i]));942 if (i < view.length()) 943 return JSValue::encode(jsNumber(view[i])); 934 944 return JSValue::encode(jsNaN()); 935 945 } 936 946 double dpos = a0.toInteger(exec); 937 if (dpos >= 0 && dpos < string.length())938 return JSValue::encode(jsNumber( string[static_cast<int>(dpos)]));947 if (dpos >= 0 && dpos < view.length()) 948 return JSValue::encode(jsNumber(view[static_cast<int>(dpos)])); 939 949 return JSValue::encode(jsNaN()); 940 950 } … … 2009 2019 JSString::SafeView source = thisValue.toString(exec)->view(exec); 2010 2020 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 2021 StringView view = source.get(); 2022 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 2011 2023 2012 2024 UNormalizationMode form = UNORM_NFC; … … 2028 2040 } 2029 2041 2030 return JSValue::encode(normalize(exec, source.get().upconvertedCharacters(), source.length(), form));2042 return JSValue::encode(normalize(exec, view.upconvertedCharacters(), view.length(), form)); 2031 2043 } 2032 2044
Note:
See TracChangeset
for help on using the changeset viewer.