summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLei Zhang <thestig@chromium.org>2017-06-16 13:48:19 -0700
committerChromium commit bot <commit-bot@chromium.org>2017-06-16 20:59:51 +0000
commit2bf942d8c21b653efdfdcae681769cffbfaa0663 (patch)
tree64c3e323c0ac00736db643f9a06976a52501761c
parent1e25e122849b0e16032f5b3d62bace4d3ce5253d (diff)
downloadpdfium-2bf942d8c21b653efdfdcae681769cffbfaa0663.tar.xz
Avoid a crash inside wcsftime() on Windows.chromium/3135chromium/3134chromium/3133
BUG=chromium:733245 Change-Id: Ic9347e2cc245831c0b71fac1d531c33c5646ab3f Reviewed-on: https://pdfium-review.googlesource.com/6671 Commit-Queue: Lei Zhang <thestig@chromium.org> Reviewed-by: Nicolás Peña <npm@chromium.org>
-rw-r--r--core/fxcrt/fx_system.cpp2
-rw-r--r--core/fxcrt/fx_system_unittest.cpp16
-rw-r--r--fpdfsdk/javascript/util.cpp7
-rw-r--r--testing/resources/javascript/util_printd.in32
-rw-r--r--testing/resources/javascript/util_printd_expected.txt14
5 files changed, 68 insertions, 3 deletions
diff --git a/core/fxcrt/fx_system.cpp b/core/fxcrt/fx_system.cpp
index cf1c7e5920..af883882b1 100644
--- a/core/fxcrt/fx_system.cpp
+++ b/core/fxcrt/fx_system.cpp
@@ -24,7 +24,7 @@ size_t FXSYS_wcsftime(wchar_t* strDest,
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 ||
+ if (timeptr->tm_year < -1900 || 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 ||
diff --git a/core/fxcrt/fx_system_unittest.cpp b/core/fxcrt/fx_system_unittest.cpp
index 5a7660d256..a83b275111 100644
--- a/core/fxcrt/fx_system_unittest.cpp
+++ b/core/fxcrt/fx_system_unittest.cpp
@@ -173,7 +173,21 @@ TEST(fxcrt, FXSYS_wcsftime) {
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);
+ EXPECT_STREQ(L"1974-08-09T11:59:59", buf);
+
+ // Ensure wcsftime handles a wide range of years without crashing.
+ struct tm year_time = {};
+ year_time.tm_mon = 7; // 0-based.
+ year_time.tm_mday = 9; // 1-based.
+ year_time.tm_hour = 11;
+ year_time.tm_min = 59;
+ year_time.tm_sec = 59;
+
+ for (int year = -2500; year <= 2500; ++year) {
+ year_time.tm_year = year;
+ wchar_t buf[100] = {};
+ FXSYS_wcsftime(buf, FX_ArraySize(buf), L"%Y-%m-%dT%H:%M:%S", &year_time);
+ }
// Ensure wcsftime handles bad years, etc. without crashing.
struct tm bad_time = {};
diff --git a/fpdfsdk/javascript/util.cpp b/fpdfsdk/javascript/util.cpp
index 72b94ab302..100a5caab4 100644
--- a/fpdfsdk/javascript/util.cpp
+++ b/fpdfsdk/javascript/util.cpp
@@ -250,6 +250,11 @@ bool util::printd(CJS_Runtime* pRuntime,
}
int iYear = jsDate.GetYear(pRuntime);
+ if (iYear < 0) {
+ sError = JSGetStringFromID(IDS_STRING_JSVALUEERROR);
+ return false;
+ }
+
int iMonth = jsDate.GetMonth(pRuntime);
int iDay = jsDate.GetDay(pRuntime);
int iHour = jsDate.GetHours(pRuntime);
@@ -290,7 +295,7 @@ bool util::printd(CJS_Runtime* pRuntime,
time.tm_sec = iSec;
wchar_t buf[64] = {};
- wcsftime(buf, 64, cFormat.c_str(), &time);
+ FXSYS_wcsftime(buf, 64, cFormat.c_str(), &time);
cFormat = buf;
vRet = CJS_Value(pRuntime, cFormat.c_str());
return true;
diff --git a/testing/resources/javascript/util_printd.in b/testing/resources/javascript/util_printd.in
index f098187cf0..4d8610d429 100644
--- a/testing/resources/javascript/util_printd.in
+++ b/testing/resources/javascript/util_printd.in
@@ -94,6 +94,38 @@ TestOneFormat({"clams": 3}, d1);
TestOneFormat(["clams", 3], d1);
TestOneXFAFormat("mm", d1, false);
TestOneXFAFormat("mm", d1, true);
+
+// Date with year 0.
+// TODO(thestig): Why is the output different from Acrobat?
+TestOneFormat("mm/dd/yyyy HH:MM:ss", new Date(0, 06, 04, 15, 59, 58));
+// Date with month 20.
+TestOneFormat("mm/dd/yyyy HH:MM:ss", new Date(2014, 20, 04, 15, 59, 58));
+// Date with day 100.
+TestOneFormat("mm/dd/yyyy HH:MM:ss", new Date(2014, 20, 100, 15, 59, 58));
+// Date with hour 50
+TestOneFormat("mm/dd/yyyy HH:MM:ss", new Date(2014, 06, 04, 50, 59, 58));
+// Date with minute 1234.
+TestOneFormat("mm/dd/yyyy HH:MM:ss", new Date(2014, 06, 04, 15, 1234, 58));
+// Date with second 65.
+TestOneFormat("mm/dd/yyyy HH:MM:ss", new Date(2014, 06, 04, 15, 59, 65));
+// Date with April 31th.
+TestOneFormat("mm/dd/yyyy HH:MM:ss", new Date(2014, 03, 31, 15, 59, 58));
+// Date with February 30th.
+TestOneFormat("mm/dd/yyyy HH:MM:ss", new Date(2014, 01, 30, 15, 59, 58));
+// Date with negative year.
+// Acrobat prints out "07/04/-001 15:59:58" but handling this rarely used case
+// outside of FXSYS_wcsftime() is a lot of work.
+TestOneFormat("mm/dd/yyyy HH:MM:ss", new Date(-1, 06, 04, 15, 59, 58));
+// Date with negative month.
+TestOneFormat("mm/dd/yyyy HH:MM:ss", new Date(2014, -1, 30, 15, 59, 58));
+// Date with negative day.
+TestOneFormat("mm/dd/yyyy HH:MM:ss", new Date(2014, 06, -1, 15, 59, 58));
+// Date with negative hour.
+TestOneFormat("mm/dd/yyyy HH:MM:ss", new Date(2014, 06, 04, -1, 59, 58));
+// Date with negative minute.
+TestOneFormat("mm/dd/yyyy HH:MM:ss", new Date(2014, 06, 04, 15, -1, 58));
+// Date with negative second.
+TestOneFormat("mm/dd/yyyy HH:MM:ss", new Date(2014, 06, 04, 15, 59, -1));
endstream
endobj
{{xref}}
diff --git a/testing/resources/javascript/util_printd_expected.txt b/testing/resources/javascript/util_printd_expected.txt
index 47abb2fd42..76ede71ee5 100644
--- a/testing/resources/javascript/util_printd_expected.txt
+++ b/testing/resources/javascript/util_printd_expected.txt
@@ -38,3 +38,17 @@ Alert: [object Object]: Caught error: util.printd: Incorrect parameter type.
Alert: clams,3: Caught error: util.printd: Incorrect parameter type.
Alert: mm: 07
Alert: mm: Caught error: util.printd: Operation not supported.
+Alert: mm/dd/yyyy HH:MM:ss: 07/03/1900 14:59:58
+Alert: mm/dd/yyyy HH:MM:ss: 09/04/2015 15:59:58
+Alert: mm/dd/yyyy HH:MM:ss: 12/09/2015 15:59:58
+Alert: mm/dd/yyyy HH:MM:ss: 07/06/2014 02:59:58
+Alert: mm/dd/yyyy HH:MM:ss: 07/05/2014 11:34:58
+Alert: mm/dd/yyyy HH:MM:ss: 07/04/2014 16:00:05
+Alert: mm/dd/yyyy HH:MM:ss: 05/01/2014 15:59:58
+Alert: mm/dd/yyyy HH:MM:ss: 03/02/2014 15:59:58
+Alert: mm/dd/yyyy HH:MM:ss: Caught error: util.printd: Incorrect parameter value.
+Alert: mm/dd/yyyy HH:MM:ss: 12/30/2013 15:59:58
+Alert: mm/dd/yyyy HH:MM:ss: 06/29/2014 15:59:58
+Alert: mm/dd/yyyy HH:MM:ss: 07/03/2014 23:59:58
+Alert: mm/dd/yyyy HH:MM:ss: 07/04/2014 14:59:58
+Alert: mm/dd/yyyy HH:MM:ss: 07/04/2014 15:58:59