From b6ae9f071accf522b96eef3a94ebdde484b2edb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20B=C3=BCnzli?= Date: Mon, 17 Nov 2008 13:57:43 +0000 Subject: [PATCH] Bug 462774: Drop JSON.jsm. r=gavin, r=sayrer, sr=brendan, a1.9.1b2=beltzner --- browser/installer/removed-files.in | 1 + js/src/xpconnect/loader/JSON.jsm | 178 ----------------------- js/src/xpconnect/loader/Makefile.in | 2 +- js/src/xpconnect/tests/unit/test_json.js | 131 ----------------- 4 files changed, 2 insertions(+), 310 deletions(-) delete mode 100644 js/src/xpconnect/loader/JSON.jsm delete mode 100644 js/src/xpconnect/tests/unit/test_json.js diff --git a/browser/installer/removed-files.in b/browser/installer/removed-files.in index 4bf016300f30..0ea7e669ef71 100644 --- a/browser/installer/removed-files.in +++ b/browser/installer/removed-files.in @@ -584,6 +584,7 @@ components/nsXmlRpcClient.js components/nsInterfaceInfoToIDL.js components/nsScriptableIO.js chrome/chromelist.txt +modules/JSON.jsm #ifdef XP_MACOSX LICENSE extensions/inspector@mozilla.org/chrome/chromelist.txt diff --git a/js/src/xpconnect/loader/JSON.jsm b/js/src/xpconnect/loader/JSON.jsm deleted file mode 100644 index 639f8749ffb7..000000000000 --- a/js/src/xpconnect/loader/JSON.jsm +++ /dev/null @@ -1,178 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla code. - * - * The Initial Developer of the Original Code is - * Simon Bünzli - * Portions created by the Initial Developer are Copyright (C) 2006-2007 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/** - * Utilities for JavaScript code to handle JSON content. - * See http://www.json.org/ for comprehensive information about JSON. - * - * Import this module through - * - * Components.utils.import("resource://gre/modules/JSON.jsm"); - * - * Usage: - * - * var newJSONString = JSONModule.toString( GIVEN_JAVASCRIPT_OBJECT ); - * var newJavaScriptObject = JSONModule.fromString( GIVEN_JSON_STRING ); - * - * Note: For your own safety, Objects/Arrays returned by - * JSONModule.fromString aren't instanceof Object/Array. - */ - -var EXPORTED_SYMBOLS = ["JSONModule"]; - -// The following code is a loose adaption of Douglas Crockford's code -// from http://www.json.org/json.js (public domain'd) - -// Notable differences: -// * Unserializable values such as |undefined| or functions aren't -// silently dropped but always lead to a TypeError. -// * An optional key blacklist has been added to JSON.toString - -var JSONModule = { - /** - * Converts a JavaScript object into a JSON string. - * - * @param aJSObject is the object to be converted - * @param aKeysToDrop is an optional array of keys which will be - * ignored in all objects during the serialization - * @return the object's JSON representation - * - * Note: aJSObject MUST not contain cyclic references. - */ - toString: function JSON_toString(aJSObject, aKeysToDrop) { - // we use a single string builder for efficiency reasons - var pieces = []; - - // this recursive function walks through all objects and appends their - // JSON representation (in one or several pieces) to the string builder - function append_piece(aObj) { - if (typeof aObj == "string") { - aObj = aObj.replace(/[\\"\x00-\x1F\u0080-\uFFFF]/g, function($0) { - // use the special escape notation if one exists, otherwise - // produce a general unicode escape sequence - switch ($0) { - case "\b": return "\\b"; - case "\t": return "\\t"; - case "\n": return "\\n"; - case "\f": return "\\f"; - case "\r": return "\\r"; - case '"': return '\\"'; - case "\\": return "\\\\"; - } - return "\\u" + ("0000" + $0.charCodeAt(0).toString(16)).slice(-4); - }); - pieces.push('"' + aObj + '"') - } - else if (typeof aObj == "boolean") { - pieces.push(aObj ? "true" : "false"); - } - else if (typeof aObj == "number" && isFinite(aObj)) { - // there is no representation for infinite numbers or for NaN! - pieces.push(aObj.toString()); - } - else if (aObj === null) { - pieces.push("null"); - } - // if it looks like an array, treat it as such - this is required - // for all arrays from either outside this module or a sandbox - else if (aObj instanceof Array || - typeof aObj == "object" && "length" in aObj && - (aObj.length === 0 || aObj[aObj.length - 1] !== undefined)) { - pieces.push("["); - for (var i = 0; i < aObj.length; i++) { - arguments.callee(aObj[i]); - pieces.push(","); - } - if (aObj.length > 0) - pieces.pop(); // drop the trailing colon - pieces.push("]"); - } - else if (typeof aObj == "object") { - pieces.push("{"); - for (var key in aObj) { - // allow callers to pass objects containing private data which - // they don't want the JSON string to contain (so they don't - // have to manually pre-process the object) - if (aKeysToDrop && aKeysToDrop.indexOf(key) != -1) - continue; - - arguments.callee(key.toString()); - pieces.push(":"); - arguments.callee(aObj[key]); - pieces.push(","); - } - if (pieces[pieces.length - 1] == ",") - pieces.pop(); // drop the trailing colon - pieces.push("}"); - } - else { - throw new TypeError("No JSON representation for this object!"); - } - } - append_piece(aJSObject); - - return pieces.join(""); - }, - - /** - * Converts a JSON string into a JavaScript object. - * - * @param aJSONString is the string to be converted - * @return a JavaScript object for the given JSON representation - */ - fromString: function JSON_fromString(aJSONString) { - if (!this.isMostlyHarmless(aJSONString)) - throw new SyntaxError("No valid JSON string!"); - - var s = new Components.utils.Sandbox("about:blank"); - return Components.utils.evalInSandbox("(" + aJSONString + ")", s); - }, - - /** - * Checks whether the given string contains potentially harmful - * content which might be executed during its evaluation - * (no parser, thus not 100% safe! Best to use a Sandbox for evaluation) - * - * @param aString is the string to be tested - * @return a boolean - */ - isMostlyHarmless: function JSON_isMostlyHarmless(aString) { - const maybeHarmful = /[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/; - const jsonStrings = /"(\\.|[^"\\\n\r])*"/g; - - return !maybeHarmful.test(aString.replace(jsonStrings, "")); - } -}; diff --git a/js/src/xpconnect/loader/Makefile.in b/js/src/xpconnect/loader/Makefile.in index 6c5a93fd50ff..3b6837c78003 100644 --- a/js/src/xpconnect/loader/Makefile.in +++ b/js/src/xpconnect/loader/Makefile.in @@ -56,7 +56,7 @@ REQUIRES = xpcom \ CPPSRCS = mozJSComponentLoader.cpp mozJSSubScriptLoader.cpp -EXTRA_JS_MODULES = XPCOMUtils.jsm JSON.jsm ISO8601DateUtils.jsm +EXTRA_JS_MODULES = XPCOMUtils.jsm ISO8601DateUtils.jsm include $(topsrcdir)/config/rules.mk diff --git a/js/src/xpconnect/tests/unit/test_json.js b/js/src/xpconnect/tests/unit/test_json.js deleted file mode 100644 index 56744b41958e..000000000000 --- a/js/src/xpconnect/tests/unit/test_json.js +++ /dev/null @@ -1,131 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Simon Bünzli - * Portions created by the Initial Developer are Copyright (C) 2007 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -function run_test() { - // converts an object to a JSON string and tests its integrity - function toJSONString(a) { - var res = JSONModule.toString(a); - if (!JSONModule.isMostlyHarmless(res)) - throw new SyntaxError("Invalid JSON string: " + res); - return res; - } - - // ensures that an object can't be converted to a JSON string - function isInvalidType(a) { - try { - JSONModule.toString(a); - return false; - } catch (ex) { - return ex.name == "TypeError"; - } - } - // ensures that a string can't be converted back to a JavaScript object - function isInvalidSyntax(a) { - try { - JSONModule.fromString(a); - return false; - } catch (ex) { - return ex.name == "SyntaxError"; - } - } - - Components.utils.import("resource://gre/modules/JSON.jsm"); - do_check_eq(typeof(JSONModule), "object"); - - // some of the tests are adapted from /testing/mochitest/tests/test_Base.js - do_check_eq(toJSONString(true), "true"); - do_check_eq(toJSONString(false), "false"); - - do_check_eq(toJSONString(1), "1"); - do_check_eq(toJSONString(1.23), "1.23"); - do_check_eq(toJSONString(1.23e-45), "1.23e-45"); - - do_check_true(isInvalidType(Infinity)); - do_check_true(isInvalidType(NaN)); - - //XXXzeniko: using € instead of \u20ac fails because of encoding issues - do_check_eq(toJSONString("Foo-Bar \b\t\n\f\r\"\\ \x01\u20ac"), - '"Foo-Bar \\b\\t\\n\\f\\r\\"\\\\ \\u0001\\u20ac"'); - - do_check_eq(toJSONString(null), "null"); - do_check_true(isInvalidType(undefined)); - - do_check_eq(toJSONString([1, "2", 3.3]), '[1,"2",3.3]'); - // duck-typed Array (since we'll never really get something instanceof Array) - do_check_eq(toJSONString({ 0: 0, 1: "1", 2: -2.2, length: 3 }), '[0,"1",-2.2]'); - - var obj = { a: 1, b: "2", c: [-3e+30] }; - do_check_eq(toJSONString(obj), '{"a":1,"b":"2","c":[-3e+30]}'); - do_check_eq(JSONModule.toString(obj, ["b", "c"] /* keys to drop */), '{"a":1}'); - - do_check_true(isInvalidType(function() { })); - - // make sure that toJSONString actually works... - do_check_eq(toJSONString(obj), JSONModule.toString(obj)); - - do_check_eq(JSONModule.fromString("true"), true); - do_check_eq(JSONModule.fromString("false"), false); - do_check_eq(JSONModule.fromString("1"), 1); - do_check_eq(JSONModule.fromString('"2.2"'), "2.2"); - do_check_eq(JSONModule.fromString("1.23e-45"), 1.23e-45); - do_check_true(isInvalidSyntax("NaN")); - - do_check_eq(JSONModule.fromString('"Foo-Bar \\b\\t\\n\\f\\r\\"\\\\ \\u0001\\u20ac"'), - "Foo-Bar \b\t\n\f\r\"\\ \x01\u20ac"); - do_check_true(isInvalidSyntax('"multi\nline"')); - do_check_eq(JSONModule.fromString("null"), null); - do_check_true(isInvalidSyntax(".")); - - var res = JSONModule.fromString('[1,"2",3.3]'); - do_check_eq(res.length, 3); - do_check_eq(res[2], 3.3); - // res is an instance of the sandbox's array - do_check_false(res instanceof Array); - - res = JSONModule.fromString(toJSONString(obj)); - do_check_eq(res.a, obj.a); - do_check_eq(res.b, obj.b); - do_check_eq(res.c.length, obj.c.length); - do_check_eq(res.c[0], obj.c[0]); - - // those would throw on JSONModule.fromString if there's no object |a| - do_check_true(JSONModule.isMostlyHarmless("a")); - do_check_true(JSONModule.isMostlyHarmless("a[0]")); - do_check_true(JSONModule.isMostlyHarmless('a["alert(\\"P0wn3d!\\");"]')); - - do_check_false(JSONModule.isMostlyHarmless('(function() { alert("P0wn3d!"); })()')); - do_check_false(JSONModule.isMostlyHarmless('{ get a() { return "P0wn3d!"; } }')); -}