Left: | ||
Right: |
OLD | NEW |
---|---|
1 // Copyright (C) 2011 Google Inc. | 1 // Copyright (C) 2011 Google Inc. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // https://www.apache.org/licenses/LICENSE-2.0 | 7 // https://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
(...skipping 15 matching lines...) Expand all Loading... | |
26 * <p>Ignore the "...requires ___global_test_function___" below. We | 26 * <p>Ignore the "...requires ___global_test_function___" below. We |
27 * create it, use it, and delete it all within this module. But we | 27 * create it, use it, and delete it all within this module. But we |
28 * need to lie to the linter since it can't tell. | 28 * need to lie to the linter since it can't tell. |
29 * | 29 * |
30 * //requires ses.mitigateSrcGotchas | 30 * //requires ses.mitigateSrcGotchas |
31 * //provides ses.ok, ses.okToLoad, ses.getMaxSeverity | 31 * //provides ses.ok, ses.okToLoad, ses.getMaxSeverity |
32 * //provides ses.is, ses.makeDelayedTamperProof | 32 * //provides ses.is, ses.makeDelayedTamperProof |
33 * //provides ses.makeCallerHarmless, ses.makeArgumentsHarmless | 33 * //provides ses.makeCallerHarmless, ses.makeArgumentsHarmless |
34 * //provides ses.noFuncPoison | 34 * //provides ses.noFuncPoison |
35 * //provides ses.verifyStrictFunctionBody | 35 * //provides ses.verifyStrictFunctionBody |
36 * //provides ses.getUndeniables, ses.earlyUndeniables | |
37 * //provides ses.getAnonIntrinsics | |
36 * | 38 * |
37 * @author Mark S. Miller | 39 * @author Mark S. Miller |
38 * @requires ___global_test_function___, ___global_valueOf_function___ | 40 * @requires ___global_test_function___, ___global_valueOf_function___ |
39 * @requires JSON, eval, this | 41 * @requires JSON, eval, this |
40 * @requires navigator, document, DOMException | 42 * @requires navigator, document, DOMException |
41 * @overrides ses, repairES5Module | 43 * @overrides ses, repairES5Module |
42 * @overrides RegExp, WeakMap, Object, parseInt | 44 * @overrides RegExp, WeakMap, Object, parseInt |
43 */ | 45 */ |
44 var RegExp; | 46 var RegExp; |
45 var ses; | 47 var ses; |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
193 * poison properties for simple safety, rather than trying to find | 195 * poison properties for simple safety, rather than trying to find |
194 * subtle corner cases by which they might lose safety. If any of | 196 * subtle corner cases by which they might lose safety. If any of |
195 * this fails, then we proceed under the assumption we're in the old | 197 * this fails, then we proceed under the assumption we're in the old |
196 * regime. | 198 * regime. |
197 * | 199 * |
198 * If noFuncPoison, then we're in the new regime made simply safe by | 200 * If noFuncPoison, then we're in the new regime made simply safe by |
199 * these deletions, and we do not treat the names 'caller' and | 201 * these deletions, and we do not treat the names 'caller' and |
200 * 'arguments' on functions as special. | 202 * 'arguments' on functions as special. |
201 */ | 203 */ |
202 var noFuncPoison = | 204 var noFuncPoison = |
203 Function.prototype.hasOwnProperty('caller') && | 205 Function.prototype.hasOwnProperty('caller') && |
204 Function.prototype.hasOwnProperty('arguments') && | 206 Function.prototype.hasOwnProperty('arguments') && |
205 !strictFnSpecimen.hasOwnProperty('caller') && | 207 !strictFnSpecimen.hasOwnProperty('caller') && |
206 !strictFnSpecimen.hasOwnProperty('arguments') && | 208 !strictFnSpecimen.hasOwnProperty('arguments') && |
207 !builtInMapMethod.hasOwnProperty('caller') && | 209 !builtInMapMethod.hasOwnProperty('caller') && |
208 !builtInMapMethod.hasOwnProperty('arguments') && | 210 !builtInMapMethod.hasOwnProperty('arguments') && |
209 delete Function.prototype.caller && | 211 delete Function.prototype.caller && |
210 delete Function.prototype.arguments && | 212 delete Function.prototype.arguments && |
211 !Function.prototype.hasOwnProperty('caller') && | 213 !Function.prototype.hasOwnProperty('caller') && |
212 !Function.prototype.hasOwnProperty('arguments'); | 214 !Function.prototype.hasOwnProperty('arguments'); |
213 ses.noFuncPoison = noFuncPoison; | 215 ses.noFuncPoison = noFuncPoison; |
214 | 216 |
215 | 217 |
216 /** | 218 /** |
217 * http://wiki.ecmascript.org/doku.php?id=harmony:egal | 219 * http://wiki.ecmascript.org/doku.php?id=harmony:egal |
218 */ | 220 */ |
219 var is = ses.is = Object.is || function(x, y) { | 221 var is = ses.is = Object.is || function(x, y) { |
220 if (x === y) { | 222 if (x === y) { |
221 // 0 === -0, but they are not identical | 223 // 0 === -0, but they are not identical |
222 return x !== 0 || 1 / x === 1 / y; | 224 return x !== 0 || 1 / x === 1 / y; |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
324 * initialization has done all the monkey patching that it is going | 326 * initialization has done all the monkey patching that it is going |
325 * to do on the Object.* methods, but before any untrusted code runs | 327 * to do on the Object.* methods, but before any untrusted code runs |
326 * in this context. | 328 * in this context. |
327 */ | 329 */ |
328 function makeTamperProof() { | 330 function makeTamperProof() { |
329 | 331 |
330 // Sample these after all trusted monkey patching initialization | 332 // Sample these after all trusted monkey patching initialization |
331 // but before any untrusted code runs in this frame. | 333 // but before any untrusted code runs in this frame. |
332 var gopd = Object.getOwnPropertyDescriptor; | 334 var gopd = Object.getOwnPropertyDescriptor; |
333 var gopn = Object.getOwnPropertyNames; | 335 var gopn = Object.getOwnPropertyNames; |
334 var getProtoOf = Object.getPrototypeOf; | |
335 var freeze = Object.freeze; | 336 var freeze = Object.freeze; |
336 var isFrozen = Object.isFrozen; | 337 var isFrozen = Object.isFrozen; |
337 var defProp = Object.defineProperty; | 338 var defProp = Object.defineProperty; |
338 var call = Function.prototype.call; | 339 var call = Function.prototype.call; |
339 | 340 |
340 function forEachNonPoisonOwn(obj, callback) { | 341 function forEachNonPoisonOwn(obj, callback) { |
341 var list = gopn(obj); | 342 var list = gopn(obj); |
342 var len = list.length; | 343 var len = list.length; |
343 var i, j, name; // crockford rule | 344 var i, j, name; // crockford rule |
344 if (typeof obj === 'function') { | 345 if (typeof obj === 'function') { |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
492 * ctor. methodName must be the name of a method on ctor.prototype | 493 * ctor. methodName must be the name of a method on ctor.prototype |
493 * that, when applied to an exotic object of this exotic type as | 494 * that, when applied to an exotic object of this exotic type as |
494 * this-value, with the provided args list, will return without | 495 * this-value, with the provided args list, will return without |
495 * error, but when applied to any other object as this-value will | 496 * error, but when applied to any other object as this-value will |
496 * throw an error. opt_example, if provided, must be an example of | 497 * throw an error. opt_example, if provided, must be an example of |
497 * such an exotic object that can be used for internal sanity | 498 * such an exotic object that can be used for internal sanity |
498 * checking before returning a brandTester. | 499 * checking before returning a brandTester. |
499 * | 500 * |
500 * <p>Uses Allen's trick from | 501 * <p>Uses Allen's trick from |
501 * https://esdiscuss.org/topic/tostringtag-spoofing-for-null-and-undefined#con tent-59 | 502 * https://esdiscuss.org/topic/tostringtag-spoofing-for-null-and-undefined#con tent-59 |
502 * for brand testing that will remain reliable in ES6. | 503 * for brand testing that will remain reliable in ES6. |
503 * However, testing reveals that, on FF 35.0.1, a proxy on an exotic | 504 * However, testing reveals that, on FF 35.0.1, a proxy on an exotic |
504 * object X will pass this brand test when X will. This is fixed as of | 505 * object X will pass this brand test when X will. This is fixed as of |
505 * FF Nightly 38.0a1. | 506 * FF Nightly 38.0a1. |
506 * | 507 * |
507 * <p>Returns a brandTester function such that, if brandTester(specimen) | 508 * <p>Returns a brandTester function such that, if brandTester(specimen) |
508 * returns true, this is a reliable indicator that specimen actually | 509 * returns true, this is a reliable indicator that specimen actually |
509 * is an exotic object of that type. | 510 * is an exotic object of that type. |
510 * | 511 * |
511 * <p>As a convenience, ctor may be undefined, in which | 512 * <p>As a convenience, ctor may be undefined, in which |
512 * case we assume that there are no exotic objects of that kind. In | 513 * case we assume that there are no exotic objects of that kind. In |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
608 RegExp, 'exec', ['x'], /x/); | 609 RegExp, 'exec', ['x'], /x/); |
609 | 610 |
610 /** | 611 /** |
611 * A reliable brand test for whether specimen has a [[WeakMapData]] | 612 * A reliable brand test for whether specimen has a [[WeakMapData]] |
612 * internal slot. | 613 * internal slot. |
613 */ | 614 */ |
614 var isBuiltinWeakMap = makeBrandTester( | 615 var isBuiltinWeakMap = makeBrandTester( |
615 global.WeakMap, 'get', [{}], global.WeakMap ? new WeakMap() : void 0); | 616 global.WeakMap, 'get', [{}], global.WeakMap ? new WeakMap() : void 0); |
616 | 617 |
617 | 618 |
618 /////////////////////////////////////////// | 619 //////////////// Undeniables and Intrinsics ////////////// |
620 | |
621 | |
622 /** | |
623 * A known strict function which returns its arguments object. | |
624 */ | |
625 function strictArguments() { return arguments; } | |
626 | |
627 /** | |
628 * A known sloppy function which returns its arguments object. | |
629 * | |
630 * Defined using Function so it'll be sloppy (not strict and not | |
631 * builtin). | |
632 */ | |
633 var sloppyArguments = Function('return arguments;'); | |
634 | |
635 /** | |
636 * If present, a known strict generator function which yields its | |
637 * arguments object. | |
638 */ | |
639 var strictArgumentsGenerator = void 0; | |
640 try { | |
641 // ES6 syntax | |
642 strictArgumentsGenerator = | |
643 eval('(function*() { "use strict"; yield arguments; })'); | |
644 } catch (_) { | |
645 try { | |
646 // Old Firefox syntax | |
647 strictArgumentsGenerator = | |
648 eval('(function() { "use strict"; yield arguments; })'); | |
649 } catch (_2) { | |
650 // ignore | |
kpreid2
2015/02/20 22:02:37
Please add a stronger verification here that the e
MarkM
2015/02/21 02:34:24
Done.
| |
651 } | |
652 } | |
653 | |
654 | |
655 /** | |
656 * The undeniable are the primordial objects are ambiently reachable | |
kpreid2
2015/02/20 22:02:37
The undeniable_s_ are the primordial objects _whic
MarkM
2015/02/21 02:34:24
Done.
| |
657 * via compositions of strict syntax, primitive wrapping (new | |
658 * Object(x)), and prototype navigation (the equivalent of | |
659 * Object.getPrototypeOf(x) or x.__proto__). Although we could in | |
660 * theory monkey patch primitive wrapping or prototype navigation, | |
661 * we won't. Hence, without parsing, the following are undeniable no | |
662 * matter what <i>other</i> monkey patching we do to the primordial | |
663 * environment. | |
664 */ | |
665 function getUndeniables() { | |
666 var gopd = Object.getOwnPropertyDescriptor; | |
667 var getProto = Object.getPrototypeOf; | |
668 | |
669 var undeniableTuples = [ | |
kpreid2
2015/02/20 22:02:37
Add a comment here explaining what the third eleme
MarkM
2015/02/21 02:34:24
Done.
| |
670 ['Object.prototype', Object.prototype, {}], | |
671 ['Function.prototype', Function.prototype, function(){}], | |
672 ['Array.prototype', Array.prototype, []], | |
673 ['RegExp.prototype', RegExp.prototype, /x/], | |
674 ['Boolean.prototype', Boolean.prototype, true], | |
675 ['Number.prototype', Number.prototype, 1], | |
676 ['String.prototype', String.prototype, 'x'], | |
677 ]; | |
678 var result = {}; | |
679 | |
680 // Get the ES6 %Generator% intrinsic, if present. | |
681 // It is undeniable because individual generator functions inherit | |
682 // from it. | |
683 (function() { | |
684 // See http://people.mozilla.org/~jorendorff/figure-2.png | |
kpreid2
2015/02/20 22:02:37
This seems like a link likely to break. Give some
MarkM
2015/02/21 02:34:24
Done.
| |
685 if (!strictArgumentsGenerator) { return; } | |
kpreid2
2015/02/20 22:02:37
If there's some less fragile condition we could us
MarkM
2015/02/21 02:34:24
None comes to mind.
| |
686 var Generator = getProto(strictArgumentsGenerator); | |
687 undeniableTuples.push(['%Generator%', Generator, | |
688 strictArgumentsGenerator]); | |
689 strictArgumentsGenerator = strictArgumentsGenerator; | |
690 }()); | |
691 | |
692 strictForEachFn(undeniableTuples, function(tuple) { | |
693 var name = tuple[0]; | |
694 var undeniable = tuple[1]; | |
695 var start = tuple[2]; | |
696 result[name] = undeniable; | |
697 if (start === void 0) { return; } | |
698 start = Object(start); | |
699 if (undeniable === start) { return; } | |
700 if (undeniable === getProto(start)) { return; } | |
701 throw new Error('Unexpected undeniable: ' + undeniable); | |
702 }); | |
703 | |
704 return result; | |
705 } | |
706 ses.getUndeniables = getUndeniables; | |
707 | |
708 // For consistency checking, once we've done all our whitelist | |
709 // processing and monkey patching, we call getUndeniables again and | |
kpreid2
2015/02/20 22:02:37
…we _will_ call…
MarkM
2015/02/21 02:34:24
Done.
| |
710 // check that the undeniables are the same. | |
711 ses.earlyUndeniables = getUndeniables(); | |
712 | |
713 | |
714 /** | |
715 * Get the intrinsics not otherwise reachable by named own property | |
716 * traversal. See | |
717 * https://people.mozilla.org/~jorendorff/es6-draft.html#sec-well-known-intrin sic-objects | |
718 * and the instrinsics section of whitelist.js | |
719 * | |
720 * <p>Unlike getUndeniables(), the result of getAnonIntrinsics() | |
721 * does depend on the current state of the primordials, so we must | |
722 * run this again after all other relevant monkey patching is done, | |
723 * in order to properly initialize cajaVM.intrinsics | |
724 */ | |
725 function getAnonIntrinsics() { | |
726 var gopd = Object.getOwnPropertyDescriptor; | |
727 var getProto = Object.getPrototypeOf; | |
728 var result = {}; | |
729 | |
730 // If there are still other ThrowTypeError objects left after | |
731 // noFuncPoison-ing, this should be caught by | |
732 // test_THROWTYPEERROR_NOT_UNIQUE below, so we assume here that | |
733 // this is the only surviving ThrowTypeError intrinsic. | |
734 result.ThrowTypeError = gopd(arguments, 'caller').get; | |
735 | |
736 // Get the ES6 %ArrayIteratorPrototype%, %StringIteratorPrototype%, | |
737 // and %IteratorPrototype% intrinsics, if present. | |
738 // TODO %MapIteratorPrototype% | |
kpreid2
2015/02/20 22:02:37
TODOs to do before submitting
MarkM
2015/02/21 02:34:24
Added explanation
| |
739 // TODO %SetIteratorPrototype% | |
740 (function() { | |
741 var iteratorSym = global.Symbol && global.Symbol.iterator || | |
742 "@@iterator"; // used instead of a symbol on FF35 | |
743 if ([][iteratorSym] === void 0) { return; } | |
kpreid2
2015/02/20 22:02:37
This will exit too early if for some reason [][ite
MarkM
2015/02/21 02:34:24
Trickier than I expected, but done.
| |
744 var arrayIter = [][iteratorSym](); | |
745 var ArrayIteratorPrototype = getProto(arrayIter); | |
746 result.ArrayIteratorPrototype = ArrayIteratorPrototype; | |
747 var IteratorPrototype = getProto(ArrayIteratorPrototype); | |
748 if (IteratorPrototype !== Object.prototype) { | |
749 if (getProto(IteratorPrototype) !== Object.prototype) { | |
750 throw new Error( | |
751 '%IteratorPrototype%.__proto__ was not Object.prototype'); | |
752 } | |
753 result.IteratorPrototype = IteratorPrototype; | |
754 } | |
755 if (''[iteratorSym] === void 0) { return; } | |
756 var stringIter = ''[iteratorSym](); | |
757 var StringIteratorPrototype = getProto(stringIter); | |
758 result.StringIteratorPrototype = StringIteratorPrototype; | |
759 var stringIterProtoBase = getProto(StringIteratorPrototype); | |
760 if (stringIterProtoBase !== IteratorPrototype && | |
761 stringIterProtoBase !== Object.prototype) { | |
762 throw new Error('unexpected %StringIteratorPrototype%.__proto__'); | |
763 } | |
764 }()); | |
765 | |
766 // Get the ES6 %GeneratorFunction% intrinsic, if present. | |
767 (function() { | |
768 var Generator = ses.earlyUndeniables['%Generator%']; | |
769 if (!Generator || Generator === Function.prototype) { return; } | |
770 if (getProto(Generator) !== Function.prototype) { | |
771 throw new Error('Generator.__proto__ was not Function.prototype'); | |
772 } | |
773 var GeneratorFunction = Generator.constructor; | |
774 if (GeneratorFunction === Function) { return; } | |
775 if (getProto(GeneratorFunction) !== Function) { | |
776 throw new Error('GeneratorFunction.__proto__ was not Function'); | |
777 } | |
778 result.GeneratorFunction = GeneratorFunction; | |
779 var genProtoBase = getProto(Generator.prototype); | |
780 if (genProtoBase !== result.IteratorPrototype && | |
781 genProtoBase !== Object.prototype) { | |
782 throw new Error('Unexpected Generator.prototype.__proto__'); | |
783 } | |
784 }()); | |
785 | |
786 // Get the ES6 %TypedArray% intrinsic, if present. | |
787 (function() { | |
788 if (!global.Float32Array) { return; } | |
789 var TypedArray = getProto(global.Float32Array); | |
790 if (TypedArray === Function.prototype) { return; } | |
791 if (getProto(TypedArray) !== Function.prototype) { | |
792 // http://bespin.cz/~ondras/html/classv8_1_1ArrayBufferView.html | |
793 // has me worried that someone might make such an intermediate | |
794 // object visible. | |
795 throw new Error('TypedArray.__proto__ was not Function.prototype'); | |
796 } | |
797 result.TypedArray = TypedArray; | |
798 }()); | |
799 | |
800 return result; | |
kpreid2
2015/02/20 22:02:37
How about a self-test that none of the values are
MarkM
2015/02/21 02:34:24
Done.
| |
801 } | |
802 ses.getAnonIntrinsics = getAnonIntrinsics; | |
803 | |
804 var unsafeIntrinsics = getAnonIntrinsics(); | |
805 | |
806 | |
807 ////////////////////////////////////////////////////////// | |
619 | 808 |
620 /** | 809 /** |
621 * Fails if {@code funcBodySrc} does not parse as a strict | 810 * Fails if {@code funcBodySrc} does not parse as a strict |
622 * FunctionBody. | 811 * FunctionBody. |
623 * | 812 * |
624 * <p>ses.verifyStrictFunctionBody is exported from repairES5 | 813 * <p>ses.verifyStrictFunctionBody is exported from repairES5 |
625 * because the best way to perform this verification on a given | 814 * because the best way to perform this verification on a given |
626 * platform depends on whether the platform's Function constructor | 815 * platform depends on whether the platform's Function constructor |
627 * <a href= | 816 * <a href= |
628 * "https://code.google.com/p/google-caja/issues/detail?id=1616" | 817 * "https://code.google.com/p/google-caja/issues/detail?id=1616" |
(...skipping 2224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2853 if (desc === undefined) { return false; } | 3042 if (desc === undefined) { return false; } |
2854 if (desc.configurable) { return false; } | 3043 if (desc.configurable) { return false; } |
2855 if (desc.value === null && desc.configurable === false) { | 3044 if (desc.value === null && desc.configurable === false) { |
2856 // the problematic-for-us case, known to occur in Chrome 25.0.1364.172 | 3045 // the problematic-for-us case, known to occur in Chrome 25.0.1364.172 |
2857 return true; | 3046 return true; |
2858 } | 3047 } |
2859 return 'Unexpected __proto__ own property descriptor, enumerable: ' + | 3048 return 'Unexpected __proto__ own property descriptor, enumerable: ' + |
2860 desc.enumerable + ', value: ' + desc.value; | 3049 desc.enumerable + ', value: ' + desc.value; |
2861 } | 3050 } |
2862 | 3051 |
2863 function getThrowTypeError() { | |
2864 return Object.getOwnPropertyDescriptor(arguments, 'caller').get; | |
2865 } | |
2866 | |
2867 /** | 3052 /** |
2868 * A known strict function which returns its arguments object. | 3053 * %ThrowTypeError% is not unique (even after whatever cleanup was |
2869 */ | 3054 * already done during the noFuncPoison testing above). |
2870 function strictArguments() { return arguments; } | |
2871 | |
2872 /** | |
2873 * A known sloppy function which returns its arguments object. | |
2874 * | |
2875 * Defined using Function so it'll be sloppy (not strict and not | |
2876 * builtin). | |
2877 */ | |
2878 var sloppyArguments = Function('return arguments;'); | |
2879 | |
2880 /** | |
2881 * [[ThrowTypeError]] is not unique (even after whatever cleanup was | |
2882 * already done during the noPoison testing above). | |
2883 */ | 3055 */ |
2884 function test_THROWTYPEERROR_NOT_UNIQUE() { | 3056 function test_THROWTYPEERROR_NOT_UNIQUE() { |
2885 var tte = getThrowTypeError(); | 3057 var tte = unsafeIntrinsics.ThrowTypeError; |
2886 if (typeof tte !== 'function') { | 3058 if (typeof tte !== 'function') { |
2887 return 'Unexpected [[ThrowTypeError]]: ' + tte; | 3059 return 'Unexpected %ThrowTypeError%: ' + tte; |
2888 } | 3060 } |
2889 var others = []; | 3061 var others = []; |
2890 strictForEachFn([ | 3062 var triples = [ |
kpreid2
2015/02/20 22:02:37
call this something less generic like "sourcesOfTT
MarkM
2015/02/21 02:34:24
Done.
| |
2891 [Function.prototype, 'Function.prototype', ['caller', 'arguments']], | 3063 [Function.prototype, 'Function.prototype', ['caller', 'arguments']], |
2892 [builtInMapMethod, 'builtin function', ['caller', 'arguments']], | 3064 [builtInMapMethod, 'builtin function', ['caller', 'arguments']], |
2893 [strictArguments, 'strict function', ['caller', 'arguments']], | 3065 [strictArguments, 'strict function', ['caller', 'arguments']], |
2894 [sloppyArguments, 'sloppy function', ['caller', 'arguments']], | 3066 [sloppyArguments, 'sloppy function', ['caller', 'arguments']], |
2895 [strictArguments(), 'strict arguments', ['caller', 'callee']], | 3067 [strictArguments(), 'strict arguments', ['caller', 'callee']], |
2896 [sloppyArguments(), 'sloppy arguments', ['caller', 'callee']] | 3068 [sloppyArguments(), 'sloppy arguments', ['caller', 'callee']] |
2897 ], function(triple) { | 3069 ]; |
3070 if (strictArgumentsGenerator) { | |
3071 var strictGeneratedArgs = strictArgumentsGenerator().next().value; | |
3072 triples.push( | |
3073 [strictArgumentsGenerator, 'strict generator', ['caller', 'arguments']], | |
3074 [strictGeneratedArgs, 'strict generated arguments', | |
3075 ['caller', 'callee']]); | |
3076 } | |
3077 var Generator = ses.earlyUndeniables['%Generator%']; | |
3078 if (Generator) { | |
3079 triples.push([Generator, '%Generator%', ['caller', 'arguments']]); | |
3080 } | |
3081 var GeneratorFunction = unsafeIntrinsics.GeneratorFunction; | |
3082 if (GeneratorFunction) { | |
3083 triples.push([GeneratorFunction, '%GeneratorFunction%', | |
3084 ['caller', 'arguments']]); | |
3085 } | |
3086 | |
3087 strictForEachFn(triples, function(triple) { | |
2898 var base = triple[0]; | 3088 var base = triple[0]; |
2899 var where = triple[1]; | 3089 var where = triple[1]; |
2900 var names = triple[2]; | 3090 var names = triple[2]; |
2901 strictForEachFn(names, function(name) { | 3091 strictForEachFn(names, function(name) { |
2902 var desc = Object.getOwnPropertyDescriptor(base, name); | 3092 var desc = Object.getOwnPropertyDescriptor(base, name); |
2903 if (!desc) { return; } | 3093 if (!desc) { return; } |
2904 strictForEachFn(['get', 'set'], function (attr) { | 3094 strictForEachFn(['get', 'set'], function (attr) { |
2905 var otherTTE = desc[attr]; | 3095 var otherTTE = desc[attr]; |
2906 if (!otherTTE || otherTTE === tte) { return; } | 3096 if (!otherTTE || otherTTE === tte) { return; } |
2907 others.push(where + ' ' + attr + ' ' + name); | 3097 others.push(where + ' ' + attr + ' ' + name); |
2908 }); | 3098 }); |
2909 }); | 3099 }); |
2910 }); | 3100 }); |
2911 if (others.length === 0) { return false; } | 3101 if (others.length === 0) { return false; } |
2912 return 'Multiple [[ThrowTypeError]]s: ' + others.join(', '); | 3102 return 'Multiple %ThrowTypeError%s: ' + others.join(', '); |
2913 } | 3103 } |
2914 | 3104 |
2915 /** | 3105 /** |
2916 * [[ThrowTypeError]] is extensible or has modifiable properties. | 3106 * %ThrowTypeError% is extensible or has modifiable properties. |
2917 */ | 3107 */ |
2918 function test_THROWTYPEERROR_UNFROZEN() { | 3108 function test_THROWTYPEERROR_UNFROZEN() { |
2919 return !Object.isFrozen(getThrowTypeError()); | 3109 return !Object.isFrozen(unsafeIntrinsics.ThrowTypeError); |
2920 } | 3110 } |
2921 | 3111 |
2922 /** | 3112 /** |
2923 * [[ThrowTypeError]] has properties which the spec gives to other function | 3113 * %ThrowTypeError% has properties which the spec gives to other function |
2924 * objects but not [[ThrowTypeError]]. | 3114 * objects but not %ThrowTypeError%. |
2925 * | 3115 * |
2926 * We don't check for arbitrary properties because they might be extensions | 3116 * We don't check for arbitrary properties because they might be extensions |
2927 * for all function objects, which we don't particularly want to complain | 3117 * for all function objects, which we don't particularly want to complain |
2928 * about (and will delete via whitelisting). | 3118 * about (and will delete via whitelisting). |
2929 */ | 3119 */ |
2930 function test_THROWTYPEERROR_PROPERTIES() { | 3120 function test_THROWTYPEERROR_PROPERTIES() { |
2931 var tte = getThrowTypeError(); | 3121 var tte = unsafeIntrinsics.ThrowTypeError; |
2932 return !!Object.getOwnPropertyDescriptor(tte, 'prototype') || | 3122 return !!Object.getOwnPropertyDescriptor(tte, 'prototype') || |
2933 !!Object.getOwnPropertyDescriptor(tte, 'arguments') || | 3123 !!Object.getOwnPropertyDescriptor(tte, 'arguments') || |
2934 !!Object.getOwnPropertyDescriptor(tte, 'caller'); | 3124 !!Object.getOwnPropertyDescriptor(tte, 'caller'); |
2935 } | 3125 } |
2936 | 3126 |
2937 /** | 3127 /** |
2938 * See https://code.google.com/p/v8/issues/detail?id=2728 | 3128 * See https://code.google.com/p/v8/issues/detail?id=2728 |
2939 * and https://code.google.com/p/google-caja/issues/detail?id=1616 | 3129 * and https://code.google.com/p/google-caja/issues/detail?id=1616 |
2940 */ | 3130 */ |
2941 function test_SYNTAX_ERRORS_ARENT_ALWAYS_EARLY() { | 3131 function test_SYNTAX_ERRORS_ARENT_ALWAYS_EARLY() { |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3180 } else { | 3370 } else { |
3181 return 'Unexpected prototype identity from setting a function\'s ' + | 3371 return 'Unexpected prototype identity from setting a function\'s ' + |
3182 'prototype with defineProperty.'; | 3372 'prototype with defineProperty.'; |
3183 } | 3373 } |
3184 } else { | 3374 } else { |
3185 return 'Unexpected result of setting a function\'s prototype ' + | 3375 return 'Unexpected result of setting a function\'s prototype ' + |
3186 'with defineProperty: ' + typeof bar.prototype; | 3376 'with defineProperty: ' + typeof bar.prototype; |
3187 } | 3377 } |
3188 } | 3378 } |
3189 | 3379 |
3380 /** | |
3381 * In ES6, the constructor property of the %Generator% intrinsic | |
3382 * initially points at the unsafe %GeneratorFunction% intrinsic. This | |
3383 * property is | |
kpreid2
2015/02/20 22:02:37
stray line break
MarkM
2015/02/21 02:34:24
Done.
| |
3384 * supposed to have attributes | |
3385 * { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true } | |
3386 * Prior to 2/19/2015, on v8 it had attributes | |
3387 * { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false } | |
3388 * making it impossible to change the property's value. | |
3389 * | |
3390 * <p>Since the original %GeneratorFunction% intrinsic, like the | |
3391 * global Function constructor, accepts a function body which it | |
3392 * executes in the global scope, it would be reachable by any | |
3393 * generator. Without parsing, we would not be able to prevent | |
3394 * the following expression | |
3395 * <pre> | |
3396 * (function*(){}).constructor('yield window;')().next().value | |
3397 * </pre> | |
3398 * from providing the genuine global window object of that realm. | |
3399 */ | |
3400 function test_GENERATORFUNCTION_CANNOT_BE_DENIED() { | |
kpreid2
2015/02/20 22:02:37
Why does this need to be a test? Won't clean() fai
MarkM
2015/02/21 02:34:24
This way, the failure, which we know to expect on
| |
3401 var gopd = Object.getOwnPropertyDescriptor; | |
3402 var getProto = Object.getPrototypeOf; | |
3403 | |
3404 var UnsafeGeneratorFunction = unsafeIntrinsics.GeneratorFunction; | |
3405 if (!UnsafeGeneratorFunction) { return false; } | |
3406 var Generator = ses.earlyUndeniables['%Generator%']; | |
3407 if (!Generator || | |
kpreid2
2015/02/20 22:02:37
I think this would be better written as !(... && .
MarkM
2015/02/21 02:34:24
Done. Amazing how much better that is.
| |
3408 Generator.constructor !== UnsafeGeneratorFunction || | |
3409 UnsafeGeneratorFunction.prototype !== Generator || | |
3410 getProto(UnsafeGeneratorFunction) !== UnsafeFunction || | |
3411 getProto(Generator) !== Function.prototype) { | |
3412 return 'Unexpected primordial Generator arrangement'; | |
3413 } | |
3414 var desc = gopd(Generator, 'constructor'); | |
3415 return desc.writable === false && desc.configurable === false; | |
3416 } | |
3417 | |
3418 | |
3190 ////////////////////// Repairs ///////////////////// | 3419 ////////////////////// Repairs ///////////////////// |
3191 // | 3420 // |
3192 // Each repair_NAME function exists primarily to repair the problem | 3421 // Each repair_NAME function exists primarily to repair the problem |
3193 // indicated by the corresponding test_NAME function. But other test | 3422 // indicated by the corresponding test_NAME function. But other test |
3194 // failures can still trigger a given repair. | 3423 // failures can still trigger a given repair. |
3195 | 3424 |
3196 | 3425 |
3197 var call = Function.prototype.call; | 3426 var call = Function.prototype.call; |
3198 var apply = Function.prototype.apply; | 3427 var apply = Function.prototype.apply; |
3199 | 3428 |
(...skipping 1305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4505 { | 4734 { |
4506 id: 'BOUND_FUNCTION_LEAKS_ARGUMENTS', | 4735 id: 'BOUND_FUNCTION_LEAKS_ARGUMENTS', |
4507 description: 'Bound functions leak "arguments"', | 4736 description: 'Bound functions leak "arguments"', |
4508 test: test_BOUND_FUNCTION_LEAKS_ARGUMENTS, | 4737 test: test_BOUND_FUNCTION_LEAKS_ARGUMENTS, |
4509 repair: void 0, | 4738 repair: void 0, |
4510 preSeverity: severities.NOT_OCAP_SAFE, | 4739 preSeverity: severities.NOT_OCAP_SAFE, |
4511 canRepair: false, // Long-dead bug, not worth keeping old repair around | 4740 canRepair: false, // Long-dead bug, not worth keeping old repair around |
4512 urls: ['https://code.google.com/p/v8/issues/detail?id=893', | 4741 urls: ['https://code.google.com/p/v8/issues/detail?id=893', |
4513 'https://bugs.webkit.org/show_bug.cgi?id=63398'], | 4742 'https://bugs.webkit.org/show_bug.cgi?id=63398'], |
4514 sections: ['15.3.4.5'], | 4743 sections: ['15.3.4.5'], |
4515 tests: ['test/language/statements/function/S13.2.3_A1.js', | 4744 tests: ['test/language/statements/function/S13.2.3_A1.js', |
4516 'test/built-ins/Function/prototype/bind/S15.3.4.5_A2.js'] | 4745 'test/built-ins/Function/prototype/bind/S15.3.4.5_A2.js'] |
4517 }, | 4746 }, |
4518 { | 4747 { |
4519 id: 'DELETED_BUILTINS_IN_OWN_NAMES', | 4748 id: 'DELETED_BUILTINS_IN_OWN_NAMES', |
4520 description: 'Deleting built-in leaves phantom behind', | 4749 description: 'Deleting built-in leaves phantom behind', |
4521 test: test_DELETED_BUILTINS_IN_OWN_NAMES, | 4750 test: test_DELETED_BUILTINS_IN_OWN_NAMES, |
4522 repair: void 0, | 4751 repair: void 0, |
4523 preSeverity: severities.SAFE_SPEC_VIOLATION, | 4752 preSeverity: severities.SAFE_SPEC_VIOLATION, |
4524 canRepair: false, // Long-dead bug, not worth keeping old repair around | 4753 canRepair: false, // Long-dead bug, not worth keeping old repair around |
4525 urls: ['https://bugs.webkit.org/show_bug.cgi?id=70207'], | 4754 urls: ['https://bugs.webkit.org/show_bug.cgi?id=70207'], |
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4888 test: test_FREEZING_BREAKS_WEAKMAP, | 5117 test: test_FREEZING_BREAKS_WEAKMAP, |
4889 repair: repair_FREEZING_BREAKS_WEAKMAP, | 5118 repair: repair_FREEZING_BREAKS_WEAKMAP, |
4890 preSeverity: severities.UNSAFE_SPEC_VIOLATION, | 5119 preSeverity: severities.UNSAFE_SPEC_VIOLATION, |
4891 canRepair: true, | 5120 canRepair: true, |
4892 urls: ['https://code.google.com/p/v8/issues/detail?id=2829'], | 5121 urls: ['https://code.google.com/p/v8/issues/detail?id=2829'], |
4893 sections: [], // TODO(kpreid): cite when ES6 is final | 5122 sections: [], // TODO(kpreid): cite when ES6 is final |
4894 tests: [] // TODO(kpreid): cite when ES6 is final | 5123 tests: [] // TODO(kpreid): cite when ES6 is final |
4895 }, | 5124 }, |
4896 { | 5125 { |
4897 id: 'THROWTYPEERROR_NOT_UNIQUE', | 5126 id: 'THROWTYPEERROR_NOT_UNIQUE', |
4898 description: '[[ThrowTypeError]] is not unique', | 5127 description: '%ThrowTypeError% is not unique', |
4899 test: test_THROWTYPEERROR_NOT_UNIQUE, | 5128 test: test_THROWTYPEERROR_NOT_UNIQUE, |
4900 repair: void 0, | 5129 repair: void 0, |
4901 preSeverity: severities.UNSAFE_SPEC_VIOLATION, | 5130 preSeverity: severities.UNSAFE_SPEC_VIOLATION, |
4902 canRepair: false, | 5131 canRepair: false, |
4903 urls: [], | 5132 urls: [], |
4904 sections: [], | 5133 sections: [], |
4905 tests: [] | 5134 tests: [] |
4906 }, | 5135 }, |
4907 { | 5136 { |
4908 id: 'THROWTYPEERROR_UNFROZEN', | 5137 id: 'THROWTYPEERROR_UNFROZEN', |
4909 description: '[[ThrowTypeError]] is not frozen', | 5138 description: '%ThrowTypeError% is not frozen', |
4910 test: test_THROWTYPEERROR_UNFROZEN, | 5139 test: test_THROWTYPEERROR_UNFROZEN, |
4911 repair: void 0, | 5140 repair: void 0, |
4912 preSeverity: severities.SAFE_SPEC_VIOLATION, // Note: Safe only because | 5141 preSeverity: severities.SAFE_SPEC_VIOLATION, // Note: Safe only because |
4913 // startSES will do whitelist and defense; per spec intent it's an | 5142 // startSES will do whitelist and defense; per spec intent it's an |
4914 // undesired communication channel. | 5143 // undesired communication channel. |
4915 canRepair: false, // will be repaired by whitelist | 5144 canRepair: false, // will be repaired by whitelist |
4916 urls: ['https://bugs.webkit.org/show_bug.cgi?id=108873'], | 5145 urls: ['https://bugs.webkit.org/show_bug.cgi?id=108873'], |
4917 // TODO(kpreid): find or file Firefox bug (writable props) | 5146 // TODO(kpreid): find or file Firefox bug (writable props) |
4918 // TODO(kpreid): find or file Chrome bug (has a .prototype) | 5147 // TODO(kpreid): find or file Chrome bug (has a .prototype) |
4919 sections: ['13.2.3'], | 5148 sections: ['13.2.3'], |
4920 tests: [] // TODO(jasvir): Add to test262 | 5149 tests: [] // TODO(jasvir): Add to test262 |
4921 }, | 5150 }, |
4922 { | 5151 { |
4923 id: 'THROWTYPEERROR_PROPERTIES', | 5152 id: 'THROWTYPEERROR_PROPERTIES', |
4924 description: '[[ThrowTypeError]] has normal function properties', | 5153 description: '%ThrowTypeError% has normal function properties', |
4925 test: test_THROWTYPEERROR_PROPERTIES, | 5154 test: test_THROWTYPEERROR_PROPERTIES, |
4926 repair: void 0, | 5155 repair: void 0, |
4927 preSeverity: severities.SAFE_SPEC_VIOLATION, | 5156 preSeverity: severities.SAFE_SPEC_VIOLATION, |
4928 canRepair: false, // will be repaired by whitelist | 5157 canRepair: false, // will be repaired by whitelist |
4929 urls: [], | 5158 urls: [], |
4930 // WebKit is OK | 5159 // WebKit is OK |
4931 // TODO(kpreid): find or file Firefox bug (has writable props) | 5160 // TODO(kpreid): find or file Firefox bug (has writable props) |
4932 // TODO(kpreid): find or file Chrome bug (has a .prototype!) | 5161 // TODO(kpreid): find or file Chrome bug (has a .prototype!) |
4933 sections: ['13.2.3'], | 5162 sections: ['13.2.3'], |
4934 tests: [] // TODO(jasvir): Add to test262 | 5163 tests: [] // TODO(jasvir): Add to test262 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5002 id: 'NUMERIC_PROPERTIES_INVISIBLE', | 5231 id: 'NUMERIC_PROPERTIES_INVISIBLE', |
5003 description: 'Numeric properties not reflectable on create()d objects', | 5232 description: 'Numeric properties not reflectable on create()d objects', |
5004 test: test_NUMERIC_PROPERTIES_INVISIBLE, | 5233 test: test_NUMERIC_PROPERTIES_INVISIBLE, |
5005 repair: repair_NUMERIC_PROPERTIES_INVISIBLE, | 5234 repair: repair_NUMERIC_PROPERTIES_INVISIBLE, |
5006 preSeverity: severities.UNSAFE_SPEC_VIOLATION, | 5235 preSeverity: severities.UNSAFE_SPEC_VIOLATION, |
5007 canRepair: true, | 5236 canRepair: true, |
5008 urls: ['http://webreflection.blogspot.co.uk/2014/04/all-ie-objects-are-bro ken.html'], | 5237 urls: ['http://webreflection.blogspot.co.uk/2014/04/all-ie-objects-are-bro ken.html'], |
5009 // TODO(kpreid): link Microsoft info page when available | 5238 // TODO(kpreid): link Microsoft info page when available |
5010 sections: ['8.12.6'], | 5239 sections: ['8.12.6'], |
5011 tests: [] // TODO(kpreid): contribute tests | 5240 tests: [] // TODO(kpreid): contribute tests |
5012 } | 5241 }, |
5242 { | |
5243 id: 'GENERATORFUNCTION_CANNOT_BE_DENIED', | |
5244 description: 'Cannot deny access to unsafe %GeneratorFunction%', | |
5245 test: test_GENERATORFUNCTION_CANNOT_BE_DENIED, | |
5246 repair: void 0, | |
5247 preSeverity: severities.NOT_ISOLATED, | |
5248 canRepair: false, | |
5249 urls: ['https://code.google.com/p/google-caja/issues/detail?id=1953', | |
kpreid2
2015/02/20 22:02:37
We don't generally put our own bug URLs in here.
MarkM
2015/02/21 02:34:24
We do, and I don't see any reason not to.
| |
5250 'https://code.google.com/p/v8/issues/detail?id=3902', | |
5251 'https://code.google.com/p/chromium/issues/detail?id=460145', | |
5252 'https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generato rfunction.prototype.constructor'], | |
5253 sections: [], | |
5254 tests: [] | |
5255 }, | |
5013 ]; | 5256 ]; |
5014 | 5257 |
5015 // SPLICE_PUT_IGNORES_FIRST_READONLY | 5258 // SPLICE_PUT_IGNORES_FIRST_READONLY |
5016 // SPLICE_PUT_DOESNT_THROW_FIRST_READONLY | 5259 // SPLICE_PUT_DOESNT_THROW_FIRST_READONLY |
5017 // SPLICE_PUT_IGNORES_FIRST_NON_WRITABLE | 5260 // SPLICE_PUT_IGNORES_FIRST_NON_WRITABLE |
5018 // SPLICE_PUT_DOESNT_THROW_FIRST_NON_WRITABLE | 5261 // SPLICE_PUT_DOESNT_THROW_FIRST_NON_WRITABLE |
5019 // SPLICE_PUT_IGNORES_LAST_READONLY | 5262 // SPLICE_PUT_IGNORES_LAST_READONLY |
5020 // SPLICE_PUT_DOESNT_THROW_LAST_READONLY | 5263 // SPLICE_PUT_DOESNT_THROW_LAST_READONLY |
5021 arrayPutProblem(supportedProblems, | 5264 arrayPutProblem(supportedProblems, |
5022 'splice', [0, 0, 'a'], 0, 'a', 'readonly'); | 5265 'splice', [0, 0, 'a'], 0, 'a', 'readonly'); |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5157 ses.es5ProblemReports = indexedReports; | 5400 ses.es5ProblemReports = indexedReports; |
5158 } catch (err) { | 5401 } catch (err) { |
5159 ses._repairer.updateMaxSeverity(ses.severities.NOT_SUPPORTED); | 5402 ses._repairer.updateMaxSeverity(ses.severities.NOT_SUPPORTED); |
5160 var during = ses._repairer.wasDoing(); | 5403 var during = ses._repairer.wasDoing(); |
5161 logger.error('ES5 Repair ' + during + 'failed with: ', err); | 5404 logger.error('ES5 Repair ' + during + 'failed with: ', err); |
5162 } | 5405 } |
5163 | 5406 |
5164 logger.reportMax(); | 5407 logger.reportMax(); |
5165 | 5408 |
5166 })(this); | 5409 })(this); |
OLD | NEW |