Declare CXFA_FMLexer as stack-allocated
Even though it has nothing to do with cppgc, this allows removing
some make_unique<CXFA_*> anti-patterns.
-- Make XFA_KEYWORD private to the one .cpp file that uses it.
Change-Id: If868242ae3ec9639e0452654195300a4aeed944c
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/73930
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 1606150..974344f 100644
--- a/fxjs/xfa/cfxjse_formcalc_context.cpp
+++ b/fxjs/xfa/cfxjse_formcalc_context.cpp
@@ -5653,7 +5653,8 @@
if (wsFormcalc.IsEmpty())
return CFX_WideTextBuf();
- CXFA_FMParser parser(pHeap, wsFormcalc);
+ CXFA_FMLexer lexer(wsFormcalc);
+ CXFA_FMParser parser(pHeap, &lexer);
CXFA_FMAST* ast = parser.Parse();
if (!ast || parser.HasError())
return pdfium::nullopt;
diff --git a/testing/fuzzers/pdf_formcalc_fuzzer.cc b/testing/fuzzers/pdf_formcalc_fuzzer.cc
index d116648..2771b04 100644
--- a/testing/fuzzers/pdf_formcalc_fuzzer.cc
+++ b/testing/fuzzers/pdf_formcalc_fuzzer.cc
@@ -12,7 +12,8 @@
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
auto* state = static_cast<XFAProcessState*>(FPDF_GetFuzzerPerProcessState());
WideString input = WideString::FromUTF8(ByteStringView(data, size));
- CXFA_FMParser parser(state->GetHeap(), input.AsStringView());
+ CXFA_FMLexer lexer(input.AsStringView());
+ CXFA_FMParser parser(state->GetHeap(), &lexer);
parser.Parse();
state->MaybeForceGCAndPump();
return 0;
diff --git a/xfa/fxfa/fm2js/cxfa_fmlexer.cpp b/xfa/fxfa/fm2js/cxfa_fmlexer.cpp
index efb59f2..159910f 100644
--- a/xfa/fxfa/fm2js/cxfa_fmlexer.cpp
+++ b/xfa/fxfa/fm2js/cxfa_fmlexer.cpp
@@ -35,6 +35,11 @@
c == 0x0020; // Space
}
+struct XFA_FMKeyword {
+ XFA_FM_TOKEN m_type;
+ const char* m_keyword; // Raw, POD struct.
+};
+
const XFA_FMKeyword keyWords[] = {
{TOKdo, "do"},
{TOKkseq, "eq"},
diff --git a/xfa/fxfa/fm2js/cxfa_fmlexer.h b/xfa/fxfa/fm2js/cxfa_fmlexer.h
index 2d9e5fc..fe55a12 100644
--- a/xfa/fxfa/fm2js/cxfa_fmlexer.h
+++ b/xfa/fxfa/fm2js/cxfa_fmlexer.h
@@ -8,6 +8,7 @@
#define XFA_FXFA_FM2JS_CXFA_FMLEXER_H_
#include "core/fxcrt/fx_string.h"
+#include "v8/include/cppgc/macros.h"
enum XFA_FM_TOKEN {
TOKand,
@@ -80,11 +81,6 @@
TOKreserver
};
-struct XFA_FMKeyword {
- XFA_FM_TOKEN m_type;
- const char* m_keyword; // Raw, POD struct.
-};
-
class CXFA_FMToken {
public:
CXFA_FMToken();
@@ -101,6 +97,8 @@
};
class CXFA_FMLexer {
+ CPPGC_STACK_ALLOCATED(); // Raw pointers allowed.
+
public:
explicit CXFA_FMLexer(WideStringView wsFormcalc);
~CXFA_FMLexer();
diff --git a/xfa/fxfa/fm2js/cxfa_fmlexer_unittest.cpp b/xfa/fxfa/fm2js/cxfa_fmlexer_unittest.cpp
index 0b3003d..3f5eacc 100644
--- a/xfa/fxfa/fm2js/cxfa_fmlexer_unittest.cpp
+++ b/xfa/fxfa/fm2js/cxfa_fmlexer_unittest.cpp
@@ -26,83 +26,95 @@
}
TEST(CXFA_FMLexerTest, Numbers) {
- auto lexer = std::make_unique<CXFA_FMLexer>(L"-12");
- CXFA_FMToken token = lexer->NextToken();
- // TODO(dsinclair): Should this return -12 instead of two tokens?
- EXPECT_EQ(TOKminus, token.m_type);
- token = lexer->NextToken();
- EXPECT_EQ(L"12", token.m_string);
- token = lexer->NextToken();
- EXPECT_EQ(TOKeof, token.m_type);
-
- lexer = std::make_unique<CXFA_FMLexer>(L"1.5362");
- token = lexer->NextToken();
- EXPECT_EQ(TOKnumber, token.m_type);
- EXPECT_EQ(L"1.5362", token.m_string);
-
- lexer = std::make_unique<CXFA_FMLexer>(L"0.875");
- token = lexer->NextToken();
- EXPECT_EQ(TOKnumber, token.m_type);
- EXPECT_EQ(L"0.875", token.m_string);
-
- lexer = std::make_unique<CXFA_FMLexer>(L"5.56e-2");
- token = lexer->NextToken();
- EXPECT_EQ(TOKnumber, token.m_type);
- EXPECT_EQ(L"5.56e-2", token.m_string);
-
- lexer = std::make_unique<CXFA_FMLexer>(L"1.234E10");
- token = lexer->NextToken();
- EXPECT_EQ(TOKnumber, token.m_type);
- EXPECT_EQ(L"1.234E10", token.m_string);
-
- lexer = std::make_unique<CXFA_FMLexer>(L"123456789.012345678");
- token = lexer->NextToken();
- EXPECT_EQ(TOKnumber, token.m_type);
- // TODO(dsinclair): This should round as per IEEE 64-bit values.
- // EXPECT_EQ(L"123456789.01234567", token.m_string);
- EXPECT_EQ(L"123456789.012345678", token.m_string);
-
- lexer = std::make_unique<CXFA_FMLexer>(L"99999999999999999");
- token = lexer->NextToken();
- EXPECT_EQ(TOKnumber, token.m_type);
- // TODO(dsinclair): This is spec'd as rounding when > 16 significant digits
- // prior to the exponent.
- // EXPECT_EQ(L"100000000000000000", token.m_string);
- EXPECT_EQ(L"99999999999999999", token.m_string);
- EXPECT_TRUE(lexer->IsComplete());
+ {
+ CXFA_FMLexer lexer(L"-12");
+ CXFA_FMToken token = lexer.NextToken();
+ // TODO(dsinclair): Should this return -12 instead of two tokens?
+ EXPECT_EQ(TOKminus, token.m_type);
+ token = lexer.NextToken();
+ EXPECT_EQ(L"12", token.m_string);
+ token = lexer.NextToken();
+ EXPECT_EQ(TOKeof, token.m_type);
+ }
+ {
+ CXFA_FMLexer lexer(L"1.5362");
+ CXFA_FMToken token = lexer.NextToken();
+ EXPECT_EQ(TOKnumber, token.m_type);
+ EXPECT_EQ(L"1.5362", token.m_string);
+ }
+ {
+ CXFA_FMLexer lexer(L"0.875");
+ CXFA_FMToken token = lexer.NextToken();
+ EXPECT_EQ(TOKnumber, token.m_type);
+ EXPECT_EQ(L"0.875", token.m_string);
+ }
+ {
+ CXFA_FMLexer lexer(L"5.56e-2");
+ CXFA_FMToken token = lexer.NextToken();
+ EXPECT_EQ(TOKnumber, token.m_type);
+ EXPECT_EQ(L"5.56e-2", token.m_string);
+ }
+ {
+ CXFA_FMLexer lexer(L"1.234E10");
+ CXFA_FMToken token = lexer.NextToken();
+ EXPECT_EQ(TOKnumber, token.m_type);
+ EXPECT_EQ(L"1.234E10", token.m_string);
+ }
+ {
+ CXFA_FMLexer lexer(L"123456789.012345678");
+ CXFA_FMToken token = lexer.NextToken();
+ EXPECT_EQ(TOKnumber, token.m_type);
+ // TODO(dsinclair): This should round as per IEEE 64-bit values.
+ // EXPECT_EQ(L"123456789.01234567", token.m_string);
+ EXPECT_EQ(L"123456789.012345678", token.m_string);
+ }
+ {
+ CXFA_FMLexer lexer(L"99999999999999999");
+ CXFA_FMToken token = lexer.NextToken();
+ EXPECT_EQ(TOKnumber, token.m_type);
+ // TODO(dsinclair): This is spec'd as rounding when > 16 significant digits
+ // prior to the exponent.
+ // EXPECT_EQ(L"100000000000000000", token.m_string);
+ EXPECT_EQ(L"99999999999999999", token.m_string);
+ EXPECT_TRUE(lexer.IsComplete());
+ }
}
// The quotes are stripped in CXFA_FMStringExpression::ToJavaScript.
TEST(CXFA_FMLexerTest, Strings) {
- auto lexer =
- std::make_unique<CXFA_FMLexer>(L"\"The cat jumped over the fence.\"");
- CXFA_FMToken token = lexer->NextToken();
- EXPECT_EQ(TOKstring, token.m_type);
- EXPECT_EQ(L"\"The cat jumped over the fence.\"", token.m_string);
+ {
+ CXFA_FMLexer lexer(L"\"The cat jumped over the fence.\"");
+ CXFA_FMToken token = lexer.NextToken();
+ EXPECT_EQ(TOKstring, token.m_type);
+ EXPECT_EQ(L"\"The cat jumped over the fence.\"", token.m_string);
- token = lexer->NextToken();
- EXPECT_EQ(TOKeof, token.m_type);
-
- lexer = std::make_unique<CXFA_FMLexer>(L"\"\"");
- token = lexer->NextToken();
- EXPECT_EQ(TOKstring, token.m_type);
- EXPECT_EQ(L"\"\"", token.m_string);
-
- lexer = std::make_unique<CXFA_FMLexer>(
- L"\"The message reads: \"\"Warning: Insufficient Memory\"\"\"");
- token = lexer->NextToken();
- EXPECT_EQ(TOKstring, token.m_type);
- EXPECT_EQ(L"\"The message reads: \"\"Warning: Insufficient Memory\"\"\"",
- token.m_string);
-
- lexer = std::make_unique<CXFA_FMLexer>(
- L"\"\\u0047\\u006f\\u0066\\u0069\\u0073\\u0068\\u0021\\u000d\\u000a\"");
- token = lexer->NextToken();
- EXPECT_EQ(TOKstring, token.m_type);
- EXPECT_EQ(
- L"\"\\u0047\\u006f\\u0066\\u0069\\u0073\\u0068\\u0021\\u000d\\u000a\"",
- token.m_string);
- EXPECT_TRUE(lexer->IsComplete());
+ token = lexer.NextToken();
+ EXPECT_EQ(TOKeof, token.m_type);
+ }
+ {
+ CXFA_FMLexer lexer(L"\"\"");
+ CXFA_FMToken token = lexer.NextToken();
+ EXPECT_EQ(TOKstring, token.m_type);
+ EXPECT_EQ(L"\"\"", token.m_string);
+ }
+ {
+ CXFA_FMLexer lexer(
+ L"\"The message reads: \"\"Warning: Insufficient Memory\"\"\"");
+ CXFA_FMToken token = lexer.NextToken();
+ EXPECT_EQ(TOKstring, token.m_type);
+ EXPECT_EQ(L"\"The message reads: \"\"Warning: Insufficient Memory\"\"\"",
+ token.m_string);
+ }
+ {
+ CXFA_FMLexer lexer(
+ L"\"\\u0047\\u006f\\u0066\\u0069\\u0073\\u0068\\u0021\\u000d\\u000a\"");
+ CXFA_FMToken token = lexer.NextToken();
+ EXPECT_EQ(TOKstring, token.m_type);
+ EXPECT_EQ(
+ L"\"\\u0047\\u006f\\u0066\\u0069\\u0073\\u0068\\u0021\\u000d\\u000a\"",
+ token.m_string);
+ EXPECT_TRUE(lexer.IsComplete());
+ }
}
// Note, 'this' is a keyword but is not matched by the lexer.
@@ -171,123 +183,137 @@
{L".*", TOKdotstar}};
for (size_t i = 0; i < pdfium::size(op); ++i) {
- auto lexer = std::make_unique<CXFA_FMLexer>(op[i].op);
- CXFA_FMToken token = lexer->NextToken();
+ CXFA_FMLexer lexer(op[i].op);
+ CXFA_FMToken token = lexer.NextToken();
EXPECT_EQ(op[i].token, token.m_type);
- EXPECT_TRUE(lexer->IsComplete());
+ EXPECT_TRUE(lexer.IsComplete());
}
}
TEST(CXFA_FMLexerTest, Comments) {
- auto lexer = std::make_unique<CXFA_FMLexer>(L"// Empty.");
- CXFA_FMToken token = lexer->NextToken();
- EXPECT_EQ(TOKeof, token.m_type);
+ {
+ CXFA_FMLexer lexer(L"// Empty.");
+ CXFA_FMToken token = lexer.NextToken();
+ EXPECT_EQ(TOKeof, token.m_type);
+ }
+ {
+ CXFA_FMLexer lexer(L"//");
+ CXFA_FMToken token = lexer.NextToken();
+ EXPECT_EQ(TOKeof, token.m_type);
+ }
+ {
+ CXFA_FMLexer lexer(L"123 // Empty.\n\"str\"");
+ CXFA_FMToken token = lexer.NextToken();
+ EXPECT_EQ(TOKnumber, token.m_type);
+ EXPECT_EQ(L"123", token.m_string);
- lexer = std::make_unique<CXFA_FMLexer>(L"//");
- token = lexer->NextToken();
- EXPECT_EQ(TOKeof, token.m_type);
+ token = lexer.NextToken();
+ EXPECT_EQ(TOKstring, token.m_type);
+ EXPECT_EQ(L"\"str\"", token.m_string);
- lexer = std::make_unique<CXFA_FMLexer>(L"123 // Empty.\n\"str\"");
- token = lexer->NextToken();
- EXPECT_EQ(TOKnumber, token.m_type);
- EXPECT_EQ(L"123", token.m_string);
+ token = lexer.NextToken();
+ EXPECT_EQ(TOKeof, token.m_type);
+ }
+ {
+ CXFA_FMLexer lexer(L";");
+ CXFA_FMToken token = lexer.NextToken();
+ EXPECT_EQ(TOKeof, token.m_type);
+ }
+ {
+ CXFA_FMLexer lexer(L"; Empty.");
+ CXFA_FMToken token = lexer.NextToken();
+ EXPECT_EQ(TOKeof, token.m_type);
+ }
+ {
+ CXFA_FMLexer lexer(L"123 ;Empty.\n\"str\"");
+ CXFA_FMToken token = lexer.NextToken();
+ EXPECT_EQ(TOKnumber, token.m_type);
+ EXPECT_EQ(L"123", token.m_string);
- token = lexer->NextToken();
- EXPECT_EQ(TOKstring, token.m_type);
- EXPECT_EQ(L"\"str\"", token.m_string);
+ token = lexer.NextToken();
+ EXPECT_EQ(TOKstring, token.m_type);
+ EXPECT_EQ(L"\"str\"", token.m_string);
- token = lexer->NextToken();
- EXPECT_EQ(TOKeof, token.m_type);
-
- lexer = std::make_unique<CXFA_FMLexer>(L";");
- token = lexer->NextToken();
- EXPECT_EQ(TOKeof, token.m_type);
-
- lexer = std::make_unique<CXFA_FMLexer>(L"; Empty.");
- token = lexer->NextToken();
- EXPECT_EQ(TOKeof, token.m_type);
-
- lexer = std::make_unique<CXFA_FMLexer>(L"123 ;Empty.\n\"str\"");
- token = lexer->NextToken();
- EXPECT_EQ(TOKnumber, token.m_type);
- EXPECT_EQ(L"123", token.m_string);
-
- token = lexer->NextToken();
- EXPECT_EQ(TOKstring, token.m_type);
- EXPECT_EQ(L"\"str\"", token.m_string);
-
- token = lexer->NextToken();
- EXPECT_EQ(TOKeof, token.m_type);
- EXPECT_TRUE(lexer->IsComplete());
+ token = lexer.NextToken();
+ EXPECT_EQ(TOKeof, token.m_type);
+ EXPECT_TRUE(lexer.IsComplete());
+ }
}
TEST(CXFA_FMLexerTest, ValidIdentifiers) {
std::vector<const wchar_t*> identifiers = {
L"a", L"an_identifier", L"_ident", L"$ident", L"!ident", L"GetAddr"};
for (const auto* ident : identifiers) {
- auto lexer = std::make_unique<CXFA_FMLexer>(ident);
- CXFA_FMToken token = lexer->NextToken();
+ CXFA_FMLexer lexer(ident);
+ CXFA_FMToken token = lexer.NextToken();
EXPECT_EQ(TOKidentifier, token.m_type);
EXPECT_EQ(ident, token.m_string);
- EXPECT_TRUE(lexer->IsComplete());
+ EXPECT_TRUE(lexer.IsComplete());
}
}
TEST(CXFA_FMLexerTest, InvalidIdentifiers) {
- auto lexer = std::make_unique<CXFA_FMLexer>(L"#a");
- auto token = lexer->NextToken();
- EXPECT_EQ(TOKreserver, token.m_type);
-
- lexer = std::make_unique<CXFA_FMLexer>(L"1a");
- token = lexer->NextToken();
- EXPECT_EQ(TOKreserver, token.m_type);
-
- lexer = std::make_unique<CXFA_FMLexer>(L"an@identifier");
- token = lexer->NextToken();
- EXPECT_NE(TOKreserver, token.m_type);
- token = lexer->NextToken();
- EXPECT_EQ(TOKreserver, token.m_type);
- token = lexer->NextToken();
- EXPECT_EQ(TOKreserver, token.m_type);
-
- lexer = std::make_unique<CXFA_FMLexer>(L"_ident@");
- token = lexer->NextToken();
- EXPECT_NE(TOKreserver, token.m_type);
- token = lexer->NextToken();
- EXPECT_EQ(TOKreserver, token.m_type);
- EXPECT_FALSE(lexer->IsComplete());
+ {
+ CXFA_FMLexer lexer(L"#a");
+ CXFA_FMToken token = lexer.NextToken();
+ EXPECT_EQ(TOKreserver, token.m_type);
+ }
+ {
+ CXFA_FMLexer lexer(L"1a");
+ CXFA_FMToken token = lexer.NextToken();
+ EXPECT_EQ(TOKreserver, token.m_type);
+ }
+ {
+ CXFA_FMLexer lexer(L"an@identifier");
+ CXFA_FMToken token = lexer.NextToken();
+ EXPECT_NE(TOKreserver, token.m_type);
+ token = lexer.NextToken();
+ EXPECT_EQ(TOKreserver, token.m_type);
+ token = lexer.NextToken();
+ EXPECT_EQ(TOKreserver, token.m_type);
+ }
+ {
+ CXFA_FMLexer lexer(L"_ident@");
+ CXFA_FMToken token = lexer.NextToken();
+ EXPECT_NE(TOKreserver, token.m_type);
+ token = lexer.NextToken();
+ EXPECT_EQ(TOKreserver, token.m_type);
+ EXPECT_FALSE(lexer.IsComplete());
+ }
}
TEST(CXFA_FMLexerTest, Whitespace) {
- auto lexer = std::make_unique<CXFA_FMLexer>(L" \t\xc\x9\xb");
- CXFA_FMToken token = lexer->NextToken();
- EXPECT_EQ(TOKeof, token.m_type);
+ {
+ CXFA_FMLexer lexer(L" \t\xc\x9\xb");
+ CXFA_FMToken token = lexer.NextToken();
+ EXPECT_EQ(TOKeof, token.m_type);
+ }
+ {
+ CXFA_FMLexer lexer(L"123 \t\xc\x9\xb 456");
+ CXFA_FMToken token = lexer.NextToken();
+ EXPECT_EQ(TOKnumber, token.m_type);
+ EXPECT_EQ(L"123", token.m_string);
- lexer = std::make_unique<CXFA_FMLexer>(L"123 \t\xc\x9\xb 456");
- token = lexer->NextToken();
- EXPECT_EQ(TOKnumber, token.m_type);
- EXPECT_EQ(L"123", token.m_string);
+ token = lexer.NextToken();
+ EXPECT_EQ(TOKnumber, token.m_type);
+ EXPECT_EQ(L"456", token.m_string);
- token = lexer->NextToken();
- EXPECT_EQ(TOKnumber, token.m_type);
- EXPECT_EQ(L"456", token.m_string);
-
- token = lexer->NextToken();
- EXPECT_EQ(TOKeof, token.m_type);
- EXPECT_TRUE(lexer->IsComplete());
+ token = lexer.NextToken();
+ EXPECT_EQ(TOKeof, token.m_type);
+ EXPECT_TRUE(lexer.IsComplete());
+ }
}
TEST(CXFA_FMLexerTest, NullData) {
- auto lexer = std::make_unique<CXFA_FMLexer>(
- WideStringView(L"\x2d\x32\x00\x2d\x32", 5));
- CXFA_FMToken token = lexer->NextToken();
+ CXFA_FMLexer lexer(WideStringView(L"\x2d\x32\x00\x2d\x32", 5));
+ CXFA_FMToken token = lexer.NextToken();
EXPECT_EQ(TOKminus, token.m_type);
- token = lexer->NextToken();
+ token = lexer.NextToken();
EXPECT_EQ(TOKnumber, token.m_type);
EXPECT_EQ(L"2", token.m_string);
- token = lexer->NextToken();
+ token = lexer.NextToken();
EXPECT_EQ(TOKeof, token.m_type);
- EXPECT_FALSE(lexer->IsComplete());
+ EXPECT_FALSE(lexer.IsComplete());
}
diff --git a/xfa/fxfa/fm2js/cxfa_fmparser.cpp b/xfa/fxfa/fm2js/cxfa_fmparser.cpp
index 24742b1..4d9f272 100644
--- a/xfa/fxfa/fm2js/cxfa_fmparser.cpp
+++ b/xfa/fxfa/fm2js/cxfa_fmparser.cpp
@@ -20,12 +20,8 @@
} // namespace
-CXFA_FMParser::CXFA_FMParser(cppgc::Heap* pHeap, WideStringView wsFormcalc)
- : m_heap(pHeap),
- m_lexer(std::make_unique<CXFA_FMLexer>(wsFormcalc)),
- m_error(false),
- m_parse_depth(0),
- m_max_parse_depth(kMaxParseDepth) {}
+CXFA_FMParser::CXFA_FMParser(cppgc::Heap* pHeap, CXFA_FMLexer* pLexer)
+ : m_heap(pHeap), m_lexer(pLexer), m_max_parse_depth(kMaxParseDepth) {}
CXFA_FMParser::~CXFA_FMParser() = default;
diff --git a/xfa/fxfa/fm2js/cxfa_fmparser.h b/xfa/fxfa/fm2js/cxfa_fmparser.h
index 007df6d..0e61abb 100644
--- a/xfa/fxfa/fm2js/cxfa_fmparser.h
+++ b/xfa/fxfa/fm2js/cxfa_fmparser.h
@@ -22,7 +22,7 @@
CPPGC_STACK_ALLOCATED(); // Allow Raw/Unowned pointers.
public:
- CXFA_FMParser(cppgc::Heap* heap, WideStringView wsFormcalc);
+ CXFA_FMParser(cppgc::Heap* heap, CXFA_FMLexer* pLexer);
~CXFA_FMParser();
// Returned object is owned by cppgc heap.
@@ -65,10 +65,10 @@
ParseArgumentList();
UnownedPtr<cppgc::Heap> const m_heap;
- std::unique_ptr<CXFA_FMLexer> m_lexer;
+ UnownedPtr<CXFA_FMLexer> m_lexer;
CXFA_FMToken m_token;
- bool m_error;
- unsigned long m_parse_depth;
+ bool m_error = false;
+ unsigned long m_parse_depth = 0;
unsigned long m_max_parse_depth;
};
diff --git a/xfa/fxfa/fm2js/cxfa_fmparser_unittest.cpp b/xfa/fxfa/fm2js/cxfa_fmparser_unittest.cpp
index 7539e7b..ade2b05 100644
--- a/xfa/fxfa/fm2js/cxfa_fmparser_unittest.cpp
+++ b/xfa/fxfa/fm2js/cxfa_fmparser_unittest.cpp
@@ -12,7 +12,8 @@
class CXFA_FMParserTest : public FXGCUnitTest {};
TEST_F(CXFA_FMParserTest, Empty) {
- CXFA_FMParser parser(heap(), L"");
+ CXFA_FMLexer lexer(L"");
+ CXFA_FMParser parser(heap(), &lexer);
CXFA_FMAST* ast = parser.Parse();
ASSERT_TRUE(ast);
EXPECT_FALSE(parser.HasError());
@@ -25,7 +26,8 @@
}
TEST_F(CXFA_FMParserTest, CommentOnlyIsError) {
- CXFA_FMParser parser(heap(), L"; Just comment");
+ CXFA_FMLexer lexer(L"; Just comment");
+ CXFA_FMParser parser(heap(), &lexer);
CXFA_FMAST* ast = parser.Parse();
ASSERT_TRUE(ast);
// TODO(dsinclair): This isn't allowed per the spec.
@@ -56,7 +58,8 @@
return pfm_rt.get_val(pfm_ret);
}).call(this);)***";
- CXFA_FMParser parser(heap(), L"; Just comment\n12");
+ CXFA_FMLexer lexer(L"; Just comment\n12");
+ CXFA_FMParser parser(heap(), &lexer);
CXFA_FMAST* ast = parser.Parse();
ASSERT_TRUE(ast);
EXPECT_FALSE(parser.HasError());
@@ -125,7 +128,8 @@
return pfm_rt.get_val(pfm_ret);
}).call(this);)***";
- CXFA_FMParser parser(heap(), input);
+ CXFA_FMLexer lexer(input);
+ CXFA_FMParser parser(heap(), &lexer);
CXFA_FMAST* ast = parser.Parse();
ASSERT_TRUE(ast);
EXPECT_FALSE(parser.HasError());
@@ -137,24 +141,27 @@
}
TEST_F(CXFA_FMParserTest, MaxParseDepth) {
- CXFA_FMParser parser(heap(), L"foo(bar[baz(fizz[0])])");
+ CXFA_FMLexer lexer(L"foo(bar[baz(fizz[0])])");
+ CXFA_FMParser parser(heap(), &lexer);
parser.SetMaxParseDepthForTest(5);
EXPECT_EQ(nullptr, parser.Parse());
EXPECT_TRUE(parser.HasError());
}
TEST_F(CXFA_FMParserTest, chromium752201) {
- CXFA_FMParser parser(heap(),
- LR"***(fTep a
+ CXFA_FMLexer lexer(
+ LR"***(fTep a
.#
fo@ =[=l)***");
+
+ CXFA_FMParser parser(heap(), &lexer);
EXPECT_EQ(nullptr, parser.Parse());
EXPECT_TRUE(parser.HasError());
}
TEST_F(CXFA_FMParserTest, MultipleAssignmentIsNotAllowed) {
- CXFA_FMParser parser(heap(), L"(a=(b=t))=u");
-
+ CXFA_FMLexer lexer(L"(a=(b=t))=u");
+ CXFA_FMParser parser(heap(), &lexer);
CXFA_FMAST* ast = parser.Parse();
ASSERT_TRUE(!ast);
EXPECT_TRUE(parser.HasError());
@@ -187,7 +194,8 @@
return pfm_rt.get_val(pfm_ret);
}).call(this);)***";
- CXFA_FMParser parser(heap(), input);
+ CXFA_FMLexer lexer(input);
+ CXFA_FMParser parser(heap(), &lexer);
CXFA_FMAST* ast = parser.Parse();
ASSERT_TRUE(ast);
EXPECT_FALSE(parser.HasError());
@@ -225,7 +233,8 @@
return pfm_rt.get_val(pfm_ret);
}).call(this);)***";
- CXFA_FMParser parser(heap(), input);
+ CXFA_FMLexer lexer(input);
+ CXFA_FMParser parser(heap(), &lexer);
CXFA_FMAST* ast = parser.Parse();
ASSERT_TRUE(ast);
EXPECT_FALSE(parser.HasError());
@@ -242,7 +251,8 @@
param1 * param2
endfunc)***";
- CXFA_FMParser parser(heap(), input);
+ CXFA_FMLexer lexer(input);
+ CXFA_FMParser parser(heap(), &lexer);
CXFA_FMAST* ast = parser.Parse();
ASSERT_TRUE(ast == nullptr);
EXPECT_TRUE(parser.HasError());
@@ -250,8 +260,8 @@
TEST_F(CXFA_FMParserTest, ParseBadIfExpression) {
const wchar_t input[] = L"if ( then";
-
- CXFA_FMParser parser(heap(), input);
+ CXFA_FMLexer lexer(input);
+ CXFA_FMParser parser(heap(), &lexer);
CXFA_FMAST* ast = parser.Parse();
ASSERT_TRUE(ast == nullptr);
EXPECT_TRUE(parser.HasError());
@@ -262,7 +272,8 @@
LR"***(if ($ ne -1) then"
elseif( then)***";
- CXFA_FMParser parser(heap(), input);
+ CXFA_FMLexer lexer(input);
+ CXFA_FMParser parser(heap(), &lexer);
CXFA_FMAST* ast = parser.Parse();
ASSERT_TRUE(ast == nullptr);
EXPECT_TRUE(parser.HasError());
@@ -272,14 +283,16 @@
const wchar_t input[] = L"a <> b <> c <> d <> e <> f <> g <> h <> i <> j";
{
- CXFA_FMParser parser(heap(), input);
+ CXFA_FMLexer lexer(input);
+ CXFA_FMParser parser(heap(), &lexer);
CXFA_FMAST* ast = parser.Parse();
ASSERT_TRUE(ast);
EXPECT_TRUE(!parser.HasError());
}
{
- CXFA_FMParser parser(heap(), input);
+ CXFA_FMLexer lexer(input);
+ CXFA_FMParser parser(heap(), &lexer);
parser.SetMaxParseDepthForTest(5);
CXFA_FMAST* ast = parser.Parse();
ASSERT_TRUE(ast == nullptr);
@@ -310,7 +323,8 @@
return pfm_rt.get_val(pfm_ret);
}).call(this);)***";
- CXFA_FMParser parser(heap(), input);
+ CXFA_FMLexer lexer(input);
+ CXFA_FMParser parser(heap(), &lexer);
CXFA_FMAST* ast = parser.Parse();
EXPECT_FALSE(parser.HasError());
@@ -351,7 +365,8 @@
return pfm_rt.get_val(pfm_ret);
}).call(this);)***";
- CXFA_FMParser parser(heap(), input);
+ CXFA_FMLexer lexer(input);
+ CXFA_FMParser parser(heap(), &lexer);
CXFA_FMAST* ast = parser.Parse();
EXPECT_FALSE(parser.HasError());
@@ -382,7 +397,8 @@
return pfm_rt.get_val(pfm_ret);
}).call(this);)***";
- CXFA_FMParser parser(heap(), input);
+ CXFA_FMLexer lexer(input);
+ CXFA_FMParser parser(heap(), &lexer);
CXFA_FMAST* ast = parser.Parse();
EXPECT_FALSE(parser.HasError());
@@ -415,9 +431,11 @@
return pfm_rt.get_val(pfm_ret);
}).call(this);)***";
- CXFA_FMParser parser(heap(), input);
+ CXFA_FMLexer lexer(input);
+ CXFA_FMParser parser(heap(), &lexer);
CXFA_FMAST* ast = parser.Parse();
EXPECT_FALSE(parser.HasError());
+
CXFA_FMToJavaScriptDepth::Reset();
Optional<CFX_WideTextBuf> buf = ast->ToJavaScript();
ASSERT_TRUE(buf.has_value());
@@ -447,9 +465,11 @@
return pfm_rt.get_val(pfm_ret);
}).call(this);)***";
- CXFA_FMParser parser(heap(), input);
+ CXFA_FMLexer lexer(input);
+ CXFA_FMParser parser(heap(), &lexer);
CXFA_FMAST* ast = parser.Parse();
EXPECT_FALSE(parser.HasError());
+
CXFA_FMToJavaScriptDepth::Reset();
Optional<CFX_WideTextBuf> buf = ast->ToJavaScript();
ASSERT_TRUE(buf.has_value());
@@ -479,9 +499,11 @@
return pfm_rt.get_val(pfm_ret);
}).call(this);)***";
- CXFA_FMParser parser(heap(), input);
+ CXFA_FMLexer lexer(input);
+ CXFA_FMParser parser(heap(), &lexer);
CXFA_FMAST* ast = parser.Parse();
EXPECT_FALSE(parser.HasError());
+
CXFA_FMToJavaScriptDepth::Reset();
Optional<CFX_WideTextBuf> buf = ast->ToJavaScript();
ASSERT_TRUE(buf.has_value());
@@ -490,8 +512,8 @@
TEST_F(CXFA_FMParserTest, ParseFunctionCallMissingCommas) {
const wchar_t input[] = L"P.x(!foo!bar!baz)";
-
- CXFA_FMParser parser(heap(), input);
+ CXFA_FMLexer lexer(input);
+ CXFA_FMParser parser(heap(), &lexer);
CXFA_FMAST* ast = parser.Parse();
ASSERT_TRUE(ast == nullptr);
EXPECT_TRUE(parser.HasError());
@@ -499,8 +521,8 @@
TEST_F(CXFA_FMParserTest, ParseFunctionCallTrailingComma) {
const wchar_t input[] = L"P.x(foo,bar,baz,)";
-
- CXFA_FMParser parser(heap(), input);
+ CXFA_FMLexer lexer(input);
+ CXFA_FMParser parser(heap(), &lexer);
CXFA_FMAST* ast = parser.Parse();
ASSERT_TRUE(ast == nullptr);
EXPECT_TRUE(parser.HasError());
@@ -508,8 +530,8 @@
TEST_F(CXFA_FMParserTest, ParseFunctionCallExtraComma) {
const wchar_t input[] = L"P.x(foo,bar,,baz)";
-
- CXFA_FMParser parser(heap(), input);
+ CXFA_FMLexer lexer(input);
+ CXFA_FMParser parser(heap(), &lexer);
CXFA_FMAST* ast = parser.Parse();
ASSERT_TRUE(ast == nullptr);
EXPECT_TRUE(parser.HasError());