Changeset 246346 in webkit


Ignore:
Timestamp:
Jun 11, 2019 8:18:53 PM (5 years ago)
Author:
commit-queue@webkit.org
Message:

JSC should throw if proxy set returns falsish in strict mode context
https://bugs.webkit.org/show_bug.cgi?id=177398

Patch by Alexey Shvayka <Alexey Shvayka> on 2019-06-11
Reviewed by Yusuke Suzuki.

JSTests:

  1. Add coverage for Proxy set trap returning falsy value in strict mode.
  2. RegExp methods throw unless Set? succeeds. Return true from Proxy set traps to fix the tests.
  • stress/proxy-set.js: Add 2 test cases.
  • stress/regexp-match-proxy.js: Fix test.
  • stress/regexp-replace-proxy.js: Fix test.

Source/JavaScriptCore:

Throw TypeError exception if Proxy's set trap returns falsy value.
(step 6.c of https://tc39.es/ecma262/#sec-putvalue)

  • runtime/ProxyObject.cpp:

(JSC::ProxyObject::performPut):
(JSC::ProxyObject::put):
(JSC::ProxyObject::putByIndexCommon):

  • runtime/ProxyObject.h:
Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r246333 r246346  
     12019-06-11  Alexey Shvayka  <shvaikalesh@gmail.com>
     2
     3        JSC should throw if proxy set returns falsish in strict mode context
     4        https://bugs.webkit.org/show_bug.cgi?id=177398
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        1. Add coverage for Proxy `set` trap returning falsy value in strict mode.
     9        2. RegExp methods throw unless [[Set]] succeeds. Return `true` from Proxy `set` traps to fix the tests.
     10
     11        * stress/proxy-set.js: Add 2 test cases.
     12        * stress/regexp-match-proxy.js: Fix test.
     13        * stress/regexp-replace-proxy.js: Fix test.
     14
    1152019-06-11  Alexey Shvayka  <shvaikalesh@gmail.com>
    216
  • trunk/JSTests/stress/proxy-set.js

    r217093 r246346  
    8080    }
    8181}
     82
     83(function() {
     84    "use strict";
     85    let target = {
     86        x: 30
     87    };
     88
     89    let handler = {
     90        set: function() {
     91            return false;
     92        }
     93    };
     94
     95    let proxy = new Proxy(target, handler);
     96    for (let i = 0; i < 1000; i++) {
     97        let threw = false;
     98        try {
     99            proxy.x = 40;
     100        } catch(e) {
     101            assert(e.toString() === "TypeError: Proxy object's 'set' trap returned falsy value for property 'x'");
     102            threw = true;
     103        }
     104        assert(threw);
     105    }
     106})();
     107
     108(function() {
     109    "use strict";
     110    let target = {
     111        x: 30
     112    };
     113
     114    let handler = {
     115        set: function() {
     116            return false;
     117        }
     118    };
     119
     120    let proxy = new Proxy(target, handler);
     121    for (let i = 0; i < 1000; i++) {
     122        let threw = false;
     123        try {
     124            proxy[42] = 40;
     125        } catch(e) {
     126            assert(e.toString() === "TypeError: Proxy object's 'set' trap returned falsy value for property '42'");
     127            threw = true;
     128        }
     129        assert(threw);
     130    }
     131})();
    82132
    83133{
  • trunk/JSTests/stress/regexp-match-proxy.js

    r198625 r246346  
    5454            getSet.push(k);
    5555            o[k] = v;
     56            return true;
    5657        }
    5758    });
     
    8485            getSet.push(k);
    8586            o[k] = v;
     87            return true;
    8688        }
    8789    });
     
    118120                regExpGlobal_tx_Greedy.lastIndex = v;
    119121            o[k] = v;
     122            return true;
    120123        }
    121124    });
     
    153156                regExpGlobalUnicode_digit_nonGreedy.lastIndex = v;
    154157            o[k] = v;
     158            return true;
    155159        }
    156160    });
  • trunk/JSTests/stress/regexp-replace-proxy.js

    r200117 r246346  
    5151            getSet.push(k);
    5252            o[k] = v;
     53            return true;
    5354        }
    5455    });
     
    7980            getSet.push(k);
    8081            o[k] = v;
     82            return true;
    8183        }
    8284    });
     
    111113                regExp_phoneNumber.lastIndex = v;
    112114            o[k] = v;
     115            return true;
    113116        }
    114117    });
     
    142145                regExpGlobalUnicode_digit_nonGreedy.lastIndex = v;
    143146            o[k] = v;
     147            return true;
    144148        }
    145149    });
  • trunk/Source/JavaScriptCore/ChangeLog

    r246333 r246346  
     12019-06-11  Alexey Shvayka  <shvaikalesh@gmail.com>
     2
     3        JSC should throw if proxy set returns falsish in strict mode context
     4        https://bugs.webkit.org/show_bug.cgi?id=177398
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        Throw TypeError exception if Proxy's `set` trap returns falsy value.
     9        (step 6.c of https://tc39.es/ecma262/#sec-putvalue)
     10
     11        * runtime/ProxyObject.cpp:
     12        (JSC::ProxyObject::performPut):
     13        (JSC::ProxyObject::put):
     14        (JSC::ProxyObject::putByIndexCommon):
     15        * runtime/ProxyObject.h:
     16
    1172019-06-11  Alexey Shvayka  <shvaikalesh@gmail.com>
    218
  • trunk/Source/JavaScriptCore/runtime/ProxyObject.cpp

    r246333 r246346  
    410410
    411411template <typename PerformDefaultPutFunction>
    412 bool ProxyObject::performPut(ExecState* exec, JSValue putValue, JSValue thisValue, PropertyName propertyName, PerformDefaultPutFunction performDefaultPut)
     412bool ProxyObject::performPut(ExecState* exec, JSValue putValue, JSValue thisValue, PropertyName propertyName, PerformDefaultPutFunction performDefaultPut, bool shouldThrow)
    413413{
    414414    NO_TAIL_CALLS();
     
    449449    bool trapResultAsBool = trapResult.toBoolean(exec);
    450450    RETURN_IF_EXCEPTION(scope, false);
    451     if (!trapResultAsBool)
    452         return false;
     451    if (!trapResultAsBool) {
     452        if (shouldThrow)
     453            throwVMTypeError(exec, scope, makeString("Proxy object's 'set' trap returned falsy value for property '", String(propertyName.uid()), "'"));
     454        return false;
     455    }
    453456
    454457    PropertyDescriptor descriptor;
     
    479482        return target->methodTable(vm)->put(target, exec, propertyName, value, slot);
    480483    };
    481     return thisObject->performPut(exec, value, slot.thisValue(), propertyName, performDefaultPut);
     484    return thisObject->performPut(exec, value, slot.thisValue(), propertyName, performDefaultPut, slot.isStrictMode());
    482485}
    483486
     
    494497        return target->methodTable(vm)->put(target, exec, ident.impl(), putValue, slot);
    495498    };
    496     RELEASE_AND_RETURN(scope, performPut(exec, putValue, thisValue, ident.impl(), performDefaultPut));
     499    RELEASE_AND_RETURN(scope, performPut(exec, putValue, thisValue, ident.impl(), performDefaultPut, shouldThrow));
    497500}
    498501
  • trunk/Source/JavaScriptCore/runtime/ProxyObject.h

    r242636 r246346  
    101101    bool performDelete(ExecState*, PropertyName, DefaultDeleteFunction);
    102102    template <typename PerformDefaultPutFunction>
    103     bool performPut(ExecState*, JSValue putValue, JSValue thisValue, PropertyName, PerformDefaultPutFunction);
     103    bool performPut(ExecState*, JSValue putValue, JSValue thisValue, PropertyName, PerformDefaultPutFunction, bool shouldThrow);
    104104    bool performPreventExtensions(ExecState*);
    105105    bool performIsExtensible(ExecState*);
Note: See TracChangeset for help on using the changeset viewer.