├── .gitignore ├── README.md ├── makexpi.sh ├── version.py └── xpi ├── GPL.txt ├── NoScript_License.txt ├── bootstrap.js ├── chrome.manifest ├── chrome ├── content │ └── noscript │ │ ├── ABE.g │ │ ├── ABE.js │ │ ├── ABELexer.js │ │ ├── ABEParser.js │ │ ├── ASPIdiocy.js │ │ ├── AddressMatcher.js │ │ ├── Bug.js │ │ ├── ChannelReplacement.js │ │ ├── ClearClickHandler.js │ │ ├── Cookie.js │ │ ├── DNS.js │ │ ├── DOM.js │ │ ├── DoNotTrack.js │ │ ├── Entities.js │ │ ├── ExternalFilters.js │ │ ├── FlashIdiocy.js │ │ ├── ForcedRedirectionCallback.js │ │ ├── FrameScript.jsm │ │ ├── HTTPS.js │ │ ├── IO.js │ │ ├── IOUtil.js │ │ ├── InjectionChecker.js │ │ ├── JSURL.js │ │ ├── Lang.js │ │ ├── MSEInterception.js │ │ ├── Main.js │ │ ├── MainChild.js │ │ ├── MainParent.js │ │ ├── Membrane.js │ │ ├── MimeService.js │ │ ├── MimeServiceParent.js │ │ ├── NoScript_License.txt │ │ ├── PasteHandler.jsm │ │ ├── Plugins.js │ │ ├── Policy.js │ │ ├── Profiler.js │ │ ├── RequestWatchdog.js │ │ ├── Restartless.jsm │ │ ├── ScriptSurrogate.js │ │ ├── ScriptlessBGThumbs.js │ │ ├── SiteUtils.js │ │ ├── Strings.js │ │ ├── SyntaxChecker.js │ │ ├── Thread.js │ │ ├── UISync.jsm │ │ ├── URIValidator.js │ │ ├── WebExt.js │ │ ├── WebGLInterception.js │ │ ├── WinScript.js │ │ ├── about.xul │ │ ├── antlr.js │ │ ├── clearClick.js │ │ ├── clearClick.xul │ │ ├── defer.jsm │ │ ├── e10sChild.js │ │ ├── e10sIPC.js │ │ ├── e10sParent.js │ │ ├── e10sProcessScript.js │ │ ├── frameScript.js │ │ ├── iaUI.js │ │ ├── importer.jsm │ │ ├── loader.js │ │ ├── noscript.js │ │ ├── noscript.xbl │ │ ├── noscriptBM.js │ │ ├── noscriptBMOverlay.xul │ │ ├── noscriptOptions.js │ │ ├── noscriptOptions.xul │ │ ├── noscriptOverlay-noStatusBar.xul │ │ ├── noscriptOverlay.js │ │ ├── noscriptOverlay.xul │ │ └── tree-copy.js ├── locale │ ├── ar │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── be-BY │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── bg-BG │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── bn-IN │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── ca-AD │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── cs-CZ │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── cy-GB │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── da │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── de │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── el │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── en-GB │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── en-US │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── eo │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── es-AR │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── es-CL │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── es-ES │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── et-EE │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── eu │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── fa-IR │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── fi │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── fr │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── gl-ES │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── he-IL │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── hr-HR │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── hsb │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── hu-HU │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── id-ID │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── it │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── ja-JP │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── kk-KZ │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── km-KH │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── ko-KR │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── lt │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── mk-MK │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── ms-MY │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── nb-NO │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── nl │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── pl │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── pt-BR │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── pt-PT │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── ro │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── ru-RU │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── sk-SK │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── sl-SI │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── sr-RS │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── sr │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── sv-SE │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── te-IN │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── th │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── tr │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── uk │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── vi │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ ├── zh-CN │ │ └── noscript │ │ │ ├── about.properties │ │ │ ├── noscript.dtd │ │ │ └── noscript.properties │ └── zh-TW │ │ └── noscript │ │ ├── about.properties │ │ ├── noscript.dtd │ │ └── noscript.properties └── skin │ └── classic │ └── noscript │ ├── abe16.png │ ├── about.css │ ├── block.wav │ ├── browser.css │ ├── clearclick16.png │ ├── close.png │ ├── console16.png │ ├── content.css │ ├── ef-no16.png │ ├── ef16.png │ ├── emb16.png │ ├── embed-no16.png │ ├── embed16.png │ ├── faq16.png │ ├── flash16.png │ ├── flash32.png │ ├── folder_closed.png │ ├── folder_open.png │ ├── font.png │ ├── glb-emb16.png │ ├── glb-no16.png │ ├── glb16.png │ ├── https16.png │ ├── ia.png │ ├── icon24.png │ ├── icon32.png │ ├── icon64.png │ ├── icon80.png │ ├── inactive-emb16.png │ ├── inactive-glb16.png │ ├── inactive-no-emb16.png │ ├── inactive-no16.png │ ├── inactive-prt16.png │ ├── inactive-yes16.png │ ├── inactive-yu16.png │ ├── java16.png │ ├── java32.png │ ├── mobile.css │ ├── no-emb16.png │ ├── no16.png │ ├── options.css │ ├── prt16.png │ ├── redirect16.png │ ├── revtemp16.png │ ├── somelight16.png │ ├── somelight32.png │ ├── subprt16.png │ ├── temp16.png │ ├── unsafe-reload16.png │ ├── untrusted-glb16.png │ ├── untrusted16.png │ ├── webgl16.png │ ├── webgl32.png │ ├── xss16.png │ ├── yes16.png │ ├── yu-emb16.png │ ├── yu-glb16.png │ └── yu16.png ├── components └── noscriptService.js ├── defaults └── preferences │ └── noscript.js ├── install.rdf ├── mozilla.cfg └── webextension ├── legacy.js └── manifest.json /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Unofficial NoScript version history 2 | 3 | This repository contains version history for the NoScript Firefox add-on **up 4 | to around March 2018**. **This repository is no longer being updated. It 5 | predates the official noscript repository on GitHub.** 6 | 7 | **As of July 2018, official noscript repository is [here](https://github.com/hackademix/noscript).** 8 | 9 | Files in the xpi/ subdirectory were automatically extracted from XPI files 10 | downloaded from https://addons.mozilla.org/en-US/firefox/addon/noscript. 11 | 12 | **This repository is not affiliated in any way with the developers of the 13 | NoScript add-on. Please do not report issues with NoScript itself here. 14 | Developers of the add-on can be reached at [noscript.net](https://noscript.net).** 15 | 16 | For some background on why this repository was created, see [this blog 17 | post](https://www.tablix.org/~avian/blog/archives/2012/02/too_much_noscript/). 18 | 19 | ## Building 20 | 21 | To build an XPI file, use `makexpi.sh` script: 22 | 23 | $ ./makexpi.sh [commit] 24 | 25 | ## License 26 | 27 | Following copyright notice appears in the latest version at the time of 28 | writing. Please refer to the files in the xpi/ subdirectory for details. 29 | 30 | NoScript - a Firefox extension for whitelist driven safe JavaScript execution 31 | Copyright (C) 2004-2014 Giorgio Maone - g.maone@informaction.com 32 | 33 | This program is free software; you can redistribute it and/or modify 34 | it under the terms of the GNU General Public License as published by 35 | the Free Software Foundation; either version 2 of the License, or 36 | (at your option) any later version. 37 | 38 | This program is distributed in the hope that it will be useful, 39 | but WITHOUT ANY WARRANTY; without even the implied warranty of 40 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 41 | GNU General Public License for more details. 42 | 43 | You should have received a copy of the GNU General Public License 44 | along with this program; if not, write to the 45 | Free Software Foundation, Inc., 46 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 47 | -------------------------------------------------------------------------------- /makexpi.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # builds a .xpi from the git repository, placing the .xpi in the root 3 | # of the repository. 4 | # 5 | # invoke with no arguments to build from the current src directory. 6 | # 7 | # ./makexpi.sh 8 | # 9 | # OR, invoke with a tag name to build a specific branch or tag. 10 | # 11 | # e.g.: 12 | # 13 | # ./makexpi.sh 0.2.3.development.2 14 | # 15 | # Script adapted from 16 | # https://gitweb.torproject.org/https-everywhere.git/blob/HEAD:/makexpi.sh 17 | 18 | set -e 19 | 20 | APP_NAME=noscript 21 | 22 | BUILDDIR=build 23 | 24 | cd "`dirname $0`" 25 | 26 | rm -rf "$BUILDDIR" 27 | mkdir "$BUILDDIR" 28 | 29 | # If the command line argument is a tag name, check that out and build it 30 | if [ -n "$1" ]; then 31 | cp -a .git "$BUILDDIR" 32 | cd "$BUILDDIR" 33 | git reset --hard "$1" 34 | else 35 | cp -a xpi "$BUILDDIR" 36 | cd "$BUILDDIR" 37 | fi 38 | 39 | # The name/version of the XPI we're building comes from manifest.json 40 | VERSION=`sed -ne '/"version":/{s/^.*: *"\(.*\)" *,.*$/\1/;p}' xpi/manifest.json` 41 | XPI_NAME="$APP_NAME-$VERSION" 42 | if [ "$1" ]; then 43 | XPI_NAME="$XPI_NAME.xpi" 44 | else 45 | XPI_NAME="$XPI_NAME~pre.xpi" 46 | fi 47 | 48 | ../version.py --add "$VERSION" xpi 49 | 50 | # Build the XPI! 51 | rm -f "../$XPI_NAME" 52 | (cd xpi && zip -q -r "../../$XPI_NAME" .) 53 | -------------------------------------------------------------------------------- /version.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import argparse 3 | import os 4 | import re 5 | from functools import partial 6 | 7 | def escape(match): 8 | g = match.group(1) 9 | if g is None: 10 | return b'@VERSION@' 11 | else: 12 | return b'@X' + g + b'VERSION@' 13 | 14 | def unescape(version, match): 15 | g = match.group(1) 16 | if g == b'': 17 | return version 18 | else: 19 | return b'@' + g[1:] + b'VERSION@' 20 | 21 | def main(): 22 | parser = argparse.ArgumentParser(description='version placeholder tool for noscript') 23 | parser.add_argument('--add', action='store_true', help='add version string') 24 | parser.add_argument('--strip', action='store_true', help='strip version string') 25 | parser.add_argument('version', nargs=1, help='version string to add or strip') 26 | parser.add_argument('path', nargs=1, help='path to xpi source') 27 | 28 | args = parser.parse_args() 29 | 30 | version = args.version[0].encode('ascii') 31 | path = args.path[0] 32 | 33 | if args.add and (not args.strip): 34 | patt = re.compile(b'@(X*)VERSION@') 35 | func = partial(unescape, version) 36 | elif args.strip and (not args.add): 37 | patt = re.compile(re.escape(version) + b'|@(X*)VERSION@') 38 | func = escape 39 | else: 40 | print('Either --add or --strip must be specified') 41 | return 42 | 43 | path_patt = re.compile(r'\.(?:dtd|xul|js)$') 44 | 45 | for root, dirs, files in os.walk(path): 46 | for name in files: 47 | if not path_patt.search(name): 48 | continue 49 | 50 | filepath = os.path.join(root, name) 51 | 52 | with open(filepath, 'rb') as f: 53 | data = f.read() 54 | 55 | ndata = patt.sub(func, data) 56 | if ndata != data: 57 | with open(filepath, 'wb') as f: 58 | f.write(ndata) 59 | 60 | if __name__ == '__main__': 61 | main() 62 | -------------------------------------------------------------------------------- /xpi/NoScript_License.txt: -------------------------------------------------------------------------------- 1 | NoScript - a Firefox extension for whitelist driven safe JavaScript execution 2 | Copyright (C) 2004-2014 Giorgio Maone - g.maone@informaction.com 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the 16 | Free Software Foundation, Inc., 17 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | -------------------------------------------------------------------------------- /xpi/bootstrap.js: -------------------------------------------------------------------------------- 1 | var { utils: Cu, interfaces: Ci } = Components; 2 | 3 | Cu.import("resource://gre/modules/Services.jsm"); 4 | 5 | let moduleURL = `chrome://noscript/content/Restartless.jsm?${Math.random() }.${Date.now()}`; 6 | let customizeStyle = "chrome://noscript/skin/browser.css"; 7 | let module = {}; 8 | 9 | function startup(data, reason) { 10 | Cu.import(moduleURL, module); 11 | module.startup(data, reason === APP_STARTUP); // Do whatever initial startup stuff you need to do 12 | 13 | if (module.loadIntoWindow) { 14 | forEachOpenWindow(module.loadIntoWindow); 15 | } 16 | Services.wm.addListener(WindowListener); 17 | } 18 | 19 | function shutdown(data, reason) { 20 | if (reason === APP_SHUTDOWN) 21 | return; 22 | 23 | Services.wm.removeListener(WindowListener); 24 | 25 | if (module.unloadFromWindow) forEachOpenWindow(module.unloadFromWindow); 26 | 27 | 28 | module.shutdown(data); 29 | 30 | Cu.unload(moduleURL); 31 | Services.obs.notifyObservers(null, "chrome-flush-caches", null); 32 | } 33 | function install(data, reason) { } 34 | function uninstall(data, reason) { } 35 | 36 | function forEachOpenWindow(todo) // Apply a function to all open browser windows 37 | { 38 | var windows = Services.wm.getEnumerator("navigator:browser"); 39 | while (windows.hasMoreElements()) 40 | todo(windows.getNext().QueryInterface(Ci.nsIDOMWindow)); 41 | } 42 | var WindowListener = 43 | { 44 | onOpenWindow: function(xulWindow) 45 | { 46 | var window = xulWindow.QueryInterface(Ci.nsIInterfaceRequestor) 47 | .getInterface(Ci.nsIDOMWindow); 48 | function onWindowLoad() 49 | { 50 | window.removeEventListener("DOMContentLoad",onWindowLoad); 51 | let doc = window.document; 52 | if (doc.documentElement.getAttribute("windowtype") == "navigator:browser") { 53 | module.loadIntoWindow(window, true); 54 | } else if(window.location.href === "chrome://global/content/customizeToolbar.xul") { 55 | let root = doc.documentElement; 56 | let styleNode = doc.createProcessingInstruction("xml-stylesheet",`href="${customizeStyle}" type="text/css"`); 57 | doc.insertBefore(styleNode, root); 58 | } 59 | } 60 | window.addEventListener("DOMContentLoaded", onWindowLoad); 61 | }, 62 | onCloseWindow: function(xulWindow) { }, 63 | onWindowTitleChange: function(xulWindow, newTitle) { } 64 | }; 65 | -------------------------------------------------------------------------------- /xpi/chrome.manifest: -------------------------------------------------------------------------------- 1 | content noscript chrome/content/noscript/ 2 | 3 | skin noscript classic/1.0 chrome/skin/classic/noscript/ 4 | 5 | # Work around for breakages caused by the .NET Framework Assistant 6 | override chrome://dotnetassistant/content/bootstrap.xul data:text/xml, 7 | 8 | # Localization 9 | locale noscript ar chrome/locale/ar/noscript/ 10 | locale noscript be-BY chrome/locale/be-BY/noscript/ 11 | locale noscript bg-BG chrome/locale/bg-BG/noscript/ 12 | locale noscript bn-IN chrome/locale/bn-IN/noscript/ 13 | locale noscript ca-AD chrome/locale/ca-AD/noscript/ 14 | locale noscript cs-CZ chrome/locale/cs-CZ/noscript/ 15 | locale noscript cy-GB chrome/locale/cy-GB/noscript/ 16 | locale noscript da chrome/locale/da/noscript/ 17 | locale noscript de chrome/locale/de/noscript/ 18 | locale noscript el chrome/locale/el/noscript/ 19 | locale noscript en-GB chrome/locale/en-GB/noscript/ 20 | locale noscript en-US chrome/locale/en-US/noscript/ 21 | locale noscript eo chrome/locale/eo/noscript/ 22 | locale noscript es-AR chrome/locale/es-AR/noscript/ 23 | locale noscript es-CL chrome/locale/es-CL/noscript/ 24 | locale noscript es-ES chrome/locale/es-ES/noscript/ 25 | locale noscript et-EE chrome/locale/et-EE/noscript/ 26 | locale noscript eu chrome/locale/eu/noscript/ 27 | locale noscript fa-IR chrome/locale/fa-IR/noscript/ 28 | locale noscript fi chrome/locale/fi/noscript/ 29 | locale noscript fr chrome/locale/fr/noscript/ 30 | locale noscript gl-ES chrome/locale/gl-ES/noscript/ 31 | locale noscript he-IL chrome/locale/he-IL/noscript/ 32 | locale noscript hr-HR chrome/locale/hr-HR/noscript/ 33 | locale noscript hsb chrome/locale/hsb/noscript/ 34 | locale noscript hu-HU chrome/locale/hu-HU/noscript/ 35 | locale noscript id-ID chrome/locale/id-ID/noscript/ 36 | locale noscript it chrome/locale/it/noscript/ 37 | locale noscript ja-JP chrome/locale/ja-JP/noscript/ 38 | locale noscript kk-KZ chrome/locale/kk-KZ/noscript/ 39 | locale noscript km-KH chrome/locale/km-KH/noscript/ 40 | locale noscript ko-KR chrome/locale/ko-KR/noscript/ 41 | locale noscript lt chrome/locale/lt/noscript/ 42 | locale noscript mk-MK chrome/locale/mk-MK/noscript/ 43 | locale noscript ms-MY chrome/locale/ms-MY/noscript/ 44 | locale noscript nb-NO chrome/locale/nb-NO/noscript/ 45 | locale noscript nl chrome/locale/nl/noscript/ 46 | locale noscript pl chrome/locale/pl/noscript/ 47 | locale noscript pt-BR chrome/locale/pt-BR/noscript/ 48 | locale noscript pt-PT chrome/locale/pt-PT/noscript/ 49 | locale noscript ro chrome/locale/ro/noscript/ 50 | locale noscript ru-RU chrome/locale/ru-RU/noscript/ 51 | locale noscript sk-SK chrome/locale/sk-SK/noscript/ 52 | locale noscript sl-SI chrome/locale/sl-SI/noscript/ 53 | locale noscript sr chrome/locale/sr/noscript/ 54 | locale noscript sr-RS chrome/locale/sr-RS/noscript/ 55 | locale noscript sv-SE chrome/locale/sv-SE/noscript/ 56 | locale noscript te-IN chrome/locale/te-IN/noscript/ 57 | locale noscript th chrome/locale/th/noscript/ 58 | locale noscript tr chrome/locale/tr/noscript/ 59 | locale noscript uk chrome/locale/uk/noscript/ 60 | locale noscript vi chrome/locale/vi/noscript/ 61 | locale noscript zh-CN chrome/locale/zh-CN/noscript/ 62 | locale noscript zh-TW chrome/locale/zh-TW/noscript/ 63 | -------------------------------------------------------------------------------- /xpi/chrome/content/noscript/ABE.g: -------------------------------------------------------------------------------- 1 | grammar ABE; 2 | 3 | options { 4 | language=JavaScript; 5 | output=AST; 6 | } 7 | 8 | tokens { 9 | T_ACTION; 10 | T_METHODS; 11 | } 12 | 13 | ruleset : rule* EOF ; 14 | rule : subject predicate+ -> subject predicate+ ; 15 | predicate : action methods? origin? -> T_ACTION action T_METHODS methods? origin? ; 16 | methods : (method+ | ALL) ; 17 | method : (HTTPVERB | SUB | inclusion) ; 18 | inclusion : INC (LPAR (INC_TYPE COMMA)* INC_TYPE? RPAR)? ; 19 | origin : T_FROM oresources ; 20 | subject : T_SITE resources ; 21 | oresources: (oresource+ | ALL) ; 22 | resources : (resource+ | ALL) ; 23 | oresource: resource | 'SELF' | 'SELF+' | 'SELF++' ; 24 | resource : REGEXP | GLOB | URI | LOCATION ; 25 | action : A_DENY | A_LOGOUT | A_SANDBOX | A_ACCEPT ; 26 | 27 | T_SITE : ('Site' | 'Request') ; 28 | T_FROM : ('f' | 'F') 'rom' ; 29 | A_DENY : 'Deny' ; 30 | A_LOGOUT : 'Logout' | 'Anon' 'ymize'? ; 31 | A_SANDBOX : 'Sandbox' ; 32 | A_ACCEPT : 'Accept' ; 33 | 34 | fragment URI_START : 'a'..'z' | '0'..'9' ; 35 | fragment URI_PART : 'a'..'z' | 'A'..'Z' | '0'..'9' | '_' | '-' | '.' | 36 | '[' | ']' | ':' | '/' | '@' | '~' | ';' | ',' | 37 | '?' | '&' | '=' | '%' | '#' ; 38 | LOCATION : 'LOCAL' ; 39 | URI : URI_START URI_PART+ ; 40 | GLOB : (URI_START | '*' | '.') (URI_PART | '*')* ; 41 | REGEXP : '^' ~'\n'+ ; 42 | 43 | ALL : 'ALL' ; 44 | SUB : 'SUB' ; 45 | INC : 'INC' 'LUSION'? ; 46 | HTTPVERB : 'GET' | 'POST' | 'PUT' | 'HEAD' | 'PATCH' | 'DELETE' | 'TRACE' | 'OPTIONS';nsI 47 | INC_TYPE : 'A'..'Z' ('A'..'Z' | 'A'..'Z' '_' 'A'..'Z')+ ; 48 | 49 | 50 | COMMA : ',' ; 51 | LPAR : '(' ; 52 | RPAR : ')' ; 53 | 54 | WS : (' '|'\r'|'\t'|'\u000C'|'\n') {$channel=HIDDEN;} ; 55 | COMMENT : '#' ~'\n'* {$channel=HIDDEN;} ; 56 | -------------------------------------------------------------------------------- /xpi/chrome/content/noscript/Bug.js: -------------------------------------------------------------------------------- 1 | var Bug = { 2 | 3 | }; 4 | 5 | { 6 | let lazy = { 7 | $677643: "8.0", 8 | $677050: ["6.0", "18.0"], 9 | $771655: "20", 10 | $789773: "19", 11 | } 12 | for (let b in lazy) { 13 | let v = lazy[b]; 14 | Bug.__defineGetter__(b, function() { 15 | delete this[b]; 16 | return this[b] = (typeof v[0] === "object") 17 | ? ns.geckoVersionCheck(v[0]) >= 0 && ns.geckoVersionCheck(v[1]) < 0 18 | : ns.geckoVersionCheck(v) < 0; 19 | }); 20 | } 21 | } -------------------------------------------------------------------------------- /xpi/chrome/content/noscript/ChannelReplacement.js: -------------------------------------------------------------------------------- 1 | function ChannelReplacement(chan, newURI, newMethod) { 2 | return this._init(chan, newURI, newMethod); 3 | } 4 | 5 | ChannelReplacement.runWhenPending = function(channel, callback) { 6 | callback(); 7 | }; 8 | 9 | ChannelReplacement.prototype = { 10 | _init: function(chan, newURI, newMethod) { 11 | this.oldChannel = this.channel = chan; 12 | this.newURI = newURI || chan.URI; 13 | this.newMethod = newMethod; 14 | return this; 15 | }, 16 | replace: function(realRedirect, callback) { 17 | let chan = this.channel; 18 | if (!this.newURI.equals(chan.URI)) { 19 | realRedirect = true; 20 | } 21 | if (this.newMethod && this.newMethod !== chan.requestMethod) { 22 | chan.requestMethod = this.newMethod; 23 | realRedirect = true; 24 | } 25 | 26 | let forceRedirect = !realRedirect; 27 | if (forceRedirect) { 28 | chan.redirectionLimit += 1; 29 | } else { 30 | let loadInfo = chan.loadInfo; 31 | if (loadInfo) { 32 | let type = loadInfo.externalContentPolicyType || loadInfo.contentPolicyType; 33 | forceRedirect = type === 11 || type === 12; 34 | } 35 | } 36 | 37 | if (forceRedirect) { 38 | let ncb = chan.notificationCallbacks; 39 | if (ncb) { 40 | try { 41 | let ces = ncb.getInterface(Ci.nsIChannelEventSink); 42 | if (ces) { 43 | INCLUDE("ForcedRedirectionCallback"); 44 | chan.notificationCallbacks = new NCBWrapper(ncb, new CESDelegate(ces)); 45 | } 46 | } catch (e) { 47 | // notificationCallbacks might not implement nsIChannelEventSink, e.g. in live bookmarks 48 | } 49 | } 50 | } 51 | 52 | 53 | chan.redirectTo(this.newURI); 54 | chan.suspend(); 55 | if (typeof callback === "function") callback(this); 56 | else this.open(); 57 | }, 58 | open: function() { 59 | this.channel.resume(); 60 | } 61 | }; 62 | -------------------------------------------------------------------------------- /xpi/chrome/content/noscript/DoNotTrack.js: -------------------------------------------------------------------------------- 1 | var DoNotTrack = { 2 | enabled: true, 3 | exceptions: null, 4 | forced: null, 5 | 6 | init: function(prefs) { 7 | this.prefs = prefs; 8 | for (let k of prefs.getChildList("", {})) { 9 | this.observe(prefs, null, k); 10 | } 11 | prefs.addObserver("", this, true); 12 | }, 13 | QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]), 14 | observe: function(prefs, topic, name) { 15 | switch(name) { 16 | case "enabled": 17 | this.enabled = prefs.getBoolPref(name); 18 | break; 19 | case "exceptions": 20 | case "forced": 21 | this[name] = AddressMatcher.create(COMPAT.getStringPref(prefs, name)); 22 | break; 23 | } 24 | }, 25 | 26 | apply: function(/* ABEReq */ req) { 27 | let url = req.destination; 28 | 29 | try { 30 | if ( 31 | (this.exceptions && this.exceptions.test(url) || 32 | req.localDestination || 33 | req.isDoc && req.method === "POST" && req.originURI.host === req.destinationURI.host 34 | ) && 35 | !(this.forced && this.forced.test(url)) 36 | // TODO: find a way to check whether this request is gonna be WWW-authenticated 37 | ) 38 | return; 39 | 40 | let channel = req.channel; 41 | channel.setRequestHeader("DNT", "1", false); 42 | 43 | // reorder headers to mirror Firefox 4's behavior 44 | let conn = channel.getRequestHeader("Connection"); 45 | channel.setRequestHeader("Connection", "", false); 46 | channel.setRequestHeader("Connection", conn, false); 47 | } catch(e) {} 48 | }, 49 | 50 | getDOMPatch: function(docShell) { 51 | try { 52 | if (docShell.document.defaultView.navigator.doNotTrack !== "1" && 53 | docShell.currentDocumentChannel.getRequestHeader("DNT") === "1") { 54 | return 'Object.defineProperty(window.navigator, "doNotTrack", { configurable: true, enumerable: true, value: "1" });'; 55 | } 56 | } catch (e) {} 57 | return ""; 58 | }, 59 | } 60 | -------------------------------------------------------------------------------- /xpi/chrome/content/noscript/Entities.js: -------------------------------------------------------------------------------- 1 | var Entities = { 2 | 3 | get htmlNode() { 4 | delete this.htmlNode; 5 | var impl = Cc["@mozilla.org/xul/xul-document;1"].createInstance(Ci.nsIDOMDocument).implementation; 6 | return this.htmlNode = (("createHTMLDocument" in impl) 7 | ? impl.createHTMLDocument("") 8 | : impl.createDocument( 9 | HTML_NS, "html", impl.createDocumentType( 10 | "html", "-//W3C//DTD HTML 4.01 Transitional//EN", "http://www.w3.org/TR/html4/loose.dtd" 11 | )) 12 | ).createElementNS(HTML_NS, "body"); 13 | }, 14 | convert: function(e) { 15 | try { 16 | this.htmlNode.innerHTML = e; 17 | var child = this.htmlNode.firstChild || null; 18 | return child && child.nodeValue || e; 19 | } catch(ex) { 20 | return e; 21 | } 22 | }, 23 | convertAll: function(s) { 24 | return s.replace(/[\\&][^<>]+/g, function(e) { return Entities.convert(e) }); 25 | }, 26 | convertDeep: function(s) { 27 | for (var prev = null; (s = this.convertAll(s)) !== prev || (s = unescape(s)) !== prev; prev = s); 28 | return s; 29 | }, 30 | neutralize: function(e, whitelist) { 31 | var c = this.convert(e); 32 | return (c == e) ? c : (whitelist && whitelist.test(c) ? e : e.replace(";", ",")); 33 | }, 34 | neutralizeAll: function(s, whitelist) { 35 | return s.replace(/&[\w#-]*?;/g, function(e) { return Entities.neutralize(e, whitelist || null); }); 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /xpi/chrome/content/noscript/FlashIdiocy.js: -------------------------------------------------------------------------------- 1 | FlashIdiocy.purgeBadEncodings = s => s.replace(/%(?:[0-9a-f]?(?:[^0-9a-f]|$))/ig, ""); 2 | FlashIdiocy.platformDecode = s => s.replace(/%[8-9a-f][0-9a-f]/ig, s => FlashIdiocy.map[s.substring(1).toLowerCase()]); 3 | 4 | FlashIdiocy.map = { 5 | "80": "?", 6 | "81": "", 7 | "82": "?", 8 | "83": "?", 9 | "84": "?", 10 | "85": "?", 11 | "86": "?", 12 | "87": "?", 13 | "88": "?", 14 | "89": "?", 15 | "8a": "?", 16 | "8b": "?", 17 | "8c": "?", 18 | "8d": "", 19 | "8e": "?", 20 | "8f": "", 21 | "90": "", 22 | "91": "?", 23 | "92": "?", 24 | "93": "?", 25 | "94": "?", 26 | "95": "?", 27 | "96": "?", 28 | "97": "?", 29 | "98": "?", 30 | "99": "?", 31 | "9a": "?", 32 | "9b": "?", 33 | "9c": "?", 34 | "9d": "", 35 | "9e": "?", 36 | "9f": "?", 37 | "a0": " ", 38 | "a1": "¡", 39 | "a2": "¢", 40 | "a3": "£", 41 | "a4": "¤", 42 | "a5": "¥", 43 | "a6": "¦", 44 | "a7": "§", 45 | "a8": "¨", 46 | "a9": "©", 47 | "aa": "ª", 48 | "ab": "«", 49 | "ac": "¬", 50 | "ad": "­", 51 | "ae": "®", 52 | "af": "¯", 53 | "b0": "°", 54 | "b1": "±", 55 | "b2": "²", 56 | "b3": "³", 57 | "b4": "´", 58 | "b5": "µ", 59 | "b6": "¶", 60 | "b7": "·", 61 | "b8": "¸", 62 | "b9": "¹", 63 | "ba": "º", 64 | "bb": "»", 65 | "bc": "¼", 66 | "bd": "½", 67 | "be": "¾", 68 | "bf": "¿", 69 | "c0": "À", 70 | "c1": "Á", 71 | "c2": "Â", 72 | "c3": "Ã", 73 | "c4": "Ä", 74 | "c5": "Å", 75 | "c6": "Æ", 76 | "c7": "Ç", 77 | "c8": "È", 78 | "c9": "É", 79 | "ca": "Ê", 80 | "cb": "Ë", 81 | "cc": "Ì", 82 | "cd": "Í", 83 | "ce": "Î", 84 | "cf": "Ï", 85 | "d0": "Ð", 86 | "d1": "Ñ", 87 | "d2": "Ò", 88 | "d3": "Ó", 89 | "d4": "Ô", 90 | "d5": "Õ", 91 | "d6": "Ö", 92 | "d7": "×", 93 | "d8": "Ø", 94 | "d9": "Ù", 95 | "da": "Ú", 96 | "db": "Û", 97 | "dc": "Ü", 98 | "dd": "Ý", 99 | "de": "Þ", 100 | "df": "ß", 101 | "e0": "à", 102 | "e1": "á", 103 | "e2": "â", 104 | "e3": "ã", 105 | "e4": "ä", 106 | "e5": "å", 107 | "e6": "æ", 108 | "e7": "ç", 109 | "e8": "è", 110 | "e9": "é", 111 | "ea": "ê", 112 | "eb": "ë", 113 | "ec": "ì", 114 | "ed": "í", 115 | "ee": "î", 116 | "ef": "ï", 117 | "f0": "ð", 118 | "f1": "ñ", 119 | "f2": "ò", 120 | "f3": "ó", 121 | "f4": "ô", 122 | "f5": "õ", 123 | "f6": "ö", 124 | "f7": "÷", 125 | "f8": "ø", 126 | "f9": "ù", 127 | "fa": "ú", 128 | "fb": "û", 129 | "fc": "ü", 130 | "fd": "ý", 131 | "fe": "þ", 132 | "ff": "ÿ", 133 | } 134 | -------------------------------------------------------------------------------- /xpi/chrome/content/noscript/ForcedRedirectionCallback.js: -------------------------------------------------------------------------------- 1 | 2 | function NCBWrapper(delegator, delegate) { 3 | this.delegator = delegator; 4 | this.delegate = delegate; 5 | } 6 | NCBWrapper.prototype = { 7 | QueryInterface: function(iid) { 8 | if (Ci.nsIInterfaceRequestor.equals(iid)) { 9 | return this; 10 | } 11 | return this.delegator.QueryInterface(iid); 12 | }, 13 | getInterface: function(iid) { 14 | try { 15 | return this.delegate.QueryInterface(iid); 16 | } catch (e) {} 17 | return this.delegator.getInterface(iid); 18 | } 19 | } 20 | 21 | function RCBDelegate(redirectCallback, label) { 22 | this.delegator = redirectCallback; 23 | this.label = label; 24 | } 25 | RCBDelegate.prototype = { 26 | QueryInterface: XPCOMUtils.generateQI([Ci.sIAsyncVerifyRedirectCallback]), 27 | onRedirectVerifyCallback: function(result) { 28 | try { 29 | if (result !== 0) ns.log("Overriding failed (" + result + ") redirect callback for " + this.label); // plugin failure is 2147500037 30 | this.delegator.onRedirectVerifyCallback(0); 31 | } catch (e) { 32 | ns.log(e); 33 | } 34 | } 35 | } 36 | 37 | function CESDelegate(ces) { 38 | this.delegator = ces; 39 | } 40 | CESDelegate.prototype = { 41 | QueryInterface: XPCOMUtils.generateQI([Ci.nsIChannelEventSink]), 42 | asyncOnChannelRedirect: function(oldChan, newChan, flags, callback) { 43 | let label = "plugin forced redirection"; 44 | try { 45 | label = (oldChan.loadInfo.externalContentPolicyType || oldChan.loadInfo.contentPolicyType)+ ": " + oldChan.name + " -> " + newChan.name + " - " + flags; 46 | } catch (e) { 47 | ns.log(e); 48 | } 49 | let cb = new RCBDelegate(callback, label); 50 | try { 51 | this.delegator.asyncOnChannelRedirect(oldChan, newChan, Ci.nsIChannelEventSink.REDIRECT_INTERNAL, cb); 52 | } catch (e) { 53 | ns.log(e); 54 | throw e; 55 | } finally { 56 | oldChan.notificationCallbacks = newChan.notificationCallbacks = this.delegator; 57 | } 58 | } 59 | }; 60 | -------------------------------------------------------------------------------- /xpi/chrome/content/noscript/FrameScript.jsm: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var EXPORTED_SYMBOLS = ["FrameScript"]; 4 | 5 | const { utils: Cu, interfaces: Ci, classes: Cc } = Components; 6 | 7 | Cu.import("resource://gre/modules/Services.jsm"); 8 | Cu.import("resource://gre/modules/XPCOMUtils.jsm"); 9 | 10 | const SERVICE_READY = "NoScript.ServiceReady"; 11 | const SERVICE_DISPOSE = "NoScript.Dispose"; 12 | 13 | Cu.import("chrome://noscript/content/importer.jsm"); 14 | let IMPORT = IMPORT_FOR(this); 15 | IMPORT("PasteHandler"); 16 | IMPORT("UISync"); 17 | 18 | function FrameScript(ctx) { 19 | Object.defineProperty(ctx, "ns", { 20 | get: function() { 21 | try { 22 | const CTRID = "@maone.net/noscript-service;1"; 23 | if (CTRID in Cc) { 24 | let ns = Cc[CTRID].getService().wrappedJSObject; 25 | delete this.ns; 26 | return (this.ns = ns); 27 | } 28 | } catch(e) { 29 | Cu.reportError(e); 30 | } 31 | return null; 32 | }, 33 | configurable: true, 34 | enumerable: true 35 | }); 36 | 37 | this.ctx = ctx; 38 | 39 | if (ctx.ns) { 40 | this.init(); 41 | } else { 42 | Services.obs.addObserver(this, SERVICE_READY, true); 43 | } 44 | 45 | } 46 | 47 | FrameScript.prototype = { 48 | QueryInterface: XPCOMUtils.generateQI( 49 | [Ci.nsIObserver, Ci.nsISupportsWeakReference]), 50 | init() { 51 | if (this.uiSync) return; 52 | 53 | let ctx = this.ctx; 54 | this.pasteHandler = new PasteHandler(ctx); 55 | this.uiSync = new UISync(ctx); 56 | ctx.addMessageListener("NoScript:unload", this); 57 | Services.obs.addObserver(this, SERVICE_DISPOSE, true); 58 | let ns = ctx.ns; 59 | if (ns.consoleDump && ctx.content && ctx.content.location) 60 | ns.dump(`Framescript initialized in ${ctx.content.location.href}`); 61 | }, 62 | observe(subj, topic, data) { 63 | switch(topic) { 64 | case SERVICE_READY: 65 | this.init(); 66 | break; 67 | case SERVICE_DISPOSE: 68 | this.dispose(); 69 | break; 70 | } 71 | }, 72 | receiveMessage(m) { 73 | if (m.name === "NoScript:unload") { 74 | this.dispose(); 75 | } 76 | }, 77 | dispose() { 78 | if (!this.uiSync) return; 79 | this.pasteHandler.dispose(); 80 | this.uiSync.unwire(); 81 | this.uiSync = this.pasteHandler = null; 82 | let ctx = this.ctx; 83 | let ns = ctx.ns; 84 | if (ns.consoleDump && ctx.content && ctx.content.location) 85 | this.ctx.ns.dump(`Framescript disposed in ${this.ctx.content.location.href}`); 86 | } 87 | }; 88 | -------------------------------------------------------------------------------- /xpi/chrome/content/noscript/IO.js: -------------------------------------------------------------------------------- 1 | var IO = { 2 | readFile: function(file, charset) { 3 | var res; 4 | 5 | const is = Cc["@mozilla.org/network/file-input-stream;1"] 6 | .createInstance(Ci.nsIFileInputStream ); 7 | is.init(file ,0x01, 256 /*0400*/, null); 8 | const sis = Cc["@mozilla.org/scriptableinputstream;1"] 9 | .createInstance(Ci.nsIScriptableInputStream); 10 | sis.init(is); 11 | 12 | res = sis.read(sis.available()); 13 | is.close(); 14 | 15 | if (charset !== null) { // use "null" if you want uncoverted data... 16 | const unicodeConverter = Cc["@mozilla.org/intl/scriptableunicodeconverter"] 17 | .createInstance(Ci.nsIScriptableUnicodeConverter); 18 | try { 19 | unicodeConverter.charset = charset || "UTF-8"; 20 | } catch(ex) { 21 | unicodeConverter.charset = "UTF-8"; 22 | } 23 | res = unicodeConverter.ConvertToUnicode(res); 24 | } 25 | 26 | return res; 27 | }, 28 | writeFile: function(file, content, charset) { 29 | const unicodeConverter = Cc["@mozilla.org/intl/scriptableunicodeconverter"] 30 | .createInstance(Ci.nsIScriptableUnicodeConverter); 31 | try { 32 | unicodeConverter.charset = charset || "UTF-8"; 33 | } catch(ex) { 34 | unicodeConverter.charset = "UTF-8"; 35 | } 36 | 37 | content = unicodeConverter.ConvertFromUnicode(content); 38 | const os = Cc["@mozilla.org/network/file-output-stream;1"] 39 | .createInstance(Ci.nsIFileOutputStream); 40 | os.init(file, 0x02 | 0x08 | 0x20, 448 /*0700*/, 0); 41 | os.write(content, content.length); 42 | os.close(); 43 | }, 44 | 45 | safeWriteFile: function(file, content, charset) { 46 | var tmp = file.clone(); 47 | var name = file.leafName; 48 | tmp.leafName = name + ".tmp"; 49 | tmp.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, file.exists() ? file.permissions : 384 /*0600*/); 50 | this.writeFile(tmp, content, charset); 51 | tmp.moveTo(file.parent, name); 52 | } 53 | }; 54 | -------------------------------------------------------------------------------- /xpi/chrome/content/noscript/JSURL.js: -------------------------------------------------------------------------------- 1 | var JSURL = { 2 | JS_VERSION: "1.8", 3 | load: function(url, document) { 4 | this._run(document, url.substring("javascript:".length) 5 | .replace(/(?:%[0-9a-f]{2})+/gi, function(m) { 6 | try { 7 | return decodeURIComponent(m); 8 | } catch (e) {} 9 | return unescape(m); 10 | })); 11 | }, 12 | 13 | _patch: (function() { 14 | (function patchAll(w) { 15 | if (!w || w.open && w.open._bypass) 16 | return w; 17 | 18 | var d = w.document; 19 | 20 | function op(data) { 21 | var code = "Object.getPrototypeOf(document)." + 22 | (typeof(data) === "string" 23 | ? 'write.call(document, ' + JSON.stringify(data) + ')' 24 | : 'open.call(document)' 25 | ); 26 | var s = d.createElement("script"); 27 | s.appendChild(d.createTextNode(code)); 28 | var p = d.documentElement; 29 | p.appendChild(s); 30 | p.removeChild(s); 31 | if (d.write === Object.getPrototypeOf(d).write) { 32 | patchAll(w); 33 | } 34 | } 35 | function patch(o, m, f) { 36 | var saved = o[m]; 37 | f._restore = function() { o[m] = saved }; 38 | f._bypass = saved; 39 | o[m] = f; 40 | } 41 | 42 | patch(d, "open", function() { op(null) }); 43 | patch(d, "write", function(s) { 44 | op(typeof(s) === "string" ? s : "" + s); 45 | }); 46 | patch(d, "writeln", function(s) { this.write(s + "\n") }); 47 | 48 | patch(w, "open", function() { 49 | return patchAll(w.open._bypass.apply(w, arguments)); 50 | }); 51 | 52 | return w; 53 | })(window); 54 | }).toSource() + "()", 55 | _restore: (function() { 56 | var d = window.document; 57 | d.writeln._restore(); 58 | d.write._restore(); 59 | d.open._restore(); 60 | }).toSource() + "()", 61 | 62 | _run: function(document, code) { 63 | var w = document.defaultView; 64 | var p = document.nodePrincipal; 65 | var s = ScriptSurrogate.createSandboxForWindow(w, p, { 66 | sandboxName: "NoScript::JSURL@" + document.documentURI, 67 | sandboxPrototype: w, 68 | wantXrays: false, 69 | }); 70 | var e = (script) => Cu.evalInSandbox("with(window) {" + script + "}", s); 71 | try { 72 | e(this._patch); 73 | let ret = e(code); 74 | if (typeof ret !== "undefined" && 75 | !DOM.getDocShellForWindow(w).isLoadingDocument) { 76 | s._ret_ = ret; 77 | e("window.location.href = 'javascript:' + JSON.stringify('' + this._ret_)"); 78 | delete s._ret_; 79 | Thread.yieldAll(); 80 | } 81 | } catch (e) { 82 | try { w.console.error("" + e) } catch(consoleError) { Cu.reportError(e) } 83 | } finally { 84 | try { e(this._restore) } catch(e) {} 85 | } 86 | }, 87 | 88 | } 89 | -------------------------------------------------------------------------------- /xpi/chrome/content/noscript/Lang.js: -------------------------------------------------------------------------------- 1 | // language utilities 2 | 3 | const Lang = { 4 | memoize: function(obj, funcs) { 5 | for (var p in funcs) { 6 | this._memoizeMember(obj, p, funcs[p]); 7 | } 8 | return obj; 9 | }, 10 | _memoizeMember: function(obj, prop, func) { 11 | obj.__defineGetter__(prop, function() { 12 | var r = func.apply(this); 13 | this.__defineGetter__(prop, function() { return r; }); 14 | return r; 15 | }); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /xpi/chrome/content/noscript/MSEInterception.js: -------------------------------------------------------------------------------- 1 | var MSEInterception = { 2 | sites: {}, 3 | handler(ev) { 4 | if (typeof ns === "undefined") { 5 | ev.currentTarget.removeEventListener(ev.type, argument.callee, true); 6 | return; 7 | } 8 | let target = ev.target; 9 | let mime = ev.detail.mime; 10 | let doc = target.ownerDocument || target; 11 | let url = doc.documentURI; 12 | let site = ns.getSite(url); 13 | if (ns.forbidMedia && ns.contentBlocker && !(ns.isAllowedObject(url, mime, site, site) || ns.isAllowedMime(mime, site))) { 14 | ev.preventDefault(); 15 | ev.stopPropagation(); 16 | ev.detail.blocked = true; 17 | MSEInterception.record(target, url, site, mime, true); 18 | } 19 | }, 20 | record(ctx, url, site, mime, fromDOM) { 21 | let data = { 22 | url, 23 | site, 24 | originSite: site, 25 | mime 26 | }; 27 | ns.tagForReplacement(ctx, data); 28 | ns.countObject(ctx, url); 29 | let doc = ctx.ownerDocument || ctx; 30 | if (fromDOM) { 31 | let ds = DOM.getDocShellForWindow(doc.defaultView); 32 | if (ds.isLoadingDocument) { // prevent fallback redirection from hiding us 33 | let sites = this.sites; 34 | sites[site] = data; 35 | doc.defaultView.addEventListener("load", () => delete sites[site], false); 36 | } 37 | } 38 | ns.recordBlocked(url, site); 39 | }, 40 | 41 | get interceptionDef() { 42 | delete this.interceptionDef; 43 | return (this.interceptionDef = function() { 44 | let urlMap = new WeakMap(); 45 | let createObjectURL = URL.createObjectURL; 46 | URL.createObjectURL = function(o, ...args) { 47 | let url = createObjectURL.call(this, o, ...args); 48 | if (o instanceof MediaSource) { 49 | let urls = urlMap.get(o); 50 | if (!urls) urlMap.set(o, urls = new Set()); 51 | urls.add(url); 52 | } 53 | return url; 54 | }; 55 | let proto = MediaSource.prototype; 56 | let addSourceBuffer = proto.addSourceBuffer; 57 | proto.addSourceBuffer = function(mime, ...args) { 58 | let ms = this; 59 | let urls = urlMap.get(ms); 60 | let me = Array.from(document.querySelectorAll("video,audio")).find(e => e.srcObject === ms || urls && urls.has(e.src)); 61 | let exposedMime = `${mime} (MSE)`; 62 | let ev = new CustomEvent("NoScript:MSE", {cancelable: true, detail: { mime: exposedMime, blocked: false }}); 63 | 64 | (me || document).dispatchEvent(ev); 65 | 66 | if (ev.detail.blocked) { 67 | throw new Error(`${exposedMime} blocked by NoScript`); 68 | } 69 | return addSourceBuffer.call(ms, mime, ...args); 70 | }; 71 | }.toSource() + "()"); 72 | }, 73 | reloadAllowed(docShell) { 74 | let curURL = docShell.currentURI.spec; 75 | let site = ns.getSite(curURL); 76 | if (site in this.sites) { 77 | let {url} = this.sites[site]; 78 | delete this.sites[site]; 79 | if (url !== curURL) { 80 | docShell.loadURI(url, Ci.nsIWebNavigation.LOAD_FLAGS_NONE, null, null, null); 81 | return true; 82 | } 83 | } 84 | return false; 85 | }, 86 | hook(doc, site) { 87 | let url = doc.documentURI; 88 | if (!(ns.isAllowedObject(url, "MSE", site, site) || ns.isAllowedMime("MSE", url))) { 89 | DOM.getFrameMM(doc.defaultView).addEventListener("NoScript:MSE", this.handler, true, true); 90 | if (site in this.sites) { 91 | let data = this.sites[site]; 92 | this.record(doc, data.url, data.site, data.mime); 93 | } 94 | return this.interceptionDef; 95 | } 96 | return null; 97 | } 98 | }; 99 | -------------------------------------------------------------------------------- /xpi/chrome/content/noscript/Membrane.js: -------------------------------------------------------------------------------- 1 | var Membrane = { 2 | create(real, wrap) { 3 | let shadow = {}; 4 | return new Proxy(shadow, { 5 | get: function(target, propKey, receiver) { 6 | var pd = Object.getOwnPropertyDescriptor(real, propKey); 7 | if (pd !== undefined && !pd.configurable && !pd.writable) { 8 | Object.defineProperty(target, propKey, { 9 | value: wrap(real, propKey, receiver), 10 | writable: false, 11 | configurable: false, 12 | enumerable: pd.enumerable 13 | }); 14 | return target[propKey]; 15 | } 16 | return wrap(real, propKey, receiver); 17 | } 18 | }); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /xpi/chrome/content/noscript/MimeService.js: -------------------------------------------------------------------------------- 1 | var MimeService = { 2 | _cache: new Map(), 3 | getTypeFromExtension(ext) { 4 | if (ext) { 5 | if (typeof ext !== "string") { 6 | Cu.reportError(`getTypeFromExtension ${ext}`); 7 | } 8 | let cache = this._cache; 9 | if (cache.has(ext)) { 10 | return cache.get(ext); 11 | } 12 | let res = Services.cpmm.sendSyncMessage("NoScript:getMime", {ext})[0]; 13 | cache.set(ext, res); 14 | return res; 15 | } 16 | } 17 | }; 18 | 19 | -------------------------------------------------------------------------------- /xpi/chrome/content/noscript/MimeServiceParent.js: -------------------------------------------------------------------------------- 1 | var MimeService = { 2 | QueryInterface: XPCOMUtils.generateQI([Ci.nsIMessageListener, Ci.nsISupportsWeakReference]), 3 | service: Cc['@mozilla.org/uriloader/external-helper-app-service;1'] 4 | .getService(Ci.nsIMIMEService), 5 | getTypeFromExtension(ext) { 6 | return this.service.getTypeFromExtension(ext); 7 | }, 8 | receiveMessage(m) { 9 | if (m.name === "NoScript:getMime") { 10 | try { 11 | return this.getTypeFromExtension(m.data.ext); 12 | } catch (e) { 13 | ns.dump(`Could not guess mime type for ${m.data.ext}`); 14 | } 15 | } 16 | return ''; 17 | } 18 | }; 19 | Services.ppmm.addWeakMessageListener("NoScript:getMime", MimeService); 20 | -------------------------------------------------------------------------------- /xpi/chrome/content/noscript/NoScript_License.txt: -------------------------------------------------------------------------------- 1 | NoScript - a Firefox extension for whitelist driven safe JavaScript execution 2 | Copyright (C) 2004-2014 Giorgio Maone - g.maone@informaction.com 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with this program; if not, write to the 16 | Free Software Foundation, Inc., 17 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -------------------------------------------------------------------------------- /xpi/chrome/content/noscript/PasteHandler.jsm: -------------------------------------------------------------------------------- 1 | var EXPORTED_SYMBOLS = ["PasteHandler"]; 2 | 3 | const Cu = Components.utils; 4 | 5 | Cu.import("chrome://noscript/content/importer.jsm"); 6 | let IMPORT = IMPORT_FOR(this); 7 | 8 | function PasteHandler(ctx) { 9 | this.ctx = ctx; 10 | ctx.addEventListener("paste", pasteEventHandler, true); 11 | } 12 | 13 | PasteHandler.prototype = { 14 | dispose() { 15 | this.ctx.removeEventListener("paste", pasteEventHandler, true); 16 | } 17 | } 18 | 19 | 20 | 21 | function pasteEventHandler(e) { 22 | if (typeof Cu === "undefined") { // uninstalled 23 | e.currentTarget.removeEventListener(e.type, arguments.callee, true); 24 | return; 25 | } 26 | Cu.import("resource://gre/modules/Services.jsm"); 27 | if (!Services.prefs.getBoolPref("noscript.sanitizePaste")) { 28 | return; 29 | } 30 | let data = e.clipboardData; 31 | let html = data.getData("text/html"); 32 | let t = e.target; 33 | if (t.nodeType !== 1) t = t.parentElement; 34 | 35 | let console = t.ownerDocument.defaultView.console; 36 | 37 | try { 38 | let node = t.cloneNode(); 39 | 40 | node.innerHTML = html; 41 | 42 | if (sanitizeExtras(node)) { 43 | let sanitized = node.innerHTML; 44 | IMPORT("defer"); 45 | defer(function() { try { 46 | sanitizeExtras(t); 47 | console.log("[NoScript] Sanitized\n\n" + html + "\nto\n\n" + sanitized + ""); 48 | } catch(ex) { 49 | console.log(ex); 50 | }}, 0); 51 | } 52 | } catch(ex) { 53 | console.log(ex); 54 | } 55 | } 56 | 57 | function sanitizeExtras(el) { 58 | let ret = false; 59 | 60 | // remove attributes from forms 61 | for (let f of el.getElementsByTagName("form")) { 62 | for (let a of f.attributes) { 63 | f.removeAttribute(a.name); 64 | ret = true; 65 | } 66 | } 67 | 68 | let doc = el.ownerDocument; 69 | 70 | // remove dangerous URLs (e.g. javascript: or data: URLs) 71 | for (let a of ['href', 'to', 'from', 'by', 'values']) { 72 | let res = doc.evaluate('//@' + a, el, null, /* DOMXPathResult.UNORDERED_NODE_SNAPSHOT_TYPE */ 6, null); 73 | for (let j = res.snapshotLength; j-- > 0;) { 74 | let attr = res.snapshotItem(j); 75 | if (/^\W*(?:(?:javascript|data):|https?:[\s\S]+[[(<])/i.test(unescape(attr.value))) { 76 | attr.value = "javascript:void(0)"; 77 | ret = true; 78 | } 79 | } 80 | } 81 | return ret; 82 | } 83 | 84 | -------------------------------------------------------------------------------- /xpi/chrome/content/noscript/Plugins.js: -------------------------------------------------------------------------------- 1 | var Plugins = { 2 | _disabled: false, 3 | get disabled() { return this._disabled; }, 4 | 5 | _registrar: Components.manager.nsIComponentRegistrar, 6 | _CTRID: "@mozilla.org/plugin/host;1", 7 | get _CID() { 8 | delete this._CID; 9 | return this._CID = this._registrar.contractIDToCID(this._CTRID); 10 | }, 11 | get _factory() { 12 | delete this._factory; 13 | 14 | return this._factory = Components.manager.getClassObject(Cc[this._CTRID], Ci.nsIFactory); 15 | }, 16 | 17 | set disabled(b) { 18 | if (b == this._disabled) return b; 19 | if (b) { 20 | this._registrar.unregisterFactory(this._CID, this._factory); 21 | } else { 22 | this._registrar.registerFactory(this._CID, "PluginHost", this._CTRID, this._factory); 23 | } 24 | return this._disabled = !!b; 25 | } 26 | 27 | }; 28 | // Gecko >= 2.0 seems to need the following to gets things rolling reliably 29 | Plugins.disabled = true; 30 | Plugins.disabled = false; 31 | -------------------------------------------------------------------------------- /xpi/chrome/content/noscript/Profiler.js: -------------------------------------------------------------------------------- 1 | Profiler = { 2 | watchlist: { NoScript: ns, requestWatchdog: RequestWatchdog.prototype, 3 | InjectionChecker: InjectionChecker, ABE: ABE, IOUtil: IOUtil, DNS: DNS}, 4 | data: {}, 5 | reset: function() { return this.data = {} }, 6 | 7 | instrument: function(b) { 8 | const oo = this.watchlist; 9 | const pf = "profiler.function"; 10 | for (let v in oo) { 11 | let o = oo[v] 12 | for (let n in o) { 13 | let f = o[n]; 14 | if (typeof f == "function") { 15 | if (b) { 16 | if (pf in f) continue; 17 | let key = v + "." + n; 18 | let patched = function() { 19 | let t = Date.now(); 20 | let r = f.apply(this, arguments); 21 | let pdata = Profiler.data; 22 | let data = pdata[key] || (pdata[key] = {count: 0, time: 0, min: 120000, max: 0}); 23 | data.count++; 24 | data.time += t = (Date.now() - t); 25 | if (t > data.max) data.max = t; 26 | if (t < data.min) data.min = t; 27 | return r; 28 | } 29 | patched[pf] = f; 30 | o[n] = patched; 31 | dump(key + "\n"); 32 | } else { 33 | if (pf in f) o[n] = f[pf]; 34 | } 35 | } 36 | } 37 | } 38 | }, 39 | 40 | report: function(count) { 41 | if (arguments.length === 0) count = 20; 42 | dump("\n\n\nProfiler Report"); 43 | let ar = []; 44 | for (let [call, data] in Iterator(this.data)) { 45 | data.avg = Math.round(data.time / data.count * 1000) / 1000; 46 | ar.push({call: call, data: data}); 47 | } 48 | let cmp = (a,b) => a > b ? - 1: a < b ? 1 : 0; 49 | ar.sort((a, b) => cmp(a.data.time, b.data.time)); 50 | for (let l of ar) { 51 | dump(l.call + ": " + l.data.toSource() + "\n"); 52 | if (count-- <= 0) break; 53 | } 54 | }, 55 | 56 | gc: function() { 57 | DOM.mostRecentBrowserWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor) 58 | .getInterface(Components.interfaces.nsIDOMWindowUtils) 59 | .garbageCollect(); 60 | } 61 | } 62 | 63 | 64 | -------------------------------------------------------------------------------- /xpi/chrome/content/noscript/ScriptlessBGThumbs.js: -------------------------------------------------------------------------------- 1 | { 2 | let scope = {}; 3 | Cu.import("resource://gre/modules/BackgroundPageThumbs.jsm", scope); 4 | 5 | let bpt = scope.BackgroundPageThumbs; 6 | 7 | if (!bpt._NoScript_) { 8 | let patched = bpt._NoScript_ = {}; 9 | let patch = (name, f) => { 10 | patched[name] = bpt[name]; 11 | bpt[name] = f; 12 | }; 13 | patch("capture", function() { 14 | Cu.import("resource://gre/modules/PageThumbs.jsm", scope); 15 | let PageThumbs = scope.PageThumbs; 16 | let e = PageThumbs._prefEnabled; 17 | if (!ns.getPref("bgThumbs.allowed")) { 18 | PageThumbs._prefEnabled = () => false; 19 | } 20 | try { 21 | bpt._NoScript_.capture.apply(bpt, arguments); 22 | } finally { 23 | PageThumbs._prefEnabled = e; 24 | } 25 | }); 26 | 27 | bpt._destroyBrowser(); 28 | 29 | patch("_ensureBrowser", function() { 30 | if (!this._thumbBrowser) { 31 | this._NoScript_._ensureBrowser.apply(this, arguments); 32 | if (this._thumbBrowser && ns.getPref("bgThumbs.disableJS")) 33 | this._thumbBrowser.messageManager.loadFrameScript( 34 | "data:text/javascript,docShell.allowJavascript = false", false); 35 | } 36 | }); 37 | 38 | ns.onDisposal(() => { 39 | let patched = bpt._NoScript_; 40 | if (!patched) return; 41 | for(let name of Object.keys(patched)) { 42 | bpt[name] = patched[name]; 43 | } 44 | delete bpt._NoScript_; 45 | }); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /xpi/chrome/content/noscript/Strings.js: -------------------------------------------------------------------------------- 1 | function Strings(chromeName) { 2 | this.chromeName = chromeName; 3 | } 4 | 5 | Strings.wrap = (s, count) => s.replace(new RegExp("\\w{" + (parseInt(count) || 20) + "}", 'g'), "$&\u200B"); 6 | 7 | Strings.prototype = { 8 | _rnd: `${Math.random()}-${Date.now()}`, 9 | bundles: {}, 10 | getBundle: function(path) { 11 | if (path in this.bundles) return this.bundles[path]; 12 | try { 13 | return this.bundles[path] = 14 | Cc["@mozilla.org/intl/stringbundle;1"] 15 | .getService(Ci.nsIStringBundleService) 16 | .createBundle( 17 | `chrome://${this.chromeName}/${path}/${this.chromeName}.properties?${this._rnd}` 18 | ); 19 | } catch(ex) { 20 | return this.bundles[path] = null; 21 | } 22 | }, 23 | 24 | 25 | _stringFrom: function(bundle, name, parms) { 26 | try { 27 | return parms ? bundle.formatStringFromName(name, parms, parms.length) : bundle.GetStringFromName(name); 28 | } catch(ex) { 29 | return null; 30 | } 31 | } 32 | , 33 | getString: function(name, parms) { 34 | var s = this._stringFrom(this.getBundle("locale"), name, parms); 35 | return s || name; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /xpi/chrome/content/noscript/SyntaxChecker.js: -------------------------------------------------------------------------------- 1 | function SyntaxChecker(version) { 2 | this.version = version || "1.5"; 3 | this.sandbox = new Cu.Sandbox("about:"); 4 | } 5 | 6 | SyntaxChecker.prototype = { 7 | lastError: null, 8 | lastFunction: null, 9 | check: function(script) { 10 | this.sandbox.script = script; 11 | try { 12 | return !!(this.lastFunction = this.ev("new Function(script)")); 13 | } catch(e) { 14 | this.lastError = e; 15 | this.lastFunction = null; 16 | } 17 | return false; 18 | }, 19 | unquote: function(s, q) { 20 | if (!(s[0] == q && s[s.length - 1] == q && 21 | !s.replace(/\\./g, '').replace(/^(['"])[^\n\r]*?\1/, "") 22 | )) return null; 23 | try { 24 | return this.ev(s); 25 | } catch(e) {} 26 | return null; 27 | }, 28 | ev: function(s) { 29 | return Cu.evalInSandbox(s, this.sandbox); 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /xpi/chrome/content/noscript/Thread.js: -------------------------------------------------------------------------------- 1 | var Thread = { 2 | 3 | hostRunning: true, 4 | activeLoops: 0, 5 | 6 | spin: function(ctrl) { 7 | ctrl.startTime = ctrl.startTime || Date.now(); 8 | ctrl.timeout = false; 9 | this.activeLoops++; 10 | this._spinInternal(ctrl); 11 | this.activeLoops--; 12 | ctrl.elapsed = Date.now() - ctrl.startTime; 13 | return ctrl.timeout; 14 | }, 15 | 16 | _spinInternal: function(ctrl) { 17 | var t = ctrl.startTime; 18 | var maxTime = parseInt(ctrl.maxTime); 19 | if (maxTime) { 20 | while(ctrl.running && this.hostRunning) { 21 | this.yield(); 22 | if (Date.now() - t > maxTime) { 23 | ctrl.timeout = true; 24 | ctrl.running = false; 25 | break; 26 | } 27 | } 28 | } else while(ctrl.running && this.hostRunning) this.yield(); 29 | }, 30 | 31 | yield: function() { 32 | this.current.processNextEvent(true); 33 | }, 34 | 35 | yieldAll: function() { 36 | var t = this.current; 37 | while(t.hasPendingEvents()) t.processNextEvent(false); 38 | }, 39 | 40 | get current() { 41 | delete this.current; 42 | var obj = "@mozilla.org/thread-manager;1" in Cc 43 | ? Cc["@mozilla.org/thread-manager;1"].getService() 44 | : Cc["@mozilla.org/thread;1"].createInstance(Ci.nsIThread); 45 | this.__defineGetter__("current", function() { return obj.currentThread; }); 46 | return this.current; 47 | }, 48 | 49 | get currentQueue() { 50 | delete this.currentQueue; 51 | var eqs = null; 52 | const CTRID = "@mozilla.org/event-queue-service;1"; 53 | if (CTRID in Cc) { 54 | const IFace = Ci.nsIEventQueueService; 55 | eqs = Cc[CTRID].getService(IFace); 56 | } 57 | this.__defineGetter__("currentQueue", eqs 58 | ? function() { return eqs.getSpecialEventQueue(IFace.CURRENT_THREAD_EVENT_QUEUE); } 59 | : this.__lookupGetter__("current") 60 | ); 61 | return this.currentQueue; 62 | }, 63 | 64 | delay: function(callback, time = 0, self = null, args = DUMMY_ARRAY) { 65 | var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); 66 | timer.initWithCallback({ 67 | notify: this._delayRunner, 68 | context: { callback, args, self } 69 | }, time, 0); 70 | }, 71 | 72 | dispatch: function(runnable) { 73 | this.current.dispatch(runnable, Ci.nsIEventTarget.DISPATCH_NORMAL); 74 | }, 75 | 76 | asap: function(callback, self, args = DUMMY_ARRAY) { 77 | this.current.dispatch({ 78 | run: function() { 79 | callback.apply(self, args); 80 | } 81 | }, Ci.nsIEventTarget.DISPATCH_NORMAL); 82 | }, 83 | 84 | _delayRunner: function(timer) { 85 | var ctx = this.context; 86 | try { 87 | if (typeof Thread === "undefined") return; 88 | ctx.callback.apply(ctx.self, ctx.args); 89 | } finally { 90 | this.context = null; 91 | timer.cancel(); 92 | } 93 | } 94 | 95 | }; 96 | -------------------------------------------------------------------------------- /xpi/chrome/content/noscript/URIValidator.js: -------------------------------------------------------------------------------- 1 | var URIValidator = { 2 | 3 | QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]), 4 | 5 | // returns false if absolute URI is not valid, undefined if it cannot be validated (i.e. no validator is found for this scheme) 6 | validate: function(uriSpec) { 7 | if (!uriSpec) return false; 8 | var parts = uriSpec.split(":"); 9 | if (parts.length < 2) return false; 10 | var scheme = parts.shift().toLowerCase(); 11 | if (!scheme) return false; 12 | var validator = this.validators[scheme]; 13 | try { 14 | // using unescape rather than decodeURI for a reason: 15 | // many external URL (e.g. mailto) default to ISO8859, and we would fail, 16 | // but on the other hand rules marking as invalid non-null high unicode chars are unlikely (let's hope it) 17 | return validator && validator.test(unescape(parts.join(":"))); 18 | } catch(e) { 19 | return false; 20 | } 21 | }, 22 | 23 | get validators() { 24 | delete this.validators; 25 | this._init(); 26 | return this.validators; 27 | }, 28 | 29 | prefs: null, 30 | _init: function() { 31 | this.validators = {}; 32 | this.prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService) 33 | .getBranch("noscript.urivalid."); 34 | for (var key of this.prefs.getChildList("", {})) { 35 | this.parseValidator(key); 36 | } 37 | this.prefs.addObserver("", this, true); 38 | }, 39 | parseValidator: function(key) { 40 | try { 41 | this.validators[key] = new RegExp("^" + this.prefs.getCharPref(key) + "$"); 42 | } catch(e) { 43 | delete this.validators[key]; 44 | } 45 | }, 46 | observe: function(prefs, topic, key) { 47 | this.parseValidator(key); 48 | } 49 | }; 50 | -------------------------------------------------------------------------------- /xpi/chrome/content/noscript/WebExt.js: -------------------------------------------------------------------------------- 1 | var WebExt = { 2 | enabled: false, 3 | started: false, 4 | running: false, 5 | port: null, 6 | saveData(json = ns.conf2JSON(true)) { 7 | this.tell("saveData", json); 8 | }, 9 | dumpData() { 10 | this.tell("dumpData"); 11 | }, 12 | tell(type, data) { 13 | if (this.port) try { 14 | this.port.postMessage({ type, data }); 15 | } catch (e) { 16 | if (!/\bdead object\b/.test(e.message)) { // normal on uninstall 17 | Cu.reportError(e); 18 | } 19 | } 20 | }, 21 | 22 | init(embeddedWebExtension) { 23 | WebExt.enabled = true; 24 | embeddedWebExtension.startup().then(({browser}) => { 25 | WebExt.started = true; 26 | ns.dump(`Embedded webext started`); 27 | browser.runtime.onMessage.addListener(msg => { 28 | switch(msg) { 29 | case "STARTED": 30 | WebExt.running = true; 31 | break; 32 | case "STOPPED": 33 | WebExt.running = false; 34 | break; 35 | } 36 | ns.dump(`Received message from embedded webext ${msg}`); 37 | }); 38 | browser.runtime.onConnect.addListener(port => { 39 | ns.dump(`Webext connected`); 40 | WebExt.port = port; 41 | WebExt.saveData(); 42 | }); 43 | }).catch(err => { 44 | Components.utils.reportError( 45 | `Embedded webext startup failed: ${err.message} ${err.stack}\n` 46 | ); 47 | }); 48 | }, 49 | }; 50 | -------------------------------------------------------------------------------- /xpi/chrome/content/noscript/WebGLInterception.js: -------------------------------------------------------------------------------- 1 | var WebGLInterception = { 2 | sites: {}, 3 | handler(ev) { 4 | WebGLInterception.record(ev.target, ns.getSite(ev.target.documentURI || ev.target.ownerDocument.documentURI), true); 5 | }, 6 | record(ctx, site, fromDOM) { 7 | ns.tagForReplacement(ctx, { 8 | url: site, 9 | site: site, 10 | originSite: site, 11 | mime: "WebGL" 12 | }); 13 | let doc = ctx.ownerDocument || ctx; 14 | if (fromDOM) { 15 | let ds = DOM.getDocShellForWindow(doc.defaultView); 16 | if (ds.isLoadingDocument) { // prevent fallback redirection from hiding us 17 | let sites = this.sites; 18 | sites[site] = doc.documentURI; 19 | doc.defaultView.addEventListener("load", () => delete sites[site], false); 20 | } 21 | } 22 | ns.recordBlocked(site, site); 23 | }, 24 | get interceptionDef() { 25 | delete this.interceptionDef; 26 | return (this.interceptionDef = function() { 27 | var proto = HTMLCanvasElement.prototype; 28 | var getContext = proto.getContext; 29 | proto.getContext = function(type) { 30 | if (type && type.toString().indexOf("webgl") !== -1) { 31 | var ev = this.ownerDocument.createEvent("Events"); 32 | ev.initEvent("NoScript:WebGL", true, false); 33 | (this.parentNode ? this : this.ownerDocument) 34 | .dispatchEvent(ev); 35 | return null; 36 | } 37 | return getContext.call(this, "2d"); 38 | }; 39 | }.toSource() + "()"); 40 | }, 41 | reloadAllowed(docShell) { 42 | let curURL = docShell.currentURI.spec; 43 | let site = ns.getSite(curURL); 44 | if (site in this.sites) { 45 | let url = this.sites[site]; 46 | delete this.sites[site]; 47 | if (url !== curURL) { 48 | docShell.loadURI(url, Ci.nsIWebNavigation.LOAD_FLAGS_NONE, null, null, null); 49 | return true; 50 | } 51 | } 52 | return false; 53 | }, 54 | hook(doc, site) { 55 | if (!(ns.isAllowedObject(site, "WebGL", site, site) || ns.isAllowedMime("WebGL", site))) { 56 | doc.addEventListener("NoScript:WebGL", this.handler, false, true); 57 | if (site in this.sites) { 58 | this.record(doc, site); 59 | } 60 | return this.interceptionDef; 61 | } 62 | return null; 63 | } 64 | }; 65 | -------------------------------------------------------------------------------- /xpi/chrome/content/noscript/WinScript.js: -------------------------------------------------------------------------------- 1 | var WinScript = { 2 | supported: true, 3 | block: function(window) { 4 | if (window._blockScriptForGlobal) return; 5 | try { 6 | Cu.blockScriptForGlobal(window); 7 | if (!("_blockScriptForGlobal" in window)) { 8 | this.patchStyle(window.document); 9 | } 10 | } catch (e) { 11 | if (e.message === "Script may not be disabled for system globals") { 12 | try { 13 | window.console.log("NoScript could not disable scripts for system global " + window.document.nodePrincipal.origin); 14 | } catch(e) {} 15 | return; 16 | } 17 | if (!this._childDo("block", window)) throw e; 18 | } 19 | window._blockScriptForGlobal = true; 20 | }, 21 | unblock: function(window) { 22 | if (!window._blockScriptForGlobal) return; 23 | try { 24 | Cu.unblockScriptForGlobal(window); 25 | } catch (e) { 26 | if (this._childDo("unblock", window)) throw e; 27 | } 28 | window._blockScriptForGlobal = false; 29 | }, 30 | isBlocked: function(window) { 31 | return window._blockScriptForGlobal; 32 | }, 33 | isDecided: function(window) { 34 | return "_blockScriptForGlobal" in window; 35 | }, 36 | get _childDo() { 37 | return (this._childDo = IPC.parent && IPC.parent.mm && ("isCrossProcessWrapper" in Cu) ? 38 | function(verb, window) { 39 | if (Cu.isCrossProcessWrapper(window)) { 40 | IPC.parent.mm.broadcastAsyncMessage("NoScript:WinScript", verb, { window: window }); 41 | return true; 42 | } 43 | return false; 44 | } 45 | : function() { return false; } 46 | ); 47 | }, 48 | _domUtils: Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils), 49 | patchStyle: function(doc) { 50 | let ss = this._domUtils.getAllStyleSheets(doc); 51 | // reverse loop because the preference stylesheet is almost always the last one 52 | for (let j = ss.length; j-- > 0;) { 53 | let s = ss[j]; 54 | switch(s.href) { 55 | 56 | case "about:PreferenceStyleSheet": 57 | { 58 | let rules = s.cssRules; 59 | // skip 1st & 2nd, as they are HTML & SVG namespaces 60 | for (let j = 2, len = rules.length; j < len; j++) { 61 | let r = rules[j]; 62 | if (r.cssText === "noscript { display: none ! important; }") { 63 | s.deleteRule(j); 64 | return; 65 | } 66 | } 67 | } 68 | break; 69 | case "data:text/css,noscript%20{%20display%3A%20none%20!important%3B%20}": 70 | case "resource://gre-resources/noscript.css": 71 | doc.defaultView.QueryInterface(Ci.nsIInterfaceRequestor) 72 | .getInterface(Ci.nsIDOMWindowUtils) 73 | .loadSheetUsingURIString("data:text/css,noscript { display: initial !important }", 0); 74 | return; 75 | } 76 | } 77 | } 78 | }; 79 | -------------------------------------------------------------------------------- /xpi/chrome/content/noscript/clearClick.xul: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 22 | 23 | 11 | 12 | -------------------------------------------------------------------------------- /xpi/chrome/content/noscript/tree-copy.js: -------------------------------------------------------------------------------- 1 | // Tree clipboard utils 2 | 3 | const Cc = Components.classes, Ci = Components.interfaces, Cu = Components.utils; 4 | 5 | var noscriptTreeCc = { 6 | cb: Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper), 7 | 8 | getSelectionString: function(tree, csc, rsc) { 9 | if (!rsc) rsc = "\n"; 10 | let start = new Object(), end = new Object(), v = tree.view, out = ""; 11 | let numRanges = v.selection.getRangeCount(); 12 | let b = tree.boxObject; 13 | b.QueryInterface(Ci.nsITreeBoxObject); 14 | let cols = b.columns, l = cols.length - 1; 15 | 16 | for (let i = 0; i < numRanges; i++) { 17 | v.selection.getRangeAt(i,start,end); 18 | for (let r = start.value; r <= end.value; r++) { 19 | for (let c = 0; c <= l; c++) { 20 | let f = c != l ? csc : "" 21 | out += v.getCellText(r, cols.getColumnAt(c)) + f; 22 | } 23 | out += rsc; 24 | } 25 | } 26 | return out.trim(); 27 | }, 28 | 29 | getSelectedItems: function(tree, sourceData) { 30 | let start = new Object(), end = new Object(), v = tree.view, out = []; 31 | let numRanges = v.selection.getRangeCount(); 32 | let b = tree.boxObject; 33 | b.QueryInterface(Ci.nsITreeBoxObject); 34 | let cols = b.columns, l = cols.length - 1; 35 | 36 | for (let i = 0; i < numRanges; i++) { 37 | v.selection.getRangeAt(i,start,end); 38 | for (let r = start.value; r <= end.value; r++) { 39 | out.push(sourceData[r]); 40 | } 41 | } 42 | return out; 43 | }, 44 | 45 | selectAll: function(t) { 46 | t.view.selection.selectAll(); 47 | }, 48 | 49 | doCopy: function(t, csc, rsc) { 50 | this.cb.copyString(this.getSelectionString(t, csc, rsc)); 51 | } 52 | 53 | }; 54 | -------------------------------------------------------------------------------- /xpi/chrome/locale/ar/noscript/about.properties: -------------------------------------------------------------------------------- 1 | extensions.{73a6fe31-595d-460b-a920-fcc0f8843232}.description=حمايةاضافية لفيرفوكس : نوسكربت يسمح لجافاسكربت و جافا وتقنيات اخرى فقظ للمجالات التي تثق بها. 2 | aboutTitle=عن %S 3 | extensionContributors=المساهمون: 4 | extensionContributors.tip=أشخاص يستحقون الشكر لهذا الامتداد 5 | extensionCreatorLabel=المؤلف: 6 | changelog=سجل التغييرات 7 | changelog.tip=استعرض سجلل التغييرات 8 | license=الترخيص 9 | license.tip=اقرأ رخصة المستخدم 10 | logo.tip=زيارة موقع الامتدادة 11 | sponsor.tip=زيارة موقع الراعي 12 | informaction.tip=زيارة موقع إنفورماكشن 13 | extensionHomepage.tip=زيارة موقع الامتدادة 14 | extensionCreator.tip=زيارة موقع المؤلف 15 | version= 16 | -------------------------------------------------------------------------------- /xpi/chrome/locale/ar/noscript/noscript.properties: -------------------------------------------------------------------------------- 1 | allowGlobal=السماح للسكربتات بشكل شامل (غير آمن) 2 | forbidGlobal=منع السكربتات نهائيا (محبذ) 3 | allowLocal=السماح من %S 4 | allowTemp=السماح من %S مؤقتا 5 | forbidLocal=المنع من %S 6 | allowed.glb=خطر! السكربتات مسموحة كلياً 7 | allowed.yes=السكربتات مسموحة حاليًا 8 | allowed.prt=السكربتات مسموحة جزئيًا 9 | allowed.no=السكربتات ممنوعة حاليًا 10 | global.warning.title=تحذير! 11 | global.warning.text=سيسمح للسكربتات كلياً (لكل المواقع).\nيمكن أن يكون هذا خطيرا.\nأمتأكد أنك تريد المواصلة؟ 12 | audio.samples=عينات صوتية 13 | confirm=هل أنت متأكد؟ 14 | alwaysAsk=إسأل دائما للتوكيد 15 | notifyHide=أخفِ بعد %S ثانية 16 | trust=ثق في %S 17 | distrust=ألتأشير %S كغير موثوق 18 | untrustedOrigin=مصدر غير موثوق 19 | xss.notify.generic=منع نوسكربت محاولة لتشغيل سركيبتات عبر المواقع من %S. تم تسجيل التفاصيل التقنية في المرقاب-الكونسول. 20 | xss.notify.showConsole=أظهار المرقاب-الكونسول… 21 | xss.notify.showConsole.accessKey=ر 22 | xss.reason.filterXGet=تم تطهير طلب مشبوه. المسار الأصلي [%1$S] طُلب من [%2$S]. المسار المطهر هو: [%3$S] 23 | xss.reason.filterXGetRef=تم تطهير محيل طلب مشبوه. المسار الأصلي [%1$S] طُلب من [%2$S]. المسار المطهر هو: [%3$S] 24 | xss.reason.filterXPost=تم تطهير تحميل مشبوه إلى [%1$S] من [%2$S]: تم تحويله إلى تنزيل فقط بالفعل GET. 25 | unsafeReload.warning=تجري إعادة تحميل غير آمنة\n\n[%1$S] [%2$S]\n\nمن[%3$S]\n\nلن يحمي نوسكربت هذا الطلب\n 26 | metaRefresh.notify=نوسكربت اعترض تحويلا باستخدام داخل عنصر