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

Side by Side Diff: Source/core/css/CSSTokenizer-in.cpp

Issue 230173005: Fix for ASSERT and more with bad CSS input. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@CHR-1552
Patch Set: Created 6 years, 8 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
« no previous file with comments | « LayoutTests/fast/css/css-escaped-identifier.html ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 template <typename CharacterType> 356 template <typename CharacterType>
357 static inline CharacterType* checkAndSkipString(CharacterType* currentCharacter, int quote) 357 static inline CharacterType* checkAndSkipString(CharacterType* currentCharacter, int quote, bool validate)
eseidel 2014/04/09 17:47:32 Please use an enum instead of a bool. enum Valida
Daniel Bratell 2014/04/09 18:07:39 Done.
358 { 358 {
359 // Returns with 0, if string check is failed. Otherwise 359 // Returns with 0, if validate is true and string check is
360 // it returns with the following character. This is necessary 360 // failed. Otherwise it returns with the following character. This
361 // since we cannot revert escape sequences, thus strings 361 // is necessary since we cannot revert escape sequences, thus
362 // must be validated before parsing. 362 // strings must be validated before parsing.
363 while (true) { 363 while (true) {
364 if (UNLIKELY(*currentCharacter == quote)) { 364 if (UNLIKELY(*currentCharacter == quote)) {
365 // String parsing is successful. 365 // String parsing is successful.
366 return currentCharacter + 1; 366 return currentCharacter + 1;
367 } 367 }
368 if (UNLIKELY(!*currentCharacter)) { 368 if (UNLIKELY(!*currentCharacter)) {
369 // String parsing is successful up to end of input. 369 // String parsing is successful up to end of input.
370 return currentCharacter; 370 return currentCharacter;
371 } 371 }
372 if (UNLIKELY(*currentCharacter <= '\r' && (*currentCharacter == '\n' || (*currentCharacter | 0x1) == '\r'))) { 372 if (validate && UNLIKELY(*currentCharacter <= '\r' && (*currentCharacter == '\n' || (*currentCharacter | 0x1) == '\r'))) {
373 // String parsing is failed for character '\n', '\f' or '\r'. 373 // String parsing is failed for character '\n', '\f' or '\r'.
374 return 0; 374 return 0;
375 } 375 }
376 376
377 if (LIKELY(currentCharacter[0] != '\\')) { 377 if (LIKELY(currentCharacter[0] != '\\')) {
378 ++currentCharacter; 378 ++currentCharacter;
379 } else if (currentCharacter[1] == '\n' || currentCharacter[1] == '\f') { 379 } else if (currentCharacter[1] == '\n' || currentCharacter[1] == '\f') {
380 currentCharacter += 2; 380 currentCharacter += 2;
381 } else if (currentCharacter[1] == '\r') { 381 } else if (currentCharacter[1] == '\r') {
382 currentCharacter += currentCharacter[2] == '\n' ? 3 : 2; 382 currentCharacter += currentCharacter[2] == '\n' ? 3 : 2;
383 } else { 383 } else {
384 currentCharacter = checkAndSkipEscape(currentCharacter); 384 CharacterType* next = checkAndSkipEscape(currentCharacter);
385 if (!currentCharacter) 385 if (!next) {
386 return 0; 386 if (validate)
387 return 0;
388 next = currentCharacter + 1;
389 }
390 currentCharacter = next;
387 } 391 }
388 } 392 }
389 } 393 }
390 394
391 template <typename CharacterType> 395 template <typename CharacterType>
392 unsigned CSSTokenizer::parseEscape(CharacterType*& src) 396 unsigned CSSTokenizer::parseEscape(CharacterType*& src)
393 { 397 {
394 ASSERT(*src == '\\' && isCSSEscape(src[1])); 398 ASSERT(*src == '\\' && isCSSEscape(src[1]));
395 399
396 unsigned unicode = 0; 400 unsigned unicode = 0;
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 } 515 }
512 516
513 template <typename SrcCharacterType> 517 template <typename SrcCharacterType>
514 size_t CSSTokenizer::peekMaxStringLen(SrcCharacterType* src, UChar quote) 518 size_t CSSTokenizer::peekMaxStringLen(SrcCharacterType* src, UChar quote)
515 { 519 {
516 // The decoded form of a CSS string (after resolving escape 520 // The decoded form of a CSS string (after resolving escape
517 // sequences) will not contain more characters (ASCII or UTF-16 521 // sequences) will not contain more characters (ASCII or UTF-16
518 // codepoints) than the input. This code can therefore ignore 522 // codepoints) than the input. This code can therefore ignore
519 // escape sequences completely and just return the length of the 523 // escape sequences completely and just return the length of the
520 // input string (possibly including terminating quote if any). 524 // input string (possibly including terminating quote if any).
521 SrcCharacterType* end = checkAndSkipString(src, quote); 525 SrcCharacterType* end = checkAndSkipString(src, quote, false);
522 return end ? end - src : 0; 526 return end ? end - src : 0;
523 } 527 }
524 528
525 template <typename SrcCharacterType, typename DestCharacterType> 529 template <typename SrcCharacterType, typename DestCharacterType>
526 inline bool CSSTokenizer::parseStringInternal(SrcCharacterType*& src, DestCharac terType*& result, UChar quote) 530 inline bool CSSTokenizer::parseStringInternal(SrcCharacterType*& src, DestCharac terType*& result, UChar quote)
527 { 531 {
528 while (true) { 532 while (true) {
529 if (UNLIKELY(*src == quote)) { 533 if (UNLIKELY(*src == quote)) {
530 // String parsing is done. 534 // String parsing is done.
531 ++src; 535 ++src;
532 return true; 536 return true;
533 } 537 }
534 if (UNLIKELY(!*src)) { 538 if (UNLIKELY(!*src)) {
535 // String parsing is done, but don't advance pointer if at the end o f input. 539 // String parsing is done, but don't advance pointer if at the end o f input.
536 return true; 540 return true;
537 } 541 }
538 ASSERT(*src > '\r' || (*src < '\n' && *src) || *src == '\v');
539
540 if (LIKELY(src[0] != '\\')) { 542 if (LIKELY(src[0] != '\\')) {
541 *result++ = *src++; 543 *result++ = *src++;
542 } else if (src[1] == '\n' || src[1] == '\f') { 544 } else if (src[1] == '\n' || src[1] == '\f') {
543 src += 2; 545 src += 2;
544 } else if (src[1] == '\r') { 546 } else if (src[1] == '\r') {
545 src += src[2] == '\n' ? 3 : 2; 547 src += src[2] == '\n' ? 3 : 2;
546 } else { 548 } else {
547 SrcCharacterType* savedEscapeStart = src; 549 SrcCharacterType* savedEscapeStart = src;
548 unsigned unicode = parseEscape<SrcCharacterType>(src); 550 unsigned unicode = parseEscape<SrcCharacterType>(src);
549 if (unicode > 0xff && sizeof(DestCharacterType) == 1) { 551 if (unicode > 0xff && sizeof(DestCharacterType) == 1) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
582 resultString.init(start, result - start); 584 resultString.init(start, result - start);
583 } 585 }
584 586
585 template <typename CharacterType> 587 template <typename CharacterType>
586 inline bool CSSTokenizer::findURI(CharacterType*& start, CharacterType*& end, UC har& quote) 588 inline bool CSSTokenizer::findURI(CharacterType*& start, CharacterType*& end, UC har& quote)
587 { 589 {
588 start = skipWhiteSpace(currentCharacter<CharacterType>()); 590 start = skipWhiteSpace(currentCharacter<CharacterType>());
589 591
590 if (*start == '"' || *start == '\'') { 592 if (*start == '"' || *start == '\'') {
591 quote = *start++; 593 quote = *start++;
592 end = checkAndSkipString(start, quote); 594 end = checkAndSkipString(start, quote, true);
593 if (!end) 595 if (!end)
594 return false; 596 return false;
595 } else { 597 } else {
596 quote = 0; 598 quote = 0;
597 end = start; 599 end = start;
598 while (isURILetter(*end)) { 600 while (isURILetter(*end)) {
599 if (LIKELY(*end != '\\')) { 601 if (LIKELY(*end != '\\')) {
600 ++end; 602 ++end;
601 } else { 603 } else {
602 end = checkAndSkipEscape(end); 604 end = checkAndSkipEscape(end);
(...skipping 758 matching lines...) Expand 10 before | Expand all | Expand 10 after
1361 if (m_parsingMode == MediaQueryMode || m_parsingMode == SupportsMode) 1363 if (m_parsingMode == MediaQueryMode || m_parsingMode == SupportsMode)
1362 m_parsingMode = NormalMode; 1364 m_parsingMode = NormalMode;
1363 break; 1365 break;
1364 1366
1365 case CharacterEndNthChild: 1367 case CharacterEndNthChild:
1366 if (m_parsingMode == NthChildMode) 1368 if (m_parsingMode == NthChildMode)
1367 m_parsingMode = NormalMode; 1369 m_parsingMode = NormalMode;
1368 break; 1370 break;
1369 1371
1370 case CharacterQuote: 1372 case CharacterQuote:
1371 if (checkAndSkipString(currentCharacter<SrcCharacterType>(), m_token)) { 1373 if (checkAndSkipString(currentCharacter<SrcCharacterType>(), m_token, tr ue)) {
1372 ++result; 1374 ++result;
1373 parseString<SrcCharacterType>(result, yylval->string, m_token); 1375 parseString<SrcCharacterType>(result, yylval->string, m_token);
1374 m_token = STRING; 1376 m_token = STRING;
1375 } 1377 }
1376 break; 1378 break;
1377 1379
1378 case CharacterExclamationMark: { 1380 case CharacterExclamationMark: {
1379 SrcCharacterType* start = skipWhiteSpace(currentCharacter<SrcCharacterTy pe>()); 1381 SrcCharacterType* start = skipWhiteSpace(currentCharacter<SrcCharacterTy pe>());
1380 if (isEqualToCSSIdentifier(start, "important")) { 1382 if (isEqualToCSSIdentifier(start, "important")) {
1381 m_token = IMPORTANT_SYM; 1383 m_token = IMPORTANT_SYM;
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
1580 m_dataStart16[length - 1] = 0; 1582 m_dataStart16[length - 1] = 0;
1581 1583
1582 m_is8BitSource = false; 1584 m_is8BitSource = false;
1583 m_currentCharacter8 = 0; 1585 m_currentCharacter8 = 0;
1584 m_currentCharacter16 = m_dataStart16.get(); 1586 m_currentCharacter16 = m_dataStart16.get();
1585 setTokenStart<UChar>(m_currentCharacter16); 1587 setTokenStart<UChar>(m_currentCharacter16);
1586 m_lexFunc = &CSSTokenizer::realLex<UChar>; 1588 m_lexFunc = &CSSTokenizer::realLex<UChar>;
1587 } 1589 }
1588 1590
1589 } // namespace WebCore 1591 } // namespace WebCore
OLDNEW
« no previous file with comments | « LayoutTests/fast/css/css-escaped-identifier.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698