@@ -98,9 +98,7 @@ public override bool CanConvertTo(ITypeDescriptorContext typeDescriptorContext,
9898 /// <param name="typeDescriptorContext"> The ITypeDescriptorContext for this call. </param>
9999 /// <param name="cultureInfo"> The CultureInfo which is respected when converting. </param>
100100 /// <param name="source"> The object to convert to a double. </param>
101- public override object ConvertFrom ( ITypeDescriptorContext typeDescriptorContext ,
102- CultureInfo cultureInfo ,
103- object source )
101+ public override object ConvertFrom ( ITypeDescriptorContext typeDescriptorContext , CultureInfo cultureInfo , object source )
104102 {
105103 if ( source is not null )
106104 {
@@ -130,10 +128,7 @@ public override object ConvertFrom(ITypeDescriptorContext typeDescriptorContext,
130128 /// <param name="cultureInfo"> The CultureInfo which is respected when converting. </param>
131129 /// <param name="value"> The double to convert. </param>
132130 /// <param name="destinationType">The type to which to convert the double. </param>
133- public override object ConvertTo ( ITypeDescriptorContext typeDescriptorContext ,
134- CultureInfo cultureInfo ,
135- object value ,
136- Type destinationType )
131+ public override object ConvertTo ( ITypeDescriptorContext typeDescriptorContext , CultureInfo cultureInfo , object value , Type destinationType )
137132 {
138133 ArgumentNullException . ThrowIfNull ( destinationType ) ;
139134
@@ -174,62 +169,65 @@ public override object ConvertTo(ITypeDescriptorContext typeDescriptorContext,
174169 // NOTE - This code is called from FontSizeConverter, so changes will affect both.
175170 static internal double FromString ( string s , CultureInfo cultureInfo )
176171 {
177- ReadOnlySpan < char > valueString = s . AsSpan ( ) . Trim ( ) ;
178-
172+ string valueString = s . Trim ( ) ;
173+ string goodString = valueString . ToLowerInvariant ( ) ;
174+ int strLen = goodString . Length ;
179175 int strLenUnit = 0 ;
180176 double unitFactor = 1.0 ;
181177
182- //Auto is represented as Double.NaN
178+ //Auto is represented and Double.NaN
183179 //properties that do not want Auto and NaN to be in their ligit values,
184180 //should disallow NaN in validation callbacks (same goes for negative values)
185- if ( valueString . Equals ( "Auto" , StringComparison . OrdinalIgnoreCase ) )
186- return double . NaN ;
181+ if ( goodString == "auto" )
182+ return Double . NaN ;
187183
188- for ( int i = 0 ; i < s_pixelUnitStrings . Length ; i ++ )
184+ for ( int i = 0 ; i < PixelUnitStrings . Length ; i ++ )
189185 {
190186 // NOTE: This is NOT a culture specific comparison.
191187 // This is by design: we want the same unit string table to work across all cultures.
192- if ( valueString . EndsWith ( s_pixelUnitStrings [ i ] , StringComparison . OrdinalIgnoreCase ) )
188+ if ( goodString . EndsWith ( PixelUnitStrings [ i ] , StringComparison . Ordinal ) )
193189 {
194- strLenUnit = s_pixelUnitStrings [ i ] . Length ;
190+ strLenUnit = PixelUnitStrings [ i ] . Length ;
195191 unitFactor = PixelUnitFactors [ i ] ;
196192 break ;
197193 }
198194 }
199195
200- // Remove pixel unit string if present, otherwise no-op
201- valueString = valueString . Slice ( 0 , valueString . Length - strLenUnit ) ;
196+ // important to substring original non-lowered string
197+ // this allows case sensitive ToDouble below handle "NaN" and "Infinity" correctly.
198+ // this addresses windows bug 1177408
199+ valueString = valueString . Substring ( 0 , strLen - strLenUnit ) ;
202200
203201 // FormatException errors thrown by Convert.ToDouble are pretty uninformative.
204202 // Throw a more meaningful error in this case that tells that we were attempting
205203 // to create a Length instance from a string. This addresses windows bug 968884
206204 try
207205 {
208- return double . Parse ( valueString , cultureInfo ) * unitFactor ;
206+ double result = Convert . ToDouble ( valueString , cultureInfo ) * unitFactor ;
207+ return result ;
209208 }
210209 catch ( FormatException )
211210 {
212- throw new FormatException ( SR . Format ( SR . LengthFormatError , valueString . ToString ( ) ) ) ;
211+ throw new FormatException ( SR . Format ( SR . LengthFormatError , valueString ) ) ;
213212 }
214213 }
215214
216- // This array contains string representations for unit known types.
215+ // This array contains strings for unit types
217216 // These are effectively "TypeConverter only" units.
218217 // They are all expressable in terms of the Pixel unit type and a conversion factor.
219- private static readonly string [ ] s_pixelUnitStrings = [ "px" , "in" , "cm" , "pt" ] ;
220-
221- /// <summary> Holds the factor value representation for units specified in <see cref="s_pixelUnitStrings"/>. </summary>
222- private static ReadOnlySpan < double > PixelUnitFactors =>
223- [
224- 1.0 , // px - Pixel itself
225- 96.0 , // in - Pixels per Inch
226- 96.0 / 2.54 , // cm - Pixels per Centimeter
227- 96.0 / 72.0 , // pt - Pixels per Point
228- ] ;
218+ static private string [ ] PixelUnitStrings = { "px" , "in" , "cm" , "pt" } ;
219+ static private double [ ] PixelUnitFactors =
220+ {
221+ 1.0 , // Pixel itself
222+ 96.0 , // Pixels per Inch
223+ 96.0 / 2.54 , // Pixels per Centimeter
224+ 96.0 / 72.0 , // Pixels per Point
225+ } ;
229226
230227 static internal string ToString ( double l , CultureInfo cultureInfo )
231228 {
232- if ( double . IsNaN ( l ) ) return "Auto" ;
229+ if ( double . IsNaN ( l ) )
230+ return "Auto" ;
233231 return Convert . ToString ( l , cultureInfo ) ;
234232 }
235233
0 commit comments