summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BUILD.gn1
-rw-r--r--core/fxcrt/fx_system.cpp28
-rw-r--r--core/fxcrt/fx_system.h13
-rw-r--r--core/fxcrt/fx_system_unittest.cpp37
4 files changed, 74 insertions, 5 deletions
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);
+}