Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(167)

Side by Side Diff: xfa/src/fxfa/src/fm2js/xfa_lexer.cpp

Issue 1701363003: Fix some issues with CXFA_FMParse/CXFA_FMLexer infinite looping. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: delete more stuff Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 PDFium Authors. All rights reserved. 1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 6
7 #include "xfa_fm2js.h" 7 #include "xfa_fm2js.h"
8
9 namespace {
10
8 struct XFA_FMDChar { 11 struct XFA_FMDChar {
9 static const FX_WCHAR* inc(const FX_WCHAR*& p) { 12 static const FX_WCHAR* inc(const FX_WCHAR*& p) {
10 ++p; 13 ++p;
11 return p; 14 return p;
12 } 15 }
13 static const FX_WCHAR* dec(const FX_WCHAR*& p) { 16 static const FX_WCHAR* dec(const FX_WCHAR*& p) {
14 --p; 17 --p;
15 return p; 18 return p;
16 } 19 }
17 static uint16_t get(const FX_WCHAR* p) { return *p; } 20 static uint16_t get(const FX_WCHAR* p) { return *p; }
(...skipping 18 matching lines...) Expand all
36 } 39 }
37 static FX_BOOL isAlpha(const FX_WCHAR* p) { 40 static FX_BOOL isAlpha(const FX_WCHAR* p) {
38 return ((*p) <= 'z' && (*p) >= 'a') || ((*p) <= 'Z' && (*p) >= 'A'); 41 return ((*p) <= 'z' && (*p) >= 'a') || ((*p) <= 'Z' && (*p) >= 'A');
39 } 42 }
40 static FX_BOOL isAvalid(const FX_WCHAR* p, FX_BOOL flag = 0); 43 static FX_BOOL isAvalid(const FX_WCHAR* p, FX_BOOL flag = 0);
41 static FX_BOOL string2number(const FX_WCHAR* s, 44 static FX_BOOL string2number(const FX_WCHAR* s,
42 FX_DOUBLE* pValue, 45 FX_DOUBLE* pValue,
43 const FX_WCHAR*& pEnd); 46 const FX_WCHAR*& pEnd);
44 static FX_BOOL isUnicodeAlpha(uint16_t ch); 47 static FX_BOOL isUnicodeAlpha(uint16_t ch);
45 }; 48 };
49
46 inline FX_BOOL XFA_FMDChar::isAvalid(const FX_WCHAR* p, FX_BOOL flag) { 50 inline FX_BOOL XFA_FMDChar::isAvalid(const FX_WCHAR* p, FX_BOOL flag) {
47 if (*p == 0) { 51 if (*p == 0) {
48 return 1; 52 return 1;
49 } 53 }
50 if ((*p <= 0x0A && *p >= 0x09) || *p == 0x0D || 54 if ((*p <= 0x0A && *p >= 0x09) || *p == 0x0D ||
51 (*p <= 0xd7ff && *p >= 0x20) || (*p <= 0xfffd && *p >= 0xe000)) { 55 (*p <= 0xd7ff && *p >= 0x20) || (*p <= 0xfffd && *p >= 0xe000)) {
52 return 1; 56 return 1;
53 } 57 }
54 if (!flag) { 58 if (!flag) {
55 if (*p == 0x0B || *p == 0x0C) { 59 if (*p == 0x0B || *p == 0x0C) {
56 return 1; 60 return 1;
57 } 61 }
58 } 62 }
59 return 0; 63 return 0;
60 } 64 }
65
61 inline FX_BOOL XFA_FMDChar::string2number(const FX_WCHAR* s, 66 inline FX_BOOL XFA_FMDChar::string2number(const FX_WCHAR* s,
62 FX_DOUBLE* pValue, 67 FX_DOUBLE* pValue,
63 const FX_WCHAR*& pEnd) { 68 const FX_WCHAR*& pEnd) {
64 if (s) { 69 if (s) {
65 *pValue = wcstod((wchar_t*)s, (wchar_t**)&pEnd); 70 *pValue = wcstod((wchar_t*)s, (wchar_t**)&pEnd);
66 } 71 }
67 return 0; 72 return 0;
68 } 73 }
74
69 inline FX_BOOL XFA_FMDChar::isUnicodeAlpha(uint16_t ch) { 75 inline FX_BOOL XFA_FMDChar::isUnicodeAlpha(uint16_t ch) {
70 if (ch == 0 || ch == 0x0A || ch == 0x0D || ch == 0x09 || ch == 0x0B || 76 if (ch == 0 || ch == 0x0A || ch == 0x0D || ch == 0x09 || ch == 0x0B ||
71 ch == 0x0C || ch == 0x20 || ch == '.' || ch == ';' || ch == '"' || 77 ch == 0x0C || ch == 0x20 || ch == '.' || ch == ';' || ch == '"' ||
72 ch == '=' || ch == '<' || ch == '>' || ch == ',' || ch == '(' || 78 ch == '=' || ch == '<' || ch == '>' || ch == ',' || ch == '(' ||
73 ch == ')' || ch == ']' || ch == '[' || ch == '&' || ch == '|' || 79 ch == ')' || ch == ']' || ch == '[' || ch == '&' || ch == '|' ||
74 ch == '+' || ch == '-' || ch == '*' || ch == '/') { 80 ch == '+' || ch == '-' || ch == '*' || ch == '/') {
75 return FALSE; 81 return FALSE;
76 } else { 82 } else {
Tom Sepez 2016/02/18 00:39:14 nit: else after return. Or just make a boolean exp
Oliver Chang 2016/02/18 00:49:02 Done. removed the else.
77 return TRUE; 83 return TRUE;
78 } 84 }
79 } 85 }
80 static XFA_FMKeyword keyWords[] = { 86
87 XFA_FMKeyword keyWords[] = {
81 {TOKand, 0x00000026, L"&"}, 88 {TOKand, 0x00000026, L"&"},
82 {TOKlparen, 0x00000028, L"("}, 89 {TOKlparen, 0x00000028, L"("},
83 {TOKrparen, 0x00000029, L")"}, 90 {TOKrparen, 0x00000029, L")"},
84 {TOKmul, 0x0000002a, L"*"}, 91 {TOKmul, 0x0000002a, L"*"},
85 {TOKplus, 0x0000002b, L"+"}, 92 {TOKplus, 0x0000002b, L"+"},
86 {TOKcomma, 0x0000002c, L","}, 93 {TOKcomma, 0x0000002c, L","},
87 {TOKminus, 0x0000002d, L"-"}, 94 {TOKminus, 0x0000002d, L"-"},
88 {TOKdot, 0x0000002e, L"."}, 95 {TOKdot, 0x0000002e, L"."},
89 {TOKdiv, 0x0000002f, L"/"}, 96 {TOKdiv, 0x0000002f, L"/"},
90 {TOKlt, 0x0000003c, L"<"}, 97 {TOKlt, 0x0000003c, L"<"},
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 {TOKelseif, 0x78253218, L"elseif"}, 138 {TOKelseif, 0x78253218, L"elseif"},
132 {TOKwhile, 0x84229259, L"while"}, 139 {TOKwhile, 0x84229259, L"while"},
133 {TOKendfor, 0x8ab49d7e, L"endfor"}, 140 {TOKendfor, 0x8ab49d7e, L"endfor"},
134 {TOKthrow, 0x8db05c94, L"throw"}, 141 {TOKthrow, 0x8db05c94, L"throw"},
135 {TOKstep, 0xa7a7887c, L"step"}, 142 {TOKstep, 0xa7a7887c, L"step"},
136 {TOKupto, 0xb5155328, L"upto"}, 143 {TOKupto, 0xb5155328, L"upto"},
137 {TOKcontinue, 0xc0340685, L"continue"}, 144 {TOKcontinue, 0xc0340685, L"continue"},
138 {TOKfunc, 0xcdce60ec, L"func"}, 145 {TOKfunc, 0xcdce60ec, L"func"},
139 {TOKendif, 0xe0e8fee6, L"endif"}, 146 {TOKendif, 0xe0e8fee6, L"endif"},
140 }; 147 };
141 static const FX_WORD KEYWORD_START = TOKdo; 148
142 static const FX_WORD KEYWORD_END = TOKendif; 149 const FX_WORD KEYWORD_START = TOKdo;
150 const FX_WORD KEYWORD_END = TOKendif;
151
152 } // namespace
153
143 const FX_WCHAR* XFA_FM_KeywordToString(XFA_FM_TOKEN op) { 154 const FX_WCHAR* XFA_FM_KeywordToString(XFA_FM_TOKEN op) {
144 return keyWords[op].m_keword; 155 return keyWords[op].m_keword;
145 } 156 }
146 CXFA_FMToken::CXFA_FMToken() { 157
147 m_type = TOKreserver; 158 CXFA_FMToken::CXFA_FMToken() : m_type(TOKreserver), m_uLinenum(1) {}
148 m_uLinenum = 1; 159
149 m_pNext = 0; 160 CXFA_FMToken::CXFA_FMToken(FX_DWORD uLineNum)
161 : m_type(TOKreserver), m_uLinenum(uLineNum) {}
162
163 CXFA_FMLexer::CXFA_FMLexer(const CFX_WideStringC& wsFormCalc,
164 CXFA_FMErrorInfo* pErrorInfo)
165 : m_ptr(wsFormCalc.GetPtr()), m_uCurrentLine(1), m_pErrorInfo(pErrorInfo) {}
166
167 CXFA_FMToken* CXFA_FMLexer::NextToken() {
168 m_pToken.reset(Scan());
169 return m_pToken.get();
150 } 170 }
151 CXFA_FMToken::CXFA_FMToken(FX_DWORD uLineNum) { 171
152 m_type = TOKreserver;
153 m_uLinenum = uLineNum;
154 m_pNext = 0;
155 }
156 CXFA_FMToken::~CXFA_FMToken() {}
157 CXFA_FMLexer::CXFA_FMLexer(const CFX_WideStringC& wsFormCalc,
158 CXFA_FMErrorInfo* pErrorInfo) {
159 m_pScript = wsFormCalc.GetPtr();
160 m_uLength = wsFormCalc.GetLength();
161 m_uCurrentLine = 1;
162 m_ptr = m_pScript;
163 m_pToken = 0;
164 m_pErrorInfo = pErrorInfo;
165 }
166 CXFA_FMToken* CXFA_FMLexer::NextToken() {
167 CXFA_FMToken* t = 0;
168 if (!m_pToken) {
169 m_pToken = Scan();
170 } else {
171 if (m_pToken->m_pNext) {
172 t = m_pToken->m_pNext;
173 delete m_pToken;
174 m_pToken = t;
175 } else {
176 t = m_pToken;
177 m_pToken = Scan();
178 delete t;
179 }
180 }
181 return m_pToken;
182 }
183 CXFA_FMToken* CXFA_FMLexer::Scan() { 172 CXFA_FMToken* CXFA_FMLexer::Scan() {
184 uint16_t ch = 0; 173 uint16_t ch = 0;
185 CXFA_FMToken* p = new CXFA_FMToken(m_uCurrentLine); 174 CXFA_FMToken* p = new CXFA_FMToken(m_uCurrentLine);
186 if (!XFA_FMDChar::isAvalid(m_ptr)) { 175 if (!XFA_FMDChar::isAvalid(m_ptr)) {
187 ch = XFA_FMDChar::get(m_ptr); 176 ch = XFA_FMDChar::get(m_ptr);
188 Error(FMERR_UNSUPPORTED_CHAR, ch); 177 Error(FMERR_UNSUPPORTED_CHAR, ch);
189 return p; 178 return p;
190 } 179 }
191 int iRet = 0; 180 int iRet = 0;
192 while (1) { 181 while (1) {
(...skipping 17 matching lines...) Expand all
210 break; 199 break;
211 case ';': { 200 case ';': {
212 const FX_WCHAR* pTemp = 0; 201 const FX_WCHAR* pTemp = 0;
213 Comment(m_ptr, pTemp); 202 Comment(m_ptr, pTemp);
214 m_ptr = pTemp; 203 m_ptr = pTemp;
215 } break; 204 } break;
216 case '"': { 205 case '"': {
217 const FX_WCHAR* pTemp = 0; 206 const FX_WCHAR* pTemp = 0;
218 p->m_type = TOKstring; 207 p->m_type = TOKstring;
219 iRet = String(p, m_ptr, pTemp); 208 iRet = String(p, m_ptr, pTemp);
220 if (iRet) {
221 return p;
222 }
223 m_ptr = pTemp; 209 m_ptr = pTemp;
224 } 210 }
225 return p; 211 return p;
226 case '0': 212 case '0':
227 case '1': 213 case '1':
228 case '2': 214 case '2':
229 case '3': 215 case '3':
230 case '4': 216 case '4':
231 case '5': 217 case '5':
232 case '6': 218 case '6':
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 m_ptr = pTemp; 393 m_ptr = pTemp;
408 if (iRet) { 394 if (iRet) {
409 return p; 395 return p;
410 } 396 }
411 p->m_type = IsKeyword(p->m_wstring); 397 p->m_type = IsKeyword(p->m_wstring);
412 } 398 }
413 return p; 399 return p;
414 } 400 }
415 } 401 }
416 } 402 }
403
417 FX_DWORD CXFA_FMLexer::Number(CXFA_FMToken* t, 404 FX_DWORD CXFA_FMLexer::Number(CXFA_FMToken* t,
418 const FX_WCHAR* p, 405 const FX_WCHAR* p,
419 const FX_WCHAR*& pEnd) { 406 const FX_WCHAR*& pEnd) {
420 FX_DOUBLE number = 0; 407 FX_DOUBLE number = 0;
421 if (XFA_FMDChar::string2number(p, &number, pEnd)) { 408 if (XFA_FMDChar::string2number(p, &number, pEnd)) {
422 return 1; 409 return 1;
423 } 410 }
424 if (pEnd && XFA_FMDChar::isAlpha(pEnd)) { 411 if (pEnd && XFA_FMDChar::isAlpha(pEnd)) {
425 return 1; 412 return 1;
426 } 413 }
427 t->m_wstring = CFX_WideStringC(p, (pEnd - p)); 414 t->m_wstring = CFX_WideStringC(p, (pEnd - p));
428 return 0; 415 return 0;
429 } 416 }
417
430 FX_DWORD CXFA_FMLexer::String(CXFA_FMToken* t, 418 FX_DWORD CXFA_FMLexer::String(CXFA_FMToken* t,
431 const FX_WCHAR* p, 419 const FX_WCHAR* p,
432 const FX_WCHAR*& pEnd) { 420 const FX_WCHAR*& pEnd) {
433 const FX_WCHAR* pStart = p; 421 const FX_WCHAR* pStart = p;
434 uint16_t ch = 0; 422 uint16_t ch = 0;
435 XFA_FMDChar::inc(p); 423 XFA_FMDChar::inc(p);
436 ch = XFA_FMDChar::get(p); 424 ch = XFA_FMDChar::get(p);
437 while (ch) { 425 while (ch) {
438 if (!XFA_FMDChar::isAvalid(p)) { 426 if (!XFA_FMDChar::isAvalid(p)) {
439 ch = XFA_FMDChar::get(p); 427 ch = XFA_FMDChar::get(p);
(...skipping 19 matching lines...) Expand all
459 } 447 }
460 } 448 }
461 NEXT: 449 NEXT:
462 XFA_FMDChar::inc(p); 450 XFA_FMDChar::inc(p);
463 ch = XFA_FMDChar::get(p); 451 ch = XFA_FMDChar::get(p);
464 } 452 }
465 pEnd = p; 453 pEnd = p;
466 t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart)); 454 t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
467 return 0; 455 return 0;
468 } 456 }
457
469 FX_DWORD CXFA_FMLexer::Identifiers(CXFA_FMToken* t, 458 FX_DWORD CXFA_FMLexer::Identifiers(CXFA_FMToken* t,
470 const FX_WCHAR* p, 459 const FX_WCHAR* p,
471 const FX_WCHAR*& pEnd) { 460 const FX_WCHAR*& pEnd) {
472 const FX_WCHAR* pStart = p; 461 const FX_WCHAR* pStart = p;
473 uint16_t ch = 0; 462 uint16_t ch = 0;
474 ch = XFA_FMDChar::get(p); 463 ch = XFA_FMDChar::get(p);
475 XFA_FMDChar::inc(p); 464 XFA_FMDChar::inc(p);
476 if (!XFA_FMDChar::isAvalid(p)) { 465 if (!XFA_FMDChar::isAvalid(p)) {
477 pEnd = p; 466 pEnd = p;
478 t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart)); 467 t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
(...skipping 14 matching lines...) Expand all
493 } else { 482 } else {
494 pEnd = p; 483 pEnd = p;
495 t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart)); 484 t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
496 return 0; 485 return 0;
497 } 486 }
498 } 487 }
499 pEnd = p; 488 pEnd = p;
500 t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart)); 489 t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
501 return 0; 490 return 0;
502 } 491 }
492
503 void CXFA_FMLexer::Comment(const FX_WCHAR* p, const FX_WCHAR*& pEnd) { 493 void CXFA_FMLexer::Comment(const FX_WCHAR* p, const FX_WCHAR*& pEnd) {
504 unsigned ch = 0; 494 unsigned ch = 0;
505 XFA_FMDChar::inc(p); 495 XFA_FMDChar::inc(p);
506 ch = XFA_FMDChar::get(p); 496 ch = XFA_FMDChar::get(p);
507 while (ch) { 497 while (ch) {
508 if (ch == 0x0D) { 498 if (ch == 0x0D) {
509 XFA_FMDChar::inc(p); 499 XFA_FMDChar::inc(p);
510 pEnd = p; 500 pEnd = p;
511 return; 501 return;
512 } 502 }
513 if (ch == 0x0A) { 503 if (ch == 0x0A) {
514 ++m_uCurrentLine; 504 ++m_uCurrentLine;
515 XFA_FMDChar::inc(p); 505 XFA_FMDChar::inc(p);
516 pEnd = p; 506 pEnd = p;
517 return; 507 return;
518 } 508 }
519 XFA_FMDChar::inc(p); 509 XFA_FMDChar::inc(p);
520 ch = XFA_FMDChar::get(p); 510 ch = XFA_FMDChar::get(p);
521 } 511 }
522 pEnd = p; 512 pEnd = p;
523 } 513 }
514
524 XFA_FM_TOKEN CXFA_FMLexer::IsKeyword(const CFX_WideStringC& str) { 515 XFA_FM_TOKEN CXFA_FMLexer::IsKeyword(const CFX_WideStringC& str) {
525 int32_t iLength = str.GetLength(); 516 int32_t iLength = str.GetLength();
526 uint32_t uHash = FX_HashCode_String_GetW(str.GetPtr(), iLength, TRUE); 517 uint32_t uHash = FX_HashCode_String_GetW(str.GetPtr(), iLength, TRUE);
527 int32_t iStart = KEYWORD_START, iEnd = KEYWORD_END; 518 int32_t iStart = KEYWORD_START, iEnd = KEYWORD_END;
528 int32_t iMid = (iStart + iEnd) / 2; 519 int32_t iMid = (iStart + iEnd) / 2;
529 XFA_FMKeyword keyword; 520 XFA_FMKeyword keyword;
530 do { 521 do {
531 iMid = (iStart + iEnd) / 2; 522 iMid = (iStart + iEnd) / 2;
532 keyword = keyWords[iMid]; 523 keyword = keyWords[iMid];
533 if (uHash == keyword.m_uHash) { 524 if (uHash == keyword.m_uHash) {
534 return keyword.m_type; 525 return keyword.m_type;
535 } else if (uHash < keyword.m_uHash) { 526 } else if (uHash < keyword.m_uHash) {
536 iEnd = iMid - 1; 527 iEnd = iMid - 1;
537 } else { 528 } else {
538 iStart = iMid + 1; 529 iStart = iMid + 1;
539 } 530 }
540 } while (iStart <= iEnd); 531 } while (iStart <= iEnd);
541 return TOKidentifier; 532 return TOKidentifier;
542 } 533 }
543 CXFA_FMLexer::~CXFA_FMLexer() { 534
544 m_pScript = 0;
545 m_ptr = m_pScript;
546 if (m_pToken) {
547 CXFA_FMToken* t1 = m_pToken;
548 CXFA_FMToken* t2 = t1->m_pNext;
549 while (t2) {
550 delete t1;
551 t1 = t2;
552 t2 = t2->m_pNext;
553 }
554 delete m_pToken;
555 m_pToken = 0;
556 }
557 m_pErrorInfo = 0;
558 }
559 void CXFA_FMLexer::Error(XFA_FM_ERRMSG msg, ...) { 535 void CXFA_FMLexer::Error(XFA_FM_ERRMSG msg, ...) {
560 m_pErrorInfo->linenum = m_uCurrentLine; 536 m_pErrorInfo->linenum = m_uCurrentLine;
561 const FX_WCHAR* lpMessageInfo = XFA_FM_ErrorMsg(msg); 537 const FX_WCHAR* lpMessageInfo = XFA_FM_ErrorMsg(msg);
562 va_list ap; 538 va_list ap;
563 va_start(ap, msg); 539 va_start(ap, msg);
564 m_pErrorInfo->message.FormatV(lpMessageInfo, ap); 540 m_pErrorInfo->message.FormatV(lpMessageInfo, ap);
565 va_end(ap); 541 va_end(ap);
566 } 542 }
543
567 FX_BOOL CXFA_FMLexer::HasError() const { 544 FX_BOOL CXFA_FMLexer::HasError() const {
568 if (m_pErrorInfo->message.IsEmpty()) { 545 if (m_pErrorInfo->message.IsEmpty()) {
569 return FALSE; 546 return FALSE;
570 } 547 }
571 return TRUE; 548 return TRUE;
572 } 549 }
OLDNEW
« xfa/src/fxfa/src/fm2js/xfa_lexer.h ('K') | « xfa/src/fxfa/src/fm2js/xfa_lexer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698