Better bounds-check in IsIsoTimeFormat()
The loop is currently checking index < size but then accessing the
element at index + 1 without additional checks. This leads to a hard
CHECK() in span's indexing operator.
Instead, check for pairs of remaining digits and fail at line 722
if there are an odd number of digits.
-- Do the same in one other place not hit by fuzzer.
-- Move loads closer to bounds checks for clarity.
-- Add "NUL" comment.
Bug: chromium:1457971
Change-Id: I5b1c26bc5bba938064ee352fd5ecb21a4f3eb4f9
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/108990
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/fxjs/xfa/cfxjse_formcalc_context.cpp b/fxjs/xfa/cfxjse_formcalc_context.cpp
index 2daba5e..790ec94 100644
--- a/fxjs/xfa/cfxjse_formcalc_context.cpp
+++ b/fxjs/xfa/cfxjse_formcalc_context.cpp
@@ -618,21 +618,18 @@
if (i == pData.size())
iZone = pData.size();
- char szBuffer[3] = {};
+ char szBuffer[3] = {}; // Last char always stays NUL for termination.
size_t iPos = 0;
size_t iIndex = 0;
- while (iIndex < iZone) {
- if (!isdigit(pData[iIndex]))
- return false;
-
+ while (iIndex + 1 < iZone) {
szBuffer[0] = pData[iIndex];
- if (!isdigit(pData[iIndex + 1]))
- return false;
-
szBuffer[1] = pData[iIndex + 1];
- if (FXSYS_atoi(szBuffer) > 60)
+ if (!isdigit(szBuffer[0]) || !isdigit(szBuffer[1])) {
return false;
-
+ }
+ if (FXSYS_atoi(szBuffer) > 60) {
+ return false;
+ }
if (pData[2] == ':') {
if (iPos == 0) {
iHour = FXSYS_atoi(szBuffer);
@@ -695,18 +692,15 @@
}
}
iPos = 0;
- while (iIndex < pData.size()) {
- if (!isdigit(pData[iIndex]))
- return false;
-
+ while (iIndex + 1 < pData.size()) {
szBuffer[0] = pData[iIndex];
- if (!isdigit(pData[iIndex + 1]))
- return false;
-
szBuffer[1] = pData[iIndex + 1];
- if (FXSYS_atoi(szBuffer) > 60)
+ if (!isdigit(szBuffer[0]) || !isdigit(szBuffer[1])) {
return false;
-
+ }
+ if (FXSYS_atoi(szBuffer) > 60) {
+ return false;
+ }
if (pData[2] == ':') {
if (iPos == 0) {
iZoneHour = FXSYS_atoi(szBuffer);