]> source.dussan.org Git - gwtquery.git/commitdiff
use JSON.parse when available when parsing properties to avoid security issues
authorManolo Carrasco <manolo@apache.org>
Fri, 23 Sep 2011 14:19:02 +0000 (14:19 +0000)
committerManolo Carrasco <manolo@apache.org>
Fri, 23 Sep 2011 14:19:02 +0000 (14:19 +0000)
gwtquery-core/src/main/java/com/google/gwt/query/client/Properties.java
gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsUtils.java
gwtquery-core/src/test/java/com/google/gwt/query/client/JreQueryCoreTest.java

index 3aefed3075158a908db93b442ceb090cab6dfe6f..125981e86fcf33d128f2251fd40fd4224c08c3e5 100644 (file)
@@ -18,6 +18,7 @@ package com.google.gwt.query.client;
 import com.google.gwt.core.client.JavaScriptObject;\r
 import com.google.gwt.core.client.JsArrayMixed;\r
 import com.google.gwt.query.client.js.JsCache;\r
+import com.google.gwt.query.client.js.JsUtils;\r
 \r
 /**\r
  * JSO for accessing Javascript objective literals used by GwtQuery functions.\r
@@ -25,14 +26,14 @@ import com.google.gwt.query.client.js.JsCache;
 public class Properties extends JavaScriptObject {\r
   \r
   public static Properties create() {\r
-    return createImpl("({})");\r
+    return JsCache.create().cast();\r
   }\r
   \r
   public static Properties create(String properties) {\r
     if (properties != null && !properties.isEmpty()) {\r
       String p = wrapPropertiesString(properties);\r
       try {\r
-        return createImpl("({" + p + "})");\r
+        return JsUtils.parseJSON(p);\r
       } catch (Exception e) {\r
         System.err.println("Error creating Properties: \n> " + properties  + "\n< " + p + "\n" + e.getMessage());\r
       }\r
@@ -40,24 +41,26 @@ public class Properties extends JavaScriptObject {
     return create();\r
   }\r
 \r
-  public static final native Properties createImpl(String properties) /*-{\r
-    return eval(properties);\r
-  }-*/;\r
-\r
   public static String wrapPropertiesString(String s) {\r
     String ret = s //\r
         .replaceAll("\\s*/\\*[\\s\\S]*?\\*/\\s*", "") // Remove comments\r
         .replaceAll("([:\\)\\(,;}{'\"])\\s+" , "$1") // Remove spaces\r
         .replaceAll("\\s+([:\\)\\(,;}{'\"])" , "$1") // Remove spaces\r
-        .replaceFirst("^[{\\(]+(|.*[^}\\)])[}\\)]+$", "$1") // Remove ({})\r
-        .replaceAll("\\(\"([^\\)]+)\"\\)" , "($1)") // Remove quotes\r
-        .replaceAll(",+([\\w-]+:+)" , ";$1") // put semicolon\r
-        .replaceAll(":\\s*[\"']?([^'\"\\]};]*)[\"']?\\s*(;+|$)", ":\"$1\",") // put quotes to all values (even empty)\r
-        .replaceAll("(^|[^\\w-$'])([\\w-]+):\"", "$1\"$2\":\"") // quote keys\r
+        .replaceFirst("^[\\(]+(.*)[\\)]+$", "$1") // Remove ()\r
+        .replaceAll("\\([\"']([^\\)]+)[\"']\\)" , "($1)") // Remove quotes\r
+        .replaceAll("[;,]+([\\w-]+):", ";$1:") // Change comma by semicolon\r
+        .replaceAll("([^,;])([\\]}])", "$1;$2") // Put control semicolon used below\r
+        .replaceAll(":\\s*[\"']?([^;\\{\\}\\[\\]\"']*)[\"']?\\s*([;,]+|$)", ":\"$1\";") // put quotes to all values (even empty)\r
+        .replaceAll("[;,]+([\\w-]+):", ";$1:") // Change semicolon by comma\r
+        .replaceAll("(^|[^\\w-$'])([\\w-]+):(['\"\\[{])", "$1\"$2\":$3") // quote keys\r
+        .replaceAll("(^|[^\\w-$'])([\\w-]+):(['\"\\[{])", "$1\"$2\":$3") // quote keys second pass\r
+        .replaceAll("(|[\\[\\]\\{\\},\\(])'([^']*)'", "$1\"$2\"") // Replace single-quote by double-quote\r
         .replaceAll(";([^:]+):", ",$1:") // change semicolon\r
-        .replaceAll(":\"(-?[\\d\\.]+|null|false|true)\",", ":$1,") // numbers do not need quote\r
-        .replaceFirst("[,]+$", "") // remove endings \r
+        .replaceAll(";([^:]+):", ",$1:") // change semicolon second pass\r
+        .replaceAll(":\"(-?[\\d\\.]+|null|false|true)\"[;,]", ":$1,") // numbers do not need quote\r
+        .replaceAll("[;,]+([\\]\\}]|$)", "$1") // remove endings \r
         ;\r
+    ret = ret.matches("(^[\\[\\{].*[\\]\\}]$)") ? ret : "{" + ret + "}";\r
     return ret;\r
   }\r
   \r
index 4145dd1e77b03a9ad9e972fe78d9e370ccfdd807..bb923dcfd9ce5c4008265673d7e5afc4176f04ea 100644 (file)
@@ -73,9 +73,13 @@ public class JsUtils {
     public Properties parseJSON(String json) {
       // No checks to the passed string so json should be
       // a well-formed json string.
-      return Properties.createImpl(json);
+      return evalImpl("(" + json + ")");
     }
     
+    public static final native Properties evalImpl(String properties) /*-{
+      return eval(properties);
+    }-*/;
+    
     @Override
     public native String XML2String(JavaScriptObject o) /*-{
       return o.xml;
index 2b3d7c000ef16cc9f87c82eb92a16e53cd9f2bb7..e91190fb1886ff630d3a6207fca879956e7b72ac 100644 (file)
@@ -34,32 +34,22 @@ public class JreQueryCoreTest extends GWTTestCase {
   }
 
   public void testWrapPropertiesString() {
-    assertEquals("({})", Properties
+    assertEquals("{}", Properties
         .wrapPropertiesString(""));
-    assertEquals("({})", Properties
+    assertEquals("{}", Properties
         .wrapPropertiesString("({})"));
-    assertEquals("({border:'1px solid black'})", Properties
+    assertEquals("{\"border\":\"1px solid black\"}", Properties
         .wrapPropertiesString("border:'1px solid black'"));
-    assertEquals("({border:'1px solid black'})", Properties
-        .wrapPropertiesString("(border:'1px solid black')"));
-    assertEquals("({border:'1px solid black'})", Properties
-        .wrapPropertiesString("{border:'1px solid black'}"));
-    assertEquals("({border:'1px solid black'})", Properties
-        .wrapPropertiesString("{border:'1px solid black'}"));
-    assertEquals("({border:'1px solid black'})", Properties
-        .wrapPropertiesString("(border:'1px solid black')"));
-    assertEquals("({border:'1px solid black'})", Properties
-        .wrapPropertiesString("{(border:'1px solid black')}"));
-    assertEquals("({border:'1px solid black'})", Properties
-        .wrapPropertiesString("({border:'1px solid black'})"));
-    assertEquals("({b:'a',c:1,d:'url(https://test.com)',e:null,f:false})", Properties
+    assertEquals("{\"b\":\"a\",\"c\":1,\"d\":\"url(https://test.com)\",\"e\":null,\"f\":false}", Properties
         .wrapPropertiesString("b: 'a'; c: 1, /*gg: aadf*/d: url('https://test.com');,e:null,f:false"));
-    assertEquals("({color:'rgb(0,0,139)',background:'red'})", Properties
+    assertEquals("{\"color\":\"rgb(0,0,139)\",\"background\":\"red\"}", Properties
         .wrapPropertiesString("color: 'rgb(0, 0,139)', background: red"));
-    assertEquals("({width:'',top:''})", Properties
+    assertEquals("{\"width\":\"\",\"top\":\"\"}", Properties
         .wrapPropertiesString("width: '' ; top:'' ;"));
-    assertEquals("({'border-left':'solid'})", Properties
+    assertEquals("{\"border-left\":\"solid\"}", Properties
         .wrapPropertiesString("border-left: solid"));
+    assertEquals("[{\"a\":1,\"b\":{\"a\":2,\"b\":{\"a\":3}},\"u\":\"url\",\"d\":2,\"t\":[\"hola\",\"adios\"],\"z\":true}]", Properties
+        .wrapPropertiesString("[{a:1, b:{a:2,b:{a:3}},u:url, d:'2','t':['hola','adios'], 'z': true}]"));
   }
 
 }