You should take a look at http://tools.ietf.org/html/rfc4627
GWT recommends using the regular expression defined in that RFC. Also, one of their classes (ExternalTextResourcePrototype.java) defines the Regular expression and runs eval.. so you could use the same strategy. See method evalObject in http://code.google.com/p/google-web-toolkit/source/browse/changes/bobv/clientbundle/user/src/com/google/gwt/resources/client/impl/ExternalTextResourcePrototype.java?spec=svn4992&r=4992 Source Code - /** * Evaluate the JSON payload. The regular expression to validate the safety of * the payload is taken from RFC 4627 (D. Crockford). * * @param data the raw JSON-encapsulated string bundle * @return the evaluated JSON object, or <code>null</code> if there is an * error. */ private static native JavaScriptObject evalObject(String data) /*-{ var safe = !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test( data.replace(/"(\\.|[^"\\])*"/g, ''))); if (!safe) { return null; } return eval('(' + data + ')') || null; }-*/; --Sri 2009/10/23 Brendan <[email protected]> > > I realize this post is coming at the end of the day on friday, but > hopefully it will get a look =) > > Going through the different JSON parsing implementations available for > GWT out there, almost all of them rely on a straight eval and note > that they should only be used for trusted code. The old JSONValue code > seems kind of quaint in light of JavaScriptObjects, and looking > through the trunk it looks like there's just a TODO in JsonUtils for > safe parsing. > > Anyway, I don't have that much experience writing JSNI code, so I > wanted to run this small class past you all and see if this aligns > with GWT best practices, if I'm doing anything monumentally stupid, or > if I'm just plain missing something. > > The following is a pretty basic adaptation of Douglas Crockford's > json2.js. When parse() is called, it checks to see if there is a > native JSON defined (which exists in the latest IE, Firefox, Chrome > and Safari) and simply uses that. If not, it defines a $wnd.JSON.parse > in javascript using the json2 code, which is then indistinguishable > from the native functionality in future calls (this tactic comes > straight from json2.js). > > It lazily initializes the JSON object, as defining an entry point > doesn't seem like a big win, and adds a lot of support necessary to > make it happen. It also defines it on the $wnd object...scope still > occasionally confuses me in javascript, but it seemed to make more > sense to define it there than on window. > > Any thoughts? Even drive by comments are useful if it gives me enough > to google. Thanks! > > The code: > /** > * Evaluates a JSON string safely > * > * @param <T> The type of JavaScriptObject that should be returned > * @param jsonString The source JSON text > * @return The evaluated object > * @throws NullPointerException if <code>jsonString</code> is > <code>null</code> > * @throws IllegalArgumentException if <code>jsonString</code> is > empty > * @throws JavaScriptException if <code>jsonString</code> is non- > parseable > */ > public static final <T extends JavaScriptObject> T parse(String > jsonString) { > if (jsonString == null) { > throw new NullPointerException(); > } > > if (jsonString.length() == 0) { > throw new IllegalArgumentException("empty argument"); > } > > // check if JSON variable is defined, if not, call init code > if (isJsonUndefined()) { > defineJSON(); > } > > return nativeParse(jsonString); > } > > private static native <T extends JavaScriptObject> T nativeParse > (String jsonString) /*-{ > return $wnd.JSON.parse(jsonString); > }-*/; > > /** > * simple check to see if JSON object is defined > * will be defined in browsers with native implementation > * otherwise, will need to init manually > * > * @return true if JSON object is undefined > */ > protected static final native boolean isJsonUndefined() /*-{ > return !$wnd.JSON; > }-*/; > > /** > * naive way to define the JSON object *if* not already > * natively defined by browser. straight copy from json2.js. > */ > private static final native void defineJSON() /*-{ > //http://www.JSON.org/json2.js > //2009-09-29 > //Public Domain. > //NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. > //See http://www.JSON.org/js.html > > // Create a JSON object only if one does not already exist. > if (!$wnd.JSON) { > $wnd.JSON = {}; > } > > (function () { > var cx = > /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f > \u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; > > // create parse method if one does not exist > // The parse method takes a text and returns > // a JavaScript value if the text is a valid JSON text. > if (typeof $wnd.JSON.parse !== 'function') { > $wnd.JSON.parse = function (text) { > > var j; > > // first stage, escape sequences > cx.lastIndex = 0; > if (cx.test(text)) { > text = text.replace(cx, function (a) { > return '\\u' + > ('0000' + > a.charCodeAt(0).toString(16)).slice(-4); > }); > } > > // second stage, remove non-JSON patterns > if (/^[\],:{}\s]*$/. > > test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@'). > > replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]? > \d+)?/g, ']'). > replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { > > // third stage, eval > j = eval('(' + text + ')'); > > return j; > > } > > // If the text is not JSON parseable, then a > SyntaxError is thrown. > throw new SyntaxError('JSON.parse'); > }; > } > }()); > > }-*/; > > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en -~----------~----~----~----~------~----~------~--~---
