Bladeren bron

[cs] fix Std.parseInt() for haxedecimal with leading whitespaces
#89701

Aleksandr Kuzmenko 5 jaren geleden
bovenliggende
commit
7cb6486add
1 gewijzigde bestanden met toevoegingen van 38 en 51 verwijderingen
  1. 38 51
      std/cs/_std/Std.hx

+ 38 - 51
std/cs/_std/Std.hx

@@ -83,61 +83,48 @@ import cs.internal.Exceptions;
 		var base = 10;
 		var i = -1;
 		var len = x.length;
-
-		if (StringTools.startsWith(x, "0") && len > 2) {
-			var c:Int = cast untyped x[1];
-			if (c == 'x'.code || c == 'X'.code) {
-				i = 1;
-				base = 16;
-			}
-		}
-
-		var foundAny = i != -1;
-		var isNeg = false;
-		while (++i < len) {
-			var c = cast(untyped x[i], Int); // fastCodeAt
-			if (!foundAny) {
-				switch (c) {
-					case '-'.code:
-						isNeg = true;
-						continue;
-					case ' '.code, '\t'.code, '\n'.code, '\r'.code, '+'.code:
-						if (isNeg)
-							return null;
-						continue;
-				}
-			}
-
-			if (c >= '0'.code && c <= '9'.code) {
-				if (!foundAny && c == '0'.code) {
-					foundAny = true;
+		var foundCount = 0;
+		var sign = 0;
+		var firstDigitIndex = 0;
+		var lastDigitIndex = -1;
+		var previous = 0;
+
+		for(i in 0...len) {
+			var c = StringTools.fastCodeAt(x, i);
+			switch c {
+				case _ if((c > 8 && c < 14) || c == 32):
+					if(foundCount > 0) {
+						return null;
+					}
 					continue;
-				}
-				ret *= base;
-				foundAny = true;
-
-				ret += c - '0'.code;
-			} else if (base == 16) {
-				if (c >= 'a'.code && c <= 'f'.code) {
-					ret *= base;
-					foundAny = true;
-					ret += c - 'a'.code + 10;
-				} else if (c >= 'A'.code && c <= 'F'.code) {
-					ret *= base;
-					foundAny = true;
-					ret += c - 'A'.code + 10;
-				} else {
+				case '-'.code if(foundCount == 0):
+					sign = -1;
+				case '+'.code if(foundCount == 0):
+					sign = 1;
+				case '0'.code if(foundCount == 0 || (foundCount == 1 && sign != 0)):
+				case 'x'.code | 'X'.code if(previous == '0'.code && ((foundCount == 1 && sign == 0) || (foundCount == 2 && sign != 0))):
+					base = 16;
+				case _ if('0'.code <= c && c <= '9'.code):
+				case _ if(base == 16 && (('a'.code <= c && c <= 'z'.code) || ('A'.code <= c && c <= 'Z'.code))):
+				case _:
 					break;
-				}
-			} else {
-				break;
 			}
+			if((foundCount == 0 && sign == 0) || (foundCount == 1 && sign != 0)) {
+				firstDigitIndex = i;
+			}
+			foundCount++;
+			lastDigitIndex = i;
+			previous = c;
 		}
-
-		if (foundAny)
-			return isNeg ? -ret : ret;
-		else
-			return null;
+		if(firstDigitIndex <= lastDigitIndex) {
+			var digits = x.substring(firstDigitIndex, lastDigitIndex + 1);
+			return try {
+				(sign == -1 ? -1 : 1) * cs.system.Convert.ToInt32(digits, base);
+			} catch(e:cs.system.FormatException) {
+				null;
+			}
+		}
+		return null;
 	}
 
 	public static function parseFloat(x:String):Float {