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

Side by Side Diff: include.postload.js

Issue 4935175632846848: Issue 1527 - Properly escape generated CSS selectors (Closed)
Patch Set: Renamed function and added test case Created Nov. 6, 2014, 2:59 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 | « no previous file | qunit/index.html » ('j') | qunit/tests/cssEscaping.js » ('J')
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 <http://adblockplus.org/>, 2 * This file is part of Adblock Plus <http://adblockplus.org/>,
3 * Copyright (C) 2006-2014 Eyeo GmbH 3 * Copyright (C) 2006-2014 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 // Click-to-hide stuff 18 // Click-to-hide stuff
19 var clickHide_activated = false; 19 var clickHide_activated = false;
20 var clickHide_filters = null; 20 var clickHide_filters = null;
21 var currentElement = null; 21 var currentElement = null;
22 var clickHideFilters = null; 22 var clickHideFilters = null;
23 var highlightedElementsSelector = null; 23 var highlightedElementsSelector = null;
24 var clickHideFiltersDialog = null; 24 var clickHideFiltersDialog = null;
25 var lastRightClickEvent = null; 25 var lastRightClickEvent = null;
26 26
27 var ctrlChar = /[\x00-\x1F\x7F]/;
28
29 function escapeChar(chr)
30 {
31 if (ctrlChar.test(chr) || /\d/.test(chr))
32 return "\\" + chr.charCodeAt(0).toString(16) + " ";
33
34 return "\\" + chr;
35 }
36
27 function quote(value) 37 function quote(value)
28 { 38 {
29 return '"' + value.replace(/(["\\])/g, "\\$1") + '"'; 39 return '"' + value.replace(new RegExp('["\\\\]|' + ctrlChar.source, "g"), esca peChar) + '"';
Wladimir Palant 2014/11/06 21:26:06 Generating regular expressions dynamically for no
Sebastian Noack 2014/11/10 12:13:18 The idea was not to hard-code the char codes for c
40 }
41
42 function escapeCSS(s)
43 {
44 return s.replace(/^\d|^-(?![^\d\-])|[^\w\-\u0080-\uFFFF]/g, escapeChar);
Wladimir Palant 2014/11/06 21:26:06 Thinking more about this, I'm definitely opposed t
Sebastian Noack 2014/11/10 12:13:18 It's probably not worth to argue here. But I still
30 } 45 }
31 46
32 function supportsShadowRoot(element) 47 function supportsShadowRoot(element)
33 { 48 {
34 if (!("createShadowRoot" in element)) 49 if (!("createShadowRoot" in element))
35 return false; 50 return false;
36 51
37 // There are some elements (e.g. <textarea>), which don't 52 // There are some elements (e.g. <textarea>), which don't
38 // support author created shadow roots and throw an exception. 53 // support author created shadow roots and throw an exception.
39 var clone = element.cloneNode(false); 54 var clone = element.cloneNode(false);
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 var elt = currentElement; 384 var elt = currentElement;
370 var url = null; 385 var url = null;
371 if (currentElement.classList.contains("__adblockplus__overlay")) 386 if (currentElement.classList.contains("__adblockplus__overlay"))
372 { 387 {
373 elt = currentElement.prisoner; 388 elt = currentElement.prisoner;
374 url = currentElement.prisonerURL; 389 url = currentElement.prisonerURL;
375 } 390 }
376 else if (elt.src) 391 else if (elt.src)
377 url = elt.src; 392 url = elt.src;
378 393
379 // Construct filters. The popup will retrieve these.
380 // Only one ID
381 var elementId = elt.id ? elt.id.split(' ').join('') : null;
382
383 clickHideFilters = new Array(); 394 clickHideFilters = new Array();
384 selectorList = new Array(); 395 selectorList = new Array();
385 396
386 var addSelector = function(selector) 397 var addSelector = function(selector)
387 { 398 {
388 clickHideFilters.push(document.domain + "##" + selector); 399 clickHideFilters.push(document.domain + "##" + selector);
389 selectorList.push(selector); 400 selectorList.push(selector);
390 }; 401 };
391 402
392 if (elementId) 403 if (elt.id)
393 addSelector("#" + elementId); 404 addSelector("#" + escapeCSS(elt.id));
394 405
395 if (elt.classList.length > 0) 406 if (elt.classList.length > 0)
396 { 407 {
397 var selector = ""; 408 var selector = "";
398 409
399 for (var i = 0; i < elt.classList.length; i++) 410 for (var i = 0; i < elt.classList.length; i++)
400 selector += "." + elt.classList[i].replace(/([^\w-])/g, "\\$1"); 411 selector += "." + escapeCSS(elt.classList[i]);
401 412
402 addSelector(selector); 413 addSelector(selector);
403 } 414 }
404 415
405 if (url) 416 if (url)
406 { 417 {
407 var src = elt.getAttribute("src"); 418 var src = elt.getAttribute("src");
408 var selector = src && elt.localName + '[src=' + quote(src) + ']'; 419 var selector = src && escapeCSS(elt.localName) + '[src=' + quote(src) + ']';
409 420
410 if (/^https?:/i.test(url)) 421 if (/^https?:/i.test(url))
411 { 422 {
412 clickHideFilters.push(url.replace(/^[\w\-]+:\/+(?:www\.)?/, "||")); 423 clickHideFilters.push(url.replace(/^[\w\-]+:\/+(?:www\.)?/, "||"));
413 424
414 if (selector) 425 if (selector)
415 selectorList.push(selector); 426 selectorList.push(selector);
416 } 427 }
417 else if (selector) 428 else if (selector)
418 addSelector(selector); 429 addSelector(selector);
419 } 430 }
420 431
421 // restore the original style, before generating the fallback filter that 432 // restore the original style, before generating the fallback filter that
422 // will include the style, and to prevent highlightElements from saving those 433 // will include the style, and to prevent highlightElements from saving those
423 unhighlightElement(currentElement); 434 unhighlightElement(currentElement);
424 435
425 // as last resort, create a filter based on inline styles 436 // as last resort, create a filter based on inline styles
426 if (clickHideFilters.length == 0) 437 if (clickHideFilters.length == 0)
427 { 438 {
428 var style = elt.getAttribute("style"); 439 var style = elt.getAttribute("style");
429 if (style) 440 if (style)
430 addSelector(elt.localName + '[style=' + quote(style) + ']'); 441 addSelector(escapeCSS(elt.localName) + '[style=' + quote(style) + ']');
431 } 442 }
432 443
433 // Show popup 444 // Show popup
434 clickHide_showDialog(e.clientX, e.clientY, clickHideFilters); 445 clickHide_showDialog(e.clientX, e.clientY, clickHideFilters);
435 446
436 // Highlight the elements specified by selector in yellow 447 // Highlight the elements specified by selector in yellow
437 highlightElements(selectorList.join(",")); 448 highlightElements(selectorList.join(","));
438 // Now, actually highlight the element the user clicked on in red 449 // Now, actually highlight the element the user clicked on in red
439 highlightElement(currentElement, "#fd1708", "#f6a1b5"); 450 highlightElement(currentElement, "#fd1708", "#f6a1b5");
440 451
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 break; 670 break;
660 default: 671 default:
661 sendResponse({}); 672 sendResponse({});
662 break; 673 break;
663 } 674 }
664 }); 675 });
665 676
666 if (window == window.top) 677 if (window == window.top)
667 ext.backgroundPage.sendMessage({type: "report-html-page"}); 678 ext.backgroundPage.sendMessage({type: "report-html-page"});
668 } 679 }
OLDNEW
« no previous file with comments | « no previous file | qunit/index.html » ('j') | qunit/tests/cssEscaping.js » ('J')

Powered by Google App Engine
This is Rietveld