robertvazan / guerrillantp

Simple NTP (SNTP) client library providing .NET applications with accurate network time.
https://guerrillantp.machinezoo.com/
Apache License 2.0
66 stars 17 forks source link

SetDateTime64 Overflow Exception #5

Closed TGibsonReach closed 2 years ago

TGibsonReach commented 2 years ago

Passing in a time >= year 2037 to function: void SetDateTime64(int offset, DateTime? value) { SetUInt64BE(offset, value == null ? 0 : Convert.ToUInt64((value.Value.Ticks - epoch.Ticks) * (0.0000001 * (1L << 32)))); } causes the conversion to UInt64 to overflow.

Test Program:


namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime EpochFuture = new DateTime(2037, 1, 1);
            DateTime EpochPast = new DateTime(1900, 1, 1);
            try
            {
                UInt64 Result = Convert.ToUInt64((EpochFuture.Ticks - EpochPast.Ticks) * (0.0000001 * (1L << 32)));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
    }
}

Output: System.OverflowException: Arithmetic operation resulted in an overflow. at System.Convert.ToUInt64(Double value) at ConsoleApp1.Program.Main(String[] args) in MyProgram

DamianMorozov commented 2 years ago

What are you doing? It is not NtpClient's methods.

TGibsonReach commented 2 years ago

NtpPacket.cs contains the inline function which is used when setting several of the packet variables?

void SetDateTime64(int offset, DateTime? value) 
{ 
       SetUInt64BE(offset, value == null ? 0 : Convert.ToUInt64((value.Value.Ticks - epoch.Ticks) * (0.0000001 * (1L << 32)))); 
}
robertvazan commented 2 years ago

I can confirm that GuerrillaNtp is not Y2038 safe. It needs to implement correct rollover.

robertvazan commented 2 years ago

This is actually Y2036 bug, not Y2038 bug. I have fixed the library. The fix will be included in 3.0 release that is coming in the next few days.