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: Created Nov. 5, 2014, 2:21 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 | no next file » | 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 <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 function escapeChar(chr, pos, s) {
28 var code = chr.charCodeAt(0);
29
30 // non-ascii, needs no escaping
31 if (code >= 128)
Sebastian Noack 2014/11/05 18:09:04 I just realized that I can easily check in the reg
32 return chr;
33
34 // control characters and numbers, must be escaped based on their code point
35 if ((code >= 0 && code <= 31) || (code >= 48 && code <= 57) || code == 127)
Wladimir Palant 2014/11/05 15:14:41 How about: if (code <= 0x1F || /\d/.test(chr) |
Sebastian Noack 2014/11/05 18:09:04 I already considered using that regex to check for
36 return "\\" + code.toString(16) + (pos + 1 < s.length ? " " : "");
Wladimir Palant 2014/11/05 15:14:41 Why create a special case for end of string? That
Sebastian Noack 2014/11/05 18:09:04 I find the extra space in the end confusing. It ca
37
38 // others, can be escaped by prepending a backslash
39 return "\\" + chr;
40 }
41
27 function quote(value) 42 function quote(value)
28 { 43 {
29 return '"' + value.replace(/(["\\])/g, "\\$1") + '"'; 44 return '"' + value.replace(/["\\\r\n\f\0]/g, escapeChar) + '"';
Wladimir Palant 2014/11/05 15:14:41 How about generally escaping all non-printable cha
Sebastian Noack 2014/11/05 18:09:04 Yeah, un-escaped control characters make quoted st
45 }
46
47 function escapeToken(s) {
48 return s.replace(/^\d|^-(?![^\d-])|[^\w-]/g, escapeChar);
Wladimir Palant 2014/11/05 15:14:41 How about always escaping leading dashes? These ar
Sebastian Noack 2014/11/05 18:09:04 I'd prefer to keep the logic for escaping dashes.
Wladimir Palant 2014/11/05 19:56:52 I'll leave the decision on whether that branch in
30 } 49 }
31 50
32 function supportsShadowRoot(element) 51 function supportsShadowRoot(element)
33 { 52 {
34 if (!("createShadowRoot" in element)) 53 if (!("createShadowRoot" in element))
35 return false; 54 return false;
36 55
37 // There are some elements (e.g. <textarea>), which don't 56 // There are some elements (e.g. <textarea>), which don't
38 // support author created shadow roots and throw an exception. 57 // support author created shadow roots and throw an exception.
39 var clone = element.cloneNode(false); 58 var clone = element.cloneNode(false);
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 var elt = currentElement; 388 var elt = currentElement;
370 var url = null; 389 var url = null;
371 if (currentElement.classList.contains("__adblockplus__overlay")) 390 if (currentElement.classList.contains("__adblockplus__overlay"))
372 { 391 {
373 elt = currentElement.prisoner; 392 elt = currentElement.prisoner;
374 url = currentElement.prisonerURL; 393 url = currentElement.prisonerURL;
375 } 394 }
376 else if (elt.src) 395 else if (elt.src)
377 url = elt.src; 396 url = elt.src;
378 397
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(); 398 clickHideFilters = new Array();
384 selectorList = new Array(); 399 selectorList = new Array();
385 400
386 var addSelector = function(selector) 401 var addSelector = function(selector)
387 { 402 {
388 clickHideFilters.push(document.domain + "##" + selector); 403 clickHideFilters.push(document.domain + "##" + selector);
389 selectorList.push(selector); 404 selectorList.push(selector);
390 }; 405 };
391 406
392 if (elementId) 407 if (elt.id)
393 addSelector("#" + elementId); 408 addSelector("#" + escapeToken(elt.id));
394 409
395 if (elt.classList.length > 0) 410 if (elt.classList.length > 0)
396 { 411 {
397 var selector = ""; 412 var selector = "";
398 413
399 for (var i = 0; i < elt.classList.length; i++) 414 for (var i = 0; i < elt.classList.length; i++)
400 selector += "." + elt.classList[i].replace(/([^\w-])/g, "\\$1"); 415 selector += "." + escapeToken(elt.classList[i]);
401 416
402 addSelector(selector); 417 addSelector(selector);
403 } 418 }
404 419
405 if (url) 420 if (url)
406 { 421 {
407 var src = elt.getAttribute("src"); 422 var src = elt.getAttribute("src");
408 var selector = src && elt.localName + '[src=' + quote(src) + ']'; 423 var selector = src && escapeToken(elt.localName) + '[src=' + quote(src) + '] ';
409 424
410 if (/^https?:/i.test(url)) 425 if (/^https?:/i.test(url))
411 { 426 {
412 clickHideFilters.push(url.replace(/^[\w\-]+:\/+(?:www\.)?/, "||")); 427 clickHideFilters.push(url.replace(/^[\w\-]+:\/+(?:www\.)?/, "||"));
413 428
414 if (selector) 429 if (selector)
415 selectorList.push(selector); 430 selectorList.push(selector);
416 } 431 }
417 else if (selector) 432 else if (selector)
418 addSelector(selector); 433 addSelector(selector);
419 } 434 }
420 435
421 // restore the original style, before generating the fallback filter that 436 // restore the original style, before generating the fallback filter that
422 // will include the style, and to prevent highlightElements from saving those 437 // will include the style, and to prevent highlightElements from saving those
423 unhighlightElement(currentElement); 438 unhighlightElement(currentElement);
424 439
425 // as last resort, create a filter based on inline styles 440 // as last resort, create a filter based on inline styles
426 if (clickHideFilters.length == 0) 441 if (clickHideFilters.length == 0)
427 { 442 {
428 var style = elt.getAttribute("style"); 443 var style = elt.getAttribute("style");
429 if (style) 444 if (style)
430 addSelector(elt.localName + '[style=' + quote(style) + ']'); 445 addSelector(escapeToken(elt.localName) + '[style=' + quote(style) + ']');
431 } 446 }
432 447
433 // Show popup 448 // Show popup
434 clickHide_showDialog(e.clientX, e.clientY, clickHideFilters); 449 clickHide_showDialog(e.clientX, e.clientY, clickHideFilters);
435 450
436 // Highlight the elements specified by selector in yellow 451 // Highlight the elements specified by selector in yellow
437 highlightElements(selectorList.join(",")); 452 highlightElements(selectorList.join(","));
438 // Now, actually highlight the element the user clicked on in red 453 // Now, actually highlight the element the user clicked on in red
439 highlightElement(currentElement, "#fd1708", "#f6a1b5"); 454 highlightElement(currentElement, "#fd1708", "#f6a1b5");
440 455
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 break; 674 break;
660 default: 675 default:
661 sendResponse({}); 676 sendResponse({});
662 break; 677 break;
663 } 678 }
664 }); 679 });
665 680
666 if (window == window.top) 681 if (window == window.top)
667 ext.backgroundPage.sendMessage({type: "report-html-page"}); 682 ext.backgroundPage.sendMessage({type: "report-html-page"});
668 } 683 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld