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

Delta Between Two Patch Sets: compiled/filter/ElemHideBase.cpp

Issue 29595633: Issue 5870 - Implement the new ElemHideEmulation filter type (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore/
Left Patch Set: Added missing ABP_NS macros Created Feb. 9, 2018, 8:34 p.m.
Right Patch Set: Deal with ill formed filters. Created Feb. 14, 2018, 5:05 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « compiled/filter/ElemHideBase.h ('k') | compiled/filter/Filter.cpp » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
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
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 delta++; 47 delta++;
48 else 48 else
49 text[pos - delta] = text[pos]; 49 text[pos - delta] = text[pos];
50 } 50 }
51 selectorStart -= delta; 51 selectorStart -= delta;
52 52
53 text.reset(text, 0, len - delta); 53 text.reset(text, 0, len - delta);
54 } 54 }
55 55
56 static constexpr String::value_type ELEM_HIDE_DELIMITER[] = u"##"; 56 static constexpr String::value_type ELEM_HIDE_DELIMITER[] = u"##";
57 static constexpr String::size_type ELEM_HIDE_DELIMITER_LEN = LENGTH_OF(ELEM_HI DE_DELIMITER); 57 static constexpr String::size_type ELEM_HIDE_DELIMITER_LEN = str_length_of(ELE M_HIDE_DELIMITER);
58 58
59 static constexpr String::value_type ELEM_HIDE_EMULATION_DELIMITER[] = u"#?#"; 59 static constexpr String::value_type ELEM_HIDE_EMULATION_DELIMITER[] = u"#?#";
60 static constexpr String::size_type ELEM_HIDE_EMULATION_DELIMITER_LEN = LENGTH_ OF(ELEM_HIDE_EMULATION_DELIMITER); 60 static constexpr String::size_type ELEM_HIDE_EMULATION_DELIMITER_LEN = str_len gth_of(ELEM_HIDE_EMULATION_DELIMITER);
61 61
62 static constexpr String::value_type OLD_PROPS_SELECTOR[] = u"[-abp-properties= "; 62 static constexpr String::value_type OLD_PROPS_SELECTOR[] = u"[-abp-properties= ";
63 static constexpr String::size_type OLD_PROPS_SELECTOR_LEN = LENGTH_OF(OLD_PROP S_SELECTOR); 63 static constexpr String::size_type OLD_PROPS_SELECTOR_LEN = str_length_of(OLD_ PROPS_SELECTOR);
64 64
65 static constexpr String::value_type PROPS_SELECTOR[] = u":-abp-properties("; 65 static constexpr String::value_type PROPS_SELECTOR[] = u":-abp-properties(";
66 static constexpr String::size_type PROPS_SELECTOR_LEN = LENGTH_OF(PROPS_SELECT OR); 66 static constexpr String::size_type PROPS_SELECTOR_LEN = str_length_of(PROPS_SE LECTOR);
67 } 67 }
68 68
69 ElemHideBase::ElemHideBase(Type type, const String& text, const ElemHideData& da ta) 69 ElemHideBase::ElemHideBase(Type type, const String& text, const ElemHideData& da ta)
70 : ActiveFilter(type, text, false), mData(data) 70 : ActiveFilter(type, text, false), mData(data)
71 { 71 {
72 if (mData.HasDomains()) 72 if (mData.HasDomains())
73 ParseDomains(mData.GetDomainsSource(mText), u','); 73 ParseDomains(mData.GetDomainsSource(mText), u',');
74 } 74 }
75 75
76 Filter::Type ElemHideBase::Parse(DependentString& text, ElemHideData& data, bool & needConversion) 76 Filter::Type ElemHideBase::Parse(DependentString& text, ElemHideData& data, bool & needConversion)
77 { 77 {
78 needConversion = false;
79
78 StringScanner scanner(text); 80 StringScanner scanner(text);
79 81
80 // Domains part 82 // Domains part
81 bool seenSpaces = false; 83 bool seenSpaces = false;
82 while (!scanner.done()) 84 while (!scanner.done())
83 { 85 {
84 String::value_type next = scanner.next(); 86 String::value_type next = scanner.next();
85 if (next == u'#') 87 if (next == u'#')
86 { 88 {
87 data.mDomainsEnd = scanner.position(); 89 data.mDomainsEnd = scanner.position();
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 String::size_type byte_len() const 162 String::size_type byte_len() const
161 { 163 {
162 return len() * sizeof(String::value_type); 164 return len() * sizeof(String::value_type);
163 } 165 }
164 }; 166 };
165 } 167 }
166 168
167 // Convert filter from the old syntax to the new. 169 // Convert filter from the old syntax to the new.
168 DependentString ElemHideBase::ConvertFilter(String& text, String::size_type& at) 170 DependentString ElemHideBase::ConvertFilter(String& text, String::size_type& at)
169 { 171 {
172 Range prefix = {at, text.find(OLD_PROPS_SELECTOR, at, OLD_PROPS_SELECTOR_LEN)} ;
173 if (prefix.end == text.npos)
174 return DependentString(text);
175
170 auto length = text.length(); 176 auto length = text.length();
171 Range prefix = {at, 0};
172 Range suffix = {at, length}; 177 Range suffix = {at, length};
173 prefix.end = text.find(OLD_PROPS_SELECTOR, at, OLD_PROPS_SELECTOR_LEN); 178 Range properties = { prefix.end + OLD_PROPS_SELECTOR_LEN, 0 };
sergei 2018/02/12 12:53:18 not important but perhaps it would be better to sa
hub 2018/02/12 18:14:39 Done.
174 if (prefix.end != text.npos) 179 String::value_type quote = 0;
sergei 2018/02/12 12:53:19 What about returning DependentString(text); here i
hub 2018/02/12 18:14:39 Done.
175 { 180 for (auto index = properties.start;
176 Range properties = { prefix.end + OLD_PROPS_SELECTOR_LEN, 0 }; 181 index < length && (suffix.start == at); index++)
177 String::value_type quote = 0; 182 {
178 bool closing = false; 183 auto c = text[index];
179 for (auto index = properties.start; 184 switch (c)
180 index < length && !closing; index++) 185 {
181 { 186 case u'"':
182 auto c = text[index]; 187 case u'\'':
183 switch (c) 188 if (quote == 0)
184 { 189 {
185 case u'"': 190 // syntax error: we already have a quoted section.
186 case u'\'': 191 if (properties.end)
187 if (quote == 0) 192 return DependentString();
188 { 193
189 // syntax error: we already have a quoted section. 194 if (properties.start != index)
190 if (properties.end) 195 return DependentString();
191 return DependentString(); 196
192 197 quote = c;
193 quote = c; 198 properties.start = index + 1;
194 properties.start = index + 1; 199 }
195 } 200 else if (quote == c)
196 else if (quote == c) 201 {
197 { 202 // end of quoted.
198 // end of quoted. 203 quote = 0;
199 quote = 0; 204 properties.end = index;
200 properties.end = index; 205 }
201 } 206 break;
202 break; 207 case u']':
203 case u']': 208 if (quote == 0)
204 if (quote == 0) 209 {
205 { 210 if (properties.end == 0)
206 if (properties.end == 0) 211 return DependentString();
207 return DependentString(); 212 if (properties.end + 1 != index)
208 suffix.start = index + 1; 213 return DependentString();
209 closing = true; 214 suffix.start = index + 1;
sergei 2018/02/12 12:53:19 What about using of suffix.start instead of `closi
hub 2018/02/12 18:14:39 suffix.start is initialised to `at`. So I'll use t
210 } 215 }
211 break; 216 break;
212 default: 217 default:
213 break; 218 break;
214 } 219 }
215 } 220 }
216 221
217 String::size_type delimiter = text.find(ELEM_HIDE_DELIMITER, 0, 222 if (suffix.start == at)
sergei 2018/02/27 10:56:53 Just for reference, I think it (what the whole for
218 ELEM_HIDE_DELIMITER_LEN); 223 return DependentString();
219 // +1 for the replacement of "##" by "#?#" 224
220 if (delimiter != text.npos) 225 String::size_type delimiter = text.find(ELEM_HIDE_DELIMITER, 0,
221 at++; 226 ELEM_HIDE_DELIMITER_LEN);
sergei 2018/02/12 12:53:20 BTW, if there is no such delimiter then is it a ma
hub 2018/02/12 18:14:40 no. #@# is valid too. We could check if it is #@#
222 auto new_len = prefix.len() + suffix.len() + properties.len() 227 // +1 for the replacement of "##" by "#?#"
223 + PROPS_SELECTOR_LEN + 1 + at; 228 if (delimiter != text.npos)
sergei 2018/02/12 12:53:19 What about at + prefix.len() + PROPS_SELECTOR_LEN
hub 2018/02/12 18:14:39 Done.
224 229 at++;
sergei 2018/02/12 12:53:18 Could you please add the assert here that new_len
hub 2018/02/12 18:14:40 Done.
225 DependentString converted(text, 0, new_len); 230 auto new_len = at + prefix.len() + PROPS_SELECTOR_LEN + properties.len() + 1 / * ) */ + suffix.len();
226 231
227 if (suffix.len()) 232 assert2(new_len + 1 == length || (delimiter == text.npos && new_len + 2 == len gth), u"Inconsistent length in filter conversion."_str);
sergei 2018/02/27 10:56:53 not important just for reference length == new_len
hub 2018/02/27 13:32:30 Acknowledged.
228 { 233
229 new_len -= suffix.len(); 234 DependentString converted(text, 0, new_len);
230 std::memmove(converted.data() + new_len, 235
231 text.data() + suffix.start, 236 if (suffix.len())
232 suffix.byte_len()); 237 {
233 } 238 new_len -= suffix.len();
234 new_len--;
235 // here we need to move the properties before inserting the ')'
236 auto parens = new_len;
237 if (properties.len())
238 {
239 new_len -= properties.len();
240 std::memmove(converted.data() + new_len,
241 text.data() + properties.start, properties.byte_len());
242 }
243 converted[parens] = u')';
244
245 new_len -= PROPS_SELECTOR_LEN;
246 std::memmove(converted.data() + new_len, 239 std::memmove(converted.data() + new_len,
sergei 2018/02/12 12:53:18 logically it should be memcpy but since memmove do
hub 2018/02/12 18:14:39 You are right. Changing it to memcpy().
247 PROPS_SELECTOR, 240 text.data() + suffix.start,
248 PROPS_SELECTOR_LEN * sizeof(String::value_type)); 241 suffix.byte_len());
249 if (prefix.len()) 242 }
250 { 243 new_len--;
251 new_len -= prefix.len(); 244 // here we need to move the properties before inserting the ')'
252 std::memmove(converted.data() + new_len, 245 auto parens = new_len;
253 text.data() + prefix.start, prefix.byte_len()); 246 if (properties.len())
254 } 247 {
255 248 new_len -= properties.len();
256 if (delimiter != String::npos) 249 std::memmove(converted.data() + new_len,
257 { 250 text.data() + properties.start, properties.byte_len());
258 std::memmove(converted.data() + delimiter, ELEM_HIDE_EMULATION_DELIMITER, 251 }
259 ELEM_HIDE_EMULATION_DELIMITER_LEN * sizeof(String::value_type )); 252 converted[parens] = u')';
260 } 253
261 254 new_len -= PROPS_SELECTOR_LEN;
262 return converted; 255 std::memcpy(converted.data() + new_len,
263 } 256 PROPS_SELECTOR,
264 257 PROPS_SELECTOR_LEN * sizeof(String::value_type));
265 return DependentString(text); 258 if (prefix.len())
259 {
260 new_len -= prefix.len();
261 std::memmove(converted.data() + new_len,
262 text.data() + prefix.start, prefix.byte_len());
263 }
264
265 if (delimiter != String::npos)
266 {
267 std::memcpy(converted.data() + delimiter, ELEM_HIDE_EMULATION_DELIMITER,
268 ELEM_HIDE_EMULATION_DELIMITER_LEN * sizeof(String::value_type));
269 }
270
271 return converted;
266 } 272 }
267 273
268 namespace 274 namespace
269 { 275 {
270 static constexpr String::value_type OPENING_CURLY_REPLACEMENT[] = u"\\7B "; 276 static constexpr String::value_type OPENING_CURLY_REPLACEMENT[] = u"\\7B ";
271 static constexpr String::value_type CLOSING_CURLY_REPLACEMENT[] = u"\\7D "; 277 static constexpr String::value_type CLOSING_CURLY_REPLACEMENT[] = u"\\7D ";
272 static constexpr String::size_type CURLY_REPLACEMENT_SIZE = LENGTH_OF(OPENING_ CURLY_REPLACEMENT); 278 static constexpr String::size_type CURLY_REPLACEMENT_SIZE = str_length_of(OPEN ING_CURLY_REPLACEMENT);
273 279
274 OwnedString EscapeCurlies(String::size_type replacementCount, 280 OwnedString EscapeCurlies(String::size_type replacementCount,
275 const DependentString& str) 281 const DependentString& str)
276 { 282 {
277 OwnedString result(str.length() + replacementCount * (CURLY_REPLACEMENT_SIZE - 1)); 283 OwnedString result(str.length() + replacementCount * (CURLY_REPLACEMENT_SIZE - 1));
278 284
279 String::value_type* current = result.data(); 285 String::value_type* current = result.data();
280 for (String::size_type i = 0; i < str.length(); i++) 286 for (String::size_type i = 0; i < str.length(); i++)
281 { 287 {
282 switch(str[i]) 288 switch(str[i])
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 if (item.second && !item.first.empty()) 332 if (item.second && !item.first.empty())
327 { 333 {
328 if (!result.empty()) 334 if (!result.empty())
329 result.append(u','); 335 result.append(u',');
330 result.append(item.first); 336 result.append(item.first);
331 } 337 }
332 } 338 }
333 } 339 }
334 return result; 340 return result;
335 } 341 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld