Revision: 5365
Author:   [email protected]
Date:     Mon Apr 22 11:12:00 2013
Log: Allow overriding inherited properties of Domado objects by assignment.
https://codereview.appspot.com/8649044

* ExpandoProxyHandler no longer treats defineProperty of a property
  name which exists somewhere in the prototype chain differently for
  no good reason.
* ExpandoProxyHandler's reimplementation of assignment no longer
  acts according to the "override mistake" (needed for ES5/3).

Fixes <https://code.google.com/p/google-caja/issues/detail?id=1650>.

[email protected]

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

Modified:
 /trunk/src/com/google/caja/plugin/domado.js
 /trunk/tests/com/google/caja/plugin/es53-test-domado-dom-guest.html

=======================================
--- /trunk/src/com/google/caja/plugin/domado.js Wed Apr 17 11:08:30 2013
+++ /trunk/src/com/google/caja/plugin/domado.js Mon Apr 22 11:12:00 2013
@@ -689,8 +689,8 @@
       if (name === weakMapMagicName) {
         if (descriptor.set === null) descriptor.set = undefined;
         Object.defineProperty(this, 'weakMapMagic', descriptor);
-      } else if (Object.prototype.hasOwnProperty(this.target, name)) {
-        // Forwards everything already defined (not expando).
+      } else if (Object.prototype.hasOwnProperty.call(this.target, name)) {
+        // Forward attempted redefinitions of own properties to the target.
         return ProxyHandler.prototype.defineProperty.call(this, name,
             descriptor);
       } else {
@@ -703,8 +703,8 @@
     ExpandoProxyHandler.prototype['delete'] = function (name) {
       if (name === weakMapMagicName) {
         return false;
-      } else if (Object.prototype.hasOwnProperty(this.target, name)) {
-        // Forwards everything already defined (not expando).
+      } else if (Object.prototype.hasOwnProperty.call(this.target, name)) {
+        // Forward attempted deletions of own properties to the target.
         return ProxyHandler.prototype['delete'].call(this, name);
       } else {
         if (!this.editable) { throw new Error(NOT_EDITABLE); }
@@ -769,11 +769,22 @@
       desc = this.getPropertyDescriptor(name);
       if (desc) {
         if ('writable' in desc) {
-          if (desc.writable) {
-            // fall through
-          } else {
-            return false;
-          }
+ // The commenting-out of the below code corresponds to "fixing the
+          // override mistake". For further information, see
+          // Object.prototype.w___ in ES5/3 and makeTamperProof in SES.
+          //
+          // We need to do the 'fix' here because this proxy trap is a
+ // reimplementation of what otherwise would be JS runtime internal
+          // algorithms, and so not doing the fix would break code which
+          // optimizes on the knowledge that the platform has the fix.
+ // (In particular, cajaVM.def uses nonwritable data properties instead
+          // of accessor properties whenever possible.)
+          //
+          // if (desc.writable) {
+          //   // fall through
+          // } else {
+          //   return false;
+          // }
         } else { // accessor
           if (desc.set) {
             desc.set.call(receiver, val);
=======================================
--- /trunk/tests/com/google/caja/plugin/es53-test-domado-dom-guest.html Thu Apr 18 11:36:23 2013 +++ /trunk/tests/com/google/caja/plugin/es53-test-domado-dom-guest.html Mon Apr 22 11:12:00 2013
@@ -561,6 +561,26 @@
   });
 </script>

+<p id="testExpandoOverride" class="testcontainer">
+  testExpandoOverride: can replace methods on instances
+</p>
+<script type="text/javascript">
+  jsunitRegister('testExpandoOverride',
+                 function testExpandoOverride() {
+    // Example from Angular -- happens to be an event
+    var obj = document.createEvent('HTMLEvents');
+    obj.preventDefault = function() { return 'boo'; };
+    assertEquals('boo', obj.preventDefault());
+
+    // similarly for nodes
+    var obj = document.createElement('span');
+    obj.blur = function() { return 'boo'; };
+    assertEquals('boo', obj.blur());
+
+    pass('testExpandoOverride');
+  });
+</script>
+
 <p id="testEditabilityInNodeLists" class="testcontainer">
   editability in node lists<br>
 </p>

--

--- 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/groups/opt_out.


Reply via email to