From f934448710955efb1dfe7c9353ca9e39a49c6b42 Mon Sep 17 00:00:00 2001 From: Konstantin Petukhov Date: Thu, 20 May 2021 11:14:44 +0700 Subject: [PATCH] Fixed parsing of floating point numbers. SVG format contains numbers in invariant format. It have to be parsed on any system with any culture. Calling of float.Parse(str) throws an exception on systems where comma used in floating numbers. --- src/UkooLabs.SVGSharpie/SvgColorTranslator.cs | 2 +- .../SvgElementStyleDataDeserializer.cs | 7 ++++--- src/UkooLabs.SVGSharpie/SvgLength.cs | 5 +++-- src/UkooLabs.SVGSharpie/SvgPathSegListParser.cs | 4 +++- .../SvgPolyPointListParser.cs | 5 +++-- src/UkooLabs.SVGSharpie/SvgRect.cs | 9 +++++---- src/UkooLabs.SVGSharpie/SvgStopElement.cs | 7 ++++--- .../SvgTransformListParser.cs | 17 +++++++++-------- 8 files changed, 32 insertions(+), 24 deletions(-) diff --git a/src/UkooLabs.SVGSharpie/SvgColorTranslator.cs b/src/UkooLabs.SVGSharpie/SvgColorTranslator.cs index 6269407..547d7fa 100644 --- a/src/UkooLabs.SVGSharpie/SvgColorTranslator.cs +++ b/src/UkooLabs.SVGSharpie/SvgColorTranslator.cs @@ -30,7 +30,7 @@ public static SvgColor FromSvgColorCode(string color) byte ParsePercent(string str) { var trimmed = str.Trim().TrimEnd('%'); - var percent = Math.Max(0, Math.Min(100, float.Parse(trimmed))); + var percent = Math.Max(0, Math.Min(100, float.Parse(trimmed, CultureInfo.InvariantCulture))); var value = Math.Floor(255 * (percent / 100)); return (byte)value; } diff --git a/src/UkooLabs.SVGSharpie/SvgElementStyleDataDeserializer.cs b/src/UkooLabs.SVGSharpie/SvgElementStyleDataDeserializer.cs index 4ac3200..c0d140c 100644 --- a/src/UkooLabs.SVGSharpie/SvgElementStyleDataDeserializer.cs +++ b/src/UkooLabs.SVGSharpie/SvgElementStyleDataDeserializer.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Linq.Expressions; using System.Reflection; @@ -25,7 +26,7 @@ internal static class SvgElementStyleDataDeserializer ["stroke-width"] = CreateParserAndSetterForNullable(v => new SvgLength(v, SvgLengthContext.Null), s => s.StrokeWidth), ["stroke-linecap"] = CreateXmlEnumParserAndSetter(s => s.StrokeLineCap), ["stroke-linejoin"] = CreateXmlEnumParserAndSetter(s => s.StrokeLineJoin), - ["stroke-miterlimit"] = CreateParserAndSetterForNullable(float.Parse, s => s.StrokeMiterLimit), + ["stroke-miterlimit"] = CreateParserAndSetterForNullable(s => float.Parse(s, CultureInfo.InvariantCulture), s => s.StrokeMiterLimit), ["visibility"] = CreateXmlEnumParserAndSetter(s => s.Visibility), ["stroke-opacity"] = CreateParserAndSetterForInheritableNumber(s => s.StrokeOpacity), ["stroke-dasharray"] = CreateParserAndSetter(v => @@ -60,7 +61,7 @@ internal static class SvgElementStyleDataDeserializer } else { - var parsed = Math.Max(0, Math.Min(1, float.Parse(v.Value))); + var parsed = Math.Max(0, Math.Min(1, float.Parse(v.Value, CultureInfo.InvariantCulture))); value = new StyleProperty(parsed, v.IsImportant); } s.FillOpacity = value; @@ -141,7 +142,7 @@ void Result(SvgElementStyleData style, CssStylePropertyValue value) } else { - var parsedValue = float.Parse(value.Value); + var parsedValue = float.Parse(value.Value, CultureInfo.InvariantCulture); StyleProperty? propertyValue = new StyleProperty(parsedValue, isImportant: value.IsImportant); propertyInfo.SetValue(style, propertyValue); } diff --git a/src/UkooLabs.SVGSharpie/SvgLength.cs b/src/UkooLabs.SVGSharpie/SvgLength.cs index 4c6aa91..beda502 100644 --- a/src/UkooLabs.SVGSharpie/SvgLength.cs +++ b/src/UkooLabs.SVGSharpie/SvgLength.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; namespace UkooLabs.SVGSharpie { @@ -56,11 +57,11 @@ internal SvgLength(string value, SvgLengthContext context) if (unit < 0) { LengthType = SvgLengthType.Number; - ValueInSpecifiedUnits = float.Parse(value); + ValueInSpecifiedUnits = float.Parse(value, CultureInfo.InvariantCulture); } else { - ValueInSpecifiedUnits = float.Parse(value.Substring(0, unit)); + ValueInSpecifiedUnits = float.Parse(value.Substring(0, unit), CultureInfo.InvariantCulture); switch (value.Substring(unit).ToLowerInvariant()) { case "%": diff --git a/src/UkooLabs.SVGSharpie/SvgPathSegListParser.cs b/src/UkooLabs.SVGSharpie/SvgPathSegListParser.cs index 55aa326..859b787 100644 --- a/src/UkooLabs.SVGSharpie/SvgPathSegListParser.cs +++ b/src/UkooLabs.SVGSharpie/SvgPathSegListParser.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.Text; namespace UkooLabs.SVGSharpie @@ -53,7 +54,8 @@ public static SvgPathSegList Parse(string markup) buffer.Append(stream.Read()); } - args[arg] = float.Parse(buffer.ToString()); + args[arg] = float.Parse(buffer.ToString(), CultureInfo.InvariantCulture); + } result.Add(CreatePathSegment(command, isNewCommand, args)); diff --git a/src/UkooLabs.SVGSharpie/SvgPolyPointListParser.cs b/src/UkooLabs.SVGSharpie/SvgPolyPointListParser.cs index 8686174..36eab32 100644 --- a/src/UkooLabs.SVGSharpie/SvgPolyPointListParser.cs +++ b/src/UkooLabs.SVGSharpie/SvgPolyPointListParser.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; namespace UkooLabs.SVGSharpie { @@ -55,8 +56,8 @@ void AddCoordsToResult() throw new Exception($"Invalid coordinate '{point}'"); } - coords.Add(float.Parse(point.Substring(0, signIndex))); - coords.Add(float.Parse(point.Substring(signIndex + 1))); + coords.Add(float.Parse(point.Substring(0, signIndex), CultureInfo.InvariantCulture)); + coords.Add(float.Parse(point.Substring(signIndex + 1), CultureInfo.InvariantCulture)); } AddCoordsToResult(); diff --git a/src/UkooLabs.SVGSharpie/SvgRect.cs b/src/UkooLabs.SVGSharpie/SvgRect.cs index fabb282..279e953 100644 --- a/src/UkooLabs.SVGSharpie/SvgRect.cs +++ b/src/UkooLabs.SVGSharpie/SvgRect.cs @@ -1,5 +1,6 @@ using System; using System.Diagnostics; +using System.Globalization; namespace UkooLabs.SVGSharpie { @@ -99,10 +100,10 @@ public static SvgRect Parse(string str) } return new SvgRect ( - float.Parse(values[0]), - float.Parse(values[1]), - float.Parse(values[2]), - float.Parse(values[3]) + float.Parse(values[0], CultureInfo.InvariantCulture), + float.Parse(values[1], CultureInfo.InvariantCulture), + float.Parse(values[2], CultureInfo.InvariantCulture), + float.Parse(values[3], CultureInfo.InvariantCulture) ); } } diff --git a/src/UkooLabs.SVGSharpie/SvgStopElement.cs b/src/UkooLabs.SVGSharpie/SvgStopElement.cs index c42c59c..0224c55 100644 --- a/src/UkooLabs.SVGSharpie/SvgStopElement.cs +++ b/src/UkooLabs.SVGSharpie/SvgStopElement.cs @@ -1,4 +1,5 @@ -using System.Xml.Serialization; +using System.Globalization; +using System.Xml.Serialization; namespace UkooLabs.SVGSharpie { @@ -86,10 +87,10 @@ protected override SvgElement CreateClone() if (trimmed.EndsWith("%")) { - return float.Parse(trimmed.Substring(0, trimmed.Length - 1)) / 100; + return float.Parse(trimmed.Substring(0, trimmed.Length - 1), CultureInfo.InvariantCulture) / 100; } - return float.Parse(trimmed); + return float.Parse(trimmed, CultureInfo.InvariantCulture); } } } \ No newline at end of file diff --git a/src/UkooLabs.SVGSharpie/SvgTransformListParser.cs b/src/UkooLabs.SVGSharpie/SvgTransformListParser.cs index 6a247f5..de538db 100644 --- a/src/UkooLabs.SVGSharpie/SvgTransformListParser.cs +++ b/src/UkooLabs.SVGSharpie/SvgTransformListParser.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Text; @@ -57,7 +58,7 @@ private static SvgTransform CreateMatrixTransformationFromArgs(string args) { throw new Exception($"Invalid matrix transformation arguments '{args}'"); } - var values = split.Select(float.Parse).ToArray(); + var values = split.Select(x => float.Parse(x, CultureInfo.InvariantCulture)).ToArray(); return new SvgTransform(SvgTransformType.Matrix, new SvgMatrix(values)); } @@ -69,8 +70,8 @@ private static SvgTransform CreateScaleTransformationFromArgs(string args) { throw new Exception($"Invalid scale transformation arguments '{args}'"); } - var x = float.Parse(split[0]); - var y = split.Length == 2 ? float.Parse(split[1]) : x; + var x = float.Parse(split[0], CultureInfo.InvariantCulture); + var y = split.Length == 2 ? float.Parse(split[1], CultureInfo.InvariantCulture) : x; return new SvgTransform(SvgTransformType.Scale, SvgMatrix.CreateScale(x, y)); } @@ -90,9 +91,9 @@ private static SvgTransform CreateRotateTransformationFromArgs(string args) { throw new Exception($"Invalid rotate transformation arguments '{args}'"); } - var angle = float.Parse(split[0]); - var cx = split.Length > 1 ? (float?)float.Parse(split[1]) : null; - var cy = split.Length > 1 ? (float?)float.Parse(split[2]) : null; + var angle = float.Parse(split[0], CultureInfo.InvariantCulture); + var cx = split.Length > 1 ? (float?)float.Parse(split[1], CultureInfo.InvariantCulture) : null; + var cy = split.Length > 1 ? (float?)float.Parse(split[2], CultureInfo.InvariantCulture) : null; var matrix = SvgMatrix.CreateRotate(angle, cx, cy); return new SvgTransform(SvgTransformType.Rotate, matrix, angle); } @@ -105,8 +106,8 @@ private static SvgTransform CreateTranslateTransformationFromArgs(string args) { throw new Exception($"Invalid translate transformation arguments '{args}'"); } - var tx = float.Parse(split[0]); - var ty = split.Length == 2 ? float.Parse(split[1]) : tx; + var tx = float.Parse(split[0], CultureInfo.InvariantCulture); + var ty = split.Length == 2 ? float.Parse(split[1], CultureInfo.InvariantCulture) : tx; return new SvgTransform(SvgTransformType.Translate, SvgMatrix.CreateTranslate(tx, ty)); }