OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2003 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 2003 Lars Knoll (knoll@kde.org) |
3 * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) | 3 * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) |
4 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc.
All rights reserved. | 4 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc.
All rights reserved. |
5 * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> | 5 * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> |
6 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> | 6 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> |
7 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo
bile.com/) | 7 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo
bile.com/) |
8 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. | 8 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. |
9 * Copyright (C) 2012 Intel Corporation. All rights reserved. | 9 * Copyright (C) 2012 Intel Corporation. All rights reserved. |
10 * | 10 * |
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
346 return tokenLocation<UChar>(); | 346 return tokenLocation<UChar>(); |
347 } | 347 } |
348 | 348 |
349 template <typename CharacterType> | 349 template <typename CharacterType> |
350 inline bool CSSTokenizer::isIdentifierStart() | 350 inline bool CSSTokenizer::isIdentifierStart() |
351 { | 351 { |
352 // Check whether an identifier is started. | 352 // Check whether an identifier is started. |
353 return isIdentifierStartAfterDash((*currentCharacter<CharacterType>() != '-'
) ? currentCharacter<CharacterType>() : currentCharacter<CharacterType>() + 1); | 353 return isIdentifierStartAfterDash((*currentCharacter<CharacterType>() != '-'
) ? currentCharacter<CharacterType>() : currentCharacter<CharacterType>() + 1); |
354 } | 354 } |
355 | 355 |
| 356 enum CheckStringValidationMode { |
| 357 AbortIfInvalid, |
| 358 SkipInvalid |
| 359 }; |
| 360 |
356 template <typename CharacterType> | 361 template <typename CharacterType> |
357 static inline CharacterType* checkAndSkipString(CharacterType* currentCharacter,
int quote) | 362 static inline CharacterType* checkAndSkipString(CharacterType* currentCharacter,
int quote, CheckStringValidationMode mode) |
358 { | 363 { |
359 // Returns with 0, if string check is failed. Otherwise | 364 // If mode is AbortIfInvalid and the string check fails it returns |
360 // it returns with the following character. This is necessary | 365 // with 0. Otherwise it returns with a pointer to the first |
361 // since we cannot revert escape sequences, thus strings | 366 // character after the string. |
362 // must be validated before parsing. | |
363 while (true) { | 367 while (true) { |
364 if (UNLIKELY(*currentCharacter == quote)) { | 368 if (UNLIKELY(*currentCharacter == quote)) { |
365 // String parsing is successful. | 369 // String parsing is successful. |
366 return currentCharacter + 1; | 370 return currentCharacter + 1; |
367 } | 371 } |
368 if (UNLIKELY(!*currentCharacter)) { | 372 if (UNLIKELY(!*currentCharacter)) { |
369 // String parsing is successful up to end of input. | 373 // String parsing is successful up to end of input. |
370 return currentCharacter; | 374 return currentCharacter; |
371 } | 375 } |
372 if (UNLIKELY(*currentCharacter <= '\r' && (*currentCharacter == '\n' ||
(*currentCharacter | 0x1) == '\r'))) { | 376 if (mode == AbortIfInvalid && UNLIKELY(*currentCharacter <= '\r' && (*cu
rrentCharacter == '\n' || (*currentCharacter | 0x1) == '\r'))) { |
373 // String parsing is failed for character '\n', '\f' or '\r'. | 377 // String parsing is failed for character '\n', '\f' or '\r'. |
374 return 0; | 378 return 0; |
375 } | 379 } |
376 | 380 |
377 if (LIKELY(currentCharacter[0] != '\\')) { | 381 if (LIKELY(currentCharacter[0] != '\\')) { |
378 ++currentCharacter; | 382 ++currentCharacter; |
379 } else if (currentCharacter[1] == '\n' || currentCharacter[1] == '\f') { | 383 } else if (currentCharacter[1] == '\n' || currentCharacter[1] == '\f') { |
380 currentCharacter += 2; | 384 currentCharacter += 2; |
381 } else if (currentCharacter[1] == '\r') { | 385 } else if (currentCharacter[1] == '\r') { |
382 currentCharacter += currentCharacter[2] == '\n' ? 3 : 2; | 386 currentCharacter += currentCharacter[2] == '\n' ? 3 : 2; |
383 } else { | 387 } else { |
384 currentCharacter = checkAndSkipEscape(currentCharacter); | 388 CharacterType* next = checkAndSkipEscape(currentCharacter); |
385 if (!currentCharacter) | 389 if (!next) { |
386 return 0; | 390 if (mode == AbortIfInvalid) |
| 391 return 0; |
| 392 next = currentCharacter + 1; |
| 393 } |
| 394 currentCharacter = next; |
387 } | 395 } |
388 } | 396 } |
389 } | 397 } |
390 | 398 |
391 template <typename CharacterType> | 399 template <typename CharacterType> |
392 unsigned CSSTokenizer::parseEscape(CharacterType*& src) | 400 unsigned CSSTokenizer::parseEscape(CharacterType*& src) |
393 { | 401 { |
394 ASSERT(*src == '\\' && isCSSEscape(src[1])); | 402 ASSERT(*src == '\\' && isCSSEscape(src[1])); |
395 | 403 |
396 unsigned unicode = 0; | 404 unsigned unicode = 0; |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 } | 519 } |
512 | 520 |
513 template <typename SrcCharacterType> | 521 template <typename SrcCharacterType> |
514 size_t CSSTokenizer::peekMaxStringLen(SrcCharacterType* src, UChar quote) | 522 size_t CSSTokenizer::peekMaxStringLen(SrcCharacterType* src, UChar quote) |
515 { | 523 { |
516 // The decoded form of a CSS string (after resolving escape | 524 // The decoded form of a CSS string (after resolving escape |
517 // sequences) will not contain more characters (ASCII or UTF-16 | 525 // sequences) will not contain more characters (ASCII or UTF-16 |
518 // codepoints) than the input. This code can therefore ignore | 526 // codepoints) than the input. This code can therefore ignore |
519 // escape sequences completely and just return the length of the | 527 // escape sequences completely and just return the length of the |
520 // input string (possibly including terminating quote if any). | 528 // input string (possibly including terminating quote if any). |
521 SrcCharacterType* end = checkAndSkipString(src, quote); | 529 SrcCharacterType* end = checkAndSkipString(src, quote, SkipInvalid); |
522 return end ? end - src : 0; | 530 return end ? end - src : 0; |
523 } | 531 } |
524 | 532 |
525 template <typename SrcCharacterType, typename DestCharacterType> | 533 template <typename SrcCharacterType, typename DestCharacterType> |
526 inline bool CSSTokenizer::parseStringInternal(SrcCharacterType*& src, DestCharac
terType*& result, UChar quote) | 534 inline bool CSSTokenizer::parseStringInternal(SrcCharacterType*& src, DestCharac
terType*& result, UChar quote) |
527 { | 535 { |
528 while (true) { | 536 while (true) { |
529 if (UNLIKELY(*src == quote)) { | 537 if (UNLIKELY(*src == quote)) { |
530 // String parsing is done. | 538 // String parsing is done. |
531 ++src; | 539 ++src; |
532 return true; | 540 return true; |
533 } | 541 } |
534 if (UNLIKELY(!*src)) { | 542 if (UNLIKELY(!*src)) { |
535 // String parsing is done, but don't advance pointer if at the end o
f input. | 543 // String parsing is done, but don't advance pointer if at the end o
f input. |
536 return true; | 544 return true; |
537 } | 545 } |
538 ASSERT(*src > '\r' || (*src < '\n' && *src) || *src == '\v'); | |
539 | |
540 if (LIKELY(src[0] != '\\')) { | 546 if (LIKELY(src[0] != '\\')) { |
541 *result++ = *src++; | 547 *result++ = *src++; |
542 } else if (src[1] == '\n' || src[1] == '\f') { | 548 } else if (src[1] == '\n' || src[1] == '\f') { |
543 src += 2; | 549 src += 2; |
544 } else if (src[1] == '\r') { | 550 } else if (src[1] == '\r') { |
545 src += src[2] == '\n' ? 3 : 2; | 551 src += src[2] == '\n' ? 3 : 2; |
546 } else { | 552 } else { |
547 SrcCharacterType* savedEscapeStart = src; | 553 SrcCharacterType* savedEscapeStart = src; |
548 unsigned unicode = parseEscape<SrcCharacterType>(src); | 554 unsigned unicode = parseEscape<SrcCharacterType>(src); |
549 if (unicode > 0xff && sizeof(DestCharacterType) == 1) { | 555 if (unicode > 0xff && sizeof(DestCharacterType) == 1) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 resultString.init(start, result - start); | 588 resultString.init(start, result - start); |
583 } | 589 } |
584 | 590 |
585 template <typename CharacterType> | 591 template <typename CharacterType> |
586 inline bool CSSTokenizer::findURI(CharacterType*& start, CharacterType*& end, UC
har& quote) | 592 inline bool CSSTokenizer::findURI(CharacterType*& start, CharacterType*& end, UC
har& quote) |
587 { | 593 { |
588 start = skipWhiteSpace(currentCharacter<CharacterType>()); | 594 start = skipWhiteSpace(currentCharacter<CharacterType>()); |
589 | 595 |
590 if (*start == '"' || *start == '\'') { | 596 if (*start == '"' || *start == '\'') { |
591 quote = *start++; | 597 quote = *start++; |
592 end = checkAndSkipString(start, quote); | 598 end = checkAndSkipString(start, quote, AbortIfInvalid); |
593 if (!end) | 599 if (!end) |
594 return false; | 600 return false; |
595 } else { | 601 } else { |
596 quote = 0; | 602 quote = 0; |
597 end = start; | 603 end = start; |
598 while (isURILetter(*end)) { | 604 while (isURILetter(*end)) { |
599 if (LIKELY(*end != '\\')) { | 605 if (LIKELY(*end != '\\')) { |
600 ++end; | 606 ++end; |
601 } else { | 607 } else { |
602 end = checkAndSkipEscape(end); | 608 end = checkAndSkipEscape(end); |
(...skipping 758 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1361 if (m_parsingMode == MediaQueryMode || m_parsingMode == SupportsMode) | 1367 if (m_parsingMode == MediaQueryMode || m_parsingMode == SupportsMode) |
1362 m_parsingMode = NormalMode; | 1368 m_parsingMode = NormalMode; |
1363 break; | 1369 break; |
1364 | 1370 |
1365 case CharacterEndNthChild: | 1371 case CharacterEndNthChild: |
1366 if (m_parsingMode == NthChildMode) | 1372 if (m_parsingMode == NthChildMode) |
1367 m_parsingMode = NormalMode; | 1373 m_parsingMode = NormalMode; |
1368 break; | 1374 break; |
1369 | 1375 |
1370 case CharacterQuote: | 1376 case CharacterQuote: |
1371 if (checkAndSkipString(currentCharacter<SrcCharacterType>(), m_token)) { | 1377 if (checkAndSkipString(currentCharacter<SrcCharacterType>(), m_token, Ab
ortIfInvalid)) { |
1372 ++result; | 1378 ++result; |
1373 parseString<SrcCharacterType>(result, yylval->string, m_token); | 1379 parseString<SrcCharacterType>(result, yylval->string, m_token); |
1374 m_token = STRING; | 1380 m_token = STRING; |
1375 } | 1381 } |
1376 break; | 1382 break; |
1377 | 1383 |
1378 case CharacterExclamationMark: { | 1384 case CharacterExclamationMark: { |
1379 SrcCharacterType* start = skipWhiteSpace(currentCharacter<SrcCharacterTy
pe>()); | 1385 SrcCharacterType* start = skipWhiteSpace(currentCharacter<SrcCharacterTy
pe>()); |
1380 if (isEqualToCSSIdentifier(start, "important")) { | 1386 if (isEqualToCSSIdentifier(start, "important")) { |
1381 m_token = IMPORTANT_SYM; | 1387 m_token = IMPORTANT_SYM; |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1580 m_dataStart16[length - 1] = 0; | 1586 m_dataStart16[length - 1] = 0; |
1581 | 1587 |
1582 m_is8BitSource = false; | 1588 m_is8BitSource = false; |
1583 m_currentCharacter8 = 0; | 1589 m_currentCharacter8 = 0; |
1584 m_currentCharacter16 = m_dataStart16.get(); | 1590 m_currentCharacter16 = m_dataStart16.get(); |
1585 setTokenStart<UChar>(m_currentCharacter16); | 1591 setTokenStart<UChar>(m_currentCharacter16); |
1586 m_lexFunc = &CSSTokenizer::realLex<UChar>; | 1592 m_lexFunc = &CSSTokenizer::realLex<UChar>; |
1587 } | 1593 } |
1588 | 1594 |
1589 } // namespace WebCore | 1595 } // namespace WebCore |
OLD | NEW |