Author: metaweta
Date: Tue Jul 14 16:22:45 2009
New Revision: 3572

Modified:
   trunk/src/com/google/caja/cajita.js
   trunk/src/com/google/caja/valija-cajita.js
trunk/tests/com/google/caja/parser/quasiliteral/CommonJsRewriterTestCase.java

Log:
Fix for issue 1067.
http://codereview.appspot.com/93041

If a property is marked canRead, then canReadPub should only
return true if the property actually exists on the object.

[email protected]


Modified: trunk/src/com/google/caja/cajita.js
==============================================================================
--- trunk/src/com/google/caja/cajita.js (original)
+++ trunk/src/com/google/caja/cajita.js Tue Jul 14 16:22:45 2009
@@ -1370,7 +1370,7 @@
     name = String(name);
     if (obj === null) { return false; }
     if (obj === void 0) { return false; }
-    if (obj[name + '_canRead___']) { return true; }
+    if (obj[name + '_canRead___']) { return (name in Object(obj)); }
     if (endsWith__.test(name)) { return false; }
     if (name === 'toString') { return false; }
     if (!isJSONContainer(obj)) { return false; }
@@ -1390,7 +1390,8 @@
    * Implements Cajita's <tt><i>name</i> in <i>obj</i></tt>
    */
   function inPub(name, obj) {
-    if (obj === null || obj === void 0) {
+    var t = typeof obj;
+    if (obj === null || (t !== "object" && t !== "function")) {
       throw new TypeError('invalid "in" operand: ' + obj);
     }
     obj = Object(obj);

Modified: trunk/src/com/google/caja/valija-cajita.js
==============================================================================
--- trunk/src/com/google/caja/valija-cajita.js  (original)
+++ trunk/src/com/google/caja/valija-cajita.js  Tue Jul 14 16:22:45 2009
@@ -264,11 +264,11 @@

     // BUG TODO(erights): figure out why things break when the
     // following line (which really shouldn't be there) is deleted.
-    if (name in obj) { return obj[name];}
+    if (name in new Object(obj)) { return obj[name];}

     var stepParent = getFakeProtoOf(cajita.directConstructor(obj));
     if (stepParent !== (void 0) &&
-        name in stepParent &&
+        name in new Object(stepParent) &&
         name !== 'valueOf') {
       return stepParent[name];
     }
@@ -447,7 +447,7 @@
   }

   function canReadRev(name, obj) {
-    if (name in obj) { return true; }
+    if (name in new Object(obj)) { return true; }
     return name in getSupplement(obj);
   }


Modified: trunk/tests/com/google/caja/parser/quasiliteral/CommonJsRewriterTestCase.java
==============================================================================
--- trunk/tests/com/google/caja/parser/quasiliteral/CommonJsRewriterTestCase.java (original) +++ trunk/tests/com/google/caja/parser/quasiliteral/CommonJsRewriterTestCase.java Tue Jul 14 16:22:45 2009
@@ -25,6 +25,40 @@
 public abstract class CommonJsRewriterTestCase extends RewriterTestCase {

   /**
+   * Tests that "in" works as expected
+   * @throws Exception
+   */
+  public void testIn() throws Exception {
+    assertConsistent(
+        "('length' in {}) && " +
+        "fail('readable property mistaken for existing property');");
+    assertConsistent(
+        "('length' in []) || " +
+        "fail('arrays should have a length');");
+
+    assertConsistent(
+        "('x' in { x: 1 }) || " +
+        "fail('failed to find existing readable property');");
+    assertConsistent(
+        "('y' in { x: 1 }) && " +
+        "fail('found nonexisting property');");
+    assertConsistent(
+        "var flag = true;" +
+        "try { 'length' in '123' }" +
+        "catch (e) { flag = false; }" +
+        "if (flag) { fail ('should throw TypeError'); }" +
+        "true;");
+  }
+
+  /**
+   * Tests that the length property whitelisting works on non-objects
+   * @throws Exception
+   */
+  public void testStringLength() throws Exception {
+    assertConsistent("('123').length;");
+  }
+
+  /**
    * Tests that eval is uncallable.
    */
   public void testEval() throws Exception {

Reply via email to