| OLD | NEW | 
|    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 /* eslint-env webextensions */ |   18 /* eslint-env webextensions */ | 
|   19 /* eslint no-console: "off" */ |   19 /* eslint no-console: "off" */ | 
|   20  |   20  | 
|   21 "use strict"; |   21 "use strict"; | 
|   22  |   22  | 
 |   23 function regexEscape(s) | 
 |   24 { | 
 |   25   return s.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&"); | 
 |   26 } | 
 |   27  | 
 |   28 function findProperty(path, root = window) | 
 |   29 { | 
 |   30   let owner = root; | 
 |   31  | 
 |   32   let chain = path.split("."); | 
 |   33   let property = chain.pop(); | 
 |   34  | 
 |   35   for (let name of chain) | 
 |   36   { | 
 |   37     if (!owner) | 
 |   38       break; | 
 |   39  | 
 |   40     owner = owner[name]; | 
 |   41   } | 
 |   42  | 
 |   43   if (!owner) | 
 |   44     return null; | 
 |   45  | 
 |   46   return {owner, property}; | 
 |   47 } | 
 |   48  | 
 |   49 function injectPropertyAccessValidator(object, property, validate) | 
 |   50 { | 
 |   51   let value = object[property]; | 
 |   52  | 
 |   53   Object.defineProperty(object, property, { | 
 |   54     get() | 
 |   55     { | 
 |   56       validate(); | 
 |   57       return value; | 
 |   58     }, | 
 |   59     set(newValue) | 
 |   60     { | 
 |   61       validate(); | 
 |   62       value = newValue; | 
 |   63     } | 
 |   64   }); | 
 |   65 } | 
 |   66  | 
|   23 function injectCode(code) |   67 function injectCode(code) | 
|   24 { |   68 { | 
|   25   let script = document.createElement("script"); |   69   let script = document.createElement("script"); | 
|   26  |   70  | 
|   27   script.type = "application/javascript"; |   71   script.type = "application/javascript"; | 
|   28   script.async = false; |   72   script.async = false; | 
|   29  |   73  | 
|   30   // Firefox 58 only bypasses site CSPs when assigning to 'src', |   74   // Firefox 58 only bypasses site CSPs when assigning to 'src', | 
|   31   // while Chrome 67 only bypasses site CSPs when using 'textContent'. |   75   // while Chrome 67 only bypasses site CSPs when using 'textContent'. | 
|   32   if (browser.runtime.getURL("").startsWith("chrome-extension://")) |   76   if (browser.runtime.getURL("").startsWith("chrome-extension://")) | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
|   48 function stringifyFunctionCall(func, ...params) |   92 function stringifyFunctionCall(func, ...params) | 
|   49 { |   93 { | 
|   50   return `"use strict";(${func})(${params.map(JSON.stringify).join(",")});`; |   94   return `"use strict";(${func})(${params.map(JSON.stringify).join(",")});`; | 
|   51 } |   95 } | 
|   52  |   96  | 
|   53 function makeInjector(injectable) |   97 function makeInjector(injectable) | 
|   54 { |   98 { | 
|   55   return (...args) => injectCode(stringifyFunctionCall(injectable, ...args)); |   99   return (...args) => injectCode(stringifyFunctionCall(injectable, ...args)); | 
|   56 } |  100 } | 
|   57  |  101  | 
 |  102 function getMagic() | 
 |  103 { | 
 |  104   return String.fromCharCode(Date.now() % 26 + 97) + | 
 |  105          Math.floor(Math.random() * 982451653 + 982451653).toString(36); | 
 |  106 } | 
 |  107  | 
 |  108 function suppressMagicError(magic) | 
 |  109 { | 
 |  110   let {onerror} = window; | 
 |  111   window.onerror = function(message, ...rest) | 
 |  112   { | 
 |  113     if (typeof message == "string" && message.includes(magic)) | 
 |  114       return true; | 
 |  115  | 
 |  116     if (typeof onerror instanceof Function) | 
 |  117       return onerror.call(this, message, ...rest); | 
 |  118   }; | 
 |  119 } | 
 |  120  | 
|   58 function log(...args) |  121 function log(...args) | 
|   59 { |  122 { | 
|   60   console.log(...args); |  123   console.log(...args); | 
|   61 } |  124 } | 
|   62  |  125  | 
|   63 exports.log = log; |  126 exports.log = log; | 
|   64  |  127  | 
|   65 function uabinjectDefuser() |  128 function uabinjectDefuser() | 
|   66 { |  129 { | 
|   67   window.trckd = true; |  130   window.trckd = true; | 
|   68   window.uabpdl = true; |  131   window.uabpdl = true; | 
|   69   window.uabInject = true; |  132   window.uabInject = true; | 
|   70   window.uabDetect = true; |  133   window.uabDetect = true; | 
|   71 } |  134 } | 
|   72  |  135  | 
|   73 exports["uabinject-defuser"] = makeInjector(uabinjectDefuser); |  136 exports["uabinject-defuser"] = makeInjector(uabinjectDefuser); | 
 |  137  | 
 |  138 function abortCurrentInlineScript(target, needle) | 
 |  139 { | 
 |  140   if (!target) | 
 |  141     return; | 
 |  142  | 
 |  143   let re = null; | 
 |  144  | 
 |  145   if (needle) | 
 |  146   { | 
 |  147     re = new RegExp(/^\/.+\/$/.test(needle) ? | 
 |  148                       needle.slice(1, -1) : | 
 |  149                       regexEscape(needle)); | 
 |  150   } | 
 |  151  | 
 |  152   let {owner, property} = findProperty(target) || {}; | 
 |  153  | 
 |  154   let descriptor = Object.getOwnPropertyDescriptor(owner, property); | 
 |  155   if (descriptor && descriptor.get) | 
 |  156     return; | 
 |  157  | 
 |  158   let magic = getMagic(); | 
 |  159  | 
 |  160   injectPropertyAccessValidator(owner, property, () => | 
 |  161   { | 
 |  162     let element = document.currentScript; | 
 |  163     if (element instanceof HTMLScriptElement && | 
 |  164         element.src == "" && (!re || re.test(element.textContent))) | 
 |  165     { | 
 |  166       throw new ReferenceError(magic); | 
 |  167     } | 
 |  168   }); | 
 |  169  | 
 |  170   suppressMagicError(magic); | 
 |  171 } | 
 |  172  | 
 |  173 exports["abort-current-inline-script"] = makeInjector(abortCurrentInlineScript); | 
| OLD | NEW |