Introduce more span<> in fxfa.
Avoid some pointer arithmetic warnings in general.
Introduce a few more bounds checks and reorder existing ones.
Use size_t where possible.
Disassembly shows the optimizer has removed the need for
any int3/ud2 bad bounds traps from these functions.
Change-Id: I77203d0580ac0f7d89deadb0a773294aca28af67
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/52610
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/xfa/fxfa/cxfa_textparser.cpp b/xfa/fxfa/cxfa_textparser.cpp
index 84ad724..d989f2c 100644
--- a/xfa/fxfa/cxfa_textparser.cpp
+++ b/xfa/fxfa/cxfa_textparser.cpp
@@ -283,9 +283,7 @@
0xb182eaae, // body
0xdb8ac455, // html
};
- static const int32_t s_iCount = FX_ArraySize(s_XFATagName);
-
- return std::binary_search(s_XFATagName, s_XFATagName + s_iCount,
+ return std::binary_search(std::begin(s_XFATagName), std::end(s_XFATagName),
FX_HashCode_GetW(wsName.AsStringView(), true));
}
diff --git a/xfa/fxfa/parser/cxfa_localevalue.cpp b/xfa/fxfa/parser/cxfa_localevalue.cpp
index fe62e81..047ead8 100644
--- a/xfa/fxfa/parser/cxfa_localevalue.cpp
+++ b/xfa/fxfa/parser/cxfa_localevalue.cpp
@@ -369,60 +369,62 @@
static const uint16_t wCountY = 4;
static const uint16_t wCountM = 2;
static const uint16_t wCountD = 2;
- int nLen = wsDate.GetLength();
- if (nLen < wCountY || nLen > wCountY + wCountM + wCountD + 2)
+ pdfium::span<const wchar_t> spDate = wsDate.AsSpan();
+ if (spDate.size() < wCountY ||
+ spDate.size() > wCountY + wCountM + wCountD + 2) {
return false;
-
+ }
const bool bSymbol = wsDate.Contains(0x2D);
uint16_t wYear = 0;
uint16_t wMonth = 0;
uint16_t wDay = 0;
- const wchar_t* pDate = wsDate.c_str();
- int nIndex = 0;
- int nStart = 0;
- while (pDate[nIndex] != '\0' && nIndex < wCountY) {
- if (!FXSYS_IsDecimalDigit(pDate[nIndex]))
+ size_t nIndex = 0;
+ size_t nStart = 0;
+ while (nIndex < wCountY && spDate[nIndex] != '\0') {
+ if (!FXSYS_IsDecimalDigit(spDate[nIndex]))
return false;
- wYear = (pDate[nIndex] - '0') + wYear * 10;
+ wYear = (spDate[nIndex] - '0') + wYear * 10;
nIndex++;
}
if (bSymbol) {
- if (pDate[nIndex] != 0x2D)
+ if (nIndex >= spDate.size() || spDate[nIndex] != 0x2D)
return false;
nIndex++;
}
nStart = nIndex;
- while (pDate[nIndex] != '\0' && nIndex - nStart < wCountM && nIndex < nLen) {
- if (!FXSYS_IsDecimalDigit(pDate[nIndex]))
+ while (nIndex < spDate.size() && spDate[nIndex] != '\0' &&
+ nIndex - nStart < wCountM) {
+ if (!FXSYS_IsDecimalDigit(spDate[nIndex]))
return false;
- wMonth = (pDate[nIndex] - '0') + wMonth * 10;
+ wMonth = (spDate[nIndex] - '0') + wMonth * 10;
nIndex++;
}
if (bSymbol) {
- if (pDate[nIndex] != 0x2D)
+ if (nIndex >= spDate.size() || spDate[nIndex] != 0x2D)
return false;
nIndex++;
}
nStart = nIndex;
- while (pDate[nIndex] != '\0' && nIndex - nStart < wCountD && nIndex < nLen) {
- if (!FXSYS_IsDecimalDigit(pDate[nIndex]))
+ while (nIndex < spDate.size() && spDate[nIndex] != '\0' &&
+ nIndex - nStart < wCountD) {
+ if (!FXSYS_IsDecimalDigit(spDate[nIndex]))
return false;
- wDay = (pDate[nIndex] - '0') + wDay * 10;
+ wDay = (spDate[nIndex] - '0') + wDay * 10;
nIndex++;
}
- if (nIndex != nLen)
+ if (nIndex != spDate.size())
return false;
if (wYear < 1900 || wYear > 2029)
return false;
if (wMonth < 1 || wMonth > 12)
- return wMonth == 0 && nLen == wCountY;
+ return wMonth == 0 && spDate.size() == wCountY;
if (wDay < 1)
- return wDay == 0 && (nLen == wCountY + wCountM);
+ return wDay == 0 && spDate.size() == wCountY + wCountM;
if (wMonth == 2) {
if (wYear % 400 == 0 || (wYear % 100 != 0 && wYear % 4 == 0)) {
if (wDay > 29)
@@ -440,8 +442,8 @@
}
bool CXFA_LocaleValue::ValidateCanonicalTime(const WideString& wsTime) {
- int nLen = wsTime.GetLength();
- if (nLen < 2)
+ pdfium::span<const wchar_t> spTime = wsTime.AsSpan();
+ if (spTime.size() < 2)
return false;
const uint16_t wCountH = 2;
@@ -453,85 +455,89 @@
uint16_t wMinute = 0;
uint16_t wSecond = 0;
uint16_t wFraction = 0;
- const wchar_t* pTime = wsTime.c_str();
- int nIndex = 0;
- int nStart = 0;
- while (nIndex - nStart < wCountH && pTime[nIndex]) {
- if (!FXSYS_IsDecimalDigit(pTime[nIndex]))
+ size_t nIndex = 0;
+ size_t nStart = 0;
+ while (nIndex - nStart < wCountH && spTime[nIndex]) {
+ if (!FXSYS_IsDecimalDigit(spTime[nIndex]))
return false;
- wHour = pTime[nIndex] - '0' + wHour * 10;
+ wHour = spTime[nIndex] - '0' + wHour * 10;
nIndex++;
}
if (bSymbol) {
- if (nIndex < nLen && pTime[nIndex] != ':')
+ if (nIndex < spTime.size() && spTime[nIndex] != ':')
return false;
nIndex++;
}
nStart = nIndex;
- while (nIndex - nStart < wCountM && nIndex < nLen && pTime[nIndex]) {
- if (!FXSYS_IsDecimalDigit(pTime[nIndex]))
+ while (nIndex < spTime.size() && spTime[nIndex] != '\0' &&
+ nIndex - nStart < wCountM) {
+ if (!FXSYS_IsDecimalDigit(spTime[nIndex]))
return false;
- wMinute = pTime[nIndex] - '0' + wMinute * 10;
+ wMinute = spTime[nIndex] - '0' + wMinute * 10;
nIndex++;
}
if (bSymbol) {
- if (nIndex < nLen && pTime[nIndex] != ':')
+ if (nIndex >= spTime.size() || spTime[nIndex] != ':')
return false;
nIndex++;
}
nStart = nIndex;
- while (nIndex - nStart < wCountS && nIndex < nLen && pTime[nIndex]) {
- if (!FXSYS_IsDecimalDigit(pTime[nIndex]))
+ while (nIndex < spTime.size() && spTime[nIndex] != '\0' &&
+ nIndex - nStart < wCountS) {
+ if (!FXSYS_IsDecimalDigit(spTime[nIndex]))
return false;
- wSecond = pTime[nIndex] - '0' + wSecond * 10;
+ wSecond = spTime[nIndex] - '0' + wSecond * 10;
nIndex++;
}
auto pos = wsTime.Find('.');
if (pos.has_value() && pos.value() != 0) {
- if (pTime[nIndex] != '.')
+ if (nIndex >= spTime.size() || spTime[nIndex] != '.')
return false;
nIndex++;
nStart = nIndex;
- while (nIndex - nStart < wCountF && nIndex < nLen && pTime[nIndex]) {
- if (!FXSYS_IsDecimalDigit(pTime[nIndex]))
+ while (nIndex < spTime.size() && spTime[nIndex] != '\0' &&
+ nIndex - nStart < wCountF) {
+ if (!FXSYS_IsDecimalDigit(spTime[nIndex]))
return false;
- wFraction = pTime[nIndex] - '0' + wFraction * 10;
+ wFraction = spTime[nIndex] - '0' + wFraction * 10;
nIndex++;
}
}
- if (nIndex < nLen) {
- if (pTime[nIndex] == 'Z') {
+ if (nIndex < spTime.size()) {
+ if (spTime[nIndex] == 'Z') {
nIndex++;
- } else if (pTime[nIndex] == '-' || pTime[nIndex] == '+') {
+ } else if (spTime[nIndex] == '-' || spTime[nIndex] == '+') {
int16_t nOffsetH = 0;
int16_t nOffsetM = 0;
nIndex++;
nStart = nIndex;
- while (nIndex - nStart < wCountH && nIndex < nLen && pTime[nIndex]) {
- if (!FXSYS_IsDecimalDigit(pTime[nIndex]))
+ while (nIndex < spTime.size() && spTime[nIndex] != '\0' &&
+ nIndex - nStart < wCountH) {
+ if (!FXSYS_IsDecimalDigit(spTime[nIndex]))
return false;
- nOffsetH = pTime[nIndex] - '0' + nOffsetH * 10;
+ nOffsetH = spTime[nIndex] - '0' + nOffsetH * 10;
nIndex++;
}
if (bSymbol) {
- if (nIndex < nLen && pTime[nIndex] != ':')
+ if (nIndex >= spTime.size() || spTime[nIndex] != ':')
return false;
nIndex++;
}
nStart = nIndex;
- while (nIndex - nStart < wCountM && nIndex < nLen && pTime[nIndex]) {
- if (!FXSYS_IsDecimalDigit(pTime[nIndex]))
+ while (nIndex < spTime.size() && spTime[nIndex] != '\0' &&
+ nIndex - nStart < wCountM) {
+ if (!FXSYS_IsDecimalDigit(spTime[nIndex]))
return false;
- nOffsetM = pTime[nIndex] - '0' + nOffsetM * 10;
+ nOffsetM = spTime[nIndex] - '0' + nOffsetM * 10;
nIndex++;
}
if (nOffsetH > 12 || nOffsetM >= 60)
return false;
}
}
- return nIndex == nLen && wHour < 24 && wMinute < 60 && wSecond < 60 &&
- wFraction <= 999;
+ return nIndex == spTime.size() && wHour < 24 && wMinute < 60 &&
+ wSecond < 60 && wFraction <= 999;
}
bool CXFA_LocaleValue::ParsePatternValue(const WideString& wsValue,
@@ -652,12 +658,12 @@
if (wsFormat.IsEmpty() || wsNumeric.IsEmpty())
return true;
- const wchar_t* pNum = wsNumeric.c_str();
- const wchar_t* pFmt = wsFormat.c_str();
+ pdfium::span<const wchar_t> spNum = wsNumeric.AsSpan();
+ pdfium::span<const wchar_t> spFmt = wsFormat.AsSpan();
int32_t n = 0;
int32_t nf = 0;
- wchar_t c = pNum[n];
- wchar_t cf = pFmt[nf];
+ wchar_t c = spNum[n];
+ wchar_t cf = spFmt[nf];
if (cf == L's') {
if (c == L'-' || c == L'+')
++n;
@@ -668,9 +674,9 @@
int32_t nCount = wsNumeric.GetLength();
int32_t nCountFmt = wsFormat.GetLength();
while (n < nCount && (bLimit ? nf < nCountFmt : true) &&
- FXSYS_IsDecimalDigit(c = pNum[n])) {
+ FXSYS_IsDecimalDigit(c = spNum[n])) {
if (bLimit == true) {
- if ((cf = pFmt[nf]) == L'*')
+ if ((cf = spFmt[nf]) == L'*')
bLimit = false;
else if (cf == L'z')
nf++;
@@ -684,7 +690,7 @@
if (nf == nCountFmt)
return false;
- while (nf < nCountFmt && (cf = pFmt[nf]) != L'.') {
+ while (nf < nCountFmt && (cf = spFmt[nf]) != L'.') {
ASSERT(cf == L'z' || cf == L'*');
++nf;
}
@@ -695,7 +701,7 @@
else
wsDecimalSymbol = WideString(L'.');
- if (pFmt[nf] != L'.')
+ if (spFmt[nf] != L'.')
return false;
if (wsDecimalSymbol != WideStringView(c) && c != L'.')
return false;
@@ -703,10 +709,10 @@
++nf;
++n;
bLimit = true;
- while (n < nCount && (bLimit ? nf < nCountFmt : true) &&
- FXSYS_IsDecimalDigit(c = pNum[n])) {
- if (bLimit == true) {
- if ((cf = pFmt[nf]) == L'*')
+ while (n < nCount && (!bLimit || nf < nCountFmt) &&
+ FXSYS_IsDecimalDigit(spNum[n])) {
+ if (bLimit) {
+ if ((cf = spFmt[nf]) == L'*')
bLimit = false;
else if (cf == L'z')
nf++;
diff --git a/xfa/fxfa/parser/cxfa_node.cpp b/xfa/fxfa/parser/cxfa_node.cpp
index 9f19a49..7a1d1fe 100644
--- a/xfa/fxfa/parser/cxfa_node.cpp
+++ b/xfa/fxfa/parser/cxfa_node.cpp
@@ -381,18 +381,13 @@
49, 50, 51, 255, 255, 255, 255, 255,
};
-uint8_t* XFA_RemoveBase64Whitespace(const uint8_t* pStr, int32_t iLen) {
- uint8_t* pCP;
- int32_t i = 0, j = 0;
- if (iLen == 0) {
- iLen = strlen((char*)pStr);
- }
- pCP = FX_Alloc(uint8_t, iLen + 1);
- for (; i < iLen; i++) {
- if ((pStr[i] & 128) == 0) {
- if (g_inv_base64[pStr[i]] != 0xFF || pStr[i] == '=') {
- pCP[j++] = pStr[i];
- }
+uint8_t* XFA_RemoveBase64Whitespace(pdfium::span<const uint8_t> spStr) {
+ uint8_t* pCP = FX_Alloc(uint8_t, spStr.size() + 1);
+ size_t j = 0;
+ for (size_t i = 0; i < spStr.size(); ++i) {
+ if ((spStr[i] & 128) == 0 &&
+ (g_inv_base64[spStr[i]] != 0xFF || spStr[i] == '=')) {
+ pCP[j++] = spStr[i];
}
}
pCP[j] = '\0';
@@ -400,14 +395,11 @@
}
int32_t XFA_Base64Decode(const char* pStr, uint8_t* pOutBuffer) {
- if (!pStr) {
+ if (!pStr)
return 0;
- }
- uint8_t* pBuffer =
- XFA_RemoveBase64Whitespace((uint8_t*)pStr, strlen((char*)pStr));
- if (!pBuffer) {
- return 0;
- }
+
+ uint8_t* pBuffer = XFA_RemoveBase64Whitespace(
+ {reinterpret_cast<const uint8_t*>(pStr), strlen(pStr)});
int32_t iLen = strlen((char*)pBuffer);
int32_t i = 0, j = 0;
uint32_t dwLimb = 0;