1 // Copyright 2014 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #include "xfa/fxfa/fm2js/cxfa_fmparser.h" 8 9 #include <memory> 10 #include <utility> 11 #include <vector> 12 13 #include "core/fxcrt/autorestorer.h" 14 #include "third_party/base/ptr_util.h" 15 16 namespace { 17 18 const unsigned int kMaxAssignmentChainLength = 12; 19 const unsigned int kMaxParseDepth = 1250; 20 21 } // namespace 22 23 CXFA_FMParser::CXFA_FMParser(const WideStringView& wsFormcalc) 24 : m_error(false), m_parse_depth(0), m_max_parse_depth(kMaxParseDepth) { 25 m_lexer = pdfium::MakeUnique<CXFA_FMLexer>(wsFormcalc); 26 m_token = m_lexer->NextToken(); 27 } 28 29 CXFA_FMParser::~CXFA_FMParser() {} 30 31 std::unique_ptr<CXFA_FMFunctionDefinition> CXFA_FMParser::Parse() { 32 auto expressions = ParseTopExpression(); 33 if (HasError()) 34 return nullptr; 35 36 std::vector<WideStringView> arguments; 37 return pdfium::MakeUnique<CXFA_FMFunctionDefinition>( 38 1, true, L"", std::move(arguments), std::move(expressions)); 39 } 40 41 bool CXFA_FMParser::NextToken() { 42 if (HasError()) 43 return false; 44 m_token = m_lexer->NextToken(); 45 while (!HasError() && m_token->m_type == TOKreserver) 46 m_token = m_lexer->NextToken(); 47 return !HasError(); 48 } 49 50 bool CXFA_FMParser::CheckThenNext(XFA_FM_TOKEN op) { 51 if (HasError()) 52 return false; 53 54 if (m_token->m_type != op) { 55 m_error = true; 56 return false; 57 } 58 return NextToken(); 59 } 60 61 bool CXFA_FMParser::IncrementParseDepthAndCheck() { 62 return ++m_parse_depth < m_max_parse_depth; 63 } 64 65 std::vector<std::unique_ptr<CXFA_FMExpression>> 66 CXFA_FMParser::ParseTopExpression() { 67 AutoRestorer<unsigned long> restorer(&m_parse_depth); 68 if (HasError() || !IncrementParseDepthAndCheck()) 69 return std::vector<std::unique_ptr<CXFA_FMExpression>>(); 70 71 std::unique_ptr<CXFA_FMExpression> expr; 72 std::vector<std::unique_ptr<CXFA_FMExpression>> expressions; 73 while (!HasError()) { 74 if (m_token->m_type == TOKeof || m_token->m_type == TOKendfunc || 75 m_token->m_type == TOKendif || m_token->m_type == TOKelseif || 76 m_token->m_type == TOKelse || m_token->m_type == TOKreserver) { 77 return expressions; 78 } 79 80 expr = m_token->m_type == TOKfunc ? ParseFunction() : ParseExpression(); 81 if (!expr) { 82 m_error = true; 83 break; 84 } 85 expressions.push_back(std::move(expr)); 86 } 87 return std::vector<std::unique_ptr<CXFA_FMExpression>>(); 88 } 89 90 std::unique_ptr<CXFA_FMExpression> CXFA_FMParser::ParseFunction() { 91 AutoRestorer<unsigned long> restorer(&m_parse_depth); 92 if (HasError() || !IncrementParseDepthAndCheck()) 93 return nullptr; 94 95 WideStringView ident; 96 std::vector<WideStringView> arguments; 97 std::vector<std::unique_ptr<CXFA_FMExpression>> expressions; 98 uint32_t line = m_token->m_line_num; 99 if (!NextToken()) 100 return nullptr; 101 if (m_token->m_type != TOKidentifier) { 102 m_error = true; 103 return nullptr; 104 } else { 105 ident = m_token->m_string; 106 if (!NextToken()) 107 return nullptr; 108 } 109 if (!CheckThenNext(TOKlparen)) 110 return nullptr; 111 if (m_token->m_type == TOKrparen) { 112 if (!NextToken()) 113 return nullptr; 114 } else { 115 while (1) { 116 if (m_token->m_type != TOKidentifier) { 117 m_error = true; 118 return nullptr; 119 } 120 arguments.push_back(m_token->m_string); 121 if (!NextToken()) 122 return nullptr; 123 if (m_token->m_type == TOKcomma) { 124 if (!NextToken()) 125 return nullptr; 126 continue; 127 } 128 if (m_token->m_type == TOKrparen) { 129 if (!NextToken()) 130 return nullptr; 131 } else { 132 if (!CheckThenNext(TOKrparen)) 133 return nullptr; 134 } 135 break; 136 } 137 } 138 if (!CheckThenNext(TOKdo)) 139 return nullptr; 140 if (m_token->m_type == TOKendfunc) { 141 if (!NextToken()) 142 return nullptr; 143 } else { 144 expressions = ParseTopExpression(); 145 if (!expressions.size() || !CheckThenNext(TOKendfunc)) 146 return nullptr; 147 } 148 149 return pdfium::MakeUnique<CXFA_FMFunctionDefinition>( 150 line, false, ident, std::move(arguments), std::move(expressions)); 151 } 152 153 std::unique_ptr<CXFA_FMExpression> CXFA_FMParser::ParseExpression() { 154 AutoRestorer<unsigned long> restorer(&m_parse_depth); 155 if (HasError() || !IncrementParseDepthAndCheck()) 156 return nullptr; 157 158 std::unique_ptr<CXFA_FMExpression> expr; 159 uint32_t line = m_token->m_line_num; 160 switch (m_token->m_type) { 161 case TOKvar: 162 expr = ParseVarExpression(); 163 break; 164 case TOKnull: 165 case TOKnumber: 166 case TOKstring: 167 case TOKplus: 168 case TOKminus: 169 case TOKksnot: 170 case TOKidentifier: 171 case TOKlparen: 172 expr = ParseExpExpression(); 173 break; 174 case TOKif: 175 expr = ParseIfExpression(); 176 break; 177 case TOKwhile: 178 expr = ParseWhileExpression(); 179 break; 180 case TOKfor: 181 expr = ParseForExpression(); 182 break; 183 case TOKforeach: 184 expr = ParseForeachExpression(); 185 break; 186 case TOKdo: 187 expr = ParseDoExpression(); 188 break; 189 case TOKbreak: 190 expr = pdfium::MakeUnique<CXFA_FMBreakExpression>(line); 191 if (!NextToken()) 192 return nullptr; 193 break; 194 case TOKcontinue: 195 expr = pdfium::MakeUnique<CXFA_FMContinueExpression>(line); 196 if (!NextToken()) 197 return nullptr; 198 break; 199 default: 200 m_error = true; 201 return nullptr; 202 } 203 return expr; 204 } 205 206 std::unique_ptr<CXFA_FMExpression> CXFA_FMParser::ParseVarExpression() { 207 AutoRestorer<unsigned long> restorer(&m_parse_depth); 208 if (HasError() || !IncrementParseDepthAndCheck()) 209 return nullptr; 210 211 WideStringView ident; 212 uint32_t line = m_token->m_line_num; 213 if (!NextToken()) 214 return nullptr; 215 if (m_token->m_type != TOKidentifier) { 216 m_error = true; 217 return nullptr; 218 } 219 220 ident = m_token->m_string; 221 if (!NextToken()) 222 return nullptr; 223 224 std::unique_ptr<CXFA_FMExpression> expr; 225 if (m_token->m_type == TOKassign) { 226 if (!NextToken()) 227 return nullptr; 228 229 expr = ParseExpExpression(); 230 if (!expr) 231 return nullptr; 232 } 233 234 return pdfium::MakeUnique<CXFA_FMVarExpression>(line, ident, std::move(expr)); 235 } 236 237 std::unique_ptr<CXFA_FMSimpleExpression> 238 CXFA_FMParser::ParseSimpleExpression() { 239 if (HasError()) 240 return nullptr; 241 242 uint32_t line = m_token->m_line_num; 243 std::unique_ptr<CXFA_FMSimpleExpression> pExp1 = ParseLogicalOrExpression(); 244 if (!pExp1) 245 return nullptr; 246 int level = 1; 247 while (m_token->m_type == TOKassign) { 248 if (!NextToken()) 249 return nullptr; 250 std::unique_ptr<CXFA_FMSimpleExpression> pExp2 = ParseLogicalOrExpression(); 251 if (!pExp2) 252 return nullptr; 253 if (level++ == kMaxAssignmentChainLength) { 254 m_error = true; 255 return nullptr; 256 } 257 pExp1 = pdfium::MakeUnique<CXFA_FMAssignExpression>( 258 line, TOKassign, std::move(pExp1), std::move(pExp2)); 259 } 260 return pExp1; 261 } 262 263 std::unique_ptr<CXFA_FMExpression> CXFA_FMParser::ParseExpExpression() { 264 AutoRestorer<unsigned long> restorer(&m_parse_depth); 265 if (HasError() || !IncrementParseDepthAndCheck()) 266 return nullptr; 267 268 uint32_t line = m_token->m_line_num; 269 std::unique_ptr<CXFA_FMSimpleExpression> pExp1 = ParseSimpleExpression(); 270 if (!pExp1) 271 return nullptr; 272 return pdfium::MakeUnique<CXFA_FMExpExpression>(line, std::move(pExp1)); 273 } 274 275 std::unique_ptr<CXFA_FMSimpleExpression> 276 CXFA_FMParser::ParseLogicalOrExpression() { 277 AutoRestorer<unsigned long> restorer(&m_parse_depth); 278 if (HasError() || !IncrementParseDepthAndCheck()) 279 return nullptr; 280 281 uint32_t line = m_token->m_line_num; 282 std::unique_ptr<CXFA_FMSimpleExpression> e1 = ParseLogicalAndExpression(); 283 if (!e1) 284 return nullptr; 285 286 for (;;) { 287 switch (m_token->m_type) { 288 case TOKor: 289 case TOKksor: { 290 if (!NextToken()) 291 return nullptr; 292 293 std::unique_ptr<CXFA_FMSimpleExpression> e2( 294 ParseLogicalAndExpression()); 295 if (!e2) 296 return nullptr; 297 298 e1 = pdfium::MakeUnique<CXFA_FMLogicalOrExpression>( 299 line, TOKor, std::move(e1), std::move(e2)); 300 continue; 301 } 302 default: 303 break; 304 } 305 break; 306 } 307 return e1; 308 } 309 310 std::unique_ptr<CXFA_FMSimpleExpression> 311 CXFA_FMParser::ParseLogicalAndExpression() { 312 AutoRestorer<unsigned long> restorer(&m_parse_depth); 313 if (HasError() || !IncrementParseDepthAndCheck()) 314 return nullptr; 315 316 uint32_t line = m_token->m_line_num; 317 std::unique_ptr<CXFA_FMSimpleExpression> e1 = ParseEqualityExpression(); 318 if (!e1) 319 return nullptr; 320 321 for (;;) { 322 switch (m_token->m_type) { 323 case TOKand: 324 case TOKksand: { 325 if (!NextToken()) 326 return nullptr; 327 328 std::unique_ptr<CXFA_FMSimpleExpression> e2 = ParseEqualityExpression(); 329 if (!e2) 330 return nullptr; 331 332 e1 = pdfium::MakeUnique<CXFA_FMLogicalAndExpression>( 333 line, TOKand, std::move(e1), std::move(e2)); 334 continue; 335 } 336 default: 337 break; 338 } 339 break; 340 } 341 return e1; 342 } 343 344 std::unique_ptr<CXFA_FMSimpleExpression> 345 CXFA_FMParser::ParseEqualityExpression() { 346 AutoRestorer<unsigned long> restorer(&m_parse_depth); 347 if (HasError() || !IncrementParseDepthAndCheck()) 348 return nullptr; 349 350 uint32_t line = m_token->m_line_num; 351 std::unique_ptr<CXFA_FMSimpleExpression> e1 = ParseRelationalExpression(); 352 if (!e1) 353 return nullptr; 354 for (;;) { 355 std::unique_ptr<CXFA_FMSimpleExpression> e2; 356 switch (m_token->m_type) { 357 case TOKeq: 358 case TOKkseq: 359 if (!NextToken()) 360 return nullptr; 361 362 e2 = ParseRelationalExpression(); 363 if (!e2) 364 return nullptr; 365 366 e1 = pdfium::MakeUnique<CXFA_FMEqualityExpression>( 367 line, TOKeq, std::move(e1), std::move(e2)); 368 continue; 369 case TOKne: 370 case TOKksne: 371 if (!NextToken()) 372 return nullptr; 373 374 e2 = ParseRelationalExpression(); 375 if (!e2) 376 return nullptr; 377 378 e1 = pdfium::MakeUnique<CXFA_FMEqualityExpression>( 379 line, TOKne, std::move(e1), std::move(e2)); 380 continue; 381 default: 382 break; 383 } 384 break; 385 } 386 return e1; 387 } 388 389 std::unique_ptr<CXFA_FMSimpleExpression> 390 CXFA_FMParser::ParseRelationalExpression() { 391 AutoRestorer<unsigned long> restorer(&m_parse_depth); 392 if (HasError() || !IncrementParseDepthAndCheck()) 393 return nullptr; 394 395 uint32_t line = m_token->m_line_num; 396 std::unique_ptr<CXFA_FMSimpleExpression> e1 = ParseAddtiveExpression(); 397 if (!e1) 398 return nullptr; 399 400 for (;;) { 401 std::unique_ptr<CXFA_FMSimpleExpression> e2; 402 switch (m_token->m_type) { 403 case TOKlt: 404 case TOKkslt: 405 if (!NextToken()) 406 return nullptr; 407 408 e2 = ParseAddtiveExpression(); 409 if (!e2) 410 return nullptr; 411 412 e1 = pdfium::MakeUnique<CXFA_FMRelationalExpression>( 413 line, TOKlt, std::move(e1), std::move(e2)); 414 continue; 415 case TOKgt: 416 case TOKksgt: 417 if (!NextToken()) 418 return nullptr; 419 420 e2 = ParseAddtiveExpression(); 421 if (!e2) 422 return nullptr; 423 424 e1 = pdfium::MakeUnique<CXFA_FMRelationalExpression>( 425 line, TOKgt, std::move(e1), std::move(e2)); 426 continue; 427 case TOKle: 428 case TOKksle: 429 if (!NextToken()) 430 return nullptr; 431 432 e2 = ParseAddtiveExpression(); 433 if (!e2) 434 return nullptr; 435 436 e1 = pdfium::MakeUnique<CXFA_FMRelationalExpression>( 437 line, TOKle, std::move(e1), std::move(e2)); 438 continue; 439 case TOKge: 440 case TOKksge: 441 if (!NextToken()) 442 return nullptr; 443 444 e2 = ParseAddtiveExpression(); 445 if (!e2) 446 return nullptr; 447 448 e1 = pdfium::MakeUnique<CXFA_FMRelationalExpression>( 449 line, TOKge, std::move(e1), std::move(e2)); 450 continue; 451 default: 452 break; 453 } 454 break; 455 } 456 return e1; 457 } 458 459 std::unique_ptr<CXFA_FMSimpleExpression> 460 CXFA_FMParser::ParseAddtiveExpression() { 461 AutoRestorer<unsigned long> restorer(&m_parse_depth); 462 if (HasError() || !IncrementParseDepthAndCheck()) 463 return nullptr; 464 465 uint32_t line = m_token->m_line_num; 466 std::unique_ptr<CXFA_FMSimpleExpression> e1 = ParseMultiplicativeExpression(); 467 if (!e1) 468 return nullptr; 469 470 for (;;) { 471 std::unique_ptr<CXFA_FMSimpleExpression> e2; 472 switch (m_token->m_type) { 473 case TOKplus: 474 if (!NextToken()) 475 return nullptr; 476 477 e2 = ParseMultiplicativeExpression(); 478 if (!e2) 479 return nullptr; 480 481 e1 = pdfium::MakeUnique<CXFA_FMAdditiveExpression>( 482 line, TOKplus, std::move(e1), std::move(e2)); 483 continue; 484 case TOKminus: 485 if (!NextToken()) 486 return nullptr; 487 488 e2 = ParseMultiplicativeExpression(); 489 if (!e2) 490 return nullptr; 491 492 e1 = pdfium::MakeUnique<CXFA_FMAdditiveExpression>( 493 line, TOKminus, std::move(e1), std::move(e2)); 494 continue; 495 default: 496 break; 497 } 498 break; 499 } 500 return e1; 501 } 502 503 std::unique_ptr<CXFA_FMSimpleExpression> 504 CXFA_FMParser::ParseMultiplicativeExpression() { 505 AutoRestorer<unsigned long> restorer(&m_parse_depth); 506 if (HasError() || !IncrementParseDepthAndCheck()) 507 return nullptr; 508 509 uint32_t line = m_token->m_line_num; 510 std::unique_ptr<CXFA_FMSimpleExpression> e1 = ParseUnaryExpression(); 511 if (!e1) 512 return nullptr; 513 514 for (;;) { 515 std::unique_ptr<CXFA_FMSimpleExpression> e2; 516 switch (m_token->m_type) { 517 case TOKmul: 518 if (!NextToken()) 519 return nullptr; 520 521 e2 = ParseUnaryExpression(); 522 if (!e2) 523 return nullptr; 524 525 e1 = pdfium::MakeUnique<CXFA_FMMultiplicativeExpression>( 526 line, TOKmul, std::move(e1), std::move(e2)); 527 continue; 528 case TOKdiv: 529 if (!NextToken()) 530 return nullptr; 531 532 e2 = ParseUnaryExpression(); 533 if (!e2) 534 return nullptr; 535 536 e1 = pdfium::MakeUnique<CXFA_FMMultiplicativeExpression>( 537 line, TOKdiv, std::move(e1), std::move(e2)); 538 continue; 539 default: 540 break; 541 } 542 break; 543 } 544 return e1; 545 } 546 547 std::unique_ptr<CXFA_FMSimpleExpression> CXFA_FMParser::ParseUnaryExpression() { 548 AutoRestorer<unsigned long> restorer(&m_parse_depth); 549 if (HasError() || !IncrementParseDepthAndCheck()) 550 return nullptr; 551 552 std::unique_ptr<CXFA_FMSimpleExpression> expr; 553 uint32_t line = m_token->m_line_num; 554 switch (m_token->m_type) { 555 case TOKplus: 556 if (!NextToken()) 557 return nullptr; 558 559 expr = ParseUnaryExpression(); 560 if (!expr) 561 return nullptr; 562 563 expr = pdfium::MakeUnique<CXFA_FMPosExpression>(line, std::move(expr)); 564 break; 565 case TOKminus: 566 if (!NextToken()) 567 return nullptr; 568 569 expr = ParseUnaryExpression(); 570 if (!expr) 571 return nullptr; 572 573 expr = pdfium::MakeUnique<CXFA_FMNegExpression>(line, std::move(expr)); 574 break; 575 case TOKksnot: 576 if (!NextToken()) 577 return nullptr; 578 579 expr = ParseUnaryExpression(); 580 if (!expr) 581 return nullptr; 582 583 expr = pdfium::MakeUnique<CXFA_FMNotExpression>(line, std::move(expr)); 584 break; 585 default: 586 expr = ParsePrimaryExpression(); 587 if (!expr) 588 return nullptr; 589 break; 590 } 591 return expr; 592 } 593 594 std::unique_ptr<CXFA_FMSimpleExpression> 595 CXFA_FMParser::ParsePrimaryExpression() { 596 AutoRestorer<unsigned long> restorer(&m_parse_depth); 597 if (HasError() || !IncrementParseDepthAndCheck()) 598 return nullptr; 599 600 std::unique_ptr<CXFA_FMSimpleExpression> expr; 601 uint32_t line = m_token->m_line_num; 602 switch (m_token->m_type) { 603 case TOKnumber: 604 expr = 605 pdfium::MakeUnique<CXFA_FMNumberExpression>(line, m_token->m_string); 606 if (!NextToken()) 607 return nullptr; 608 break; 609 case TOKstring: 610 expr = 611 pdfium::MakeUnique<CXFA_FMStringExpression>(line, m_token->m_string); 612 if (!NextToken()) 613 return nullptr; 614 break; 615 case TOKidentifier: { 616 WideStringView wsIdentifier(m_token->m_string); 617 if (!NextToken()) 618 return nullptr; 619 if (m_token->m_type == TOKlbracket) { 620 std::unique_ptr<CXFA_FMSimpleExpression> s = ParseIndexExpression(); 621 if (!s) 622 return nullptr; 623 624 expr = pdfium::MakeUnique<CXFA_FMDotAccessorExpression>( 625 line, nullptr, TOKdot, wsIdentifier, std::move(s)); 626 if (!expr) 627 return nullptr; 628 if (!NextToken()) 629 return nullptr; 630 } else { 631 expr = 632 pdfium::MakeUnique<CXFA_FMIdentifierExpression>(line, wsIdentifier); 633 } 634 break; 635 } 636 case TOKif: 637 expr = pdfium::MakeUnique<CXFA_FMIdentifierExpression>(line, 638 m_token->m_string); 639 if (!expr || !NextToken()) 640 return nullptr; 641 break; 642 case TOKnull: 643 expr = pdfium::MakeUnique<CXFA_FMNullExpression>(line); 644 if (!expr || !NextToken()) 645 return nullptr; 646 break; 647 case TOKlparen: 648 expr = ParseParenExpression(); 649 if (!expr) 650 return nullptr; 651 break; 652 default: 653 m_error = true; 654 return nullptr; 655 } 656 expr = ParsePostExpression(std::move(expr)); 657 if (!expr) 658 return nullptr; 659 return expr; 660 } 661 662 std::unique_ptr<CXFA_FMSimpleExpression> CXFA_FMParser::ParsePostExpression( 663 std::unique_ptr<CXFA_FMSimpleExpression> expr) { 664 AutoRestorer<unsigned long> restorer(&m_parse_depth); 665 if (HasError() || !IncrementParseDepthAndCheck()) 666 return nullptr; 667 668 if (HasError()) 669 return nullptr; 670 671 uint32_t line = m_token->m_line_num; 672 while (1) { 673 switch (m_token->m_type) { 674 case TOKlparen: { 675 if (!NextToken()) 676 return nullptr; 677 std::vector<std::unique_ptr<CXFA_FMSimpleExpression>> expressions; 678 if (m_token->m_type != TOKrparen) { 679 while (m_token->m_type != TOKrparen) { 680 std::unique_ptr<CXFA_FMSimpleExpression> simple_expr = 681 ParseSimpleExpression(); 682 if (!simple_expr) 683 return nullptr; 684 685 expressions.push_back(std::move(simple_expr)); 686 if (m_token->m_type == TOKcomma) { 687 if (!NextToken()) 688 return nullptr; 689 } else if (m_token->m_type == TOKeof || 690 m_token->m_type == TOKreserver) { 691 break; 692 } 693 } 694 if (m_token->m_type != TOKrparen) { 695 m_error = true; 696 return nullptr; 697 } 698 } 699 expr = pdfium::MakeUnique<CXFA_FMCallExpression>( 700 line, std::move(expr), std::move(expressions), false); 701 if (!NextToken()) 702 return nullptr; 703 if (m_token->m_type != TOKlbracket) 704 continue; 705 706 std::unique_ptr<CXFA_FMSimpleExpression> s = ParseIndexExpression(); 707 if (!s) 708 return nullptr; 709 710 expr = pdfium::MakeUnique<CXFA_FMDotAccessorExpression>( 711 line, std::move(expr), TOKcall, L"", std::move(s)); 712 break; 713 } 714 case TOKdot: { 715 if (!NextToken()) 716 return nullptr; 717 if (m_token->m_type != TOKidentifier) { 718 m_error = true; 719 return nullptr; 720 } 721 WideStringView tempStr = m_token->m_string; 722 uint32_t tempLine = m_token->m_line_num; 723 if (!NextToken()) 724 return nullptr; 725 if (m_token->m_type == TOKlparen) { 726 std::unique_ptr<CXFA_FMSimpleExpression> pExpCall; 727 if (!NextToken()) 728 return nullptr; 729 730 std::vector<std::unique_ptr<CXFA_FMSimpleExpression>> expressions; 731 if (m_token->m_type != TOKrparen) { 732 while (m_token->m_type != TOKrparen) { 733 std::unique_ptr<CXFA_FMSimpleExpression> exp = 734 ParseSimpleExpression(); 735 if (!exp) 736 return nullptr; 737 738 expressions.push_back(std::move(exp)); 739 if (m_token->m_type == TOKcomma) { 740 if (!NextToken()) 741 return nullptr; 742 } else if (m_token->m_type == TOKeof || 743 m_token->m_type == TOKreserver) { 744 break; 745 } 746 } 747 if (m_token->m_type != TOKrparen) { 748 m_error = true; 749 return nullptr; 750 } 751 } 752 std::unique_ptr<CXFA_FMSimpleExpression> pIdentifier = 753 pdfium::MakeUnique<CXFA_FMIdentifierExpression>(tempLine, 754 tempStr); 755 pExpCall = pdfium::MakeUnique<CXFA_FMCallExpression>( 756 line, std::move(pIdentifier), std::move(expressions), true); 757 expr = pdfium::MakeUnique<CXFA_FMMethodCallExpression>( 758 line, std::move(expr), std::move(pExpCall)); 759 if (!NextToken()) 760 return nullptr; 761 if (m_token->m_type != TOKlbracket) 762 continue; 763 764 std::unique_ptr<CXFA_FMSimpleExpression> s = ParseIndexExpression(); 765 if (!s) 766 return nullptr; 767 768 expr = pdfium::MakeUnique<CXFA_FMDotAccessorExpression>( 769 line, std::move(expr), TOKcall, L"", std::move(s)); 770 } else if (m_token->m_type == TOKlbracket) { 771 std::unique_ptr<CXFA_FMSimpleExpression> s = ParseIndexExpression(); 772 if (!s) 773 return nullptr; 774 775 expr = pdfium::MakeUnique<CXFA_FMDotAccessorExpression>( 776 tempLine, std::move(expr), TOKdot, tempStr, std::move(s)); 777 } else { 778 std::unique_ptr<CXFA_FMSimpleExpression> s = 779 pdfium::MakeUnique<CXFA_FMIndexExpression>( 780 tempLine, ACCESSOR_NO_INDEX, nullptr, false); 781 expr = pdfium::MakeUnique<CXFA_FMDotAccessorExpression>( 782 line, std::move(expr), TOKdot, tempStr, std::move(s)); 783 continue; 784 } 785 } break; 786 case TOKdotdot: { 787 if (!NextToken()) 788 return nullptr; 789 if (m_token->m_type != TOKidentifier) { 790 m_error = true; 791 return nullptr; 792 } 793 WideStringView tempStr = m_token->m_string; 794 uint32_t tempLine = m_token->m_line_num; 795 if (!NextToken()) 796 return nullptr; 797 if (m_token->m_type == TOKlbracket) { 798 std::unique_ptr<CXFA_FMSimpleExpression> s = ParseIndexExpression(); 799 if (!s) 800 return nullptr; 801 802 expr = pdfium::MakeUnique<CXFA_FMDotDotAccessorExpression>( 803 tempLine, std::move(expr), TOKdotdot, tempStr, std::move(s)); 804 } else { 805 std::unique_ptr<CXFA_FMSimpleExpression> s = 806 pdfium::MakeUnique<CXFA_FMIndexExpression>( 807 tempLine, ACCESSOR_NO_INDEX, nullptr, false); 808 expr = pdfium::MakeUnique<CXFA_FMDotDotAccessorExpression>( 809 line, std::move(expr), TOKdotdot, tempStr, std::move(s)); 810 continue; 811 } 812 } break; 813 case TOKdotscream: { 814 if (!NextToken()) 815 return nullptr; 816 if (m_token->m_type != TOKidentifier) { 817 m_error = true; 818 return nullptr; 819 } 820 WideStringView tempStr = m_token->m_string; 821 uint32_t tempLine = m_token->m_line_num; 822 if (!NextToken()) 823 return nullptr; 824 if (m_token->m_type != TOKlbracket) { 825 std::unique_ptr<CXFA_FMSimpleExpression> s = 826 pdfium::MakeUnique<CXFA_FMIndexExpression>( 827 tempLine, ACCESSOR_NO_INDEX, nullptr, false); 828 expr = pdfium::MakeUnique<CXFA_FMDotAccessorExpression>( 829 line, std::move(expr), TOKdotscream, tempStr, std::move(s)); 830 continue; 831 } 832 std::unique_ptr<CXFA_FMSimpleExpression> s = ParseIndexExpression(); 833 if (!s) 834 return nullptr; 835 836 expr = pdfium::MakeUnique<CXFA_FMDotAccessorExpression>( 837 tempLine, std::move(expr), TOKdotscream, tempStr, std::move(s)); 838 break; 839 } 840 case TOKdotstar: { 841 std::unique_ptr<CXFA_FMSimpleExpression> s = 842 pdfium::MakeUnique<CXFA_FMIndexExpression>(line, ACCESSOR_NO_INDEX, 843 nullptr, false); 844 expr = pdfium::MakeUnique<CXFA_FMDotAccessorExpression>( 845 line, std::move(expr), TOKdotstar, L"*", std::move(s)); 846 break; 847 } 848 default: 849 return expr; 850 } 851 if (!NextToken()) 852 return nullptr; 853 } 854 return expr; 855 } 856 857 std::unique_ptr<CXFA_FMSimpleExpression> CXFA_FMParser::ParseIndexExpression() { 858 AutoRestorer<unsigned long> restorer(&m_parse_depth); 859 if (HasError() || !IncrementParseDepthAndCheck()) 860 return nullptr; 861 862 uint32_t line = m_token->m_line_num; 863 if (!NextToken()) 864 return nullptr; 865 866 std::unique_ptr<CXFA_FMSimpleExpression> s; 867 XFA_FM_AccessorIndex accessorIndex = ACCESSOR_NO_RELATIVEINDEX; 868 std::unique_ptr<CXFA_FMSimpleExpression> pExp; 869 if (m_token->m_type == TOKmul) { 870 pExp = pdfium::MakeUnique<CXFA_FMIndexExpression>(line, accessorIndex, 871 std::move(s), true); 872 if (!pExp || !NextToken()) 873 return nullptr; 874 if (m_token->m_type != TOKrbracket) { 875 m_error = true; 876 return nullptr; 877 } 878 return pExp; 879 } 880 if (m_token->m_type == TOKplus) { 881 accessorIndex = ACCESSOR_POSITIVE_INDEX; 882 if (!NextToken()) 883 return nullptr; 884 } else if (m_token->m_type == TOKminus) { 885 accessorIndex = ACCESSOR_NEGATIVE_INDEX; 886 if (!NextToken()) 887 return nullptr; 888 } 889 s = ParseSimpleExpression(); 890 if (!s) 891 return nullptr; 892 if (m_token->m_type != TOKrbracket) { 893 m_error = true; 894 return nullptr; 895 } 896 return pdfium::MakeUnique<CXFA_FMIndexExpression>(line, accessorIndex, 897 std::move(s), false); 898 } 899 900 std::unique_ptr<CXFA_FMSimpleExpression> CXFA_FMParser::ParseParenExpression() { 901 AutoRestorer<unsigned long> restorer(&m_parse_depth); 902 if (HasError() || !IncrementParseDepthAndCheck()) 903 return nullptr; 904 905 if (!CheckThenNext(TOKlparen)) 906 return nullptr; 907 908 if (m_token->m_type == TOKrparen) { 909 m_error = true; 910 return nullptr; 911 } 912 913 uint32_t line = m_token->m_line_num; 914 std::unique_ptr<CXFA_FMSimpleExpression> pExp1 = ParseLogicalOrExpression(); 915 if (!pExp1) 916 return nullptr; 917 918 int level = 1; 919 while (m_token->m_type == TOKassign) { 920 if (!NextToken()) 921 return nullptr; 922 923 std::unique_ptr<CXFA_FMSimpleExpression> pExp2 = ParseLogicalOrExpression(); 924 if (!pExp2) 925 return nullptr; 926 if (level++ == kMaxAssignmentChainLength) { 927 m_error = true; 928 return nullptr; 929 } 930 931 pExp1 = pdfium::MakeUnique<CXFA_FMAssignExpression>( 932 line, TOKassign, std::move(pExp1), std::move(pExp2)); 933 } 934 if (!CheckThenNext(TOKrparen)) 935 return nullptr; 936 return pExp1; 937 } 938 939 std::unique_ptr<CXFA_FMExpression> CXFA_FMParser::ParseBlockExpression() { 940 AutoRestorer<unsigned long> restorer(&m_parse_depth); 941 if (HasError() || !IncrementParseDepthAndCheck()) 942 return nullptr; 943 944 if (HasError()) 945 return nullptr; 946 947 uint32_t line = m_token->m_line_num; 948 std::vector<std::unique_ptr<CXFA_FMExpression>> expressions; 949 while (1) { 950 std::unique_ptr<CXFA_FMExpression> expr; 951 switch (m_token->m_type) { 952 case TOKeof: 953 case TOKendif: 954 case TOKelseif: 955 case TOKelse: 956 case TOKendwhile: 957 case TOKendfor: 958 case TOKend: 959 case TOKendfunc: 960 case TOKreserver: 961 break; 962 case TOKfunc: 963 expr = ParseFunction(); 964 if (!expr) 965 return nullptr; 966 967 expressions.push_back(std::move(expr)); 968 continue; 969 default: 970 expr = ParseExpression(); 971 if (!expr) 972 return nullptr; 973 974 expressions.push_back(std::move(expr)); 975 continue; 976 } 977 break; 978 } 979 return pdfium::MakeUnique<CXFA_FMBlockExpression>(line, 980 std::move(expressions)); 981 } 982 983 std::unique_ptr<CXFA_FMExpression> CXFA_FMParser::ParseIfExpression() { 984 AutoRestorer<unsigned long> restorer(&m_parse_depth); 985 if (HasError() || !IncrementParseDepthAndCheck()) 986 return nullptr; 987 988 uint32_t line = m_token->m_line_num; 989 const wchar_t* pStartPos = m_lexer->GetPos(); 990 if (!NextToken() || !CheckThenNext(TOKlparen)) 991 return nullptr; 992 993 std::unique_ptr<CXFA_FMSimpleExpression> pExpression; 994 while (m_token->m_type != TOKrparen) { 995 pExpression = ParseSimpleExpression(); 996 if (!pExpression) 997 return nullptr; 998 if (m_token->m_type != TOKcomma) 999 break; 1000 if (!NextToken()) 1001 return nullptr; 1002 } 1003 if (!CheckThenNext(TOKrparen)) 1004 return nullptr; 1005 if (m_token->m_type != TOKthen) { 1006 m_lexer->SetCurrentLine(line); 1007 auto pNewToken = pdfium::MakeUnique<CXFA_FMToken>(line); 1008 m_token = std::move(pNewToken); 1009 m_token->m_type = TOKidentifier; 1010 m_token->m_string = L"if"; 1011 m_lexer->SetPos(pStartPos); 1012 return ParseExpExpression(); 1013 } 1014 if (!CheckThenNext(TOKthen)) 1015 return nullptr; 1016 1017 std::unique_ptr<CXFA_FMExpression> pIfExpression = ParseBlockExpression(); 1018 if (!pIfExpression) 1019 return nullptr; 1020 1021 std::unique_ptr<CXFA_FMExpression> pElseExpression; 1022 switch (m_token->m_type) { 1023 case TOKeof: 1024 case TOKendif: 1025 if (!CheckThenNext(TOKendif)) 1026 return nullptr; 1027 break; 1028 case TOKif: 1029 pElseExpression = ParseIfExpression(); 1030 if (!pElseExpression || !CheckThenNext(TOKendif)) 1031 return nullptr; 1032 break; 1033 case TOKelseif: 1034 pElseExpression = ParseIfExpression(); 1035 if (!pElseExpression) 1036 return nullptr; 1037 break; 1038 case TOKelse: 1039 if (!NextToken()) 1040 return nullptr; 1041 pElseExpression = ParseBlockExpression(); 1042 if (!pElseExpression || !CheckThenNext(TOKendif)) 1043 return nullptr; 1044 break; 1045 default: 1046 m_error = true; 1047 return nullptr; 1048 } 1049 return pdfium::MakeUnique<CXFA_FMIfExpression>(line, std::move(pExpression), 1050 std::move(pIfExpression), 1051 std::move(pElseExpression)); 1052 } 1053 1054 std::unique_ptr<CXFA_FMExpression> CXFA_FMParser::ParseWhileExpression() { 1055 AutoRestorer<unsigned long> restorer(&m_parse_depth); 1056 if (HasError() || !IncrementParseDepthAndCheck()) 1057 return nullptr; 1058 1059 uint32_t line = m_token->m_line_num; 1060 if (!NextToken()) 1061 return nullptr; 1062 1063 std::unique_ptr<CXFA_FMSimpleExpression> pCondition = ParseParenExpression(); 1064 if (!pCondition || !CheckThenNext(TOKdo)) 1065 return nullptr; 1066 1067 std::unique_ptr<CXFA_FMExpression> pExpression = ParseBlockExpression(); 1068 if (!pExpression || !CheckThenNext(TOKendwhile)) 1069 return nullptr; 1070 return pdfium::MakeUnique<CXFA_FMWhileExpression>(line, std::move(pCondition), 1071 std::move(pExpression)); 1072 } 1073 1074 std::unique_ptr<CXFA_FMSimpleExpression> 1075 CXFA_FMParser::ParseSubassignmentInForExpression() { 1076 AutoRestorer<unsigned long> restorer(&m_parse_depth); 1077 if (HasError() || !IncrementParseDepthAndCheck()) 1078 return nullptr; 1079 1080 if (HasError()) 1081 return nullptr; 1082 1083 if (m_token->m_type != TOKidentifier) { 1084 m_error = true; 1085 return nullptr; 1086 } 1087 std::unique_ptr<CXFA_FMSimpleExpression> expr = ParseSimpleExpression(); 1088 if (!expr) 1089 return nullptr; 1090 return expr; 1091 } 1092 1093 std::unique_ptr<CXFA_FMExpression> CXFA_FMParser::ParseForExpression() { 1094 AutoRestorer<unsigned long> restorer(&m_parse_depth); 1095 if (HasError() || !IncrementParseDepthAndCheck()) 1096 return nullptr; 1097 1098 WideStringView wsVariant; 1099 uint32_t line = m_token->m_line_num; 1100 if (!NextToken()) 1101 return nullptr; 1102 if (m_token->m_type != TOKidentifier) { 1103 m_error = true; 1104 return nullptr; 1105 } 1106 1107 wsVariant = m_token->m_string; 1108 if (!NextToken()) 1109 return nullptr; 1110 if (m_token->m_type != TOKassign) { 1111 m_error = true; 1112 return nullptr; 1113 } 1114 if (!NextToken()) 1115 return nullptr; 1116 1117 std::unique_ptr<CXFA_FMSimpleExpression> pAssignment = 1118 ParseSimpleExpression(); 1119 if (!pAssignment) 1120 return nullptr; 1121 1122 int32_t iDirection = 0; 1123 if (m_token->m_type == TOKupto) { 1124 iDirection = 1; 1125 } else if (m_token->m_type == TOKdownto) { 1126 iDirection = -1; 1127 } else { 1128 m_error = true; 1129 return nullptr; 1130 } 1131 1132 if (!NextToken()) 1133 return nullptr; 1134 1135 std::unique_ptr<CXFA_FMSimpleExpression> pAccessor = ParseSimpleExpression(); 1136 if (!pAccessor) 1137 return nullptr; 1138 1139 std::unique_ptr<CXFA_FMSimpleExpression> pStep; 1140 if (m_token->m_type == TOKstep) { 1141 if (!NextToken()) 1142 return nullptr; 1143 pStep = ParseSimpleExpression(); 1144 if (!pStep) 1145 return nullptr; 1146 } 1147 if (!CheckThenNext(TOKdo)) 1148 return nullptr; 1149 1150 std::unique_ptr<CXFA_FMExpression> pList = ParseBlockExpression(); 1151 if (!pList || !CheckThenNext(TOKendfor)) 1152 return nullptr; 1153 1154 std::unique_ptr<CXFA_FMExpression> expr; 1155 if (!expr) 1156 return nullptr; 1157 return pdfium::MakeUnique<CXFA_FMForExpression>( 1158 line, wsVariant, std::move(pAssignment), std::move(pAccessor), iDirection, 1159 std::move(pStep), std::move(pList)); 1160 } 1161 1162 std::unique_ptr<CXFA_FMExpression> CXFA_FMParser::ParseForeachExpression() { 1163 AutoRestorer<unsigned long> restorer(&m_parse_depth); 1164 if (HasError() || !IncrementParseDepthAndCheck()) 1165 return nullptr; 1166 1167 if (HasError()) 1168 return nullptr; 1169 1170 std::unique_ptr<CXFA_FMExpression> expr; 1171 WideStringView wsIdentifier; 1172 std::vector<std::unique_ptr<CXFA_FMSimpleExpression>> pAccessors; 1173 std::unique_ptr<CXFA_FMExpression> pList; 1174 uint32_t line = m_token->m_line_num; 1175 if (!NextToken()) 1176 return nullptr; 1177 if (m_token->m_type != TOKidentifier) { 1178 m_error = true; 1179 return nullptr; 1180 } 1181 1182 wsIdentifier = m_token->m_string; 1183 if (!NextToken() || !CheckThenNext(TOKin) || !CheckThenNext(TOKlparen)) 1184 return nullptr; 1185 if (m_token->m_type == TOKrparen) { 1186 m_error = true; 1187 return nullptr; 1188 } 1189 1190 while (m_token->m_type != TOKrparen) { 1191 std::unique_ptr<CXFA_FMSimpleExpression> s = ParseSimpleExpression(); 1192 if (!s) 1193 return nullptr; 1194 1195 pAccessors.push_back(std::move(s)); 1196 if (m_token->m_type != TOKcomma) 1197 break; 1198 if (!NextToken()) 1199 return nullptr; 1200 } 1201 if (!CheckThenNext(TOKrparen) || !CheckThenNext(TOKdo)) 1202 return nullptr; 1203 1204 pList = ParseBlockExpression(); 1205 if (!pList || !CheckThenNext(TOKendfor)) 1206 return nullptr; 1207 return pdfium::MakeUnique<CXFA_FMForeachExpression>( 1208 line, wsIdentifier, std::move(pAccessors), std::move(pList)); 1209 } 1210 1211 std::unique_ptr<CXFA_FMExpression> CXFA_FMParser::ParseDoExpression() { 1212 AutoRestorer<unsigned long> restorer(&m_parse_depth); 1213 if (HasError() || !IncrementParseDepthAndCheck()) 1214 return nullptr; 1215 1216 if (HasError()) 1217 return nullptr; 1218 1219 uint32_t line = m_token->m_line_num; 1220 if (!NextToken()) 1221 return nullptr; 1222 1223 std::unique_ptr<CXFA_FMExpression> expr = ParseBlockExpression(); 1224 if (!expr || !CheckThenNext(TOKend)) 1225 return nullptr; 1226 return pdfium::MakeUnique<CXFA_FMDoExpression>(line, std::move(expr)); 1227 } 1228 1229 bool CXFA_FMParser::HasError() const { 1230 return m_error || m_token == nullptr; 1231 } 1232