From 9ff306d958e178843b292044ce208cda86adc825 Mon Sep 17 00:00:00 2001 From: Tom Sepez Date: Mon, 24 Apr 2017 15:55:11 -0700 Subject: Add FXSYS_wcsftime() to avoid termination on win. Bug: 712725 Change-Id: I3384385176410964a87b12c2587f68247ea80cc9 Reviewed-on: https://pdfium-review.googlesource.com/4454 Reviewed-by: Lei Zhang Commit-Queue: Tom Sepez --- BUILD.gn | 1 + core/fxcrt/fx_system.cpp | 28 ++++++++++++++++++++++++++++ core/fxcrt/fx_system.h | 13 ++++++++----- core/fxcrt/fx_system_unittest.cpp | 37 +++++++++++++++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 core/fxcrt/fx_system.cpp diff --git a/BUILD.gn b/BUILD.gn index 23e1cf2dbe..3e5eafbe1a 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -782,6 +782,7 @@ static_library("fxcrt") { "core/fxcrt/fx_stream.cpp", "core/fxcrt/fx_stream.h", "core/fxcrt/fx_string.h", + "core/fxcrt/fx_system.cpp", "core/fxcrt/fx_system.h", "core/fxcrt/fx_ucd.h", "core/fxcrt/fx_ucddata.cpp", diff --git a/core/fxcrt/fx_system.cpp b/core/fxcrt/fx_system.cpp new file mode 100644 index 0000000000..d2b04f502a --- /dev/null +++ b/core/fxcrt/fx_system.cpp @@ -0,0 +1,28 @@ +// Copyright 2017 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fxcrt/fx_system.h" + +#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ + +size_t FXSYS_wcsftime(wchar_t* strDest, + size_t maxsize, + const wchar_t* format, + const struct tm* timeptr) { + // Avoid tripping an invalid parameter handler and crashing process. + // Note: leap seconds may cause tm_sec == 60. + if (timeptr->tm_year < 0 || timeptr->tm_mon < 0 || timeptr->tm_mon > 11 || + timeptr->tm_mday < 1 || timeptr->tm_mday > 31 || timeptr->tm_hour < 0 || + timeptr->tm_hour > 23 || timeptr->tm_min < 0 || timeptr->tm_min > 59 || + timeptr->tm_sec < 0 || timeptr->tm_sec > 60 || timeptr->tm_wday < 0 || + timeptr->tm_wday > 6 || timeptr->tm_yday < 0 || timeptr->tm_yday > 365) { + strDest[0] = L'\0'; + return 0; + } + return wcsftime(strDest, maxsize, format, timeptr); +} + +#endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ diff --git a/core/fxcrt/fx_system.h b/core/fxcrt/fx_system.h index 1ee0d8b601..1e66e7bb80 100644 --- a/core/fxcrt/fx_system.h +++ b/core/fxcrt/fx_system.h @@ -114,7 +114,7 @@ void FXSYS_snprintf(char* str, _Printf_format_string_ const char* fmt, ...); void FXSYS_vsnprintf(char* str, size_t size, const char* fmt, va_list ap); -#else +#else // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ && _MSC_VER < 1900 #define FXSYS_snprintf (void)snprintf #define FXSYS_vsnprintf (void)vsnprintf #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ && _MSC_VER < 1900 @@ -180,7 +180,10 @@ extern "C" { #define FXSYS_pow(a, b) (float)powf(a, b) #define FXSYS_GetFullPathName GetFullPathName #define FXSYS_GetModuleFileName GetModuleFileName - +size_t FXSYS_wcsftime(wchar_t* strDest, + size_t maxsize, + const wchar_t* format, + const struct tm* timeptr); #ifdef _NATIVE_WCHAR_T_DEFINED #define FXSYS_wcsicmp(str1, str2) _wcsicmp((wchar_t*)(str1), (wchar_t*)(str2)) #define FXSYS_WideCharToMultiByte(p1, p2, p3, p4, p5, p6, p7, p8) \ @@ -189,14 +192,14 @@ extern "C" { MultiByteToWideChar(p1, p2, p3, p4, (wchar_t*)(p5), p6) #define FXSYS_wcslwr(str) _wcslwr((wchar_t*)(str)) #define FXSYS_wcsupr(str) _wcsupr((wchar_t*)(str)) -#else +#else // _NATIVE_WCHAR_T_DEFINED #define FXSYS_wcsicmp _wcsicmp #define FXSYS_WideCharToMultiByte WideCharToMultiByte #define FXSYS_MultiByteToWideChar MultiByteToWideChar #define FXSYS_wcslwr _wcslwr #define FXSYS_wcsupr _wcsupr #endif // _NATIVE_WCHAR_T_DEFINED -#else +#else // _FXM_PLATFORM == _FXM_PLATFORM_WINDOWS_ int FXSYS_GetACP(); char* FXSYS_itoa(int value, char* str, int radix); int FXSYS_WideCharToMultiByte(uint32_t codepage, @@ -225,6 +228,7 @@ int FXSYS_wcsicmp(const wchar_t* str1, const wchar_t* str2); wchar_t* FXSYS_wcslwr(wchar_t* str); wchar_t* FXSYS_wcsupr(wchar_t* str); #define FXSYS_pow(a, b) (float)pow(a, b) +#define FXSYS_wcsftime wcsftime #endif // _FXM_PLATFORM == _FXM_PLATFORM_WINDOWS_ #define FXDWORD_GET_LSBFIRST(p) \ @@ -249,7 +253,6 @@ int FXSYS_round(float f); // size_t size; // printf("xyz: %" PRIuS, size); // The "u" in the macro corresponds to %u, and S is for "size". - #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ #if (defined(_INTTYPES_H) || defined(_INTTYPES_H_)) && !defined(PRId64) diff --git a/core/fxcrt/fx_system_unittest.cpp b/core/fxcrt/fx_system_unittest.cpp index def0043bab..5a7660d256 100644 --- a/core/fxcrt/fx_system_unittest.cpp +++ b/core/fxcrt/fx_system_unittest.cpp @@ -160,3 +160,40 @@ TEST(fxcrt, FXSYS_i64toa) { } #endif // _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ + +TEST(fxcrt, FXSYS_wcsftime) { + struct tm good_time = {}; + good_time.tm_year = 74; // 1900-based. + good_time.tm_mon = 7; // 0-based. + good_time.tm_mday = 9; // 1-based. + good_time.tm_hour = 11; + good_time.tm_min = 59; + good_time.tm_sec = 59; + + wchar_t buf[100] = {}; + EXPECT_EQ(19u, FXSYS_wcsftime(buf, FX_ArraySize(buf), L"%Y-%m-%dT%H:%M:%S", + &good_time)); + EXPECT_EQ(std::wstring(L"1974-08-09T11:59:59"), buf); + + // Ensure wcsftime handles bad years, etc. without crashing. + struct tm bad_time = {}; + bad_time.tm_year = -1; + bad_time.tm_mon = -1; + bad_time.tm_mday = -1; + bad_time.tm_hour = -1; + bad_time.tm_min = -1; + bad_time.tm_sec = -1; + + FXSYS_wcsftime(buf, FX_ArraySize(buf), L"%y-%m-%dT%H:%M:%S", &bad_time); + + // Ensure wcsftime handles bad-ish day without crashing (Feb 30). + struct tm feb_time = {}; + feb_time.tm_year = 115; // 1900-based. + feb_time.tm_mon = 1; // 0-based. + feb_time.tm_mday = 30; // 1-based. + feb_time.tm_hour = 12; + feb_time.tm_min = 00; + feb_time.tm_sec = 00; + + FXSYS_wcsftime(buf, FX_ArraySize(buf), L"%y-%m-%dT%H:%M:%S", &feb_time); +} -- cgit v1.2.3