2
0
Эх сурвалжийг харах

Merge pull request #1918 from rzuckerm/fix-number-parsing

Bugfixes for number parsing
Brian Fiete 1 жил өмнө
parent
commit
d452978605

+ 7 - 1
BeefLibs/corlib/src/Float.bf

@@ -182,6 +182,7 @@ namespace System
 
 			bool isNeg = val[0] == '-';
 			bool isPos = val[0] == '+';
+			bool digitsFound = false;
 			double result = 0;
 			double decimalMultiplier = 0;
 
@@ -205,7 +206,7 @@ namespace System
 				if ((c == 'e') || (c == 'E'))
 				{
 					//Error if there are no numbers after the prefix
-					if(i == val.Length - 1)
+					if(i == val.Length - 1 || !digitsFound)
 						return .Err;
 					var exponent = Try!(int32.Parse(val.Substring(i + 1)));
 					result *= Math.Pow(10, (double)exponent);
@@ -237,10 +238,15 @@ namespace System
 				{
 					result *= 10;
 					result += (int32)(c - '0');
+					digitsFound = true;
 				}
 				else
 					return .Err;
 			}
+
+			if (!digitsFound)
+				return .Err;
+
 			return isNeg ? (float)(-result) : (float)result;
 		}
     }

+ 8 - 0
BeefLibs/corlib/src/Int16.bf

@@ -83,6 +83,7 @@ namespace System
 				return .Err(.NoValue);
 
 			bool isNeg = false;
+			bool digitsFound = false;
 			int16 result = 0;
 
 			int16 radix = style.HasFlag(.Hex) ? 0x10 : 10;
@@ -101,6 +102,7 @@ namespace System
 				{
 					result &*= radix;
 					result &+= (int16)(c - '0');
+					digitsFound = true;
 				}
 				else if ((c >= 'a') && (c <= 'f'))
 				{
@@ -108,6 +110,7 @@ namespace System
 						return .Err(.InvalidChar(result));
 					result &*= radix;
 					result &+= c - 'a' + 10;
+					digitsFound = true;
 				}
 				else if ((c >= 'A') && (c <= 'F'))
 				{
@@ -115,12 +118,14 @@ namespace System
 						return .Err(.InvalidChar(result));
 					result &*= radix;
 					result &+= c - 'A' + 10;
+					digitsFound = true;
 				}
 				else if ((c == 'X') || (c == 'x'))
 				{
 					if ((!style.HasFlag(.AllowHexSpecifier)) || (i == 0) || (result != 0))
 						return .Err(.InvalidChar(result));
 					radix = 0x10;
+					digitsFound = false;
 				}
 				else if (c == '\'')
 				{
@@ -137,6 +142,9 @@ namespace System
 					return .Err(.Overflow);
 			}
 
+			if (!digitsFound)
+				return .Err(.NoValue);
+
 			return isNeg ? -result : result;
 		}
 

+ 8 - 0
BeefLibs/corlib/src/Int32.bf

@@ -132,6 +132,7 @@ namespace System
 				return .Err(.NoValue);
 
 			bool isNeg = false;
+			bool digitsFound = false;
 			int32 result = 0;
 
 			int32 radix = style.HasFlag(.Hex) ? 0x10 : 10;
@@ -150,6 +151,7 @@ namespace System
 				{
 					result &*= radix;
 					result &+= (int32)(c - '0');
+					digitsFound = true;
 				}
 				else if ((c >= 'a') && (c <= 'f'))
 				{
@@ -157,6 +159,7 @@ namespace System
 						return .Err(.InvalidChar(result));
 					result &*= radix;
 					result &+= c - 'a' + 10;
+					digitsFound = true;
 				}
 				else if ((c >= 'A') && (c <= 'F'))
 				{
@@ -164,12 +167,14 @@ namespace System
 						return .Err(.InvalidChar(result));
 					result &*= radix;
 					result &+= c - 'A' + 10;
+					digitsFound = true;
 				}
 				else if ((c == 'X') || (c == 'x'))
 				{
 					if ((!style.HasFlag(.AllowHexSpecifier)) || (i == 0) || (result != 0))
 						return .Err(.InvalidChar(result));
 					radix = 0x10;
+					digitsFound = false;
 				}
 				else if (c == '\'')
 				{
@@ -186,6 +191,9 @@ namespace System
 					return .Err(.Overflow);
 			}
 
+			if (!digitsFound)
+				return .Err(.NoValue);
+
 			return isNeg ? -result : result;
 		}
 

+ 8 - 0
BeefLibs/corlib/src/Int64.bf

@@ -113,6 +113,7 @@ namespace System
 				return .Err(.NoValue);
 
 			bool isNeg = false;
+			bool digitsFound = false;
 			int64 result = 0;
 
 			int64 radix = style.HasFlag(.Hex) ? 0x10 : 10;
@@ -131,6 +132,7 @@ namespace System
 				{
 					result &*= radix;
 					result &+= (int64)(c - '0');
+					digitsFound = true;
 				}
 				else if ((c >= 'a') && (c <= 'f'))
 				{
@@ -138,6 +140,7 @@ namespace System
 						return .Err(.InvalidChar(result));
 					result &*= radix;
 					result &+= c - 'a' + 10;
+					digitsFound = true;
 				}
 				else if ((c >= 'A') && (c <= 'F'))
 				{
@@ -145,12 +148,14 @@ namespace System
 						return .Err(.InvalidChar(result));
 					result &*= radix;
 					result &+= c - 'A' + 10;
+					digitsFound = true;
 				}
 				else if ((c == 'X') || (c == 'x'))
 				{
 					if ((!style.HasFlag(.AllowHexSpecifier)) || (i == 0) || (result != 0))
 						return .Err(.InvalidChar(result));
 					radix = 0x10;
+					digitsFound = false;
 				}
 				else if (c == '\'')
 				{
@@ -167,6 +172,9 @@ namespace System
 					return .Err(.Overflow);
 			}
 
+			if (!digitsFound)
+				return .Err(.NoValue);
+
 			return isNeg ? -result : result;
 		}
 

+ 8 - 0
BeefLibs/corlib/src/Int8.bf

@@ -83,6 +83,7 @@ namespace System
 				return .Err(.NoValue);
 
 			bool isNeg = false;
+			bool digitsFound = false;
 			int8 result = 0;
 
 			int8 radix = style.HasFlag(.Hex) ? 0x10 : 10;
@@ -101,6 +102,7 @@ namespace System
 				{
 					result &*= radix;
 					result &+= (int8)(c - '0');
+					digitsFound = true;
 				}
 				else if ((c >= 'a') && (c <= 'f'))
 				{
@@ -108,6 +110,7 @@ namespace System
 						return .Err(.InvalidChar(result));
 					result &*= radix;
 					result &+= (int8)(c - 'a' + 10);
+					digitsFound = true;
 				}
 				else if ((c >= 'A') && (c <= 'F'))
 				{
@@ -115,12 +118,14 @@ namespace System
 						return .Err(.InvalidChar(result));
 					result &*= radix;
 					result &+= (int8)(c - 'A' + 10);
+					digitsFound = true;
 				}
 				else if ((c == 'X') || (c == 'x'))
 				{
 					if ((!style.HasFlag(.AllowHexSpecifier)) || (i == 0) || (result != 0))
 						return .Err(.InvalidChar(result));
 					radix = 0x10;
+					digitsFound = false;
 				}
 				else if (c == '\'')
 				{
@@ -137,6 +142,9 @@ namespace System
 					return .Err(.Overflow);
 			}
 
+			if (!digitsFound)
+				return .Err(.NoValue);
+
 			return isNeg ? -result : result;
 		}
 

+ 8 - 0
BeefLibs/corlib/src/UInt16.bf

@@ -82,6 +82,7 @@ namespace System
 			if (val.IsEmpty)
 				return .Err(.NoValue);
 
+			bool digitsFound = false;
 			uint16 result = 0;
 			uint16 prevResult = 0;
 
@@ -95,6 +96,7 @@ namespace System
 				{
 					result &*= radix;
 					result &+= (uint16)(c - '0');
+					digitsFound = true;
 				}
 				else if ((c >= 'a') && (c <= 'f'))
 				{
@@ -102,6 +104,7 @@ namespace System
 						return .Err(.InvalidChar(result));
 					result &*= radix;
 					result &+= (uint16)(c - 'a' + 10);
+					digitsFound = true;
 				}
 				else if ((c >= 'A') && (c <= 'F'))
 				{
@@ -109,12 +112,14 @@ namespace System
 						return .Err(.InvalidChar(result));
 					result &*= radix;
 					result &+= (uint16)(c - 'A' + 10);
+					digitsFound = true;
 				}
 				else if ((c == 'X') || (c == 'x'))
 				{
 					if ((!style.HasFlag(.AllowHexSpecifier)) || (i == 0) || (result != 0))
 						return .Err(.InvalidChar(result));
 					radix = 0x10;
+					digitsFound = false;
 				}
 				else if (c == '\'')
 				{
@@ -132,6 +137,9 @@ namespace System
 				prevResult = result;
 			}
 
+			if (!digitsFound)
+				return .Err(.NoValue);
+
 			return result;
 		}
 

+ 8 - 0
BeefLibs/corlib/src/UInt32.bf

@@ -110,6 +110,7 @@ namespace System
 			if (val.IsEmpty)
 				return .Err(.NoValue);
 
+			bool digitsFound = false;
 			uint32 result = 0;
 			uint32 prevResult = 0;
 
@@ -123,6 +124,7 @@ namespace System
 				{
 					result &*= radix;
 					result &+= (uint32)(c - '0');
+					digitsFound = true;
 				}
 				else if ((c >= 'a') && (c <= 'f'))
 				{
@@ -130,6 +132,7 @@ namespace System
 						return .Err(.InvalidChar(result));
 					result &*= radix;
 					result &+= (uint32)(c - 'a' + 10);
+					digitsFound = true;
 				}
 				else if ((c >= 'A') && (c <= 'F'))
 				{
@@ -137,12 +140,14 @@ namespace System
 						return .Err(.InvalidChar(result));
 					result &*= radix;
 					result &+= (uint32)(c - 'A' + 10);
+					digitsFound = true;
 				}
 				else if ((c == 'X') || (c == 'x'))
 				{
 					if ((!style.HasFlag(.AllowHexSpecifier)) || (i == 0) || (result != 0))
 						return .Err(.InvalidChar(result));
 					radix = 0x10;
+					digitsFound = false;
 				}
 				else if (c == '\'')
 				{
@@ -160,6 +165,9 @@ namespace System
 				prevResult = result;
 			}
 
+			if (!digitsFound)
+				return .Err(.NoValue);
+
 			return result;
 		}
 

+ 8 - 0
BeefLibs/corlib/src/UInt64.bf

@@ -94,6 +94,7 @@ namespace System
 			if (val.IsEmpty)
 				return .Err(.NoValue);
 
+			bool digitsFound = false;
 			uint64 result = 0;
 			uint64 prevResult = 0;
 
@@ -107,6 +108,7 @@ namespace System
 				{
 					result &*= radix;
 					result &+= (uint64)(c - '0');
+					digitsFound = true;
 				}
 				else if ((c >= 'a') && (c <= 'f'))
 				{
@@ -114,6 +116,7 @@ namespace System
 						return .Err(.InvalidChar(result));
 					result &*= radix;
 					result &+= (uint64)(c - 'a' + 10);
+					digitsFound = true;
 				}
 				else if ((c >= 'A') && (c <= 'F'))
 				{
@@ -121,12 +124,14 @@ namespace System
 						return .Err(.InvalidChar(result));
 					result &*= radix;
 					result &+= (uint64)(c - 'A' + 10);
+					digitsFound = true;
 				}
 				else if ((c == 'X') || (c == 'x'))
 				{
 					if ((!style.HasFlag(.AllowHexSpecifier)) || (i == 0) || (result != 0))
 						return .Err(.InvalidChar(result));
 					radix = 0x10;
+					digitsFound = false;
 				}
 				else if (c == '\'')
 				{
@@ -144,6 +149,9 @@ namespace System
 				prevResult = result;
 			}
 
+			if (!digitsFound)
+				return .Err(.NoValue);
+
 			return result;
 		}
 

+ 8 - 0
BeefLibs/corlib/src/UInt8.bf

@@ -82,6 +82,7 @@ namespace System
 			if (val.IsEmpty)
 				return .Err(.NoValue);
 
+			bool digitsFound = false;
 			uint8 result = 0;
 			uint8 prevResult = 0;
 
@@ -95,6 +96,7 @@ namespace System
 				{
 					result &*= radix;
 					result &+= (uint8)(c - '0');
+					digitsFound = true;
 				}
 				else if ((c >= 'a') && (c <= 'f'))
 				{
@@ -102,6 +104,7 @@ namespace System
 						return .Err(.InvalidChar(result));
 					result &*= radix;
 					result &+= (uint8)(c - 'a' + 10);
+					digitsFound = true;
 				}
 				else if ((c >= 'A') && (c <= 'F'))
 				{
@@ -109,12 +112,14 @@ namespace System
 						return .Err(.InvalidChar(result));
 					result &*= radix;
 					result &+= (uint8)(c - 'A' + 10);
+					digitsFound = true;
 				}
 				else if ((c == 'X') || (c == 'x'))
 				{
 					if ((!style.HasFlag(.AllowHexSpecifier)) || (i == 0) || (result != 0))
 						return .Err(.InvalidChar(result));
 					radix = 0x10;
+					digitsFound = false;
 				}
 				else if (c == '\'')
 				{
@@ -132,6 +137,9 @@ namespace System
 				prevResult = result;
 			}
 
+			if (!digitsFound)
+				return .Err(.NoValue);
+
 			return result;
 		}
 

+ 28 - 0
IDEHelper/Tests/src/Floats.bf

@@ -22,5 +22,33 @@ namespace Tests
 			FloatParseTest("3.3e-11", 3.3e-11f);
 			FloatParseTest("0.002e5", 0.002e5f);
 		}
+
+		public static void FloatParseErrTest(StringView string)
+		{
+			Test.Assert(float.Parse(string) case .Err);
+		}
+
+		[Test]
+		public static void TestErrors()
+		{
+			FloatParseErrTest("");
+			FloatParseErrTest("-");
+			FloatParseErrTest("+");
+			FloatParseErrTest(".");
+			FloatParseErrTest("+.");
+			FloatParseErrTest("-.");
+			FloatParseErrTest("E");
+			FloatParseErrTest("e");
+			FloatParseErrTest(".E");
+			FloatParseErrTest(".e");
+			FloatParseErrTest("-.E");
+			FloatParseErrTest("-.e");
+			FloatParseErrTest("+.E");
+			FloatParseErrTest("+.e");
+			FloatParseErrTest("5E-");
+			FloatParseErrTest("5e-");
+			FloatParseErrTest("6E+");
+			FloatParseErrTest("6e+");
+		}
 	}
 }

+ 70 - 0
IDEHelper/Tests/src/Ints.bf

@@ -1,6 +1,7 @@
 #pragma warning disable 168
 
 using System;
+using System.Globalization;
 
 namespace Tests
 {
@@ -43,5 +44,74 @@ namespace Tests
 			int i1 = i0 % 1;
 			Test.Assert(i1 == 0);
 		}
+
+		public static void Int64ParseTest(StringView string, int64 expectedResult, NumberStyles style = .Number)
+		{
+			int64 result = int64.Parse(string, style);
+			Test.Assert(expectedResult == result);
+		}
+
+		[Test]
+		public static void TestInt64Parse()
+		{
+			Int64ParseTest("1234567890", 1234567890L);
+			Int64ParseTest("+1234567890", 1234567890L);
+			Int64ParseTest("-9876543210", -9876543210L);
+			Int64ParseTest("0x123456789abcdef", 81985529216486895L, .HexNumber);
+			Int64ParseTest("0X123456789ABCDEF", 81985529216486895L, .HexNumber);
+			Int64ParseTest("+0x123456789abcdef", 81985529216486895L, .HexNumber);
+			Int64ParseTest("-0x76543210fedcba", -33306621262093498L, .HexNumber);
+		}
+
+		public static void Int64ParseErrorTest(StringView string, NumberStyles style = .Number)
+		{
+			Test.Assert(int64.Parse(string, style) case .Err);
+		}
+
+		[Test]
+		public static void TestInt64ParseError()
+		{
+			Int64ParseErrorTest("");
+			Int64ParseErrorTest("-");
+			Int64ParseErrorTest("+");
+			Int64ParseErrorTest("0x", .HexNumber);
+			Int64ParseErrorTest("0X", .HexNumber);
+			Int64ParseErrorTest("+0x", .HexNumber);
+			Int64ParseErrorTest("+0X", .HexNumber);
+			Int64ParseErrorTest("-0x", .HexNumber);
+			Int64ParseErrorTest("-0X", .HexNumber);
+		}
+
+		public static void Uint64ParseTest(StringView string, uint64 expectedResult, NumberStyles style = .Number)
+		{
+			uint64 result = uint64.Parse(string, style);
+			Test.Assert(expectedResult == result);
+		}
+
+		[Test]
+		public static void TestUint64Parse()
+		{
+			Uint64ParseTest("1234567890", 1234567890UL);
+			Uint64ParseTest("+9876543210", 9876543210UL);
+			Uint64ParseTest("0x123456789abcdef", 81985529216486895UL, .HexNumber);
+			Uint64ParseTest("0X123456789ABCDEF", 81985529216486895UL, .HexNumber);
+			Uint64ParseTest("+0xfedcba9876543210", 18364758544493064720UL, .HexNumber);
+		}
+
+		public static void Uint64ParseErrorTest(StringView string, NumberStyles style = .Number)
+		{
+			Test.Assert(uint64.Parse(string, style) case .Err);
+		}
+
+		[Test]
+		public static void TestUint64ParseError()
+		{
+			Uint64ParseErrorTest("");
+			Uint64ParseErrorTest("+");
+			Uint64ParseErrorTest("0x", .HexNumber);
+			Uint64ParseErrorTest("0X", .HexNumber);
+			Uint64ParseErrorTest("+0x", .HexNumber);
+			Uint64ParseErrorTest("+0X", .HexNumber);
+		}
 	}
 }