<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[178313] trunk/Source</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/178313">178313</a></dd>
<dt>Author</dt> <dd>benjamin@webkit.org</dd>
<dt>Date</dt> <dd>2015-01-12 17:37:25 -0800 (Mon, 12 Jan 2015)</dd>
</dl>
<h3>Log Message</h3>
<pre>Add basic pattern matching support to the url filters
https://bugs.webkit.org/show_bug.cgi?id=140283
Reviewed by Andreas Kling.
Source/JavaScriptCore:
* JavaScriptCore.xcodeproj/project.pbxproj:
Make YarrParser.h private in order to use it from WebCore.
Source/WebCore:
This patch adds some basic generic pattern support for the url filters
of ContentExtensions.
Instead of writting a new parser, I re-used Gavin's parser for JavaScript
RegExp.
This patch only implements the very basic stuffs: transition on any character
and repetition.
* WebCore.xcodeproj/project.pbxproj:
* contentextensions/ContentExtensionsBackend.cpp:
(WebCore::ContentExtensions::ContentExtensionsBackend::setRuleList):
Use the new parser.
* contentextensions/DFA.cpp:
(WebCore::ContentExtensions::DFA::DFA):
(WebCore::ContentExtensions::printRange):
(WebCore::ContentExtensions::printTransition):
(WebCore::ContentExtensions::DFA::debugPrintDot):
* contentextensions/NFA.cpp:
(WebCore::ContentExtensions::printRange):
(WebCore::ContentExtensions::printTransition):
(WebCore::ContentExtensions::NFA::debugPrintDot):
The graphs generated with the extended patterns are vastly more complicated
than the old prefix matcher.
I changed the debug output to have a single link between any two nodes
instead of one per transition. This makes the graph a little more manageable.
* contentextensions/NFA.cpp:
(WebCore::ContentExtensions::NFA::addTransition):
(WebCore::ContentExtensions::NFA::addEpsilonTransition):
(WebCore::ContentExtensions::NFA::graphSize):
(WebCore::ContentExtensions::NFA::restoreToGraphSize):
* contentextensions/NFA.h:
* contentextensions/NFANode.h:
(WebCore::ContentExtensions::epsilonClosure):
The new parser can generate transitions back to the root node of index zero.
All the hash structures had to be updated to support this kind of key.
* contentextensions/NFAToDFA.cpp:
(WebCore::ContentExtensions::HashableNodeIdSetHash::hash):
Two tiny improvements:
-Don't hash zero to zero, it causes more conflicts that needed.
-The hash operation must use a commutative operation, otherwise the order
of elements can affect the hash, which is undesired for a set.
I'll improve this further later.
(WebCore::ContentExtensions::NFAToDFA::convert):
* contentextensions/URLFilterParser.cpp: Added.
(WebCore::ContentExtensions::GraphBuilder::GraphBuilder):
(WebCore::ContentExtensions::GraphBuilder::m_lastAtom):
(WebCore::ContentExtensions::GraphBuilder::finalize):
(WebCore::ContentExtensions::GraphBuilder::errorMessage):
(WebCore::ContentExtensions::GraphBuilder::atomPatternCharacter):
(WebCore::ContentExtensions::GraphBuilder::atomBuiltInCharacterClass):
(WebCore::ContentExtensions::GraphBuilder::quantifyAtom):
(WebCore::ContentExtensions::GraphBuilder::atomBackReference):
(WebCore::ContentExtensions::GraphBuilder::atomCharacterClassAtom):
(WebCore::ContentExtensions::GraphBuilder::assertionBOL):
(WebCore::ContentExtensions::GraphBuilder::assertionEOL):
(WebCore::ContentExtensions::GraphBuilder::assertionWordBoundary):
(WebCore::ContentExtensions::GraphBuilder::atomCharacterClassBegin):
(WebCore::ContentExtensions::GraphBuilder::atomCharacterClassRange):
(WebCore::ContentExtensions::GraphBuilder::atomCharacterClassBuiltIn):
(WebCore::ContentExtensions::GraphBuilder::atomCharacterClassEnd):
(WebCore::ContentExtensions::GraphBuilder::atomParenthesesSubpatternBegin):
(WebCore::ContentExtensions::GraphBuilder::atomParentheticalAssertionBegin):
(WebCore::ContentExtensions::GraphBuilder::atomParenthesesEnd):
(WebCore::ContentExtensions::GraphBuilder::disjunction):
(WebCore::ContentExtensions::GraphBuilder::hasError):
(WebCore::ContentExtensions::GraphBuilder::fail):
(WebCore::ContentExtensions::URLFilterParser::parse):
* contentextensions/URLFilterParser.h:
(WebCore::ContentExtensions::URLFilterParser::hasError):
(WebCore::ContentExtensions::URLFilterParser::errorMessage):</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCorecontentextensionsContentExtensionsBackendcpp">trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.cpp</a></li>
<li><a href="#trunkSourceWebCorecontentextensionsDFAcpp">trunk/Source/WebCore/contentextensions/DFA.cpp</a></li>
<li><a href="#trunkSourceWebCorecontentextensionsNFAcpp">trunk/Source/WebCore/contentextensions/NFA.cpp</a></li>
<li><a href="#trunkSourceWebCorecontentextensionsNFAh">trunk/Source/WebCore/contentextensions/NFA.h</a></li>
<li><a href="#trunkSourceWebCorecontentextensionsNFANodeh">trunk/Source/WebCore/contentextensions/NFANode.h</a></li>
<li><a href="#trunkSourceWebCorecontentextensionsNFAToDFAcpp">trunk/Source/WebCore/contentextensions/NFAToDFA.cpp</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCorecontentextensionsURLFilterParsercpp">trunk/Source/WebCore/contentextensions/URLFilterParser.cpp</a></li>
<li><a href="#trunkSourceWebCorecontentextensionsURLFilterParserh">trunk/Source/WebCore/contentextensions/URLFilterParser.h</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (178312 => 178313)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-01-13 01:20:35 UTC (rev 178312)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-01-13 01:37:25 UTC (rev 178313)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2015-01-12 Benjamin Poulain <benjamin@webkit.org>
+
+ Add basic pattern matching support to the url filters
+ https://bugs.webkit.org/show_bug.cgi?id=140283
+
+ Reviewed by Andreas Kling.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ Make YarrParser.h private in order to use it from WebCore.
+
</ins><span class="cx"> 2015-01-12 Geoffrey Garen <ggaren@apple.com>
</span><span class="cx">
</span><span class="cx"> Out of bounds read in IdentifierArena::makeIdentifier
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (178312 => 178313)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-01-13 01:20:35 UTC (rev 178312)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-01-13 01:37:25 UTC (rev 178313)
</span><span class="lines">@@ -968,7 +968,7 @@
</span><span class="cx">                 86704B8512DBA33700A9FE7B /* YarrInterpreter.h in Headers */ = {isa = PBXBuildFile; fileRef = 86704B7E12DBA33700A9FE7B /* YarrInterpreter.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 86704B8612DBA33700A9FE7B /* YarrJIT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86704B7F12DBA33700A9FE7B /* YarrJIT.cpp */; };
</span><span class="cx">                 86704B8712DBA33700A9FE7B /* YarrJIT.h in Headers */ = {isa = PBXBuildFile; fileRef = 86704B8012DBA33700A9FE7B /* YarrJIT.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><del>-                86704B8812DBA33700A9FE7B /* YarrParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 86704B8112DBA33700A9FE7B /* YarrParser.h */; settings = {ATTRIBUTES = (); }; };
</del><ins>+                86704B8812DBA33700A9FE7B /* YarrParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 86704B8112DBA33700A9FE7B /* YarrParser.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 86704B8912DBA33700A9FE7B /* YarrPattern.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86704B8212DBA33700A9FE7B /* YarrPattern.cpp */; };
</span><span class="cx">                 86704B8A12DBA33700A9FE7B /* YarrPattern.h in Headers */ = {isa = PBXBuildFile; fileRef = 86704B8312DBA33700A9FE7B /* YarrPattern.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 86880F1F14328BB900B08D42 /* DFGSpeculativeJIT32_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86880F1B14328BB900B08D42 /* DFGSpeculativeJIT32_64.cpp */; };
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (178312 => 178313)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-01-13 01:20:35 UTC (rev 178312)
+++ trunk/Source/WebCore/ChangeLog        2015-01-13 01:37:25 UTC (rev 178313)
</span><span class="lines">@@ -1,3 +1,87 @@
</span><ins>+2015-01-12 Benjamin Poulain <benjamin@webkit.org>
+
+ Add basic pattern matching support to the url filters
+ https://bugs.webkit.org/show_bug.cgi?id=140283
+
+ Reviewed by Andreas Kling.
+
+ This patch adds some basic generic pattern support for the url filters
+ of ContentExtensions.
+
+ Instead of writting a new parser, I re-used Gavin's parser for JavaScript
+ RegExp.
+
+ This patch only implements the very basic stuffs: transition on any character
+ and repetition.
+
+ * WebCore.xcodeproj/project.pbxproj:
+ * contentextensions/ContentExtensionsBackend.cpp:
+ (WebCore::ContentExtensions::ContentExtensionsBackend::setRuleList):
+ Use the new parser.
+
+ * contentextensions/DFA.cpp:
+ (WebCore::ContentExtensions::DFA::DFA):
+ (WebCore::ContentExtensions::printRange):
+ (WebCore::ContentExtensions::printTransition):
+ (WebCore::ContentExtensions::DFA::debugPrintDot):
+ * contentextensions/NFA.cpp:
+ (WebCore::ContentExtensions::printRange):
+ (WebCore::ContentExtensions::printTransition):
+ (WebCore::ContentExtensions::NFA::debugPrintDot):
+ The graphs generated with the extended patterns are vastly more complicated
+ than the old prefix matcher.
+ I changed the debug output to have a single link between any two nodes
+ instead of one per transition. This makes the graph a little more manageable.
+
+ * contentextensions/NFA.cpp:
+ (WebCore::ContentExtensions::NFA::addTransition):
+ (WebCore::ContentExtensions::NFA::addEpsilonTransition):
+ (WebCore::ContentExtensions::NFA::graphSize):
+ (WebCore::ContentExtensions::NFA::restoreToGraphSize):
+ * contentextensions/NFA.h:
+ * contentextensions/NFANode.h:
+ (WebCore::ContentExtensions::epsilonClosure):
+ The new parser can generate transitions back to the root node of index zero.
+ All the hash structures had to be updated to support this kind of key.
+
+ * contentextensions/NFAToDFA.cpp:
+ (WebCore::ContentExtensions::HashableNodeIdSetHash::hash):
+ Two tiny improvements:
+ -Don't hash zero to zero, it causes more conflicts that needed.
+ -The hash operation must use a commutative operation, otherwise the order
+ of elements can affect the hash, which is undesired for a set.
+ I'll improve this further later.
+
+ (WebCore::ContentExtensions::NFAToDFA::convert):
+
+ * contentextensions/URLFilterParser.cpp: Added.
+ (WebCore::ContentExtensions::GraphBuilder::GraphBuilder):
+ (WebCore::ContentExtensions::GraphBuilder::m_lastAtom):
+ (WebCore::ContentExtensions::GraphBuilder::finalize):
+ (WebCore::ContentExtensions::GraphBuilder::errorMessage):
+ (WebCore::ContentExtensions::GraphBuilder::atomPatternCharacter):
+ (WebCore::ContentExtensions::GraphBuilder::atomBuiltInCharacterClass):
+ (WebCore::ContentExtensions::GraphBuilder::quantifyAtom):
+ (WebCore::ContentExtensions::GraphBuilder::atomBackReference):
+ (WebCore::ContentExtensions::GraphBuilder::atomCharacterClassAtom):
+ (WebCore::ContentExtensions::GraphBuilder::assertionBOL):
+ (WebCore::ContentExtensions::GraphBuilder::assertionEOL):
+ (WebCore::ContentExtensions::GraphBuilder::assertionWordBoundary):
+ (WebCore::ContentExtensions::GraphBuilder::atomCharacterClassBegin):
+ (WebCore::ContentExtensions::GraphBuilder::atomCharacterClassRange):
+ (WebCore::ContentExtensions::GraphBuilder::atomCharacterClassBuiltIn):
+ (WebCore::ContentExtensions::GraphBuilder::atomCharacterClassEnd):
+ (WebCore::ContentExtensions::GraphBuilder::atomParenthesesSubpatternBegin):
+ (WebCore::ContentExtensions::GraphBuilder::atomParentheticalAssertionBegin):
+ (WebCore::ContentExtensions::GraphBuilder::atomParenthesesEnd):
+ (WebCore::ContentExtensions::GraphBuilder::disjunction):
+ (WebCore::ContentExtensions::GraphBuilder::hasError):
+ (WebCore::ContentExtensions::GraphBuilder::fail):
+ (WebCore::ContentExtensions::URLFilterParser::parse):
+ * contentextensions/URLFilterParser.h:
+ (WebCore::ContentExtensions::URLFilterParser::hasError):
+ (WebCore::ContentExtensions::URLFilterParser::errorMessage):
+
</ins><span class="cx"> 2015-01-11 Sam Weinig <sam@webkit.org>
</span><span class="cx">
</span><span class="cx"> Remove support for SharedWorkers
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (178312 => 178313)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2015-01-13 01:20:35 UTC (rev 178312)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2015-01-13 01:37:25 UTC (rev 178313)
</span><span class="lines">@@ -1027,6 +1027,8 @@
</span><span class="cx">                 267725FF1A5B3AD9003C24DD /* DFANode.h in Headers */ = {isa = PBXBuildFile; fileRef = 267725F91A5B3AD9003C24DD /* DFANode.h */; };
</span><span class="cx">                 267726001A5B3AD9003C24DD /* NFAToDFA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 267725FA1A5B3AD9003C24DD /* NFAToDFA.cpp */; };
</span><span class="cx">                 267726011A5B3AD9003C24DD /* NFAToDFA.h in Headers */ = {isa = PBXBuildFile; fileRef = 267725FB1A5B3AD9003C24DD /* NFAToDFA.h */; };
</span><ins>+                267726041A5DF6F2003C24DD /* URLFilterParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 267726021A5DF6F2003C24DD /* URLFilterParser.cpp */; };
+                267726051A5DF6F2003C24DD /* URLFilterParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 267726031A5DF6F2003C24DD /* URLFilterParser.h */; };
</ins><span class="cx">                 269239961505E1AA009E57FC /* JSIDBVersionChangeEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 269239921505E1AA009E57FC /* JSIDBVersionChangeEvent.h */; };
</span><span class="cx">                 269397211A4A412F00E8349D /* NFANode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2693971F1A4A412F00E8349D /* NFANode.cpp */; };
</span><span class="cx">                 269397221A4A412F00E8349D /* NFANode.h in Headers */ = {isa = PBXBuildFile; fileRef = 269397201A4A412F00E8349D /* NFANode.h */; };
</span><span class="lines">@@ -8023,6 +8025,8 @@
</span><span class="cx">                 267725F91A5B3AD9003C24DD /* DFANode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DFANode.h; sourceTree = "<group>"; };
</span><span class="cx">                 267725FA1A5B3AD9003C24DD /* NFAToDFA.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NFAToDFA.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 267725FB1A5B3AD9003C24DD /* NFAToDFA.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NFAToDFA.h; sourceTree = "<group>"; };
</span><ins>+                267726021A5DF6F2003C24DD /* URLFilterParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = URLFilterParser.cpp; sourceTree = "<group>"; };
+                267726031A5DF6F2003C24DD /* URLFilterParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = URLFilterParser.h; sourceTree = "<group>"; };
</ins><span class="cx">                 269239911505E1AA009E57FC /* JSIDBVersionChangeEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSIDBVersionChangeEvent.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 269239921505E1AA009E57FC /* JSIDBVersionChangeEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSIDBVersionChangeEvent.h; sourceTree = "<group>"; };
</span><span class="cx">                 2693971F1A4A412F00E8349D /* NFANode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NFANode.cpp; sourceTree = "<group>"; };
</span><span class="lines">@@ -15332,6 +15336,8 @@
</span><span class="cx">                                 269397201A4A412F00E8349D /* NFANode.h */,
</span><span class="cx">                                 267725FA1A5B3AD9003C24DD /* NFAToDFA.cpp */,
</span><span class="cx">                                 267725FB1A5B3AD9003C24DD /* NFAToDFA.h */,
</span><ins>+                                267726021A5DF6F2003C24DD /* URLFilterParser.cpp */,
+                                267726031A5DF6F2003C24DD /* URLFilterParser.h */,
</ins><span class="cx">                         );
</span><span class="cx">                         path = contentextensions;
</span><span class="cx">                         sourceTree = "<group>";
</span><span class="lines">@@ -23990,6 +23996,7 @@
</span><span class="cx">                                 85992EBE0AA5069500AC0785 /* DOMHTMLLinkElement.h in Headers */,
</span><span class="cx">                                 85E711B80AC5D5350053270F /* DOMHTMLLinkElementInternal.h in Headers */,
</span><span class="cx">                                 85ECBEF30AA7626900544F0B /* DOMHTMLMapElement.h in Headers */,
</span><ins>+                                267726051A5DF6F2003C24DD /* URLFilterParser.h in Headers */,
</ins><span class="cx">                                 85E711B90AC5D5350053270F /* DOMHTMLMapElementInternal.h in Headers */,
</span><span class="cx">                                 BC51579F0C03BBD3008BB0EE /* DOMHTMLMarqueeElement.h in Headers */,
</span><span class="cx">                                 BC5156EA0C03B741008BB0EE /* DOMHTMLMarqueeElementInternal.h in Headers */,
</span><span class="lines">@@ -28733,6 +28740,7 @@
</span><span class="cx">                                 07B5A2DB1464320A00A81ECE /* JSTextTrackList.cpp in Sources */,
</span><span class="cx">                                 07B5A30D14687D7100A81ECE /* JSTextTrackListCustom.cpp in Sources */,
</span><span class="cx">                                 E446141A0CD6826900FADA75 /* JSTimeRanges.cpp in Sources */,
</span><ins>+                                267726041A5DF6F2003C24DD /* URLFilterParser.cpp in Sources */,
</ins><span class="cx">                                 0FDA7C16188322EB00C954B5 /* JSTouch.cpp in Sources */,
</span><span class="cx">                                 0FDA7C18188322EB00C954B5 /* JSTouchEvent.cpp in Sources */,
</span><span class="cx">                                 0FDA7C1A188322EB00C954B5 /* JSTouchList.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCorecontentextensionsContentExtensionsBackendcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.cpp (178312 => 178313)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.cpp        2015-01-13 01:20:35 UTC (rev 178312)
+++ trunk/Source/WebCore/contentextensions/ContentExtensionsBackend.cpp        2015-01-13 01:37:25 UTC (rev 178313)
</span><span class="lines">@@ -31,7 +31,10 @@
</span><span class="cx"> #include "NFA.h"
</span><span class="cx"> #include "NFAToDFA.h"
</span><span class="cx"> #include "URL.h"
</span><ins>+#include "URLFilterParser.h"
+#include <wtf/DataLog.h>
</ins><span class="cx"> #include <wtf/NeverDestroyed.h>
</span><ins>+#include <wtf/text/CString.h>
</ins><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><span class="lines">@@ -55,21 +58,18 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> NFA nfa;
</span><del>- unsigned rootNode = nfa.root();
</del><span class="cx"> for (unsigned ruleIndex = 0; ruleIndex < ruleList.size(); ++ruleIndex) {
</span><span class="cx"> const ContentExtensionRule& contentExtensionRule = ruleList[ruleIndex];
</span><span class="cx"> const ContentExtensionRule::Trigger& trigger = contentExtensionRule.trigger();
</span><span class="cx"> ASSERT(trigger.urlFilter.length());
</span><span class="cx">
</span><del>- unsigned lastNode = rootNode;
</del><ins>+ URLFilterParser urlFilterParser;
+ urlFilterParser.parse(trigger.urlFilter, ruleIndex, nfa);
</ins><span class="cx">
</span><del>- for (unsigned i = 0; i < trigger.urlFilter.length(); ++i) {
- unsigned newNode = nfa.createNode(ruleIndex);
- nfa.addTransition(lastNode, newNode, trigger.urlFilter[i]);
- lastNode = newNode;
</del><ins>+ if (urlFilterParser.hasError()) {
+ dataLogF("Error while parsing %s: %s", trigger.urlFilter.utf8().data(), urlFilterParser.errorMessage().utf8().data());
+ continue;
</ins><span class="cx"> }
</span><del>-
- nfa.setFinal(lastNode);
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> // FIXME: never add a DFA that only matches the empty set.
</span></span></pre></div>
<a id="trunkSourceWebCorecontentextensionsDFAcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/contentextensions/DFA.cpp (178312 => 178313)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/contentextensions/DFA.cpp        2015-01-13 01:20:35 UTC (rev 178312)
+++ trunk/Source/WebCore/contentextensions/DFA.cpp        2015-01-13 01:37:25 UTC (rev 178313)
</span><span class="lines">@@ -43,7 +43,7 @@
</span><span class="cx"> : m_nodes(WTF::move(nodes))
</span><span class="cx"> , m_root(rootIndex)
</span><span class="cx"> {
</span><del>- ASSERT(rootIndex < nodes.size());
</del><ins>+ ASSERT(rootIndex < m_nodes.size());
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> DFA::DFA(const DFA& dfa)
</span><span class="lines">@@ -80,6 +80,62 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> #ifndef NDEBUG
</span><ins>+static void printRange(bool firstRange, char rangeStart, char rangeEnd)
+{
+ if (!firstRange)
+ dataLogF(", ");
+ if (rangeStart == rangeEnd) {
+ if (rangeStart == '"' || rangeStart == '\\')
+ dataLogF("\\%c", rangeStart);
+ else if (rangeStart >= '!' && rangeStart <= '~')
+ dataLogF("%c", rangeStart);
+ else
+ dataLogF("\\\\%d", rangeStart);
+ } else
+ dataLogF("\\\\%d-\\\\%d", rangeStart, rangeEnd);
+}
+
+static void printTransition(unsigned sourceNode, const HashMap<uint16_t, unsigned>& transitions)
+{
+ if (transitions.isEmpty())
+ return;
+
+ HashMap<unsigned, Vector<uint16_t>, DefaultHash<unsigned>::Hash, WTF::UnsignedWithZeroKeyHashTraits<unsigned>> transitionsPerTarget;
+
+ // First, we build the list of transitions coming to each target node.
+ for (const auto& transition : transitions) {
+ unsigned target = transition.value;
+ transitionsPerTarget.add(target, Vector<uint16_t>());
+
+ transitionsPerTarget.find(target)->value.append(transition.key);
+ }
+
+ // Then we go over each one an display the ranges one by one.
+ for (const auto& transitionPerTarget : transitionsPerTarget) {
+ dataLogF(" %d -> %d [label=\"", sourceNode, transitionPerTarget.key);
+
+ Vector<uint16_t> incommingCharacters = transitionPerTarget.value;
+ std::sort(incommingCharacters.begin(), incommingCharacters.end());
+
+ char rangeStart = incommingCharacters.first();
+ char rangeEnd = rangeStart;
+ bool first = true;
+ for (unsigned sortedTransitionIndex = 1; sortedTransitionIndex < incommingCharacters.size(); ++sortedTransitionIndex) {
+ char nextChar = incommingCharacters[sortedTransitionIndex];
+ if (nextChar == rangeEnd+1) {
+ rangeEnd = nextChar;
+ continue;
+ }
+ printRange(first, rangeStart, rangeEnd);
+ rangeStart = rangeEnd = nextChar;
+ first = false;
+ }
+ printRange(first, rangeStart, rangeEnd);
+
+ dataLogF("\"];\n");
+ }
+}
+
</ins><span class="cx"> void DFA::debugPrintDot() const
</span><span class="cx"> {
</span><span class="cx"> dataLogF("digraph DFA_Transitions {\n");
</span><span class="lines">@@ -117,10 +173,9 @@
</span><span class="cx"> dataLogF(" }\n");
</span><span class="cx">
</span><span class="cx"> dataLogF(" {\n");
</span><del>- for (unsigned i = 0; i < m_nodes.size(); ++i) {
- for (const auto& slot : m_nodes[i].transitions)
- dataLogF(" %d -> %d [label=\"%c\"];\n", i, slot.value, slot.key);
- }
</del><ins>+ for (unsigned i = 0; i < m_nodes.size(); ++i)
+ printTransition(i, m_nodes[i].transitions);
+
</ins><span class="cx"> dataLogF(" }\n");
</span><span class="cx"> dataLogF("}\n");
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorecontentextensionsNFAcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/contentextensions/NFA.cpp (178312 => 178313)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/contentextensions/NFA.cpp        2015-01-13 01:20:35 UTC (rev 178312)
+++ trunk/Source/WebCore/contentextensions/NFA.cpp        2015-01-13 01:37:25 UTC (rev 178313)
</span><span class="lines">@@ -53,7 +53,7 @@
</span><span class="cx"> ASSERT(to < m_nodes.size());
</span><span class="cx"> ASSERT(character);
</span><span class="cx">
</span><del>- auto addResult = m_nodes[from].transitions.add(character, HashSet<unsigned>());
</del><ins>+ auto addResult = m_nodes[from].transitions.add(character, HashSet<unsigned, DefaultHash<unsigned>::Hash, WTF::UnsignedWithZeroKeyHashTraits<unsigned>>());
</ins><span class="cx"> addResult.iterator->value.add(to);
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -62,7 +62,7 @@
</span><span class="cx"> ASSERT(from < m_nodes.size());
</span><span class="cx"> ASSERT(to < m_nodes.size());
</span><span class="cx">
</span><del>- auto addResult = m_nodes[from].transitions.add(epsilonTransitionCharacter, HashSet<unsigned>());
</del><ins>+ auto addResult = m_nodes[from].transitions.add(epsilonTransitionCharacter, HashSet<unsigned, DefaultHash<unsigned>::Hash, WTF::UnsignedWithZeroKeyHashTraits<unsigned>>());
</ins><span class="cx"> addResult.iterator->value.add(to);
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -72,7 +72,79 @@
</span><span class="cx"> m_nodes[node].isFinal = true;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+unsigned NFA::graphSize() const
+{
+ return m_nodes.size();
+}
+
+void NFA::restoreToGraphSize(unsigned size)
+{
+ ASSERT(size > 1);
+ ASSERT(size <= graphSize());
+
+ m_nodes.shrink(size);
+}
+
</ins><span class="cx"> #ifndef NDEBUG
</span><ins>+
+static void printRange(bool firstRange, uint16_t rangeStart, uint16_t rangeEnd, uint16_t epsilonTransitionCharacter)
+{
+ if (!firstRange)
+ dataLogF(", ");
+ if (rangeStart == rangeEnd) {
+ if (rangeStart == epsilonTransitionCharacter)
+ dataLogF("ɛ");
+ else if (rangeStart == '"' || rangeStart == '\\')
+ dataLogF("\\%c", rangeStart);
+ else if (rangeStart >= '!' && rangeStart <= '~')
+ dataLogF("%c", rangeStart);
+ else
+ dataLogF("\\\\%d", rangeStart);
+ } else {
+ if (rangeStart == 1 && rangeEnd == 127)
+ dataLogF("[any input]");
+ else
+ dataLogF("\\\\%d-\\\\%d", rangeStart, rangeEnd);
+ }
+}
+
+static void printTransition(unsigned sourceNode, const HashMap<uint16_t, HashSet<unsigned, DefaultHash<unsigned>::Hash, WTF::UnsignedWithZeroKeyHashTraits<unsigned>>>& transitions, uint16_t epsilonTransitionCharacter)
+{
+ HashMap<unsigned, HashSet<uint16_t>, DefaultHash<unsigned>::Hash, WTF::UnsignedWithZeroKeyHashTraits<unsigned>> transitionsPerTarget;
+
+ for (const auto& transition : transitions) {
+ for (unsigned targetNode : transition.value) {
+ transitionsPerTarget.add(targetNode, HashSet<uint16_t>());
+ transitionsPerTarget.find(targetNode)->value.add(transition.key);
+ }
+ }
+
+ for (const auto& transitionPerTarget : transitionsPerTarget) {
+ dataLogF(" %d -> %d [label=\"", sourceNode, transitionPerTarget.key);
+
+ Vector<uint16_t> incommingCharacters;
+ copyToVector(transitionPerTarget.value, incommingCharacters);
+ std::sort(incommingCharacters.begin(), incommingCharacters.end());
+
+ uint16_t rangeStart = incommingCharacters.first();
+ uint16_t rangeEnd = rangeStart;
+ bool first = true;
+ for (unsigned sortedTransitionIndex = 1; sortedTransitionIndex < incommingCharacters.size(); ++sortedTransitionIndex) {
+ uint16_t nextChar = incommingCharacters[sortedTransitionIndex];
+ if (nextChar == rangeEnd+1) {
+ rangeEnd = nextChar;
+ continue;
+ }
+ printRange(first, rangeStart, rangeEnd, epsilonTransitionCharacter);
+ rangeStart = rangeEnd = nextChar;
+ first = false;
+ }
+ printRange(first, rangeStart, rangeEnd, epsilonTransitionCharacter);
+
+ dataLogF("\"];\n");
+ }
+}
+
</ins><span class="cx"> void NFA::debugPrintDot() const
</span><span class="cx"> {
</span><span class="cx"> dataLogF("digraph NFA_Transitions {\n");
</span><span class="lines">@@ -93,16 +165,8 @@
</span><span class="cx"> dataLogF(" }\n");
</span><span class="cx">
</span><span class="cx"> dataLogF(" {\n");
</span><del>- for (unsigned i = 0; i < m_nodes.size(); ++i) {
- for (const auto& slot : m_nodes[i].transitions) {
- for (unsigned nextState : slot.value) {
- if (slot.key == epsilonTransitionCharacter)
- dataLogF(" %d -> %d [label=\"ɛ\"];\n", i, nextState);
- else
- dataLogF(" %d -> %d [label=\"%c\"];\n", i, nextState, slot.key);
- }
- }
- }
</del><ins>+ for (unsigned i = 0; i < m_nodes.size(); ++i)
+ printTransition(i, m_nodes[i].transitions, epsilonTransitionCharacter);
</ins><span class="cx"> dataLogF(" }\n");
</span><span class="cx"> dataLogF("}\n");
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCorecontentextensionsNFAh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/contentextensions/NFA.h (178312 => 178313)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/contentextensions/NFA.h        2015-01-13 01:20:35 UTC (rev 178312)
+++ trunk/Source/WebCore/contentextensions/NFA.h        2015-01-13 01:37:25 UTC (rev 178313)
</span><span class="lines">@@ -50,6 +50,9 @@
</span><span class="cx"> void addEpsilonTransition(unsigned from, unsigned to);
</span><span class="cx"> void setFinal(unsigned node);
</span><span class="cx">
</span><ins>+ unsigned graphSize() const;
+ void restoreToGraphSize(unsigned);
+
</ins><span class="cx"> #ifndef NDEBUG
</span><span class="cx"> void debugPrintDot() const;
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCorecontentextensionsNFANodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/contentextensions/NFANode.h (178312 => 178313)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/contentextensions/NFANode.h        2015-01-13 01:20:35 UTC (rev 178312)
+++ trunk/Source/WebCore/contentextensions/NFANode.h        2015-01-13 01:37:25 UTC (rev 178313)
</span><span class="lines">@@ -40,7 +40,7 @@
</span><span class="cx"> public:
</span><span class="cx"> NFANode(uint64_t ruleId);
</span><span class="cx">
</span><del>- HashMap<uint16_t, HashSet<unsigned>> transitions;
</del><ins>+ HashMap<uint16_t, HashSet<unsigned, DefaultHash<unsigned>::Hash, WTF::UnsignedWithZeroKeyHashTraits<unsigned>>> transitions;
</ins><span class="cx"> bool isFinal;
</span><span class="cx"> const uint64_t ruleId;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCorecontentextensionsNFAToDFAcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/contentextensions/NFAToDFA.cpp (178312 => 178313)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/contentextensions/NFAToDFA.cpp        2015-01-13 01:20:35 UTC (rev 178312)
+++ trunk/Source/WebCore/contentextensions/NFAToDFA.cpp        2015-01-13 01:37:25 UTC (rev 178313)
</span><span class="lines">@@ -58,7 +58,7 @@
</span><span class="cx"> const NFANode& node = graph[nodeId];
</span><span class="cx"> auto epsilonTransitionSlot = node.transitions.find(epsilonTransitionCharacter);
</span><span class="cx"> if (epsilonTransitionSlot != node.transitions.end()) {
</span><del>- const HashSet<unsigned>& targets = epsilonTransitionSlot->value;
</del><ins>+ const HashSet<unsigned, DefaultHash<unsigned>::Hash, WTF::UnsignedWithZeroKeyHashTraits<unsigned>>& targets = epsilonTransitionSlot->value;
</ins><span class="cx"> for (unsigned targetNodeId : targets) {
</span><span class="cx"> if (!outputNodeSet.contains(targetNodeId))
</span><span class="cx"> nextGenerationDiscoveredNodes.add(targetNodeId);
</span><span class="lines">@@ -148,9 +148,9 @@
</span><span class="cx"> struct HashableNodeIdSetHash {
</span><span class="cx"> static unsigned hash(const HashableNodeIdSet& p)
</span><span class="cx"> {
</span><del>- unsigned hash = 0;
</del><ins>+ unsigned hash = 4207445155;
</ins><span class="cx"> for (unsigned nodeId : p.nodeIdSet())
</span><del>- hash ^= DefaultHash<unsigned>::Hash::hash(nodeId);
</del><ins>+ hash += DefaultHash<unsigned>::Hash::hash(nodeId);
</ins><span class="cx"> return hash;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -212,7 +212,7 @@
</span><span class="cx"> do {
</span><span class="cx"> HashableNodeIdSet stateSet = unprocessedStateSets.takeAny();
</span><span class="cx">
</span><del>- ASSERT(!processedStateSets.contains(stateSet));
</del><ins>+ ASSERT(!processedStateSets.contains(stateSet.nodeIdSet()));
</ins><span class="cx"> processedStateSets.add(stateSet.nodeIdSet());
</span><span class="cx">
</span><span class="cx"> unsigned dfaNodeId = nfaToDFANodeMap.get(stateSet);
</span></span></pre></div>
<a id="trunkSourceWebCorecontentextensionsURLFilterParsercpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/contentextensions/URLFilterParser.cpp (0 => 178313)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/contentextensions/URLFilterParser.cpp         (rev 0)
+++ trunk/Source/WebCore/contentextensions/URLFilterParser.cpp        2015-01-13 01:37:25 UTC (rev 178313)
</span><span class="lines">@@ -0,0 +1,245 @@
</span><ins>+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "URLFilterParser.h"
+
+#if ENABLE(CONTENT_EXTENSIONS)
+
+#include "NFA.h"
+#include <JavaScriptCore/YarrParser.h>
+
+namespace WebCore {
+
+namespace ContentExtensions {
+
+class GraphBuilder {
+private:
+ struct BoundedSubGraph {
+ unsigned start;
+ unsigned end;
+ };
+public:
+ GraphBuilder(NFA& nfa, uint64_t patternId)
+ : m_nfa(nfa)
+ , m_patternId(patternId)
+ , m_activeGroup({ nfa.root(), nfa.root() })
+ , m_lastAtom(m_activeGroup)
+ {
+ }
+
+ void finalize()
+ {
+ if (hasError())
+ return;
+ if (m_activeGroup.start != m_activeGroup.end)
+ m_nfa.setFinal(m_activeGroup.end);
+ else
+ fail(ASCIILiteral("The pattern cannot match anything."));
+ }
+
+ const String& errorMessage() const
+ {
+ return m_errorMessage;
+ }
+
+ void atomPatternCharacter(UChar character)
+ {
+ if (isASCII(character)) {
+ fail(ASCIILiteral("Only ASCII characters are supported in pattern."));
+ return;
+ }
+
+ if (hasError())
+ return;
+
+ m_hasValidAtom = true;
+ unsigned newEnd = m_nfa.createNode(m_patternId);
+ m_nfa.addTransition(m_lastAtom.end, newEnd, static_cast<char>(character));
+ m_lastAtom.start = m_lastAtom.end;
+ m_lastAtom.end = newEnd;
+ m_activeGroup.end = m_lastAtom.end;
+ }
+
+ void atomBuiltInCharacterClass(JSC::Yarr::BuiltInCharacterClassID builtInCharacterClassID, bool inverted)
+ {
+ if (hasError())
+ return;
+
+ if (builtInCharacterClassID == JSC::Yarr::NewlineClassID && inverted) {
+ // FIXME: handle new line properly.
+ m_hasValidAtom = true;
+ unsigned newEnd = m_nfa.createNode(m_patternId);
+ for (unsigned i = 1; i < 128; ++i)
+ m_nfa.addTransition(m_lastAtom.end, newEnd, i);
+ m_lastAtom.start = m_lastAtom.end;
+ m_lastAtom.end = newEnd;
+ m_activeGroup.end = m_lastAtom.end;
+ } else
+ fail(ASCIILiteral("Character class is not supported."));
+ }
+
+ void quantifyAtom(unsigned minimum, unsigned maximum, bool)
+ {
+ if (hasError())
+ return;
+
+ ASSERT(m_hasValidAtom);
+ if (!m_hasValidAtom) {
+ fail(ASCIILiteral("Quantifier without corresponding atom to quantify."));
+ return;
+ }
+
+ if (!minimum && maximum == 1)
+ m_nfa.addEpsilonTransition(m_lastAtom.start, m_lastAtom.end);
+ else if (!minimum && maximum == JSC::Yarr::quantifyInfinite) {
+ m_nfa.addEpsilonTransition(m_lastAtom.start, m_lastAtom.end);
+ m_nfa.addEpsilonTransition(m_lastAtom.end, m_lastAtom.start);
+ } else if (minimum == 1 && maximum == JSC::Yarr::quantifyInfinite)
+ m_nfa.addEpsilonTransition(m_lastAtom.end, m_lastAtom.start);
+ else
+ fail(ASCIILiteral("Arbitrary atom repetitions are not supported."));
+ }
+
+ NO_RETURN_DUE_TO_ASSERT void atomBackReference(unsigned)
+ {
+ fail(ASCIILiteral("Patterns cannot contain backreferences."));
+ ASSERT_NOT_REACHED();
+ }
+
+ void atomCharacterClassAtom(UChar)
+ {
+ fail(ASCIILiteral("Character class atoms are not supported yet."));
+ }
+
+ void assertionBOL()
+ {
+ fail(ASCIILiteral("Line boundary assertions are not supported yet."));
+ }
+
+ void assertionEOL()
+ {
+ fail(ASCIILiteral("Line boundary assertions are not supported yet."));
+ }
+
+ void assertionWordBoundary(bool)
+ {
+ fail(ASCIILiteral("Word boundaries assertions are not supported yet."));
+ }
+
+ void atomCharacterClassBegin(bool = false)
+ {
+ fail(ASCIILiteral("Character class atoms are not supported yet."));
+ }
+
+ void atomCharacterClassRange(UChar, UChar)
+ {
+ fail(ASCIILiteral("Character class ranges are not supported yet."));
+ }
+
+ void atomCharacterClassBuiltIn(JSC::Yarr::BuiltInCharacterClassID, bool)
+ {
+ fail(ASCIILiteral("Buildins character class atoms are not supported yet."));
+ }
+
+ void atomCharacterClassEnd()
+ {
+ fail(ASCIILiteral("Character class are not supported yet."));
+ }
+
+ void atomParenthesesSubpatternBegin(bool = true)
+ {
+ fail(ASCIILiteral("Groups are not supported yet."));
+ }
+
+ void atomParentheticalAssertionBegin(bool = false)
+ {
+ fail(ASCIILiteral("Groups are not supported yet."));
+ }
+
+ void atomParenthesesEnd()
+ {
+ fail(ASCIILiteral("Groups are not supported yet."));
+ }
+
+ void disjunction()
+ {
+ fail(ASCIILiteral("Disjunctions are not supported yet."));
+ }
+
+
+private:
+ bool hasError() const
+ {
+ return !m_errorMessage.isNull();
+ }
+
+ void fail(const String& errorMessage)
+ {
+ if (hasError())
+ return;
+ m_errorMessage = errorMessage;
+ }
+
+ NFA& m_nfa;
+ const uint64_t m_patternId;
+
+ BoundedSubGraph m_activeGroup;
+
+ bool m_hasValidAtom = false;
+ BoundedSubGraph m_lastAtom;
+
+ String m_errorMessage;
+};
+
+void URLFilterParser::parse(const String& pattern, uint64_t patternId, NFA& nfa)
+{
+ if (!pattern.containsOnlyASCII())
+ m_errorMessage = ASCIILiteral("URLFilterParser only supports ASCII patterns.");
+ ASSERT(!pattern.isEmpty());
+
+ if (pattern.isEmpty())
+ return;
+
+ unsigned oldSize = nfa.graphSize();
+
+ GraphBuilder graphBuilder(nfa, patternId);
+ const char* error = JSC::Yarr::parse(graphBuilder, pattern, 0);
+ if (error)
+ m_errorMessage = String(error);
+ else
+ graphBuilder.finalize();
+
+ if (!error)
+ m_errorMessage = graphBuilder.errorMessage();
+
+ if (hasError())
+ nfa.restoreToGraphSize(oldSize);
+}
+
+} // namespace ContentExtensions
+} // namespace WebCore
+
+#endif // ENABLE(CONTENT_EXTENSIONS)
</ins></span></pre></div>
<a id="trunkSourceWebCorecontentextensionsURLFilterParserh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/contentextensions/URLFilterParser.h (0 => 178313)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/contentextensions/URLFilterParser.h         (rev 0)
+++ trunk/Source/WebCore/contentextensions/URLFilterParser.h        2015-01-13 01:37:25 UTC (rev 178313)
</span><span class="lines">@@ -0,0 +1,61 @@
</span><ins>+/*
+ * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef URLFilterParser_h
+#define URLFilterParser_h
+
+#if ENABLE(CONTENT_EXTENSIONS)
+
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+namespace ContentExtensions {
+
+class NFA;
+
+class URLFilterParser {
+public:
+ void parse(const String& pattern, uint64_t patternId, NFA&);
+
+ bool hasError() const { return !m_errorMessage.isNull(); }
+ String errorMessage() const { return m_errorMessage; }
+
+private:
+ struct BoundedSubGraph {
+ unsigned start;
+ unsigned end;
+ };
+
+ String m_errorMessage;
+};
+
+} // namespace ContentExtensions
+
+} // namespace WebCore
+
+#endif // ENABLE(CONTENT_EXTENSIONS)
+
+#endif // URLFilterParser_h
</ins></span></pre>
</div>
</div>
</body>
</html>