7#include "xfa/fxfa/formcalc/cxfa_fmparser.h"
12#include "core/fxcrt/autorestorer.h"
13#include "v8/include/cppgc/heap.h"
17constexpr unsigned int kMaxParseDepth = 1250;
18constexpr unsigned int kMaxPostExpressions = 256;
19constexpr unsigned int kMaxExpressionListSize = 10000;
24 :
m_heap(
pHeap), m_lexer(pLexer), m_max_parse_depth(kMaxParseDepth) {}
29 m_token = m_lexer->NextToken();
33 auto expressions = ParseExpressionList();
41 return cppgc::MakeGarbageCollected<CXFA_FMAST>(m_heap->GetAllocationHandle(),
42 std::move(expressions));
49 m_token = m_lexer->NextToken();
50 while (!HasError() && m_token.GetType() == TOKreserver)
51 m_token = m_lexer->NextToken();
59 if (m_token.GetType() != op) {
67 return ++m_parse_depth < m_max_parse_depth;
70std::vector<cppgc::Member<CXFA_FMExpression>>
71CXFA_FMParser::ParseExpressionList() {
72 AutoRestorer<
unsigned long> restorer(&m_parse_depth);
73 if (HasError() || !IncrementParseDepthAndCheck())
74 return std::vector<cppgc::Member<CXFA_FMExpression>>();
76 std::vector<cppgc::Member<CXFA_FMExpression>> expressions;
78 if (m_token.GetType() == TOKeof || m_token.GetType() == TOKendfunc ||
79 m_token.GetType() == TOKendif || m_token.GetType() == TOKelseif ||
80 m_token.GetType() == TOKelse || m_token.GetType() == TOKendwhile ||
81 m_token.GetType() == TOKendfor || m_token.GetType() == TOKend ||
82 m_token.GetType() == TOKendfunc || m_token.GetType() == TOKreserver) {
86 CXFA_FMExpression* expr =
87 m_token.GetType() == TOKfunc ? ParseFunction() : ParseExpression();
90 return std::vector<cppgc::Member<CXFA_FMExpression>>();
92 if (expressions.size() >= kMaxExpressionListSize) {
94 return std::vector<cppgc::Member<CXFA_FMExpression>>();
96 expressions.push_back(expr);
106 if (
HasError() || !IncrementParseDepthAndCheck())
110 if (m_token.GetType() != TOKidentifier)
113 WideString ident(m_token.GetString());
119 std::vector<WideString> arguments;
120 bool last_was_comma =
false;
122 if (m_token.GetType() == TOKrparen)
124 if (m_token.GetType() != TOKidentifier)
127 last_was_comma =
false;
129 arguments.emplace_back(m_token.GetString());
132 if (m_token.GetType() != TOKcomma)
135 last_was_comma =
true;
139 if (last_was_comma || !CheckThenNext(
TOKrparen))
141 if (!CheckThenNext(
TOKdo))
144 std::vector<cppgc::Member<CXFA_FMExpression>> expressions;
145 if (m_token.GetType() != TOKendfunc)
146 expressions = ParseExpressionList();
151 return cppgc::MakeGarbageCollected<CXFA_FMFunctionDefinition>(
152 m_heap->GetAllocationHandle(), std::move(ident), std::move(arguments),
153 std::move(expressions));
161 if (
HasError() || !IncrementParseDepthAndCheck())
165 switch (m_token.GetType()) {
167 expr = ParseDeclarationExpression();
177 expr = ParseExpExpression();
180 expr = ParseIfExpression();
183 expr = ParseWhileExpression();
186 expr = ParseForExpression();
189 expr = ParseForeachExpression();
192 expr = ParseDoExpression();
195 expr = cppgc::MakeGarbageCollected<CXFA_FMBreakExpression>(
196 m_heap->GetAllocationHandle());
201 expr = cppgc::MakeGarbageCollected<CXFA_FMContinueExpression>(
202 m_heap->GetAllocationHandle());
217 if (
HasError() || !IncrementParseDepthAndCheck())
220 if (!NextToken() || m_token.GetType() != TOKidentifier)
223 WideString ident(m_token.GetString());
228 if (m_token.GetType() == TOKassign) {
232 expr = ParseSimpleExpression();
237 return cppgc::MakeGarbageCollected<CXFA_FMVarExpression>(
238 m_heap->GetAllocationHandle(), std::move(ident), expr);
246 return ParseLogicalOrExpression();
252 if (
HasError() || !IncrementParseDepthAndCheck())
259 if (m_token.GetType() == TOKassign) {
267 pExp1 = cppgc::MakeGarbageCollected<CXFA_FMAssignExpression>(
268 m_heap->GetAllocationHandle(), TOKassign, pExp1, pExp2);
270 return cppgc::MakeGarbageCollected<CXFA_FMExpExpression>(
271 m_heap->GetAllocationHandle(), pExp1);
278 if (
HasError() || !IncrementParseDepthAndCheck())
286 if (!IncrementParseDepthAndCheck())
289 switch (m_token.GetType()) {
297 e1 = cppgc::MakeGarbageCollected<CXFA_FMLogicalOrExpression>(
298 m_heap->GetAllocationHandle(), TOKor, e1, e2);
311 if (
HasError() || !IncrementParseDepthAndCheck())
319 if (!IncrementParseDepthAndCheck())
322 switch (m_token.GetType()) {
330 e1 = cppgc::MakeGarbageCollected<CXFA_FMLogicalAndExpression>(
331 m_heap->GetAllocationHandle(), TOKand, e1, e2);
344 if (
HasError() || !IncrementParseDepthAndCheck())
352 if (!IncrementParseDepthAndCheck())
355 switch (m_token.GetType()) {
363 e1 = cppgc::MakeGarbageCollected<CXFA_FMEqualExpression>(
364 m_heap->GetAllocationHandle(), TOKeq, e1, e2);
374 e1 = cppgc::MakeGarbageCollected<CXFA_FMNotEqualExpression>(
375 m_heap->GetAllocationHandle(), TOKne, e1, e2);
388 if (
HasError() || !IncrementParseDepthAndCheck())
396 if (!IncrementParseDepthAndCheck())
399 switch (m_token.GetType()) {
407 e1 = cppgc::MakeGarbageCollected<CXFA_FMLtExpression>(
408 m_heap->GetAllocationHandle(), TOKlt, e1, e2);
418 e1 = cppgc::MakeGarbageCollected<CXFA_FMGtExpression>(
419 m_heap->GetAllocationHandle(), TOKgt, e1, e2);
429 e1 = cppgc::MakeGarbageCollected<CXFA_FMLeExpression>(
430 m_heap->GetAllocationHandle(), TOKle, e1, e2);
440 e1 = cppgc::MakeGarbageCollected<CXFA_FMGeExpression>(
441 m_heap->GetAllocationHandle(), TOKge, e1, e2);
454 if (
HasError() || !IncrementParseDepthAndCheck())
462 if (!IncrementParseDepthAndCheck())
465 switch (m_token.GetType()) {
472 e1 = cppgc::MakeGarbageCollected<CXFA_FMPlusExpression>(
473 m_heap->GetAllocationHandle(), TOKplus, e1, e2);
482 e1 = cppgc::MakeGarbageCollected<CXFA_FMMinusExpression>(
483 m_heap->GetAllocationHandle(), TOKminus, e1, e2);
496 if (
HasError() || !IncrementParseDepthAndCheck())
504 if (!IncrementParseDepthAndCheck())
507 switch (m_token.GetType()) {
514 e1 = cppgc::MakeGarbageCollected<CXFA_FMMulExpression>(
515 m_heap->GetAllocationHandle(), TOKmul, e1, e2);
524 e1 = cppgc::MakeGarbageCollected<CXFA_FMDivExpression>(
525 m_heap->GetAllocationHandle(), TOKdiv, e1, e2);
537 if (
HasError() || !IncrementParseDepthAndCheck())
540 switch (m_token.GetType()) {
547 return cppgc::MakeGarbageCollected<CXFA_FMPosExpression>(
548 m_heap->GetAllocationHandle(), expr);
556 return cppgc::MakeGarbageCollected<CXFA_FMNegExpression>(
557 m_heap->GetAllocationHandle(), expr);
565 return cppgc::MakeGarbageCollected<CXFA_FMNotExpression>(
566 m_heap->GetAllocationHandle(), expr);
569 return ParsePrimaryExpression();
577 if (
HasError() || !IncrementParseDepthAndCheck())
582 return NextToken() ? expr :
nullptr;
584 switch (m_token.GetType()) {
586 WideString wsIdentifier(m_token.GetString());
589 if (m_token.GetType() == TOKlbracket) {
593 expr = cppgc::MakeGarbageCollected<CXFA_FMDotAccessorExpression>(
594 m_heap->GetAllocationHandle(),
nullptr, TOKdot,
595 std::move(wsIdentifier), s);
601 expr = cppgc::MakeGarbageCollected<CXFA_FMIdentifierExpression>(
602 m_heap->GetAllocationHandle(), wsIdentifier);
607 expr = ParseParenExpression();
615 return ParsePostExpression(expr);
620 switch (m_token.GetType()) {
622 return cppgc::MakeGarbageCollected<CXFA_FMNumberExpression>(
623 m_heap->GetAllocationHandle(), WideString(m_token.GetString()));
625 return cppgc::MakeGarbageCollected<CXFA_FMStringExpression>(
626 m_heap->GetAllocationHandle(), WideString(m_token.GetString()));
628 return cppgc::MakeGarbageCollected<CXFA_FMNullExpression>(
629 m_heap->GetAllocationHandle());
640 if (
HasError() || !IncrementParseDepthAndCheck())
643 size_t expr_count = 0;
649 if (expr_count > kMaxPostExpressions)
652 switch (m_token.GetType()) {
654 absl::optional<std::vector<cppgc::Member<CXFA_FMSimpleExpression>>>
655 expressions = ParseArgumentList();
656 if (!expressions.has_value())
659 expr = cppgc::MakeGarbageCollected<CXFA_FMCallExpression>(
660 m_heap->GetAllocationHandle(), expr, std::move(expressions.value()),
664 if (m_token.GetType() != TOKlbracket)
671 expr = cppgc::MakeGarbageCollected<CXFA_FMDotAccessorExpression>(
672 m_heap->GetAllocationHandle(), expr, TOKcall, WideString(), s);
678 if (m_token.GetType() != TOKidentifier)
681 WideString tempStr(m_token.GetString());
684 if (m_token.GetType() == TOKlparen) {
685 absl::optional<std::vector<cppgc::Member<CXFA_FMSimpleExpression>>>
686 expressions = ParseArgumentList();
687 if (!expressions.has_value())
691 cppgc::MakeGarbageCollected<CXFA_FMIdentifierExpression>(
692 m_heap->GetAllocationHandle(), std::move(tempStr));
693 auto* pExpCall = cppgc::MakeGarbageCollected<CXFA_FMCallExpression>(
694 m_heap->GetAllocationHandle(), pIdentifier,
695 std::move(expressions.value()),
true);
696 expr = cppgc::MakeGarbageCollected<CXFA_FMMethodCallExpression>(
697 m_heap->GetAllocationHandle(), expr, pExpCall);
700 if (m_token.GetType() != TOKlbracket)
707 expr = cppgc::MakeGarbageCollected<CXFA_FMDotAccessorExpression>(
708 m_heap->GetAllocationHandle(), expr, TOKcall, WideString(), s);
709 }
else if (m_token.GetType() == TOKlbracket) {
714 expr = cppgc::MakeGarbageCollected<CXFA_FMDotAccessorExpression>(
715 m_heap->GetAllocationHandle(), expr, TOKdot, std::move(tempStr),
718 auto* subexpr = cppgc::MakeGarbageCollected<CXFA_FMIndexExpression>(
719 m_heap->GetAllocationHandle(),
720 CXFA_FMIndexExpression::AccessorIndex::kNoIndex,
nullptr,
false);
721 expr = cppgc::MakeGarbageCollected<CXFA_FMDotAccessorExpression>(
722 m_heap->GetAllocationHandle(), expr, TOKdot, std::move(tempStr),
731 if (m_token.GetType() != TOKidentifier)
734 WideString tempStr(m_token.GetString());
737 if (m_token.GetType() == TOKlbracket) {
742 expr = cppgc::MakeGarbageCollected<CXFA_FMDotDotAccessorExpression>(
743 m_heap->GetAllocationHandle(), expr, TOKdotdot,
744 std::move(tempStr), s);
746 auto* subexpr = cppgc::MakeGarbageCollected<CXFA_FMIndexExpression>(
747 m_heap->GetAllocationHandle(),
748 CXFA_FMIndexExpression::AccessorIndex::kNoIndex,
nullptr,
false);
749 expr = cppgc::MakeGarbageCollected<CXFA_FMDotDotAccessorExpression>(
750 m_heap->GetAllocationHandle(), expr, TOKdotdot,
751 std::move(tempStr), subexpr);
759 if (m_token.GetType() != TOKidentifier)
762 WideString tempStr(m_token.GetString());
766 if (m_token.GetType() != TOKlbracket) {
767 auto* subexpr = cppgc::MakeGarbageCollected<CXFA_FMIndexExpression>(
768 m_heap->GetAllocationHandle(),
769 CXFA_FMIndexExpression::AccessorIndex::kNoIndex,
nullptr,
false);
770 expr = cppgc::MakeGarbageCollected<CXFA_FMDotAccessorExpression>(
771 m_heap->GetAllocationHandle(), expr, TOKdotscream,
772 std::move(tempStr), subexpr);
780 expr = cppgc::MakeGarbageCollected<CXFA_FMDotAccessorExpression>(
781 m_heap->GetAllocationHandle(), expr, TOKdotscream,
782 std::move(tempStr), s);
786 auto* subexpr = cppgc::MakeGarbageCollected<CXFA_FMIndexExpression>(
787 m_heap->GetAllocationHandle(),
788 CXFA_FMIndexExpression::AccessorIndex::kNoIndex,
nullptr,
false);
789 expr = cppgc::MakeGarbageCollected<CXFA_FMDotAccessorExpression>(
790 m_heap->GetAllocationHandle(), expr, TOKdotstar, L"*", subexpr);
803absl::optional<std::vector<cppgc::Member<CXFA_FMSimpleExpression>>>
804CXFA_FMParser::ParseArgumentList() {
805 if (m_token.GetType() != TOKlparen || !NextToken())
806 return absl::nullopt;
808 std::vector<cppgc::Member<CXFA_FMSimpleExpression>> expressions;
809 bool first_arg =
true;
810 while (m_token.GetType() != TOKrparen) {
814 if (m_token.GetType() != TOKcomma || !NextToken())
815 return absl::nullopt;
818 CXFA_FMSimpleExpression* exp = ParseSimpleExpression();
820 return absl::nullopt;
822 expressions.push_back(exp);
823 if (expressions.size() > kMaxPostExpressions)
824 return absl::nullopt;
833 if (
HasError() || !IncrementParseDepthAndCheck())
838 if (m_token.GetType() == TOKmul) {
839 auto* pExp = cppgc::MakeGarbageCollected<CXFA_FMIndexExpression>(
840 m_heap->GetAllocationHandle(),
841 CXFA_FMIndexExpression::AccessorIndex::kNoRelativeIndex,
nullptr,
true);
842 if (!pExp || !NextToken())
847 if (m_token.GetType() != TOKrbracket)
854 if (m_token.GetType() == TOKplus) {
858 }
else if (m_token.GetType() == TOKminus) {
867 if (m_token.GetType() != TOKrbracket)
870 return cppgc::MakeGarbageCollected<CXFA_FMIndexExpression>(
871 m_heap->GetAllocationHandle(), accessorIndex, s,
false);
877 if (
HasError() || !IncrementParseDepthAndCheck())
882 if (m_token.GetType() == TOKrparen)
900 if (
HasError() || !IncrementParseDepthAndCheck())
903 if (!CheckThenNext(
TOKif))
912 auto* pIfExpressions = cppgc::MakeGarbageCollected<CXFA_FMBlockExpression>(
913 m_heap->GetAllocationHandle(), ParseExpressionList());
915 std::vector<cppgc::Member<CXFA_FMIfExpression>> pElseIfExpressions;
916 while (m_token.GetType() == TOKelseif) {
920 auto* elseIfCondition = ParseParenExpression();
921 if (!elseIfCondition)
926 auto elseIfExprs = ParseExpressionList();
927 pElseIfExpressions.push_back(
928 cppgc::MakeGarbageCollected<CXFA_FMIfExpression>(
929 m_heap->GetAllocationHandle(), elseIfCondition,
930 cppgc::MakeGarbageCollected<CXFA_FMBlockExpression>(
931 m_heap->GetAllocationHandle(), std::move(elseIfExprs)),
932 std::vector<cppgc::Member<CXFA_FMIfExpression>>(),
nullptr));
936 if (m_token.GetType() == TOKelse) {
940 pElseExpression = cppgc::MakeGarbageCollected<CXFA_FMBlockExpression>(
941 m_heap->GetAllocationHandle(), ParseExpressionList());
946 return cppgc::MakeGarbageCollected<CXFA_FMIfExpression>(
947 m_heap->GetAllocationHandle(), pCondition, pIfExpressions,
948 std::move(pElseIfExpressions), pElseExpression);
954 if (
HasError() || !IncrementParseDepthAndCheck())
960 if (!pCondition || !CheckThenNext(
TOKdo))
963 auto exprs = ParseExpressionList();
967 return cppgc::MakeGarbageCollected<CXFA_FMWhileExpression>(
968 m_heap->GetAllocationHandle(), pCondition,
969 cppgc::MakeGarbageCollected<CXFA_FMBlockExpression>(
970 m_heap->GetAllocationHandle(), std::move(exprs)));
979 if (
HasError() || !IncrementParseDepthAndCheck())
981 if (!CheckThenNext(
TOKfor))
983 if (m_token.GetType() != TOKidentifier)
986 WideString wsVariant(m_token.GetString());
996 int32_t iDirection = 0;
997 if (m_token.GetType() == TOKupto)
999 else if (m_token.GetType() == TOKdownto)
1012 if (m_token.GetType() == TOKstep) {
1015 pStep = ParseSimpleExpression();
1019 if (!CheckThenNext(
TOKdo))
1022 auto exprs = ParseExpressionList();
1026 return cppgc::MakeGarbageCollected<CXFA_FMForExpression>(
1027 m_heap->GetAllocationHandle(), wsVariant, pAssignment, pAccessor,
1029 cppgc::MakeGarbageCollected<CXFA_FMBlockExpression>(
1030 m_heap->GetAllocationHandle(), std::move(exprs)));
1036 if (m_token.GetType() != TOKforeach)
1040 if (
HasError() || !IncrementParseDepthAndCheck())
1044 if (m_token.GetType() != TOKidentifier)
1047 WideString wsIdentifier(m_token.GetString());
1048 if (!NextToken() || !CheckThenNext(
TOKin) || !CheckThenNext(
TOKlparen))
1051 std::vector<cppgc::Member<CXFA_FMSimpleExpression>> pArgumentList;
1052 while (m_token.GetType() != TOKrparen) {
1057 pArgumentList.push_back(s);
1058 if (m_token.GetType() != TOKcomma)
1064 if (pArgumentList.empty())
1069 auto exprs = ParseExpressionList();
1073 return cppgc::MakeGarbageCollected<CXFA_FMForeachExpression>(
1074 m_heap->GetAllocationHandle(), std::move(wsIdentifier),
1075 std::move(pArgumentList),
1076 cppgc::MakeGarbageCollected<CXFA_FMBlockExpression>(
1077 m_heap->GetAllocationHandle(), std::move(exprs)));
1082 if (m_token.GetType() != TOKdo)
1086 if (
HasError() || !IncrementParseDepthAndCheck())
1088 if (!CheckThenNext(
TOKdo))
1091 auto exprs = ParseExpressionList();
1092 if (!CheckThenNext(
TOKend))
1095 return cppgc::MakeGarbageCollected<CXFA_FMDoExpression>(
1096 m_heap->GetAllocationHandle(),
1097 cppgc::MakeGarbageCollected<CXFA_FMBlockExpression>(
1098 m_heap->GetAllocationHandle(), std::move(exprs)));
1102 return m_error || m_token.GetType() == TOKreserver;
CXFA_FMParser(cppgc::Heap *heap, CXFA_FMLexer *pLexer)