Make cxfa_fmlexer.cpp resilient to null strings
As currently written, the calculation of m_end will underflow
when passed a {nullptr, 0} pair as input, and m_end becomes
essentially unbounded.
Change-Id: Id3249b201c446555d9aa4fa04e6a3c94a357cd99
Reviewed-on: https://pdfium-review.googlesource.com/30230
Reviewed-by: dsinclair <dsinclair@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/xfa/fxfa/fm2js/cxfa_fmlexer.cpp b/xfa/fxfa/fm2js/cxfa_fmlexer.cpp
index 3559fb7..72fe0f2 100644
--- a/xfa/fxfa/fm2js/cxfa_fmlexer.cpp
+++ b/xfa/fxfa/fm2js/cxfa_fmlexer.cpp
@@ -130,7 +130,7 @@
CXFA_FMLexer::CXFA_FMLexer(const WideStringView& wsFormCalc)
: m_cursor(wsFormCalc.unterminated_c_str()),
- m_end(m_cursor + wsFormCalc.GetLength() - 1),
+ m_end(m_cursor + wsFormCalc.GetLength()),
m_lexer_error(false) {}
CXFA_FMLexer::~CXFA_FMLexer() {}
@@ -139,7 +139,7 @@
if (m_lexer_error)
return CXFA_FMToken();
- while (m_cursor <= m_end && *m_cursor) {
+ while (m_cursor < m_end && *m_cursor) {
if (!IsFormCalcCharacter(*m_cursor)) {
RaiseError();
return CXFA_FMToken();
@@ -170,7 +170,7 @@
return AdvanceForNumber();
case '=':
++m_cursor;
- if (m_cursor > m_end)
+ if (m_cursor >= m_end)
return CXFA_FMToken(TOKassign);
if (!IsFormCalcCharacter(*m_cursor)) {
@@ -184,7 +184,7 @@
return CXFA_FMToken(TOKassign);
case '<':
++m_cursor;
- if (m_cursor > m_end)
+ if (m_cursor >= m_end)
return CXFA_FMToken(TOKlt);
if (!IsFormCalcCharacter(*m_cursor)) {
@@ -202,7 +202,7 @@
return CXFA_FMToken(TOKlt);
case '>':
++m_cursor;
- if (m_cursor > m_end)
+ if (m_cursor >= m_end)
return CXFA_FMToken(TOKgt);
if (!IsFormCalcCharacter(*m_cursor)) {
@@ -246,7 +246,7 @@
return CXFA_FMToken(TOKmul);
case '/': {
++m_cursor;
- if (m_cursor > m_end)
+ if (m_cursor >= m_end)
return CXFA_FMToken(TOKdiv);
if (!IsFormCalcCharacter(*m_cursor)) {
@@ -261,7 +261,7 @@
}
case '.':
++m_cursor;
- if (m_cursor > m_end)
+ if (m_cursor >= m_end)
return CXFA_FMToken(TOKdot);
if (!IsFormCalcCharacter(*m_cursor)) {
@@ -323,7 +323,7 @@
const wchar_t* start = m_cursor;
++m_cursor;
- while (m_cursor <= m_end && *m_cursor) {
+ while (m_cursor < m_end && *m_cursor) {
if (!IsFormCalcCharacter(*m_cursor))
break;
@@ -331,7 +331,7 @@
// Check for escaped "s, i.e. "".
++m_cursor;
// If the end of the input has been reached it was not escaped.
- if (m_cursor > m_end) {
+ if (m_cursor >= m_end) {
token.m_string =
WideStringView(start, static_cast<size_t>(m_cursor - start));
return token;
@@ -357,7 +357,7 @@
CXFA_FMToken CXFA_FMLexer::AdvanceForIdentifier() {
const wchar_t* start = m_cursor;
++m_cursor;
- while (m_cursor <= m_end && *m_cursor) {
+ while (m_cursor < m_end && *m_cursor) {
if (!IsFormCalcCharacter(*m_cursor)) {
RaiseError();
return CXFA_FMToken();
@@ -377,7 +377,7 @@
void CXFA_FMLexer::AdvanceForComment() {
m_cursor++;
- while (m_cursor <= m_end && *m_cursor) {
+ while (m_cursor < m_end && *m_cursor) {
if (!IsFormCalcCharacter(*m_cursor)) {
RaiseError();
return;
diff --git a/xfa/fxfa/fm2js/cxfa_fmlexer_unittest.cpp b/xfa/fxfa/fm2js/cxfa_fmlexer_unittest.cpp
index 00dc494..248b9fe 100644
--- a/xfa/fxfa/fm2js/cxfa_fmlexer_unittest.cpp
+++ b/xfa/fxfa/fm2js/cxfa_fmlexer_unittest.cpp
@@ -10,6 +10,13 @@
#include "testing/test_support.h"
#include "third_party/base/ptr_util.h"
+TEST(CXFA_FMLexerTest, NullString) {
+ WideStringView null_string;
+ CXFA_FMLexer lexer(null_string);
+ CXFA_FMToken token = lexer.NextToken();
+ EXPECT_EQ(TOKeof, token.m_type);
+}
+
TEST(CXFA_FMLexerTest, EmptyString) {
CXFA_FMLexer lexer(L"");
CXFA_FMToken token = lexer.NextToken();