Changeset 279915 in webkit


Ignore:
Timestamp:
Jul 14, 2021 12:15:56 PM (3 years ago)
Author:
mark.lam@apple.com
Message:

Check for out of memory in JSC::globalFuncEscape() and JSC::globalFuncUnescape().
https://bugs.webkit.org/show_bug.cgi?id=227962
rdar://78392251

Reviewed by Yusuke Suzuki.

JSTests:

  • stress/out-of-memory-in-globalFuncUnescape.js: Added.

Source/JavaScriptCore:

  • runtime/JSGlobalObjectFunctions.cpp:

(JSC::JSC_DEFINE_HOST_FUNCTION):

Location:
trunk
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r279910 r279915  
     12021-07-14  Mark Lam  <mark.lam@apple.com>
     2
     3        Check for out of memory in JSC::globalFuncEscape() and JSC::globalFuncUnescape().
     4        https://bugs.webkit.org/show_bug.cgi?id=227962
     5        rdar://78392251
     6
     7        Reviewed by Yusuke Suzuki.
     8
     9        * stress/out-of-memory-in-globalFuncUnescape.js: Added.
     10
    1112021-07-14  Mark Lam  <mark.lam@apple.com>
    212
  • trunk/Source/JavaScriptCore/ChangeLog

    r279913 r279915  
     12021-07-14  Mark Lam  <mark.lam@apple.com>
     2
     3        Check for out of memory in JSC::globalFuncEscape() and JSC::globalFuncUnescape().
     4        https://bugs.webkit.org/show_bug.cgi?id=227962
     5        rdar://78392251
     6
     7        Reviewed by Yusuke Suzuki.
     8
     9        * runtime/JSGlobalObjectFunctions.cpp:
     10        (JSC::JSC_DEFINE_HOST_FUNCTION):
     11
    1122021-07-14  Yusuke Suzuki  <ysuzuki@apple.com>
    213
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp

    r278253 r279915  
    578578JSC_DEFINE_HOST_FUNCTION(globalFuncEscape, (JSGlobalObject* globalObject, CallFrame* callFrame))
    579579{
    580     return JSValue::encode(toStringView(globalObject, callFrame->argument(0), [&] (StringView view) {
     580    return JSValue::encode(toStringView(globalObject, callFrame->argument(0), [&] (StringView view) -> JSString* {
    581581        static const Bitmap<256> doNotEscape = makeCharacterBitmap(
    582582            "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
     
    587587
    588588        VM& vm = globalObject->vm();
    589         StringBuilder builder;
     589        auto scope = DECLARE_THROW_SCOPE(vm);
     590
     591        StringBuilder builder(StringBuilder::OverflowHandler::RecordOverflow);
    590592        if (view.is8Bit()) {
    591593            const LChar* c = view.characters8();
     
    597599                    builder.append('%', hex(u, 2));
    598600            }
    599             return jsString(vm, builder.toString());
    600         }
    601 
    602         const UChar* c = view.characters16();
    603         for (unsigned k = 0; k < view.length(); k++, c++) {
    604             UChar u = c[0];
    605             if (u >= doNotEscape.size())
    606                 builder.append("%u", hex(static_cast<uint8_t>(u >> 8), 2), hex(static_cast<uint8_t>(u), 2));
    607             else if (doNotEscape.get(static_cast<LChar>(u)))
    608                 builder.append(*c);
    609             else
    610                 builder.append('%', hex(u, 2));
    611         }
    612 
     601        } else {
     602            const UChar* c = view.characters16();
     603            for (unsigned k = 0; k < view.length(); k++, c++) {
     604                UChar u = c[0];
     605                if (u >= doNotEscape.size())
     606                    builder.append("%u", hex(static_cast<uint8_t>(u >> 8), 2), hex(static_cast<uint8_t>(u), 2));
     607                else if (doNotEscape.get(static_cast<LChar>(u)))
     608                    builder.append(*c);
     609                else
     610                    builder.append('%', hex(u, 2));
     611            }
     612        }
     613
     614        if (UNLIKELY(builder.hasOverflowed())) {
     615            throwOutOfMemoryError(globalObject, scope);
     616            return { };
     617        }
    613618        return jsString(vm, builder.toString());
    614619    }));
     
    617622JSC_DEFINE_HOST_FUNCTION(globalFuncUnescape, (JSGlobalObject* globalObject, CallFrame* callFrame))
    618623{
    619     return JSValue::encode(toStringView(globalObject, callFrame->argument(0), [&] (StringView view) {
     624    return JSValue::encode(toStringView(globalObject, callFrame->argument(0), [&] (StringView view) -> JSString* {
    620625        // We use int for k and length intentionally since we would like to evaluate
    621626        // the condition `k <= length -6` even if length is less than 6.
     
    623628        int length = view.length();
    624629
    625         StringBuilder builder;
     630        VM& vm = globalObject->vm();
     631        auto scope = DECLARE_THROW_SCOPE(vm);
     632
     633        StringBuilder builder(StringBuilder::OverflowHandler::RecordOverflow);
    626634        builder.reserveCapacity(length);
    627635
     
    667675        }
    668676
    669         return jsString(globalObject->vm(), builder.toString());
     677        if (UNLIKELY(builder.hasOverflowed())) {
     678            throwOutOfMemoryError(globalObject, scope);
     679            return { };
     680        }
     681        return jsString(vm, builder.toString());
    670682    }));
    671683}
Note: See TracChangeset for help on using the changeset viewer.