Prevent a crash in Safari when calling String#evalJSON(true) on very large strings. Add String#isJSON. Closes #7834. [Tobie Langel]
This commit is contained in:
parent
1e13c1d0b7
commit
9ff57b042d
|
@ -1,5 +1,7 @@
|
|||
*SVN*
|
||||
|
||||
* Prevent a crash in Safari when calling String#evalJSON(true) on very large strings. Add String#isJSON. Closes #7834. [Tobie Langel]
|
||||
|
||||
* Prevent a crash in Safari 1.3 on String#stripScripts and String#extractScripts. Closes #8332. [grant, Tobie Langel]
|
||||
|
||||
* Allow JSON data to contain line breaks. Closes #8271. [pijyster, Tobie Langel]
|
||||
|
|
|
@ -167,11 +167,15 @@ Object.extend(String.prototype, {
|
|||
return this.sub(filter || Prototype.JSONFilter, '#{1}');
|
||||
},
|
||||
|
||||
isJSON: function() {
|
||||
var str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
|
||||
return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
|
||||
},
|
||||
|
||||
evalJSON: function(sanitize) {
|
||||
var json = this.unfilterJSON();
|
||||
try {
|
||||
if (!sanitize || (/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(json)))
|
||||
return eval('(' + json + ')');
|
||||
if (!sanitize || json.isJSON()) return eval('(' + json + ')');
|
||||
} catch (e) { }
|
||||
throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
|
||||
},
|
||||
|
|
|
@ -415,11 +415,32 @@
|
|||
assertEqual('\"\"', ''.toJSON());
|
||||
assertEqual('\"test\"', 'test'.toJSON());
|
||||
}},
|
||||
|
||||
testIsJSON: function() {with(this) {
|
||||
assert(''.isJSON());
|
||||
assert('"foo"'.isJSON());
|
||||
assert('{}'.isJSON());
|
||||
assert('[]'.isJSON());
|
||||
assert('null'.isJSON());
|
||||
assert('123'.isJSON());
|
||||
assert('true'.isJSON());
|
||||
assert('false'.isJSON());
|
||||
assert('"\\""'.isJSON());
|
||||
assert(!'\\"'.isJSON());
|
||||
assert(!'new'.isJSON());
|
||||
assert(!'\u0028\u0029'.isJSON());
|
||||
// we use '@' as a placeholder for characters authorized only inside brackets,
|
||||
// so this tests make sure it is considered as authorized.
|
||||
assert(!'@'.isJSON());
|
||||
}},
|
||||
|
||||
testEvalJSON: function() {with(this) {
|
||||
var valid = '{test: \n\r"hello world!"}';
|
||||
var invalid = '{test: "hello world!"';
|
||||
var dangerous = '{});attackTarget = "attack succeeded!";({}';
|
||||
var longString = '"' + '123456789\\"'.times(1000) + '"';
|
||||
var object = '{' + longString + ': ' + longString + '},';
|
||||
var huge = '[' + object.times(100) + '{"test": 123}]';
|
||||
|
||||
assertEqual('hello world!', valid.evalJSON().test);
|
||||
assertEqual('hello world!', valid.evalJSON(true).test);
|
||||
|
@ -439,6 +460,8 @@
|
|||
Prototype.JSONFilter = /^\/\*([\s\S]*)\*\/$/; // test custom delimiters.
|
||||
assertEqual('hello world!', ('/*' + valid + '*/').evalJSON().test);
|
||||
Prototype.JSONFilter = temp;
|
||||
|
||||
assertMatch(123, huge.evalJSON(true).last().test);
|
||||
}}
|
||||
}, 'testlog');
|
||||
// ]]>
|
||||
|
|
Loading…
Reference in New Issue