Revision: 5686
Author:   erights
Date:     Mon May 19 18:19:29 2014 UTC
Log:      Adds test for newly reported defineProperty bug with old repair.
https://codereview.appspot.com/96420043

https://code.google.com/p/chromium/issues/detail?id=374327
https://gist.github.com/getify/22ac00ba029e707f19f5
demonstrate that setting a function's prototype with defineProperty
updates its descriptor but not its actual value.

[email protected]

http://code.google.com/p/google-caja/source/detail?r=5686

Modified:
 /trunk/src/com/google/caja/ses/repairES5.js

=======================================
--- /trunk/src/com/google/caja/ses/repairES5.js Fri May 16 16:33:03 2014 UTC
+++ /trunk/src/com/google/caja/ses/repairES5.js Mon May 19 18:19:29 2014 UTC
@@ -2705,6 +2705,36 @@
       return 'Unexpected results from numeric property on created object';
     }
   }
+
+  /**
+   * Tests for https://code.google.com/p/v8/issues/detail?id=3334
+   * which reports that setting a function's prototype with
+   * defineProperty can update its descriptor without updating the
+   * actual value when also changing writable from true to false.
+   */
+  function test_DEFINE_PROPERTY_CONFUSES_FUNC_PROTO() {
+    function bar() {}
+    var oldBarPrototype = bar.prototype;
+    Object.defineProperty(bar, 'prototype', {value: 2, writable: false});
+    var desc = Object.getOwnPropertyDescriptor(bar, 'prototype');
+    if (desc.value !== 2) {
+        return 'Unexpected descriptor from setting a function\'s ' +
+          'protptype with defineProperty: ' + JSON.stringify(desc);
+    }
+    if (bar.prototype === 2) {
+      return false;
+    } else if (typeof bar.prototype === 'object') {
+      if (bar.prototype === oldBarPrototype) {
+        return true;
+      } else {
+ return 'Unexpected prototype identity from setting a function\'s ' +
+          'prototype with defineProperty.';
+      }
+    } else {
+      return 'Unexpected result of setting a function\'s prototype ' +
+        'with defineProperty: ' + typeof bar.prototype;
+    }
+  }

   ////////////////////// Repairs /////////////////////
   //
@@ -2724,8 +2754,9 @@
   var isExtensible = Object.isExtensible;

   /*
-   * Fixes both FUNCTION_PROTOTYPE_DESCRIPTOR_LIES and
-   * DEFINING_READ_ONLY_PROTO_FAILS_SILENTLY.
+   * Fixes FUNCTION_PROTOTYPE_DESCRIPTOR_LIES,
+   * DEFINING_READ_ONLY_PROTO_FAILS_SILENTLY and
+   * DEFINE_PROPERTY_CONFUSES_FUNC_PROTO.
    */
   function repair_DEFINE_PROPERTY() {
     function repairedDefineProperty(base, name, desc) {
@@ -2736,6 +2767,7 @@
           base.prototype = desc.value;
         } catch (err) {
           logger.warn('prototype fixup failed', err);
+          throw err;
         }
       } else if (name === '__proto__' && !isExtensible(base)) {
throw TypeError('Cannot redefine __proto__ on a non-extensible object');
@@ -3998,6 +4030,18 @@
       sections: ['8.6.2'],
       tests: [] // TODO(jasvir): Add to test262
     },
+    {
+      id: 'DEFINE_PROPERTY_CONFUSES_FUNC_PROTO',
+      description: 'Setting a function\'s prototype with defineProperty ' +
+        'doesn\'t change its value',
+      test: test_DEFINE_PROPERTY_CONFUSES_FUNC_PROTO,
+      repair: repair_DEFINE_PROPERTY,
+      preSeverity: severities.UNSAFE_SPEC_VIOLATION,
+      canRepair: true,
+      urls: ['https://code.google.com/p/v8/issues/detail?id=3334'],
+      sections: [],
+      tests: []  // TODO(kpreid): contribute tests
+    },
     {
       id: 'STRICT_EVAL_LEAKS_GLOBAL_VARS',
       description: 'Strict eval function leaks variable definitions',
@@ -4449,7 +4493,7 @@
       strictForEachFn(supportedProblems, ses._repairer.registerProblem);
       ses._repairer.testAndRepair();
     }
-
+
     var reports = ses._repairer.getReports();

     // Made available to allow for later code reusing our diagnoses to work

--

--- You received this message because you are subscribed to the Google Groups "Google Caja Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to