如何破解 gmtime_r C++

bmb*_*bmb 3 c++ unit-testing

这可能是一个奇怪的问题,但我正在尝试找到一种方法来破坏该gmtime_r功能。我正在为这段代码编写一个测试,但我找不到一个案例来到达不包含设置ptrdatesto的 else 语句NULL

int main() {
    time_t ptr; // Actual storage for time_t
    struct tm dates; // Actual storage for struct tm
    time(&ptr); // Pointer to a time_t
    if(gmtime_r(&ptr, &dates)) { // Pointer to a time_t, pointer to a
        size_t a = 10;
    }
    else
    {
        size_t a = 20; //<-- trying to reach this else statement
    }
return 0;
}
Run Code Online (Sandbox Code Playgroud)

是否有任何有效的非 NULL 值可以设置ptr,或者dates可以绕过 if 语句并进入 else ?

Alc*_*te_ 5

To provide an exact answer your question, we would need to know the implementation you're using to build your project.

Usually, standard headers like have public source, so you can search by yourself for the failure possibilities.

For glibc, I went down the rabbithole to give an example. (See source here)

In time/gmtime.c, we can see that gmtime_r is a weak alias for __gmtime_r, which returns __tz_convert directly.

In time/txset.c we see that __tz_convert can only return NULL if the __offtime function fails (returning 0).

Finally, in time/offtime.c, we see that:

  tp->tm_year = y - 1900;
  if (tp->tm_year != y - 1900)
    {
      /* The year cannot be represented due to overflow.  */
      __set_errno (EOVERFLOW);
      return 0;
    }
Run Code Online (Sandbox Code Playgroud)

Which indicates a good clue about how we can make it fail. You can verify your idea with a short program.

e.g. 用于测试如何使 gmtime_r 失败的示例程序

In my case, simply providing a large positive time does the trick, as the code uses integers for years, but time_t being a 64 bit value (on my system), I can have much more years than what int (on my system) can represent.

当然,您可以立即执行示例测试程序,而无需查看源代码..但是这样不是更有趣吗?:P