Browse Source

[php] fix Std.parseInt() and parseFloat() for haxedecimals on PHP 7.1 (fixes #5521)

Alexander Kuzmenko 8 years ago
parent
commit
7a148bd1b0
1 changed files with 34 additions and 12 deletions
  1. 34 12
      std/php/_std/Std.hx

+ 34 - 12
std/php/_std/Std.hx

@@ -41,26 +41,48 @@
 	}
 
 	public static function parseInt( x : String ) : Null<Int> {
-		untyped if (!__call__("is_numeric", x)) {
-			var matches = null;
-			__call__('preg_match', '/^-?\\d+/', x, matches);
-			return __call__("count", matches) == 0 ? null : __call__('intval', matches[0]);
-		} else
-			return x.substr(0, 2).toLowerCase() == "0x" ? __php__("(int) hexdec(substr($x, 2))") : __php__("intval($x)");
+		if (untyped __call__("is_numeric", x)) {
+			return untyped __call__("intval", x, 10);
+		} else {
+			x = untyped __call__("ltrim", x);
+			var firstCharIndex = (x.charAt(0) == '-' ? 1 : 0);
+			var firstCharCode = x.charCodeAt(firstCharIndex);
+			if (!isDigitCode(firstCharCode)) {
+				return null;
+			}
+			var secondChar = x.charAt(firstCharIndex + 1);
+			if (secondChar == 'x' || secondChar == 'X') {
+				return untyped __call__("intval", x, 0);
+			} else {
+				return untyped __call__("intval", x, 10);
+			}
+		}
 	}
 
 	public static function parseFloat( x : String ) : Float {
-		var v : Float = untyped __call__("floatval", x);
-		untyped	if (v==0.0) {
-			x=untyped __call__("rtrim", x);
-			v=untyped __call__("floatval", x);
-			if (v == 0.0 && !__call__("is_numeric", x)) v = untyped __call__("acos", 1.01);
+		var result = untyped __call__("floatval", x);
+		if (untyped __php__("$result != 0")) return result;
+
+		x = untyped __call__("ltrim", x);
+		var firstCharIndex = (x.charAt(0) == '-' ? 1 : 0);
+		var charCode = x.charCodeAt(firstCharIndex);
+
+		if (charCode == '.'.code) {
+			charCode = x.charCodeAt(firstCharIndex + 1);
+		}
+
+		if (isDigitCode(charCode)) {
+			return 0.0;
+		} else {
+			return Math.NaN;
 		}
-		return v;
 	}
 
 	public static function random( x : Int ) : Int {
 		return untyped x <= 0 ? 0 : __call__("mt_rand", 0, x-1);
 	}
 
+	static inline function isDigitCode( charCode:Null<Int> ) : Bool {
+		return charCode != null && charCode >= '0'.code && charCode <= '9'.code;
+	}
 }