Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: compiled/filter/ElemHideBase.cpp

Issue 29595633: Issue 5870 - Implement the new ElemHideEmulation filter type (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore/
Patch Set: Reworked the strings const. String::find() from a String::value_type* Created Feb. 1, 2018, 8:36 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « compiled/filter/ElemHideBase.h ('k') | compiled/filter/Filter.cpp » ('j') | 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 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-present eyeo GmbH 3 * Copyright (C) 2006-present eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 #include <cstring> 18 #include <cstring>
19 19
20 #include "ElemHideBase.h" 20 #include "ElemHideBase.h"
21 #include "../StringScanner.h" 21 #include "../StringScanner.h"
22 22
23 // the length of a static string array
24 #define LENGTH_OF(x) ((sizeof(x) / sizeof(x[0])) - 1)
25
23 namespace 26 namespace
24 { 27 {
25 void NormalizeWhitespace(DependentString& text, String::size_type& domainsEnd, 28 void NormalizeWhitespace(DependentString& text, String::size_type& domainsEnd,
26 String::size_type& selectorStart) 29 String::size_type& selectorStart)
27 { 30 {
28 // For element hiding filters we only want to remove spaces preceding the 31 // For element hiding filters we only want to remove spaces preceding the
29 // selector part. The positions we've determined already have to be adjusted 32 // selector part. The positions we've determined already have to be adjusted
30 // accordingly. 33 // accordingly.
31 34
32 String::size_type delta = 0; 35 String::size_type delta = 0;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 case u'"': 85 case u'"':
83 case u'!': 86 case u'!':
84 return Type::UNKNOWN; 87 return Type::UNKNOWN;
85 case u' ': 88 case u' ':
86 seenSpaces = true; 89 seenSpaces = true;
87 break; 90 break;
88 } 91 }
89 } 92 }
90 93
91 seenSpaces |= scanner.skip(u' '); 94 seenSpaces |= scanner.skip(u' ');
95 bool emulation = false;
92 bool exception = scanner.skipOne(u'@'); 96 bool exception = scanner.skipOne(u'@');
93 if (exception) 97 if (exception)
94 seenSpaces |= scanner.skip(u' '); 98 seenSpaces |= scanner.skip(u' ');
99 else
100 emulation = scanner.skipOne(u'?');
95 101
96 String::value_type next = scanner.next(); 102 String::value_type next = scanner.next();
97 if (next != u'#') 103 if (next != u'#')
98 return Type::UNKNOWN; 104 return Type::UNKNOWN;
99 105
100 // Selector part 106 // Selector part
101 107
102 // Selector shouldn't be empty 108 // Selector shouldn't be empty
103 seenSpaces |= scanner.skip(u' '); 109 seenSpaces |= scanner.skip(u' ');
104 if (scanner.done()) 110 if (scanner.done())
105 return Type::UNKNOWN; 111 return Type::UNKNOWN;
106 112
107 data.mSelectorStart = scanner.position() + 1; 113 data.mSelectorStart = scanner.position() + 1;
114 data.mNeedConversion = false;
108 115
109 // We are done validating, now we can normalize whitespace and the domain part 116 // We are done validating, now we can normalize whitespace and the domain part
110 if (seenSpaces) 117 if (seenSpaces)
111 NormalizeWhitespace(text, data.mDomainsEnd, data.mSelectorStart); 118 NormalizeWhitespace(text, data.mDomainsEnd, data.mSelectorStart);
112 DependentString(text, 0, data.mDomainsEnd).toLower(); 119 DependentString(text, 0, data.mDomainsEnd).toLower();
113 120
121 // We still need to check the old syntax. It will be converted when
122 // we instantiate the filter.
123 if (!emulation &&
124 text.find(u"[-abp-properties="_str, data.mSelectorStart) != text.npos)
125 {
126 data.mNeedConversion = true;
127 emulation = !exception;
128 }
129
114 if (exception) 130 if (exception)
115 return Type::ELEMHIDEEXCEPTION; 131 return Type::ELEMHIDEEXCEPTION;
116 132
117 if (text.find(u"[-abp-properties="_str, data.mSelectorStart) != text.npos) 133 if (emulation)
118 return Type::ELEMHIDEEMULATION; 134 return Type::ELEMHIDEEMULATION;
119 135
120 return Type::ELEMHIDE; 136 return Type::ELEMHIDE;
121 } 137 }
122 138
123 namespace 139 namespace
124 { 140 {
141 static constexpr String::value_type ELEM_HIDE_DELIMITER[] = u"##";
142 static constexpr String::size_type ELEM_HIDE_DELIMITER_LEN = LENGTH_OF(ELEM_HI DE_DELIMITER);
143
144 static constexpr String::value_type ELEM_HIDE_EMULATION_DELIMITER[] = u"#?#";
145 static constexpr String::size_type ELEM_HIDE_EMULATION_DELIMITER_LEN = LENGTH_ OF(ELEM_HIDE_EMULATION_DELIMITER);
146
147 static constexpr String::value_type PROPS_SELECTOR[] = u"[-abp-properties=";
148 static constexpr String::size_type PROPS_SELECTOR_LEN = LENGTH_OF(PROPS_SELECT OR);
149
150 static constexpr String::value_type NEW_PROPS_SELECTOR[] = u":-abp-properties( ";
151 static constexpr String::size_type NEW_PROPS_SELECTOR_LEN = LENGTH_OF(NEW_PROP S_SELECTOR);
152 }
153
154 // Convert filter from the old syntax to the new.
155 OwnedString ElemHideBase::ConvertFilter(const String& text, String::size_type& a t)
156 {
157 auto selectorPos = text.find(PROPS_SELECTOR, at, PROPS_SELECTOR_LEN);
158 if (selectorPos != text.npos)
159 {
160 auto length = text.length();
161 auto properties = selectorPos + PROPS_SELECTOR_LEN;
162 String::value_type quote = 0;
163 bool escape = false;
164 String::size_type removed = 0; // how many chars we remove
165 String::size_type end = properties;
166 String::size_type quote_start = 0;
167 String::size_type quote_end = 0;
168 for (auto index = properties;
169 index < length && end == properties; index++)
170 {
171 if (escape)
172 {
173 escape = false;
174 continue;
175 }
176
177 auto c = text[index];
178 switch (c)
179 {
180 case '\\':
181 escape = true;
182 break;
183 case '"':
184 case '\'':
185 if (quote == 0)
186 {
187 quote = c;
188 quote_start = index + 1;
189 }
190 else if (quote == c)
191 {
192 // end of quoted.
193 quote = 0;
194 removed += 2;
195 quote_end = index;
196 }
197 break;
198 case ']':
199 if (quote == 0)
200 end = index + 1; // end of properties (after ])
201 break;
202 default:
203 break;
204 }
205 }
206
207 if (quote != 0)
208 quote_end = end - 1;
209 else if (quote_end <= quote_start)
210 {
211 // we likely didn't find a quoted content so we just take it as is.
212 quote_start = properties;
213 quote_end = end - 1;
214 }
215
216 // +1 for the replacement of "##" by "#?#"
217 String::size_type offset = 0;
218
219 String::size_type delimiter = text.find(ELEM_HIDE_DELIMITER, 0,
220 ELEM_HIDE_DELIMITER_LEN);
221 OwnedString converted(length + ((delimiter != text.npos) ? 1 : 0) - removed) ;
222 if (delimiter != text.npos)
223 {
224 if (delimiter >= selectorPos)
225 return OwnedString(text);
226
227 at++;
228 std::memcpy(converted.data(), text.data(),
229 delimiter * sizeof(String::value_type));
230 offset += delimiter;
231 std::memcpy(converted.data() + offset, ELEM_HIDE_EMULATION_DELIMITER,
232 ELEM_HIDE_EMULATION_DELIMITER_LEN * sizeof(String::value_type) );
233 offset += ELEM_HIDE_EMULATION_DELIMITER_LEN;
234 delimiter += ELEM_HIDE_DELIMITER_LEN;
235 // we have already parsed to past the delimiter.
236 selectorPos -= delimiter;
237 }
238 else
239 delimiter = 0;
240
241
242 std::memcpy(converted.data() + offset, text.data() + delimiter,
243 selectorPos * sizeof(String::value_type));
244 offset += selectorPos;
245
246 std::memcpy(converted.data() + offset, NEW_PROPS_SELECTOR,
247 NEW_PROPS_SELECTOR_LEN * sizeof(String::value_type));
248 offset += NEW_PROPS_SELECTOR_LEN;
249
250 std::memcpy(converted.data() + offset, text.data() + quote_start,
251 (quote_end - quote_start) * sizeof(String::value_type));
252 offset += quote_end - quote_start;
253
254 std::memcpy(converted.data() + offset, u")", sizeof(String::value_type));
255 offset++;
256
257 std::memcpy(converted.data() + offset, text.data() + end,
258 (length - end) * sizeof(String::value_type));
259 offset += (length - end) * sizeof(String::value_type);
260
261 return converted;
262 }
263
264 return OwnedString(text);
265 }
266
267 namespace
268 {
125 static constexpr String::value_type OPENING_CURLY_REPLACEMENT[] = u"\\7B "; 269 static constexpr String::value_type OPENING_CURLY_REPLACEMENT[] = u"\\7B ";
126 static constexpr String::value_type CLOSING_CURLY_REPLACEMENT[] = u"\\7D "; 270 static constexpr String::value_type CLOSING_CURLY_REPLACEMENT[] = u"\\7D ";
127 static constexpr String::size_type CURLY_REPLACEMENT_SIZE = sizeof(OPENING_CUR LY_REPLACEMENT) / sizeof(OPENING_CURLY_REPLACEMENT[0]) - 1; 271 static constexpr String::size_type CURLY_REPLACEMENT_SIZE = LENGTH_OF(OPENING_ CURLY_REPLACEMENT);
128 272
129 OwnedString EscapeCurlies(String::size_type replacementCount, 273 OwnedString EscapeCurlies(String::size_type replacementCount,
130 const DependentString& str) 274 const DependentString& str)
131 { 275 {
132 OwnedString result(str.length() + replacementCount * (CURLY_REPLACEMENT_SIZE - 1)); 276 OwnedString result(str.length() + replacementCount * (CURLY_REPLACEMENT_SIZE - 1));
133 277
134 String::value_type* current = result.data(); 278 String::value_type* current = result.data();
135 for (String::size_type i = 0; i < str.length(); i++) 279 for (String::size_type i = 0; i < str.length(); i++)
136 { 280 {
137 switch(str[i]) 281 switch(str[i])
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 if (item.second && !item.first.empty()) 325 if (item.second && !item.first.empty())
182 { 326 {
183 if (!result.empty()) 327 if (!result.empty())
184 result.append(u','); 328 result.append(u',');
185 result.append(item.first); 329 result.append(item.first);
186 } 330 }
187 } 331 }
188 } 332 }
189 return result; 333 return result;
190 } 334 }
OLDNEW
« no previous file with comments | « compiled/filter/ElemHideBase.h ('k') | compiled/filter/Filter.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld