From 66ac10e4be76d9f612a155fff57ba2968b9f2d67 Mon Sep 17 00:00:00 2001 From: Frederik Carlier Date: Fri, 3 Jun 2016 15:39:54 +0200 Subject: [PATCH] Make sure to always specify CultureInfo when parsing numbers. --- plist-cil.test/NSNumberTests.cs | 53 +++++++++++++++++++++++++++++++++ plist-cil/NSNumber.cs | 12 ++++---- 2 files changed, 59 insertions(+), 6 deletions(-) diff --git a/plist-cil.test/NSNumberTests.cs b/plist-cil.test/NSNumberTests.cs index 8dfdfc3..c466b9e 100644 --- a/plist-cil.test/NSNumberTests.cs +++ b/plist-cil.test/NSNumberTests.cs @@ -2,8 +2,10 @@ using NUnit.Framework; using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace plistcil.test @@ -18,5 +20,56 @@ namespace plistcil.test Assert.AreEqual(NSNumber.INTEGER, number.GetNSNumberType()); 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: + // TimeZoneOffsetFromUTC + // 7200.000000 + + [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: + // TimeZoneOffsetFromUTC + // 7200.000000 + 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: + // TimeZoneOffsetFromUTC + // 7200.000000 + 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: + // TimeZoneOffsetFromUTC + // 7200.000000 + var number = new NSNumber("7200.000000", NSNumber.REAL); + Assert.IsTrue(number.isReal()); + Assert.AreEqual(7200d, number.ToDouble()); + } } } diff --git a/plist-cil/NSNumber.cs b/plist-cil/NSNumber.cs index 9614da1..8809d0f 100644 --- a/plist-cil/NSNumber.cs +++ b/plist-cil/NSNumber.cs @@ -94,12 +94,12 @@ namespace Claunia.PropertyList { case INTEGER: { - doubleValue = longValue = long.Parse(text); + doubleValue = longValue = long.Parse(text, CultureInfo.InvariantCulture); break; } case REAL: { - doubleValue = double.Parse(text); + doubleValue = double.Parse(text, CultureInfo.InvariantCulture); longValue = (long)Math.Round(doubleValue); break; } @@ -126,12 +126,12 @@ namespace Claunia.PropertyList long l; double d; - if (long.TryParse(text, out l)) + if (long.TryParse(text, NumberStyles.Number, CultureInfo.InvariantCulture, out l)) { doubleValue = longValue = l; type = INTEGER; } - else if (double.TryParse(text, out d)) + else if (double.TryParse(text, NumberStyles.Number, CultureInfo.InvariantCulture, out d)) { doubleValue = d; longValue = (long)Math.Round(doubleValue); @@ -139,8 +139,8 @@ namespace Claunia.PropertyList } else { - bool isTrue = text.ToLower().Equals("true") || text.ToLower().Equals("yes"); - bool isFalse = text.ToLower().Equals("false") || text.ToLower().Equals("no"); + bool isTrue = string.Equals(text, "true", StringComparison.InvariantCultureIgnoreCase) || string.Equals(text, "yes", StringComparison.InvariantCultureIgnoreCase); + bool isFalse = string.Equals(text, "false", StringComparison.InvariantCultureIgnoreCase) || string.Equals(text, "no", StringComparison.InvariantCultureIgnoreCase); if (isTrue || isFalse) {