Make sure to always specify CultureInfo when parsing numbers.

This commit is contained in:
Frederik Carlier
2016-06-03 15:39:54 +02:00
parent 3c4e3257f2
commit 66ac10e4be
2 changed files with 59 additions and 6 deletions

View File

@@ -2,8 +2,10 @@
using NUnit.Framework; using NUnit.Framework;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace plistcil.test namespace plistcil.test
@@ -18,5 +20,56 @@ namespace plistcil.test
Assert.AreEqual(NSNumber.INTEGER, number.GetNSNumberType()); Assert.AreEqual(NSNumber.INTEGER, number.GetNSNumberType());
Assert.AreEqual(10032936613, number.ToObject()); Assert.AreEqual(10032936613, number.ToObject());
} }
// The tests below make sure the numbers are being parsed correctly, and do not depend on the culture info
// being set. Especially, decimal point may vary between cultures and we don't want to take a dependency on that
// The value being used comes seen in a real property list:
// <key>TimeZoneOffsetFromUTC</key>
// <real>7200.000000</real>
[Test]
[SetCulture("en-US")]
public static void ParseNumberEnTest()
{
var number = new NSNumber("7200.000001");
Assert.IsTrue(number.isReal());
Assert.AreEqual(7200.000001d, number.ToDouble());
}
[Test]
[SetCulture("nl-BE")]
public static void ParseNumberNlTest()
{
// As seen in a real property list:
// <key>TimeZoneOffsetFromUTC</key>
// <real>7200.000000</real>
var number = new NSNumber("7200.000001");
Assert.IsTrue(number.isReal());
Assert.AreEqual(7200.000001d, number.ToDouble());
}
[Test]
[SetCulture("en-US")]
public static void ParseNumberEnTest2()
{
// As seen in a real property list:
// <key>TimeZoneOffsetFromUTC</key>
// <real>7200.000000</real>
var number = new NSNumber("7200.000000", NSNumber.REAL);
Assert.IsTrue(number.isReal());
Assert.AreEqual(7200d, number.ToDouble());
}
[Test]
[SetCulture("nl-BE")]
public static void ParseNumberNlTest2()
{
// As seen in a real property list:
// <key>TimeZoneOffsetFromUTC</key>
// <real>7200.000000</real>
var number = new NSNumber("7200.000000", NSNumber.REAL);
Assert.IsTrue(number.isReal());
Assert.AreEqual(7200d, number.ToDouble());
}
} }
} }

View File

@@ -94,12 +94,12 @@ namespace Claunia.PropertyList
{ {
case INTEGER: case INTEGER:
{ {
doubleValue = longValue = long.Parse(text); doubleValue = longValue = long.Parse(text, CultureInfo.InvariantCulture);
break; break;
} }
case REAL: case REAL:
{ {
doubleValue = double.Parse(text); doubleValue = double.Parse(text, CultureInfo.InvariantCulture);
longValue = (long)Math.Round(doubleValue); longValue = (long)Math.Round(doubleValue);
break; break;
} }
@@ -126,12 +126,12 @@ namespace Claunia.PropertyList
long l; long l;
double d; double d;
if (long.TryParse(text, out l)) if (long.TryParse(text, NumberStyles.Number, CultureInfo.InvariantCulture, out l))
{ {
doubleValue = longValue = l; doubleValue = longValue = l;
type = INTEGER; type = INTEGER;
} }
else if (double.TryParse(text, out d)) else if (double.TryParse(text, NumberStyles.Number, CultureInfo.InvariantCulture, out d))
{ {
doubleValue = d; doubleValue = d;
longValue = (long)Math.Round(doubleValue); longValue = (long)Math.Round(doubleValue);
@@ -139,8 +139,8 @@ namespace Claunia.PropertyList
} }
else else
{ {
bool isTrue = text.ToLower().Equals("true") || text.ToLower().Equals("yes"); bool isTrue = string.Equals(text, "true", StringComparison.InvariantCultureIgnoreCase) || string.Equals(text, "yes", StringComparison.InvariantCultureIgnoreCase);
bool isFalse = text.ToLower().Equals("false") || text.ToLower().Equals("no"); bool isFalse = string.Equals(text, "false", StringComparison.InvariantCultureIgnoreCase) || string.Equals(text, "no", StringComparison.InvariantCultureIgnoreCase);
if (isTrue || isFalse) if (isTrue || isFalse)
{ {