Skip to content

Commit 6c26aea

Browse files
committed
Improve scalar type casting, throw for unclosed comment, invalid hex
1 parent f506279 commit 6c26aea

File tree

12 files changed

+705
-55
lines changed

12 files changed

+705
-55
lines changed

ValveKeyValue/ValveKeyValue.Test/Binary/BinaryObjectSerializationTestCase.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,36 @@ public void SerializesToBinaryStructure()
5959
Assert.That((ulong)deserialized["lng"], Is.EqualTo(0x8877665544332211u));
6060
Assert.That((long)deserialized["i64"], Is.EqualTo(0x0102030405060708));
6161
}
62+
63+
[Test]
64+
public void NewValueTypesAreWidenedInBinarySerialization()
65+
{
66+
var kvo = KVObject.ListCollection();
67+
kvo.Add("bool", new KVObject(true));
68+
kvo.Add("i16", (short)42);
69+
kvo.Add("u16", (ushort)42);
70+
kvo.Add("u32", (uint)42);
71+
kvo.Add("f64", 3.14);
72+
kvo.Add("blob", KVObject.Blob([0xAB, 0xCD]));
73+
kvo.Add("null", KVObject.Null());
74+
var doc = new KVDocument(null, "Test", kvo);
75+
76+
using var ms = new MemoryStream();
77+
KVSerializer.Create(KVSerializationFormat.KeyValues1Binary).Serialize(ms, doc);
78+
79+
ms.Seek(0, SeekOrigin.Begin);
80+
var deserialized = KVSerializer.Create(KVSerializationFormat.KeyValues1Binary).Deserialize(ms);
81+
82+
Assert.Multiple(() =>
83+
{
84+
Assert.That((int)deserialized["bool"], Is.EqualTo(1));
85+
Assert.That((int)deserialized["i16"], Is.EqualTo(42));
86+
Assert.That((int)deserialized["u16"], Is.EqualTo(42));
87+
Assert.That((ulong)deserialized["u32"], Is.EqualTo(42UL));
88+
Assert.That((float)deserialized["f64"], Is.EqualTo(3.14f).Within(0.01));
89+
Assert.That((string)deserialized["blob"], Is.EqualTo("AB CD"));
90+
Assert.That((string)deserialized["null"], Is.EqualTo(string.Empty));
91+
});
92+
}
6293
}
6394
}

ValveKeyValue/ValveKeyValue.Test/ConversionCoverageTestCase.cs

Lines changed: 283 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -68,38 +68,6 @@ public void KVObjectToByte()
6868

6969
#region Cross-type conversions (store as X, read as Y)
7070

71-
[Test]
72-
public void IntToFloat()
73-
{
74-
KVObject v = 42;
75-
float f = (float)v;
76-
Assert.That(f, Is.EqualTo(42.0f));
77-
}
78-
79-
[Test]
80-
public void FloatToInt()
81-
{
82-
KVObject v = 3.14f;
83-
int i = (int)v;
84-
Assert.That(i, Is.EqualTo(3));
85-
}
86-
87-
[Test]
88-
public void IntToLong()
89-
{
90-
KVObject v = 42;
91-
long l = (long)v;
92-
Assert.That(l, Is.EqualTo(42L));
93-
}
94-
95-
[Test]
96-
public void IntToString()
97-
{
98-
KVObject v = 42;
99-
string s = (string)v;
100-
Assert.That(s, Is.EqualTo("42"));
101-
}
102-
10371
[Test]
10472
public void StringToInt()
10573
{
@@ -419,5 +387,288 @@ public void ValuesOnNullIsEmpty()
419387
}
420388

421389
#endregion
390+
391+
#region Native type cross-conversion: success paths
392+
393+
[Test]
394+
public void BooleanConversions()
395+
{
396+
KVObject t = true;
397+
KVObject f = false;
398+
399+
Assert.Multiple(() =>
400+
{
401+
Assert.That((bool)t, Is.True);
402+
Assert.That((bool)f, Is.False);
403+
Assert.That((int)t, Is.EqualTo(1));
404+
Assert.That((int)f, Is.EqualTo(0));
405+
Assert.That((long)t, Is.EqualTo(1L));
406+
Assert.That((uint)t, Is.EqualTo(1U));
407+
Assert.That((ulong)t, Is.EqualTo(1UL));
408+
Assert.That((float)t, Is.EqualTo(1.0f));
409+
Assert.That((double)t, Is.EqualTo(1.0));
410+
Assert.That((string)t, Is.EqualTo("1"));
411+
Assert.That((string)f, Is.EqualTo("0"));
412+
Assert.That(t.ToDecimal(null), Is.EqualTo(1m));
413+
});
414+
}
415+
416+
[Test]
417+
public void Int16Conversions()
418+
{
419+
KVObject v = (short)-42;
420+
421+
Assert.Multiple(() =>
422+
{
423+
Assert.That((short)v, Is.EqualTo((short)-42));
424+
Assert.That((int)v, Is.EqualTo(-42));
425+
Assert.That((long)v, Is.EqualTo(-42L));
426+
Assert.That((float)v, Is.EqualTo(-42.0f));
427+
Assert.That((double)v, Is.EqualTo(-42.0));
428+
Assert.That((string)v, Is.EqualTo("-42"));
429+
Assert.That(v.ToDecimal(null), Is.EqualTo(-42m));
430+
Assert.That((bool)v, Is.True);
431+
});
432+
}
433+
434+
[Test]
435+
public void UInt16Conversions()
436+
{
437+
KVObject v = (ushort)60000;
438+
439+
Assert.Multiple(() =>
440+
{
441+
Assert.That((ushort)v, Is.EqualTo((ushort)60000));
442+
Assert.That((int)v, Is.EqualTo(60000));
443+
Assert.That((long)v, Is.EqualTo(60000L));
444+
Assert.That((uint)v, Is.EqualTo(60000U));
445+
Assert.That((ulong)v, Is.EqualTo(60000UL));
446+
Assert.That((float)v, Is.EqualTo(60000.0f));
447+
Assert.That((double)v, Is.EqualTo(60000.0));
448+
Assert.That((string)v, Is.EqualTo("60000"));
449+
Assert.That(v.ToDecimal(null), Is.EqualTo(60000m));
450+
});
451+
}
452+
453+
[Test]
454+
public void Int32Conversions()
455+
{
456+
KVObject v = -100;
457+
458+
Assert.Multiple(() =>
459+
{
460+
Assert.That((int)v, Is.EqualTo(-100));
461+
Assert.That((long)v, Is.EqualTo(-100L));
462+
Assert.That((short)v, Is.EqualTo((short)-100));
463+
Assert.That((double)v, Is.EqualTo(-100.0));
464+
Assert.That((string)v, Is.EqualTo("-100"));
465+
Assert.That(v.ToDecimal(null), Is.EqualTo(-100m));
466+
Assert.That((bool)v, Is.True);
467+
});
468+
}
469+
470+
[Test]
471+
public void UInt32Conversions()
472+
{
473+
KVObject v = (uint)42;
474+
475+
Assert.Multiple(() =>
476+
{
477+
Assert.That((uint)v, Is.EqualTo(42U));
478+
Assert.That((int)v, Is.EqualTo(42));
479+
Assert.That((long)v, Is.EqualTo(42L));
480+
Assert.That((ulong)v, Is.EqualTo(42UL));
481+
Assert.That((float)v, Is.EqualTo(42.0f));
482+
Assert.That((double)v, Is.EqualTo(42.0));
483+
Assert.That((string)v, Is.EqualTo("42"));
484+
Assert.That(v.ToDecimal(null), Is.EqualTo(42m));
485+
Assert.That((bool)v, Is.True);
486+
});
487+
}
488+
489+
[Test]
490+
public void Int64Conversions()
491+
{
492+
KVObject v = 100_000L;
493+
494+
Assert.Multiple(() =>
495+
{
496+
Assert.That((long)v, Is.EqualTo(100_000L));
497+
Assert.That((int)v, Is.EqualTo(100_000));
498+
Assert.That((float)v, Is.EqualTo(100_000.0f));
499+
Assert.That((double)v, Is.EqualTo(100_000.0));
500+
Assert.That((string)v, Is.EqualTo("100000"));
501+
Assert.That(v.ToDecimal(null), Is.EqualTo(100_000m));
502+
Assert.That((ulong)v, Is.EqualTo(100_000UL));
503+
});
504+
}
505+
506+
[Test]
507+
public void UInt64Conversions()
508+
{
509+
KVObject v = (ulong)42;
510+
511+
Assert.Multiple(() =>
512+
{
513+
Assert.That((ulong)v, Is.EqualTo(42UL));
514+
Assert.That((long)v, Is.EqualTo(42L));
515+
Assert.That((int)v, Is.EqualTo(42));
516+
Assert.That((float)v, Is.EqualTo(42.0f));
517+
Assert.That((double)v, Is.EqualTo(42.0));
518+
Assert.That((string)v, Is.EqualTo("42"));
519+
Assert.That(v.ToDecimal(null), Is.EqualTo(42m));
520+
Assert.That((bool)v, Is.True);
521+
});
522+
}
523+
524+
[Test]
525+
public void LargeUInt64Conversions()
526+
{
527+
KVObject v = ulong.MaxValue;
528+
529+
Assert.Multiple(() =>
530+
{
531+
Assert.That((ulong)v, Is.EqualTo(ulong.MaxValue));
532+
Assert.That((float)v, Is.EqualTo((float)ulong.MaxValue));
533+
Assert.That((double)v, Is.EqualTo((double)ulong.MaxValue));
534+
Assert.That((string)v, Is.EqualTo("18446744073709551615"));
535+
Assert.That(v.ToDecimal(null), Is.EqualTo((decimal)ulong.MaxValue));
536+
Assert.That((bool)v, Is.True);
537+
});
538+
}
539+
540+
[Test]
541+
public void FloatingPointConversions()
542+
{
543+
KVObject v = 3.14f;
544+
545+
Assert.Multiple(() =>
546+
{
547+
Assert.That((float)v, Is.EqualTo(3.14f));
548+
Assert.That((double)v, Is.EqualTo(3.14f).Within(0.001));
549+
Assert.That((int)v, Is.EqualTo(3));
550+
Assert.That((long)v, Is.EqualTo(3L));
551+
Assert.That(v.ToDecimal(null), Is.EqualTo(3.14m).Within(0.01m));
552+
Assert.That((bool)v, Is.True);
553+
Assert.That((bool)(KVObject)0.0f, Is.False);
554+
});
555+
}
556+
557+
[Test]
558+
public void FloatingPoint64Conversions()
559+
{
560+
KVObject v = 3.14159265;
561+
562+
Assert.Multiple(() =>
563+
{
564+
Assert.That((double)v, Is.EqualTo(3.14159265));
565+
Assert.That((float)v, Is.EqualTo(3.14159265f).Within(0.0001f));
566+
Assert.That((int)v, Is.EqualTo(3));
567+
Assert.That((long)v, Is.EqualTo(3L));
568+
Assert.That(v.ToDecimal(null), Is.EqualTo(3.14159265m).Within(0.0001m));
569+
Assert.That((string)v, Does.Contain("3.14159"));
570+
Assert.That((bool)v, Is.True);
571+
Assert.That((bool)(KVObject)0.0, Is.False);
572+
});
573+
}
574+
575+
[Test]
576+
public void PointerConversions()
577+
{
578+
KVObject v = new IntPtr(42);
579+
580+
Assert.Multiple(() =>
581+
{
582+
Assert.That((IntPtr)v, Is.EqualTo(new IntPtr(42)));
583+
Assert.That((int)v, Is.EqualTo(42));
584+
Assert.That((long)v, Is.EqualTo(42L));
585+
Assert.That((string)v, Is.EqualTo("42"));
586+
Assert.That((bool)v, Is.True);
587+
});
588+
}
589+
590+
#endregion
591+
592+
#region Native type cross-conversion: overflow boundaries
593+
594+
[Test]
595+
public void UInt32ToInt32ThrowsOnOverflow()
596+
{
597+
KVObject v = (uint)3_000_000_000;
598+
Assert.That(() => (int)v, Throws.InstanceOf<OverflowException>());
599+
}
600+
601+
[Test]
602+
public void NegativeInt32ToUInt32ThrowsOnOverflow()
603+
{
604+
KVObject v = -1;
605+
Assert.That(() => (uint)v, Throws.InstanceOf<OverflowException>());
606+
}
607+
608+
[Test]
609+
public void NegativeInt32ToUInt64ThrowsOnOverflow()
610+
{
611+
KVObject v = -1;
612+
Assert.That(() => (ulong)v, Throws.InstanceOf<OverflowException>());
613+
}
614+
615+
[Test]
616+
public void NegativeInt64ToUInt64ThrowsOnOverflow()
617+
{
618+
KVObject v = (long)-1;
619+
Assert.That(() => (ulong)v, Throws.InstanceOf<OverflowException>());
620+
}
621+
622+
[Test]
623+
public void NegativeInt16ToUInt32ThrowsOnOverflow()
624+
{
625+
KVObject v = (short)-1;
626+
Assert.That(() => (uint)v, Throws.InstanceOf<OverflowException>());
627+
}
628+
629+
[Test]
630+
public void NegativeInt16ToUInt64ThrowsOnOverflow()
631+
{
632+
KVObject v = (short)-1;
633+
Assert.That(() => (ulong)v, Throws.InstanceOf<OverflowException>());
634+
}
635+
636+
[Test]
637+
public void UInt16MaxToInt16ThrowsOnOverflow()
638+
{
639+
KVObject v = (ushort)65535;
640+
Assert.That(() => (short)v, Throws.InstanceOf<OverflowException>());
641+
}
642+
643+
[Test]
644+
public void Int64MaxToInt32ThrowsOnOverflow()
645+
{
646+
KVObject v = long.MaxValue;
647+
Assert.That(() => (int)v, Throws.InstanceOf<OverflowException>());
648+
}
649+
650+
[Test]
651+
public void LargeUInt64ToInt64ThrowsOnOverflow()
652+
{
653+
KVObject v = ulong.MaxValue;
654+
Assert.That(() => (long)v, Throws.InstanceOf<OverflowException>());
655+
}
656+
657+
[Test]
658+
public void LargeUInt64ToInt32ThrowsOnOverflow()
659+
{
660+
KVObject v = ulong.MaxValue;
661+
Assert.That(() => (int)v, Throws.InstanceOf<OverflowException>());
662+
}
663+
664+
[Test]
665+
public void LargeUInt64ToDecimalSucceeds()
666+
{
667+
var largeValue = (ulong)long.MaxValue + 1;
668+
KVObject v = largeValue;
669+
Assert.That(v.ToDecimal(null), Is.EqualTo((decimal)largeValue));
670+
}
671+
672+
#endregion
422673
}
423674
}

0 commit comments

Comments
 (0)