瀏覽代碼

Fix parsing of invalid json (#6734)

* Fix parsing of invalid json

* adding tests

* follow Nadako recommendation

* [json] test when dot after e
Guillaume Desquesnes 7 年之前
父節點
當前提交
9897b777a1
共有 2 個文件被更改,包括 48 次插入2 次删除
  1. 17 2
      std/haxe/format/JsonParser.hx
  2. 31 0
      tests/unit/src/unit/issues/Issue5691.hx

+ 17 - 2
std/haxe/format/JsonParser.hx

@@ -42,7 +42,7 @@ class JsonParser {
 		If `str` is null, the result is unspecified.
 	**/
 	static public inline function parse(str : String) : Dynamic {
-		return new JsonParser(str).parseRec();
+		return new JsonParser(str).doParse();
 	}
 
 	var str : String;
@@ -53,6 +53,20 @@ class JsonParser {
 		this.pos = 0;
 	}
 
+	function doParse() : Dynamic {
+		var result = parseRec();
+		var c;
+		while( !StringTools.isEof(c = nextChar()) ) {
+			switch( c ) {
+				case ' '.code, '\r'.code, '\n'.code, '\t'.code:
+					// allow trailing whitespace
+				default:
+					invalidChar();
+			}
+		}
+		return result;
+	}
+
 	function parseRec() : Dynamic {
 		while( true ) {
 			var c = nextChar();
@@ -222,7 +236,7 @@ class JsonParser {
 					if (minus) minus = false;
 					digit = true; zero = false;
 				case '.'.code :
-					if (minus || point) invalidNumber(start);
+					if (minus || point || e) invalidNumber(start);
 					digit = false; point = true;
 				case 'e'.code, 'E'.code :
 					if (minus || zero || e) invalidNumber(start);
@@ -237,6 +251,7 @@ class JsonParser {
 			}
 			if (end) break;
 		}
+
 		var f = Std.parseFloat(str.substr(start, pos - start));
 		var i = Std.int(f);
 		return if( i == f ) i else f;

+ 31 - 0
tests/unit/src/unit/issues/Issue5691.hx

@@ -0,0 +1,31 @@
+package unit.issues;
+
+import haxe.format.JsonParser;
+
+class Issue5691 extends unit.Test {
+	function test() {
+		var jsons =  ['trueeee', 'falseah', 'nullol', '123asd', '{"a" : 1} trail'];
+		for (j in jsons) {
+			try {
+				JsonParser.parse(j);
+				t(false);
+			} catch(e:Dynamic) {
+				t(true);
+			}
+		}
+		try {
+			JsonParser.parse("1e2");
+			t(true);
+		}
+		catch (e:Dynamic) {
+			t(false);
+		}
+		try {
+			JsonParser.parse("1e2.5");
+			t(false);
+		}
+		catch(e:Dynamic) {
+			t(true);
+		}
+	}
+}