Browse Source

Merge pull request #85 from fredericaltorres/master

JSON parser should handle negative number
Sébastien Ros 11 years ago
parent
commit
b1fb890d92
2 changed files with 63 additions and 2 deletions
  1. 44 0
      Jint.Tests/Runtime/EngineTests.cs
  2. 19 2
      Jint/Native/Json/JsonParser.cs

+ 44 - 0
Jint.Tests/Runtime/EngineTests.cs

@@ -705,6 +705,50 @@ namespace Jint.Tests.Runtime
             Assert.Equal(expected, result);
         }
 
+        [Fact]
+        public void JsonParserShouldParseNegativeNumber()
+        {
+            var engine = new Engine();
+            var result = engine.Execute(@"JSON.parse('{ ""x"":-1 }').x === -1").GetCompletionValue().AsBoolean();
+            Assert.Equal(true, result);
+
+            result = engine.Execute(@"JSON.parse('{ ""x"": -1 }').x === -1").GetCompletionValue().AsBoolean();
+            Assert.Equal(true, result);
+        }
+
+        [Fact]
+        public void JsonParserShouldDetectInvalidNegativeNumberSyntax()
+        {
+            var engine = new Engine();            
+            var code = @"
+                function f() {
+                    try {
+                        JSON.parse('{ ""x"": -.1 }'); // Not allowed
+                        return false;
+                    }
+                    catch(ex) {
+                        return ex.toString().indexOf('Unexpected token') !== -1;
+                    }
+                }
+                f();
+            ";
+            Assert.True(engine.Execute(code).GetCompletionValue().AsBoolean());
+
+            code = @"
+                function f() {
+                    try {
+                        JSON.parse('{ ""x"": - 1 }'); // Not allowed
+                        return false;
+                    }
+                    catch(ex) {
+                        return ex.toString().indexOf('Unexpected token') !== -1;
+                    }
+                }
+                f();
+            ";
+            Assert.True(engine.Execute(code).GetCompletionValue().AsBoolean());
+        }
+
         [Fact]
         public void ShouldBeCultureInvariant()
         {

+ 19 - 2
Jint/Native/Json/JsonParser.cs

@@ -161,9 +161,17 @@ namespace Jint.Native.Json
 
             int start = _index;
             string number = "";
+            
+            // Number start with a -
+            if (ch == '-')
+            {
+                number += _source.CharCodeAt(_index++).ToString();
+                ch = _source.CharCodeAt(_index);
+            }
+
             if (ch != '.')
             {
-                number = _source.CharCodeAt(_index++).ToString();
+                number += _source.CharCodeAt(_index++).ToString();
                 ch = _source.CharCodeAt(_index);
 
                 // Hex number starts with '0x'.
@@ -219,7 +227,7 @@ namespace Jint.Native.Json
             return new Token
                 {
                     Type = Tokens.Number,
-                    Value = Double.Parse(number, NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent, CultureInfo.InvariantCulture),
+                    Value = Double.Parse(number, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent, CultureInfo.InvariantCulture),
                     LineNumber = _lineNumber,
                     LineStart = _lineStart,
                     Range = new[] {start, _index}
@@ -447,6 +455,15 @@ namespace Jint.Native.Json
                 return ScanPunctuator();
             }
 
+            if (ch == '-') // Negative Number
+            {
+                if (IsDecimalDigit(_source.CharCodeAt(_index + 1)))
+                {
+                    return ScanNumericLiteral();
+                }
+                return ScanPunctuator();
+            }
+
             if (IsDecimalDigit(ch))
             {
                 return ScanNumericLiteral();