Changeset 181726 in webkit
- Timestamp:
- Mar 18, 2015, 9:57:20 PM (11 years ago)
- Location:
- trunk
- Files:
-
- 13 edited
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/WebCore.xcodeproj/project.pbxproj (modified) (2 diffs)
-
Source/WebCore/contentextensions/CompiledContentExtension.cpp (modified) (2 diffs)
-
Source/WebCore/contentextensions/CompiledContentExtension.h (modified) (1 diff)
-
Source/WebCore/contentextensions/ContentExtensionCompiler.cpp (modified) (3 diffs)
-
Source/WebCore/contentextensions/DFA.h (modified) (1 diff)
-
Source/WebCore/contentextensions/DFABytecodeInterpreter.cpp (modified) (2 diffs)
-
Source/WebCore/contentextensions/DFABytecodeInterpreter.h (modified) (1 diff)
-
Source/WebCore/contentextensions/NFA.h (modified) (1 diff)
-
Source/WebCore/contentextensions/URLFilterParser.cpp (modified) (23 diffs)
-
Source/WebCore/contentextensions/URLFilterParser.h (modified) (1 diff)
-
Tools/ChangeLog (modified) (1 diff)
-
Tools/TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r181725 r181726 1 2015-03-18 Alex Christensen <achristensen@webkit.org> 2 3 [ContentExtensions] Prepare for compiling stylesheets of selectors to be used on every page. 4 https://bugs.webkit.org/show_bug.cgi?id=142799 5 6 Reviewed by Brady Eidson. 7 8 * WebCore.xcodeproj/project.pbxproj: 9 Make private headers to use with API tests. 10 * contentextensions/CompiledContentExtension.cpp: 11 (WebCore::ContentExtensions::CompiledContentExtension::globalDisplayNoneSelectors): 12 * contentextensions/CompiledContentExtension.h: 13 Added method to get only the selectors from the root of the DFA, which apply to all URLs. 14 * contentextensions/ContentExtensionCompiler.cpp: 15 (WebCore::ContentExtensions::compileRuleList): 16 Added checking if the trigger will match everything. 17 These actions can be put directly on the root of the DFA without adding extra epsilon transitions to the NFA. 18 * contentextensions/DFA.h: 19 (WebCore::ContentExtensions::DFA::nodeAt): 20 * contentextensions/DFABytecodeInterpreter.cpp: 21 (WebCore::ContentExtensions::DFABytecodeInterpreter::actionsFromDFARoot): 22 (WebCore::ContentExtensions::DFABytecodeInterpreter::interpret): 23 * contentextensions/DFABytecodeInterpreter.h: 24 * contentextensions/NFA.h: 25 * contentextensions/URLFilterParser.cpp: 26 (WebCore::ContentExtensions::Term::quantifier): 27 Sink terms to a vector then add nodes to NFA when finalizing after checking for regexes that match everything. 28 (WebCore::ContentExtensions::GraphBuilder::GraphBuilder): 29 (WebCore::ContentExtensions::GraphBuilder::finalize): 30 (WebCore::ContentExtensions::GraphBuilder::parseStatus): 31 (WebCore::ContentExtensions::GraphBuilder::atomPatternCharacter): 32 (WebCore::ContentExtensions::GraphBuilder::atomBuiltInCharacterClass): 33 (WebCore::ContentExtensions::GraphBuilder::quantifyAtom): 34 (WebCore::ContentExtensions::GraphBuilder::atomBackReference): 35 (WebCore::ContentExtensions::GraphBuilder::assertionBOL): 36 (WebCore::ContentExtensions::GraphBuilder::assertionWordBoundary): 37 (WebCore::ContentExtensions::GraphBuilder::atomCharacterClassAtom): 38 (WebCore::ContentExtensions::GraphBuilder::atomCharacterClassRange): 39 (WebCore::ContentExtensions::GraphBuilder::atomCharacterClassBuiltIn): 40 (WebCore::ContentExtensions::GraphBuilder::atomParentheticalAssertionBegin): 41 (WebCore::ContentExtensions::GraphBuilder::disjunction): 42 (WebCore::ContentExtensions::GraphBuilder::hasError): 43 (WebCore::ContentExtensions::GraphBuilder::fail): 44 (WebCore::ContentExtensions::GraphBuilder::sinkFloatingTermIfNecessary): 45 (WebCore::ContentExtensions::URLFilterParser::addPattern): 46 (WebCore::ContentExtensions::URLFilterParser::statusString): 47 (WebCore::ContentExtensions::GraphBuilder::errorMessage): Deleted. 48 * contentextensions/URLFilterParser.h: 49 Use an enum instead of strings for the status to avoid checking strings when we have a regex that matches everything. 50 1 51 2015-03-18 Yusuke Suzuki <utatane.tea@gmail.com> 2 52 -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r181671 r181726 994 994 2542F4DA1166C25A00E89A86 /* UserGestureIndicator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2542F4D81166C25A00E89A86 /* UserGestureIndicator.cpp */; }; 995 995 2542F4DB1166C25A00E89A86 /* UserGestureIndicator.h in Headers */ = {isa = PBXBuildFile; fileRef = 2542F4D91166C25A00E89A86 /* UserGestureIndicator.h */; settings = {ATTRIBUTES = (Private, ); }; }; 996 262391361A648CEE007251A3 /* ContentExtensionsDebugging.h in Headers */ = {isa = PBXBuildFile; fileRef = 262391351A648CEE007251A3 /* ContentExtensionsDebugging.h */; };996 262391361A648CEE007251A3 /* ContentExtensionsDebugging.h in Headers */ = {isa = PBXBuildFile; fileRef = 262391351A648CEE007251A3 /* ContentExtensionsDebugging.h */; settings = {ATTRIBUTES = (Private, ); }; }; 997 997 26255F0018878DFF0006E1FD /* UserAgentIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 26255EFF18878DFF0006E1FD /* UserAgentIOS.mm */; }; 998 998 26255F0318878E110006E1FD /* UserAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 26255F0118878E110006E1FD /* UserAgent.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 1009 1009 267726011A5B3AD9003C24DD /* NFAToDFA.h in Headers */ = {isa = PBXBuildFile; fileRef = 267725FB1A5B3AD9003C24DD /* NFAToDFA.h */; }; 1010 1010 267726041A5DF6F2003C24DD /* URLFilterParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 267726021A5DF6F2003C24DD /* URLFilterParser.cpp */; }; 1011 267726051A5DF6F2003C24DD /* URLFilterParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 267726031A5DF6F2003C24DD /* URLFilterParser.h */; };1011 267726051A5DF6F2003C24DD /* URLFilterParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 267726031A5DF6F2003C24DD /* URLFilterParser.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1012 1012 269239961505E1AA009E57FC /* JSIDBVersionChangeEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 269239921505E1AA009E57FC /* JSIDBVersionChangeEvent.h */; }; 1013 269397221A4A412F00E8349D /* NFANode.h in Headers */ = {isa = PBXBuildFile; fileRef = 269397201A4A412F00E8349D /* NFANode.h */; };1014 269397241A4A5B6400E8349D /* NFA.h in Headers */ = {isa = PBXBuildFile; fileRef = 269397231A4A5B6400E8349D /* NFA.h */; };1013 269397221A4A412F00E8349D /* NFANode.h in Headers */ = {isa = PBXBuildFile; fileRef = 269397201A4A412F00E8349D /* NFANode.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1014 269397241A4A5B6400E8349D /* NFA.h in Headers */ = {isa = PBXBuildFile; fileRef = 269397231A4A5B6400E8349D /* NFA.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1015 1015 269397261A4A5FBD00E8349D /* NFA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 269397251A4A5FBD00E8349D /* NFA.cpp */; }; 1016 1016 26AA0F9E18D2A18B00419381 /* SelectorPseudoElementTypeMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26AA0F9D18D2A18B00419381 /* SelectorPseudoElementTypeMap.cpp */; }; -
trunk/Source/WebCore/contentextensions/CompiledContentExtension.cpp
r181200 r181726 26 26 #include "config.h" 27 27 #include "CompiledContentExtension.h" 28 #include "DFABytecodeInterpreter.h" 28 29 29 30 #if ENABLE(CONTENT_EXTENSIONS) … … 36 37 } 37 38 39 Vector<String> CompiledContentExtension::globalDisplayNoneSelectors() 40 { 41 DFABytecodeInterpreter interpreter(bytecode(), bytecodeLength()); 42 DFABytecodeInterpreter::Actions actionLocations = interpreter.actionsFromDFARoot(); 43 44 Vector<Action> globalActions; 45 for (uint64_t actionLocation : actionLocations) 46 globalActions.append(Action::deserialize(actions(), actionsLength(), static_cast<unsigned>(actionLocation))); 47 48 Vector<String> selectors; 49 for (Action& action : globalActions) { 50 if (action.cssSelector().length()) 51 selectors.append(action.cssSelector()); 52 } 53 54 return selectors; 55 } 56 38 57 } // namespace ContentExtensions 39 58 } // namespace WebCore -
trunk/Source/WebCore/contentextensions/CompiledContentExtension.h
r181200 r181726 45 45 virtual const SerializedActionByte* actions() const = 0; 46 46 virtual unsigned actionsLength() const = 0; 47 Vector<String> globalDisplayNoneSelectors(); 47 48 }; 48 49 -
trunk/Source/WebCore/contentextensions/ContentExtensionCompiler.cpp
r181421 r181726 109 109 Vector<SerializedActionByte> actions; 110 110 Vector<unsigned> actionLocations = serializeActions(parsedRuleList, actions); 111 Vector<uint64_t> universalActionLocations; 111 112 112 113 NFA nfa; 113 114 URLFilterParser urlFilterParser(nfa); 115 bool nonUniversalActionSeen = false; 114 116 for (unsigned ruleIndex = 0; ruleIndex < parsedRuleList.size(); ++ruleIndex) { 115 117 const ContentExtensionRule& contentExtensionRule = parsedRuleList[ruleIndex]; … … 118 120 119 121 // High bits are used for flags. This should match how they are used in DFABytecodeCompiler::compileNode. 120 String error = urlFilterParser.addPattern(trigger.urlFilter, trigger.urlFilterIsCaseSensitive, (static_cast<uint64_t>(trigger.flags) << 32) | static_cast<uint64_t>(actionLocations[ruleIndex])); 122 uint64_t actionLocationAndFlags =(static_cast<uint64_t>(trigger.flags) << 32) | static_cast<uint64_t>(actionLocations[ruleIndex]); 123 URLFilterParser::ParseStatus status = urlFilterParser.addPattern(trigger.urlFilter, trigger.urlFilterIsCaseSensitive, actionLocationAndFlags); 121 124 122 if (!error.isNull()) { 123 dataLogF("Error while parsing %s: %s\n", trigger.urlFilter.utf8().data(), error.utf8().data()); 125 if (status == URLFilterParser::MatchesEverything) { 126 if (nonUniversalActionSeen) 127 dataLogF("Trigger matching everything found not at beginning. This may cause incorrect behavior with ignore-previous-rules"); 128 universalActionLocations.append(actionLocationAndFlags); 129 } else 130 nonUniversalActionSeen = true; 131 132 if (status != URLFilterParser::Ok && status != URLFilterParser::MatchesEverything) { 133 dataLogF("Error while parsing %s: %s\n", trigger.urlFilter.utf8().data(), URLFilterParser::statusString(status).utf8().data()); 124 134 continue; 125 135 } … … 139 149 #endif 140 150 141 const DFA dfa = NFAToDFA::convert(nfa); 151 DFA dfa = NFAToDFA::convert(nfa); 152 for (uint64_t actionLocation : universalActionLocations) 153 dfa.nodeAt(dfa.root()).actions.append(actionLocation); 142 154 143 155 #if CONTENT_EXTENSIONS_PERFORMANCE_REPORTING -
trunk/Source/WebCore/contentextensions/DFA.h
r180769 r181726 49 49 unsigned size() const { return m_nodes.size(); } 50 50 const DFANode& nodeAt(unsigned i) const { return m_nodes[i]; } 51 DFANode& nodeAt(unsigned i) { return m_nodes[i]; } 51 52 52 53 #if CONTENT_EXTENSIONS_STATE_MACHINE_DEBUGGING -
trunk/Source/WebCore/contentextensions/DFABytecodeInterpreter.cpp
r181663 r181726 41 41 return *reinterpret_cast<const IntType*>(&bytecode[index]); 42 42 } 43 43 44 DFABytecodeInterpreter::Actions DFABytecodeInterpreter::actionsFromDFARoot() 45 { 46 unsigned programCounter = 0; 47 DFABytecodeInterpreter::Actions globalActionLocations; 48 while (static_cast<DFABytecodeInstruction>(m_bytecode[programCounter]) == DFABytecodeInstruction::AppendAction) { 49 globalActionLocations.add(static_cast<uint64_t>(getBits<unsigned>(m_bytecode, m_bytecodeLength, programCounter + sizeof(DFABytecode)))); 50 programCounter += instructionSizeWithArguments(DFABytecodeInstruction::AppendAction); 51 } 52 return globalActionLocations; 53 } 54 44 55 DFABytecodeInterpreter::Actions DFABytecodeInterpreter::interpret(const CString& urlCString, uint16_t flags) 45 56 { … … 51 62 bool urlIndexIsAfterEndOfString = false; 52 63 Actions actions; 64 65 // FIXME: Skip the actions from the root once they are used through actionsFromDFARoot. Change AppendAction to AppendActions to make this faster. 53 66 54 67 // This should always terminate if interpreting correctly compiled bytecode. -
trunk/Source/WebCore/contentextensions/DFABytecodeInterpreter.h
r181421 r181726 49 49 50 50 Actions interpret(const CString&, uint16_t flags); 51 Actions actionsFromDFARoot(); 51 52 52 53 private: -
trunk/Source/WebCore/contentextensions/NFA.h
r178857 r181726 43 43 class NFA { 44 44 public: 45 NFA();45 WEBCORE_EXPORT NFA(); 46 46 unsigned root() const { return m_root; } 47 47 unsigned createNode(); -
trunk/Source/WebCore/contentextensions/URLFilterParser.cpp
r181405 r181726 33 33 #include <wtf/BitVector.h> 34 34 #include <wtf/Deque.h> 35 #include <wtf/text/CString.h> 35 36 36 37 namespace WebCore { … … 175 176 m_quantifier = quantifier; 176 177 } 178 AtomQuantifier quantifier() const { return m_quantifier; } 177 179 178 180 unsigned generateGraph(NFA& nfa, uint64_t patternId, unsigned start) const … … 429 431 , m_subtreeEnd(nfa.root()) 430 432 , m_lastPrefixTreeEntry(&prefixTreeRoot) 433 , m_parseStatus(URLFilterParser::Ok) 431 434 { 432 435 } … … 439 442 sinkFloatingTermIfNecessary(); 440 443 444 // Check to see if there are any terms without ? or *. 445 bool matchesEverything = true; 446 for (const auto& term : m_sunkTerms) { 447 if (term.quantifier() == AtomQuantifier::One || term.quantifier() == AtomQuantifier::OneOrMore) { 448 matchesEverything = false; 449 break; 450 } 451 } 452 if (matchesEverything) 453 fail(URLFilterParser::MatchesEverything); 454 455 for (const auto& term : m_sunkTerms) { 456 ASSERT(m_lastPrefixTreeEntry); 457 auto nextEntry = m_lastPrefixTreeEntry->nextPattern.find(term); 458 if (nextEntry != m_lastPrefixTreeEntry->nextPattern.end()) { 459 m_lastPrefixTreeEntry = nextEntry->value.get(); 460 m_nfa.addRuleId(m_lastPrefixTreeEntry->nfaNode, m_patternId); 461 } else { 462 std::unique_ptr<PrefixTreeEntry> nextPrefixTreeEntry = std::make_unique<PrefixTreeEntry>(); 463 464 unsigned newEnd = term.generateGraph(m_nfa, m_patternId, m_lastPrefixTreeEntry->nfaNode); 465 nextPrefixTreeEntry->nfaNode = newEnd; 466 467 auto addResult = m_lastPrefixTreeEntry->nextPattern.set(term, WTF::move(nextPrefixTreeEntry)); 468 ASSERT(addResult.isNewEntry); 469 470 if (!m_newPrefixSubtreeRoot) { 471 m_newPrefixSubtreeRoot = m_lastPrefixTreeEntry; 472 m_newPrefixStaringPoint = term; 473 } 474 475 m_lastPrefixTreeEntry = addResult.iterator->value.get(); 476 } 477 m_subtreeEnd = m_lastPrefixTreeEntry->nfaNode; 478 } 479 441 480 if (!m_openGroups.isEmpty()) { 442 fail( ASCIILiteral("The expression has unclosed groups."));481 fail(URLFilterParser::UnclosedGroups); 443 482 return; 444 483 } … … 447 486 m_nfa.setFinal(m_subtreeEnd, m_patternId); 448 487 else 449 fail( ASCIILiteral("The pattern cannot match anything."));450 } 451 452 const String& errorMessage() const453 { 454 return m_ errorMessage;488 fail(URLFilterParser::CannotMatchAnything); 489 } 490 491 URLFilterParser::ParseStatus parseStatus() const 492 { 493 return m_parseStatus; 455 494 } 456 495 … … 461 500 462 501 if (!isASCII(character)) { 463 fail( ASCIILiteral("Only ASCII characters are supported in pattern."));502 fail(URLFilterParser::NonASCII); 464 503 return; 465 504 } … … 483 522 m_floatingTerm = Term(Term::UniversalTransition); 484 523 else 485 fail( ASCIILiteral("Character class is not supported."));524 fail(URLFilterParser::UnsupportedCharacterClass); 486 525 } 487 526 … … 492 531 493 532 if (!m_floatingTerm.isValid()) 494 fail( ASCIILiteral("Quantifier without corresponding term to quantify."));533 fail(URLFilterParser::MisplacedQuantifier); 495 534 496 535 if (!minimum && maximum == 1) … … 501 540 m_floatingTerm.quantify(AtomQuantifier::OneOrMore); 502 541 else 503 fail( ASCIILiteral("Arbitrary atom repetitions are not supported."));542 fail(URLFilterParser::InvalidQuantifier); 504 543 } 505 544 506 545 void atomBackReference(unsigned) 507 546 { 508 fail( ASCIILiteral("Patterns cannot contain backreferences."));547 fail(URLFilterParser::BackReference); 509 548 } 510 549 … … 515 554 516 555 if (m_subtreeStart != m_subtreeEnd || m_floatingTerm.isValid() || !m_openGroups.isEmpty()) 517 fail( ASCIILiteral("Start of line assertion can only appear as the first term in a filter."));556 fail(URLFilterParser::MisplacedStartOfLine); 518 557 } 519 558 … … 531 570 void assertionWordBoundary(bool) 532 571 { 533 fail( ASCIILiteral("Word boundaries assertions are not supported yet."));572 fail(URLFilterParser::WordBoundary); 534 573 } 535 574 … … 550 589 return; 551 590 552 if (!isASCII(character)) { 553 fail(ASCIILiteral("Non ASCII Character in a character set.")); 554 return; 555 } 591 ASSERT(isASCII(character)); 556 592 557 593 m_floatingTerm.addCharacter(character, m_patternIsCaseSensitive); … … 563 599 return; 564 600 565 if (!a || !b || !isASCII(a) || !isASCII(b)) {566 fail(ASCIILiteral("Non ASCII Character in a character range of a character set."));567 return;568 }601 ASSERT(a); 602 ASSERT(b); 603 ASSERT(isASCII(a)); 604 ASSERT(isASCII(b)); 569 605 570 606 for (unsigned i = a; i <= b; ++i) … … 579 615 void atomCharacterClassBuiltIn(JSC::Yarr::BuiltInCharacterClassID, bool) 580 616 { 581 fail( ASCIILiteral("Builtins character class atoms are not supported yet."));617 fail(URLFilterParser::AtomCharacter); 582 618 } 583 619 … … 594 630 void atomParentheticalAssertionBegin(bool = false) 595 631 { 596 fail( ASCIILiteral("Groups are not supported yet."));632 fail(URLFilterParser::Group); 597 633 } 598 634 … … 610 646 void disjunction() 611 647 { 612 fail( ASCIILiteral("Disjunctions are not supported yet."));648 fail(URLFilterParser::Disjunction); 613 649 } 614 650 … … 616 652 bool hasError() const 617 653 { 618 return !m_errorMessage.isNull();619 } 620 621 void fail( const String& errorMessage)654 return m_parseStatus != URLFilterParser::Ok; 655 } 656 657 void fail(URLFilterParser::ParseStatus reason) 622 658 { 623 659 if (hasError()) … … 627 663 m_newPrefixSubtreeRoot->nextPattern.remove(m_newPrefixStaringPoint); 628 664 629 m_ errorMessage = errorMessage;665 m_parseStatus = reason; 630 666 } 631 667 … … 635 671 return; 636 672 637 ASSERT(m_lastPrefixTreeEntry);638 639 673 if (m_hasProcessedEndOfLineAssertion) { 640 fail( ASCIILiteral("The end of line assertion must be the last term in an expression."));674 fail(URLFilterParser::MisplacedEndOfLine); 641 675 m_floatingTerm = Term(); 642 676 return; … … 652 686 } 653 687 654 auto nextEntry = m_lastPrefixTreeEntry->nextPattern.find(m_floatingTerm); 655 if (nextEntry != m_lastPrefixTreeEntry->nextPattern.end()) { 656 m_lastPrefixTreeEntry = nextEntry->value.get(); 657 m_nfa.addRuleId(m_lastPrefixTreeEntry->nfaNode, m_patternId); 658 } else { 659 std::unique_ptr<PrefixTreeEntry> nextPrefixTreeEntry = std::make_unique<PrefixTreeEntry>(); 660 661 unsigned newEnd = m_floatingTerm.generateGraph(m_nfa, m_patternId, m_lastPrefixTreeEntry->nfaNode); 662 nextPrefixTreeEntry->nfaNode = newEnd; 663 664 auto addResult = m_lastPrefixTreeEntry->nextPattern.set(m_floatingTerm, WTF::move(nextPrefixTreeEntry)); 665 ASSERT(addResult.isNewEntry); 666 667 if (!m_newPrefixSubtreeRoot) { 668 m_newPrefixSubtreeRoot = m_lastPrefixTreeEntry; 669 m_newPrefixStaringPoint = m_floatingTerm; 670 } 671 672 m_lastPrefixTreeEntry = addResult.iterator->value.get(); 673 } 674 m_subtreeEnd = m_lastPrefixTreeEntry->nfaNode; 675 688 m_sunkTerms.append(m_floatingTerm); 676 689 m_floatingTerm = Term(); 677 ASSERT(m_lastPrefixTreeEntry);678 690 } 679 691 … … 687 699 PrefixTreeEntry* m_lastPrefixTreeEntry; 688 700 Deque<Term> m_openGroups; 701 Vector<Term> m_sunkTerms; 689 702 Term m_floatingTerm; 690 703 bool m_hasProcessedEndOfLineAssertion { false }; … … 693 706 Term m_newPrefixStaringPoint; 694 707 695 String m_errorMessage;708 URLFilterParser::ParseStatus m_parseStatus; 696 709 }; 697 710 … … 707 720 } 708 721 709 StringURLFilterParser::addPattern(const String& pattern, bool patternIsCaseSensitive, uint64_t patternId)722 URLFilterParser::ParseStatus URLFilterParser::addPattern(const String& pattern, bool patternIsCaseSensitive, uint64_t patternId) 710 723 { 711 724 if (!pattern.containsOnlyASCII()) 712 return ASCIILiteral("URLFilterParser only supports ASCII patterns.");725 return NonASCII; 713 726 ASSERT(!pattern.isEmpty()); 714 727 715 728 if (pattern.isEmpty()) 716 return ASCIILiteral("Empty pattern.");729 return EmptyPattern; 717 730 718 731 unsigned oldSize = m_nfa.graphSize(); 719 732 720 String error; 721 733 ParseStatus status = Ok; 722 734 GraphBuilder graphBuilder(m_nfa, *m_prefixTreeRoot, patternIsCaseSensitive, patternId); 723 error = String(JSC::Yarr::parse(graphBuilder, pattern, 0));735 String error = String(JSC::Yarr::parse(graphBuilder, pattern, 0)); 724 736 if (error.isNull()) 725 737 graphBuilder.finalize(); 726 727 if (error.isNull()) 728 error = graphBuilder.errorMessage(); 729 730 if (!error.isNull()) 738 else 739 status = YarrError; 740 741 if (status == Ok) 742 status = graphBuilder.parseStatus(); 743 744 if (status != Ok) 731 745 m_nfa.restoreToGraphSize(oldSize); 732 746 733 return error;747 return status; 734 748 } 735 749 750 String URLFilterParser::statusString(ParseStatus status) 751 { 752 switch (status) { 753 case Ok: 754 return "Ok"; 755 case MatchesEverything: 756 return "Matches everything."; 757 case UnclosedGroups: 758 return "The expression has unclosed groups."; 759 case CannotMatchAnything: 760 return "The pattern cannot match anything."; 761 case NonASCII: 762 return "Only ASCII characters are supported in pattern."; 763 case UnsupportedCharacterClass: 764 return "Character class is not supported."; 765 case MisplacedQuantifier: 766 return "Quantifier without corresponding term to quantify."; 767 case BackReference: 768 return "Patterns cannot contain backreferences."; 769 case MisplacedStartOfLine: 770 return "Start of line assertion can only appear as the first term in a filter."; 771 case WordBoundary: 772 return "Word boundaries assertions are not supported yet."; 773 case AtomCharacter: 774 return "Builtins character class atoms are not supported yet."; 775 case Group: 776 return "Groups are not supported yet."; 777 case Disjunction: 778 return "Disjunctions are not supported yet."; 779 case MisplacedEndOfLine: 780 return "The end of line assertion must be the last term in an expression."; 781 case EmptyPattern: 782 return "Empty pattern."; 783 case YarrError: 784 return "Internal error in YARR."; 785 case InvalidQuantifier: 786 return "Arbitrary atom repetitions are not supported."; 787 } 788 } 789 736 790 } // namespace ContentExtensions 737 791 } // namespace WebCore -
trunk/Source/WebCore/contentextensions/URLFilterParser.h
r181282 r181726 40 40 struct PrefixTreeEntry; 41 41 42 class URLFilterParser {42 class WEBCORE_EXPORT URLFilterParser { 43 43 public: 44 enum ParseStatus { 45 Ok, 46 MatchesEverything, 47 UnclosedGroups, 48 CannotMatchAnything, 49 NonASCII, 50 UnsupportedCharacterClass, 51 MisplacedQuantifier, 52 BackReference, 53 MisplacedStartOfLine, 54 WordBoundary, 55 AtomCharacter, 56 Group, 57 Disjunction, 58 MisplacedEndOfLine, 59 EmptyPattern, 60 YarrError, 61 InvalidQuantifier, 62 }; 63 static String statusString(ParseStatus); 44 64 explicit URLFilterParser(NFA&); 45 65 ~URLFilterParser(); 46 StringaddPattern(const String& pattern, bool patternIsCaseSensitive, uint64_t patternId);66 ParseStatus addPattern(const String& pattern, bool patternIsCaseSensitive, uint64_t patternId); 47 67 48 68 private: -
trunk/Tools/ChangeLog
r181717 r181726 1 2015-03-18 Alex Christensen <achristensen@webkit.org> 2 3 [ContentExtensions] Prepare for compiling stylesheets of selectors to be used on every page. 4 https://bugs.webkit.org/show_bug.cgi?id=142799 5 6 Reviewed by Brady Eidson. 7 8 * TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp: 9 (TestWebKitAPI::testPattern): 10 (TestWebKitAPI::TEST_F): 11 Start testing regex failures. 12 1 13 2015-03-18 Dhi Aurrahman <diorahman@rockybars.com> 2 14 -
trunk/Tools/TestWebKitAPI/Tests/WebCore/ContentExtensions.cpp
r181663 r181726 30 30 #include <WebCore/ContentExtensionCompiler.h> 31 31 #include <WebCore/ContentExtensionsBackend.h> 32 #include <WebCore/NFA.h> 32 33 #include <WebCore/ResourceLoadInfo.h> 33 34 #include <WebCore/URL.h> 35 #include <WebCore/URLFilterParser.h> 34 36 #include <wtf/MainThread.h> 35 37 #include <wtf/RunLoop.h> 38 #include <wtf/text/CString.h> 36 39 37 40 namespace WebCore { … … 336 339 } 337 340 341 static void testPatternStatus(const char* pattern, ContentExtensions::URLFilterParser::ParseStatus status) 342 { 343 ContentExtensions::NFA nfa; 344 ContentExtensions::URLFilterParser parser(nfa); 345 EXPECT_EQ(status, parser.addPattern(ASCIILiteral(pattern), false, 0)); 346 } 347 348 TEST_F(ContentExtensionTest, ParsingFailures) 349 { 350 testPatternStatus("a*b?.*.?[a-z]?[a-z]*", ContentExtensions::URLFilterParser::ParseStatus::MatchesEverything); 351 testPatternStatus("a*b?.*.?[a-z]?[a-z]+", ContentExtensions::URLFilterParser::ParseStatus::Ok); 352 testPatternStatus("a*b?.*.?[a-z]?[a-z]", ContentExtensions::URLFilterParser::ParseStatus::Ok); 353 // FIXME: Add regexes that cause each parse status. 354 } 355 338 356 } // namespace TestWebKitAPI
Note:
See TracChangeset
for help on using the changeset viewer.