Skip to content

Improper use of GetTickCount #3437

@mkujawa

Description

@mkujawa

e9ababd#diff-0a54b726bba1300aed45ad5693c349d1 has introduced a warning regression by switching from a compile-time check to a run-time check, but highlights a real bug.

I did this

Compiled for windows with msvc /analyze and many warnings enabled

I expected the following

Clean compilation. But instead,

  curl\lib\timeval.c(55): error C2220: warning treated as error - no 'object' file generated
  curl\lib\timeval.c(50) : warning C28159: Consider using 'GetTickCount64' instead of 'GetTickCount'. Reason: GetTickCount overflows roughly every 49 days.  Code that does not take that into account can loop indefinitely.  GetTickCount64 operates on 64 bit values and does not have that problem

And that warning is highlighting a real bug with this code. GetTickCount() should not be used as a monotonically increasing time source. Instead, you should store your own count and increment it by the change in GetTickCount().

Pseudocode:

  static DWORDLONG ticks = {};
  static DWORD lastMilliseconds = 0;
  DWORD curMilliseconds = GetTickCount();
  if ( lastMilliseconds )
  {
    ticks += (curMilliseconds - lastMilliseconds);
  }
  lastMilliseconds = curMilliseconds;
  now.tv_sec = (time_t)(ticks / 1000);
  now.tv_usec = (unsigned int)(ticks % 1000);

This will have no overflow issues so long as it's called more frequently than once every 2^31-1 milliseconds. My pseudocode does have issues with multiple threads, though.

curl/libcurl version

251cabf

operating system

Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24215.1 for x64

Metadata

Metadata

Assignees

No one assigned

    Labels

    WindowsWindows-specific

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions