aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorMisko Hevery2010-10-15 15:28:58 -0700
committerMisko Hevery2010-10-18 08:50:36 -0700
commit9e9bdbdc405b6afecd2e536e375c9d8fe40f110b (patch)
tree89bd9cdeb19782a6d449c931ae4688e5617a562e /test
parent352dbfa38fca660a80d6fae2c6e810f820247791 (diff)
downloadangular.js-9e9bdbdc405b6afecd2e536e375c9d8fe40f110b.tar.bz2
JSON parser is now strict (ie, expressions are not allowed for security)
Close #57
Diffstat (limited to 'test')
-rw-r--r--test/JsonSpec.js134
-rw-r--r--test/JsonTest.js102
-rw-r--r--test/ParserSpec.js2
3 files changed, 135 insertions, 103 deletions
diff --git a/test/JsonSpec.js b/test/JsonSpec.js
new file mode 100644
index 00000000..6fc40e09
--- /dev/null
+++ b/test/JsonSpec.js
@@ -0,0 +1,134 @@
+describe('json', function(){
+ it('should parse Primitives', function() {
+ assertEquals("null", toJson(0/0));
+ assertEquals("null", toJson(null));
+ assertEquals("true", toJson(true));
+ assertEquals("false", toJson(false));
+ assertEquals("123.45", toJson(123.45));
+ assertEquals('"abc"', toJson("abc"));
+ assertEquals('"a \\t \\n \\r b \\\\"', toJson("a \t \n \r b \\"));
+ });
+
+ it('should parse Escaping', function() {
+ assertEquals("\"7\\\\\\\"7\"", toJson("7\\\"7"));
+ });
+
+ it('should parse Objects', function() {
+ assertEquals('{"a":1,"b":2}', toJson({a:1,b:2}));
+ assertEquals('{"a":{"b":2}}', toJson({a:{b:2}}));
+ assertEquals('{"a":{"b":{"c":0}}}', toJson({a:{b:{c:0}}}));
+ assertEquals('{"a":{"b":null}}', toJson({a:{b:0/0}}));
+ });
+
+ it('should parse ObjectPretty', function() {
+ assertEquals('{\n "a":1,\n "b":2}', toJson({a:1,b:2}, true));
+ assertEquals('{\n "a":{\n "b":2}}', toJson({a:{b:2}}, true));
+ });
+
+ it('should parse Array', function() {
+ assertEquals('[]', toJson([]));
+ assertEquals('[1,"b"]', toJson([1,"b"]));
+ });
+
+ it('should parse IgnoreFunctions', function() {
+ assertEquals('[null,1]', toJson([function(){},1]));
+ assertEquals('{}', toJson({a:function(){}}));
+ });
+
+ it('should parse ParseNull', function() {
+ assertNull(fromJson("null"));
+ });
+
+ it('should parse ParseBoolean', function() {
+ assertTrue(fromJson("true"));
+ assertFalse(fromJson("false"));
+ });
+
+ it('should parse $$isIgnored', function() {
+ assertEquals("{}", toJson({$$:0}));
+ });
+
+ it('should parse ArrayWithEmptyItems', function() {
+ var a = [];
+ a[1] = "X";
+ assertEquals('[null,"X"]', toJson(a));
+ });
+
+ it('should parse ItShouldEscapeUnicode', function() {
+ assertEquals(1, "\u00a0".length);
+ assertEquals(8, toJson("\u00a0").length);
+ assertEquals(1, fromJson(toJson("\u00a0")).length);
+ });
+
+ it('should parse ItShouldUTCDates', function() {
+ var date = angular.String.toDate("2009-10-09T01:02:03Z");
+ assertEquals('"2009-10-09T01:02:03Z"', toJson(date));
+ assertEquals(date.getTime(),
+ fromJson('"2009-10-09T01:02:03Z"').getTime());
+ });
+
+ it('should parse ItShouldPreventRecursion', function() {
+ var obj = {a:'b'};
+ obj.recursion = obj;
+ assertEquals('{"a":"b","recursion":RECURSION}', angular.toJson(obj));
+ });
+
+ it('should parse ItShouldIgnore$Properties', function() {
+ var scope = createScope();
+ scope.a = 'a';
+ scope['$b'] = '$b';
+ scope.c = 'c';
+ expect(angular.toJson(scope)).toEqual('{"a":"a","c":"c","this":RECURSION}');
+ });
+
+ it('should parse ItShouldSerializeInheritedProperties', function() {
+ var scope = createScope({p:'p'});
+ scope.a = 'a';
+ expect(angular.toJson(scope)).toEqual('{"a":"a","p":"p","this":RECURSION}');
+ });
+
+ it('should parse ItShouldSerializeSameObjectsMultipleTimes', function() {
+ var obj = {a:'b'};
+ assertEquals('{"A":{"a":"b"},"B":{"a":"b"}}', angular.toJson({A:obj, B:obj}));
+ });
+
+ it('should parse ItShouldNotSerializeUndefinedValues', function() {
+ assertEquals('{}', angular.toJson({A:undefined}));
+ });
+
+ it('should parse ItShouldParseFloats', function() {
+ expect(fromJson("{value:2.55, name:'misko'}")).toEqual({value:2.55, name:'misko'});
+ });
+
+ describe('security', function(){
+ it('should not allow naked expressions', function(){
+ expect(function(){fromJson('1+2');}).toThrow("Did not understand '+2' while evaluating '1+2'.");
+ });
+
+ it('should not allow naked expressions group', function(){
+ expect(function(){fromJson('(1+2)');}).toThrow("Expression at column='0' of expression '(1+2)' starting at '(1+2)' is not valid json.");
+ });
+
+ it('should not allow expressions in objects', function(){
+ expect(function(){fromJson('{a:abc()}');}).toThrow("Expression at column='3' of expression '{a:abc()}' starting at 'abc()}' is not valid json.");
+ });
+
+ it('should not allow expressions in arrays', function(){
+ expect(function(){fromJson('[1+2]');}).toThrow("Expression at column='2' of expression '[1+2]' starting at '+2]' is not valid json.");
+ });
+
+ it('should not allow vars', function(){
+ expect(function(){fromJson('[1, x]');}).toThrow("Expression at column='4' of expression '[1, x]' starting at 'x]' is not valid json.");
+ });
+
+ it('should not allow dereference', function(){
+ expect(function(){fromJson('["".constructor]');}).toThrow("Expression at column='3' of expression '[\"\".constructor]' starting at '.constructor]' is not valid json.");
+ });
+
+ it('should not allow expressions ofter valid json', function(){
+ expect(function(){fromJson('[].constructor');}).toThrow("Expression at column='2' of expression '[].constructor' starting at '.constructor' is not valid json.");
+ });
+ });
+
+});
+
diff --git a/test/JsonTest.js b/test/JsonTest.js
deleted file mode 100644
index c723121f..00000000
--- a/test/JsonTest.js
+++ /dev/null
@@ -1,102 +0,0 @@
-JsonTest = TestCase("JsonTest");
-
-JsonTest.prototype.testPrimitives = function () {
- assertEquals("null", toJson(0/0));
- assertEquals("null", toJson(null));
- assertEquals("true", toJson(true));
- assertEquals("false", toJson(false));
- assertEquals("123.45", toJson(123.45));
- assertEquals('"abc"', toJson("abc"));
- assertEquals('"a \\t \\n \\r b \\\\"', toJson("a \t \n \r b \\"));
-};
-
-JsonTest.prototype.testEscaping = function () {
- assertEquals("\"7\\\\\\\"7\"", toJson("7\\\"7"));
-};
-
-JsonTest.prototype.testObjects = function () {
- assertEquals('{"a":1,"b":2}', toJson({a:1,b:2}));
- assertEquals('{"a":{"b":2}}', toJson({a:{b:2}}));
- assertEquals('{"a":{"b":{"c":0}}}', toJson({a:{b:{c:0}}}));
- assertEquals('{"a":{"b":null}}', toJson({a:{b:0/0}}));
-};
-
-JsonTest.prototype.testObjectPretty = function () {
- assertEquals('{\n "a":1,\n "b":2}', toJson({a:1,b:2}, true));
- assertEquals('{\n "a":{\n "b":2}}', toJson({a:{b:2}}, true));
-};
-
-JsonTest.prototype.testArray = function () {
- assertEquals('[]', toJson([]));
- assertEquals('[1,"b"]', toJson([1,"b"]));
-};
-
-JsonTest.prototype.testIgnoreFunctions = function () {
- assertEquals('[null,1]', toJson([function(){},1]));
- assertEquals('{}', toJson({a:function(){}}));
-};
-
-JsonTest.prototype.testParseNull = function () {
- assertNull(fromJson("null"));
-};
-
-JsonTest.prototype.testParseBoolean = function () {
- assertTrue(fromJson("true"));
- assertFalse(fromJson("false"));
-};
-
-JsonTest.prototype.test$$isIgnored = function () {
- assertEquals("{}", toJson({$$:0}));
-};
-
-JsonTest.prototype.testArrayWithEmptyItems = function () {
- var a = [];
- a[1] = "X";
- assertEquals('[null,"X"]', toJson(a));
-};
-
-JsonTest.prototype.testItShouldEscapeUnicode = function () {
- assertEquals(1, "\u00a0".length);
- assertEquals(8, toJson("\u00a0").length);
- assertEquals(1, fromJson(toJson("\u00a0")).length);
-};
-
-JsonTest.prototype.testItShouldUTCDates = function() {
- var date = angular.String.toDate("2009-10-09T01:02:03Z");
- assertEquals('"2009-10-09T01:02:03Z"', toJson(date));
- assertEquals(date.getTime(),
- fromJson('"2009-10-09T01:02:03Z"').getTime());
-};
-
-JsonTest.prototype.testItShouldPreventRecursion = function () {
- var obj = {a:'b'};
- obj.recursion = obj;
- assertEquals('{"a":"b","recursion":RECURSION}', angular.toJson(obj));
-};
-
-JsonTest.prototype.testItShouldIgnore$Properties = function() {
- var scope = createScope();
- scope.a = 'a';
- scope['$b'] = '$b';
- scope.c = 'c';
- expect(angular.toJson(scope)).toEqual('{"a":"a","c":"c","this":RECURSION}');
-};
-
-JsonTest.prototype.testItShouldSerializeInheritedProperties = function() {
- var scope = createScope({p:'p'});
- scope.a = 'a';
- expect(angular.toJson(scope)).toEqual('{"a":"a","p":"p","this":RECURSION}');
-};
-
-JsonTest.prototype.testItShouldSerializeSameObjectsMultipleTimes = function () {
- var obj = {a:'b'};
- assertEquals('{"A":{"a":"b"},"B":{"a":"b"}}', angular.toJson({A:obj, B:obj}));
-};
-
-JsonTest.prototype.testItShouldNotSerializeUndefinedValues = function () {
- assertEquals('{}', angular.toJson({A:undefined}));
-};
-
-JsonTest.prototype.testItShouldParseFloats = function () {
- expect(fromJson("{value:2.55, name:'misko'}")).toEqual({value:2.55, name:'misko'});
-};
diff --git a/test/ParserSpec.js b/test/ParserSpec.js
index ac359cb0..6c45d52f 100644
--- a/test/ParserSpec.js
+++ b/test/ParserSpec.js
@@ -443,7 +443,7 @@ describe('parser', function(){
assertEquals(12/6/2, scope.$eval("12/6/2"));
});
- it('should parse BugStringConfusesParser', function(){
+ it('should parse BugStringConfusesparser', function(){
var scope = createScope();
assertEquals('!', scope.$eval('suffix = "!"'));
});