Skip to content

Commit 8263544

Browse files
committed
* added json-sans-eval credits
* implemented JSON.stringify, based on older implementation by Ruben git-svn-id: svn://svn.ajax.org/platform/source/trunk@2554 3c3c2983-eddd-4584-88e6-321645f70290
1 parent 3aec158 commit 8263544

File tree

2 files changed

+105
-104
lines changed

2 files changed

+105
-104
lines changed

NOTICE

+4
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ The Math.uuid.js library, version 1.4, is copyrighted by Robert Kieffer 2008
6565
(http://www.broofa.com/blog/?p=151) and licensed under a permissive,
6666
non-standard license.
6767

68+
The JSON parser is a modified version of the json-sans-eval JSON parser, rev. 8,
69+
copyighted by Google Inc. 2008 (http://code.google.com/p/json-sans-eval/) and
70+
licensed under the Apache License, Version 2.0.
71+
6872
Other libraries used in this product require their respective headers with
6973
copyright and license notices to remain unchanged in the file(s) containing the
7074
source code.

core/lib/util/json.js

+101-104
Original file line numberDiff line numberDiff line change
@@ -100,47 +100,102 @@ apf.isJson = (function() {
100100
})();
101101

102102
if (!window["JSON"]) {
103-
window["JSON"] = {};
104-
JSON.parse = (function() {
105-
// Will match a value in a well-formed JSON file.
106-
// If the input is not well-formed, may match strangely, but not in an
107-
// unsafe way.
108-
// Since this only matches value tokens, it does not match whitespace,
109-
// colons, or commas.
110-
// The second line of the regex string matches numbers, lines number 4,
111-
// 5 and 6 match a string and line number 5 specifically matches one
112-
// character.
113-
var jsonToken = new RegExp(
103+
window["JSON"] = (function() {
104+
// Will match a value in a well-formed JSON file.
105+
// If the input is not well-formed, may match strangely, but not in an
106+
// unsafe way.
107+
// Since this only matches value tokens, it does not match whitespace,
108+
// colons, or commas.
109+
// The second line of the regex string matches numbers, lines number 4,
110+
// 5 and 6 match a string and line number 5 specifically matches one
111+
// character.
112+
var jsonToken = new RegExp(
114113
'(?:false|true|null|[\\{\\}\\[\\]]|\
115114
(?:-?\\b(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\\b)\
116115
|\
117116
(?:\"\
118117
(?:[^\\0-\\x08\\x0a-\\x1f\"\\\\]|\\\\(?:[\"/\\\\bfnrt]|u[0-9A-Fa-f]{4}))\
119118
*\"))', "g"),
120-
// Matches escape sequences in a string literal
121-
escapeSequence = new RegExp("\\\\(?:([^u])|u(.{4}))", "g"),
122-
// Decodes escape sequences in object literals
123-
escapes = {
124-
"\"": "\"",
125-
"/": "/",
126-
"\\": "\\",
127-
"b": "\b",
128-
"f": "\f",
129-
"n": "\n",
130-
"r": "\r",
131-
"t": "\t"
119+
// Matches escape sequences in a string literal
120+
escapeSequence = new RegExp("\\\\(?:([^u])|u(.{4}))", "g"),
121+
// Decodes escape sequences in object literals
122+
escapes = {
123+
"\"": "\"",
124+
"/": "/",
125+
"\\": "\\",
126+
"b": "\b",
127+
"f": "\f",
128+
"n": "\n",
129+
"r": "\r",
130+
"t": "\t"
131+
},
132+
unescapeOne = function(_, ch, hex) {
133+
return ch ? escapes[ch] : String.fromCharCode(parseInt(hex, 16));
134+
},
135+
// A non-falsy value that coerces to the empty string when used as a key.
136+
EMPTY_STRING = new String(""),
137+
SLASH = "\\",
138+
// Constructor to use based on an open token.
139+
firstTokenCtors = { "{": Object, "[": Array },
140+
hop = Object.hasOwnProperty,
141+
jsonSerialize = {
142+
object: function(o){
143+
//XML support - NOTICE: Ajax.org Platform specific
144+
if (o.nodeType && o.cloneNode)
145+
return "apf.xmldb.getXml("
146+
+ this.string(apf.getXmlString(o)) + ")";
147+
148+
//Normal JS object support
149+
var str = [];
150+
for (var prop in o) {
151+
str.push('"' + prop.replace(/(["\\])/g, '\\$1') + '": '
152+
+ apf.serialize(o[prop]));
153+
}
154+
155+
return "{" + str.join(", ") + "}";
156+
},
157+
158+
string: function(s){
159+
s = '"' + s.replace(/(["\\])/g, '\\$1') + '"';
160+
return s.replace(/(\n)/g, "\\n").replace(/\r/g, "");
132161
},
133-
unescapeOne = function(_, ch, hex) {
134-
return ch ? escapes[ch] : String.fromCharCode(parseInt(hex, 16));
162+
163+
number: function(i){
164+
return i.toString();
165+
},
166+
167+
"boolean": function(b){
168+
return b.toString();
169+
},
170+
171+
date: function(d){
172+
var padd = function(s, p){
173+
s = p + s;
174+
return s.substring(s.length - p.length);
175+
};
176+
var y = padd(d.getUTCFullYear(), "0000");
177+
var m = padd(d.getUTCMonth() + 1, "00");
178+
var D = padd(d.getUTCDate(), "00");
179+
var h = padd(d.getUTCHours(), "00");
180+
var min = padd(d.getUTCMinutes(), "00");
181+
var s = padd(d.getUTCSeconds(), "00");
182+
183+
var isodate = y + m + D + "T" + h + ":" + min + ":" + s;
184+
185+
return '{"jsonclass":["sys.ISODate", ["' + isodate + '"]]}';
135186
},
136-
// A non-falsy value that coerces to the empty string when used as a key.
137-
EMPTY_STRING = new String(""),
138-
SLASH = "\\",
139-
// Constructor to use based on an open token.
140-
firstTokenCtors = { "{": Object, "[": Array },
141-
hop = Object.hasOwnProperty;
142187

143-
return function (json, opt_reviver) {
188+
array: function(a){
189+
for (var q = [], i = 0; i < a.length; i++)
190+
q.push(apf.serialize(a[i]));
191+
192+
return "[" + q.join(", ") + "]";
193+
}
194+
};
195+
196+
197+
return {
198+
parse: function(json, opt_reviver) {
144199
// Split into tokens
145200
var toks = json.match(jsonToken),
146201
// Construct the object to return
@@ -261,96 +316,38 @@ if (!window["JSON"]) {
261316
result = walk({ "": result }, "");
262317
}
263318
return result;
264-
};
265-
})();
266-
}
267-
268-
// Serialize Objects
269-
/**
270-
* @private
271-
*/
272-
apf.JSONSerialize = {
273-
object: function(o){
274-
//XML support - NOTICE: Ajax.org Platform specific
275-
if (o.nodeType && o.cloneNode)
276-
return "apf.xmldb.getXml("
277-
+ this.string(apf.getXmlString(o)) + ")";
278-
279-
//Normal JS object support
280-
var str = [];
281-
for (var prop in o) {
282-
str.push('"' + prop.replace(/(["\\])/g, '\\$1') + '": '
283-
+ apf.serialize(o[prop]));
319+
},
320+
stringify: function(o) {
321+
if (typeof args == "function" || apf.isNot(o))
322+
return "null";
323+
return jsonSerialize[o.dataType || "object"](o);
284324
}
325+
};
285326

286-
return "{" + str.join(", ") + "}";
287-
},
288-
289-
string: function(s){
290-
s = '"' + s.replace(/(["\\])/g, '\\$1') + '"';
291-
return s.replace(/(\n)/g, "\\n").replace(/\r/g, "");
292-
},
293-
294-
number: function(i){
295-
return i.toString();
296-
},
297-
298-
"boolean": function(b){
299-
return b.toString();
300-
},
301-
302-
date: function(d){
303-
var padd = function(s, p){
304-
s = p + s;
305-
return s.substring(s.length - p.length);
306-
};
307-
var y = padd(d.getUTCFullYear(), "0000");
308-
var m = padd(d.getUTCMonth() + 1, "00");
309-
var D = padd(d.getUTCDate(), "00");
310-
var h = padd(d.getUTCHours(), "00");
311-
var min = padd(d.getUTCMinutes(), "00");
312-
var s = padd(d.getUTCSeconds(), "00");
313-
314-
var isodate = y + m + D + "T" + h + ":" + min + ":" + s;
315-
316-
return '{"jsonclass":["sys.ISODate", ["' + isodate + '"]]}';
317-
},
318-
319-
array: function(a){
320-
for (var q = [], i = 0; i < a.length; i++)
321-
q.push(apf.serialize(a[i]));
322-
323-
return "[" + q.join(", ") + "]";
324-
}
325-
};
327+
})();
328+
}
326329

327330
/**
328331
* Creates a json string from a javascript object.
329-
* @param {mixed} the javascript object to serialize.
332+
* @param {mixed} o the javascript object to serialize.
330333
* @return {String} the json string representation of the object.
331334
* @todo allow for XML serialization
332335
*/
333-
apf.serialize = function(args){
334-
if (typeof args == "function" || apf.isNot(args))
335-
return "null";
336-
return apf.JSONSerialize[args.dataType || "object"](args);
336+
apf.serialize = function(o){
337+
return JSON.stringify(o);
337338
};
338339

339340
/**
340341
* Evaluate a serialized object back to JS with eval(). When the 'secure' flag
341342
* is set to 'TRUE', the provided string will be validated for being valid
342343
* JSON.
343344
*
344-
* @param {String} str the json string to create an object from.
345-
* @param {Boolean} secure whether the json string should be checked to prevent malice.
345+
* @param {String} str the json string to create an object from.
346346
* @return {Object} the object created from the json string.
347347
*/
348-
apf.unserialize = function(str, secure){
348+
apf.unserialize = function(str){
349349
if (!str) return str;
350-
if (secure && !(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/)
351-
.test(str.replace(/\\./g, '@').replace(/"(?:\\"|[^"])*"|'(?:\\'|[^'])*'/g, '')))
352-
return str;
353-
return eval('(' + str + ')');
350+
return JSON.parse(str);
354351
};
355352

356353
// #endif

0 commit comments

Comments
 (0)