Skip to content

Commit

Permalink
Fix deserialization of ulongs greater than long.MaxValue.
Browse files Browse the repository at this point in the history
  • Loading branch information
aaubry committed Sep 23, 2016
1 parent a732b2e commit 62bcaac
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 24 deletions.
26 changes: 26 additions & 0 deletions YamlDotNet.Test/Serialization/SerializationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1343,5 +1343,31 @@ public void Write(IEmitter emitter, ObjectSerializer nestedObjectSerializer)
nestedObjectSerializer(Value, typeof(T));
}
}

[Theory]
[InlineData(uint.MinValue)]
[InlineData(uint.MaxValue)]
[InlineData(0x8000000000000000UL)]
public void DeserializationOfUInt64Succeeds(ulong value)
{
var yaml = new Serializer().Serialize(value);
Assert.Contains(value.ToString(), yaml);

ulong parsed = new Deserializer().Deserialize<ulong>(yaml);
Assert.Equal(value, parsed);
}

[Theory]
[InlineData(int.MinValue)]
[InlineData(int.MaxValue)]
[InlineData(0L)]
public void DeserializationOfInt64Succeeds(long value)
{
var yaml = new Serializer().Serialize(value);
Assert.Contains(value.ToString(), yaml);

long parsed = new Deserializer().Deserialize<long>(yaml);
Assert.Equal(value, parsed);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ private object DeserializeIntegerHelper(TypeCode typeCode, string value)
int currentIndex = 0;
bool isNegative = false;
int numberBase = 0;
long result = 0;
ulong result = 0;

if (value[0] == '-')
{
Expand Down Expand Up @@ -202,11 +202,11 @@ private object DeserializeIntegerHelper(TypeCode typeCode, string value)
case 2:
case 8:
// TODO: how to incorporate the numberFormat?
result = Convert.ToInt64(numberBuilder.ToString(), numberBase);
result = Convert.ToUInt64(numberBuilder.ToString(), numberBase);
break;

case 16:
result = Int64.Parse(numberBuilder.ToString(), NumberStyles.HexNumber, YamlFormatter.NumberFormat);
result = ulong.Parse(numberBuilder.ToString(), NumberStyles.HexNumber, YamlFormatter.NumberFormat);
break;

case 10:
Expand All @@ -226,43 +226,89 @@ private object DeserializeIntegerHelper(TypeCode typeCode, string value)
result *= 60;

// TODO: verify that chunks after the first are non-negative and less than 60
result += long.Parse(chunks[chunkIndex].Replace("_", ""));
result += ulong.Parse(chunks[chunkIndex].Replace("_", ""));
}
}

if (isNegative)
{
result = -result;
return CastInteger(checked(-(long)result), typeCode);
}
else
{
return CastInteger(result, typeCode);
}
}

private static object CastInteger(long number, TypeCode typeCode)
{
checked
{
switch (typeCode)
{
case TypeCode.Byte:
return (byte)number;

case TypeCode.Int16:
return (short)number;

case TypeCode.Int32:
return (int)number;

case TypeCode.Int64:
return number;

case TypeCode.SByte:
return (sbyte)number;

case TypeCode.UInt16:
return (ushort)number;

case TypeCode.UInt32:
return (uint)number;

case TypeCode.UInt64:
return (ulong)number;

switch (typeCode)
default:
return number;
}
}
}

private static object CastInteger(ulong number, TypeCode typeCode)
{
checked
{
case TypeCode.Byte:
return (byte)result;
switch (typeCode)
{
case TypeCode.Byte:
return (byte)number;

case TypeCode.Int16:
return (short)result;
case TypeCode.Int16:
return (short)number;

case TypeCode.Int32:
return (int)result;
case TypeCode.Int32:
return (int)number;

case TypeCode.Int64:
return result;
case TypeCode.Int64:
return (long)number;

case TypeCode.SByte:
return (sbyte)result;
case TypeCode.SByte:
return (sbyte)number;

case TypeCode.UInt16:
return (ushort)result;
case TypeCode.UInt16:
return (ushort)number;

case TypeCode.UInt32:
return (uint)result;
case TypeCode.UInt32:
return (uint)number;

case TypeCode.UInt64:
return (ulong)result;
case TypeCode.UInt64:
return number;

default:
return result;
default:
return number;
}
}
}
}
Expand Down

0 comments on commit 62bcaac

Please sign in to comment.