tbb-commits
Threads by month
- ----- 2025 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 1 participants
- 18730 discussions

[tor-browser-build/master] Bug 31467: Switch to clang for cctools project
by boklm@torproject.org 27 Aug '19
by boklm@torproject.org 27 Aug '19
27 Aug '19
commit d14719716fe9b4940686fd5a6b449fd7680176df
Author: Georg Koppen <gk(a)torproject.org>
Date: Tue Aug 20 08:55:37 2019 +0000
Bug 31467: Switch to clang for cctools project
---
projects/cctools/build | 4 ++--
projects/cctools/config | 4 ++--
projects/llvm/build | 37 -------------------------------------
projects/llvm/config | 35 -----------------------------------
4 files changed, 4 insertions(+), 76 deletions(-)
diff --git a/projects/cctools/build b/projects/cctools/build
index cad9e3a..a724399 100644
--- a/projects/cctools/build
+++ b/projects/cctools/build
@@ -2,8 +2,8 @@
[% c("var/set_default_env") -%]
distdir=/var/tmp/dist/[% project %]
mkdir -p /var/tmp/dist
-tar -C /var/tmp/dist -xf [% c('input_files_by_name/llvm') %]
-export PATH="/var/tmp/dist/llvm/bin:$PATH"
+tar -C /var/tmp/dist -xf [% c('input_files_by_name/clang') %]
+export PATH="/var/tmp/dist/clang/bin:$PATH"
mkdir -p /var/tmp/build
tar -C /var/tmp/build -xf [% project %]-[% c('version') %].tar.gz
cd /var/tmp/build/[% project %]-[% c('version') %]/cctools
diff --git a/projects/cctools/config b/projects/cctools/config
index cb84ec4..8e7ff65 100644
--- a/projects/cctools/config
+++ b/projects/cctools/config
@@ -12,5 +12,5 @@ var:
input_files:
- project: container-image
- - name: llvm
- project: llvm
+ - name: clang
+ project: clang
diff --git a/projects/llvm/build b/projects/llvm/build
deleted file mode 100644
index 0958a4c..0000000
--- a/projects/llvm/build
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/bash
-[% c("var/set_default_env") -%]
-distdir=/var/tmp/dist/[% project %]
-mkdir -p /var/tmp/dist
-tar -C /var/tmp/dist -xf [% c('input_files_by_name/cmake') %]
-export PATH="/var/tmp/dist/cmake/bin:$PATH"
-[% IF c("var/linux") %]
- # We need a link to our GCC, otherwise the system cc gets used which points to
- # /usr/bin/gcc.
- [% pc('gcc', 'var/setup', { compiler_tarfile => c('input_files_by_name/gcc'),
- hardened_gcc => 0 }) %]
- ln -s gcc /var/tmp/dist/gcc/bin/cc
-[% END -%]
-mkdir -p /var/tmp/build
-cd /var/tmp/build
-tar -xf $rootdir/[% c('input_files_by_name/llvm') %]
-tar -xf $rootdir/[% c('input_files_by_name/cfe') %]
-tar -xf $rootdir/[% c('input_files_by_name/libcxx') %]
-tar -xf $rootdir/[% c('input_files_by_name/libcxxabi') %]
-mv cfe-* clang
-mv libcxx-* libcxx
-mv libcxxabi-* libcxxabi
-mv clang llvm-*/tools
-mv libcxx llvm-*/projects
-mv libcxxabi llvm-*/projects
-cd llvm-*
-export LLVM_HOME=$(pwd)
-mkdir build
-cd build
-cmake .. -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=$distdir -DCMAKE_BUILD_TYPE:STRING=Release $LLVM_HOME
-make -j[% c("buildconf/num_procs") %]
-make install
-cd /var/tmp/dist
-[% c('tar', {
- tar_src => [ project ],
- tar_args => '-czf ' _ dest_dir _ '/' _ c('filename'),
- }) %]
diff --git a/projects/llvm/config b/projects/llvm/config
deleted file mode 100644
index 76fb2c0..0000000
--- a/projects/llvm/config
+++ /dev/null
@@ -1,35 +0,0 @@
-# vim: filetype=yaml sw=2
-version: 3.9.1
-filename: '[% project %]-[% c("version") %]-[% c("var/build_id") %].tar.gz'
-
-var:
- container:
- use_container: 1
-
-input_files:
- - project: container-image
- - name: '[% c("var/compiler") %]'
- project: '[% c("var/compiler") %]'
- enable: '[% c("var/linux") %]'
- - project: cmake
- name: cmake
- - URL: 'https://releases.llvm.org/[% c("version") %]/llvm-[% c("version") %].src.tar.xz'
- name: llvm
- sig_ext: sig
- file_gpg_id: 1
- gpg_keyring: llvm.gpg
- - URL: 'https://releases.llvm.org/[% c("version") %]/cfe-[% c("version") %].src.tar.xz'
- name: cfe
- sig_ext: sig
- file_gpg_id: 1
- gpg_keyring: llvm.gpg
- - URL: 'https://releases.llvm.org/[% c("version") %]/libcxx-[% c("version") %].src.tar.xz'
- name: libcxx
- sig_ext: sig
- file_gpg_id: 1
- gpg_keyring: llvm.gpg
- - URL: 'https://releases.llvm.org/[% c("version") %]/libcxxabi-[% c("version") %].src.tar.xz'
- name: libcxxabi
- sig_ext: sig
- file_gpg_id: 1
- gpg_keyring: llvm.gpg
1
0

[torbutton/master] Bug 10760: bring back review changes that got lost by mistake
by gk@torproject.org 27 Aug '19
by gk@torproject.org 27 Aug '19
27 Aug '19
commit 11c41cf294050dbe364f287e35f06da8b437214b
Author: Alex Catarineu <acat(a)torproject.org>
Date: Tue Aug 27 11:26:44 2019 +0200
Bug 10760: bring back review changes that got lost by mistake
---
chrome/content/aboutTor/aboutTor-content.js | 10 +++-------
chrome/content/tor-circuit-display.js | 2 +-
chrome/content/torbutton.js | 31 +++++++----------------------
chrome/content/torbutton_util.js | 1 -
components/cookie-jar-selector.js | 25 ++++++-----------------
components/domain-isolator.js | 9 ++-------
components/dragDropFilter.js | 4 ++--
components/external-app-blocker.js | 9 ++++-----
components/startup-observer.js | 30 +++++-----------------------
components/torCheckService.js | 4 ++--
components/torbutton-logger.js | 7 ++-----
modules/noscript-control.js | 4 ++--
modules/tor-control-port.js | 2 +-
modules/utils.js | 2 +-
14 files changed, 38 insertions(+), 102 deletions(-)
diff --git a/chrome/content/aboutTor/aboutTor-content.js b/chrome/content/aboutTor/aboutTor-content.js
index d4399624..01b4c2c7 100644
--- a/chrome/content/aboutTor/aboutTor-content.js
+++ b/chrome/content/aboutTor/aboutTor-content.js
@@ -14,11 +14,9 @@
* AboutTor:ChromeData privileged data chrome -> content
*/
-var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
+const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-
-Cu.import("resource://gre/modules/Services.jsm");
-let { bindPrefAndInit, show_torbrowser_manual } = Cu.import("resource://torbutton/modules/utils.js", {});
+let { bindPrefAndInit, show_torbrowser_manual } = ChromeUtils.import("resource://torbutton/modules/utils.js", {});
var AboutTorListener = {
@@ -139,9 +137,7 @@ var AboutTorListener = {
// Display the Tor Browser product name and version.
try {
const kBrandBundle = "chrome://branding/locale/brand.properties";
- let brandBundle = Cc["@mozilla.org/intl/stringbundle;1"]
- .getService(Ci.nsIStringBundleService)
- .createBundle(kBrandBundle);
+ let brandBundle = Services.strings.createBundle(kBrandBundle);
let productName = brandBundle.GetStringFromName("brandFullName");
let tbbVersion = Services.prefs.getCharPref("torbrowser.version");
let elem = content.document.getElementById("torbrowser-version");
diff --git a/chrome/content/tor-circuit-display.js b/chrome/content/tor-circuit-display.js
index 05dc14de..d21b0770 100644
--- a/chrome/content/tor-circuit-display.js
+++ b/chrome/content/tor-circuit-display.js
@@ -357,7 +357,7 @@ let setupGuardNote = function () {
["div", {},
noteBefore, ["span", {class: "circuit-guard-name"}, name],
noteAfter, " ",
- ["span", {onclick: `gBrowser.selectedTab = gBrowser.addTab('https://support.torproject.org/${localeCode}/tbb/tbb-2/', {triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()});`,
+ ["span", {onclick: `gBrowser.selectedTab = gBrowser.addWebTab('https://support.torproject.org/${localeCode}/tbb/tbb-2/');`,
class: "circuit-link"},
learnMoreString]]);
};
diff --git a/chrome/content/torbutton.js b/chrome/content/torbutton.js
index 605f6d29..0ad9d620 100644
--- a/chrome/content/torbutton.js
+++ b/chrome/content/torbutton.js
@@ -200,9 +200,7 @@ var torbutton_tor_check_observer = {
}
if (!foundTab) {
- gBrowser.selectedTab = gBrowser.addTab("about:tor", {
- triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
- });
+ gBrowser.selectedTab = gBrowser.addTrustedTab("about:tor");
}
}
}
@@ -883,7 +881,6 @@ function torbutton_new_identity() {
// conditions leading to failures (see bug 11783 for an example).
// TODO: Remove the Torbutton menu entry again once we have done our
// security control redesign.
- // document.getElementById("torbutton-new-identity").disabled = true;
document.getElementById("menu_newIdentity").disabled = true;
document.getElementById("appMenuNewIdentity").disabled = true;
@@ -909,7 +906,6 @@ function torbutton_new_identity() {
} else {
// TODO: Remove the Torbutton menu entry again once we have done our
// security control redesign.
- // document.getElementById("torbutton-new-identity").disabled = false;
document.getElementById("menu_newIdentity").disabled = false;
document.getElementById("appMenuNewIdentity").disabled = false;
}
@@ -923,7 +919,6 @@ function torbutton_new_identity() {
// security control redesign.
torbutton_log(5, "Unexpected error on new identity: " + e);
window.alert("Torbutton: Unexpected error on new identity: " + e);
- // document.getElementById("torbutton-new-identity").disabled = false;
document.getElementById("menu_newIdentity").disabled = false;
document.getElementById("appMenuNewIdentity").disabled = false;
}
@@ -1575,7 +1570,7 @@ function torbutton_close_tabs_on_new_identity() {
let tabCount = browser.browsers.length;
torbutton_log(3, "Tab count for window: " + tabCount);
- let tabsToRemove = new Array();
+ let tabsToRemove = [];
for (let i = 0; i < tabCount; i++) {
let tab = browser.getTabForBrowser(browser.browsers[i]);
if (!tab) {
@@ -1586,9 +1581,7 @@ function torbutton_close_tabs_on_new_identity() {
}
if (win == window) {
- browser.addTab("about:blank", {
- triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
- });
+ browser.addWebTab("about:blank");
} else {
// It is a bad idea to alter the window list while iterating
// over it, so add this window to an array and close it later.
@@ -1641,7 +1634,6 @@ function torbutton_check_protections()
if (!m_tb_control_pass || (!m_tb_control_ipc_file && !m_tb_control_port)) {
// TODO: Remove the Torbutton menu entry again once we have done our
// security control redesign.
- document.getElementById("torbutton-new-identity").disabled = true;
document.getElementById("menu_newIdentity").disabled = true;
document.getElementById("appMenuNewIdentity").disabled = true;
}
@@ -1651,12 +1643,6 @@ function torbutton_check_protections()
}
}
-// Bug 1506 P2: I think cookie protections is a neat feature.
-function torbutton_open_cookie_dialog() {
- showDialog(window, 'chrome://torbutton/content/torcookiedialog.xul',
- 'Cookie Protections', 'centerscreen,chrome,dialog,modal,resizable');
-}
-
// -------------- HISTORY & COOKIES ---------------------
// Bug 1506 P4: Used by New Identity if cookie protections are
@@ -1680,9 +1666,7 @@ function torbutton_disable_browser_js(browser) {
if (!browser.contentWindow)
torbutton_log(3, "No content window to disable JS events.");
else
- eventSuppressor = browser.contentWindow.
- QueryInterface(Ci.nsIInterfaceRequestor).
- getInterface(Ci.nsIDOMWindowUtils);
+ eventSuppressor = browser.contentWindow.windowUtils;
} catch(e) {
torbutton_log(4, "Failed to disable JS events: "+e)
}
@@ -1805,8 +1789,8 @@ function torbutton_do_startup()
{
if(m_tb_prefs.getBoolPref("extensions.torbutton.startup")) {
// Bug 1506: Still want to do this
- // torbutton_toggle_plugins(
- // m_tb_prefs.getBoolPref("plugin.disable"));
+ torbutton_toggle_plugins(
+ m_tb_prefs.getBoolPref("plugin.disable"));
// Bug 1506: Should probably be moved to an XPCOM component
torbutton_do_main_window_startup();
@@ -1894,10 +1878,9 @@ function showSecurityPreferencesPanel(chromeWindow) {
if (settingsTab === null) {
// Open up the settings panel in a new tab.
- tabBrowser.addTab(SECURITY_PREFERENCES_URI, {
+ tabBrowser.addTrustedTab(SECURITY_PREFERENCES_URI, {
"selected": true,
"parentId": tabBrowser.selectedTab.id,
- triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
});
} else {
// Activate an existing settings panel tab.
diff --git a/chrome/content/torbutton_util.js b/chrome/content/torbutton_util.js
index c7116a09..e6446cde 100644
--- a/chrome/content/torbutton_util.js
+++ b/chrome/content/torbutton_util.js
@@ -3,7 +3,6 @@
// code directly. I don't see any of them as essential for 1506,
// really.
-// let { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm", {});
var m_tb_torlog = Cc["@torproject.org/torbutton-logger;1"]
.getService(Ci.nsISupports).wrappedJSObject;
diff --git a/components/cookie-jar-selector.js b/components/cookie-jar-selector.js
index b3eeda53..79a66e8a 100644
--- a/components/cookie-jar-selector.js
+++ b/components/cookie-jar-selector.js
@@ -21,9 +21,9 @@ const kMODULE_CID = Components.ID("e6204253-b690-4159-bfe8-d4eedab6b3be");
ChromeUtils.import("resource://torbutton/modules/default-prefs.js", {})
.ensureDefaultPrefs();
-const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-// XXX: Must match the definition in torcookie.js :/
function Cookie(number,name,value,isDomain,host,rawHost,HttpOnly,path,isSecure,isSession,
expires,isProtected) {
this.number = number;
@@ -88,9 +88,7 @@ function CookieJarSelector() {
if (typeof(cookiesAsJS) == "undefined" || !cookiesAsJS)
return;
- var cookieManager =
- Cc["@mozilla.org/cookiemanager;1"]
- .getService(Ci.nsICookieManager2);
+ var cookieManager = Services.cookies;
for (var i = 0; i < cookiesAsJS.length; i++) {
var cookie = cookiesAsJS[i];
@@ -299,9 +297,7 @@ function CookieJarSelector() {
this.clearCookies();
return;
}
- var cookiemanager =
- Cc["@mozilla.org/cookiemanager;1"]
- .getService(Ci.nsICookieManager2);
+ var cookiemanager = Services.cookies;
var enumerator = cookiemanager.enumerator;
var count = 0;
@@ -329,7 +325,7 @@ function CookieJarSelector() {
}
// Emit cookie-changed event. This instructs other components to clear their identifiers
// (Specifically DOM storage and safe browsing, but possibly others)
- var obsSvc = Cc["@mozilla.org/observer-service;1"].getService(nsIObserverService);
+ var obsSvc = Services.obs;
obsSvc.notifyObservers(this, "cookie-changed", "cleared");
} catch (e) {
this.logger.log(5, "Error deleting unprotected cookies: " + e);
@@ -367,10 +363,6 @@ function CookieJarSelector() {
this.logger.log(2, "Cookies reloaded");
};
- // Check firefox version to know filename
- // var appInfo = Services.appinfo;
- // var versionChecker = Services.vc;
-
// This JSObject is exported directly to chrome
this.wrappedJSObject = this;
@@ -399,13 +391,9 @@ function CookieJarSelector() {
}
-const nsISupports = Ci.nsISupports;
const nsIClassInfo = Ci.nsIClassInfo;
const nsIObserver = Ci.nsIObserver;
const nsITimer = Ci.nsITimer;
-const nsIComponentRegistrar = Ci.nsIComponentRegistrar;
-const nsIObserverService = Ci.nsIObserverService;
-const nsICategoryManager = Ci.nsICategoryManager;
// Start1506: You may or may not care about this:
CookieJarSelector.prototype =
@@ -446,7 +434,7 @@ CookieJarSelector.prototype =
}
break;
case "profile-after-change":
- var obsSvc = Cc["@mozilla.org/observer-service;1"].getService(nsIObserverService);
+ var obsSvc = Services.obs;
obsSvc.addObserver(this, "cookie-changed");
// after profil loading, initialize a timer to call timerCallback
// at a specified interval
@@ -464,7 +452,6 @@ CookieJarSelector.prototype =
* XPCOMUtils.generateNSGetFactory was introduced in Mozilla 2 (Firefox 4).
* XPCOMUtils.generateNSGetModule is for Mozilla 1.9.2 (Firefox 3.6).
*/
-const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
if (XPCOMUtils.generateNSGetFactory)
var NSGetFactory = XPCOMUtils.generateNSGetFactory([CookieJarSelector]);
else
diff --git a/components/domain-isolator.js b/components/domain-isolator.js
index 891a19cc..f6a6d598 100644
--- a/components/domain-isolator.js
+++ b/components/domain-isolator.js
@@ -8,7 +8,8 @@
// ### Abbreviations
-const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
// Make the logger available.
let logger = Cc["@torproject.org/torbutton-logger;1"]
@@ -17,9 +18,6 @@ let logger = Cc["@torproject.org/torbutton-logger;1"]
let { ensureDefaultPrefs } = ChromeUtils.import("resource://torbutton/modules/default-prefs.js", {});
ensureDefaultPrefs();
-// Import Services object
-ChromeUtils.import("resource://gre/modules/Services.jsm");
-
// Import crypto object (FF 37+).
Cu.importGlobalProperties(["crypto"]);
@@ -163,9 +161,6 @@ const kMODULE_NAME = "TorBrowser Domain Isolator";
const kMODULE_CONTRACTID = "@torproject.org/domain-isolator;1";
const kMODULE_CID = Components.ID("e33fd6d4-270f-475f-a96f-ff3140279f68");
-// Import XPCOMUtils object.
-const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-
// DomainIsolator object.
function DomainIsolator() {
this.wrappedJSObject = this;
diff --git a/components/dragDropFilter.js b/components/dragDropFilter.js
index 66dbe3a4..9d6f74c8 100644
--- a/components/dragDropFilter.js
+++ b/components/dragDropFilter.js
@@ -8,8 +8,8 @@
ChromeUtils.import("resource://torbutton/modules/default-prefs.js", {}).ensureDefaultPrefs();
-const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
// Module specific constants
const kMODULE_NAME = "Torbutton Drag and Drop Handler";
diff --git a/components/external-app-blocker.js b/components/external-app-blocker.js
index 1cc2000f..afd5c002 100644
--- a/components/external-app-blocker.js
+++ b/components/external-app-blocker.js
@@ -12,9 +12,9 @@
* handle an URL (e.g., when the user clicks on a mailto: URL).
*************************************************************************/
-const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
-const {PromptUtils} = ChromeUtils.import("resource://gre/modules/SharedPromptUtils.jsm");
+const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const { PromptUtils } = ChromeUtils.import("resource://gre/modules/SharedPromptUtils.jsm");
// Module specific constants
const kMODULE_NAME = "Torbutton External App Handler";
@@ -33,8 +33,7 @@ ExternalAppBlocker.prototype =
{
_helperAppLauncher: undefined,
- QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver,
- Ci.nsIHelperAppWarningDialog]),
+ QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver, Ci.nsIHelperAppWarningDialog]),
// make this an nsIClassInfo object
flags: Ci.nsIClassInfo.DOM_OBJECT,
diff --git a/components/startup-observer.js b/components/startup-observer.js
index eea9e8db..742b1a0f 100644
--- a/components/startup-observer.js
+++ b/components/startup-observer.js
@@ -12,18 +12,14 @@
*
*************************************************************************/
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cr = Components.results;
-const Cu = Components.utils;
+const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
"resource://gre/modules/FileUtils.jsm");
-Cu.import("resource://torbutton/modules/default-prefs.js", {}).ensureDefaultPrefs();
-let NoScriptControl = Cu.import("resource://torbutton/modules/noscript-control.js", {});
+ChromeUtils.import("resource://torbutton/modules/default-prefs.js", {}).ensureDefaultPrefs();
+let NoScriptControl = ChromeUtils.import("resource://torbutton/modules/noscript-control.js", {});
// Module specific constants
const kMODULE_NAME = "Startup";
@@ -158,15 +154,7 @@ StartupObserver.prototype = {
Services.prefs.savePrefFile(null);
},
- QueryInterface: function(iid) {
- if (iid.equals(Ci.nsISupports)) {
- return this;
- }
- if(iid.equals(Ci.nsIClassInfo)) {
- return this;
- }
- return this;
- },
+ QueryInterface: ChromeUtils.generateQI([Ci.nsIClassInfo]),
// method of nsIClassInfo
classDescription: "Torbutton Startup Observer",
@@ -175,14 +163,6 @@ StartupObserver.prototype = {
// Hack to get us registered early to observe recovery
_xpcom_categories: [{category:"profile-after-change"}],
-
- getInterfaces: function(count) {
- var interfaceList = [nsIClassInfo];
- count.value = interfaceList.length;
- return interfaceList;
- },
- getHelperForLanguage: function(count) { return null; }
-
};
var NSGetFactory = XPCOMUtils.generateNSGetFactory([StartupObserver]);
diff --git a/components/torCheckService.js b/components/torCheckService.js
index d4815ee2..409cc2c5 100644
--- a/components/torCheckService.js
+++ b/components/torCheckService.js
@@ -7,7 +7,8 @@
* Tor check service
*************************************************************************/
-const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
// Module specific constants
const kMODULE_NAME = "Torbutton Tor Check Service";
@@ -130,5 +131,4 @@ TBTorCheckService.prototype =
},
};
-const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
var NSGetFactory = XPCOMUtils.generateNSGetFactory([TBTorCheckService]);
diff --git a/components/torbutton-logger.js b/components/torbutton-logger.js
index 22c664fa..52fdfc23 100644
--- a/components/torbutton-logger.js
+++ b/components/torbutton-logger.js
@@ -15,7 +15,8 @@ const kMODULE_CID = Components.ID("f36d72c9-9718-4134-b550-e109638331d7");
ChromeUtils.import("resource://torbutton/modules/default-prefs.js", {}).ensureDefaultPrefs();
-const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
function TorbuttonLogger() {
// Register observer
@@ -44,10 +45,7 @@ function TorbuttonLogger() {
* Everything below is boring boilerplate and can probably be ignored.
*/
-const nsISupports = Ci.nsISupports;
const nsIClassInfo = Ci.nsIClassInfo;
-const nsIComponentRegistrar = Ci.nsIComponentRegistrar;
-const nsIObserverService = Ci.nsIObserverService;
const logString = { 1:"VERB", 2:"DBUG", 3: "INFO", 4:"NOTE", 5:"WARN" };
@@ -162,7 +160,6 @@ TorbuttonLogger.prototype =
* XPCOMUtils.generateNSGetFactory was introduced in Mozilla 2 (Firefox 4).
* XPCOMUtils.generateNSGetModule is for Mozilla 1.9.2 (Firefox 3.6).
*/
-const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
if (XPCOMUtils.generateNSGetFactory)
var NSGetFactory = XPCOMUtils.generateNSGetFactory([TorbuttonLogger]);
else
diff --git a/modules/noscript-control.js b/modules/noscript-control.js
index 0daf15e1..0383b9b5 100644
--- a/modules/noscript-control.js
+++ b/modules/noscript-control.js
@@ -100,7 +100,7 @@ var initialize = () => {
try {
// LegacyExtensionContext is not there anymore. Using raw
- // Services.mm.broadcastAsyncMessage mecanism to communicate with
+ // Services.cpmm.sendAsyncMessage mechanism to communicate with
// NoScript.
// The component that handles WebExtensions' sendMessage.
@@ -113,7 +113,7 @@ var initialize = () => {
// TODO: Is there a better way?
let sendNoScriptSettings = settings =>
- Services.mm.broadcastAsyncMessage("MessageChannel:Messages", [{
+ Services.cpmm.sendAsyncMessage("MessageChannel:Messages", [{
messageName: "Extension:Message",
sender: { id: noscriptID, extensionId: noscriptID },
recipient: { extensionId: noscriptID },
diff --git a/modules/tor-control-port.js b/modules/tor-control-port.js
index f1d9ed14..afb3d606 100644
--- a/modules/tor-control-port.js
+++ b/modules/tor-control-port.js
@@ -22,7 +22,7 @@
let { Constructor: CC } = Components;
// ### Import Mozilla Services
-const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
// __log__.
// Logging function
diff --git a/modules/utils.js b/modules/utils.js
index 7b81819d..ea41fce9 100644
--- a/modules/utils.js
+++ b/modules/utils.js
@@ -2,7 +2,7 @@
// Various helpful utility functions.
// ### Import Mozilla Services
-const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
// ### About firstPartyDomain literal
const k_tb_about_uri_first_party_domain = "about.ef2a7dd5-93bc-417f-a698-142c3116864f.mozilla";
1
0

[torbutton/maint-2.1] Bug 31520: Remove monthly giving banner from Tor Browser
by gk@torproject.org 27 Aug '19
by gk@torproject.org 27 Aug '19
27 Aug '19
commit 0928f38e17224cf67d3059d1656f41a89f142450
Author: Alex Catarineu <acat(a)torproject.org>
Date: Tue Aug 27 12:10:10 2019 +0200
Bug 31520: Remove monthly giving banner from Tor Browser
This reverts commit 99210412d9f7b33ed40f9407e179c6cbeaa61957.
---
src/chrome/content/aboutTor/aboutTor-content.js | 19 ------
src/chrome/content/aboutTor/aboutTor.xhtml | 13 ----
src/chrome/content/torbutton.js | 17 -----
src/chrome/locale/en-US/aboutTor.dtd | 3 -
src/chrome/skin/aboutTor.css | 83 ------------------------
src/chrome/skin/icon_monthly_donors.png | Bin 3093 -> 0 bytes
src/defaults/preferences/preferences.js | 1 -
7 files changed, 136 deletions(-)
diff --git a/src/chrome/content/aboutTor/aboutTor-content.js b/src/chrome/content/aboutTor/aboutTor-content.js
index d4399624..2b65dbcf 100644
--- a/src/chrome/content/aboutTor/aboutTor-content.js
+++ b/src/chrome/content/aboutTor/aboutTor-content.js
@@ -24,7 +24,6 @@ let { bindPrefAndInit, show_torbrowser_manual } = Cu.import("resource://torbutto
var AboutTorListener = {
kAboutTorLoadedMessage: "AboutTor:Loaded",
kAboutTorChromeDataMessage: "AboutTor:ChromeData",
- kAboutTorHideDonationBanner: "AboutTor:HideDonationBanner",
get isAboutTor() {
return content.document.documentURI.toLowerCase() == "about:tor";
@@ -59,22 +58,6 @@ var AboutTorListener = {
}
},
- setupBannerClosing: function () {
- let that = this;
- let closer = content.document.getElementById("donation-banner-closer");
- closer.addEventListener("click", function () {
- sendAsyncMessage(that.kAboutTorHideDonationBanner);
- });
-
- bindPrefAndInit("extensions.torbutton.donation_banner_countdown3",
- countdown => {
- if (content.document && content.document.body) {
- content.document.body.setAttribute(
- "show-donation-banner", countdown > 0);
- }
- });
- },
-
onPageLoad: function() {
// Arrange to update localized text and links.
bindPrefAndInit("intl.locale.requested", aNewVal => {
@@ -83,8 +66,6 @@ var AboutTorListener = {
}
});
- this.setupBannerClosing();
-
// Add message and event listeners.
addMessageListener(this.kAboutTorChromeDataMessage, this);
addEventListener("pagehide", this, false);
diff --git a/src/chrome/content/aboutTor/aboutTor.xhtml b/src/chrome/content/aboutTor/aboutTor.xhtml
index 106bd936..4736f653 100644
--- a/src/chrome/content/aboutTor/aboutTor.xhtml
+++ b/src/chrome/content/aboutTor/aboutTor.xhtml
@@ -34,19 +34,6 @@ window.addEventListener("pageshow", function() {
</script>
</head>
<body dir="&locale.dir;">
- <div id="donation-banner">
- <div><!--EMPTY SPACER DIV--></div>
- <div id="donation-banner-message">
- <div id="donation-banner-icon"></div>
- <div>&aboutTor.donationBanner3.line1;
- <a href="https://donate.torproject.org/monthly-giving">
- &aboutTor.donationBanner3.line2;
- </a>
- </div>
- </div>
- <div id="donation-banner-closer">×</div>
- </div>
-
<div class="torcontent-container">
<div id="torbrowser-info">
<div id="torbrowser-version"/>
diff --git a/src/chrome/content/torbutton.js b/src/chrome/content/torbutton.js
index d9813e62..971d3023 100644
--- a/src/chrome/content/torbutton.js
+++ b/src/chrome/content/torbutton.js
@@ -22,7 +22,6 @@ const k_tb_last_browser_version_pref = "extensions.torbutton.lastBrowserVersion"
const k_tb_browser_update_needed_pref = "extensions.torbutton.updateNeeded";
const k_tb_last_update_check_pref = "extensions.torbutton.lastUpdateCheck";
const k_tb_tor_check_failed_topic = "Torbutton:TorCheckFailed";
-const k_tb_donation_banner_countdown = "extensions.torbutton.donation_banner_countdown3";
var m_tb_prefs = Services.prefs;
@@ -218,14 +217,6 @@ function torbutton_init_toolbutton()
}
}
-// Show the donation banner a finite number of times.
-function torbutton_donation_banner_countdown() {
- let count = m_tb_prefs.getIntPref(k_tb_donation_banner_countdown, 0);
- if (count > 0) {
- m_tb_prefs.setIntPref(k_tb_donation_banner_countdown, count - 1);
- }
-}
-
function torbutton_is_mobile() {
return Services.appinfo.OS === "Android";
}
@@ -338,10 +329,6 @@ function torbutton_init() {
// Add about:tor IPC message listener.
window.messageManager.addMessageListener("AboutTor:Loaded",
torbutton_abouttor_message_handler);
- window.messageManager.addMessageListener("AboutTor:HideDonationBanner",
- torbutton_abouttor_message_handler);
-
- torbutton_donation_banner_countdown();
setupPreferencesForMobile();
@@ -457,10 +444,6 @@ var torbutton_abouttor_message_handler = {
aMessage.target.messageManager.sendAsyncMessage("AboutTor:ChromeData",
this.getChromeData(true));
break;
- case "AboutTor:HideDonationBanner":
- torbutton_log(5, "message AboutTor:HideDonationBanner received");
- m_tb_prefs.setIntPref(k_tb_donation_banner_countdown, 0);
- break;
}
},
diff --git a/src/chrome/locale/en-US/aboutTor.dtd b/src/chrome/locale/en-US/aboutTor.dtd
index 5757fae4..c4273ad2 100644
--- a/src/chrome/locale/en-US/aboutTor.dtd
+++ b/src/chrome/locale/en-US/aboutTor.dtd
@@ -30,6 +30,3 @@
<!ENTITY aboutTor.newsletter.link_text "Sign up for Tor News.">
<!ENTITY aboutTor.donationBanner.line2e "Keep Tor strong.">
<!ENTITY aboutTor.donationBanner.buttonA "Donate Now">
-
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
diff --git a/src/chrome/skin/aboutTor.css b/src/chrome/skin/aboutTor.css
index 09f6208d..baa92b42 100644
--- a/src/chrome/skin/aboutTor.css
+++ b/src/chrome/skin/aboutTor.css
@@ -137,12 +137,6 @@ body:not([showmanual]) .showForManual {
margin-top: 10vh;
}
-/* Reducing this on mobile to avoid vertical overflow
- * on small screens when showing donation banner */
-body[mobile] #bottom {
- margin-top: 3vh;
-}
-
#bottom p {
font-size: 10px;
text-align: start;
@@ -310,83 +304,6 @@ body[mobile] #bottom {
border-radius: 50px 50px 0 0;
}
-/* Donation Banner
- * While this banner is present, we need to
- * offset the elements normally at the top of
- * the window.
- */
-
-#donation-banner {
- display: flex;
- align-items: stretch;
- background-color: white;
- color: var(--abouttor-bg-toron-color);
- font-size: 16px;
- height: 70px;
- justify-content: center;
- left: 0px;
- right: 0px;
- top: 0px;
- position: absolute;
- transform: translateY(-70px);
- transition: transform 200ms;
- z-index: 1;
- padding-right:38px;
-}
-
-body[mobile] #donation-banner {
- font-size: 14px;
-}
-
-body[show-donation-banner="true"] #donation-banner {
- transform: translateY(0px);
- transition: transform 0ms;
-}
-
-#donation-banner-message {
- align-items: center;
- display: flex;
- justify-content: center;
-}
-
-#donation-banner-message a {
- color: var(--abouttor-bg-toron-color);
-}
-
-#donation-banner-icon {
- background: url('chrome://torbutton/skin/icon_monthly_donors.png') no-repeat center center;
- background-size: contain;
- background-position: bottom;
- height: 56px;
- margin: 14px 16px 0px 16px;
- width: 65px;
-}
-
-#donation-banner-closer {
- display: flex;
- align-items: center;
- font-size: 20px;
- height: 22px;
- justify-content: center;
- margin: 4px;
- padding: 4px;
- position: absolute;
- offset-inline-end: 0px;
- top: 0px;
- width: 22px;
- -moz-user-select: none;
-}
-
-#donation-banner-closer:hover {
- background-color: gray;
- cursor: pointer;
-}
-
-body[show-donation-banner="true"] #onboarding-overlay-button-container,
-body[show-donation-banner="true"] .torcontent-container {
- margin-top: 72px;
-}
-
/*
* Mobile specific css
*/
diff --git a/src/chrome/skin/icon_monthly_donors.png b/src/chrome/skin/icon_monthly_donors.png
deleted file mode 100644
index 9505f471..00000000
Binary files a/src/chrome/skin/icon_monthly_donors.png and /dev/null differ
diff --git a/src/defaults/preferences/preferences.js b/src/defaults/preferences/preferences.js
index 3a2cdcd3..e5d66d55 100644
--- a/src/defaults/preferences/preferences.js
+++ b/src/defaults/preferences/preferences.js
@@ -6,7 +6,6 @@ pref("extensions.torbutton.logmethod",1); // 0=stdout, 1=errorconsole, 2=debuglo
pref("extensions.torbutton.display_circuit", true);
pref("extensions.torbutton(a)torproject.org.description", "chrome://torbutton/locale/torbutton.properties");
pref("extensions.torbutton.updateNeeded", false);
-pref("extensions.torbutton.donation_banner_countdown3", 4);
// Tor check and proxy prefs
pref("extensions.torbutton.test_enabled",true);
1
0

[torbutton/maint-2.1] fixup! Bug 31140 - Do not enable IonMonkey at low security level on AARCH64
by gk@torproject.org 27 Aug '19
by gk@torproject.org 27 Aug '19
27 Aug '19
commit 5533b49ca22cacebb2900e427413bed4444b1f87
Author: Alex Catarineu <acat(a)torproject.org>
Date: Tue Aug 27 12:42:31 2019 +0200
fixup! Bug 31140 - Do not enable IonMonkey at low security level on AARCH64
---
src/modules/security-prefs.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/modules/security-prefs.js b/src/modules/security-prefs.js
index 94480123..fb465a05 100644
--- a/src/modules/security-prefs.js
+++ b/src/modules/security-prefs.js
@@ -51,7 +51,7 @@ var write_setting_to_prefs = function (settingIndex) {
if (XPCOMABI.split("-")[0] == "aarch64" &&
prefName == "javascript.options.ion") {
setBoolPref(prefName, false);
- continue;
+ return;
}
setBoolPref(
prefName, kSecuritySettings[prefName][settingIndex]);
1
0

[tor-browser/tor-browser-60.8.0esr-8.5-1] fixup! TB4: Tor Browser's Firefox preference overrides.
by gk@torproject.org 27 Aug '19
by gk@torproject.org 27 Aug '19
27 Aug '19
commit 393eb8915c202736cd22f489724af9fa14dacb2d
Author: Georg Koppen <gk(a)torproject.org>
Date: Mon Aug 19 07:38:56 2019 +0000
fixup! TB4: Tor Browser's Firefox preference overrides.
Fixes bug 31141.
---
browser/app/profile/000-tor-browser.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/browser/app/profile/000-tor-browser.js b/browser/app/profile/000-tor-browser.js
index c810c18a84a1..5f961f40deeb 100644
--- a/browser/app/profile/000-tor-browser.js
+++ b/browser/app/profile/000-tor-browser.js
@@ -366,7 +366,7 @@ pref("font.name.sans-serif.ar", "Arial");
#endif
#ifdef XP_WIN
-pref("font.system.whitelist", "Arial, Batang, 바탕, Cambria Math, Courier New, Euphemia, Gautami, Georgia, Gulim, 굴림, GulimChe, 굴림체, Iskoola Pota, Kalinga, Kartika, Latha, Lucida Console, MS Gothic, MS ゴシック, MS Mincho, MS 明朝, MS PGothic, MS Pゴシック, MS PMincho, MS P明朝, MV Boli, Malgun Gothic, Mangal, Meiryo, Meiryo UI, Microsoft Himalaya, Microsoft JhengHei, Microsoft JengHei UI, Microsoft YaHei, 微软雅黑, Microsoft YaHei UI, MingLiU, 細明體, Noto Sans Buginese, Noto Sans Khmer, Noto Sans Lao, Noto Sans Myanmar, Noto Sans Yi, Nyala, PMingLiU, 新細明體, Plantagenet Cherokee, Raavi, Segoe UI, Shruti, SimSun, 宋体, Sylfaen, Tahoma, Times New Roman, Tunga, Verdana, Vrinda, Yu Gothic UI");
+pref("font.system.whitelist", "Arial, Batang, 바탕, Cambria Math, Courier New, Euphemia, Gautami, Georgia, Gulim, 굴림, GulimChe, 굴림체, Iskoola Pota, Kalinga, Kartika, Latha, Lucida Console, MS Gothic, MS ゴシック, MS Mincho, MS 明朝, MS PGothic, MS Pゴシック, MS PMincho, MS P明朝, MV Boli, Malgun Gothic, Mangal, Meiryo, Meiryo UI, Microsoft Himalaya, Microsoft JhengHei, Microsoft JhengHei UI, Microsoft YaHei, 微软雅黑, Microsoft YaHei UI, MingLiU, 細明體, Noto Sans Buginese, Noto Sans Khmer, Noto Sans Lao, Noto Sans Myanmar, Noto Sans Yi, Nyala, PMingLiU, 新細明體, Plantagenet Cherokee, Raavi, Segoe UI, Shruti, SimSun, 宋体, Sylfaen, Tahoma, Times New Roman, Tunga, Verdana, Vrinda, Yu Gothic UI");
#endif
#ifdef XP_LINUX
1
0

27 Aug '19
commit dd665cd95f680d7a8232220abad3cd1c623fbd66
Author: Georg Koppen <gk(a)torproject.org>
Date: Tue Aug 27 08:20:00 2019 +0000
Bump NoScript version to 11.0.3
This bump fixes our #26847 and #31287
---
projects/tor-browser/config | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/projects/tor-browser/config b/projects/tor-browser/config
index 667d579..28b2522 100644
--- a/projects/tor-browser/config
+++ b/projects/tor-browser/config
@@ -91,9 +91,9 @@ input_files:
enable: '[% c("var/snowflake") %]'
- filename: Bundle-Data
enable: '[% ! c("var/android") %]'
- - URL: https://addons.cdn.mozilla.net/user-media/addons/722/noscript_security_suit…
+ - URL: https://addons.cdn.mozilla.net/user-media/addons/722/noscript_security_suit…
name: noscript
- sha256sum: 2f9e10d2512263fbf56cb225c1622576037f01305e09e0e7757e23d13eb3f97d
+ sha256sum: 2d15f8011640b49525e5005a54486c507c11863f8d73b0742f379b16c2a4b204
- filename: 'RelativeLink/start-tor-browser.desktop'
enable: '[% c("var/linux") %]'
- filename: 'RelativeLink/execdesktop'
1
0

27 Aug '19
commit 9c03e532c542eb9f01399d39fb39d9fede00e705
Author: Georg Koppen <gk(a)torproject.org>
Date: Tue Aug 27 08:20:00 2019 +0000
Bump NoScript version to 11.0.3
This bump fixes our #26847 and #31287
---
projects/tor-browser/config | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/projects/tor-browser/config b/projects/tor-browser/config
index cf8fcb3..04e9368 100644
--- a/projects/tor-browser/config
+++ b/projects/tor-browser/config
@@ -76,9 +76,9 @@ input_files:
enable: '[% c("var/snowflake") %]'
- filename: Bundle-Data
enable: '[% ! c("var/android") %]'
- - URL: https://addons.cdn.mozilla.net/user-media/addons/722/noscript_security_suit…
+ - URL: https://addons.cdn.mozilla.net/user-media/addons/722/noscript_security_suit…
name: noscript
- sha256sum: 2f9e10d2512263fbf56cb225c1622576037f01305e09e0e7757e23d13eb3f97d
+ sha256sum: 2d15f8011640b49525e5005a54486c507c11863f8d73b0742f379b16c2a4b204
- filename: 'RelativeLink/start-tor-browser.desktop'
enable: '[% c("var/linux") %]'
- filename: 'RelativeLink/execdesktop'
1
0

[tor-browser-build/maint-8.5] Revert "5af627e10e6ab2da4dd24e8321cd2c933481d4ba"
by gk@torproject.org 27 Aug '19
by gk@torproject.org 27 Aug '19
27 Aug '19
commit 9e0ba5ce2aaf03fe436d223d591fe08f7db44865
Author: Georg Koppen <gk(a)torproject.org>
Date: Tue Aug 27 07:42:37 2019 +0000
Revert "5af627e10e6ab2da4dd24e8321cd2c933481d4ba"
This reverts commit 0dfb0a6602c5608721ddf14f8f30c6a4d57537d8.
---
projects/tor-android-service/config | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/projects/tor-android-service/config b/projects/tor-android-service/config
index 1581cc2..881b143 100644
--- a/projects/tor-android-service/config
+++ b/projects/tor-android-service/config
@@ -1,7 +1,7 @@
# vim: filetype=yaml sw=2
version: '[% c("abbrev") %]'
filename: '[% project %]-[% c("version") %]-[% c("var/build_id") %].tar.gz'
-git_hash: e7ca52e09c9bad0635ad1f2e77a23534f071b53c
+git_hash: f81e8f61fd83367aead34ae0ce3b397d2ed6a494
git_url: https://git.torproject.org/tor-android-service.git
git_submodule: 1
1
0
commit 0430509e52869e86585df054cce3b3523afe7b9c
Author: Georg Koppen <gk(a)torproject.org>
Date: Tue Aug 27 07:43:07 2019 +0000
Pick up fix for #31357
---
projects/tor-android-service/config | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/projects/tor-android-service/config b/projects/tor-android-service/config
index 881b143..1581cc2 100644
--- a/projects/tor-android-service/config
+++ b/projects/tor-android-service/config
@@ -1,7 +1,7 @@
# vim: filetype=yaml sw=2
version: '[% c("abbrev") %]'
filename: '[% project %]-[% c("version") %]-[% c("var/build_id") %].tar.gz'
-git_hash: f81e8f61fd83367aead34ae0ce3b397d2ed6a494
+git_hash: e7ca52e09c9bad0635ad1f2e77a23534f071b53c
git_url: https://git.torproject.org/tor-android-service.git
git_submodule: 1
1
0

[tor-browser-build/maint-8.5] 5af627e10e6ab2da4dd24e8321cd2c933481d4ba
by gk@torproject.org 27 Aug '19
by gk@torproject.org 27 Aug '19
27 Aug '19
commit 0dfb0a6602c5608721ddf14f8f30c6a4d57537d8
Author: Georg Koppen <gk(a)torproject.org>
Date: Tue Aug 27 07:40:14 2019 +0000
5af627e10e6ab2da4dd24e8321cd2c933481d4ba
---
projects/tor-android-service/config | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/projects/tor-android-service/config b/projects/tor-android-service/config
index 881b143..1581cc2 100644
--- a/projects/tor-android-service/config
+++ b/projects/tor-android-service/config
@@ -1,7 +1,7 @@
# vim: filetype=yaml sw=2
version: '[% c("abbrev") %]'
filename: '[% project %]-[% c("version") %]-[% c("var/build_id") %].tar.gz'
-git_hash: f81e8f61fd83367aead34ae0ce3b397d2ed6a494
+git_hash: e7ca52e09c9bad0635ad1f2e77a23534f071b53c
git_url: https://git.torproject.org/tor-android-service.git
git_submodule: 1
1
0
commit 5af627e10e6ab2da4dd24e8321cd2c933481d4ba
Author: Georg Koppen <gk(a)torproject.org>
Date: Tue Aug 27 07:36:27 2019 +0000
Pick up fix for #31357
---
projects/tor-android-service/config | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/projects/tor-android-service/config b/projects/tor-android-service/config
index e269704..9a90ebd 100644
--- a/projects/tor-android-service/config
+++ b/projects/tor-android-service/config
@@ -1,7 +1,7 @@
# vim: filetype=yaml sw=2
version: '[% c("abbrev") %]'
filename: '[% project %]-[% c("version") %]-[% c("var/build_id") %]'
-git_hash: f81e8f61fd83367aead34ae0ce3b397d2ed6a494
+git_hash: e7ca52e09c9bad0635ad1f2e77a23534f071b53c
git_url: https://git.torproject.org/tor-android-service.git
git_submodule: 1
1
0
commit e7ca52e09c9bad0635ad1f2e77a23534f071b53c
Author: Philipp Winter <phw(a)nymity.ch>
Date: Tue Aug 6 12:33:37 2019 -0700
Remove default bridge.
The operator's server contract expires at the end of August.
This fixes <https://bugs.torproject.org/31357>.
---
service/src/main/assets/common/bridges.txt | 1 -
1 file changed, 1 deletion(-)
diff --git a/service/src/main/assets/common/bridges.txt b/service/src/main/assets/common/bridges.txt
index 353ada5..c1c00a6 100644
--- a/service/src/main/assets/common/bridges.txt
+++ b/service/src/main/assets/common/bridges.txt
@@ -1,5 +1,4 @@
obfs4 192.95.36.142:443 CDF2E852BF539B82BD10E27E9115A31734E378C2 cert=qUVQ0srL1JI/vO6V6m/24anYXiJD3QP2HgzUKQtQ7GRqqUvs7P+tG43RtAqdhLOALP7DJQ iat-mode=1
-obfs4 85.17.30.79:443 FC259A04A328A07FED1413E9FC6526530D9FD87A cert=RutxZlu8BtyP+y0NX7bAVD41+J/qXNhHUrKjFkRSdiBAhIHIQLhKQ2HxESAKZprn/lR3KA iat-mode=0
obfs4 38.229.1.78:80 C8CBDB2464FC9804A69531437BCF2BE31FDD2EE4 cert=Hmyfd2ev46gGY7NoVxA9ngrPF2zCZtzskRTzoWXbxNkzeVnGFPWmrTtILRyqCTjHR+s9dg iat-mode=1
obfs4 [2001:470:b381:bfff:216:3eff:fe23:d6c3]:443 CDF2E852BF539B82BD10E27E9115A31734E378C2 cert=qUVQ0srL1JI/vO6V6m/24anYXiJD3QP2HgzUKQtQ7GRqqUvs7P+tG43RtAqdhLOALP7DJQ iat-mode=1
obfs4 37.218.240.34:40035 88CD36D45A35271963EF82E511C8827A24730913 cert=eGXYfWODcgqIdPJ+rRupg4GGvVGfh25FWaIXZkit206OSngsp7GAIiGIXOJJROMxEqFKJg iat-mode=1
1
0
commit baf55154a76c0c593eda2857906e0d2a1671a4d7
Author: Philipp Winter <phw(a)nymity.ch>
Date: Tue Aug 6 12:21:41 2019 -0700
Remove default bridge.
The operator's server contract expires at the end of August.
This fixes <https://bugs.torproject.org/31357>.
---
.../tor-browser/Bundle-Data/PTConfigs/bridge_prefs.js | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/projects/tor-browser/Bundle-Data/PTConfigs/bridge_prefs.js b/projects/tor-browser/Bundle-Data/PTConfigs/bridge_prefs.js
index 4eb4644..3405a53 100644
--- a/projects/tor-browser/Bundle-Data/PTConfigs/bridge_prefs.js
+++ b/projects/tor-browser/Bundle-Data/PTConfigs/bridge_prefs.js
@@ -3,16 +3,15 @@ pref("extensions.torlauncher.default_bridge_recommended_type", "obfs4");
// Default bridges.
pref("extensions.torlauncher.default_bridge.obfs4.1", "obfs4 192.95.36.142:443 CDF2E852BF539B82BD10E27E9115A31734E378C2 cert=qUVQ0srL1JI/vO6V6m/24anYXiJD3QP2HgzUKQtQ7GRqqUvs7P+tG43RtAqdhLOALP7DJQ iat-mode=1");
-pref("extensions.torlauncher.default_bridge.obfs4.2", "obfs4 85.17.30.79:443 FC259A04A328A07FED1413E9FC6526530D9FD87A cert=RutxZlu8BtyP+y0NX7bAVD41+J/qXNhHUrKjFkRSdiBAhIHIQLhKQ2HxESAKZprn/lR3KA iat-mode=0");
-pref("extensions.torlauncher.default_bridge.obfs4.3", "obfs4 38.229.1.78:80 C8CBDB2464FC9804A69531437BCF2BE31FDD2EE4 cert=Hmyfd2ev46gGY7NoVxA9ngrPF2zCZtzskRTzoWXbxNkzeVnGFPWmrTtILRyqCTjHR+s9dg iat-mode=1");
-/**/pref/**/(/**/"extensions.torlauncher.default_bridge.obfs4.4"/**/, /**/"obfs4 38.229.33.83:80 0BAC39417268B96B9F514E7F63FA6FBA1A788955 cert=VwEFpk9F/UN9JED7XpG1XOjm/O8ZCXK80oPecgWnNDZDv5pdkhq1OpbAH0wNqOT6H6BmRQ iat-mode=1");
-pref("extensions.torlauncher.default_bridge.obfs4.5", "obfs4 [2001:470:b381:bfff:216:3eff:fe23:d6c3]:443 CDF2E852BF539B82BD10E27E9115A31734E378C2 cert=qUVQ0srL1JI/vO6V6m/24anYXiJD3QP2HgzUKQtQ7GRqqUvs7P+tG43RtAqdhLOALP7DJQ iat-mode=1");
-pref("extensions.torlauncher.default_bridge.obfs4.6", "obfs4 37.218.240.34:40035 88CD36D45A35271963EF82E511C8827A24730913 cert=eGXYfWODcgqIdPJ+rRupg4GGvVGfh25FWaIXZkit206OSngsp7GAIiGIXOJJROMxEqFKJg iat-mode=1");
-pref("extensions.torlauncher.default_bridge.obfs4.7", "obfs4 37.218.245.14:38224 D9A82D2F9C2F65A18407B1D2B764F130847F8B5D cert=bjRaMrr1BRiAW8IE9U5z27fQaYgOhX1UCmOpg2pFpoMvo6ZgQMzLsaTzzQNTlm7hNcb+Sg iat-mode=0");
-pref("extensions.torlauncher.default_bridge.obfs4.8", "obfs4 85.31.186.98:443 011F2599C0E9B27EE74B353155E244813763C3E5 cert=ayq0XzCwhpdysn5o0EyDUbmSOx3X/oTEbzDMvczHOdBJKlvIdHHLJGkZARtT4dcBFArPPg iat-mode=0");
-pref("extensions.torlauncher.default_bridge.obfs4.9", "obfs4 85.31.186.26:443 91A6354697E6B02A386312F68D82CF86824D3606 cert=PBwr+S8JTVZo6MPdHnkTwXJPILWADLqfMGoVvhZClMq/Urndyd42BwX9YFJHZnBB3H0XCw iat-mode=0");
-pref("extensions.torlauncher.default_bridge.obfs4.10", "obfs4 216.252.162.21:46089 0DB8799466902192B6C7576D58D4F7F714EC87C1 cert=XPUwcQPxEXExHfJYX58gZXN7mYpos7VNAHbkgERNFg+FCVNzuYo1Wp+uMscl3aR9hO2DRQ iat-mode=0");
-pref("extensions.torlauncher.default_bridge.obfs4.11", "obfs4 144.217.20.138:80 FB70B257C162BF1038CA669D568D76F5B7F0BABB cert=vYIV5MgrghGQvZPIi1tJwnzorMgqgmlKaB77Y3Z9Q/v94wZBOAXkW+fdx4aSxLVnKO+xNw iat-mode=0");
+pref("extensions.torlauncher.default_bridge.obfs4.2", "obfs4 38.229.1.78:80 C8CBDB2464FC9804A69531437BCF2BE31FDD2EE4 cert=Hmyfd2ev46gGY7NoVxA9ngrPF2zCZtzskRTzoWXbxNkzeVnGFPWmrTtILRyqCTjHR+s9dg iat-mode=1");
+/**/pref/**/(/**/"extensions.torlauncher.default_bridge.obfs4.3"/**/, /**/"obfs4 38.229.33.83:80 0BAC39417268B96B9F514E7F63FA6FBA1A788955 cert=VwEFpk9F/UN9JED7XpG1XOjm/O8ZCXK80oPecgWnNDZDv5pdkhq1OpbAH0wNqOT6H6BmRQ iat-mode=1");
+pref("extensions.torlauncher.default_bridge.obfs4.4", "obfs4 [2001:470:b381:bfff:216:3eff:fe23:d6c3]:443 CDF2E852BF539B82BD10E27E9115A31734E378C2 cert=qUVQ0srL1JI/vO6V6m/24anYXiJD3QP2HgzUKQtQ7GRqqUvs7P+tG43RtAqdhLOALP7DJQ iat-mode=1");
+pref("extensions.torlauncher.default_bridge.obfs4.5", "obfs4 37.218.240.34:40035 88CD36D45A35271963EF82E511C8827A24730913 cert=eGXYfWODcgqIdPJ+rRupg4GGvVGfh25FWaIXZkit206OSngsp7GAIiGIXOJJROMxEqFKJg iat-mode=1");
+pref("extensions.torlauncher.default_bridge.obfs4.6", "obfs4 37.218.245.14:38224 D9A82D2F9C2F65A18407B1D2B764F130847F8B5D cert=bjRaMrr1BRiAW8IE9U5z27fQaYgOhX1UCmOpg2pFpoMvo6ZgQMzLsaTzzQNTlm7hNcb+Sg iat-mode=0");
+pref("extensions.torlauncher.default_bridge.obfs4.7", "obfs4 85.31.186.98:443 011F2599C0E9B27EE74B353155E244813763C3E5 cert=ayq0XzCwhpdysn5o0EyDUbmSOx3X/oTEbzDMvczHOdBJKlvIdHHLJGkZARtT4dcBFArPPg iat-mode=0");
+pref("extensions.torlauncher.default_bridge.obfs4.8", "obfs4 85.31.186.26:443 91A6354697E6B02A386312F68D82CF86824D3606 cert=PBwr+S8JTVZo6MPdHnkTwXJPILWADLqfMGoVvhZClMq/Urndyd42BwX9YFJHZnBB3H0XCw iat-mode=0");
+pref("extensions.torlauncher.default_bridge.obfs4.9", "obfs4 216.252.162.21:46089 0DB8799466902192B6C7576D58D4F7F714EC87C1 cert=XPUwcQPxEXExHfJYX58gZXN7mYpos7VNAHbkgERNFg+FCVNzuYo1Wp+uMscl3aR9hO2DRQ iat-mode=0");
+pref("extensions.torlauncher.default_bridge.obfs4.10", "obfs4 144.217.20.138:80 FB70B257C162BF1038CA669D568D76F5B7F0BABB cert=vYIV5MgrghGQvZPIi1tJwnzorMgqgmlKaB77Y3Z9Q/v94wZBOAXkW+fdx4aSxLVnKO+xNw iat-mode=0");
pref("extensions.torlauncher.default_bridge.meek-azure.1", "meek 0.0.2.0:2 97700DFE9F483596DDA6264C4D7DF7641E1E39CE url=https://meek.azureedge.net/ front=ajax.aspnetcdn.com");
1
0
commit fa9325b3cc143ce7b72308ad4727fb0a96268915
Author: Philipp Winter <phw(a)nymity.ch>
Date: Tue Aug 6 12:21:41 2019 -0700
Remove default bridge.
The operator's server contract expires at the end of August.
This fixes <https://bugs.torproject.org/31357>.
---
.../tor-browser/Bundle-Data/PTConfigs/bridge_prefs.js | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/projects/tor-browser/Bundle-Data/PTConfigs/bridge_prefs.js b/projects/tor-browser/Bundle-Data/PTConfigs/bridge_prefs.js
index 4eb4644..3405a53 100644
--- a/projects/tor-browser/Bundle-Data/PTConfigs/bridge_prefs.js
+++ b/projects/tor-browser/Bundle-Data/PTConfigs/bridge_prefs.js
@@ -3,16 +3,15 @@ pref("extensions.torlauncher.default_bridge_recommended_type", "obfs4");
// Default bridges.
pref("extensions.torlauncher.default_bridge.obfs4.1", "obfs4 192.95.36.142:443 CDF2E852BF539B82BD10E27E9115A31734E378C2 cert=qUVQ0srL1JI/vO6V6m/24anYXiJD3QP2HgzUKQtQ7GRqqUvs7P+tG43RtAqdhLOALP7DJQ iat-mode=1");
-pref("extensions.torlauncher.default_bridge.obfs4.2", "obfs4 85.17.30.79:443 FC259A04A328A07FED1413E9FC6526530D9FD87A cert=RutxZlu8BtyP+y0NX7bAVD41+J/qXNhHUrKjFkRSdiBAhIHIQLhKQ2HxESAKZprn/lR3KA iat-mode=0");
-pref("extensions.torlauncher.default_bridge.obfs4.3", "obfs4 38.229.1.78:80 C8CBDB2464FC9804A69531437BCF2BE31FDD2EE4 cert=Hmyfd2ev46gGY7NoVxA9ngrPF2zCZtzskRTzoWXbxNkzeVnGFPWmrTtILRyqCTjHR+s9dg iat-mode=1");
-/**/pref/**/(/**/"extensions.torlauncher.default_bridge.obfs4.4"/**/, /**/"obfs4 38.229.33.83:80 0BAC39417268B96B9F514E7F63FA6FBA1A788955 cert=VwEFpk9F/UN9JED7XpG1XOjm/O8ZCXK80oPecgWnNDZDv5pdkhq1OpbAH0wNqOT6H6BmRQ iat-mode=1");
-pref("extensions.torlauncher.default_bridge.obfs4.5", "obfs4 [2001:470:b381:bfff:216:3eff:fe23:d6c3]:443 CDF2E852BF539B82BD10E27E9115A31734E378C2 cert=qUVQ0srL1JI/vO6V6m/24anYXiJD3QP2HgzUKQtQ7GRqqUvs7P+tG43RtAqdhLOALP7DJQ iat-mode=1");
-pref("extensions.torlauncher.default_bridge.obfs4.6", "obfs4 37.218.240.34:40035 88CD36D45A35271963EF82E511C8827A24730913 cert=eGXYfWODcgqIdPJ+rRupg4GGvVGfh25FWaIXZkit206OSngsp7GAIiGIXOJJROMxEqFKJg iat-mode=1");
-pref("extensions.torlauncher.default_bridge.obfs4.7", "obfs4 37.218.245.14:38224 D9A82D2F9C2F65A18407B1D2B764F130847F8B5D cert=bjRaMrr1BRiAW8IE9U5z27fQaYgOhX1UCmOpg2pFpoMvo6ZgQMzLsaTzzQNTlm7hNcb+Sg iat-mode=0");
-pref("extensions.torlauncher.default_bridge.obfs4.8", "obfs4 85.31.186.98:443 011F2599C0E9B27EE74B353155E244813763C3E5 cert=ayq0XzCwhpdysn5o0EyDUbmSOx3X/oTEbzDMvczHOdBJKlvIdHHLJGkZARtT4dcBFArPPg iat-mode=0");
-pref("extensions.torlauncher.default_bridge.obfs4.9", "obfs4 85.31.186.26:443 91A6354697E6B02A386312F68D82CF86824D3606 cert=PBwr+S8JTVZo6MPdHnkTwXJPILWADLqfMGoVvhZClMq/Urndyd42BwX9YFJHZnBB3H0XCw iat-mode=0");
-pref("extensions.torlauncher.default_bridge.obfs4.10", "obfs4 216.252.162.21:46089 0DB8799466902192B6C7576D58D4F7F714EC87C1 cert=XPUwcQPxEXExHfJYX58gZXN7mYpos7VNAHbkgERNFg+FCVNzuYo1Wp+uMscl3aR9hO2DRQ iat-mode=0");
-pref("extensions.torlauncher.default_bridge.obfs4.11", "obfs4 144.217.20.138:80 FB70B257C162BF1038CA669D568D76F5B7F0BABB cert=vYIV5MgrghGQvZPIi1tJwnzorMgqgmlKaB77Y3Z9Q/v94wZBOAXkW+fdx4aSxLVnKO+xNw iat-mode=0");
+pref("extensions.torlauncher.default_bridge.obfs4.2", "obfs4 38.229.1.78:80 C8CBDB2464FC9804A69531437BCF2BE31FDD2EE4 cert=Hmyfd2ev46gGY7NoVxA9ngrPF2zCZtzskRTzoWXbxNkzeVnGFPWmrTtILRyqCTjHR+s9dg iat-mode=1");
+/**/pref/**/(/**/"extensions.torlauncher.default_bridge.obfs4.3"/**/, /**/"obfs4 38.229.33.83:80 0BAC39417268B96B9F514E7F63FA6FBA1A788955 cert=VwEFpk9F/UN9JED7XpG1XOjm/O8ZCXK80oPecgWnNDZDv5pdkhq1OpbAH0wNqOT6H6BmRQ iat-mode=1");
+pref("extensions.torlauncher.default_bridge.obfs4.4", "obfs4 [2001:470:b381:bfff:216:3eff:fe23:d6c3]:443 CDF2E852BF539B82BD10E27E9115A31734E378C2 cert=qUVQ0srL1JI/vO6V6m/24anYXiJD3QP2HgzUKQtQ7GRqqUvs7P+tG43RtAqdhLOALP7DJQ iat-mode=1");
+pref("extensions.torlauncher.default_bridge.obfs4.5", "obfs4 37.218.240.34:40035 88CD36D45A35271963EF82E511C8827A24730913 cert=eGXYfWODcgqIdPJ+rRupg4GGvVGfh25FWaIXZkit206OSngsp7GAIiGIXOJJROMxEqFKJg iat-mode=1");
+pref("extensions.torlauncher.default_bridge.obfs4.6", "obfs4 37.218.245.14:38224 D9A82D2F9C2F65A18407B1D2B764F130847F8B5D cert=bjRaMrr1BRiAW8IE9U5z27fQaYgOhX1UCmOpg2pFpoMvo6ZgQMzLsaTzzQNTlm7hNcb+Sg iat-mode=0");
+pref("extensions.torlauncher.default_bridge.obfs4.7", "obfs4 85.31.186.98:443 011F2599C0E9B27EE74B353155E244813763C3E5 cert=ayq0XzCwhpdysn5o0EyDUbmSOx3X/oTEbzDMvczHOdBJKlvIdHHLJGkZARtT4dcBFArPPg iat-mode=0");
+pref("extensions.torlauncher.default_bridge.obfs4.8", "obfs4 85.31.186.26:443 91A6354697E6B02A386312F68D82CF86824D3606 cert=PBwr+S8JTVZo6MPdHnkTwXJPILWADLqfMGoVvhZClMq/Urndyd42BwX9YFJHZnBB3H0XCw iat-mode=0");
+pref("extensions.torlauncher.default_bridge.obfs4.9", "obfs4 216.252.162.21:46089 0DB8799466902192B6C7576D58D4F7F714EC87C1 cert=XPUwcQPxEXExHfJYX58gZXN7mYpos7VNAHbkgERNFg+FCVNzuYo1Wp+uMscl3aR9hO2DRQ iat-mode=0");
+pref("extensions.torlauncher.default_bridge.obfs4.10", "obfs4 144.217.20.138:80 FB70B257C162BF1038CA669D568D76F5B7F0BABB cert=vYIV5MgrghGQvZPIi1tJwnzorMgqgmlKaB77Y3Z9Q/v94wZBOAXkW+fdx4aSxLVnKO+xNw iat-mode=0");
pref("extensions.torlauncher.default_bridge.meek-azure.1", "meek 0.0.2.0:2 97700DFE9F483596DDA6264C4D7DF7641E1E39CE url=https://meek.azureedge.net/ front=ajax.aspnetcdn.com");
1
0

27 Aug '19
commit c8b281ca4609c3d86b30f102f90a26440679c3ea
Author: Georg Koppen <gk(a)torproject.org>
Date: Tue Aug 20 08:17:15 2019 +0000
Bug 31465: Bump Go to 1.12.9
This is not only a fix for macOS notarization related issues but picks
up security fixes as well (see: #31456).
---
projects/go/config | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/projects/go/config b/projects/go/config
index c039b04..34aea9a 100644
--- a/projects/go/config
+++ b/projects/go/config
@@ -1,5 +1,5 @@
# vim: filetype=yaml sw=2
-version: 1.11.5
+version: 1.12.9
filename: '[% project %]-[% c("version") %]-[% c("var/build_id") %].tar.gz'
var:
@@ -87,7 +87,7 @@ input_files:
enable: '[% c("var/windows") || c("var/osx") %]'
- URL: 'https://golang.org/dl/go[% c("version") %].src.tar.gz'
name: go
- sha256sum: bc1ef02bb1668835db1390a2e478dcbccb5dd16911691af9d75184bbe5aa943e
+ sha256sum: ab0e56ed9c4732a653ed22e232652709afbf573e710f56a07f7fdeca578d62fc
- URL: 'https://golang.org/dl/go[% c("var/go14_version") %].src.tar.gz'
name: go14
sha256sum: 9947fc705b0b841b5938c48b22dc33e9647ec0752bae66e50278df4f23f64959
1
0

27 Aug '19
commit 1eeda4986c5f88f07bf53a2801e9e32ba3dba80b
Author: Georg Koppen <gk(a)torproject.org>
Date: Fri May 31 13:01:30 2019 +0000
Bug 28119: Tor Browser for aarch64
Thanks to boklm for help with this patch.
---
Makefile | 15 +++++++++
projects/android-toolchain/build | 8 ++---
projects/firefox/mozconfig-android-aarch64 | 50 ++++++++++++++++++++++++++++++
projects/release/build | 3 ++
projects/release/config | 10 ++++++
projects/rust/config | 4 +++
projects/tor-browser/build.android | 9 ++++--
rbm.conf | 14 ++++++++-
8 files changed, 104 insertions(+), 9 deletions(-)
diff --git a/Makefile b/Makefile
index 285b49d..94a26f6 100644
--- a/Makefile
+++ b/Makefile
@@ -11,6 +11,9 @@ release-android-armv7: submodule-update
release-android-x86: submodule-update
$(rbm) build release --target release --target torbrowser-android-x86
+release-android-aarch64: submodule-update
+ $(rbm) build release --target release --target torbrowser-android-aarch64
+
release-linux-x86_64: submodule-update
$(rbm) build release --target release --target torbrowser-linux-x86_64
@@ -41,6 +44,9 @@ alpha-android-armv7: submodule-update
alpha-android-x86: submodule-update
$(rbm) build release --target alpha --target torbrowser-android-x86
+alpha-android-aarch64: submodule-update
+ $(rbm) build release --target alpha --target torbrowser-android-aarch64
+
alpha-linux-x86_64: submodule-update
$(rbm) build release --target alpha --target torbrowser-linux-x86_64
@@ -71,6 +77,9 @@ nightly-android-armv7: submodule-update
nightly-android-x86: submodule-update
$(rbm) build release --target nightly --target torbrowser-android-x86
+nightly-android-aarch64: submodule-update
+ $(rbm) build release --target nightly --target torbrowser-android-aarch64
+
nightly-linux-x86_64: submodule-update
$(rbm) build release --target nightly --target torbrowser-linux-x86_64
@@ -101,6 +110,9 @@ alpha_nightly-android-armv7: submodule-update
alpha_nightly-android-x86: submodule-update
$(rbm) build release --target alpha_nightly --target torbrowser-android-x86
+alpha_nightly-android-aarch64: submodule-update
+ $(rbm) build release --target alpha_nightly --target torbrowser-android-aarch64
+
alpha_nightly-linux-x86_64: submodule-update
$(rbm) build release --target alpha_nightly --target torbrowser-linux-x86_64
@@ -128,6 +140,9 @@ testbuild-android-armv7: submodule-update
testbuild-android-x86: submodule-update
$(rbm) build release --target testbuild --target torbrowser-android-x86
+testbuild-android-aarch64: submodule-update
+ $(rbm) build release --target testbuild --target torbrowser-android-aarch64
+
testbuild-linux-x86_64: submodule-update
$(rbm) build release --target testbuild --target torbrowser-linux-x86_64
diff --git a/projects/android-toolchain/build b/projects/android-toolchain/build
index 9fe40f7..e0f59a9 100644
--- a/projects/android-toolchain/build
+++ b/projects/android-toolchain/build
@@ -18,11 +18,9 @@ cd $NDK_HOME
mv android-ndk-r15c/* .
rm -fR android-ndk-r15c
-# The architectures we support
-archs="arm x86"
-for arch in $archs; do
- ./build/tools/make_standalone_toolchain.py --api [% c("var/android_min_api") %] --arch $arch --install-dir=./$arch
-done
+./build/tools/make_standalone_toolchain.py --api [% c("var/android_min_api_armv7") %] --arch arm --install-dir=./arm
+./build/tools/make_standalone_toolchain.py --api [% c("var/android_min_api_x86") %] --arch x86 --install-dir=./x86
+./build/tools/make_standalone_toolchain.py --api [% c("var/android_min_api_aarch64") %] --arch arm64 --install-dir=./arm64
# Tool Archives
cd $SDK_HOME
diff --git a/projects/firefox/mozconfig-android-aarch64 b/projects/firefox/mozconfig-android-aarch64
new file mode 100644
index 0000000..2a9eb67
--- /dev/null
+++ b/projects/firefox/mozconfig-android-aarch64
@@ -0,0 +1,50 @@
+mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-aarch64-linux-android
+mk_add_options MOZ_APP_DISPLAYNAME="Tor Browser"
+export MOZILLA_OFFICIAL=1
+
+ac_add_options --enable-optimize
+ac_add_options --enable-official-branding
+
+ac_add_options --enable-application=mobile/android
+ac_add_options --target=aarch64-linux-android
+ac_add_options --with-android-ndk=/var/tmp/dist/android-toolchain/android-ndk
+ac_add_options --with-android-sdk=/var/tmp/dist/android-toolchain/android-sdk-linux
+ac_add_options --with-gradle=/var/tmp/dist/android-toolchain/gradle/gradle-4.1/bin/gradle
+ac_add_options --with-android-version=21
+
+# Android NDK does not contain llvm-config so set clang path in options
+ac_add_options --with-libclang-path=/var/tmp/dist/android-toolchain/android-ndk/arm64/lib64
+ac_add_options --with-clang-path=/var/tmp/dist/android-toolchain/android-ndk/arm64/bin/clang
+
+ac_add_options --with-android-distribution-directory=@TOPSRCDIR@/mobile/android/torbrowser
+ac_add_options --with-l10n-base=/var/tmp/dist/locales
+
+# We do not use Tor Launcher on Android:
+ac_add_options --disable-tor-launcher
+
+if [ -z "${TB_BUILD_WITH_UPDATER}" ]; then
+# Because Google Play will likely be the primary distribution medium,
+# we disable updating and rely on Google Play by default. The
+# Developer Policy explicitly prohibits in-app updating:
+# An app distributed via Google Play may not modify, replace, or
+# update itself using any method other than Google Plays update
+# mechanism.
+# https://play.google.com/about/privacy-security-deception/malicious-behavior/
+
+ ac_add_options --disable-tor-browser-update
+ ac_add_options --disable-signmar
+ ac_add_options --disable-verify-mar
+fi
+
+ac_add_options --enable-strip
+ac_add_options --disable-tests
+ac_add_options --disable-debug
+ac_add_options --disable-rust-debug
+ac_add_options --disable-maintenance-service
+ac_add_options --disable-crashreporter
+ac_add_options --disable-webrtc
+
+ac_add_options --without-google-play-services
+
+# Let's make sure no preference is enabling either Adobe's or Google's CDM.
+ac_add_options --disable-eme
diff --git a/projects/release/build b/projects/release/build
index af9d673..3e930e0 100644
--- a/projects/release/build
+++ b/projects/release/build
@@ -10,6 +10,9 @@ mkdir -p "$destdir"
[% IF c("var/torbrowser-android-x86") -%]
mv [% c('input_files_by_name/android-x86') %]/* "$destdir"/
[% END -%]
+[% IF c("var/torbrowser-android-aarch64") -%]
+ mv [% c('input_files_by_name/android-aarch64') %]/* "$destdir"/
+[% END -%]
[% IF c("var/torbrowser-windows-i686") -%]
mv [% c('input_files_by_name/windows-i686') %]/* "$destdir"/
mv [% c('input_files_by_name/windows-expert-bundle') %]/* "$destdir"/
diff --git a/projects/release/config b/projects/release/config
index ddb17d1..1623083 100644
--- a/projects/release/config
+++ b/projects/release/config
@@ -24,6 +24,9 @@ targets:
torbrowser-android-x86:
var:
torbrowser-android-x86: 1
+ torbrowser-android-aarch64:
+ var:
+ torbrowser-android-aarch64: 1
torbrowser-linux-x86_64:
var:
torbrowser-linux-x86_64: 1
@@ -117,6 +120,13 @@ input_files:
- '[% c("var/build_target") %]'
- torbrowser-android-x86
+ - name: android-aarch64
+ project: tor-browser
+ enable: '[% c("var/torbrowser-android-aarch64") %]'
+ target:
+ - '[% c("var/build_target") %]'
+ - torbrowser-android-aarch64
+
- name: linux-x86_64
project: tor-browser
enable: '[% c("var/torbrowser-linux-x86_64") %]'
diff --git a/projects/rust/config b/projects/rust/config
index 0c3b280..e2b0999 100644
--- a/projects/rust/config
+++ b/projects/rust/config
@@ -30,6 +30,10 @@ targets:
var:
configure_opt: --enable-local-rust --enable-vendor --enable-extended --release-channel=stable --sysconfdir=etc --target=i686-linux-android --set=target.i686-linux-android.cc=$ANDROID_NDK_HOME/x86/bin/i686-linux-android-gcc
+ android-aarch64:
+ var:
+ configure_opt: --enable-local-rust --enable-vendor --enable-extended --release-channel=stable --sysconfdir=etc --target=aarch64-linux-android --set=target.aarch64-linux-android.cc=$ANDROID_NDK_HOME/arm64/bin/aarch64-linux-android-gcc
+
linux:
var:
rust_arch: x86_64
diff --git a/projects/tor-browser/build.android b/projects/tor-browser/build.android
index be36abc..b90c8b9 100644
--- a/projects/tor-browser/build.android
+++ b/projects/tor-browser/build.android
@@ -24,13 +24,16 @@ zip -d $apk lib/\*
zip_src => [ 'lib/x86/*' ],
zip_args => '$apk',
}) %]
-[% END %]
-
-[% IF c("var/android-armv7") %]
+[% ELSIF c("var/android-armv7") %]
[% c('zip', {
zip_src => [ 'lib/armeabi-v7a/*' ],
zip_args => '$apk',
}) %]
+[% ELSIF c("var/android-aarch64") %]
+ [% c('zip', {
+ zip_src => [ 'lib/arm64-v8a/*' ],
+ zip_args => '$apk',
+ }) %]
[% END %]
rm -fR lib
diff --git a/rbm.conf b/rbm.conf
index 831f918..0ad63c1 100644
--- a/rbm.conf
+++ b/rbm.conf
@@ -190,12 +190,24 @@ targets:
var:
android-x86: 1
osname: android-x86
+ torbrowser-android-aarch64:
+ - android-aarch64
+ - android
+ android-aarch64:
+ arch: aarch64
+ var:
+ android-aarch64: 1
+ osname: android-aarch64
android:
var:
android: 1
compiler: android-toolchain
# API 16 is the minimum we currently support for Tor Browser on Android
- android_min_api: 16
+ android_min_api: '[% GET c("var/android_min_api_" _ c("arch")) %]'
+ # API 21 is the minimum we currently support for arm64 on Android
+ android_min_api_aarch64: 21
+ android_min_api_armv7: 16
+ android_min_api_x86: 16
snowflake: 0
fteproxy: 0
container:
1
0

[torbutton/maint-2.1] Bug 31140 - Do not enable IonMonkey at low security level on AARCH64
by gk@torproject.org 27 Aug '19
by gk@torproject.org 27 Aug '19
27 Aug '19
commit 2a15af35080b9723d88e5111151f8cd889d592e0
Author: Matthew Finkel <Matthew.Finkel(a)gmail.com>
Date: Mon Aug 19 16:18:40 2019 +0000
Bug 31140 - Do not enable IonMonkey at low security level on AARCH64
---
src/modules/security-prefs.js | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/src/modules/security-prefs.js b/src/modules/security-prefs.js
index fa97b70d..94480123 100644
--- a/src/modules/security-prefs.js
+++ b/src/modules/security-prefs.js
@@ -5,6 +5,11 @@
let {classes: Cc, utils: Cu } = Components;
let { getBoolPref, setBoolPref, getIntPref, setIntPref } =
Cu.import("resource://gre/modules/Services.jsm", {}).Services.prefs;
+
+// Used for detecting the current system architecture
+let { XPCOMABI } =
+ Cu.import("resource://gre/modules/Services.jsm", {}).Services.appinfo;
+
let { bindPref, bindPrefAndInit } =
Cu.import("resource://torbutton/modules/utils.js", {});
let logger = Components.classes["@torproject.org/torbutton-logger;1"]
@@ -41,8 +46,16 @@ const kCustomPref = "extensions.torbutton.security_custom";
// to the pref database.
var write_setting_to_prefs = function (settingIndex) {
Object.keys(kSecuritySettings).forEach(
- prefName => setBoolPref(
- prefName, kSecuritySettings[prefName][settingIndex]));
+ prefName => {
+ // Bug 31140 - Do not enable IonMonkey on AARCH64.
+ if (XPCOMABI.split("-")[0] == "aarch64" &&
+ prefName == "javascript.options.ion") {
+ setBoolPref(prefName, false);
+ continue;
+ }
+ setBoolPref(
+ prefName, kSecuritySettings[prefName][settingIndex]);
+ });
};
// __read_setting_from_prefs()__.
1
0

[tor-browser/tor-browser-68.0esr-9.0-3] Bug 1572844 - Consistently check for MOZ_BITS_DOWNLOAD
by gk@torproject.org 26 Aug '19
by gk@torproject.org 26 Aug '19
26 Aug '19
commit 39af5f2d4da655d6cb7bb5c411272634a4cdf039
Author: Adam Gashlin <agashlin(a)mozilla.com>
Date: Mon Aug 19 15:44:42 2019 -0700
Bug 1572844 - Consistently check for MOZ_BITS_DOWNLOAD
---
toolkit/components/bitsdownload/components.conf | 2 +-
toolkit/components/bitsdownload/moz.build | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/toolkit/components/bitsdownload/components.conf b/toolkit/components/bitsdownload/components.conf
index d8a7b5721e00..fe7090d366be 100644
--- a/toolkit/components/bitsdownload/components.conf
+++ b/toolkit/components/bitsdownload/components.conf
@@ -5,7 +5,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
Classes = []
-if buildconfig.substs['OS_ARCH'] == 'WINNT' and defined('MOZ_BITS_DOWNLOAD'):
+if defined('MOZ_BITS_DOWNLOAD'):
Classes += [
{
'cid': '{495d6f3d-9748-4d30-8ce5-0290c0001edf}',
diff --git a/toolkit/components/bitsdownload/moz.build b/toolkit/components/bitsdownload/moz.build
index 1d3f45937bdb..5f1dc96e9490 100644
--- a/toolkit/components/bitsdownload/moz.build
+++ b/toolkit/components/bitsdownload/moz.build
@@ -14,7 +14,7 @@ XPCOM_MANIFESTS += [
'components.conf',
]
-if CONFIG['OS_ARCH'] == 'WINNT':
+if CONFIG['MOZ_BITS_DOWNLOAD']:
EXPORTS += [
'Bits.h'
]
1
0

[tor-browser-build/master] Bug 31447: Update comment about python package
by gk@torproject.org 24 Aug '19
by gk@torproject.org 24 Aug '19
24 Aug '19
commit ace69bc2a6abb9bc5aaba625eb9a693ae2e2a5c7
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Mon Aug 19 18:45:32 2019 +0200
Bug 31447: Update comment about python package
---
projects/firefox/config | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/projects/firefox/config b/projects/firefox/config
index a481815..a5851fa 100644
--- a/projects/firefox/config
+++ b/projects/firefox/config
@@ -20,7 +20,9 @@ var:
- zip
- autoconf2.13
- yasm
- # XXX: for mach
+ # We are building our own version of Python 3.6, which is required
+ # for the build. However mach still requires Python 2.7, so we
+ # install this version using the package.
- python
- pkg-config
container:
1
0

[tor-browser-build/master] Merge remote-tracking branch 'boklm/bug_31447_v2'
by gk@torproject.org 24 Aug '19
by gk@torproject.org 24 Aug '19
24 Aug '19
commit 00354e514c96c25dea3107a8240249063526a29a
Merge: 7d1b5fa ace69bc
Author: Georg Koppen <gk(a)torproject.org>
Date: Sat Aug 24 06:18:35 2019 +0000
Merge remote-tracking branch 'boklm/bug_31447_v2'
projects/firefox/config | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
1
0

[tor-browser-build/master] Remove torbutton from projects/release
by boklm@torproject.org 23 Aug '19
by boklm@torproject.org 23 Aug '19
23 Aug '19
commit 7d1b5facf83069f7d8a055a6f0e65350e39a75f2
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Fri Aug 23 09:42:51 2019 +0200
Remove torbutton from projects/release
Torbutton was removed with commit 44c6bc36a106f2e95eec12c296041bd13c999c58.
---
projects/release/build | 1 -
projects/release/config | 8 --------
2 files changed, 9 deletions(-)
diff --git a/projects/release/build b/projects/release/build
index 3e930e0..347d9a8 100644
--- a/projects/release/build
+++ b/projects/release/build
@@ -32,7 +32,6 @@ mkdir -p "$destdir"
[% END -%]
[% IF c("var/torbrowser-src") -%]
mv [% c('input_files_by_name/src-firefox') %] \
- [% c('input_files_by_name/src-torbutton') %] \
[% c('input_files_by_name/src-tor-launcher') %] \
"$destdir"/
[% END -%]
diff --git a/projects/release/config b/projects/release/config
index 0133c3f..524eadf 100644
--- a/projects/release/config
+++ b/projects/release/config
@@ -188,14 +188,6 @@ input_files:
- '[% c("var/build_target") %]'
- torbrowser-src
- - name: src-torbutton
- project: torbutton
- enable: '[% c("var/torbrowser-src") %]'
- pkg_type: src-tarballs
- target:
- - '[% c("var/build_target") %]'
- - torbrowser-src
-
- name: src-tor-launcher
project: tor-launcher
enable: '[% c("var/torbrowser-src") %]'
1
0

23 Aug '19
commit 4dbcdaaca258bf7c9a8486f103ad9e0816426a36
Author: Georg Koppen <gk(a)torproject.org>
Date: Fri Aug 23 06:22:00 2019 +0000
Re-enable missing configure arguments
We disabled a bunch of configure arguments to get nightly builds going
as some of the required patches were not available back then. Re-enable
the missing arguments now.
---
projects/firefox/build | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/projects/firefox/build b/projects/firefox/build
index 5d4d2a3..31b812a 100644
--- a/projects/firefox/build
+++ b/projects/firefox/build
@@ -154,7 +154,7 @@ fi
rm -f configure
rm -f js/src/configure
-./mach configure --with-distribution-id=org.torproject --enable-bundled-fonts
+./mach configure --with-tor-browser-version=[% c("var/torbrowser_version") %] --with-distribution-id=org.torproject --enable-update-channel=[% c("var/torbrowser_update_channel") %] --enable-bundled-fonts --with-branding=[% c("var/branding_directory") %]
# Don't build with --verbose anymore or otherwise Stylo compilation breaks on
# Linux. See: #30321 for details.
./mach build
1
0

22 Aug '19
commit c54f90e102124dcd77d6efb9e186a4e3215972a8
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Aug 22 21:41:11 2019 +0000
Pick up 68.0 -3 for updater patches
---
projects/firefox/config | 2 +-
projects/firefox/mozconfig-linux-i686 | 2 +-
projects/firefox/mozconfig-linux-x86_64 | 2 +-
projects/firefox/mozconfig-osx-x86_64 | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/projects/firefox/config b/projects/firefox/config
index a1073d5..f6ce67c 100644
--- a/projects/firefox/config
+++ b/projects/firefox/config
@@ -49,7 +49,7 @@ targets:
branding_directory: '[% IF c("var/android") %]mobile/android[% ELSE %]browser[% END %]/branding/official'
nightly:
- git_hash: 'tor-browser-[% c("var/firefox_version") %]-[% c("var/torbrowser_branch") %]-2'
+ git_hash: 'tor-browser-[% c("var/firefox_version") %]-[% c("var/torbrowser_branch") %]-3'
tag_gpg_id: 0
var:
torbrowser_update_channel: default
diff --git a/projects/firefox/mozconfig-linux-i686 b/projects/firefox/mozconfig-linux-i686
index ff65c87..c8f19a4 100755
--- a/projects/firefox/mozconfig-linux-i686
+++ b/projects/firefox/mozconfig-linux-i686
@@ -28,7 +28,7 @@ ac_add_options --enable-official-branding
# Let's support GTK3 for ESR60
ac_add_options --enable-default-toolkit=cairo-gtk3
-# XXX: ac_add_options --enable-tor-browser-update
+ac_add_options --enable-tor-browser-update
ac_add_options --enable-signmar
ac_add_options --enable-verify-mar
diff --git a/projects/firefox/mozconfig-linux-x86_64 b/projects/firefox/mozconfig-linux-x86_64
index 69dc4ef..12f1b28 100755
--- a/projects/firefox/mozconfig-linux-x86_64
+++ b/projects/firefox/mozconfig-linux-x86_64
@@ -23,7 +23,7 @@ ac_add_options --enable-official-branding
# Let's support GTK3 for ESR60
ac_add_options --enable-default-toolkit=cairo-gtk3
-# XXX: ac_add_options --enable-tor-browser-update
+ac_add_options --enable-tor-browser-update
ac_add_options --enable-signmar
ac_add_options --enable-verify-mar
diff --git a/projects/firefox/mozconfig-osx-x86_64 b/projects/firefox/mozconfig-osx-x86_64
index 188bcc9..07dd023 100644
--- a/projects/firefox/mozconfig-osx-x86_64
+++ b/projects/firefox/mozconfig-osx-x86_64
@@ -38,7 +38,7 @@ ac_add_options --enable-optimize
ac_add_options --disable-debug
ac_add_options --enable-tor-browser-data-outside-app-dir
-#ac_add_options --enable-tor-browser-update
+ac_add_options --enable-tor-browser-update
ac_add_options --enable-signmar
ac_add_options --enable-verify-mar
1
0

[tor-browser-build/master] Revert "No .mar files an non-en-US locales for nightlies right now"
by gk@torproject.org 22 Aug '19
by gk@torproject.org 22 Aug '19
22 Aug '19
commit 536715a6c5d134bc25ebb07147c81c422c11c3b3
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Aug 22 21:42:26 2019 +0000
Revert "No .mar files an non-en-US locales for nightlies right now"
This reverts commit 4ae27ff4c296983624c4701e8fed38619a75ca6f.
---
rbm.conf | 2 --
1 file changed, 2 deletions(-)
diff --git a/rbm.conf b/rbm.conf
index c7c3320..ca3f058 100644
--- a/rbm.conf
+++ b/rbm.conf
@@ -146,8 +146,6 @@ targets:
fetch: 1
var:
nightly: 1
- testbuild: 1
- build_mar: 0
channel: nightly
torbrowser_version: tbb-nightly
1
0

[tor-launcher/master] Bug 31488: Moat: support a comma-separated list of transports
by gk@torproject.org 22 Aug '19
by gk@torproject.org 22 Aug '19
22 Aug '19
commit 71ade2c3d4bb53fdd61f5a40fa574bc614db5d6a
Author: Kathy Brade <brade(a)pearlcrescent.com>
Date: Thu Aug 22 09:45:38 2019 -0400
Bug 31488: Moat: support a comma-separated list of transports
Improve our ClientTransportPlugin config parser to recognize
"meek" and "meek_client" when they appear within a comma-separated
list of transports.
---
src/chrome/content/network-settings.js | 24 ++++++++++++++++++------
1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/src/chrome/content/network-settings.js b/src/chrome/content/network-settings.js
index a4f2866..8c1db0f 100644
--- a/src/chrome/content/network-settings.js
+++ b/src/chrome/content/network-settings.js
@@ -642,14 +642,26 @@ function onOpenBridgeDBRequestPrompt()
let meekClientArgs;
reply.lineArray.forEach(aLine =>
{
+ // Parse each ClientTransportPlugin line and look for the meek or
+ // meek_lite transport. This code works a lot like the Tor daemon's
+ // parse_transport_line() function.
let tokens = aLine.split(' ');
- if ((tokens.length > 2) &&
- ((tokens[0] == "meek") || (tokens[0] == "meek_lite")) &&
- (tokens[1] == "exec"))
+ if ((tokens.length > 2) && (tokens[1] == "exec"))
{
- meekTransport = tokens[0];
- meekClientPath = tokens[2];
- meekClientArgs = tokens.slice(3);
+ let transportArray = tokens[0].split(",").map(aStr => aStr.trim());
+ let transport = transportArray.find(
+ aTransport => (aTransport === "meek"));
+ if (!transport)
+ {
+ transport = transportArray.find(
+ aTransport => (aTransport === "meek_lite"));
+ }
+ if (transport)
+ {
+ meekTransport = transport;
+ meekClientPath = tokens[2];
+ meekClientArgs = tokens.slice(3);
+ }
}
});
1
0

[tor-launcher/master] Bug 31487: Modify moat client code so it is compatible with ESR68
by gk@torproject.org 22 Aug '19
by gk@torproject.org 22 Aug '19
22 Aug '19
commit f69f055708526c207eb69f40f577da9a80cd75ca
Author: Kathy Brade <brade(a)pearlcrescent.com>
Date: Thu Aug 22 09:39:20 2019 -0400
Bug 31487: Modify moat client code so it is compatible with ESR68
Account for changes to XPCOM APIs.
---
src/modules/tl-bridgedb.jsm | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/src/modules/tl-bridgedb.jsm b/src/modules/tl-bridgedb.jsm
index de580bc..8cc7919 100644
--- a/src/modules/tl-bridgedb.jsm
+++ b/src/modules/tl-bridgedb.jsm
@@ -532,7 +532,7 @@ _MoatRequestor.prototype =
let noTimeout = 0xFFFFFFFF; // UINT32_MAX
let proxyInfo = proxyPS.newProxyInfoWithAuth(this.mMeekClientProxyType,
this.mMeekClientIP, this.mMeekClientPort,
- userName, password,
+ userName, password, undefined, undefined,
flags, noTimeout, undefined);
let uriStr = TorLauncherUtil.getCharPref(this.kPrefMoatService);
if (!uriStr)
@@ -546,14 +546,14 @@ _MoatRequestor.prototype =
// There does not seem to be a way to directly create an nsILoadInfo from
// JavaScript, so we create a throw away non-proxied channel to get one.
- let loadInfo = Services.io.newChannelFromURI2(uri, undefined,
+ let loadInfo = Services.io.newChannelFromURI(uri, undefined,
Services.scriptSecurityManager.getSystemPrincipal(),
undefined,
Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
Ci.nsIContentPolicy.TYPE_OTHER).loadInfo;
let httpHandler = Services.io.getProtocolHandler("http")
.QueryInterface(Ci.nsIHttpProtocolHandler);
- let ch = httpHandler.newProxiedChannel2(uri, proxyInfo, 0, undefined,
+ let ch = httpHandler.newProxiedChannel(uri, proxyInfo, 0, undefined,
loadInfo).QueryInterface(Ci.nsIHttpChannel);
// Remove unwanted HTTP headers and set request parameters.
@@ -616,13 +616,13 @@ _MoatResponseListener.prototype =
mResponseLength: 0,
mResponseBody: undefined,
- onStartRequest: function(aRequest, aContext)
+ onStartRequest: function(aRequest)
{
this.mResponseLength = 0;
this.mResponseBody = "";
},
- onStopRequest: function(aRequest, aContext, aStatus)
+ onStopRequest: function(aRequest, aStatus)
{
this.mChannel = undefined;
@@ -636,9 +636,9 @@ _MoatResponseListener.prototype =
let statusCode, msg;
try
{
- statusCode = aContext.responseStatus;
- if (aContext.responseStatusText)
- msg = statusCode + " " + aContext.responseStatusText;
+ statusCode = aRequest.responseStatus;
+ if (aRequest.responseStatusText)
+ msg = statusCode + " " + aRequest.responseStatusText;
}
catch (e) {}
@@ -693,7 +693,7 @@ _MoatResponseListener.prototype =
}
}, // onStopRequest
- onDataAvailable: function(aRequest, aContext, aStream, aSrcOffset, aLength)
+ onDataAvailable: function(aRequest, aStream, aSrcOffset, aLength)
{
TorLauncherLogger.log(2, "Moat onDataAvailable: " + aLength + " bytes");
if ((this.mResponseLength + aLength) > this.mRequestor.kMaxResponseLength)
1
0

[tor-browser-build/master] Bug 31465: Make SDK version explicit in directory
by gk@torproject.org 22 Aug '19
by gk@torproject.org 22 Aug '19
22 Aug '19
commit 859c6e9dd35010047749372791062e47d2464eea
Author: Georg Koppen <gk(a)torproject.org>
Date: Tue Aug 20 11:00:41 2019 +0000
Bug 31465: Make SDK version explicit in directory
---
projects/firefox/mozconfig-osx-x86_64 | 2 +-
projects/macosx-toolchain/build | 2 +-
projects/macosx-toolchain/config | 2 +-
projects/rust/build | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/projects/firefox/mozconfig-osx-x86_64 b/projects/firefox/mozconfig-osx-x86_64
index 5d82d12..188bcc9 100644
--- a/projects/firefox/mozconfig-osx-x86_64
+++ b/projects/firefox/mozconfig-osx-x86_64
@@ -4,7 +4,7 @@ TOOLCHAIN_DIR=/var/tmp/dist/macosx-toolchain
mk_add_options "export LD_LIBRARY_PATH=$TOOLCHAIN_DIR/clang/lib"
CROSS_CCTOOLS_PATH=$TOOLCHAIN_DIR/cctools
-CROSS_SYSROOT=$TOOLCHAIN_DIR/SDK
+CROSS_SYSROOT=$TOOLCHAIN_DIR/MacOSX10.11.sdk
CROSS_PRIVATE_FRAMEWORKS=$CROSS_SYSROOT/System/Library/PrivateFrameworks
HARDENING_FLAGS="-Werror=format -Werror=format-security -fstack-protector-strong -D_FORTIFY_SOURCE=2"
FLAGS="-target x86_64-apple-darwin11 -B $CROSS_CCTOOLS_PATH/bin -isysroot $CROSS_SYSROOT $HARDENING_FLAGS"
diff --git a/projects/macosx-toolchain/build b/projects/macosx-toolchain/build
index c9cd282..f306302 100644
--- a/projects/macosx-toolchain/build
+++ b/projects/macosx-toolchain/build
@@ -3,7 +3,7 @@
distdir="/var/tmp/dist/[% project %]"
mkdir -p "$distdir"
tar xjf [% c('input_files_by_name/SDK') %]
-mv MacOSX10.11.sdk "$distdir/SDK"
+mv MacOSX10.11.sdk "$distdir/"
tar xf [% c('input_files_by_name/clang') %]
mv clang "$distdir/clang"
tar -C $distdir -xf [% c('input_files_by_name/cctools') %]
diff --git a/projects/macosx-toolchain/config b/projects/macosx-toolchain/config
index 57e471f..b7d5a39 100644
--- a/projects/macosx-toolchain/config
+++ b/projects/macosx-toolchain/config
@@ -7,7 +7,7 @@ var:
setup: |
mkdir -p /var/tmp/dist
tar -C /var/tmp/dist -xf $rootdir/[% c("compiler_tarfile") %]
- export sysrootdir=/var/tmp/dist/[% project %]/SDK/
+ export sysrootdir=/var/tmp/dist/[% project %]/MacOSX10.11.sdk/
export clangdir=/var/tmp/dist/[% project %]/clang
export cctoolsdir=/var/tmp/dist/[% project %]/cctools/bin
export PATH="$clangdir/bin:$cctoolsdir:$PATH"
diff --git a/projects/rust/build b/projects/rust/build
index 592c6ea..9624c2f 100644
--- a/projects/rust/build
+++ b/projects/rust/build
@@ -40,7 +40,7 @@ export PATH="$distdir-rust-old/bin:$PATH"
cat > $distdir/helper/x86_64-apple-darwin-clang << 'EOF'
#!/bin/sh
BASEDIR=/var/tmp/dist/macosx-toolchain
-$BASEDIR/cctools/bin/x86_64-apple-darwin-clang -target x86_64-apple-darwin -B $BASEDIR/cctools/bin -isysroot $BASEDIR/SDK/ -Wl,-syslibroot,$BASEDIR/SDK/ -Wl,-dead_strip -Wl,-pie "$@"
+$BASEDIR/cctools/bin/x86_64-apple-darwin-clang -target x86_64-apple-darwin -B $BASEDIR/cctools/bin -isysroot $BASEDIR/MacOSX10.11.sdk/ -Wl,-syslibroot,$BASEDIR/MacOSX10.11.sdk/ -Wl,-dead_strip -Wl,-pie "$@"
EOF
chmod +x $distdir/helper/x86_64-apple-darwin-clang
1
0

[tor-browser-build/master] Bug 31465: Set proper MACOSX_DEPLOYMENT_TARGET for tor and libevent
by gk@torproject.org 22 Aug '19
by gk@torproject.org 22 Aug '19
22 Aug '19
commit 4c6a14cd4d4cbd539302264d9cc9228a0f2b6074
Author: Georg Koppen <gk(a)torproject.org>
Date: Tue Aug 20 08:37:38 2019 +0000
Bug 31465: Set proper MACOSX_DEPLOYMENT_TARGET for tor and libevent
---
projects/libevent/build | 3 +++
projects/tor/build | 2 ++
2 files changed, 5 insertions(+)
diff --git a/projects/libevent/build b/projects/libevent/build
index 00ee78c..0ec76b6 100644
--- a/projects/libevent/build
+++ b/projects/libevent/build
@@ -7,6 +7,9 @@ tar -C /var/tmp/build -xf [% project %]-[% c('version') %].tar.gz
cd /var/tmp/build/[% project %]-[% c('version') %]
[% IF c("var/osx") -%]
patch -p1 < $rootdir/autotools-openssl-mac.patch
+ # Setting this after `configure` but before `make` might be enough, but let's
+ # not bet on that and just set it here.
+ export MACOSX_DEPLOYMENT_TARGET=10.9
[% END -%]
./autogen.sh
./configure --disable-static [% c("var/configure_opt") %] --prefix=$distdir
diff --git a/projects/tor/build b/projects/tor/build
index 8c8ed45..8737716 100644
--- a/projects/tor/build
+++ b/projects/tor/build
@@ -72,6 +72,8 @@ openssldir=/var/tmp/dist/openssl
[% IF c("var/osx") %]
cp $libeventdir/lib/libevent-*.dylib $TORBINDIR/
+ # The target version needs to be set before the configure step.
+ export MACOSX_DEPLOYMENT_TARGET=10.9
[% END %]
cd /var/tmp/build/[% project %]-[% c('version') %]
1
0

[tor-browser-build/master] fixup! Bug 30323: Bump MACOSX_DEPLOYMENT_TARGET
by gk@torproject.org 22 Aug '19
by gk@torproject.org 22 Aug '19
22 Aug '19
commit 7a01c99641fcdc88a94c94dccb2698fbb7d82bee
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Wed Aug 21 20:15:29 2019 +0200
fixup! Bug 30323: Bump MACOSX_DEPLOYMENT_TARGET
---
projects/go-webrtc/config | 6 +++---
projects/rust/build | 4 ++--
projects/snowflake/build | 6 +++---
projects/webrtc/build | 4 ++--
rbm.conf | 1 +
5 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/projects/go-webrtc/config b/projects/go-webrtc/config
index ba1e801..fcf6e89 100644
--- a/projects/go-webrtc/config
+++ b/projects/go-webrtc/config
@@ -27,9 +27,9 @@ var:
[% END -%]
[% IF c("var/osx") -%]
export CGO_ENABLED=1
- export CGO_CFLAGS="[% c("var/FLAGS") %] -mmacosx-version-min=10.7"
- export CGO_CXXFLAGS="[% c("var/FLAGS") %] -stdlib=libc++ -mmacosx-version-min=10.7"
- export CGO_LDFLAGS="[% c("var/FLAGS") %] -stdlib=libc++ -mmacosx-version-min=10.7"
+ export CGO_CFLAGS="[% c("var/FLAGS") %] -mmacosx-version-min=[% c("var/macosx_deployment_target") %]"
+ export CGO_CXXFLAGS="[% c("var/FLAGS") %] -stdlib=libc++ -mmacosx-version-min=[% c("var/macosx_deployment_target") %]"
+ export CGO_LDFLAGS="[% c("var/FLAGS") %] -stdlib=libc++ -mmacosx-version-min=[% c("var/macosx_deployment_target") %]"
export CC="$clangdir/bin/clang"
export CXX="$clangdir/bin/clang++"
[% END -%]
diff --git a/projects/rust/build b/projects/rust/build
index 9624c2f..5cf8c02 100644
--- a/projects/rust/build
+++ b/projects/rust/build
@@ -20,12 +20,12 @@ export PATH="$distdir-rust-old/bin:$PATH"
# Target 10.9 as our toolchain does. Without this explicit declaration Bad
# Things will happen, as a lot of dependent code then assumes that the
# official macOS target, x86_64-apple-darwin, essentially means 10.4.
- export MACOSX_DEPLOYMENT_TARGET=10.9
+ export MACOSX_DEPLOYMENT_TARGET=[% c("var/macosx_deployment_target") %]
# The Rust target for macOS is x86_64-apple-darwin, yet our toolchain is built
# for x86_64-apple-darwin11. We can't mix those targets as clang gets confused
# that way. Changing the Rust target to x86_64-apple-darwin11 would require a
# fair amount of patching, thus we create symlinks to provide Rust with the
- # necessary tools while using our toolchain underneath, targeting 10.7.
+ # necessary tools while using our toolchain underneath, targeting 10.9.
cd $cctoolsdir
for f in `ls x86_64-apple-darwin11-*`; do
ln -s $f ${f//x86_64-apple-darwin11/x86_64-apple-darwin}
diff --git a/projects/snowflake/build b/projects/snowflake/build
index ae0ebea..6534329 100644
--- a/projects/snowflake/build
+++ b/projects/snowflake/build
@@ -16,9 +16,9 @@ distdir=/var/tmp/dist/[% project %]
mkdir -p $PTDIR $DOCSDIR
[% IF c("var/osx") %]
export CGO_ENABLED=1
- export CGO_CFLAGS="[% c("var/FLAGS") %] -mmacosx-version-min=10.9"
- export CGO_CXXFLAGS="[% c("var/FLAGS") %] -stdlib=libc++ -mmacosx-version-min=10.9"
- export CGO_LDFLAGS="[% c("var/FLAGS") %] -stdlib=libc++ -mmacosx-version-min=10.9"
+ export CGO_CFLAGS="[% c("var/FLAGS") %] -mmacosx-version-min=[% c("var/macosx_deployment_target") %]"
+ export CGO_CXXFLAGS="[% c("var/FLAGS") %] -stdlib=libc++ -mmacosx-version-min=[% c("var/macosx_deployment_target") %]"
+ export CGO_LDFLAGS="[% c("var/FLAGS") %] -stdlib=libc++ -mmacosx-version-min=[% c("var/macosx_deployment_target") %]"
export CC="$clangdir/bin/clang"
export CXX="$clangdir/bin/clang++"
[% END %]
diff --git a/projects/webrtc/build b/projects/webrtc/build
index e84a0b1..77d4026 100644
--- a/projects/webrtc/build
+++ b/projects/webrtc/build
@@ -66,7 +66,7 @@ print("$sysrootdir")
print("10.11")
EOF
cat <<EOF > build/config/mac/sdk_info.py
-print("machine_os_build=\"10.9\"")
+print("machine_os_build=\"[% c("var/macosx_deployment_target") %]\"")
print("sdk_build=\"10.11\"")
print("sdk_path=\"$sysrootdir\"")
print("sdk_platform_path=\"$sysrootdir\"")
@@ -115,7 +115,7 @@ GN_ARGS+=" use_custom_libcxx=false"
#GN_ARGS+=" rtc_include_tests=false"
[% END -%]
[% IF c("var/osx") -%]
- GN_ARGS+=" target_os=\"mac\" target_cpu=\"x64\" mac_deployment_target=\"10.9\""
+ GN_ARGS+=" target_os=\"mac\" target_cpu=\"x64\" mac_deployment_target=\"[% c("var/macosx_deployment_target") %]\""
GN_ARGS+=" clang_use_chrome_plugins=false"
GN_ARGS+=" clang_base_path=\"$clangdir\""
# No lld in our toolchain currently.
diff --git a/rbm.conf b/rbm.conf
index d6c0926..c7c3320 100644
--- a/rbm.conf
+++ b/rbm.conf
@@ -334,6 +334,7 @@ targets:
configure_opt: '--host=x86_64-apple-darwin11 CC="x86_64-apple-darwin11-clang [% c("var/FLAGS") %]" CXX="x86_64-apple-darwin11-clang++ [% c("var/FLAGS") %]"'
FLAGS: "-target x86_64-apple-darwin11 -B $cctoolsdir -isysroot $sysrootdir"
LDFLAGS: "-Wl,-syslibroot,$sysrootdir -Wl,-dead_strip -Wl,-pie"
+ macosx_deployment_target: '10.9'
locale_ja: ja-JP-mac
# We only build snowflake for linux and macOS on the alpha and nightly
# channels for now.
1
0

22 Aug '19
commit 3c36d79abdb6b56c67ff42f844c6f8a2d6dbce3c
Author: Georg Koppen <gk(a)torproject.org>
Date: Mon Aug 19 18:19:43 2019 +0000
Bug 30323: Bump MACOSX_DEPLOYMENT_TARGET
---
projects/rust/build | 4 ++--
projects/snowflake/build | 6 +++---
projects/snowflake/config | 1 +
projects/webrtc/build | 4 ++--
4 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/projects/rust/build b/projects/rust/build
index 633604c..592c6ea 100644
--- a/projects/rust/build
+++ b/projects/rust/build
@@ -17,10 +17,10 @@ export PATH="$distdir-rust-old/bin:$PATH"
# (i.e. Linux).
unset CC
unset LDFLAGS
- # Target 10.7 as our toolchain does. Without this explicit declaration Bad
+ # Target 10.9 as our toolchain does. Without this explicit declaration Bad
# Things will happen, as a lot of dependent code then assumes that the
# official macOS target, x86_64-apple-darwin, essentially means 10.4.
- export MACOSX_DEPLOYMENT_TARGET=10.7
+ export MACOSX_DEPLOYMENT_TARGET=10.9
# The Rust target for macOS is x86_64-apple-darwin, yet our toolchain is built
# for x86_64-apple-darwin11. We can't mix those targets as clang gets confused
# that way. Changing the Rust target to x86_64-apple-darwin11 would require a
diff --git a/projects/snowflake/build b/projects/snowflake/build
index daeb185..ae0ebea 100644
--- a/projects/snowflake/build
+++ b/projects/snowflake/build
@@ -16,9 +16,9 @@ distdir=/var/tmp/dist/[% project %]
mkdir -p $PTDIR $DOCSDIR
[% IF c("var/osx") %]
export CGO_ENABLED=1
- export CGO_CFLAGS="[% c("var/FLAGS") %] -mmacosx-version-min=10.7"
- export CGO_CXXFLAGS="[% c("var/FLAGS") %] -stdlib=libc++ -mmacosx-version-min=10.7"
- export CGO_LDFLAGS="[% c("var/FLAGS") %] -stdlib=libc++ -mmacosx-version-min=10.7"
+ export CGO_CFLAGS="[% c("var/FLAGS") %] -mmacosx-version-min=10.9"
+ export CGO_CXXFLAGS="[% c("var/FLAGS") %] -stdlib=libc++ -mmacosx-version-min=10.9"
+ export CGO_LDFLAGS="[% c("var/FLAGS") %] -stdlib=libc++ -mmacosx-version-min=10.9"
export CC="$clangdir/bin/clang"
export CXX="$clangdir/bin/clang++"
[% END %]
diff --git a/projects/snowflake/config b/projects/snowflake/config
index 468b704..cef0930 100644
--- a/projects/snowflake/config
+++ b/projects/snowflake/config
@@ -22,6 +22,7 @@ targets:
osx-x86_64:
var:
arch_deps:
+ - pkg-config
- faketime
input_files:
diff --git a/projects/webrtc/build b/projects/webrtc/build
index ecbccb3..e84a0b1 100644
--- a/projects/webrtc/build
+++ b/projects/webrtc/build
@@ -66,7 +66,7 @@ print("$sysrootdir")
print("10.11")
EOF
cat <<EOF > build/config/mac/sdk_info.py
-print("machine_os_build=\"10.7\"")
+print("machine_os_build=\"10.9\"")
print("sdk_build=\"10.11\"")
print("sdk_path=\"$sysrootdir\"")
print("sdk_platform_path=\"$sysrootdir\"")
@@ -115,7 +115,7 @@ GN_ARGS+=" use_custom_libcxx=false"
#GN_ARGS+=" rtc_include_tests=false"
[% END -%]
[% IF c("var/osx") -%]
- GN_ARGS+=" target_os=\"mac\" target_cpu=\"x64\" mac_deployment_target=\"10.7\""
+ GN_ARGS+=" target_os=\"mac\" target_cpu=\"x64\" mac_deployment_target=\"10.9\""
GN_ARGS+=" clang_use_chrome_plugins=false"
GN_ARGS+=" clang_base_path=\"$clangdir\""
# No lld in our toolchain currently.
1
0
commit 15d4645a678b12e093f5db89f60f726275f508f6
Author: Georg Koppen <gk(a)torproject.org>
Date: Tue Aug 20 08:17:15 2019 +0000
Bug 31465: Bump Go to 1.12.9
This is not only a fix for macOS notarization related issues but picks
up security fixes as well (see: #31456).
---
projects/go/config | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/projects/go/config b/projects/go/config
index c2baeca..fd96bb6 100644
--- a/projects/go/config
+++ b/projects/go/config
@@ -1,5 +1,5 @@
# vim: filetype=yaml sw=2
-version: 1.12.5
+version: 1.12.9
filename: '[% project %]-[% c("version") %]-[% c("var/build_id") %].tar.gz'
var:
@@ -91,7 +91,7 @@ input_files:
enable: '[% c("var/windows") || c("var/osx") %]'
- URL: 'https://golang.org/dl/go[% c("version") %].src.tar.gz'
name: go
- sha256sum: 2aa5f088cbb332e73fc3def546800616b38d3bfe6b8713b8a6404060f22503e8
+ sha256sum: ab0e56ed9c4732a653ed22e232652709afbf573e710f56a07f7fdeca578d62fc
- URL: 'https://golang.org/dl/go[% c("var/go14_version") %].src.tar.gz'
name: go14
sha256sum: 9947fc705b0b841b5938c48b22dc33e9647ec0752bae66e50278df4f23f64959
1
0

[tor-browser-build/master] fixup! Bug 31465: Set proper MACOSX_DEPLOYMENT_TARGET for tor and libevent
by gk@torproject.org 22 Aug '19
by gk@torproject.org 22 Aug '19
22 Aug '19
commit 0be0e0461475a29b5c01ad3b841030633c345179
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Wed Aug 21 20:16:38 2019 +0200
fixup! Bug 31465: Set proper MACOSX_DEPLOYMENT_TARGET for tor and libevent
---
projects/libevent/build | 2 +-
projects/tor/build | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/projects/libevent/build b/projects/libevent/build
index 0ec76b6..de9ba80 100644
--- a/projects/libevent/build
+++ b/projects/libevent/build
@@ -9,7 +9,7 @@ cd /var/tmp/build/[% project %]-[% c('version') %]
patch -p1 < $rootdir/autotools-openssl-mac.patch
# Setting this after `configure` but before `make` might be enough, but let's
# not bet on that and just set it here.
- export MACOSX_DEPLOYMENT_TARGET=10.9
+ export MACOSX_DEPLOYMENT_TARGET=[% c("var/macosx_deployment_target") %]
[% END -%]
./autogen.sh
./configure --disable-static [% c("var/configure_opt") %] --prefix=$distdir
diff --git a/projects/tor/build b/projects/tor/build
index 8737716..6b684a0 100644
--- a/projects/tor/build
+++ b/projects/tor/build
@@ -73,7 +73,7 @@ openssldir=/var/tmp/dist/openssl
[% IF c("var/osx") %]
cp $libeventdir/lib/libevent-*.dylib $TORBINDIR/
# The target version needs to be set before the configure step.
- export MACOSX_DEPLOYMENT_TARGET=10.9
+ export MACOSX_DEPLOYMENT_TARGET=[% c("var/macosx_deployment_target") %]
[% END %]
cd /var/tmp/build/[% project %]-[% c('version') %]
1
0

[tor-browser-build/master] Merge remote-tracking branch 'boklm/bug_31465'
by gk@torproject.org 22 Aug '19
by gk@torproject.org 22 Aug '19
22 Aug '19
commit 039f83d716b5050d6faeda8e1bbce3a674a9f2d5
Merge: e9ff867 0be0e04
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Aug 22 06:36:28 2019 +0000
Merge remote-tracking branch 'boklm/bug_31465'
projects/go-webrtc/config | 6 +++---
projects/libevent/build | 3 +++
projects/rust/build | 6 +++---
projects/snowflake/build | 6 +++---
projects/snowflake/config | 1 +
projects/tor/build | 2 ++
projects/webrtc/build | 4 ++--
rbm.conf | 1 +
8 files changed, 18 insertions(+), 11 deletions(-)
1
0

[tor-browser-build/master] Bug 31465: Make SDK version explicit in directory
by boklm@torproject.org 21 Aug '19
by boklm@torproject.org 21 Aug '19
21 Aug '19
commit e5c707ff79b3e0191e0c2e1065c5df09cd584895
Author: Georg Koppen <gk(a)torproject.org>
Date: Tue Aug 20 11:00:41 2019 +0000
Bug 31465: Make SDK version explicit in directory
---
projects/firefox/mozconfig-osx-x86_64 | 2 +-
projects/macosx-toolchain/build | 2 +-
projects/macosx-toolchain/config | 2 +-
projects/rust/build | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/projects/firefox/mozconfig-osx-x86_64 b/projects/firefox/mozconfig-osx-x86_64
index 5d82d12..188bcc9 100644
--- a/projects/firefox/mozconfig-osx-x86_64
+++ b/projects/firefox/mozconfig-osx-x86_64
@@ -4,7 +4,7 @@ TOOLCHAIN_DIR=/var/tmp/dist/macosx-toolchain
mk_add_options "export LD_LIBRARY_PATH=$TOOLCHAIN_DIR/clang/lib"
CROSS_CCTOOLS_PATH=$TOOLCHAIN_DIR/cctools
-CROSS_SYSROOT=$TOOLCHAIN_DIR/SDK
+CROSS_SYSROOT=$TOOLCHAIN_DIR/MacOSX10.11.sdk
CROSS_PRIVATE_FRAMEWORKS=$CROSS_SYSROOT/System/Library/PrivateFrameworks
HARDENING_FLAGS="-Werror=format -Werror=format-security -fstack-protector-strong -D_FORTIFY_SOURCE=2"
FLAGS="-target x86_64-apple-darwin11 -B $CROSS_CCTOOLS_PATH/bin -isysroot $CROSS_SYSROOT $HARDENING_FLAGS"
diff --git a/projects/macosx-toolchain/build b/projects/macosx-toolchain/build
index c9cd282..f306302 100644
--- a/projects/macosx-toolchain/build
+++ b/projects/macosx-toolchain/build
@@ -3,7 +3,7 @@
distdir="/var/tmp/dist/[% project %]"
mkdir -p "$distdir"
tar xjf [% c('input_files_by_name/SDK') %]
-mv MacOSX10.11.sdk "$distdir/SDK"
+mv MacOSX10.11.sdk "$distdir/"
tar xf [% c('input_files_by_name/clang') %]
mv clang "$distdir/clang"
tar -C $distdir -xf [% c('input_files_by_name/cctools') %]
diff --git a/projects/macosx-toolchain/config b/projects/macosx-toolchain/config
index 57e471f..b7d5a39 100644
--- a/projects/macosx-toolchain/config
+++ b/projects/macosx-toolchain/config
@@ -7,7 +7,7 @@ var:
setup: |
mkdir -p /var/tmp/dist
tar -C /var/tmp/dist -xf $rootdir/[% c("compiler_tarfile") %]
- export sysrootdir=/var/tmp/dist/[% project %]/SDK/
+ export sysrootdir=/var/tmp/dist/[% project %]/MacOSX10.11.sdk/
export clangdir=/var/tmp/dist/[% project %]/clang
export cctoolsdir=/var/tmp/dist/[% project %]/cctools/bin
export PATH="$clangdir/bin:$cctoolsdir:$PATH"
diff --git a/projects/rust/build b/projects/rust/build
index 633604c..599d42e 100644
--- a/projects/rust/build
+++ b/projects/rust/build
@@ -40,7 +40,7 @@ export PATH="$distdir-rust-old/bin:$PATH"
cat > $distdir/helper/x86_64-apple-darwin-clang << 'EOF'
#!/bin/sh
BASEDIR=/var/tmp/dist/macosx-toolchain
-$BASEDIR/cctools/bin/x86_64-apple-darwin-clang -target x86_64-apple-darwin -B $BASEDIR/cctools/bin -isysroot $BASEDIR/SDK/ -Wl,-syslibroot,$BASEDIR/SDK/ -Wl,-dead_strip -Wl,-pie "$@"
+$BASEDIR/cctools/bin/x86_64-apple-darwin-clang -target x86_64-apple-darwin -B $BASEDIR/cctools/bin -isysroot $BASEDIR/MacOSX10.11.sdk/ -Wl,-syslibroot,$BASEDIR/MacOSX10.11.sdk/ -Wl,-dead_strip -Wl,-pie "$@"
EOF
chmod +x $distdir/helper/x86_64-apple-darwin-clang
1
0

21 Aug '19
commit e9ff8677a5ab59325bcf435fa92e06ba73d67f2f
Author: Georg Koppen <gk(a)torproject.org>
Date: Tue Aug 20 08:17:15 2019 +0000
Bug 31465: Bump Go to 1.12.9
This is not only a fix for macOS notarization related issues but picks
up security fixes as well (see: #31456).
---
projects/go/config | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/projects/go/config b/projects/go/config
index c2baeca..fd96bb6 100644
--- a/projects/go/config
+++ b/projects/go/config
@@ -1,5 +1,5 @@
# vim: filetype=yaml sw=2
-version: 1.12.5
+version: 1.12.9
filename: '[% project %]-[% c("version") %]-[% c("var/build_id") %].tar.gz'
var:
@@ -91,7 +91,7 @@ input_files:
enable: '[% c("var/windows") || c("var/osx") %]'
- URL: 'https://golang.org/dl/go[% c("version") %].src.tar.gz'
name: go
- sha256sum: 2aa5f088cbb332e73fc3def546800616b38d3bfe6b8713b8a6404060f22503e8
+ sha256sum: ab0e56ed9c4732a653ed22e232652709afbf573e710f56a07f7fdeca578d62fc
- URL: 'https://golang.org/dl/go[% c("var/go14_version") %].src.tar.gz'
name: go14
sha256sum: 9947fc705b0b841b5938c48b22dc33e9647ec0752bae66e50278df4f23f64959
1
0

[tor-browser-build/master] Bug 30323: Adapt macOS toolchain for esr68
by boklm@torproject.org 21 Aug '19
by boklm@torproject.org 21 Aug '19
21 Aug '19
commit 1877dbbdf499e51beb6dd5be2d53e74f57428130
Author: Georg Koppen <gk(a)torproject.org>
Date: Mon Aug 19 18:18:22 2019 +0000
Bug 30323: Adapt macOS toolchain for esr68
There are already included some simplifications as done in
https://bugzilla.mozilla.org/show_bug.cgi?id=1513798 but not all of them
as some break our current setup. This needs to get investigated in a
different bug.
---
projects/firefox/build | 48 +++++++++++++++--------------------
projects/firefox/config | 1 -
projects/firefox/mozconfig-osx-x86_64 | 15 +++++------
projects/macosx-toolchain/build | 7 ++---
projects/macosx-toolchain/config | 4 +--
5 files changed, 31 insertions(+), 44 deletions(-)
diff --git a/projects/firefox/build b/projects/firefox/build
index 18db7b9..5d4d2a3 100644
--- a/projects/firefox/build
+++ b/projects/firefox/build
@@ -52,24 +52,23 @@ EOF
wine wineboot -i
[% END -%]
+mkdir -p /var/tmp/dist
+tar -C /var/tmp/dist -xf [% c('input_files_by_name/rust') %]
+tar -C /var/tmp/dist -xf [% c('input_files_by_name/cbindgen') %]
+tar -C /var/tmp/dist -xf [% c('input_files_by_name/nasm') %]
+tar -C /var/tmp/dist -xf [% c('input_files_by_name/python') %]
+tar -C /var/tmp/dist -xf [% c('input_files_by_name/node') %]
+export PATH="/var/tmp/dist/rust/bin:/var/tmp/dist/cbindgen:/var/tmp/dist/nasm/bin:/var/tmp/dist/python/bin:/var/tmp/dist/node/bin:$PATH"
+tar -C /var/tmp/dist -xf [% c('input_files_by_name/clang') %]
+export LLVM_CONFIG="/var/tmp/dist/clang/bin/llvm-config"
+
[% IF c("var/linux") %]
- mkdir -p /var/tmp/dist
tar -C /var/tmp/dist -xf $rootdir/[% c('input_files_by_name/binutils') %]
- tar -C /var/tmp/dist -xf $rootdir/[% c('input_files_by_name/python') %]
- tar -C /var/tmp/dist -xf $rootdir/[% c('input_files_by_name/node') %]
- export PATH="/var/tmp/dist/binutils/bin:/var/tmp/dist/python/bin:/var/tmp/dist/node/bin:$PATH"
+ export PATH="/var/tmp/dist/binutils/bin:$PATH"
# Use clang for everything on Linux now.
- tar -C /var/tmp/dist -xf [% c('input_files_by_name/clang') %]
- export LLVM_CONFIG="/var/tmp/dist/clang/bin/llvm-config"
export PATH="/var/tmp/dist/clang/bin:$PATH"
[% END -%]
-mkdir -p /var/tmp/dist
-tar -C /var/tmp/dist -xf [% c('input_files_by_name/rust') %]
-tar -C /var/tmp/dist -xf [% c('input_files_by_name/cbindgen') %]
-tar -C /var/tmp/dist -xf [% c('input_files_by_name/nasm') %]
-export PATH="/var/tmp/dist/rust/bin:/var/tmp/dist/cbindgen:/var/tmp/dist/nasm/bin:$PATH"
-
tar -C /var/tmp/build -xf [% project %]-[% c('version') %].tar.gz
[% IF c("var/osx") %]
@@ -226,27 +225,22 @@ cp -p config/createprecomplete.py $MARTOOLS/
cp -p tools/update-packaging/*.sh $MARTOOLS/
cp -p obj-*/dist/host/bin/mar $MARTOOLS/
cp -p obj-*/dist/host/bin/mbsdiff $MARTOOLS/
-[% IF c("var/linux") %]
+[% IF c("var/linux") || c("var/osx") %]
cp -p obj-*/dist/bin/signmar $MARTOOLS/
cp -p obj-*/dist/bin/certutil $MARTOOLS/
cp -p obj-*/dist/bin/modutil $MARTOOLS/
cp -p obj-*/dist/bin/pk12util $MARTOOLS/
cp -p obj-*/dist/bin/shlibsign $MARTOOLS/
- NSS_LIBS="libfreeblpriv3.so libmozsqlite3.so libnss3.so libnssckbi.so libnssdbm3.so libnssutil3.so libsmime3.so libsoftokn3.so libssl3.so"
- NSPR_LIBS="libnspr4.so libplc4.so libplds4.so"
+ [% IF c("var/linux") %]
+ NSS_LIBS="libfreeblpriv3.so libmozsqlite3.so libnss3.so libnssckbi.so libnssdbm3.so libnssutil3.so libsmime3.so libsoftokn3.so libssl3.so"
+ NSPR_LIBS="libnspr4.so libplc4.so libplds4.so"
+ [% ELSE %]
+ NSS_LIBS="libfreebl3.dylib libmozglue.dylib libnss3.dylib libnssckbi.dylib libnssdbm3.dylib libsoftokn3.dylib"
+ # No NSPR_LIBS for macOS
+ NSPR_LIBS=""
+ [% END %]
for LIB in $NSS_LIBS $NSPR_LIBS; do
- cp -p obj-*/dist/bin/$LIB $MARTOOLS/
- done
-[% END %]
-[% IF c("var/osx") %]
- cp -p obj-*/modules/libmar/tool/signmar $MARTOOLS/
- cp -p obj-*/security/nss/cmd/certutil/certutil_certutil/certutil $MARTOOLS/
- cp -p obj-*/security/nss/cmd/modutil/modutil_modutil/modutil $MARTOOLS/
- cp -p obj-*/security/nss/cmd/pk12util/pk12util_pk12util/pk12util $MARTOOLS/
- cp -p obj-*/security/nss/cmd/shlibsign/shlibsign_shlibsign/shlibsign $MARTOOLS/
- NSS_LIBS="libfreebl3.dylib libmozglue.dylib libnss3.dylib libnssckbi.dylib libnssdbm3.dylib libsoftokn3.dylib"
- for LIB in $NSS_LIBS; do
- cp -p obj-*/dist/bin/$LIB $MARTOOLS/
+ cp -p obj-*/dist/bin/$LIB $MARTOOLS/
done
[% END %]
[% IF c("var/windows") %]
diff --git a/projects/firefox/config b/projects/firefox/config
index a481815..a1073d5 100644
--- a/projects/firefox/config
+++ b/projects/firefox/config
@@ -152,7 +152,6 @@ input_files:
name: python
- project: clang
name: clang
- enable: '[% c("var/linux") %]'
- project: fxc2
name: fxc2
enable: '[% c("var/windows") %]'
diff --git a/projects/firefox/mozconfig-osx-x86_64 b/projects/firefox/mozconfig-osx-x86_64
index a87bf35..5d82d12 100644
--- a/projects/firefox/mozconfig-osx-x86_64
+++ b/projects/firefox/mozconfig-osx-x86_64
@@ -11,21 +11,18 @@ FLAGS="-target x86_64-apple-darwin11 -B $CROSS_CCTOOLS_PATH/bin -isysroot $CROSS
export CC="$TOOLCHAIN_DIR/clang/bin/clang $FLAGS"
export CXX="$TOOLCHAIN_DIR/clang/bin/clang++ $FLAGS"
-export CPP="$TOOLCHAIN_DIR/clang/bin/clang $FLAGS -E"
export LLVMCONFIG=$TOOLCHAIN_DIR/clang/bin/llvm-config
-export LDFLAGS="-Wl,-syslibroot,$CROSS_SYSROOT -Wl,-dead_strip -Wl,-pie"
+export LDFLAGS="-Wl,-syslibroot,$CROSS_SYSROOT -Wl,-pie"
export BINDGEN_CFLAGS="$FLAGS"
export TOOLCHAIN_PREFIX=$CROSS_CCTOOLS_PATH/bin/x86_64-apple-darwin11-
-export DSYMUTIL="$TOOLCHAIN_DIR/clang/bin/llvm-dsymutil"
+export DSYMUTIL="$TOOLCHAIN_DIR/clang/bin/dsymutil"
-export HOST_CC="$TOOLCHAIN_DIR/clang/bin/clang"
-export HOST_CXX="$TOOLCHAIN_DIR/clang/bin/clang++"
-export HOST_CPP="$TOOLCHAIN_DIR/clang/bin/clang -E"
export HOST_CFLAGS="-g"
export HOST_CXXFLAGS="-g"
export HOST_LDFLAGS="-g"
-ac_add_options --target=x86_64-apple-darwin
+ac_add_options --target=x86_64-apple-darwin11
+ac_add_options --with-macos-sdk=$CROSS_SYSROOT
ac_add_options --with-macos-private-frameworks=$CROSS_PRIVATE_FRAMEWORKS
mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-macos
@@ -41,14 +38,14 @@ ac_add_options --enable-optimize
ac_add_options --disable-debug
ac_add_options --enable-tor-browser-data-outside-app-dir
-ac_add_options --enable-tor-browser-update
+#ac_add_options --enable-tor-browser-update
ac_add_options --enable-signmar
ac_add_options --enable-verify-mar
ac_add_options --disable-crashreporter
-ac_add_options --disable-maintenance-service
ac_add_options --disable-webrtc
ac_add_options --disable-tests
# Let's make sure no preference is enabling either Adobe's or Google's CDM.
ac_add_options --disable-eme
+ac_add_options --enable-proxy-bypass-protection
# ac_add_options --disable-ctypes
diff --git a/projects/macosx-toolchain/build b/projects/macosx-toolchain/build
index d1d8c34..c9cd282 100644
--- a/projects/macosx-toolchain/build
+++ b/projects/macosx-toolchain/build
@@ -4,15 +4,12 @@ distdir="/var/tmp/dist/[% project %]"
mkdir -p "$distdir"
tar xjf [% c('input_files_by_name/SDK') %]
mv MacOSX10.11.sdk "$distdir/SDK"
-tar xf [% c('input_files_by_name/llvm') %]
-mv llvm "$distdir/clang"
+tar xf [% c('input_files_by_name/clang') %]
+mv clang "$distdir/clang"
tar -C $distdir -xf [% c('input_files_by_name/cctools') %]
cd $distdir/cctools/bin
ln -s ../../clang/bin/clang x86_64-apple-darwin11-clang
ln -s ../../clang/bin/clang++ x86_64-apple-darwin11-clang++
-# "go link", libevent, and the jemalloc cross-compilation during the Rust build
-# expect to find a program called "dsymutil" exactly.
-ln -s ../../clang/bin/llvm-dsymutil dsymutil
cd "/var/tmp/dist"
[% c('tar', {
diff --git a/projects/macosx-toolchain/config b/projects/macosx-toolchain/config
index 8502f57..57e471f 100644
--- a/projects/macosx-toolchain/config
+++ b/projects/macosx-toolchain/config
@@ -17,8 +17,8 @@ var:
input_files:
- project: container-image
- - name: llvm
- project: llvm
+ - name: clang
+ project: clang
- name: cctools
project: cctools
- name: SDK
1
0

[tor-browser-build/master] Bump tor-browser branch to pick up latest changes from #30429
by gk@torproject.org 19 Aug '19
by gk@torproject.org 19 Aug '19
19 Aug '19
commit 4792ed5246d389caad036290e9ed34ff0ae1f0ad
Author: Georg Koppen <gk(a)torproject.org>
Date: Mon Aug 19 10:04:50 2019 +0000
Bump tor-browser branch to pick up latest changes from #30429
---
projects/firefox/config | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/projects/firefox/config b/projects/firefox/config
index ef0fa83..a481815 100644
--- a/projects/firefox/config
+++ b/projects/firefox/config
@@ -49,7 +49,7 @@ targets:
branding_directory: '[% IF c("var/android") %]mobile/android[% ELSE %]browser[% END %]/branding/official'
nightly:
- git_hash: 'tor-browser-[% c("var/firefox_version") %]-[% c("var/torbrowser_branch") %]-1'
+ git_hash: 'tor-browser-[% c("var/firefox_version") %]-[% c("var/torbrowser_branch") %]-2'
tag_gpg_id: 0
var:
torbrowser_update_channel: default
1
0
commit 4f475bc94a0237cfb8c932f21d9c7770ea5d0501
Author: Cecylia Bocovich <cohosh(a)torproject.org>
Date: Wed Aug 14 20:22:53 2019 +0000
Bump snowflake to cd650fa009
Closes bug 31403.
---
projects/snowflake/config | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/projects/snowflake/config b/projects/snowflake/config
index 2165f80..468b704 100644
--- a/projects/snowflake/config
+++ b/projects/snowflake/config
@@ -1,7 +1,7 @@
# vim: filetype=yaml sw=2
version: '[% c("abbrev") %]'
git_url: https://git.torproject.org/pluggable-transports/snowflake.git
-git_hash: d11e55aabe3753dbddca18ae084c80ad09e282d3
+git_hash: cd650fa0097f948b15dddd889ad2e6908b58bd66
filename: '[% project %]-[% c("version") %]-[% c("var/osname") %]-[% c("var/build_id") %].tar.gz'
var:
1
0

[tor-browser-build/master] Bug 31394: Replace "-1" with "−1" in start-tor-browser.desktop.
by gk@torproject.org 19 Aug '19
by gk@torproject.org 19 Aug '19
19 Aug '19
commit aebf0e3244e7a8a7fc1f1f21f3f28eddbe60aa5a
Author: David Fifield <david(a)bamsoftware.com>
Date: Sun Aug 11 16:31:18 2019 -0700
Bug 31394: Replace "-1" with "−1" in start-tor-browser.desktop.
The former character was U+002D HYPHEN-MINUS. The replacement is
U+2212 MINUS SIGN.
---
projects/tor-browser/RelativeLink/start-tor-browser.desktop | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/projects/tor-browser/RelativeLink/start-tor-browser.desktop b/projects/tor-browser/RelativeLink/start-tor-browser.desktop
index 9c63466..c02a59f 100755
--- a/projects/tor-browser/RelativeLink/start-tor-browser.desktop
+++ b/projects/tor-browser/RelativeLink/start-tor-browser.desktop
@@ -26,7 +26,7 @@
Type=Application
Name=Tor Browser Setup
GenericName=Web Browser
-Comment=Tor Browser is +1 for privacy and -1 for mass surveillance
+Comment=Tor Browser is +1 for privacy and −1 for mass surveillance
Categories=Network;WebBrowser;Security;
Exec=sh -c '"$(dirname "$*")"/Browser/start-tor-browser --detach || ([ ! -x "$(dirname "$*")"/Browser/start-tor-browser ] && "$(dirname "$*")"/start-tor-browser --detach)' dummy %k
X-TorBrowser-ExecShell=./Browser/start-tor-browser --detach
1
0

[tor-browser-build/master] No .mar files an non-en-US locales for nightlies right now
by gk@torproject.org 08 Aug '19
by gk@torproject.org 08 Aug '19
08 Aug '19
commit 4ae27ff4c296983624c4701e8fed38619a75ca6f
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Aug 8 08:43:19 2019 +0000
No .mar files an non-en-US locales for nightlies right now
---
rbm.conf | 2 ++
1 file changed, 2 insertions(+)
diff --git a/rbm.conf b/rbm.conf
index 76695f3..d6c0926 100644
--- a/rbm.conf
+++ b/rbm.conf
@@ -146,6 +146,8 @@ targets:
fetch: 1
var:
nightly: 1
+ testbuild: 1
+ build_mar: 0
channel: nightly
torbrowser_version: tbb-nightly
1
0

[tor-browser-build/master] There is no separate Torbutton project to build anymore
by gk@torproject.org 08 Aug '19
by gk@torproject.org 08 Aug '19
08 Aug '19
commit 44c6bc36a106f2e95eec12c296041bd13c999c58
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Aug 8 08:09:57 2019 +0000
There is no separate Torbutton project to build anymore
---
projects/tor-browser/build | 1 -
projects/tor-browser/config | 3 ---
projects/torbutton/build | 13 -------------
projects/torbutton/config | 26 --------------------------
4 files changed, 43 deletions(-)
diff --git a/projects/tor-browser/build b/projects/tor-browser/build
index 71084f2..f728612 100644
--- a/projects/tor-browser/build
+++ b/projects/tor-browser/build
@@ -49,7 +49,6 @@ mkdir -p "$TBDIR/$MEEKPROFILEPATH/extensions"
unzip -d $rootdir $rootdir/[% c('input_files_by_name/firefox') %]/mar-tools-*.zip
MARTOOLS=$rootdir/mar-tools
-mv [% c('input_files_by_name/torbutton') %] "$TBDIR/$EXTSPATH/torbutton(a)torproject.org.xpi"
mv [% c('input_files_by_name/https-everywhere') %] "$TBDIR/$EXTSPATH/https-everywhere-eff(a)eff.org.xpi"
mv [% c('input_files_by_name/noscript') %] "$TBDIR/$EXTSPATH/{73a6fe31-595d-460b-a920-fcc0f8843232}.xpi"
diff --git a/projects/tor-browser/config b/projects/tor-browser/config
index dc95350..cf8fcb3 100644
--- a/projects/tor-browser/config
+++ b/projects/tor-browser/config
@@ -60,9 +60,6 @@ input_files:
- project: firefox-langpacks
name: firefox-langpacks
enable: '[% ! c("var/testbuild") && ! c("var/android") %]'
- - project: torbutton
- name: torbutton
- enable: '[% ! c("var/android") %]'
- project: https-everywhere
name: https-everywhere
- project: fonts
diff --git a/projects/torbutton/build b/projects/torbutton/build
deleted file mode 100644
index 38136c4..0000000
--- a/projects/torbutton/build
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/bash
-[% c("var/set_default_env") -%]
-tar xvf [% project %]-[% c('version') %].tar.gz
-cd [% project %]-[% c('version') %]
-mkdir -p pkg
-./makexpi.sh
-mkdir pkg/tmp
-cd pkg/tmp
-unzip ../*.xpi
-[% c('zip', {
- zip_src => [ '.' ],
- zip_args => dest_dir _ '/' _ c('filename'),
- }) %]
diff --git a/projects/torbutton/config b/projects/torbutton/config
deleted file mode 100644
index 1e37b80..0000000
--- a/projects/torbutton/config
+++ /dev/null
@@ -1,26 +0,0 @@
-# vim: filetype=yaml sw=2
-version: 2.2.1
-git_url: https://git.torproject.org/torbutton.git
-git_hash: '[% c("version") %]'
-gpg_keyring: torbutton.gpg
-tag_gpg_id: 1
-filename: "[% project %]-[% c('version') %]-[% c('var/build_id') %].xpi"
-var:
- container:
- use_container: 1
-input_files:
- - project: container-image
-
-steps:
- src-tarballs:
- filename: 'src-[% project %]-[% c("version") %].tar.xz'
- input_files: []
- var:
- container:
- use_container: 0
-
-targets:
- nightly:
- version: '[% c("abbrev") %]'
- git_hash: master
- tag_gpg_id: 0
1
0
commit f6ebe5f9d074459d8a566e82f441e908e411b7ad
Author: Georg Koppen <gk(a)torproject.org>
Date: Wed Aug 7 21:18:55 2019 +0000
Switching over to esr68
---
projects/firefox-langpacks/config | 2 +-
projects/firefox/config | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/projects/firefox-langpacks/config b/projects/firefox-langpacks/config
index 34d6fad..17a707a 100644
--- a/projects/firefox-langpacks/config
+++ b/projects/firefox-langpacks/config
@@ -4,7 +4,7 @@ filename: '[% project %]-[% c("version") %]-[% c("var/osname") %]-[% c("var/buil
var:
ff_version: '[% pc("firefox", "var/firefox_version") %]'
- ff_build: build1
+ ff_build: build2
input_filename: 'dl-langpack-[% c("var/ff_arch") %]-[% c("version") %]'
targets:
diff --git a/projects/firefox/config b/projects/firefox/config
index 3608a56..ef0fa83 100644
--- a/projects/firefox/config
+++ b/projects/firefox/config
@@ -8,7 +8,7 @@ git_submodule: 1
gpg_keyring: torbutton.gpg
var:
- firefox_platform_version: 60.8.0
+ firefox_platform_version: 68.0
firefox_version: '[% c("var/firefox_platform_version") %]esr'
torbrowser_branch: 9.0
torbrowser_update_channel: alpha
1
0

[tor-browser-build/master] Bug 30321: Linux changes for Firefox ESR 68
by gk@torproject.org 07 Aug '19
by gk@torproject.org 07 Aug '19
07 Aug '19
commit c26b8196c90e908a83104c639865a2aca6598efe
Author: Georg Koppen <gk(a)torproject.org>
Date: Wed Aug 7 20:12:43 2019 +0000
Bug 30321: Linux changes for Firefox ESR 68
---
projects/firefox/build | 40 ++++++++++++++++-----------------
projects/firefox/config | 24 +++++++++++---------
projects/firefox/mozconfig-linux-i686 | 23 +++++++++++--------
projects/firefox/mozconfig-linux-x86_64 | 12 ++++++++--
4 files changed, 56 insertions(+), 43 deletions(-)
diff --git a/projects/firefox/build b/projects/firefox/build
index e0870c1..18db7b9 100644
--- a/projects/firefox/build
+++ b/projects/firefox/build
@@ -55,18 +55,20 @@ EOF
[% IF c("var/linux") %]
mkdir -p /var/tmp/dist
tar -C /var/tmp/dist -xf $rootdir/[% c('input_files_by_name/binutils') %]
- export PATH="/var/tmp/dist/binutils/bin:$PATH"
+ tar -C /var/tmp/dist -xf $rootdir/[% c('input_files_by_name/python') %]
+ tar -C /var/tmp/dist -xf $rootdir/[% c('input_files_by_name/node') %]
+ export PATH="/var/tmp/dist/binutils/bin:/var/tmp/dist/python/bin:/var/tmp/dist/node/bin:$PATH"
+ # Use clang for everything on Linux now.
+ tar -C /var/tmp/dist -xf [% c('input_files_by_name/clang') %]
+ export LLVM_CONFIG="/var/tmp/dist/clang/bin/llvm-config"
+ export PATH="/var/tmp/dist/clang/bin:$PATH"
[% END -%]
mkdir -p /var/tmp/dist
tar -C /var/tmp/dist -xf [% c('input_files_by_name/rust') %]
-export PATH="/var/tmp/dist/rust/bin:$PATH"
-
-[% IF c("var/linux") %]
- # Add llvm so stylo can build
- tar -C /var/tmp/dist -xf [% c('input_files_by_name/llvm') %]
- export LLVM_CONFIG="/var/tmp/dist/llvm/bin/llvm-config"
-[% END -%]
+tar -C /var/tmp/dist -xf [% c('input_files_by_name/cbindgen') %]
+tar -C /var/tmp/dist -xf [% c('input_files_by_name/nasm') %]
+export PATH="/var/tmp/dist/rust/bin:/var/tmp/dist/cbindgen:/var/tmp/dist/nasm/bin:$PATH"
tar -C /var/tmp/build -xf [% project %]-[% c('version') %].tar.gz
@@ -135,12 +137,6 @@ fi
export WIDL_TIME_OVERRIDE="0"
[% END %]
-[% IF c("var/osname") == "linux-i686" -%]
- export LDFLAGS=-m32
- export CFLAGS=-m32
- export CC='gcc -m32'
-[% END -%]
-
[% IF c("var/windows") %]
patch -p1 < $rootdir/nsis-uninstall.patch
[% END -%]
@@ -159,8 +155,10 @@ fi
rm -f configure
rm -f js/src/configure
-./mach configure --with-tor-browser-version=[% c("var/torbrowser_version") %] --with-distribution-id=org.torproject --enable-update-channel=[% c("var/torbrowser_update_channel") %] --enable-bundled-fonts --with-branding=[% c("var/branding_directory") %]
-./mach build --verbose
+./mach configure --with-distribution-id=org.torproject --enable-bundled-fonts
+# Don't build with --verbose anymore or otherwise Stylo compilation breaks on
+# Linux. See: #30321 for details.
+./mach build
[% IF c("var/android") %]
# Building a multi-locale .apk
@@ -229,11 +227,11 @@ cp -p tools/update-packaging/*.sh $MARTOOLS/
cp -p obj-*/dist/host/bin/mar $MARTOOLS/
cp -p obj-*/dist/host/bin/mbsdiff $MARTOOLS/
[% IF c("var/linux") %]
- cp -p obj-*/modules/libmar/tool/signmar $MARTOOLS/
- cp -p obj-*/security/nss/cmd/certutil/certutil_certutil/certutil $MARTOOLS/
- cp -p obj-*/security/nss/cmd/modutil/modutil_modutil/modutil $MARTOOLS/
- cp -p obj-*/security/nss/cmd/pk12util/pk12util_pk12util/pk12util $MARTOOLS/
- cp -p obj-*/security/nss/cmd/shlibsign/shlibsign_shlibsign/shlibsign $MARTOOLS/
+ cp -p obj-*/dist/bin/signmar $MARTOOLS/
+ cp -p obj-*/dist/bin/certutil $MARTOOLS/
+ cp -p obj-*/dist/bin/modutil $MARTOOLS/
+ cp -p obj-*/dist/bin/pk12util $MARTOOLS/
+ cp -p obj-*/dist/bin/shlibsign $MARTOOLS/
NSS_LIBS="libfreeblpriv3.so libmozsqlite3.so libnss3.so libnssckbi.so libnssdbm3.so libnssutil3.so libsmime3.so libsoftokn3.so libssl3.so"
NSPR_LIBS="libnspr4.so libplc4.so libplds4.so"
for LIB in $NSS_LIBS $NSPR_LIBS; do
diff --git a/projects/firefox/config b/projects/firefox/config
index 14be6ef..3608a56 100644
--- a/projects/firefox/config
+++ b/projects/firefox/config
@@ -20,7 +20,9 @@ var:
- zip
- autoconf2.13
- yasm
+ # XXX: for mach
- python
+ - pkg-config
container:
use_container: 1
# this should be updated when the list of gradle dependencies is changed
@@ -78,12 +80,8 @@ targets:
- hardening-wrapper
# To pass configure since ESR 31.
- libpulse-dev
- # To pass configure since ESR 45.
- - libgconf2-dev
# To pass configure since ESR 52
- libx11-xcb-dev
- # We built GCC but not the libmpc2, thus we need to install it
- - libmpc2
linux-i686:
var:
@@ -94,15 +92,11 @@ targets:
- libgtk-3-dev:i386
- libdbus-glib-1-dev:i386
- libxt-dev:i386
+ - hardening-wrapper
# To pass configure since ESR 31.
- libpulse-dev:i386
- # To pass configure since ESR 45.
- - libgconf2-dev:i386
# To pass configure since ESR 52
- libx11-xcb-dev:i386
- # We built GCC but not the libmpc2, thus we need to install it
- - libmpc2
- - hardening-wrapper
osx-x86_64:
var:
@@ -148,8 +142,16 @@ input_files:
enable: '[% c("var/windows") %]'
- project: rust
name: rust
- - project: llvm
- name: llvm
+ - project: cbindgen
+ name: cbindgen
+ - project: node
+ name: node
+ - project: nasm
+ name: nasm
+ - project: python
+ name: python
+ - project: clang
+ name: clang
enable: '[% c("var/linux") %]'
- project: fxc2
name: fxc2
diff --git a/projects/firefox/mozconfig-linux-i686 b/projects/firefox/mozconfig-linux-i686
index ef952aa..ff65c87 100755
--- a/projects/firefox/mozconfig-linux-i686
+++ b/projects/firefox/mozconfig-linux-i686
@@ -6,15 +6,20 @@ mk_add_options MOZILLA_OFFICIAL=1
export MOZILLA_OFFICIAL=1
mk_add_options BUILD_OFFICIAL=1
-export CFLAGS=-m32
-export CXXFLAGS=-m32
-export LDFLAGS=-m32
-export XLDOPTS=-m32
-export ASFLAGS=-m32
-export BINDGEN_CFLAGS='-m32 --gcc-toolchain=/var/tmp/dist/gcc'
+# We want to build with clang now and point to the GCC toolchain until #29041 is
+# fixed. We explicitly need to define the host compiler as well as for some
+# reason the gcc-toolchain argument does not get passed along otherwise.
+CC="clang --gcc-toolchain=/var/tmp/dist/gcc"
+CXX="clang++ --gcc-toolchain=/var/tmp/dist/gcc"
+HOST_CC=$CC
+HOST_CXX=$CXX
+
+export BINDGEN_CFLAGS='--gcc-toolchain=/var/tmp/dist/gcc'
ac_add_options --target=i686-linux-gnu
-ac_add_options --host=i686-linux-gnu
+
+# XXX: gold and lld break when linking libxul, resort to bfd
+ac_add_options --enable-linker=bfd
ac_add_options --enable-optimize
#ac_add_options --disable-optimize
@@ -23,7 +28,7 @@ ac_add_options --enable-official-branding
# Let's support GTK3 for ESR60
ac_add_options --enable-default-toolkit=cairo-gtk3
-ac_add_options --enable-tor-browser-update
+# XXX: ac_add_options --enable-tor-browser-update
ac_add_options --enable-signmar
ac_add_options --enable-verify-mar
@@ -31,9 +36,9 @@ ac_add_options --disable-strip
ac_add_options --disable-install-strip
ac_add_options --disable-tests
ac_add_options --disable-debug
-ac_add_options --disable-maintenance-service
ac_add_options --disable-crashreporter
ac_add_options --disable-webrtc
# Let's make sure no preference is enabling either Adobe's or Google's CDM.
ac_add_options --disable-eme
+ac_add_options --enable-proxy-bypass-protection
#ac_add_options --disable-ctypes
diff --git a/projects/firefox/mozconfig-linux-x86_64 b/projects/firefox/mozconfig-linux-x86_64
index 75fba50..69dc4ef 100755
--- a/projects/firefox/mozconfig-linux-x86_64
+++ b/projects/firefox/mozconfig-linux-x86_64
@@ -6,6 +6,14 @@ mk_add_options MOZILLA_OFFICIAL=1
export MOZILLA_OFFICIAL=1
mk_add_options BUILD_OFFICIAL=1
+# We want to build with clang now and point to the GCC toolchain until #29041 is
+# fixed. We explicitly need to define the host compiler as well as for some
+# reason the gcc-toolchain argument does not get passed along otherwise.
+CC="clang --gcc-toolchain=/var/tmp/dist/gcc"
+CXX="clang++ --gcc-toolchain=/var/tmp/dist/gcc"
+HOST_CC=$CC
+HOST_CXX=$CXX
+
export BINDGEN_CFLAGS='--gcc-toolchain=/var/tmp/dist/gcc'
ac_add_options --enable-optimize
@@ -15,7 +23,7 @@ ac_add_options --enable-official-branding
# Let's support GTK3 for ESR60
ac_add_options --enable-default-toolkit=cairo-gtk3
-ac_add_options --enable-tor-browser-update
+# XXX: ac_add_options --enable-tor-browser-update
ac_add_options --enable-signmar
ac_add_options --enable-verify-mar
@@ -23,9 +31,9 @@ ac_add_options --disable-strip
ac_add_options --disable-install-strip
ac_add_options --disable-tests
ac_add_options --disable-debug
-ac_add_options --disable-maintenance-service
ac_add_options --disable-crashreporter
ac_add_options --disable-webrtc
# Let's make sure no preference is enabling either Adobe's or Google's CDM.
ac_add_options --disable-eme
+ac_add_options --enable-proxy-bypass-protection
#ac_add_options --disable-ctypes
1
0

[tor-browser-build/master] Remove search engines from language packs
by gk@torproject.org 07 Aug '19
by gk@torproject.org 07 Aug '19
07 Aug '19
commit 4a632f8ac10f5d01ac9ef075fc698bd7454ab6cb
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Mon Aug 5 10:36:18 2019 +0200
Remove search engines from language packs
With https://bugzilla.mozilla.org/show_bug.cgi?id=1437942 search engines
are removed from language packs.
---
projects/tor-browser/build | 53 +++++++++++++++++++++-------------------------
1 file changed, 24 insertions(+), 29 deletions(-)
diff --git a/projects/tor-browser/build b/projects/tor-browser/build
index 1f155d1..71084f2 100644
--- a/projects/tor-browser/build
+++ b/projects/tor-browser/build
@@ -169,10 +169,6 @@ fi
pushd "$TBDIR[% IF c("var/osx") %]/Contents/Resources[% END %]/browser/"
-# For the proper search engines in our language packs
-unzip omni.ja chrome/en-US/locale/browser/searchplugins* || [ $? -lt 3 ]
-mv chrome/en-US/locale/browser/searchplugins $rootdir
-rm -rf chrome/en-US
unzip omni.ja defaults/preferences/000-tor-browser.js || [ $? -lt 3 ]
# Append our built extension-overrides.js to 000-tor-browser.js
cat "$GENERATEDPREFSPATH" >> defaults/preferences/000-tor-browser.js
@@ -194,32 +190,31 @@ rm -rf defaults
echo '{"version":"[% c("var/torbrowser_version") %]","architecture":"[% c("var/mar_osname") %]","channel":"[% c("var/channel") %]","locale":"en-US"}' > ../tbb_version.json
popd
-# Prepare our language packs for using the proper search engines and embed
-# our default bookmarks. See bugs 18915 and 21879 for more details.
-[% SET locales = c("var/testbuild") ? [] : c("var/locales") -%]
-[% FOREACH lang = locales %]
-[% SET lang = tmpl(lang);
- SET xpi = '$rootdir/' _ c('input_files_by_name/firefox-langpacks') _ '/' _ lang _ '.xpi';
- %]
- unzip -d prep_[% lang %] [% xpi %]
- search_plugins_path=prep_[% lang %]/browser/chrome/[% lang %]/locale/browser
- rm -rf $search_plugins_path/searchplugins
- cp -rf $rootdir/searchplugins $search_plugins_path
- [% IF c("var/osx") -%]
- cp $rootdir/bookmarks.html prep_[% lang %]/browser/chrome/[% lang %]/locale/browser/
- [% END -%]
- rm [% xpi %]
- cd prep_[% lang %]
- [% c('zip', {
- zip_src => [ '.' ],
- zip_args => xpi,
- }) %]
- # If we are building a multi-lingual package, add all of the language packs.
- [% IF c("var/multi_lingual") %]
- cp [% xpi %] "$TBDIR/$EXTSPATH/langpack-[% lang %](a)firefox.mozilla.org.xpi"
+[% IF c("var/osx") || c("var/multi_lingual") -%]
+ # Prepare our language packs to embed our default bookmarks.
+ # See bug 21879 for more details.
+ [% SET locales = c("var/testbuild") ? [] : c("var/locales") -%]
+ [% FOREACH lang = locales %]
+ [% SET lang = tmpl(lang);
+ SET xpi = '$rootdir/' _ c('input_files_by_name/firefox-langpacks') _ '/' _ lang _ '.xpi';
+ %]
+ [% IF c("var/osx") -%]
+ unzip -d prep_[% lang %] [% xpi %]
+ cp $rootdir/bookmarks.html prep_[% lang %]/browser/chrome/[% lang %]/locale/browser/
+ rm [% xpi %]
+ cd prep_[% lang %]
+ [% c('zip', {
+ zip_src => [ '.' ],
+ zip_args => xpi,
+ }) %]
+ [% END -%]
+ # If we are building a multi-lingual package, add all of the language packs.
+ [% IF c("var/multi_lingual") %]
+ cp [% xpi %] "$TBDIR/$EXTSPATH/langpack-[% lang %](a)firefox.mozilla.org.xpi"
+ [% END %]
+ cd ..
+ rm -rf prep_[% lang %]
[% END %]
- cd ..
- rm -rf prep_[% lang %]
[% END %]
[% IF c("var/multi_lingual") %]
1
0

[tor-browser-build/master] Bug 30490: Add cbindgen project for building Firefox 68 ESR
by gk@torproject.org 07 Aug '19
by gk@torproject.org 07 Aug '19
07 Aug '19
commit a61d68dc37a39d0aca74b273ca2b444fe33a07dc
Author: Georg Koppen <gk(a)torproject.org>
Date: Wed Aug 7 19:45:53 2019 +0000
Bug 30490: Add cbindgen project for building Firefox 68 ESR
---
projects/cbindgen/build | 32 ++++++++++++++++++++++++++++++++
projects/cbindgen/config | 15 +++++++++++++++
2 files changed, 47 insertions(+)
diff --git a/projects/cbindgen/build b/projects/cbindgen/build
new file mode 100644
index 0000000..429f567
--- /dev/null
+++ b/projects/cbindgen/build
@@ -0,0 +1,32 @@
+#!/bin/bash
+[% c("var/set_default_env") -%]
+distdir=/var/tmp/dist
+builddir=/var/tmp/build/[% project %]
+mkdir -p $distdir/[% project %]
+tar -C /var/tmp/dist -xf $rootdir/[% c('input_files_by_name/rust') %]
+export PATH="/var/tmp/dist/rust/bin:$PATH"
+mkdir -p /var/tmp/build
+tar -C /var/tmp/build -xf [% project %]-[% c('version') %].tar.gz
+
+# Now prepare the offline build
+# Move the directory for hardcoding the path in .cargo/config
+mv /var/tmp/build/[% project %]-[% c('version') %] $builddir
+tar -C $builddir -xjf cbindgen-vendor.tar.bz2
+cd $builddir
+mkdir .cargo
+cat > .cargo/config << 'EOF'
+[source.crates-io]
+replace-with = "vendored-sources"
+
+[source.vendored-sources]
+directory = "/var/tmp/build/cbindgen/vendor"
+EOF
+
+cargo build --release --frozen --target x86_64-unknown-linux-gnu
+mv target/x86_64-unknown-linux-gnu/release/cbindgen $distdir/[% project %]
+
+cd $distdir
+[% c('tar', {
+ tar_src => [ project ],
+ tar_args => '-czf ' _ dest_dir _ '/' _ c('filename'),
+ }) %]
diff --git a/projects/cbindgen/config b/projects/cbindgen/config
new file mode 100644
index 0000000..69014bf
--- /dev/null
+++ b/projects/cbindgen/config
@@ -0,0 +1,15 @@
+# vim: filetype=yaml sw=2
+version: '[% c("abbrev") %]'
+git_url: https://github.com/eqrion/cbindgen
+git_hash: 23a991a5b21e89aa1dcdc70f1371be20c93ece8e #v0.8.7
+filename: '[% project %]-[% c("version") %]-[% c("var/osname") %]-[% c("var/build_id") %].tar.gz'
+
+var:
+ container:
+ use_container: 1
+input_files:
+ - project: container-image
+ - name: rust
+ project: rust
+ - URL: https://people.torproject.org/~boklm/mirrors/sources/cbindgen-vendor.tar.bz2
+ sha256sum: f4cde3d56df893b543b35b7e4a6e295a275dbb3cee8e8eae549efe679db50ab9
1
0

[tor-browser-build/master] Bug 30376: Use Rust 1.34 for Tor Browser 9
by gk@torproject.org 07 Aug '19
by gk@torproject.org 07 Aug '19
07 Aug '19
commit d4f7c37aefc702fb9a66604cdf05bd8977036fc8
Author: Georg Koppen <gk(a)torproject.org>
Date: Wed Aug 7 19:34:23 2019 +0000
Bug 30376: Use Rust 1.34 for Tor Browser 9
Use 1.34 for tor Rust support on nightly builds as well.
---
projects/rust/build | 15 +---
projects/rust/config | 19 ++---
projects/rust/unwind.patch | 102 +++++++++++++-------------
projects/rust/unwind_128.patch | 161 -----------------------------------------
projects/tor/config | 6 --
5 files changed, 61 insertions(+), 242 deletions(-)
diff --git a/projects/rust/build b/projects/rust/build
index 0df84a1..633604c 100644
--- a/projects/rust/build
+++ b/projects/rust/build
@@ -59,11 +59,7 @@ cd /var/tmp/build/rustc-[% c('version') %]-src
# See: https://github.com/rust-lang/rust/issues/12859 for discussion about
# that and https://github.com/rust-lang/rust/pull/49633 for a newer attempt to
# fix this problem. We apply the patch from neersighted.
- [% IF !c("input_file_var/unwind_128") %]
- patch -p1 < $rootdir/unwind.patch
- [% ELSE %]
- patch -p1 < $rootdir/unwind_128.patch
- [% END %]
+ patch -p1 < $rootdir/unwind.patch
[% END %]
[% IF c("var/android") %]
@@ -78,15 +74,6 @@ mkdir build
cd build
../configure --prefix=$distdir [% c("var/configure_opt") %]
-# We need to disable Thin LTO due to reproducibility issues on macOS and
-# probably Linux. Alas, there is no direct option available in the config.toml
-# in 1.26.1 yet, so we need to toggle this indirectly via `codegen-units`.
-[% IF c("var/osx") || c("var/linux") %]
- # It seems hard to pass the proper value via ./configure so we resort to our
- # old friend `sed`.
- sed -i 's/#codegen-units = 1/codegen-units = 1/' config.toml
-[% END %]
-
make -j[% c("buildconf/num_procs") %]
make install
cd /var/tmp/dist
diff --git a/projects/rust/config b/projects/rust/config
index d784d39..011920b 100644
--- a/projects/rust/config
+++ b/projects/rust/config
@@ -1,15 +1,9 @@
# vim: filetype=yaml sw=2
filename: '[% project %]-[% c("version") %]-[% c("var/build_id") %].tar.gz'
-version: '[% c("input_file_var/rust_version") %]'
-
-# those values can be changed from the input_files section of other
-# projects. See projects/tor/config and bug 28260.
-input_file_var:
- rust_version: 1.26.1
- prev_version: 1.25.0
+version: 1.34.2
var:
- prev_version: '[% c("input_file_var/prev_version") %]'
+ prev_version: 1.33.0
rust_arch: '[% c("arch") %]'
container:
use_container: 1
@@ -55,6 +49,9 @@ targets:
#
# `--enable-extended` to build not only rustc but cargo as well
#
+ # `--enable-llvm-static-stdccp` to take a libstdc++ on Wheezy into account
+ # which is too old and if used gives undefined reference errors
+ #
# `--release-channel=stable` to just include stable features in the
# compiler
#
@@ -72,7 +69,7 @@ targets:
# version mismatch. We avoid that with this configure option. We need to
# build our own GCC in the first place as 4.7.2 is too old to get all the
# Rust pieces compiled.
- configure_opt: --enable-local-rust --enable-vendor --enable-extended --release-channel=stable --sysconfdir=etc --target=x86_64-unknown-linux-gnu,i686-unknown-linux-gnu --set=target.x86_64-unknown-linux-gnu.cc=gcc --set=target.i686-unknown-linux-gnu.cc=gcc
+ configure_opt: --enable-local-rust --enable-vendor --enable-extended --enable-llvm-static-stdcpp --release-channel=stable --sysconfdir=etc --target=x86_64-unknown-linux-gnu,i686-unknown-linux-gnu --set=target.x86_64-unknown-linux-gnu.cc=gcc --set=target.i686-unknown-linux-gnu.cc=gcc
osx-x86_64:
var:
@@ -107,9 +104,7 @@ input_files:
file_gpg_id: 1
gpg_keyring: rust.gpg
- filename: unwind.patch
- enable: '[% c("var/windows-i686") && !c("input_file_var/unwind_128") %]'
- - filename: unwind_128.patch
- enable: '[% c("input_file_var/unwind_128") %]'
+ enable: '[% c("var/windows-i686") %]'
- filename: replace_pagesize_in_mmap.patch
enable: '[% c("var/android") %]'
- filename: 0001-Make-sure-dl_iterate_phdr-is-undefined-on-Android.patch
diff --git a/projects/rust/unwind.patch b/projects/rust/unwind.patch
index 3a191b9..7b22dcb 100644
--- a/projects/rust/unwind.patch
+++ b/projects/rust/unwind.patch
@@ -1,6 +1,6 @@
-From dd808373aefe6247975455006bbfb89aa6410ed9 Mon Sep 17 00:00:00 2001
+From b3bea7008ece7a5bdf9b5a5dcc95e82febad1854 Mon Sep 17 00:00:00 2001
From: Bjorn Neergaard <bjorn(a)neersighted.com>
-Date: Tue, 3 Apr 2018 19:01:07 -0600
+Date: Sat, 9 Feb 2019 19:39:23 +0000
Subject: [PATCH] Fix cross-compiling i686-pc-windows-gnu from Linux
This is still very rough and serves as a proof-of-concept for fixing
@@ -32,49 +32,49 @@ rethinking of how iOS is special-cased above, to avoid further
duplication. Input on how to best structure this file is requested.
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
-index e6aa78fba5..624f2ccfbe 100644
+index 249a183189..df08d6eb0c 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
-@@ -146,6 +146,11 @@ pub fn std_cargo(build: &Builder,
- cargo.env("MACOSX_DEPLOYMENT_TARGET", target);
- }
-
-+ // FIXME: Temporary detection of SJLJ MinGW compilers.
-+ if build.build.build.contains("linux") && target == "i686-pc-windows-gnu" {
-+ features.push_str(" sjlj_eh");
-+ }
+@@ -162,7 +162,12 @@ pub fn std_cargo(builder: &Builder<'_>,
+ .arg("--features")
+ .arg("compiler-builtins-mem");
+ } else {
+- let features = builder.std_features();
++ let mut features = builder.std_features();
+
- // When doing a local rebuild we tell cargo that we're stage1 rather than
- // stage0. This works fine if the local rust and being-built rust have the
- // same view of what the default allocator is, but fails otherwise. Since
++ // FIXME: Temporary detection of SJLJ MinGW compilers.
++ if builder.config.build.contains("linux") && target == "i686-pc-windows-gnu" {
++ features.push_str(" sjlj_eh");
++ }
+
+ if compiler.stage != 0 && builder.config.sanitizers {
+ // This variable is used by the sanitizer runtime crates, e.g.
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
-index 1201759885..a06ef7e0e6 100644
+index 7d60a17042..d876d0b89a 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
-@@ -49,3 +49,4 @@ force_alloc_system = []
- panic-unwind = ["panic_unwind"]
- profiler = ["profiler_builtins"]
- wasm_syscall = []
+@@ -71,3 +71,4 @@ wasm-bindgen-threads = []
+ # https://github.com/rust-lang-nursery/stdsimd/blob/master/crates/std_detect/…
+ std_detect_file_io = []
+ std_detect_dlsym_getauxval = []
+sjlj_eh = ["unwind/sjlj_eh"]
diff --git a/src/libunwind/Cargo.toml b/src/libunwind/Cargo.toml
-index fbd9789d2f..15a20d7ff4 100644
+index 2378b0a315..0b5979ed62 100644
--- a/src/libunwind/Cargo.toml
+++ b/src/libunwind/Cargo.toml
-@@ -14,3 +14,7 @@ doc = false
- [dependencies]
+@@ -16,3 +16,6 @@ doc = false
core = { path = "../libcore" }
- libc = { path = "../rustc/libc_shim" }
+ libc = { version = "0.2.43", features = ['rustc-dep-of-std'], default-features = false }
+ compiler_builtins = "0.1.0"
+
+[features]
+sjlj_eh = []
-+
diff --git a/src/libunwind/libunwind.rs b/src/libunwind/libunwind.rs
-index aa73b11fb3..16c21be736 100644
+index 339b554ed6..ec2f93ed60 100644
--- a/src/libunwind/libunwind.rs
+++ b/src/libunwind/libunwind.rs
-@@ -10,11 +10,6 @@
-
- #![allow(bad_style)]
+@@ -1,10 +1,5 @@
+ #![allow(nonstandard_style)]
-macro_rules! cfg_if {
- ( $( if #[cfg( $meta:meta )] { $($it1:item)* } else { $($it2:item)* } )* ) =>
@@ -84,15 +84,18 @@ index aa73b11fb3..16c21be736 100644
use libc::{c_int, c_void, uintptr_t};
#[repr(C)]
-@@ -85,7 +80,6 @@ pub type _Unwind_Exception_Cleanup_Fn = extern "C" fn(unwind_code: _Unwind_Reaso
+@@ -73,8 +68,8 @@ pub enum _Unwind_Context {}
+ pub type _Unwind_Exception_Cleanup_Fn = extern "C" fn(unwind_code: _Unwind_Reason_Code,
+ exception: *mut _Unwind_Exception);
extern "C" {
- #[cfg_attr(stage0, unwind)]
- #[cfg_attr(not(stage0), unwind(allowed))]
+- #[unwind(allowed)]
- pub fn _Unwind_Resume(exception: *mut _Unwind_Exception) -> !;
++ #[cfg_attr(stage0, unwind)]
++ #[cfg_attr(not(stage0), unwind(allowed))]
pub fn _Unwind_DeleteException(exception: *mut _Unwind_Exception);
pub fn _Unwind_GetLanguageSpecificData(ctx: *mut _Unwind_Context) -> *mut c_void;
pub fn _Unwind_GetRegionStart(ctx: *mut _Unwind_Context) -> _Unwind_Ptr;
-@@ -217,28 +211,52 @@ if #[cfg(all(any(target_os = "ios", not(target_arch = "arm"))))] {
+@@ -206,26 +201,52 @@ if #[cfg(all(any(target_os = "ios", target_os = "netbsd", not(target_arch = "arm
pc
}
}
@@ -104,17 +107,13 @@ index aa73b11fb3..16c21be736 100644
+if #[cfg(all(target_os = "ios", target_arch = "arm"))] {
+ // 32-bit iOS uses SjLj and does not provide _Unwind_Backtrace()
extern "C" {
- #[cfg_attr(stage0, unwind)]
- #[cfg_attr(not(stage0), unwind(allowed))]
+- #[unwind(allowed)]
- pub fn _Unwind_RaiseException(exception: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
-- pub fn _Unwind_Backtrace(trace: _Unwind_Trace_Fn,
-- trace_argument: *mut c_void)
-- -> _Unwind_Reason_Code;
++ #[cfg_attr(stage0, unwind)]
++ #[cfg_attr(not(stage0), unwind(allowed))]
+ pub fn _Unwind_Resume(exception: *mut _Unwind_Exception) -> !;
+ pub fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
- }
--} else {
-- // 32-bit iOS uses SjLj and does not provide _Unwind_Backtrace()
++ }
+
+ #[inline]
+ pub unsafe fn _Unwind_RaiseException(exc: *mut _Unwind_Exception) -> _Unwind_Reason_Code {
@@ -122,15 +121,20 @@ index aa73b11fb3..16c21be736 100644
+ }
+
+} else if #[cfg(feature = "sjlj_eh")] {
- extern "C" {
- #[cfg_attr(stage0, unwind)]
- #[cfg_attr(not(stage0), unwind(allowed))]
++ extern "C" {
++ #[cfg_attr(stage0, unwind)]
++ #[cfg_attr(not(stage0), unwind(allowed))]
+ pub fn _Unwind_SjLj_Resume(e: *mut _Unwind_Exception) -> !;
- pub fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
-+ pub fn _Unwind_Backtrace(trace: _Unwind_Trace_Fn,
-+ trace_argument: *mut c_void)
-+ -> _Unwind_Reason_Code;
-+ }
++ pub fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
+ pub fn _Unwind_Backtrace(trace: _Unwind_Trace_Fn,
+ trace_argument: *mut c_void)
+ -> _Unwind_Reason_Code;
+ }
+-} else {
+- // 32-bit iOS uses SjLj and does not provide _Unwind_Backtrace()
+- extern "C" {
+- #[unwind(allowed)]
+- pub fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
+
+ #[inline]
+ pub unsafe fn _Unwind_Resume(exc: *mut _Unwind_Exception) -> ! {
@@ -154,5 +158,5 @@ index aa73b11fb3..16c21be736 100644
}
} // cfg_if!
--
-2.17.1
+2.23.0.rc0
diff --git a/projects/rust/unwind_128.patch b/projects/rust/unwind_128.patch
deleted file mode 100644
index 93528c9..0000000
--- a/projects/rust/unwind_128.patch
+++ /dev/null
@@ -1,161 +0,0 @@
-From 0a186eafebf26ca01879827a4cc95cc274791334 Mon Sep 17 00:00:00 2001
-From: Bjorn Neergaard <bjorn(a)neersighted.com>
-Date: Sat, 9 Feb 2019 19:39:23 +0000
-Subject: [PATCH] Fix cross-compiling i686-pc-windows-gnu from Linux
-
-This is still very rough and serves as a proof-of-concept for fixing
-Linux -> 32-bit MinGW cross compilation workflow. Currently, clang and
-GCC's MinGW targets both only support DW2 (DWARF) or SJLJ (Set Jump Long
-Jump) unwinding on 32-bit Windows.
-
-The default for GCC (and the way it is shipped on every major distro) is
-to use SJLJ on Windows, as DWARF cannot traverse non-DWARF frames. This
-would work fine, except for the fact that libgcc (our C runtime on the
-MinGW platform) exports symbols under a different name when configured
-to use SJLJ-style unwinding, and uses a preprocessor macro internally to
-alias them.
-
-Because of this, we have to detect this scenario and link to the correct
-symbols ourselves. Linking has been tested with a full bootstrap on both
-x86_64-unknown-linux-gnu and i686-pc-windows-gnu, as well as
-cross-compilation of some of my own projects.
-
-Obviously, the detection is a bit unrefined. Right now we
-unconditionally use SJLJ when compiling Linux -> MinGW. I'd like to add
-feature detection using compiler build flags or autotools-style
-compilation and object analysis. Input on the best way to proceed here
-is welcome.
-
-Also, currently there is copy-pasted/duplicated code in libunwind.
-Ideally, this could be reduced, but this would likely require a
-rethinking of how iOS is special-cased above, to avoid further
-duplication. Input on how to best structure this file is requested.
-
-diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
-index 11d9154ba6..bd8ff844f7 100644
---- a/src/bootstrap/compile.rs
-+++ b/src/bootstrap/compile.rs
-@@ -154,6 +154,11 @@ pub fn std_cargo(builder: &Builder,
- } else {
- let mut features = builder.std_features();
-
-+ // FIXME: Temporary detection of SJLJ MinGW compilers.
-+ if builder.config.build.contains("linux") && target == "i686-pc-windows-gnu" {
-+ features.push_str(" sjlj_eh");
-+ }
-+
- // When doing a local rebuild we tell cargo that we're stage1 rather than
- // stage0. This works fine if the local rust and being-built rust have the
- // same view of what the default allocator is, but fails otherwise. Since
-diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
-index 5a2dce5930..e1c876f503 100644
---- a/src/libstd/Cargo.toml
-+++ b/src/libstd/Cargo.toml
-@@ -50,3 +50,4 @@ force_alloc_system = []
- panic-unwind = ["panic_unwind"]
- profiler = ["profiler_builtins"]
- wasm_syscall = []
-+sjlj_eh = ["unwind/sjlj_eh"]
-diff --git a/src/libunwind/Cargo.toml b/src/libunwind/Cargo.toml
-index 4760461df6..27c7303604 100644
---- a/src/libunwind/Cargo.toml
-+++ b/src/libunwind/Cargo.toml
-@@ -15,3 +15,6 @@ doc = false
- core = { path = "../libcore" }
- libc = { path = "../rustc/libc_shim" }
- compiler_builtins = { path = "../rustc/compiler_builtins_shim" }
-+
-+[features]
-+sjlj_eh = []
-diff --git a/src/libunwind/libunwind.rs b/src/libunwind/libunwind.rs
-index 73a259bd44..ff3404864f 100644
---- a/src/libunwind/libunwind.rs
-+++ b/src/libunwind/libunwind.rs
-@@ -10,11 +10,6 @@
-
- #![allow(bad_style)]
-
--macro_rules! cfg_if {
-- ( $( if #[cfg( $meta:meta )] { $($it1:item)* } else { $($it2:item)* } )* ) =>
-- ( $( $( #[cfg($meta)] $it1)* $( #[cfg(not($meta))] $it2)* )* )
--}
--
- use libc::{c_int, c_void, uintptr_t};
-
- #[repr(C)]
-@@ -83,8 +78,8 @@ pub enum _Unwind_Context {}
- pub type _Unwind_Exception_Cleanup_Fn = extern "C" fn(unwind_code: _Unwind_Reason_Code,
- exception: *mut _Unwind_Exception);
- extern "C" {
-- #[unwind(allowed)]
-- pub fn _Unwind_Resume(exception: *mut _Unwind_Exception) -> !;
-+ #[cfg_attr(stage0, unwind)]
-+ #[cfg_attr(not(stage0), unwind(allowed))]
- pub fn _Unwind_DeleteException(exception: *mut _Unwind_Exception);
- pub fn _Unwind_GetLanguageSpecificData(ctx: *mut _Unwind_Context) -> *mut c_void;
- pub fn _Unwind_GetRegionStart(ctx: *mut _Unwind_Context) -> _Unwind_Ptr;
-@@ -216,26 +211,52 @@ if #[cfg(all(any(target_os = "ios", target_os = "netbsd", not(target_arch = "arm
- pc
- }
- }
-+} // cfg_if!
-
--if #[cfg(not(all(target_os = "ios", target_arch = "arm")))] {
-- // Not 32-bit iOS
-+cfg_if! {
-+if #[cfg(all(target_os = "ios", target_arch = "arm"))] {
-+ // 32-bit iOS uses SjLj and does not provide _Unwind_Backtrace()
- extern "C" {
-- #[unwind(allowed)]
-- pub fn _Unwind_RaiseException(exception: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
-+ #[cfg_attr(stage0, unwind)]
-+ #[cfg_attr(not(stage0), unwind(allowed))]
-+ pub fn _Unwind_Resume(exception: *mut _Unwind_Exception) -> !;
-+ pub fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
-+ }
-+
-+ #[inline]
-+ pub unsafe fn _Unwind_RaiseException(exc: *mut _Unwind_Exception) -> _Unwind_Reason_Code {
-+ _Unwind_SjLj_RaiseException(exc)
-+ }
-+
-+} else if #[cfg(feature = "sjlj_eh")] {
-+ extern "C" {
-+ #[cfg_attr(stage0, unwind)]
-+ #[cfg_attr(not(stage0), unwind(allowed))]
-+ pub fn _Unwind_SjLj_Resume(e: *mut _Unwind_Exception) -> !;
-+ pub fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
- pub fn _Unwind_Backtrace(trace: _Unwind_Trace_Fn,
- trace_argument: *mut c_void)
- -> _Unwind_Reason_Code;
- }
--} else {
-- // 32-bit iOS uses SjLj and does not provide _Unwind_Backtrace()
-- extern "C" {
-- #[unwind(allowed)]
-- pub fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
-+
-+ #[inline]
-+ pub unsafe fn _Unwind_Resume(exc: *mut _Unwind_Exception) -> ! {
-+ _Unwind_SjLj_Resume(exc)
- }
-
- #[inline]
- pub unsafe fn _Unwind_RaiseException(exc: *mut _Unwind_Exception) -> _Unwind_Reason_Code {
- _Unwind_SjLj_RaiseException(exc)
- }
-+} else {
-+ extern "C" {
-+ #[cfg_attr(stage0, unwind)]
-+ #[cfg_attr(not(stage0), unwind(allowed))]
-+ pub fn _Unwind_Resume(exception: *mut _Unwind_Exception) -> !;
-+ pub fn _Unwind_RaiseException(exception: *mut _Unwind_Exception) -> _Unwind_Reason_Code;
-+ pub fn _Unwind_Backtrace(trace: _Unwind_Trace_Fn,
-+ trace_argument: *mut c_void)
-+ -> _Unwind_Reason_Code;
-+ }
- }
- } // cfg_if!
---
-2.20.1
-
diff --git a/projects/tor/config b/projects/tor/config
index 35b37ce..682cfd3 100644
--- a/projects/tor/config
+++ b/projects/tor/config
@@ -59,10 +59,4 @@ input_files:
project: '[% c("var/compiler") %]'
- name: rust
project: rust
- # Tor needs rust >= 1.28.0
- # See bug 28260
- input_file_var:
- rust_version: 1.28.0
- prev_version: 1.27.2
- unwind_128: '[% c("var/windows-i686") %]'
enable: '[% !c("var/android") && c("var/nightly") %]'
1
0
commit 2a501682217eff74df47f45c60618b71f2a38353
Author: Alex Catarineu <acat(a)torproject.org>
Date: Mon May 13 18:30:50 2019 +0200
Remove unused files
---
src/chrome/content/popup.xul | 43 ----
src/chrome/content/pref-connection.xul | 10 -
src/chrome/content/torbutton_tb.xul | 38 ----
src/chrome/content/torcookie.js | 385 ---------------------------------
src/chrome/content/torcookiedialog.xul | 72 ------
5 files changed, 548 deletions(-)
diff --git a/src/chrome/content/popup.xul b/src/chrome/content/popup.xul
deleted file mode 100644
index 5d9b76ce..00000000
--- a/src/chrome/content/popup.xul
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://torbutton/skin/torbutton.css" type="text/css"?>
-
-<!DOCTYPE overlay SYSTEM "chrome://torbutton/locale/torbutton.dtd">
-
-<overlay id="torbutton-popup-overlay"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
- <stringbundleset id="torbutton-stringbundleset">
- <stringbundle id="torbutton-bundle" src="chrome://torbutton/locale/torbutton.properties"/>
- </stringbundleset>
- <panel id="torbutton-context-menu"
- onpopupshowing="torbutton_check_protections();"
- titlebar="normal" noautohide="true"
- anchor="torbutton-button" position="after_start" >
- <hbox align="start">
- <vbox>
- <menuitem id="torbutton-new-identity"
- label="&torbutton.context_menu.new_identity;"
- accesskey="&torbutton.context_menu.new_identity_key;"
- insertafter="context-stop"
- oncommand="torbutton_new_identity()"/>
- <menuseparator/>
- <menuitem id="torbutton-cookie-protector"
- label="&torbutton.context_menu.cookieProtections;"
- accesskey="&torbutton.context_menu.cookieProtections.key;"
- insertafter="context-stop"
- hidden="true"
- oncommand="torbutton_open_cookie_dialog()"/>
- <menuitem id="torbutton-networksettings"
- label="&torbutton.context_menu.networksettings;"
- accesskey="&torbutton.context_menu.networksettings.key;"
- oncommand="torbutton_open_network_settings()"/>
- <menuseparator id="torbutton-checkForUpdateSeparator"/>
- <menuitem id="torbutton-checkForUpdate"
- label="&torbutton.context_menu.downloadUpdate;"
- accesskey="&torbutton.context_menu.downloadUpdate.key;"
- insertafter="context-stop"
- oncommand="torbutton_check_for_update()"/>
- </vbox>
- </hbox>
- </panel>
-</overlay>
diff --git a/src/chrome/content/pref-connection.xul b/src/chrome/content/pref-connection.xul
deleted file mode 100644
index 4d5fb613..00000000
--- a/src/chrome/content/pref-connection.xul
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- TODO: This entire file could be removed, but see bug 19929. -->
-
-<!DOCTYPE overlay SYSTEM "chrome://torbutton/locale/torbutton.dtd">
-
-<overlay id="torbutton-prefs-notice"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-</overlay>
diff --git a/src/chrome/content/torbutton_tb.xul b/src/chrome/content/torbutton_tb.xul
deleted file mode 100644
index 450ffb3a..00000000
--- a/src/chrome/content/torbutton_tb.xul
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://torbutton/skin/torbutton.css" type="text/css"?>
-<?xul-overlay href="chrome://torbutton/content/popup.xul"?>
-
-<!DOCTYPE overlay SYSTEM "chrome://torbutton/locale/torbutton.dtd">
-
-<overlay id="torbutton-overlay"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
- <script type="application/x-javascript" src="chrome://torbutton/content/torbutton_util.js" />
- <script type="application/x-javascript" src="chrome://torbutton/content/torbutton.js" />
- <script language="JavaScript">
- //onLoad Hander
- try{window.addEventListener("load", torbutton_init, false);}catch(e){}
- </script>
-
- <stringbundleset id="torbutton-stringbundleset">
- <stringbundle id="torbutton-bundle" src="chrome://torbutton/locale/torbutton.properties"/>
- </stringbundleset>
-
- <toolbarpalette id="MailToolbarPalette">
- <toolbarbutton
- id="torbutton-button-tb"
- class="toolbarbutton-1"
- label="Torbutton"
- tooltiptext="&torbutton.button.tooltip;"
- context="torbutton-context-menu" />
- </toolbarpalette>
-
- <toolbarpalette id="MsgComposeToolbarPalette">
- <toolbarbutton
- id="torbutton-button-tb-msg"
- class="toolbarbutton-1"
- label="Torbutton"
- tooltiptext="&torbutton.button.tooltip;"
- context="torbutton-context-menu" />
- </toolbarpalette>
-
-</overlay>
diff --git a/src/chrome/content/torcookie.js b/src/chrome/content/torcookie.js
deleted file mode 100644
index 0a3dace6..00000000
--- a/src/chrome/content/torcookie.js
+++ /dev/null
@@ -1,385 +0,0 @@
-// Bug 1506 P2: I think cookie protections is a neat feature.
-
-var cookiesTree = null;
-var prefs = null;
-var cookies = [];
-var protectedCookies = [];
-var deletedCookies = [];
-var lastCookieSortColumn = "";
-var lastCookieSortAscending = false;
-var cookiemanager = null;
-var selector = null;
-//custom tree view, this is how we dynamically add the cookies
-var cookiesTreeView = {
- rowCount : 0,
- setTree : function(tree){},
- getImageSrc : function(row,column) {},
- getProgressMode : function(row,column) {},
- getCellValue : function(row,column) {},
- getCellText : function(row,column){
- var rv="";
- switch (column.id) {
- case "domainCol" : rv = cookies[row].rawHost; break;
- case "nameCol" : rv = cookies[row].name; break;
- case "lockCol" : rv = cookies[row].isProtected; break;
- case "pathCol" : rv = cookies[row].path; break;
- }
- return rv;
- },
- isSeparator : function(index) {return false;},
- isSorted: function() { return false; },
- isContainer : function(index) {return false;},
- cycleHeader : function(column, aElt) {},
- getRowProperties : function(row,column,prop){},
- getColumnProperties : function(column,columnElement,prop){},
- getCellProperties : function(row,column,prop) {}
- };
-
-// XXX: Must match the definition in cookie-jar-selector :/
-function Cookie(number,name,value,isDomain,host,rawHost,HttpOnly,path,isSecure,isSession,
- expires,isProtected) {
- this.number = number;
- this.name = name;
- this.value = value;
- this.isDomain = isDomain;
- this.host = host;
- this.rawHost = rawHost;
- this.isHttpOnly = HttpOnly;
- this.path = path;
- this.isSecure = isSecure;
- this.isSession = isSession;
- this.expires = expires;
- this.isProtected = isProtected;
-}
-
-function initDialog() {
- cookiesTree = document.getElementById("cookiesTree");
- prefs =Components.classes["@mozilla.org/preferences-service;1"]
- .getService(Components.interfaces.nsIPrefBranch);
- selector = Components.classes["@torproject.org/cookie-jar-selector;1"]
- .getService(Components.interfaces.nsISupports)
- .wrappedJSObject;
- //init cookie manager
- cookiemanager = Components.classes["@mozilla.org/cookiemanager;1"].getService();
- cookiemanager = cookiemanager.QueryInterface(Components.interfaces.nsICookieManager);
- var enumerator = cookiemanager.enumerator;
- var count = 0;
- getProtectedCookies();
- while (enumerator.hasMoreElements()) {
- var nextCookie = enumerator.getNext();
- if (!nextCookie) break;
- nextCookie = nextCookie.QueryInterface(Components.interfaces.nsICookie);
- var host = nextCookie.host;
- var isProt = checkIfProtected(nextCookie.name, host, nextCookie.path);
- //populate list
- cookies[count] =
- new Cookie(count++, nextCookie.name, nextCookie.value, nextCookie.isDomain, host,
- (host.charAt(0)==".") ? host.substring(1,host.length) : host, nextCookie.isHttpOnly,
- nextCookie.path, nextCookie.isSecure, nextCookie.isSession, nextCookie.expires,
- isProt);
- }
- //apply custom view
- cookiesTreeView.rowCount = cookies.length;
- cookiesTree.treeBoxObject.view = cookiesTreeView;
- document.getElementById('defaultCookieGroup').selectedIndex = prefs.getBoolPref("extensions.torbutton.cookie_auto_protect")? 0 : 1;
-}
-function protectCookie()
-{
- ProtectInTree(cookiesTree, cookiesTreeView,
- cookies, "protectCookie", "unprotectCookie", "removeCookie");
-}
-function unprotectCookie() {
- UnProtectInTree(cookiesTree, cookiesTreeView,
- cookies, "protectCookie", "unprotectCookie", "removeCookie");
-}
-function checkIfProtected(name, host, path)
-{
- for (var i = 0; i < protectedCookies.length; i++)
- {
- var cookie = protectedCookies[i];
- if (cookie.name == name && cookie.host == host && cookie.path == path)
- return true;
- }
- return false;
-}
-function itemSelected() {
- var selections = getTreeSelections(cookiesTree);
- if (selections.length) {
-
-//DY - check if (the last in list) selection is protected/unprotected, set buttons
- if (cookies[selections[(selections.length)-1]].isProtected) {
- document.getElementById("removeCookie").disabled = true;
- document.getElementById("unprotectCookie").disabled = false;
- document.getElementById("protectCookie").disabled = true;
- } else {
- document.getElementById("removeCookie").disabled = false;
- document.getElementById("unprotectCookie").disabled = true;
- document.getElementById("protectCookie").disabled = false;
- }
-
- }
-}
-function acceptDialog() {
-
- FinalizeCookieDeletions();
- var protectedcount = 0;
- var protcookies = [];
- for (var i = 0; i < cookies.length; i++)
- {
- if (cookies[i].isProtected)
- {
- protcookies[protectedcount] = cookies[i];
- protectedcount++;
- }
- }
- selector.protectCookies(protcookies);
- //output protected cookies
- prefs.setBoolPref("extensions.torbutton.cookie_auto_protect",document.getElementById('saveAllCookies').selected);
-}
-function CookieColumnSort(column) {
- lastCookieSortAscending =
- SortTree(cookiesTree, cookiesTreeView, cookies,
- column, lastCookieSortColumn, lastCookieSortAscending);
- lastCookieSortColumn = column;
-}
-function DeleteCookie() {
-//DY - check if any selection is protected
- var selections = getTreeSelections(cookiesTree);
- var protect = false;
- var i;
- for (i=0; i<selections.length; i++) {
- if (cookies[selections[i]].isProtected) {
- protect = true;
- }
- }
- if (!protect && i>0 ) {
- DeleteSelectedItemFromTree(cookiesTree, cookiesTreeView,
- cookies, deletedCookies,
- "removeCookie", "removeAllCookies",
- "protectCookie", "unprotectCookie");
- if (!cookies.length) {
- ;//ClearCookieProperties();
- }
-
- }
-}
-
-function getProtectedCookies()
-{
- var gotCookies = selector.getProtectedCookies("tor");
- if (gotCookies == null)
- return;
- protectedCookies = gotCookies;
-}
-
-//Tree Utils
-
-function SortTree(tree, view, table, column, lastSortColumn, lastSortAscending, updateSelection) {
-
- // remember which item was selected so we can restore it after the sort
- var selections = getTreeSelections(tree);
- var selectedNumber = selections.length ? table[selections[0]].number : -1;
-
- // determine if sort is to be ascending or descending
- var ascending = (column == lastSortColumn) ? !lastSortAscending : true;
-
- // do the sort or re-sort
- var compareFunc = function compare(first, second) {
- if (column=="isProtected") {
- return second[column].toString().localeCompare(first[column].toString());
- } else {
- return first[column].toLowerCase().localeCompare(second[column].toLowerCase());
- }
- }
- table.sort(compareFunc);
- if (!ascending)
- table.reverse();
-
- // restore the selection
- var selectedRow = -1;
- if (selectedNumber>=0 && updateSelection) {
- for (var s=0; s<table.length; s++) {
- if (table[s].number == selectedNumber) {
- // update selection
- // note: we need to deselect before reselecting in order to trigger ...Selected()
- tree.view.selection.select(-1);
- tree.view.selection.select(s);
- selectedRow = s;
- break;
- }
- }
- }
-
- // display the results
- tree.treeBoxObject.invalidate();
- if (selectedRow >= 0) {
- tree.treeBoxObject.ensureRowIsVisible(selectedRow)
- }
-
- return ascending;
-}
-function FinalizeCookieDeletions() {
- for (var c=0; c<deletedCookies.length; c++) {
- cookiemanager.remove(deletedCookies[c].host,
- deletedCookies[c].name,
- deletedCookies[c].path,
- false);
- }
- deletedCookies.length = 0;
-}
-function getTreeSelections(tree) {
- var selections = [];
- var select;
-
- select = tree.view.selection;
- if (select) {
- var count = select.getRangeCount();
- var min = new Object();
- var max = new Object();
- for (var i=0; i<count; i++) {
- select.getRangeAt(i, min, max);
- for (var k=min.value; k<=max.value; k++) {
- if (k != -1) {
- selections[selections.length] = k;
- }
- }
- }
- }
- return selections;
-}
-function ProtectInTree
- (tree, view, table, protButton, unprotButton, removeButton) {
-
- var selections = getTreeSelections(tree);
- for (var s=selections.length-1; s>= 0; s--) {
- var i = selections[s];
- table[i].isProtected = true;
- }
-
- //update tree view
- tree.treeBoxObject.invalidate();
-//DY - Update selections
- tree.treeBoxObject.ensureRowIsVisible(selections[0]);
- // disable/enable buttons
- document.getElementById(unprotButton).disabled = false;
- document.getElementById(protButton).disabled = true;
- document.getElementById(removeButton).disabled = true;
-}
-function UnProtectInTree
- (tree, view, table, protButton, unprotButton, removeButton) {
-
- var selections = getTreeSelections(tree);
- for (var s=selections.length-1; s>= 0; s--) {
- var i = selections[s];
- table[i].isProtected = false;
- }
-
- //update tree view
- tree.treeBoxObject.invalidate();
-//DY - Update selections
- tree.treeBoxObject.ensureRowIsVisible(selections[0]);
- // disable/enable buttons
- document.getElementById(unprotButton).disabled = true;
- document.getElementById(protButton).disabled = false;
- document.getElementById(removeButton).disabled = false;
-}
-function DeleteAllCookies() {
-
- DeleteAllFromTree(cookiesTree, cookiesTreeView,
- cookies, deletedCookies,
- "removeCookie", "removeAllCookies",
- "protectCookie", "unprotectCookie");
-
-}
-function DeleteSelectedItemFromTree
- (tree, view, table, deletedTable, removeButton, removeAllButton, protButton, unprotButton) {
-
- var selections = getTreeSelections(tree);
-
- tree.view.selection.clearSelection();
-
-
- // remove selected items from list (by setting them to null) and place in deleted list
- for (var s=selections.length-1; s>= 0; s--) {
- var i = selections[s];
- deletedTable[deletedTable.length] = table[i];
- table[i] = null;
- }
- // collapse list by removing all the null entries
- for (var j=0; j<table.length; j++) {
- if (table[j] == null) {
- var k = j;
- while ((k < table.length) && (table[k] == null)) {
- k++;
- }
- table.splice(j, k-j);
- view.rowCount -= k - j;
- tree.treeBoxObject.rowCountChanged(j, j - k);
- }
- }
-//DY - update selection and/or buttons
- if (table.length) {
-
-//DY - update selection to previous (first of) selected position or bottom
- var nextSelection = (selections[0] < table.length) ? selections[0] : table.length-1;
-
- tree.view.selection.select(nextSelection);
- tree.treeBoxObject.ensureRowIsVisible(nextSelection);
- if (table[nextSelection].isProtected) {
- document.getElementById(unprotButton).disabled = false;
- document.getElementById(protButton).disabled = true;
- } else {
- document.getElementById(unprotButton).disabled = true;
- document.getElementById(protButton).disabled = false;
- }
- } else {
- // disable buttons
- document.getElementById(removeButton).disabled = true;
- document.getElementById(removeAllButton).disabled = true;
- document.getElementById(unprotButton).disabled = true;
- document.getElementById(protButton).disabled = true;
- }
-}
-function DeleteAllFromTree
- (tree, view, table, deletedTable, removeButton, removeAllButton, protButton, unprotButton) {
-
- // remove items from table and place in deleted table
- for (var i=0; i<table.length; i++) {
-//DY - only if unprotected
- if (!table[i].isProtected) {
- deletedTable[deletedTable.length] = table[i];
- table[i] = null;
- }
- }
-
- tree.view.selection.clearSelection();
-
-//DY - fix up tree
- // collapse list by removing all the null entries
- for (var j=0; j<table.length; j++) {
- if (table[j] == null) {
- var k = j;
- while ((k < table.length) && (table[k] == null)) {
- k++;
- }
- table.splice(j, k-j);
- view.rowCount -= k - j;
- tree.treeBoxObject.rowCountChanged(j, j - k);
- }
- }
- // update selection and/or buttons
- if (table.length) {
- // update selection to top
- tree.view.selection.select(0);
- tree.treeBoxObject.ensureRowIsVisible(0);
- //if it exists is must already be protected
- document.getElementById(unprotButton).disabled = false;
- document.getElementById(protButton).disabled = true;
- } else {
- // disable all buttons
- document.getElementById(removeButton).disabled = true;
- document.getElementById(removeAllButton).disabled = true;
- document.getElementById(unprotButton).disabled = true;
- document.getElementById(protButton).disabled = true;
- }
-}
diff --git a/src/chrome/content/torcookiedialog.xul b/src/chrome/content/torcookiedialog.xul
deleted file mode 100644
index 68a7cafe..00000000
--- a/src/chrome/content/torcookiedialog.xul
+++ /dev/null
@@ -1,72 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://torbutton/skin/torbutton.css" type="text/css"?>
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-
-<!DOCTYPE overlay SYSTEM "chrome://torbutton/locale/torbutton.dtd">
-
-<dialog id="TorCookieDialog"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- title="&torbutton.cookiedialog.title;"
- buttons="accept,cancel"
- style="width: 30em;"
- onload="initDialog();"
- ondialogaccept="acceptDialog();"
- persist="screenX screenY width height">
- <script src="chrome://torbutton/content/torbutton.js" type="application/x-javascript"/>
- <script src="chrome://torbutton/content/torcookie.js" type="application/x-javascript"/>
- <stringbundleset id="torbutton-stringbundleset">
- <stringbundle id="torbutton-bundle" src="chrome://torbutton/locale/torbutton.properties"/>
- </stringbundleset>
-
- <label value=""/>
- <separator class="thin"/>
- <vbox flex="1">
- <tree id="cookiesTree" flex="1" style="height: 10em;"
- onkeypress="return;//do this later"
- onselect="itemSelected();"
- hidecolumnpicker="true">
- <treecols>
- <treecol id="lockCol" label="&torbutton.cookiedialog.lockCol;" flex="1"
- onclick="CookieColumnSort('isProtected', true);" persist="width"/>
- <splitter class="tree-splitter"/>
- <treecol id="domainCol" label="&torbutton.cookiedialog.domainCol;" flex="2"
- onclick="CookieColumnSort('rawHost', true);" persist="width"/>
- <splitter class="tree-splitter"/>
- <treecol id="nameCol" label="&torbutton.cookiedialog.nameCol;" flex="1"
- onclick="CookieColumnSort('name', true);" persist="width"/>
- <treecol id="pathCol" label="&torbutton.cookiedialog.pathCol;" flex="1"
- onclick="CookieColumnSort('path', true);" persist="width"/>
-
- </treecols>
- <treechildren/>
- </tree>
- </vbox>
- <groupbox>
- <hbox>
- <vbox>
- <button id="protectCookie" disabled="true"
- label="&torbutton.cookiedialog.protectCookie;"
- oncommand="protectCookie();"/>
- <button id="removeCookie" disabled="true"
- label="&torbutton.cookiedialog.removeCookie;"
- oncommand="DeleteCookie();"/>
- </vbox>
- <vbox>
- <button id="unprotectCookie" disabled="true"
- label="&torbutton.cookiedialog.unprotectCookie;"
- oncommand="unprotectCookie();"/>
- <button id="removeAllCookies"
- label="&torbutton.cookiedialog.removeAllBut;"
- oncommand="DeleteAllCookies();"/>
- </vbox>
- </hbox>
- <hbox>
- <radiogroup id="defaultCookieGroup">
- <radio id="saveAllCookies" label="&torbutton.cookiedialog.saveAllCookies;" />
- <radio id="donnotsaveCookies" label="&torbutton.cookiedialog.doNotSaveAllCookies;" />
- </radiogroup>
- </hbox>
- </groupbox>
-
-</dialog>
-
1
0
commit 02c91349acdb2a493fe0089139ae765b64250a77
Author: Alex Catarineu <acat(a)torproject.org>
Date: Fri May 10 11:51:26 2019 +0200
Delete chrome.manifest.*jar
---
src/chrome.manifest.jar | 60 -----------------------------------------------
src/chrome.manifest.nojar | 60 -----------------------------------------------
2 files changed, 120 deletions(-)
diff --git a/src/chrome.manifest.jar b/src/chrome.manifest.jar
deleted file mode 100644
index 8d503630..00000000
--- a/src/chrome.manifest.jar
+++ /dev/null
@@ -1,60 +0,0 @@
-content torbutton jar:chrome/torbutton.jar!/content/
-overlay chrome://browser/content/browser.xul chrome://torbutton/content/torbutton.xul
-overlay chrome://browser/content/preferences/connection.xul chrome://torbutton/content/pref-connection.xul
-overlay chrome://messenger/content/messenger.xul chrome://torbutton/content/torbutton_tb.xul
-overlay chrome://messenger/content/messengercompose/messengercompose.xul chrome://torbutton/content/torbutton_tb.xul
-
-locale torbutton af jar:chrome/torbutton.jar!/locale/af/
-locale torbutton ar jar:chrome/torbutton.jar!/locale/ar/
-locale torbutton bg jar:chrome/torbutton.jar!/locale/bg/
-locale torbutton bms jar:chrome/torbutton.jar!/locale/bms/
-locale torbutton bo jar:chrome/torbutton.jar!/locale/bo/
-locale torbutton ca jar:chrome/torbutton.jar!/locale/ca/
-locale torbutton cs jar:chrome/torbutton.jar!/locale/cs/
-locale torbutton da jar:chrome/torbutton.jar!/locale/da/
-locale torbutton de jar:chrome/torbutton.jar!/locale/de/
-locale torbutton el jar:chrome/torbutton.jar!/locale/el/
-locale torbutton en jar:chrome/torbutton.jar!/locale/en/
-locale torbutton es jar:chrome/torbutton.jar!/locale/es/
-locale torbutton eu jar:chrome/torbutton.jar!/locale/eu/
-locale torbutton fa jar:chrome/torbutton.jar!/locale/fa/
-locale torbutton fi jar:chrome/torbutton.jar!/locale/fi/
-locale torbutton fr jar:chrome/torbutton.jar!/locale/fr/
-locale torbutton fur jar:chrome/torbutton.jar!/locale/fur/
-locale torbutton gl jar:chrome/torbutton.jar!/locale/gl/
-locale torbutton gu jar:chrome/torbutton.jar!/locale/gu/
-locale torbutton he jar:chrome/torbutton.jar!/locale/he/
-locale torbutton hi jar:chrome/torbutton.jar!/locale/hi/
-locale torbutton hr jar:chrome/torbutton.jar!/locale/hr/
-locale torbutton hu jar:chrome/torbutton.jar!/locale/hu/
-locale torbutton id jar:chrome/torbutton.jar!/locale/id/
-locale torbutton is jar:chrome/torbutton.jar!/locale/is/
-locale torbutton it jar:chrome/torbutton.jar!/locale/it/
-locale torbutton ja jar:chrome/torbutton.jar!/locale/ja/
-locale torbutton ka jar:chrome/torbutton.jar!/locale/ka/
-locale torbutton km jar:chrome/torbutton.jar!/locale/km/
-locale torbutton ko jar:chrome/torbutton.jar!/locale/ko/
-locale torbutton ku jar:chrome/torbutton.jar!/locale/ku/
-locale torbutton mt jar:chrome/torbutton.jar!/locale/mt/
-locale torbutton nb jar:chrome/torbutton.jar!/locale/nb/
-locale torbutton nl jar:chrome/torbutton.jar!/locale/nl/
-locale torbutton pa jar:chrome/torbutton.jar!/locale/pa/
-locale torbutton pl jar:chrome/torbutton.jar!/locale/pl/
-locale torbutton pt-BR jar:chrome/torbutton.jar!/locale/pt-BR/
-locale torbutton pt jar:chrome/torbutton.jar!/locale/pt/
-locale torbutton ro jar:chrome/torbutton.jar!/locale/ro/
-locale torbutton ru jar:chrome/torbutton.jar!/locale/ru/
-locale torbutton sl jar:chrome/torbutton.jar!/locale/sl/
-locale torbutton sq jar:chrome/torbutton.jar!/locale/sq/
-locale torbutton sv jar:chrome/torbutton.jar!/locale/sv/
-locale torbutton sw jar:chrome/torbutton.jar!/locale/sw/
-locale torbutton th jar:chrome/torbutton.jar!/locale/th/
-locale torbutton tr jar:chrome/torbutton.jar!/locale/tr/
-locale torbutton uk jar:chrome/torbutton.jar!/locale/uk/
-locale torbutton vi jar:chrome/torbutton.jar!/locale/vi/
-locale torbutton zh-CN jar:chrome/torbutton.jar!/locale/zh-CN/
-locale torbutton zh-HK jar:chrome/torbutton.jar!/locale/zh-HK/
-locale torbutton zh-TW jar:chrome/torbutton.jar!/locale/zh-TW/
-
-skin torbutton classic/1.0 jar:chrome/torbutton.jar!/skin/
-style chrome://global/content/customizeToolbar.xul chrome://torbutton/skin/torbutton.css
diff --git a/src/chrome.manifest.nojar b/src/chrome.manifest.nojar
deleted file mode 100644
index 7631874e..00000000
--- a/src/chrome.manifest.nojar
+++ /dev/null
@@ -1,60 +0,0 @@
-content torbutton chrome/content/
-overlay chrome://browser/content/browser.xul chrome://torbutton/content/torbutton.xul
-overlay chrome://browser/content/preferences/connection.xul chrome://torbutton/content/pref-connection.xul
-overlay chrome://messenger/content/messenger.xul chrome://torbutton/content/torbutton_tb.xul
-overlay chrome://messenger/content/messengercompose/messengercompose.xul chrome://torbutton/content/torbutton_tb.xul
-
-locale torbutton af chrome/locale/af/
-locale torbutton ar chrome/locale/ar/
-locale torbutton bg chrome/locale/bg/
-locale torbutton bms chrome/locale/bms/
-locale torbutton bo chrome/locale/bo/
-locale torbutton ca chrome/locale/ca/
-locale torbutton cs chrome/locale/cs/
-locale torbutton da chrome/locale/da/
-locale torbutton de chrome/locale/de/
-locale torbutton el chrome/locale/el/
-locale torbutton en chrome/locale/en/
-locale torbutton es chrome/locale/es/
-locale torbutton eu chrome/locale/eu/
-locale torbutton fa chrome/locale/fa/
-locale torbutton fi chrome/locale/fi/
-locale torbutton fr chrome/locale/fr/
-locale torbutton fur chrome/locale/fur/
-locale torbutton gl chrome/locale/gl/
-locale torbutton gu chrome/locale/gu/
-locale torbutton he chrome/locale/he/
-locale torbutton hi chrome/locale/hi/
-locale torbutton hr chrome/locale/hr/
-locale torbutton hu chrome/locale/hu/
-locale torbutton id chrome/locale/id/
-locale torbutton is chrome/locale/is/
-locale torbutton it chrome/locale/it/
-locale torbutton ja chrome/locale/ja/
-locale torbutton ka chrome/locale/ka/
-locale torbutton km chrome/locale/km/
-locale torbutton ko chrome/locale/ko/
-locale torbutton ku chrome/locale/ku/
-locale torbutton mt chrome/locale/mt/
-locale torbutton nb chrome/locale/nb/
-locale torbutton nl chrome/locale/nl/
-locale torbutton pa chrome/locale/pa/
-locale torbutton pl chrome/locale/pl/
-locale torbutton pt chrome/locale/pt/
-locale torbutton pt-BR chrome/locale/pt-BR/
-locale torbutton ro chrome/locale/ro/
-locale torbutton ru chrome/locale/ru/
-locale torbutton sl chrome/locale/sl/
-locale torbutton sq chrome/locale/sq/
-locale torbutton sv chrome/locale/sv/
-locale torbutton sw chrome/locale/sw/
-locale torbutton th chrome/locale/th/
-locale torbutton tr chrome/locale/tr/
-locale torbutton uk chrome/locale/uk/
-locale torbutton vi chrome/locale/vi/
-locale torbutton zh-CN chrome/locale/zh-CN/
-locale torbutton zh-HK chrome/locale/zh-HK/
-locale torbutton zh-TW chrome/locale/zh-TW/
-
-skin torbutton classic/1.0 chrome/skin/
-style chrome://global/content/customizeToolbar.xul chrome://torbutton/skin/torbutton.css
1
0

[torbutton/master] Fix components and modules, and minor style changes
by gk@torproject.org 07 Aug '19
by gk@torproject.org 07 Aug '19
07 Aug '19
commit 18e7226776301a82bb2c5715739b25f9c2b281ad
Author: Alex Catarineu <acat(a)torproject.org>
Date: Thu May 9 19:48:10 2019 +0200
Fix components and modules, and minor style changes
---
src/chrome/content/preferences-mobile.js | 10 +-
src/chrome/content/tor-circuit-display.js | 18 +--
src/chrome/content/torbutton.js | 230 +++++++++++++-----------------
src/chrome/content/torbutton_util.js | 14 +-
src/components/aboutTor.js | 21 +--
src/components/cookie-jar-selector.js | 131 +++++------------
src/components/domain-isolator.js | 19 ++-
src/components/dragDropFilter.js | 16 +--
src/components/external-app-blocker.js | 13 +-
src/components/torCheckService.js | 27 +---
src/components/torbutton-logger.js | 38 ++---
src/modules/default-prefs.js | 2 +-
src/modules/noscript-control.js | 50 ++++---
src/modules/security-prefs.js | 9 +-
src/modules/tor-control-port.js | 10 +-
src/modules/utils.js | 16 +--
16 files changed, 243 insertions(+), 381 deletions(-)
diff --git a/src/chrome/content/preferences-mobile.js b/src/chrome/content/preferences-mobile.js
index e2da9b88..fa79dce8 100644
--- a/src/chrome/content/preferences-mobile.js
+++ b/src/chrome/content/preferences-mobile.js
@@ -1,12 +1,12 @@
// # Security Settings User Interface for Mobile
// Utilities
-let { utils: Cu } = Components;
-let { getBoolPref, getIntPref, setBoolPref, setIntPref, getCharPref } =
- Cu.import("resource://gre/modules/Services.jsm", {}).Services.prefs;
+const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const { getBoolPref, getIntPref, setBoolPref, setIntPref, getCharPref }
+ = Services.prefs;
let { getLocale, show_torbrowser_manual } =
- Cu.import("resource://torbutton/modules/utils.js", {});
+ ChromeUtils.import("resource://torbutton/modules/utils.js", {});
// Description elements have the follow names.
const descNames =
@@ -64,7 +64,7 @@ function torbutton_set_learn_more_links() {
locale = getLocale();
}
let links = linkNames.map(name => document.getElementById(name));
- links.forEach(link => {;
+ links.forEach(link => {
if (show_manual && locale != "") {
link.href= "https:/tb-manual.torproject.org/" + locale +
"/security-slider.html";
diff --git a/src/chrome/content/tor-circuit-display.js b/src/chrome/content/tor-circuit-display.js
index 5ecbe7d7..05dc14de 100644
--- a/src/chrome/content/tor-circuit-display.js
+++ b/src/chrome/content/tor-circuit-display.js
@@ -26,18 +26,17 @@ let createTorCircuitDisplay = (function () {
"use strict";
// Mozilla utilities
-const { Cu : utils , Ci : interfaces } = Components.utils;
-Cu.import("resource://gre/modules/Services.jsm");
+const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
// Import the controller code.
-let { controller } = Cu.import("resource://torbutton/modules/tor-control-port.js", {});
+let { controller } = ChromeUtils.import("resource://torbutton/modules/tor-control-port.js", {});
// Utility functions
-let { bindPrefAndInit, observe, getLocale, getDomainForBrowser } = Cu.import("resource://torbutton/modules/utils.js", {});
+let { bindPrefAndInit, observe, getLocale, getDomainForBrowser } = ChromeUtils.import("resource://torbutton/modules/utils.js", {});
// Make the TorButton logger available.
let logger = Cc["@torproject.org/torbutton-logger;1"]
- .getService(Components.interfaces.nsISupports).wrappedJSObject;
+ .getService(Ci.nsISupports).wrappedJSObject;
// ## Circuit/stream credentials and node monitoring
@@ -209,18 +208,13 @@ let uiString = function (shortName) {
return torbuttonBundle.GetStringFromName("torbutton.circuit_display." + shortName);
};
-// __regionBundle__.
-// A list of localized region (country) names.
-let regionBundle = Services.strings.createBundle(
- "chrome://global/locale/regionNames.properties");
-
// __localizedCountryNameFromCode(countryCode)__.
// Convert a country code to a localized country name.
// Example: `'de'` -> `'Deutschland'` in German locale.
let localizedCountryNameFromCode = function (countryCode) {
if (!countryCode) return uiString("unknown_country");
try {
- return regionBundle.GetStringFromName(countryCode.toLowerCase());
+ return Services.intl.getRegionDisplayNames(undefined, [countryCode])[0];
} catch (e) {
return countryCode.toUpperCase();
}
@@ -363,7 +357,7 @@ let setupGuardNote = function () {
["div", {},
noteBefore, ["span", {class: "circuit-guard-name"}, name],
noteAfter, " ",
- ["span", {onclick: `gBrowser.selectedTab = gBrowser.addTab('https://support.torproject.org/${localeCode}/tbb/tbb-2/');`,
+ ["span", {onclick: `gBrowser.selectedTab = gBrowser.addTab('https://support.torproject.org/${localeCode}/tbb/tbb-2/', {triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()});`,
class: "circuit-link"},
learnMoreString]]);
};
diff --git a/src/chrome/content/torbutton.js b/src/chrome/content/torbutton.js
index a7bd4f8c..d73ddf73 100644
--- a/src/chrome/content/torbutton.js
+++ b/src/chrome/content/torbutton.js
@@ -7,16 +7,20 @@
// TODO: Double-check there are no strange exploits to defeat:
// http://kb.mozillazine.org/Links_to_local_pages_don%27t_work
-let { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
-const {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
+/* global torbutton_log, gBrowser, torbutton_safelog, CustomizableUI,
+ createTorCircuitDisplay, torbutton_get_property_string, gFindBarInitialized,
+ gFindBar, OpenBrowserWindow, PrivateBrowsingUtils, torbutton_get_stringbundle,
+ Services, AppConstants
+ */
+
let {
showDialog,
show_torbrowser_manual,
unescapeTorString,
bindPrefAndInit,
getDomainForBrowser,
-} = Cu.import("resource://torbutton/modules/utils.js", {});
-let SecurityPrefs = Cu.import("resource://torbutton/modules/security-prefs.js", {});
+} = ChromeUtils.import("resource://torbutton/modules/utils.js", {});
+let SecurityPrefs = ChromeUtils.import("resource://torbutton/modules/security-prefs.js", {});
const k_tb_last_browser_version_pref = "extensions.torbutton.lastBrowserVersion";
const k_tb_browser_update_needed_pref = "extensions.torbutton.updateNeeded";
@@ -44,8 +48,7 @@ var m_tb_control_host = null; // Set if using TCP.
var m_tb_control_pass = null;
var m_tb_control_desc = null; // For logging.
-var m_tb_domWindowUtils = window.QueryInterface(Ci.nsIInterfaceRequestor).
- getInterface(Ci.nsIDOMWindowUtils);
+var m_tb_domWindowUtils = window.windowUtils;
// Bug 1506 P1: This object is only for updating the UI for toggling and style
var torbutton_window_pref_observer =
@@ -91,9 +94,8 @@ var torbutton_unique_pref_observer =
m_tb_prefs.addObserver("privacy.resistFingerprinting", this, false);
// We observe xpcom-category-entry-added for plugins w/ Gecko-Content-Viewers
- var observerService = Cc["@mozilla.org/observer-service;1"].
- getService(Ci.nsIObserverService);
- observerService.addObserver(this, "xpcom-category-entry-added", false);
+ var observerService = Services.obs;
+ observerService.addObserver(this, "xpcom-category-entry-added");
},
unregister: function()
@@ -106,8 +108,7 @@ var torbutton_unique_pref_observer =
m_tb_prefs.removeObserver("privacy.firstparty.isolate", this);
m_tb_prefs.removeObserver("privacy.resistFingerprinting", this);
- var observerService = Cc["@mozilla.org/observer-service;1"].
- getService(Ci.nsIObserverService);
+ var observerService = Services.obs;
observerService.removeObserver(this, "xpcom-category-entry-added");
},
@@ -165,11 +166,9 @@ var torbutton_unique_pref_observer =
}
var torbutton_tor_check_observer = {
- register: function()
- {
- this._obsSvc = Cc["@mozilla.org/observer-service;1"]
- .getService(Ci.nsIObserverService);
- this._obsSvc.addObserver(this, k_tb_tor_check_failed_topic, false);
+ register() {
+ this._obsSvc = Services.obs;
+ this._obsSvc.addObserver(this, k_tb_tor_check_failed_topic);
},
unregister: function()
@@ -189,22 +188,24 @@ var torbutton_tor_check_observer = {
// If the user does not have an about:tor tab open in the front most
// window, open one.
- var wm = Cc["@mozilla.org/appshell/window-mediator;1"]
- .getService(Components.interfaces.nsIWindowMediator);
+ var wm = Services.wm;
var win = wm.getMostRecentWindow("navigator:browser");
if (win == window) {
let foundTab = false;
- let tabBrowser = top.getBrowser();
+ let tabBrowser = top.gBrowser;
for (let i = 0; !foundTab && (i < tabBrowser.browsers.length); ++i) {
let b = tabBrowser.getBrowserAtIndex(i);
foundTab = (b.currentURI.spec.toLowerCase() == "about:tor");
}
- if (!foundTab)
- gBrowser.selectedTab = gBrowser.addTab("about:tor");
+ if (!foundTab) {
+ gBrowser.selectedTab = gBrowser.addTab("about:tor", {
+ triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+ });
+ }
}
}
- }
+ },
};
function torbutton_init_toolbutton()
@@ -268,8 +269,8 @@ function torbutton_init() {
} catch(e) {}
// Bug 1506 P4: These vars are very important for New Identity
- var environ = Components.classes["@mozilla.org/process/environment;1"]
- .getService(Components.interfaces.nsIEnvironment);
+ var environ = Cc["@mozilla.org/process/environment;1"]
+ .getService(Ci.nsIEnvironment);
if (environ.exists("TOR_CONTROL_PASSWD")) {
m_tb_control_pass = environ.get("TOR_CONTROL_PASSWD");
@@ -282,10 +283,12 @@ function torbutton_init() {
} catch(e) {
torbutton_log(4, 'unable to read authentication cookie');
}
- } else try {
+ } else {
+ try {
// Try to get password from Tor Launcher.
m_tb_control_pass = tlps.TorGetPassword(false);
- } catch(e) {}
+ } catch (e) {}
+ }
// Try to get the control port IPC file (an nsIFile) from Tor Launcher,
// since Tor Launcher knows how to handle its own preferences and how to
@@ -341,9 +344,8 @@ function torbutton_init() {
// This works only by setting the pref to `true` otherwise we get an
// exception and nothing is happening.
m_tb_prefs.setBoolPref("dom.quotaManager.testing", true);
- Cc["@mozilla.org/dom/quota-manager-service;1"]
- .getService(Ci.nsIQuotaManagerService).clear();
- } catch(e) {
+ Services.qms.clear();
+ } catch (e) {
} finally {
m_tb_prefs.setBoolPref("dom.quotaManager.testing", orig_quota_test);
}
@@ -503,8 +505,7 @@ function torbutton_confirm_plugins() {
torbutton_log(3, "Confirming plugin usage.");
- var prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"]
- .getService(Components.interfaces.nsIPromptService);
+ var prompts = Services.prompt;
// Display two buttons, both with string titles.
var flags = prompts.STD_YES_NO_BUTTONS + prompts.BUTTON_DELAY_ENABLE;
@@ -513,8 +514,7 @@ function torbutton_confirm_plugins() {
var askAgainText = torbutton_get_property_string("torbutton.popup.never_ask_again");
var askAgain = {value: false};
- var wm = Cc["@mozilla.org/appshell/window-mediator;1"]
- .getService(Components.interfaces.nsIWindowMediator);
+ var wm = Services.wm;
var win = wm.getMostRecentWindow("navigator:browser");
var no_plugins = (prompts.confirmEx(win, "", message, flags, null, null, null,
askAgainText, askAgain) == 1);
@@ -531,8 +531,6 @@ function torbutton_confirm_plugins() {
// Now, if any tabs were open to about:addons, reload them. Our popup
// messed up that page.
- var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
- .getService(Components.interfaces.nsIWindowMediator);
var browserEnumerator = wm.getEnumerator("navigator:browser");
// Check each browser instance for our URL
@@ -553,15 +551,13 @@ function torbutton_confirm_plugins() {
}
function torbutton_inform_about_tbb() {
- var prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"]
- .getService(Components.interfaces.nsIPromptService);
+ var prompts = Services.prompt;
var message = torbutton_get_property_string("torbutton.popup.prompt_torbrowser");
var title = torbutton_get_property_string("torbutton.title.prompt_torbrowser");
var checkbox = {value: false};
- var sb = Components.classes["@mozilla.org/intl/stringbundle;1"]
- .getService(Components.interfaces.nsIStringBundleService);
+ var sb = Services.strings;
var browserstrings = sb.createBundle("chrome://browser/locale/browser.properties");
var askagain = browserstrings.GetStringFromName("privateBrowsingNeverAsk");
@@ -761,14 +757,14 @@ function torbutton_socket_readline(input) {
// Bug 1506 P4: Control port interaction. Needed for New Identity.
function torbutton_read_authentication_cookie(path) {
- var file = Components.classes['@mozilla.org/file/local;1']
- .createInstance(Components.interfaces.nsIFile);
+ var file = Cc["@mozilla.org/file/local;1"]
+ .createInstance(Ci.nsIFile);
file.initWithPath(path);
- var fileStream = Components.classes['@mozilla.org/network/file-input-stream;1']
- .createInstance(Components.interfaces.nsIFileInputStream);
+ var fileStream = Cc["@mozilla.org/network/file-input-stream;1"]
+ .createInstance(Ci.nsIFileInputStream);
fileStream.init(file, 1, 0, false);
- var binaryStream = Components.classes['@mozilla.org/binaryinputstream;1']
- .createInstance(Components.interfaces.nsIBinaryInputStream);
+ var binaryStream = Cc["@mozilla.org/binaryinputstream;1"]
+ .createInstance(Ci.nsIBinaryInputStream);
binaryStream.setInputStream(fileStream);
var array = binaryStream.readByteArray(fileStream.available());
binaryStream.close();
@@ -795,8 +791,7 @@ function torbutton_send_ctrl_cmd(command) {
// suppressing/unsuppressing user initiated events in a window's document to
// be sure that these events are not interfering with processing events being
// in the event queue.
- var thread = Cc["@mozilla.org/thread-manager;1"].
- getService(Ci.nsIThreadManager).currentThread;
+ var thread = Services.tm.currentThread;
m_tb_domWindowUtils.suppressEventHandling(true);
while (thread.processNextEvent(false)) {}
m_tb_domWindowUtils.suppressEventHandling(false);
@@ -871,15 +866,14 @@ function torbutton_new_identity() {
// conditions leading to failures (see bug 11783 for an example).
// TODO: Remove the Torbutton menu entry again once we have done our
// security control redesign.
- document.getElementById("torbutton-new-identity").disabled = true;
+ // document.getElementById("torbutton-new-identity").disabled = true;
document.getElementById("menu_newIdentity").disabled = true;
document.getElementById("appMenuNewIdentity").disabled = true;
let shouldConfirm = m_tb_prefs.getBoolPref("extensions.torbutton.confirm_newnym");
if (shouldConfirm) {
- let prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"]
- .getService(Ci.nsIPromptService);
+ let prompts = Services.prompt;
// Display two buttons, both with string titles.
let flags = prompts.STD_YES_NO_BUTTONS;
@@ -898,7 +892,7 @@ function torbutton_new_identity() {
} else {
// TODO: Remove the Torbutton menu entry again once we have done our
// security control redesign.
- document.getElementById("torbutton-new-identity").disabled = false;
+ // document.getElementById("torbutton-new-identity").disabled = false;
document.getElementById("menu_newIdentity").disabled = false;
document.getElementById("appMenuNewIdentity").disabled = false;
}
@@ -910,11 +904,11 @@ function torbutton_new_identity() {
// enabled (again).
// TODO: Remove the Torbutton menu entry again once we have done our
// security control redesign.
- document.getElementById("torbutton-new-identity").disabled = false;
+ torbutton_log(5, "Unexpected error on new identity: " + e);
+ window.alert("Torbutton: Unexpected error on new identity: " + e);
+ // document.getElementById("torbutton-new-identity").disabled = false;
document.getElementById("menu_newIdentity").disabled = false;
document.getElementById("appMenuNewIdentity").disabled = false;
- torbutton_log(5, "Unexpected error on new identity: "+e);
- window.alert("Torbutton: Unexpected error on new identity: "+e);
}
}
@@ -941,7 +935,7 @@ function torbutton_new_identity() {
*/
// Bug 1506 P4: Needed for New Identity.
function torbutton_do_new_identity() {
- var obsSvc = Components.classes["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
+ var obsSvc = Services.obs;
torbutton_log(3, "New Identity: Disabling JS");
torbutton_disable_all_js();
@@ -995,9 +989,9 @@ function torbutton_do_new_identity() {
torbutton_log(3, "New Identity: Clearing HTTP Auth");
- if(m_tb_prefs.getBoolPref('extensions.torbutton.clear_http_auth')) {
- var auth = Components.classes["@mozilla.org/network/http-auth-manager;1"].
- getService(Components.interfaces.nsIHttpAuthManager);
+ if (m_tb_prefs.getBoolPref("extensions.torbutton.clear_http_auth")) {
+ var auth = Cc["@mozilla.org/network/http-auth-manager;1"].
+ getService(Ci.nsIHttpAuthManager);
auth.clearAll();
}
@@ -1006,8 +1000,8 @@ function torbutton_do_new_identity() {
// Clear all crypto auth tokens. This includes calls to PK11_LogoutAll(),
// nsNSSComponent::LogoutAuthenticatedPK11() and clearing the SSL session
// cache.
- let sdr = Components.classes["@mozilla.org/security/sdr;1"].
- getService(Components.interfaces.nsISecretDecoderRing);
+ let sdr = Cc["@mozilla.org/security/sdr;1"].
+ getService(Ci.nsISecretDecoderRing);
sdr.logoutAndTeardown();
// This clears the OCSP cache.
@@ -1047,8 +1041,7 @@ function torbutton_do_new_identity() {
torbutton_log(3, "New Identity: Clearing Offline Cache");
try {
- const LoadContextInfo = Cc["@mozilla.org/load-context-info-factory;1"]
- .getService(Ci.nsILoadContextInfoFactory);
+ const LoadContextInfo = Services.loadContextInfo;
for (let contextInfo of [LoadContextInfo.default, LoadContextInfo.private]) {
let appCacheStorage = Services.cache2.appCacheStorage(contextInfo, null);
@@ -1089,19 +1082,18 @@ function torbutton_do_new_identity() {
// This works only by setting the pref to `true` otherwise we get an
// exception and nothing is happening.
m_tb_prefs.setBoolPref("dom.quotaManager.testing", true);
- Cc["@mozilla.org/dom/quota-manager-service;1"]
- .getService(Ci.nsIQuotaManagerService).clear();
- } catch(e) {
- torbutton_log(5, "Exception on storage clearing: "+e);
+ Services.qms.clear();
+ } catch (e) {
+ torbutton_log(5, "Exception on storage clearing: " + e);
} finally {
m_tb_prefs.setBoolPref("dom.quotaManager.testing", orig_quota_test);
}
torbutton_log(3, "New Identity: Clearing Cookies and DOM Storage");
- if (m_tb_prefs.getBoolPref('extensions.torbutton.cookie_protections')) {
- var selector = Components.classes["@torproject.org/cookie-jar-selector;1"]
- .getService(Components.interfaces.nsISupports)
+ if (m_tb_prefs.getBoolPref("extensions.torbutton.cookie_protections")) {
+ var selector = Cc["@torproject.org/cookie-jar-selector;1"]
+ .getService(Ci.nsISupports)
.wrappedJSObject;
// This emits "cookie-changed", "cleared", which kills DOM storage
// and the safe browsing API key
@@ -1119,18 +1111,12 @@ function torbutton_do_new_identity() {
// XXX: This may not clear zoom site-specific
// browser.content.full-zoom
- if (Ci.nsIContentPrefService2) { // Firefox >= 20
- XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
- "resource://gre/modules/PrivateBrowsingUtils.jsm");
- var pbCtxt = PrivateBrowsingUtils.privacyContextFromWindow(window);
- var cps = Cc["@mozilla.org/content-pref/service;1"]
- .getService(Ci.nsIContentPrefService2);
- cps.removeAllDomains(pbCtxt);
- } else { // Firefox < 20
- var cps = Cc["@mozilla.org/content-pref/service;1"].
- createInstance(Ci.nsIContentPrefService);
- cps.removeGroupedPrefs();
- }
+ ChromeUtils.defineModuleGetter(this, "PrivateBrowsingUtils",
+ "resource://gre/modules/PrivateBrowsingUtils.jsm");
+ var pbCtxt = PrivateBrowsingUtils.privacyContextFromWindow(window);
+ var cps = Cc["@mozilla.org/content-pref/service;1"]
+ .getService(Ci.nsIContentPrefService2);
+ cps.removeAllDomains(pbCtxt);
torbutton_log(3, "New Identity: Syncing prefs");
@@ -1139,8 +1125,7 @@ function torbutton_do_new_identity() {
torbutton_log(3, "New Identity: Clearing permissions");
- let pm = Cc["@mozilla.org/permissionmanager;1"].
- getService(Ci.nsIPermissionManager);
+ let pm = Services.perms;
pm.removeAll();
// Clear the domain isolation state.
@@ -1234,8 +1219,7 @@ function torbutton_clear_image_caches()
// Try to clear the private browsing cache. To do so, we must locate
// a content document that is contained within a private browsing window.
let didClearPBCache = false;
- let wm = Cc["@mozilla.org/appshell/window-mediator;1"]
- .getService(Ci.nsIWindowMediator);
+ let wm = Services.wm;
let enumerator = wm.getEnumerator("navigator:browser");
while (!didClearPBCache && enumerator.hasMoreElements()) {
let win = enumerator.getNext();
@@ -1243,7 +1227,7 @@ function torbutton_clear_image_caches()
if (!browserDoc.hasAttribute("privatebrowsingmode"))
continue;
- let tabbrowser = win.getBrowser();
+ let tabbrowser = win.gBrowser;
if (!tabbrowser)
continue;
@@ -1372,8 +1356,7 @@ function torbutton_local_tor_check()
if (socksAddr && socksAddr.startsWith("file:")) {
// Convert the file URL to a file path.
try {
- let ioService = Cc["@mozilla.org/network/io-service;1"]
- .getService(Ci.nsIIOService);
+ let ioService = Services.io;
let fph = ioService.getProtocolHandler("file")
.QueryInterface(Ci.nsIFileProtocolHandler);
socksIPCPath = fph.getFileFromURLSpec(socksAddr).path;
@@ -1440,11 +1423,8 @@ function torbutton_local_tor_check()
} // torbutton_local_tor_check
-function torbutton_initiate_remote_tor_check()
-{
- let obsSvc = Cc["@mozilla.org/observer-service;1"]
- .getService(Ci.nsIObserverService);
-
+function torbutton_initiate_remote_tor_check() {
+ let obsSvc = Services.obs;
try {
let checkSvc = Cc["@torproject.org/torbutton-torCheckService;1"]
.getService(Ci.nsISupports).wrappedJSObject;
@@ -1573,13 +1553,12 @@ function torbutton_close_tabs_on_new_identity() {
// TODO: muck around with browser.tabs.warnOnClose.. maybe..
torbutton_log(3, "Closing tabs...");
- let wm = Cc["@mozilla.org/appshell/window-mediator;1"]
- .getService(Ci.nsIWindowMediator);
+ let wm = Services.wm;
let enumerator = wm.getEnumerator("navigator:browser");
- let windowsToClose = new Array();
+ let windowsToClose = [];
while (enumerator.hasMoreElements()) {
let win = enumerator.getNext();
- let browser = win.getBrowser();
+ let browser = win.gBrowser;
if (!browser) {
torbutton_log(5, "No browser for possible closed window");
continue;
@@ -1598,7 +1577,9 @@ function torbutton_close_tabs_on_new_identity() {
}
if (win == window) {
- browser.addTab("about:blank");
+ browser.addTab("about:blank", {
+ triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
+ });
} else {
// It is a bad idea to alter the window list while iterating
// over it, so add this window to an array and close it later.
@@ -1672,9 +1653,8 @@ function torbutton_open_cookie_dialog() {
// Bug 1506 P4: Used by New Identity if cookie protections are
// not in use.
function torbutton_clear_cookies() {
- torbutton_log(2, 'called torbutton_clear_cookies');
- var cm = Components.classes["@mozilla.org/cookiemanager;1"]
- .getService(Components.interfaces.nsICookieManager);
+ torbutton_log(2, "called torbutton_clear_cookies");
+ var cm = Services.cookies;
cm.removeAll();
}
@@ -1692,7 +1672,7 @@ function torbutton_disable_browser_js(browser) {
torbutton_log(3, "No content window to disable JS events.");
else
eventSuppressor = browser.contentWindow.
- QueryInterface(Components.interfaces.nsIInterfaceRequestor).
+ QueryInterface(Ci.nsIInterfaceRequestor).
getInterface(Ci.nsIDOMWindowUtils);
} catch(e) {
torbutton_log(4, "Failed to disable JS events: "+e)
@@ -1718,8 +1698,8 @@ function torbutton_disable_browser_js(browser) {
// Bug 1506 P3: The JS-killing bits of this are used by
// New Identity as a defense-in-depth measure.
function torbutton_disable_window_js(win) {
- var browser = win.getBrowser();
- if(!browser) {
+ var browser = win.gBrowser;
+ if (!browser) {
torbutton_log(5, "No browser for plugin window...");
return;
}
@@ -1760,8 +1740,7 @@ function torbutton_disable_window_js(win) {
// This is an ugly beast.. But unfortunately it has to be so..
// Looping over all tabs twice is not somethign we wanna do..
function torbutton_disable_all_js() {
- var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
- .getService(Components.interfaces.nsIWindowMediator);
+ var wm = Services.wm;
var enumerator = wm.getEnumerator("navigator:browser");
while(enumerator.hasMoreElements()) {
var win = enumerator.getNext();
@@ -1817,8 +1796,8 @@ function torbutton_do_startup()
{
if(m_tb_prefs.getBoolPref("extensions.torbutton.startup")) {
// Bug 1506: Still want to do this
- torbutton_toggle_plugins(
- m_tb_prefs.getBoolPref("plugin.disable"));
+ // torbutton_toggle_plugins(
+ // m_tb_prefs.getBoolPref("plugin.disable"));
// Bug 1506: Should probably be moved to an XPCOM component
torbutton_do_main_window_startup();
@@ -1839,7 +1818,7 @@ function torbutton_do_startup()
if (!m_tb_tbb && m_tb_prefs.getBoolPref("extensions.torbutton.prompt_torbrowser")) {
var warning = torbutton_get_property_string("torbutton.popup.short_torbrowser");
var title = torbutton_get_property_string("torbutton.title.prompt_torbrowser");
- var prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
+ var prompts = Services.prompt;
prompts.alert(null, title, warning);
}
@@ -1867,8 +1846,8 @@ function torbutton_new_tab(event)
function torbutton_is_windowed(wind) {
torbutton_log(3, "Window: (" + wind.outerWidth + "," + wind.outerHeight + ") ?= ("
+ wind.screen.availWidth + "," + wind.screen.availHeight + ")");
- if(wind.windowState == Components.interfaces.nsIDOMChromeWindow.STATE_MINIMIZED
- || wind.windowState == Components.interfaces.nsIDOMChromeWindow.STATE_MAXIMIZED) {
+ if (wind.windowState == Ci.nsIDOMChromeWindow.STATE_MINIMIZED
+ || wind.windowState == Ci.nsIDOMChromeWindow.STATE_MAXIMIZED) {
torbutton_log(2, "Window is minimized/maximized");
return false;
}
@@ -1904,8 +1883,9 @@ function showSecurityPreferencesPanel(chromeWindow) {
if (settingsTab === null) {
// Open up the settings panel in a new tab.
tabBrowser.addTab(SECURITY_PREFERENCES_URI, {
- 'selected': true,
- 'parentId': tabBrowser.selectedTab.id
+ "selected": true,
+ "parentId": tabBrowser.selectedTab.id,
+ triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
});
} else {
// Activate an existing settings panel tab.
@@ -1984,8 +1964,7 @@ function torbutton_close_window(event) {
// But that is a major overhaul..
if (m_tb_is_main_window) {
torbutton_log(3, "Original window closed. Searching for another");
- var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
- .getService(Components.interfaces.nsIWindowMediator);
+ var wm = Services.wm;
var enumerator = wm.getEnumerator("navigator:browser");
while(enumerator.hasMoreElements()) {
var win = enumerator.getNext();
@@ -2016,9 +1995,8 @@ function torbutton_close_window(event) {
function torbutton_open_network_settings() {
- var obsSvc = Components.classes["@mozilla.org/observer-service;1"]
- .getService(Ci.nsIObserverService);
- obsSvc.notifyObservers(this, "TorOpenNetworkSettings", null);
+ var obsSvc = Services.obs;
+ obsSvc.notifyObservers(this, "TorOpenNetworkSettings");
}
@@ -2032,14 +2010,7 @@ var m_tb_resize_date = null;
// probably not for android.
var torbutton_resizelistener =
{
- QueryInterface: function(aIID)
- {
- if (aIID.equals(Ci.nsIWebProgressListener) ||
- aIID.equals(Ci.nsISupportsWeakReference) ||
- aIID.equals(Ci.nsISupports))
- return this;
- throw Cr.NS_NOINTERFACE;
- },
+ QueryInterface: ChromeUtils.generateQI(["nsIWebProgressListener", "nsISupportsWeakReference"]),
onLocationChange: function(aProgress, aRequest, aURI) {},
onStateChange: function(aProgress, aRequest, aFlag, aStatus) {
@@ -2072,10 +2043,8 @@ var torbutton_resizelistener =
m_tb_resize_date = Date.now();
}
- let sb = torbutton_get_stringbundle();
// No need to get "OK" translated again.
- let sbSvc = Cc["@mozilla.org/intl/stringbundle;1"].
- getService(Ci.nsIStringBundleService);
+ let sbSvc = Services.strings;
let bundle = sbSvc.
createBundle("chrome://global/locale/commonDialogs.properties");
let button_label = bundle.GetStringFromName("OK");
@@ -2141,8 +2110,7 @@ var torbutton_resizelistener =
function torbutton_get_current_accept_language_value(aURI)
{
try {
- let ioService = Cc["@mozilla.org/network/io-service;1"]
- .getService(Ci.nsIIOService);
+ let ioService = Services.io;
let channel = ioService.newChannelFromURI(aURI);
let httpChannel = channel.QueryInterface(Ci.nsIHttpChannel);
return httpChannel.getRequestHeader("Accept-Language");
diff --git a/src/chrome/content/torbutton_util.js b/src/chrome/content/torbutton_util.js
index e6de7681..c7116a09 100644
--- a/src/chrome/content/torbutton_util.js
+++ b/src/chrome/content/torbutton_util.js
@@ -3,8 +3,9 @@
// code directly. I don't see any of them as essential for 1506,
// really.
-var m_tb_torlog = Components.classes["@torproject.org/torbutton-logger;1"]
-.getService(Components.interfaces.nsISupports).wrappedJSObject;
+// let { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm", {});
+var m_tb_torlog = Cc["@torproject.org/torbutton-logger;1"]
+.getService(Ci.nsISupports).wrappedJSObject;
var m_tb_string_bundle = torbutton_get_stringbundle();
@@ -28,10 +29,8 @@ function torbutton_get_prefbranch(branch_name) {
var o_branch = false;
torbutton_log(1, "called get_prefbranch()");
- o_prefs = Components.classes["@mozilla.org/preferences-service;1"]
- .getService(Components.interfaces.nsIPrefService);
- if (!o_prefs)
- {
+ o_prefs = Services.prefs;
+ if (!o_prefs) {
torbutton_log(5, "Failed to get preferences-service!");
return false;
}
@@ -52,8 +51,7 @@ function torbutton_get_stringbundle()
var o_stringbundle = false;
try {
- var oBundle = Components.classes["@mozilla.org/intl/stringbundle;1"]
- .getService(Components.interfaces.nsIStringBundleService);
+ var oBundle = Services.strings;
o_stringbundle = oBundle.createBundle("chrome://torbutton/locale/torbutton.properties");
} catch(err) {
o_stringbundle = false;
diff --git a/src/components/aboutTor.js b/src/components/aboutTor.js
index e3ee03d6..ec48d668 100644
--- a/src/components/aboutTor.js
+++ b/src/components/aboutTor.js
@@ -14,20 +14,15 @@ const kMODULE_CID = Components.ID("84d47da6-79c3-4661-aa9f-8049476f7bf5");
const kAboutTorURL = "chrome://torbutton/content/aboutTor/aboutTor.xhtml";
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
+const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-function AboutTor()
-{
-}
+function AboutTor() {}
AboutTor.prototype =
{
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]),
+ QueryInterface: ChromeUtils.generateQI([Ci.nsIAboutModule]),
// nsIClassInfo implementation:
classDescription: kMODULE_NAME,
@@ -35,11 +30,9 @@ AboutTor.prototype =
contractID: kMODULE_CONTRACTID,
// nsIAboutModule implementation:
- newChannel: function(aURI, aLoadInfo)
- {
- let ioSvc = Cc["@mozilla.org/network/io-service;1"]
- .getService(Ci.nsIIOService);
- let uri = ioSvc.newURI(kAboutTorURL, null, null);
+ newChannel(aURI, aLoadInfo) {
+ let ioSvc = Services.io;
+ let uri = ioSvc.newURI(kAboutTorURL);
let channel = ioSvc.newChannelFromURIWithLoadInfo(uri, aLoadInfo);
channel.originalURI = aURI;
diff --git a/src/components/cookie-jar-selector.js b/src/components/cookie-jar-selector.js
index 8456da3b..b3eeda53 100644
--- a/src/components/cookie-jar-selector.js
+++ b/src/components/cookie-jar-selector.js
@@ -18,12 +18,11 @@ const kMODULE_NAME = "Cookie Jar Selector";
const kMODULE_CONTRACTID = "@torproject.org/cookie-jar-selector;1";
const kMODULE_CID = Components.ID("e6204253-b690-4159-bfe8-d4eedab6b3be");
-const Cr = Components.results;
-const Cu = Components.utils;
-
-Cu.import("resource://torbutton/modules/default-prefs.js", {})
+ChromeUtils.import("resource://torbutton/modules/default-prefs.js", {})
.ensureDefaultPrefs();
+const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
+
// XXX: Must match the definition in torcookie.js :/
function Cookie(number,name,value,isDomain,host,rawHost,HttpOnly,path,isSecure,isSession,
expires,isProtected) {
@@ -42,73 +41,32 @@ function Cookie(number,name,value,isDomain,host,rawHost,HttpOnly,path,isSecure,i
}
function CookieJarSelector() {
- var Cc = Components.classes;
- var Ci = Components.interfaces;
-
- this.logger = Components.classes["@torproject.org/torbutton-logger;1"]
- .getService(Components.interfaces.nsISupports).wrappedJSObject;
+ this.logger = Cc["@torproject.org/torbutton-logger;1"]
+ .getService(Ci.nsISupports).wrappedJSObject;
- this.logger.log(3, "Component Load 5: New CookieJarSelector "+kMODULE_CONTRACTID);
+ this.logger.log(3, "Component Load 5: New CookieJarSelector " + kMODULE_CONTRACTID);
- this.prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
+ this.prefs = Services.prefs;
var getProfileFile = function(filename) {
- var loc = "ProfD"; // profile directory
- var file =
- Cc["@mozilla.org/file/directory_service;1"]
- .getService(Ci.nsIProperties)
+ var loc = "ProfD"; // profile directory
+ var file = Services.dirsvc
.get(loc, Ci.nsIFile)
.clone();
file.append(filename);
return file;
};
- var copyProfileFile = function(src, dest) {
- var srcfile = getProfileFile(src);
- var destfile = getProfileFile(dest);
- if (srcfile.exists()) {
- // XXX: Permissions issue with Vista roaming profiles?
- // Maybe file locking?
- try {
- if (destfile.exists()) {
- destfile.remove(false);
- }
- } catch(e) {
- this.logger.log(4, "Cookie file deletion exception: "+e);
- }
- try {
- srcfile.copyTo(null, dest);
- } catch(e) {
- this.logger.log(5, "Cookie file copy exception: "+e);
- }
- }
- };
-
- var moveProfileFile = function(src, dest) { // FIXME: Why does this not work?
- var srcfile = getProfileFile(src);
- var destfile = getProfileFile(dest);
- if (srcfile.exists()) {
- if (destfile.exists()) {
- destfile.remove(false);
- }
- srcfile.moveTo(null, dest);
- }
- };
-
this.clearCookies = function() {
try {
- Cc["@mozilla.org/cookiemanager;1"]
- .getService(Ci.nsICookieManager)
- .removeAll();
- } catch(e) {
- this.logger.log(4, "Cookie clearing exception: "+e);
+ Services.cookies.removeAll();
+ } catch (e) {
+ this.logger.log(4, "Cookie clearing exception: " + e);
}
};
this._cookiesToJS = function(getSession) {
- var cookieManager =
- Cc["@mozilla.org/cookiemanager;1"]
- .getService(Ci.nsICookieManager);
+ var cookieManager = Services.cookies;
var cookiesEnum = cookieManager.enumerator;
var cookiesAsJS = [];
var count = 0;
@@ -353,7 +311,7 @@ function CookieJarSelector() {
var nextCookie = enumerator.getNext();
if (!nextCookie) break;
- nextCookie = nextCookie.QueryInterface(Components.interfaces.nsICookie);
+ nextCookie = nextCookie.QueryInterface(Ci.nsICookie);
for (var i = 0; i < protCookies.length; i++) {
protcookie = protcookie || (nextCookie.host == protCookies[i].host &&
nextCookie.name == protCookies[i].name &&
@@ -371,7 +329,7 @@ function CookieJarSelector() {
}
// Emit cookie-changed event. This instructs other components to clear their identifiers
// (Specifically DOM storage and safe browsing, but possibly others)
- var obsSvc = Components.classes["@mozilla.org/observer-service;1"].getService(nsIObserverService);
+ var obsSvc = Cc["@mozilla.org/observer-service;1"].getService(nsIObserverService);
obsSvc.notifyObservers(this, "cookie-changed", "cleared");
} catch (e) {
this.logger.log(5, "Error deleting unprotected cookies: " + e);
@@ -410,10 +368,8 @@ function CookieJarSelector() {
};
// Check firefox version to know filename
- var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]
- .getService(Components.interfaces.nsIXULAppInfo);
- var versionChecker = Components.classes["@mozilla.org/xpcom/version-comparator;1"]
- .getService(Components.interfaces.nsIVersionComparator);
+ // var appInfo = Services.appinfo;
+ // var versionChecker = Services.vc;
// This JSObject is exported directly to chrome
this.wrappedJSObject = this;
@@ -424,15 +380,8 @@ function CookieJarSelector() {
this.timerCallback = {
cookie_changed: false,
- QueryInterface: function(iid) {
- if (!iid.equals(Component.interfaces.nsISupports) &&
- !iid.equals(Component.interfaces.nsITimer)) {
- Components.returnCode = Cr.NS_ERROR_NO_INTERFACE;
- return null;
- }
- return this;
- },
- notify: function() {
+ QueryInterface: ChromeUtils.generateQI(["nsITimer"]),
+ notify() {
// this refers to timerCallback object. use jarThis to reference
// CookieJarSelector object.
if(!this.cookie_changed) {
@@ -450,27 +399,18 @@ function CookieJarSelector() {
}
-const nsISupports = Components.interfaces.nsISupports;
-const nsIClassInfo = Components.interfaces.nsIClassInfo;
-const nsIObserver = Components.interfaces.nsIObserver;
-const nsITimer = Components.interfaces.nsITimer;
-const nsIComponentRegistrar = Components.interfaces.nsIComponentRegistrar;
-const nsIObserverService = Components.interfaces.nsIObserverService;
-const nsICategoryManager = Components.interfaces.nsICategoryManager;
+const nsISupports = Ci.nsISupports;
+const nsIClassInfo = Ci.nsIClassInfo;
+const nsIObserver = Ci.nsIObserver;
+const nsITimer = Ci.nsITimer;
+const nsIComponentRegistrar = Ci.nsIComponentRegistrar;
+const nsIObserverService = Ci.nsIObserverService;
+const nsICategoryManager = Ci.nsICategoryManager;
// Start1506: You may or may not care about this:
CookieJarSelector.prototype =
{
- QueryInterface: function(iid)
- {
- if (!iid.equals(nsIClassInfo) &&
- !iid.equals(nsIObserver) &&
- !iid.equals(nsISupports)) {
- Components.returnCode = Cr.NS_ERROR_NO_INTERFACE;
- return null;
- }
- return this;
- },
+ QueryInterface: ChromeUtils.generateQI(["nsIClassInfo", "nsIObserver"]),
wrappedJSObject: null, // Initialized by constructor
@@ -496,19 +436,18 @@ CookieJarSelector.prototype =
observe : function(aSubject, aTopic, aData) {
switch(aTopic) {
case "cookie-changed":
- var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
+ var prefs = Services.prefs;
this.timerCallback.cookie_changed = true;
-
+
if (aData == "added"
&& prefs.getBoolPref("extensions.torbutton.cookie_auto_protect")
- && !prefs.getBoolPref("extensions.torbutton.tor_memory_jar"))
- {
- this.addProtectedCookie(aSubject.QueryInterface(Components.interfaces.nsICookie2));//protect the new cookie!
+ && !prefs.getBoolPref("extensions.torbutton.tor_memory_jar")) {
+ this.addProtectedCookie(aSubject.QueryInterface(Ci.nsICookie2));// protect the new cookie!
}
break;
case "profile-after-change":
- var obsSvc = Components.classes["@mozilla.org/observer-service;1"].getService(nsIObserverService);
- obsSvc.addObserver(this, "cookie-changed", false);
+ var obsSvc = Cc["@mozilla.org/observer-service;1"].getService(nsIObserverService);
+ obsSvc.addObserver(this, "cookie-changed");
// after profil loading, initialize a timer to call timerCallback
// at a specified interval
this.timer.initWithCallback(this.timerCallback, 60 * 1000, nsITimer.TYPE_REPEATING_SLACK); // 1 minute
@@ -517,7 +456,7 @@ CookieJarSelector.prototype =
}
},
- timer: Components.classes["@mozilla.org/timer;1"].createInstance(nsITimer),
+ timer: Cc["@mozilla.org/timer;1"].createInstance(nsITimer),
}
@@ -525,7 +464,7 @@ CookieJarSelector.prototype =
* XPCOMUtils.generateNSGetFactory was introduced in Mozilla 2 (Firefox 4).
* XPCOMUtils.generateNSGetModule is for Mozilla 1.9.2 (Firefox 3.6).
*/
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
if (XPCOMUtils.generateNSGetFactory)
var NSGetFactory = XPCOMUtils.generateNSGetFactory([CookieJarSelector]);
else
diff --git a/src/components/domain-isolator.js b/src/components/domain-isolator.js
index fc28703f..e04005a5 100644
--- a/src/components/domain-isolator.js
+++ b/src/components/domain-isolator.js
@@ -6,21 +6,19 @@
// call earlier functions). The code file can be processed
// with docco.js to provide clear documentation.
-/* jshint esversion: 6 */
-/* global Components, console, XPCOMUtils */
-
// ### Abbreviations
-const Cc = Components.classes, Ci = Components.interfaces, Cu = Components.utils;
+
+const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
// Make the logger available.
let logger = Cc["@torproject.org/torbutton-logger;1"]
- .getService(Components.interfaces.nsISupports).wrappedJSObject;
+ .getService(Ci.nsISupports).wrappedJSObject;
-let { ensureDefaultPrefs } = Cu.import("resource://torbutton/modules/default-prefs.js", {});
+let { ensureDefaultPrefs } = ChromeUtils.import("resource://torbutton/modules/default-prefs.js", {});
ensureDefaultPrefs();
// Import Services object
-Cu.import("resource://gre/modules/Services.jsm");
+ChromeUtils.import("resource://gre/modules/Services.jsm");
// Import crypto object (FF 37+).
Cu.importGlobalProperties(["crypto"]);
@@ -82,6 +80,8 @@ tor.socksProxyCredentials = function (originalProxy, domain) {
proxy.port,
domain, // username
tor.noncesForDomains[domain], // password
+ "", // aProxyAuthorizationHeader
+ "", // aConnectionIsolationKey
proxy.flags,
proxy.failoverTimeout,
proxy.failoverProxy);
@@ -138,7 +138,6 @@ tor.isolateCircuitsByDomain = function () {
}
try {
let channel = aChannel.QueryInterface(Ci.nsIChannel),
- proxy = aProxy.QueryInterface(Ci.nsIProxyInfo),
firstPartyDomain = channel.loadInfo.originAttributes.firstPartyDomain;
if (firstPartyDomain === "") {
firstPartyDomain = "--unknown--";
@@ -165,7 +164,7 @@ const kMODULE_CONTRACTID = "@torproject.org/domain-isolator;1";
const kMODULE_CID = Components.ID("e33fd6d4-270f-475f-a96f-ff3140279f68");
// Import XPCOMUtils object.
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
// DomainIsolator object.
function DomainIsolator() {
@@ -174,7 +173,7 @@ function DomainIsolator() {
// Firefox component requirements
DomainIsolator.prototype = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports, Ci.nsIObserver]),
+ QueryInterface: ChromeUtils.generateQI([Ci.nsISupports, Ci.nsIObserver]),
classDescription: kMODULE_NAME,
classID: kMODULE_CID,
contractID: kMODULE_CONTRACTID,
diff --git a/src/components/dragDropFilter.js b/src/components/dragDropFilter.js
index 916b835f..4465187e 100644
--- a/src/components/dragDropFilter.js
+++ b/src/components/dragDropFilter.js
@@ -5,13 +5,11 @@
* access to URLs (a potential proxy bypass vector).
*************************************************************************/
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-Cu.import("resource://torbutton/modules/default-prefs.js", {}).ensureDefaultPrefs();
+ChromeUtils.import("resource://torbutton/modules/default-prefs.js", {}).ensureDefaultPrefs();
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
// Module specific constants
const kMODULE_NAME = "Torbutton Drag and Drop Handler";
@@ -26,17 +24,15 @@ function DragDropFilter() {
this.logger.log(3, "Component Load 0: New DragDropFilter.");
try {
- var observerService = Cc["@mozilla.org/observer-service;1"].
- getService(Ci.nsIObserverService);
- observerService.addObserver(this, "on-datatransfer-available", false);
- } catch(e) {
+ Services.obs.addObserver(this, "on-datatransfer-available");
+ } catch (e) {
this.logger.log(5, "Failed to register drag observer");
}
}
DragDropFilter.prototype =
{
- QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports, Ci.nsIObserver]),
+ QueryInterface: ChromeUtils.generateQI([Ci.nsISupports, Ci.nsIObserver]),
// make this an nsIClassInfo object
flags: Ci.nsIClassInfo.DOM_OBJECT,
diff --git a/src/components/external-app-blocker.js b/src/components/external-app-blocker.js
index 1f88fc78..747824d1 100644
--- a/src/components/external-app-blocker.js
+++ b/src/components/external-app-blocker.js
@@ -12,14 +12,9 @@
* handle an URL (e.g., when the user clicks on a mailto: URL).
*************************************************************************/
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cr = Components.results;
-const Cu = Components.utils;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/SharedPromptUtils.jsm");
+const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const {PromptUtils} = ChromeUtils.import("resource://gre/modules/SharedPromptUtils.jsm");
// Module specific constants
const kMODULE_NAME = "Torbutton External App Handler";
@@ -38,7 +33,7 @@ ExternalAppBlocker.prototype =
{
_helperAppLauncher: undefined,
- QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports, Ci.nsIObserver,
+ QueryInterface: ChromeUtils.generateQI([Ci.nsISupports, Ci.nsIObserver,
Ci.nsIHelperAppWarningDialog]),
// make this an nsIClassInfo object
diff --git a/src/components/torCheckService.js b/src/components/torCheckService.js
index 19e13f49..4f79bef4 100644
--- a/src/components/torCheckService.js
+++ b/src/components/torCheckService.js
@@ -7,16 +7,13 @@
* Tor check service
*************************************************************************/
+const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
+
// Module specific constants
const kMODULE_NAME = "Torbutton Tor Check Service";
const kMODULE_CONTRACTID = "@torproject.org/torbutton-torCheckService;1";
const kMODULE_CID = Components.ID("5d57312b-5d8c-4169-b4af-e80d6a28a72e");
-const Cr = Components.results;
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-
function TBTorCheckService() {
this._logger = Cc["@torproject.org/torbutton-logger;1"]
.getService(Ci.nsISupports).wrappedJSObject;
@@ -28,15 +25,7 @@ function TBTorCheckService() {
TBTorCheckService.prototype =
{
- QueryInterface: function(iid) {
- if (!iid.equals(Ci.nsIClassInfo) &&
- !iid.equals(Ci.nsISupports)) {
- Components.returnCode = Cr.NS_ERROR_NO_INTERFACE;
- return null;
- }
-
- return this;
- },
+ QueryInterface: ChromeUtils.generateQI([Ci.nsISupports, Ci.nsIClassInfo]),
kCheckNotInitiated: 0, // Possible values for statusOfTorCheck.
kCheckSuccessful: 1,
@@ -79,10 +68,8 @@ TBTorCheckService.prototype =
{
Cu.importGlobalProperties(["XMLHttpRequest"]);
let req = new XMLHttpRequest();
- let prefs = Cc["@mozilla.org/preferences-service;1"]
- .getService(Ci.nsIPrefBranch);
- let url = prefs.getCharPref("extensions.torbutton.test_url");
- req.open('GET', url, aAsync);
+ let url = Services.prefs.getCharPref("extensions.torbutton.test_url");
+ req.open("GET", url, aAsync);
req.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
req.overrideMimeType("text/xml");
req.timeout = 120000; // Wait at most two minutes for a response.
@@ -140,8 +127,8 @@ TBTorCheckService.prototype =
}
return ret;
- }
+ },
};
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
var NSGetFactory = XPCOMUtils.generateNSGetFactory([TBTorCheckService]);
diff --git a/src/components/torbutton-logger.js b/src/components/torbutton-logger.js
index fdf7bb7d..ce4ba70b 100644
--- a/src/components/torbutton-logger.js
+++ b/src/components/torbutton-logger.js
@@ -13,31 +13,25 @@ const kMODULE_NAME = "Torbutton Logger";
const kMODULE_CONTRACTID = "@torproject.org/torbutton-logger;1";
const kMODULE_CID = Components.ID("f36d72c9-9718-4134-b550-e109638331d7");
-const Cr = Components.results;
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
+ChromeUtils.import("resource://torbutton/modules/default-prefs.js", {}).ensureDefaultPrefs();
-Cu.import("resource://torbutton/modules/default-prefs.js", {}).ensureDefaultPrefs();
-
-Cu.import("resource://gre/modules/Services.jsm");
+const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
function TorbuttonLogger() {
// Register observer
- Services.prefs.addObserver("extensions.torbutton", this, false);
+ Services.prefs.addObserver("extensions.torbutton", this);
this.loglevel = Services.prefs.getIntPref("extensions.torbutton.loglevel");
this.logmethod = Services.prefs.getIntPref("extensions.torbutton.logmethod");
try {
- var logMngr = Components.classes["@mozmonkey.com/debuglogger/manager;1"]
- .getService(Components.interfaces.nsIDebugLoggerManager);
+ var logMngr = Cc["@mozmonkey.com/debuglogger/manager;1"]
+ .getService(Ci.nsIDebugLoggerManager);
this._debuglog = logMngr.registerLogger("torbutton");
} catch (exErr) {
this._debuglog = false;
}
- this._console = Components.classes["@mozilla.org/consoleservice;1"]
- .getService(Components.interfaces.nsIConsoleService);
+ this._console = Services.console;
// This JSObject is exported directly to chrome
this.wrappedJSObject = this;
@@ -50,10 +44,10 @@ function TorbuttonLogger() {
* Everything below is boring boilerplate and can probably be ignored.
*/
-const nsISupports = Components.interfaces.nsISupports;
-const nsIClassInfo = Components.interfaces.nsIClassInfo;
-const nsIComponentRegistrar = Components.interfaces.nsIComponentRegistrar;
-const nsIObserverService = Components.interfaces.nsIObserverService;
+const nsISupports = Ci.nsISupports;
+const nsIClassInfo = Ci.nsIClassInfo;
+const nsIComponentRegistrar = Ci.nsIComponentRegistrar;
+const nsIObserverService = Ci.nsIObserverService;
const logString = { 1:"VERB", 2:"DBUG", 3: "INFO", 4:"NOTE", 5:"WARN" };
@@ -64,15 +58,7 @@ function padInt(i)
TorbuttonLogger.prototype =
{
- QueryInterface: function(iid)
- {
- if (!iid.equals(nsIClassInfo) &&
- !iid.equals(nsISupports)) {
- Components.returnCode = Cr.NS_ERROR_NO_INTERFACE;
- return null;
- }
- return this;
- },
+ QueryInterface: ChromeUtils.generateQI([Ci.nsISupports, Ci.nsIClassInfo]),
wrappedJSObject: null, // Initialized by constructor
@@ -176,7 +162,7 @@ TorbuttonLogger.prototype =
* XPCOMUtils.generateNSGetFactory was introduced in Mozilla 2 (Firefox 4).
* XPCOMUtils.generateNSGetModule is for Mozilla 1.9.2 (Firefox 3.6).
*/
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
if (XPCOMUtils.generateNSGetFactory)
var NSGetFactory = XPCOMUtils.generateNSGetFactory([TorbuttonLogger]);
else
diff --git a/src/modules/default-prefs.js b/src/modules/default-prefs.js
index 6a2bd86c..5ea549f4 100644
--- a/src/modules/default-prefs.js
+++ b/src/modules/default-prefs.js
@@ -4,7 +4,7 @@ function ensureDefaultPrefs () {
if (loaded) {
return;
}
- Components.utils.import("resource://gre/modules/Services.jsm");
+ const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
const kDefaultPreferences = "resource://torbutton/defaults/preferences/preferences.js";
const defaultPrefBranch = Services.prefs.getDefaultBranch(null);
diff --git a/src/modules/noscript-control.js b/src/modules/noscript-control.js
index 4513dce8..0daf15e1 100644
--- a/src/modules/noscript-control.js
+++ b/src/modules/noscript-control.js
@@ -1,17 +1,16 @@
// # NoScript settings control (for binding to Security Slider)
-/* jshint esversion:6 */
-
// ## Utilities
-const { utils: Cu } = Components;
-const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
-const { LegacyExtensionContext } =
- Cu.import("resource://gre/modules/LegacyExtensionsUtils.jsm", {});
+const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm", {});
const { bindPref } =
- Cu.import("resource://torbutton/modules/utils.js", {});
-let logger = Components.classes["@torproject.org/torbutton-logger;1"]
- .getService(Components.interfaces.nsISupports).wrappedJSObject;
+ ChromeUtils.import("resource://torbutton/modules/utils.js", {});
+
+const { ExtensionUtils } = ChromeUtils.import("resource://gre/modules/ExtensionUtils.jsm");
+const { MessageChannel } = ChromeUtils.import("resource://gre/modules/MessageChannel.jsm");
+
+let logger = Cc["@torproject.org/torbutton-logger;1"]
+ .getService(Ci.nsISupports).wrappedJSObject;
let log = (level, msg) => logger.log(level, msg);
// ## NoScript settings
@@ -100,20 +99,28 @@ var initialize = () => {
initialized = true;
try {
- // A mock extension object that can communicate with another extension
- // via the WebExtensions sendMessage/onMessage mechanism.
- let extensionContext = new LegacyExtensionContext({ id : noscriptID });
+ // LegacyExtensionContext is not there anymore. Using raw
+ // Services.mm.broadcastAsyncMessage mecanism to communicate with
+ // NoScript.
// The component that handles WebExtensions' sendMessage.
- let messageManager = extensionContext.messenger.messageManagers[0];
// __setNoScriptSettings(settings)__.
// NoScript listens for internal settings with onMessage. We can send
// a new settings JSON object according to NoScript's
// protocol and these are accepted! See the use of
// `browser.runtime.onMessage.addListener(...)` in NoScript's bg/main.js.
+
+ // TODO: Is there a better way?
let sendNoScriptSettings = settings =>
- extensionContext.messenger.sendMessage(messageManager, settings, noscriptID);
+ Services.mm.broadcastAsyncMessage("MessageChannel:Messages", [{
+ messageName: "Extension:Message",
+ sender: { id: noscriptID, extensionId: noscriptID },
+ recipient: { extensionId: noscriptID },
+ data: new StructuredCloneHolder(settings),
+ channelId: ExtensionUtils.getUniqueId(),
+ responseType: MessageChannel.RESPONSE_NONE,
+ }]);
// __setNoScriptSafetyLevel(safetyLevel)__.
// Set NoScript settings according to a particular safety level
@@ -129,13 +136,20 @@ var initialize = () => {
// Wait for the first message from NoScript to arrive, and then
// bind the security_slider pref to the NoScript settings.
- let messageListener = (a,b,c) => {
+ const listener = ({ data }) => {
+ for (const msg of data) {
+ if (msg.recipient.extensionId === noscriptID) {
+ messageListener(msg.data.deserialize({}), msg.sender);
+ }
+ }
+ };
+ let messageListener = (a, b, c) => {
try {
- log(3, `Message received from NoScript: ${JSON.stringify([a,b,c])}`);
+ log(3, `Message received from NoScript: ${JSON.stringify([a, b, c])}`);
if (!["started", "pageshow"].includes(a.__meta.name)) {
return;
}
- extensionContext.api.browser.runtime.onMessage.removeListener(messageListener);
+ Services.mm.removeMessageListener("MessageChannel:Messages", listener);
let noscriptPersist = Services.prefs.getBoolPref("extensions.torbutton.noscript_persist", false);
let noscriptInited = Services.prefs.getBoolPref("extensions.torbutton.noscript_inited", false);
// Set the noscript safety level once if we have never run noscript
@@ -153,7 +167,7 @@ var initialize = () => {
log(5, e.message);
}
};
- extensionContext.api.browser.runtime.onMessage.addListener(messageListener);
+ Services.mm.addMessageListener("MessageChannel:Messages", listener);
log(3, "Listening for message from NoScript.");
} catch (e) {
log(5, e.message);
diff --git a/src/modules/security-prefs.js b/src/modules/security-prefs.js
index fa97b70d..ffc5ee39 100644
--- a/src/modules/security-prefs.js
+++ b/src/modules/security-prefs.js
@@ -2,13 +2,12 @@
// ### Utilities
-let {classes: Cc, utils: Cu } = Components;
let { getBoolPref, setBoolPref, getIntPref, setIntPref } =
- Cu.import("resource://gre/modules/Services.jsm", {}).Services.prefs;
+ ChromeUtils.import("resource://gre/modules/Services.jsm", {}).Services.prefs;
let { bindPref, bindPrefAndInit } =
- Cu.import("resource://torbutton/modules/utils.js", {});
-let logger = Components.classes["@torproject.org/torbutton-logger;1"]
- .getService(Components.interfaces.nsISupports).wrappedJSObject;
+ ChromeUtils.import("resource://torbutton/modules/utils.js", {});
+let logger = Cc["@torproject.org/torbutton-logger;1"]
+ .getService(Ci.nsISupports).wrappedJSObject;
let log = (level, msg) => logger.log(level, msg);
// ### Constants
diff --git a/src/modules/tor-control-port.js b/src/modules/tor-control-port.js
index 2c399367..f1d9ed14 100644
--- a/src/modules/tor-control-port.js
+++ b/src/modules/tor-control-port.js
@@ -19,15 +19,15 @@
"use strict";
// ### Mozilla Abbreviations
-let {classes: Cc, interfaces: Ci, results: Cr, Constructor: CC, utils: Cu } = Components;
+let { Constructor: CC } = Components;
// ### Import Mozilla Services
-Cu.import("resource://gre/modules/Services.jsm");
+const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
// __log__.
// Logging function
let logger = Cc["@torproject.org/torbutton-logger;1"]
- .getService(Components.interfaces.nsISupports).wrappedJSObject;
+ .getService(Ci.nsISupports).wrappedJSObject;
let log = x => logger.eclog(3, x.trimRight().replace(/\r\n/g, "\n"));
// ### announce this file
@@ -42,8 +42,8 @@ let io = {};
// given ipcFile or host and port.
io.asyncSocketStreams = function (ipcFile, host, port) {
let sts = Cc["@mozilla.org/network/socket-transport-service;1"]
- .getService(Components.interfaces.nsISocketTransportService),
- UNBUFFERED = Ci.nsITransport.OPEN_UNBUFFERED;
+ .getService(Ci.nsISocketTransportService),
+ UNBUFFERED = Ci.nsITransport.OPEN_UNBUFFERED;
// Create an instance of a socket transport.
let socketTransport;
diff --git a/src/modules/utils.js b/src/modules/utils.js
index d7baca6e..7b81819d 100644
--- a/src/modules/utils.js
+++ b/src/modules/utils.js
@@ -1,14 +1,8 @@
// # Utils.js
// Various helpful utility functions.
-// ### Shortcut
-const { Cu: utils, Cr: results } = Components;
-
// ### Import Mozilla Services
-Cu.import("resource://gre/modules/Services.jsm");
-
-// ### Import global URL
-Cu.importGlobalProperties(["URL"]);
+const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
// ### About firstPartyDomain literal
const k_tb_about_uri_first_party_domain = "about.ef2a7dd5-93bc-417f-a698-142c3116864f.mozilla";
@@ -76,8 +70,8 @@ var observe = function (topic, callback) {
// __env__.
// Provides access to process environment variables.
-let env = Components.classes["@mozilla.org/process/environment;1"]
- .getService(Components.interfaces.nsIEnvironment);
+let env = Cc["@mozilla.org/process/environment;1"]
+ .getService(Ci.nsIEnvironment);
// __getEnv(name)__.
// Reads the environment variable of the given name.
@@ -88,8 +82,8 @@ var getEnv = function (name) {
// __getLocale
// Reads the browser locale, the default locale is en-US.
var getLocale = function() {
- return Services.locale.getRequestedLocale() || "en-US";
-}
+ return Services.locale.requestedLocale || "en-US";
+};
// ## Windows
1
0
commit f7238d222fe4803070f65638cd5bbd4f778a477a
Author: Alex Catarineu <acat(a)torproject.org>
Date: Fri May 10 13:11:03 2019 +0200
XPI build not supported anymore
---
.gitignore | 1 -
README.BUILD | 19 ---
README.RELEASE | 107 --------------
makexpi.sh | 32 -----
update-unsigned.rdf | 392 ----------------------------------------------------
5 files changed, 551 deletions(-)
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 5fff1d9c..00000000
--- a/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-pkg
diff --git a/README.BUILD b/README.BUILD
deleted file mode 100644
index ea0803d7..00000000
--- a/README.BUILD
+++ /dev/null
@@ -1,19 +0,0 @@
-To build an XPI that is suitable for Babelzilla, do the following:
-
- patch -p0 < no-english.diff
- chmod +x makexpi.sh
- ./makexpi.sh
- cd pkg/
-
-You should see:
-
- file torbutton-1.2.0rc1.xpi
- pkg/torbutton-1.2.0rc1.xpi: Zip archive data, at least v1.0 to extract
-
-This is to work around the fact that an xpi requires empty strings for
-incomplete translations or the formatting of various dialogs will be broken.
-Furthermore, Babelzilla doesn't know an english string from a Japanese string
-and simply records translations as matching strings. The XPI resulting from
-the above build process will be ready for Babelzilla but should not be used by
-anyone else.
-
diff --git a/README.RELEASE b/README.RELEASE
deleted file mode 100644
index 42365832..00000000
--- a/README.RELEASE
+++ /dev/null
@@ -1,107 +0,0 @@
-# Magical Torbutton Release Process Incantations
-#
-# "May this part of my job one day be replaced by a small shell script"
-#
-
-#. Decide the version number.
-
- export VERSION="1.5.2"
- vim ./src/install.rdf # edit <em:version> tag to reflect version
-
-#. Test upgrades of candidate XPI in latest Firefox and TBB product matrix
-
- # TODO: Currently manual
-
-#. Generate changelog from git shortlog
-
- # TODO: Currently manual
-
-#. tx noise: https://svn.torproject.org/svn/translation/trunk/documentation/howto.txt
-
- cd torbutton.git/trans_tools/po
- torsocks svn up
- torsocks tx pull -a
- cd ..
- ./validate_all.sh | less
-
- torsocks ./new_tb_strings.sh
-
- ./mkmoz.sh
- ./mvmoz.sh
- cd ..
- git diff .
- git commit .
-
-#. Tag the release:
-
- git tag -u mikeperry(a)fscked.org -s ${VERSION}
- torsocks git push origin-push --tags
-
-#. Create the .xpi
-
- cd /tmp/
- torsocks git clone git://git.torproject.org/git/torbutton.git torbutton-release
- cd torbutton-release
- git tag -v ${VERSION} # verify signature against git protocol haaAAXXXX
- git checkout -b tag-${VERSION} ${VERSION}
- mkdir ./pkg
- sh makexpi.sh
-
-#. SHA1 + Sign the .xpi
-
- gpg -abs ./pkg/torbutton-${VERSION}.xpi
- sha1sum ./pkg/torbutton-${VERSION}.xpi
-
-#. Upload .xpi to website
-
- chmod 664 ./pkg/torbutton-${VERSION}.xpi*
- torsocks scp ./pkg/torbutton-${VERSION}.xpi* vescum:/srv/www-master.torproject.org/htdocs/dist/torbutton/
- torsocks scp ./pkg/torbutton-${VERSION}.xpi vescum:/srv/www-master.torproject.org/htdocs/dist/torbutton/torbutton-curre…
- torsocks scp ./pkg/torbutton-${VERSION}.xpi.asc vescum:/srv/www-master.torproject.org/htdocs/dist/torbutton/torbutton-curre…
-
-#. Update update-unsigned.rdf in torbutton.git with package sha1
-
- cd torbutton.git
- vim update-unsigned.rdf # Add <li> and <description> w/ sha1 and version
-
-#. Sign the new update-unsigned.rdf.
-
- # Key creation based on these instructions:
- # Command line: http://blog.techno-barje.fr/post/2009/10/08/How-to-setup-a-mozilla-extensio…
- # Gui: https://www.binaryturf.com/steps-release-extension-firefox-3/
-
- # TODO: Process currently manual due to offline signing.
- # No need to fear the reaper, man. We can do online signing if we just put
- # our minds to it: https://trac.torproject.org/projects/tor/ticket/6011
-
- # Special note: I was unable to update an already signed
- # copy of the update.rdf for a new release. We probably need to
- # keep the unsigned version around as input? See the root directory
- # of the torbutton.git for a copy.
- ./mccoy-cli.x86/mccoy -profile ./.mozilla/mccoy/*.default/ -signRDF update-unsigned.rdf -key Torbutton
-
- # Copy the signed update.rdf into place in the website svn
-
-#. Update update.rdf
-
- cd website-svn
- vim ./include/versions.wmi # Add sha1 and version
- cp /mnt/update-signed.rdf ./torbutton/update.rdf
-
-#. Update website
-
- torsocks svn up .
- torsocks svn commit .
-
- torsocks ssh vescum "/home/mirroradm/bin/trigger-mirrors"
-
-#. Test firefox autoupdate
-
- # Wait for mirrors to sync first.. Pester phobos/weasel/helix/Sebastian for
- # website push + dist chown + mirror update.
- # TODO: Currently manual
-
-#. Announce on tor-talk
-
- # FIXME: May need eventual minor improvements
- echo "Troll food." | mail tor-talk(a)lists.torproject.org -s "Feed the trolls"
diff --git a/makexpi.sh b/makexpi.sh
deleted file mode 100755
index 243fbd6b..00000000
--- a/makexpi.sh
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/sh
-APP_NAME=torbutton
-#VERSION=`grep em:version src/install.rdf | sed -e 's/["]//g' | cut -f2 -d=`
-XPI_NAME="$APP_NAME-`grep em:version src/install.rdf | sed -e 's/[<>]/ /g' | cut -f3`.xpi"
-
-if [ -e "pkg/$XPI_NAME" ]; then
- echo pkg/$XPI_NAME already exists.
- rm pkg/$XPI_NAME # meh.
- # exit 1
-fi
-
-# create jar file (we're just storing files here)
-echo ---------- create $APP_NAME.jar file ----------
-cd src/chrome
-#zip -r0 ../../$APP_NAME.jar ./ -x "*.svn/*"
-cd ../..
-
-# create .xpi
-echo ---------- create $APP_NAME.xpi ----------
-# create the pkg directory if it doesn't exist yet
-mkdir -p pkg
-cd src
-echo zip -X -9r ../pkg/$XPI_NAME ./ -x "chrome/*" -x "*.diff" -x "*.svn/*"
-zip -X -9r ../pkg/$XPI_NAME ./ -x "*.svn/*" -x "*.diff" #-x "chrome/*"
-#mv ../$APP_NAME.jar ./chrome
-#zip -9m ../pkg/$XPI_NAME chrome/$APP_NAME.jar
-cd ..
-
-#cp ./pkg/$XPI_NAME ~/
-#zip -9m ../../downloads/$sXpiName chrome/$APP_NAME.jar
-#zip -9 ../../downloads/$sXpiName install.rdf
-#cd ..
diff --git a/update-unsigned.rdf b/update-unsigned.rdf
deleted file mode 100644
index d4a013a7..00000000
--- a/update-unsigned.rdf
+++ /dev/null
@@ -1,392 +0,0 @@
-<?xml version="1.0"?>
-
-<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:em="http://www.mozilla.org/2004/em-rdf#">
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}">
- <em:updates>
- <Seq>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.1.14-alpha"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.1.15-alpha"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.1.16-alpha"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.1.17-alpha"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.1.18alpha"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.0rc1"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.0rc2"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.0rc3"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.0rc4"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.0rc5"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.0rc6"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.0"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.3.2-alpha"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.3.3-alpha"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.4.0"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.4.1"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.4.2"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.4.3"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.4.4"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.4.4.1"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.4.5"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.4.5.1"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.4.6"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.4.6.1"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.4.6.2"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.4.6.3"/>
- </Seq>
- </em:updates>
-
- </Description>
-
- <!-- version 1.1.14 -->
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.1.14-alpha">
- <em:version>1.1.14-alpha</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>3.0b*</em:maxVersion>
- <em:updateLink>https://www.torproject.org/torbutton/releases/torbutton-1.1.14-alpha.xpi</em:updateLink>
- <em:updateHash>sha1:b316f9d84930ecf23b0797f93a6433334a4c38d5</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.1.15-alpha">
- <em:version>1.1.15-alpha</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>3.0b*</em:maxVersion>
- <em:updateLink>https://www.torproject.org/torbutton/releases/torbutton-1.1.15-alpha.xpi</em:updateLink>
- <em:updateHash>sha1:fa0d47c98d258ba904d828bea15b140ab438eb56</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.1.16-alpha">
- <em:version>1.1.16-alpha</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>3.0b*</em:maxVersion>
- <em:updateLink>https://www.torproject.org/torbutton/releases/torbutton-1.1.16-alpha.xpi</em:updateLink>
- <em:updateHash>sha1:f892dac7e5da8c63005f896c9aa1436e3f77ab4b</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.1.17-alpha">
- <em:version>1.1.17-alpha</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>3.0b*</em:maxVersion>
- <em:updateLink>https://www.torproject.org/torbutton/releases/torbutton-1.1.17-alpha.xpi</em:updateLink>
- <em:updateHash>sha1:93e17f955655eb31e5a6ff9f71dfde479a5b7a6d</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.1.18alpha">
- <em:version>1.1.18alpha</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>3.0b*</em:maxVersion>
- <em:updateLink>https://www.torproject.org/torbutton/releases/torbutton-1.1.18alpha.xpi</em:updateLink>
- <em:updateHash>sha1:6fdcebcb1e6cc694b45065c2b6df07ffb12ea164</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.0rc1">
- <em:version>1.2.0rc1</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>3.1a1pre</em:maxVersion>
- <em:updateLink>https://www.torproject.org/torbutton/releases/torbutton-1.2.0rc1.xpi</em:updateLink>
- <em:updateHash>sha1:8c8cb5e7e3844b8310151c5b56fb622134ea67f6</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.0rc2">
- <em:version>1.2.0rc2</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>3.1a1pre</em:maxVersion>
- <em:updateLink>https://www.torproject.org/torbutton/releases/torbutton-1.2.0rc2.xpi</em:updateLink>
- <em:updateHash>sha1:f0d6e121e2b0fbd4d1db7c3f333b8d7ab5c1d906</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.0rc3">
- <em:version>1.2.0rc3</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>3.1a1pre</em:maxVersion>
- <em:updateLink>https://www.torproject.org/torbutton/releases/torbutton-1.2.0rc3.xpi</em:updateLink>
- <em:updateHash>sha1:184294b480119bb7b943ede116345c52ee7772fc</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.0rc4">
- <em:version>1.2.0rc4</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>3.1a1pre</em:maxVersion>
- <em:updateLink>https://www.torproject.org/torbutton/releases/torbutton-1.2.0rc4.xpi</em:updateLink>
- <em:updateHash>sha1:23df6a12c7140b5817338136da1cd7737412bbbb</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.0rc5">
- <em:version>1.2.0rc5</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>3.1a1pre</em:maxVersion>
- <em:updateLink>https://www.torproject.org/torbutton/releases/torbutton-1.2.0rc5.xpi</em:updateLink>
- <em:updateHash>sha1:050925e2c02e61f2f0ceb4683600fc0c58a835bb</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.0rc6">
- <em:version>1.2.0rc6</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>3.1a1pre</em:maxVersion>
- <em:updateLink>https://www.torproject.org/torbutton/releases/torbutton-1.2.0rc6.xpi</em:updateLink>
- <em:updateHash>sha1:7f01c577641b6222781cd880c9825d6f50ff1cc4</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.0">
- <em:version>1.2.0</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>3.1a1pre</em:maxVersion>
- <em:updateLink>https://www.torproject.org/torbutton/releases/torbutton-1.2.0.xpi</em:updateLink>
- <em:updateHash>sha1:086e2a05b8e5393f2f28533cdb715e69465c3169</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.1">
- <em:version>1.2.1</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>3.1a1pre</em:maxVersion>
- <em:updateLink>https://www.torproject.org/torbutton/releases/torbutton-1.2.1.xpi</em:updateLink>
- <em:updateHash>sha1:204766e5c9112aba7313e3ab98023f57f1668978</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.3.2-alpha">
- <em:version>1.3.2-alpha</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>4.0</em:maxVersion>
- <em:updateLink>https://www.torproject.org/torbutton/releases/torbutton-1.3.2-alpha.xpi</em:updateLink>
- <em:updateHash>sha1:4231cf0e568fe61f49011d4626e85cdb467c6a48</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.3.3-alpha">
- <em:version>1.3.3-alpha</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>10000.0</em:maxVersion>
- <em:updateLink>https://www.torproject.org/dist/torbutton/torbutton-1.3.3-alpha.xpi</em:updateLink>
- <em:updateHash>sha1:c7323cd408ebee28ee23b6a91fe056d59de668f5</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.4.0">
- <em:version>1.4.0</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>10000.0</em:maxVersion>
- <em:updateLink>https://www.torproject.org/dist/torbutton/torbutton-1.4.0.xpi</em:updateLink>
- <em:updateHash>sha1:4df99e70b2991bb51ea70d0c217961174b24a98e</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.4.1">
- <em:version>1.4.1</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>10000.0</em:maxVersion>
- <em:updateLink>https://www.torproject.org/dist/torbutton/torbutton-1.4.1.xpi</em:updateLink>
- <em:updateHash>sha1:7f80cf8eea6d523fdb0bac94eefce52ebbb192be</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.4.2">
- <em:version>1.4.2</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>10000.0</em:maxVersion>
- <em:updateLink>https://www.torproject.org/dist/torbutton/torbutton-1.4.2.xpi</em:updateLink>
- <em:updateHash>sha1:a724c55165f81a86e2ec1d56026c9160964c5b87</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.4.3">
- <em:version>1.4.3</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>10000.0</em:maxVersion>
- <em:updateLink>https://www.torproject.org/dist/torbutton/torbutton-1.4.3.xpi</em:updateLink>
- <em:updateHash>sha1:e048d53b3e36c161ccfb75b09c6aece8b7f1e94f</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.4.4">
- <em:version>1.4.4</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>10000.0</em:maxVersion>
- <em:updateLink>https://www.torproject.org/dist/torbutton/torbutton-1.4.4.xpi</em:updateLink>
- <em:updateHash>sha1:3f352e7d8577fc576a9011d858a8b34f4fea4b09</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.4.4.1">
- <em:version>1.4.4.1</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>10000.0</em:maxVersion>
- <em:updateLink>https://www.torproject.org/dist/torbutton/torbutton-1.4.4.1.xpi</em:updateLink>
- <em:updateHash>sha1:95dc1e079da873aae9ca1beb7354fb8fdeaa7414</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.4.5">
- <em:version>1.4.5</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>10000.0</em:maxVersion>
- <em:updateLink>https://www.torproject.org/dist/torbutton/torbutton-1.4.5.xpi</em:updateLink>
- <em:updateHash>sha1:5f2e2d72343b2d4702ec24491a11babedd3650b9</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.4.5.1">
- <em:version>1.4.5.1</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>10000.0</em:maxVersion>
- <em:updateLink>https://www.torproject.org/dist/torbutton/torbutton-1.4.5.1.xpi</em:updateLink>
- <em:updateHash>sha1:0002e2d61613504e41d8b773c30ff6307b8286da</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.4.6">
- <em:version>1.4.6</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>10000.0</em:maxVersion>
- <em:updateLink>https://www.torproject.org/dist/torbutton/torbutton-1.4.6.xpi</em:updateLink>
- <em:updateHash>sha1:eedadda6e5aacb8dabe2118e6c14c4dd4441fed0</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.4.6.1">
- <em:version>1.4.6.1</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>10000.0</em:maxVersion>
- <em:updateLink>https://www.torproject.org/dist/torbutton/torbutton-1.4.6.1.xpi</em:updateLink>
- <em:updateHash>sha1:fb1df9ce40c5b1282e701f2a96694b0bfbdc2687</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.4.6.2">
- <em:version>1.4.6.2</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>10000.0</em:maxVersion>
- <em:updateLink>https://www.torproject.org/dist/torbutton/torbutton-1.4.6.2.xpi</em:updateLink>
- <em:updateHash>sha1:1182fa2dcb095ad8054a218c41bc0a849b5b30ed</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.4.6.3">
- <em:version>1.4.6.3</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>10000.0</em:maxVersion>
- <em:updateLink>https://www.torproject.org/dist/torbutton/torbutton-1.4.6.3.xpi</em:updateLink>
- <em:updateHash>sha1:968455a5b702b3cabb6c16499e531a5a8f4c5f21</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
-</RDF>
1
0
commit 9cf79bcf222cfb1ca47f2cd6f119ac1f19b2f54d
Author: Alex Catarineu <acat(a)torproject.org>
Date: Thu May 9 19:50:40 2019 +0200
Remove overlays from chrome.manifest
---
src/chrome.manifest | 12 ------------
1 file changed, 12 deletions(-)
diff --git a/src/chrome.manifest b/src/chrome.manifest
index f6a267d7..13bef661 100644
--- a/src/chrome.manifest
+++ b/src/chrome.manifest
@@ -1,22 +1,10 @@
content torbutton chrome/content/
-overlay chrome://browser/content/browser.xul chrome://torbutton/content/torbutton.xul
-overlay chrome://browser/content/preferences/connection.xul chrome://torbutton/content/pref-connection.xul
-overlay chrome://messenger/content/messenger.xul chrome://torbutton/content/torbutton_tb.xul
-overlay chrome://messenger/content/messengercompose/messengercompose.xul chrome://torbutton/content/torbutton_tb.xul
-overlay about:addons chrome://torbutton/content/torbutton-extensions.xul
-overlay chrome://mozapps/content/extensions/extensions.xul chrome://torbutton/content/torbutton-extensions.xul
resource torbutton ./
resource torbutton-assets resource://torbutton/chrome/skin/ contentaccessible=yes
# browser branding
override chrome://branding/locale/brand.dtd chrome://torbutton/locale/brand.dtd
override chrome://branding/locale/brand.properties chrome://torbutton/locale/brand.properties
-overlay chrome://browser/content/aboutDialog.xul chrome://torbutton/content/aboutDialog.xul
-
-# UI customization
-overlay chrome://browser/content/browser.xul chrome://torbutton/content/menu-items-overlay.xul
-overlay chrome://browser/content/browser.xul chrome://torbutton/content/menu-overlay.xul
-overlay chrome://browser/content/browser.xul chrome://torbutton/content/tor-circuit-display.xul
# Strings for the about:tbupdate page
override chrome://browser/locale/aboutTBUpdate.dtd chrome://torbutton/locale/aboutTBUpdate.dtd
1
0
commit ce346d069afa5f1a42dfa13eb8fce2a23cfbf679
Author: Alex Catarineu <acat(a)torproject.org>
Date: Mon May 13 18:31:58 2019 +0200
Remove ported overlays
---
chrome/content/aboutDialog.xul | 56 ---------------------------------
chrome/content/menu-items-overlay.xul | 31 ------------------
chrome/content/menu-overlay.xul | 29 -----------------
chrome/content/tor-circuit-display.xul | 34 --------------------
chrome/content/torbutton-extensions.xul | 28 -----------------
chrome/content/torbutton.xul | 46 ---------------------------
6 files changed, 224 deletions(-)
diff --git a/chrome/content/aboutDialog.xul b/chrome/content/aboutDialog.xul
deleted file mode 100644
index 5b89a811..00000000
--- a/chrome/content/aboutDialog.xul
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?> <!-- -*- Mode: HTML -*- -->
-<?xml-stylesheet href="chrome://torbutton/skin/aboutDialog.css" type="text/css"?>
-
-<!DOCTYPE window [
-<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
-%brandDTD;
-<!ENTITY % aboutDialogDTD SYSTEM "chrome://torbutton/locale/aboutDialog.dtd" >
-%aboutDialogDTD;
-]>
-
-<overlay id="main-overlay"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
- <vbox id="rightBox">
- <vbox id="detailsBox">
- <description class="text-blurb" id="projectDesc">
- &project.start;
- <label class="text-link"
- href="https://www.torproject.org/">
- &project.tpoLink;
- </label>&project.end;
- </description>
- <description class="text-blurb" id="helpDesc">
- &help.start;
- <label class="text-link"
- href="https://www.torproject.org/donate/donate.html.en">
- &help.donateLink;
- </label>
- &help.or;
- <label class="text-link"
- href="https://www.torproject.org/getinvolved/volunteer.html.en">
- &help.getInvolvedLink;
- </label>&help.end;
- </description>
- </vbox>
- </vbox>
-
- <vbox id="bottomBox">
- <hbox id="newBottom" pack="center" position="1">
- <label class="text-link bottom-link"
- href="https://www.torproject.org/docs/faq.html.en">
- &bottomLinks.questions;
- </label>
- <label class="text-link bottom-link"
- href="https://www.torproject.org/getinvolved/relays">
- &bottomLinks.grow;
- </label>
- <label class="text-link bottom-link"
- href="about:license">
- &bottomLinks.license;
- </label>
- </hbox>
- <description id="trademarkTor" insertafter="trademark">
- &tor.TrademarkStatement;
- </description>
- </vbox>
-</overlay>
diff --git a/chrome/content/menu-items-overlay.xul b/chrome/content/menu-items-overlay.xul
deleted file mode 100644
index b2e862b3..00000000
--- a/chrome/content/menu-items-overlay.xul
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?> <!-- -*- Mode: HTML -*- -->
-
-<!DOCTYPE overlay SYSTEM "chrome://torbutton/locale/torbutton.dtd">
-
-<overlay id="torbutton-menu-overlay"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
- <menuitem id="menu_newIdentity"
- accesskey="&torbutton.context_menu.new_identity_key;"
- key="torbutton-new-identity-key"
- label="&torbutton.context_menu.new_identity;"
- oncommand="torbutton_new_identity();"/>
- <menuitem id="menu_newCircuit"
- accesskey="&torbutton.context_menu.new_circuit_key;"
- key="torbutton-new-circuit-key"
- label="&torbutton.context_menu.new_circuit;"
- oncommand="torbutton_new_circuit();"/>
- <toolbarbutton id="appMenuNewIdentity"
- class="subviewbutton subviewbutton-iconic"
- key="torbutton-new-identity-key"
- label="&torbutton.context_menu.new_identity;"
- oncommand="torbutton_new_identity();"/>
- <toolbarbutton id="appMenuNewCircuit"
- class="subviewbutton subviewbutton-iconic"
- key="torbutton-new-circuit-key"
- label="&torbutton.context_menu.new_circuit;"
- oncommand="torbutton_new_circuit();"/>
- <toolbarbutton id="appMenu-private-window-button"
- hidden="true"/>
- <toolbarbutton id="appMenuRestoreLastSession"
- hidden="true"/>
-</overlay>
diff --git a/chrome/content/menu-overlay.xul b/chrome/content/menu-overlay.xul
deleted file mode 100644
index 1e812cce..00000000
--- a/chrome/content/menu-overlay.xul
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?> <!-- -*- Mode: HTML -*- -->
-
-<!DOCTYPE overlay SYSTEM "chrome://torbutton/locale/aboutTor.dtd">
-
-<overlay id="torbutton-menu-overlay"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
- <menupopup id="menu_HelpPopup">
- <!-- Bug 18905: Hide unused help menu items -->
- <menuitem id="menu_openHelp" removeelement="true"/>
- <menuitem id="menu_openTour" removeelement="true"/>
- <menuitem id="healthReport" removeelement="true"/>
- <menuitem id="feedbackPage" removeelement="true"/>
- <menuitem id="helpSafeMode" removeelement="true"/>
- <menuitem id="menu_HelpPopup_reportPhishingtoolmenu" removeelement="true"/>
- <menuitem id="menu_HelpPopup_reportPhishingErrortoolmenu" removeelement="true"/>
- <!-- dummy elements to avoid 'getElementById' errors -->
- <box id="feedbackPage"/>
- <box id="helpSafeMode"/>
- <box id="menu_HelpPopup_reportPhishingtoolmenu"/>
- <box id="menu_HelpPopup_reportPhishingErrortoolmenu"/>
- <!-- Add Tor Browser manual link -->
- <menuitem name="torBrowserUserManual"
- id="torBrowserUserManual"
- position="1"
- label="&aboutTor.torbrowser_user_manual.label;"
- accesskey="&aboutTor.torbrowser_user_manual.accesskey;"
- oncommand="gBrowser.selectedTab = gBrowser.addTab('https://tb-manual.torproject.org/' + Services.locale.getRequestedLocale())" />
- </menupopup>
-</overlay>
diff --git a/chrome/content/tor-circuit-display.xul b/chrome/content/tor-circuit-display.xul
deleted file mode 100644
index b4d4ac7b..00000000
--- a/chrome/content/tor-circuit-display.xul
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://torbutton/skin/tor-circuit-display.css" type="text/css"?>
-
-<!DOCTYPE overlay SYSTEM "chrome://torbutton/locale/torbutton.dtd">
-
-<overlay id="circuit-display-overlay"
- xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- xmlns:html="http://www.w3.org/1999/xhtml">
- <panelview id="identity-popup-mainView">
- <!-- Circuit display section -->
- <xul:hbox id="circuit-display-container"
- class="identity-popup-section"
- insertafter="identity-popup-security">
- <xul:vbox id="circuit-display-content" flex="1">
- <xul:label id="circuit-display-headline"
- class="identity-popup-headline"
- value="&torbutton.circuit_display.title;"/>
- <html:ul id="circuit-display-nodes" dir="auto">
- <li>example A</li>
- <li>example B</li>
- <li>example C</li>
- </html:ul>
- </xul:vbox>
- <xul:vbox id="circuit-reload-content" flex="1">
- <html:button id="circuit-reload-button"
- onclick="torbutton_new_circuit()">
- &torbutton.circuit_display.new_circuit;
- </html:button>
- <xul:hbox id="circuit-guard-note-container">
- </xul:hbox>
- </xul:vbox>
- </xul:hbox>
- </panelview>
-</overlay>
diff --git a/chrome/content/torbutton-extensions.xul b/chrome/content/torbutton-extensions.xul
deleted file mode 100644
index 060594df..00000000
--- a/chrome/content/torbutton-extensions.xul
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0"?>
-
-<!DOCTYPE overlay SYSTEM "chrome://torbutton/locale/brand.dtd">
-
-<overlay id="torbutton-extensions-overlay"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
- <vbox id="plugin-enable-button" class="alert-container" flex="1"
- hidden="true">
- <spacer class="alert-spacer-before"/>
- <vbox class="alert">
- <label value="&plugins.installed.find;"/>
- <button class="button-plugin-enable"
- label="&plugins.installed.enable;"
- command="cmd_pluginEnable"/>
- </vbox>
- <spacer class="alert-spacer-after"/>
- </vbox>
-
- <vbox id="plugin-disable-button" class="global-info" flex="1" align="end">
- <button class="button-plugin-disable"
- label="&plugins.installed.disable;"
- tooltiptext="&plugins.installed.disable.tip;"
- command="cmd_pluginDisable"/>
- <spacer flex="5000"/>
- </vbox>
-
-</overlay>
diff --git a/chrome/content/torbutton.xul b/chrome/content/torbutton.xul
deleted file mode 100644
index 2f6e72e4..00000000
--- a/chrome/content/torbutton.xul
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://torbutton/skin/torbutton.css" type="text/css"?>
-<?xul-overlay href="chrome://torbutton/content/popup.xul"?>
-
-<!DOCTYPE overlay SYSTEM "chrome://torbutton/locale/torbutton.dtd">
-
-<overlay id="torbutton-overlay"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
- <script type="application/x-javascript" src="chrome://torbutton/content/torbutton_util.js" />
- <script type="application/x-javascript" src="chrome://torbutton/content/tor-circuit-display.js" />
- <script type="application/x-javascript" src="chrome://torbutton/content/content-sizer.js" />
- <script type="application/x-javascript" src="chrome://torbutton/content/torbutton.js" />
- <script language="JavaScript">
- //onLoad Hander
- try{window.addEventListener("load", torbutton_init, false);}catch(e){}
- </script>
-
- <stringbundleset id="torbutton-stringbundleset">
- <stringbundle id="torbutton-bundle" src="chrome://torbutton/locale/torbutton.properties"/>
- </stringbundleset>
-
- <!-- Place the context menu in the nav bar, so that the lack
- of the status bar on FF4 doesn't make it invisible -->
- <toolbar id="nav-bar">
- <menupopup id="torbutton-context-menu"/>
- </toolbar>
-
- <toolbarpalette id="BrowserToolbarPalette">
- <toolbarbutton
- id="torbutton-button"
- class="toolbarbutton-1 chromeclass-toolbar-additional"
- type="menu"
- orient="horizontal"
- label="Torbutton"
- tooltiptext="&torbutton.button.tooltip;"
- menu="torbutton-context-menu"
- context="torbutton-context-menu"/>
- </toolbarpalette>
-
-<!-- Global keyboard shortcuts for new identity and new circuit. -->
- <keyset>
- <key id="torbutton-new-identity-key" modifiers="accel shift" key="U" oncommand="torbutton_new_identity()"/>
- <key id="torbutton-new-circuit-key" modifiers="accel shift" key="L" oncommand="torbutton_new_circuit()"/>
- </keyset>
-</overlay>
1
0
commit 4dd346e2b81527785d7f8b68a5cff14972dd645c
Author: Alex Catarineu <acat(a)torproject.org>
Date: Mon May 13 18:35:51 2019 +0200
Remove ported overlays from jar.mn
---
jar.mn | 13 -------------
1 file changed, 13 deletions(-)
diff --git a/jar.mn b/jar.mn
index 68fdb9ec..cfbe1476 100644
--- a/jar.mn
+++ b/jar.mn
@@ -10,24 +10,12 @@ torbutton.jar:
modules/ (modules/*)
skin/ (chrome/skin/*)
-% overlay chrome://browser/content/browser.xul chrome://torbutton/content/torbutton.xul
-% overlay chrome://browser/content/preferences/connection.xul chrome://torbutton/content/pref-connection.xul
-% overlay chrome://messenger/content/messenger.xul chrome://torbutton/content/torbutton_tb.xul
-% overlay chrome://messenger/content/messengercompose/messengercompose.xul chrome://torbutton/content/torbutton_tb.xul
-% overlay about:addons chrome://torbutton/content/torbutton-extensions.xul
-% overlay chrome://mozapps/content/extensions/extensions.xul chrome://torbutton/content/torbutton-extensions.xul
% resource torbutton %
% resource torbutton-assets resource://torbutton/skin/ contentaccessible=yes
# browser branding
% override chrome://branding/locale/brand.dtd chrome://torbutton/locale/brand.dtd
% override chrome://branding/locale/brand.properties chrome://torbutton/locale/brand.properties
-% overlay chrome://browser/content/aboutDialog.xul chrome://torbutton/content/aboutDialog.xul
-
-# UI customization
-% overlay chrome://browser/content/browser.xul chrome://torbutton/content/menu-items-overlay.xul
-% overlay chrome://browser/content/browser.xul chrome://torbutton/content/menu-overlay.xul
-% overlay chrome://browser/content/browser.xul chrome://torbutton/content/tor-circuit-display.xul
# Strings for the about:tbupdate page
% override chrome://browser/locale/aboutTBUpdate.dtd chrome://torbutton/locale/aboutTBUpdate.dtd
@@ -94,7 +82,6 @@ torbutton.jar:
locale/zh-TW/ (chrome/locale/zh-TW/*)
% skin torbutton classic/1.0 %skin/
-% style chrome://global/content/customizeToolbar.xul chrome://torbutton/skin/torbutton.css
# Firefox 4-style component registration
% component {f605ec27-d867-44b5-ad97-2a29276642c3} %components/dragDropFilter.js
1
0
commit 5b13748cdf2af2db9e829cf76e52287fb2eb2445
Author: Alex Catarineu <acat(a)torproject.org>
Date: Tue May 28 15:15:36 2019 +0200
Remove aboutTor component
---
components/aboutTor.js | 53 ------------------------------------------
components/startup-observer.js | 7 ------
2 files changed, 60 deletions(-)
diff --git a/components/aboutTor.js b/components/aboutTor.js
deleted file mode 100644
index ec48d668..00000000
--- a/components/aboutTor.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/*************************************************************************
- * Copyright (c) 2017, The Tor Project, Inc.
- * See LICENSE for licensing information.
- *
- * vim: set sw=2 sts=2 ts=8 et syntax=javascript:
- *
- * about:tor component
- *************************************************************************/
-
-// Module specific constants
-const kMODULE_NAME = "about:tor";
-const kMODULE_CONTRACTID = "@mozilla.org/network/protocol/about;1?what=tor";
-const kMODULE_CID = Components.ID("84d47da6-79c3-4661-aa9f-8049476f7bf5");
-
-const kAboutTorURL = "chrome://torbutton/content/aboutTor/aboutTor.xhtml";
-
-const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
-
-function AboutTor() {}
-
-
-AboutTor.prototype =
-{
- QueryInterface: ChromeUtils.generateQI([Ci.nsIAboutModule]),
-
- // nsIClassInfo implementation:
- classDescription: kMODULE_NAME,
- classID: kMODULE_CID,
- contractID: kMODULE_CONTRACTID,
-
- // nsIAboutModule implementation:
- newChannel(aURI, aLoadInfo) {
- let ioSvc = Services.io;
- let uri = ioSvc.newURI(kAboutTorURL);
- let channel = ioSvc.newChannelFromURIWithLoadInfo(uri, aLoadInfo);
- channel.originalURI = aURI;
-
- return channel;
- },
-
- getURIFlags: function(aURI)
- {
- return Ci.nsIAboutModule.URI_SAFE_FOR_UNTRUSTED_CONTENT |
- Ci.nsIAboutModule.URI_MUST_LOAD_IN_CHILD |
- Ci.nsIAboutModule.ALLOW_SCRIPT;
- }
-};
-
-
-let factory = XPCOMUtils._getFactory(AboutTor);
-let reg = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
-reg.registerFactory(kMODULE_CID, "", kMODULE_CONTRACTID, factory);
diff --git a/components/startup-observer.js b/components/startup-observer.js
index 2d20a8ad..eea9e8db 100644
--- a/components/startup-observer.js
+++ b/components/startup-observer.js
@@ -62,13 +62,6 @@ function StartupObserver() {
} catch(e) {
this.logger.log(4, "Early proxy change failed. Will try again at profile load. Error: "+e);
}
-
- // Arrange for our about:tor handler to be loaded in the default (chrome)
- // process as well as in each content process.
- let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
- .getService(Ci.nsIProcessScriptLoader);
- ppmm.loadProcessScript("resource://torbutton/components/aboutTor.js",
- true);
}
StartupObserver.prototype = {
1
0

07 Aug '19
commit 45b990730502ac878e39ba9bbd86347b4e8e533e
Author: Alex Catarineu <acat(a)torproject.org>
Date: Fri Aug 2 12:01:50 2019 +0200
Remove nsISupports from ChromeUtils.generateQI
This was causing an assert on debug builds of the browser.
---
components/domain-isolator.js | 2 +-
components/dragDropFilter.js | 2 +-
components/external-app-blocker.js | 2 +-
components/torCheckService.js | 2 +-
components/torbutton-logger.js | 2 +-
5 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/components/domain-isolator.js b/components/domain-isolator.js
index e04005a5..891a19cc 100644
--- a/components/domain-isolator.js
+++ b/components/domain-isolator.js
@@ -173,7 +173,7 @@ function DomainIsolator() {
// Firefox component requirements
DomainIsolator.prototype = {
- QueryInterface: ChromeUtils.generateQI([Ci.nsISupports, Ci.nsIObserver]),
+ QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
classDescription: kMODULE_NAME,
classID: kMODULE_CID,
contractID: kMODULE_CONTRACTID,
diff --git a/components/dragDropFilter.js b/components/dragDropFilter.js
index 4465187e..66dbe3a4 100644
--- a/components/dragDropFilter.js
+++ b/components/dragDropFilter.js
@@ -32,7 +32,7 @@ function DragDropFilter() {
DragDropFilter.prototype =
{
- QueryInterface: ChromeUtils.generateQI([Ci.nsISupports, Ci.nsIObserver]),
+ QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
// make this an nsIClassInfo object
flags: Ci.nsIClassInfo.DOM_OBJECT,
diff --git a/components/external-app-blocker.js b/components/external-app-blocker.js
index 747824d1..1cc2000f 100644
--- a/components/external-app-blocker.js
+++ b/components/external-app-blocker.js
@@ -33,7 +33,7 @@ ExternalAppBlocker.prototype =
{
_helperAppLauncher: undefined,
- QueryInterface: ChromeUtils.generateQI([Ci.nsISupports, Ci.nsIObserver,
+ QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver,
Ci.nsIHelperAppWarningDialog]),
// make this an nsIClassInfo object
diff --git a/components/torCheckService.js b/components/torCheckService.js
index 4f79bef4..d4815ee2 100644
--- a/components/torCheckService.js
+++ b/components/torCheckService.js
@@ -25,7 +25,7 @@ function TBTorCheckService() {
TBTorCheckService.prototype =
{
- QueryInterface: ChromeUtils.generateQI([Ci.nsISupports, Ci.nsIClassInfo]),
+ QueryInterface: ChromeUtils.generateQI([Ci.nsIClassInfo]),
kCheckNotInitiated: 0, // Possible values for statusOfTorCheck.
kCheckSuccessful: 1,
diff --git a/components/torbutton-logger.js b/components/torbutton-logger.js
index ce4ba70b..22c664fa 100644
--- a/components/torbutton-logger.js
+++ b/components/torbutton-logger.js
@@ -58,7 +58,7 @@ function padInt(i)
TorbuttonLogger.prototype =
{
- QueryInterface: ChromeUtils.generateQI([Ci.nsISupports, Ci.nsIClassInfo]),
+ QueryInterface: ChromeUtils.generateQI([Ci.nsIClassInfo]),
wrappedJSObject: null, // Initialized by constructor
1
0

07 Aug '19
commit 8c5a555b50274aabf0498a2da39696e4cde77cf7
Merge: cbf7172b 45b99073
Author: Georg Koppen <gk(a)torproject.org>
Date: Wed Aug 7 19:15:41 2019 +0000
Merge remote-tracking branch 'acat/10760+1'
.gitignore | 1 -
src/CREDITS => CREDITS | 0
README | 23 -
README.BUILD | 19 -
README.RELEASE | 107 -
src/chrome.manifest => chrome.manifest | 12 -
.../content/aboutTor/aboutTor-content.js | 0
.../content/aboutTor/aboutTor.xhtml | 0
.../content/locale/non-localized.properties | 0
.../content/preferences-mobile.js | 10 +-
{src/chrome => chrome}/content/preferences.xhtml | 0
.../content/tor-circuit-display.js | 18 +-
{src/chrome => chrome}/content/torbutton.js | 230 +-
{src/chrome => chrome}/content/torbutton_util.js | 14 +-
{src/chrome => chrome}/locale/af/aboutTor.dtd | 0
{src/chrome => chrome}/locale/af/brand.dtd | 0
{src/chrome => chrome}/locale/af/brand.properties | 0
{src/chrome => chrome}/locale/af/torbutton.dtd | 0
.../locale/af/torbutton.properties | 0
{src/chrome => chrome}/locale/ak/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ak/brand.dtd | 0
{src/chrome => chrome}/locale/ak/brand.properties | 0
{src/chrome => chrome}/locale/ak/torbutton.dtd | 0
.../locale/ak/torbutton.properties | 0
{src/chrome => chrome}/locale/am/aboutTor.dtd | 0
{src/chrome => chrome}/locale/am/brand.dtd | 0
{src/chrome => chrome}/locale/am/brand.properties | 0
{src/chrome => chrome}/locale/am/torbutton.dtd | 0
.../locale/am/torbutton.properties | 0
{src/chrome => chrome}/locale/ar/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/ar/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/ar/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ar/brand.dtd | 0
{src/chrome => chrome}/locale/ar/brand.properties | 0
.../locale/ar/browserOnboarding.properties | 0
.../locale/ar/securityLevel.properties | 0
{src/chrome => chrome}/locale/ar/torbutton.dtd | 0
.../locale/ar/torbutton.properties | 0
{src/chrome => chrome}/locale/arn/aboutTor.dtd | 0
{src/chrome => chrome}/locale/arn/brand.dtd | 0
{src/chrome => chrome}/locale/arn/brand.properties | 0
{src/chrome => chrome}/locale/arn/torbutton.dtd | 0
.../locale/arn/torbutton.properties | 0
{src/chrome => chrome}/locale/ast/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ast/brand.dtd | 0
{src/chrome => chrome}/locale/ast/brand.properties | 0
{src/chrome => chrome}/locale/ast/torbutton.dtd | 0
.../locale/ast/torbutton.properties | 0
{src/chrome => chrome}/locale/az/aboutTor.dtd | 0
{src/chrome => chrome}/locale/az/brand.dtd | 0
{src/chrome => chrome}/locale/az/brand.properties | 0
.../locale/az/securityLevel.properties | 0
{src/chrome => chrome}/locale/az/torbutton.dtd | 0
.../locale/az/torbutton.properties | 0
{src/chrome => chrome}/locale/be/aboutTor.dtd | 0
{src/chrome => chrome}/locale/be/brand.dtd | 0
{src/chrome => chrome}/locale/be/brand.properties | 0
{src/chrome => chrome}/locale/be/torbutton.dtd | 0
.../locale/be/torbutton.properties | 0
{src/chrome => chrome}/locale/bg/aboutTor.dtd | 0
{src/chrome => chrome}/locale/bg/brand.dtd | 0
{src/chrome => chrome}/locale/bg/brand.properties | 0
.../locale/bg/securityLevel.properties | 0
{src/chrome => chrome}/locale/bg/torbutton.dtd | 0
.../locale/bg/torbutton.properties | 0
{src/chrome => chrome}/locale/bms/aboutTor.dtd | 0
.../locale/bms/securityLevel.properties | 0
{src/chrome => chrome}/locale/bms/torbutton.dtd | 0
.../locale/bms/torbutton.properties | 0
.../chrome => chrome}/locale/bn-BD/aboutDialog.dtd | 0
.../locale/bn-BD/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/bn-BD/aboutTor.dtd | 0
{src/chrome => chrome}/locale/bn-BD/brand.dtd | 0
.../locale/bn-BD/brand.properties | 0
.../locale/bn-BD/browserOnboarding.properties | 0
.../locale/bn-BD/securityLevel.properties | 0
{src/chrome => chrome}/locale/bn-BD/torbutton.dtd | 0
.../locale/bn-BD/torbutton.properties | 0
{src/chrome => chrome}/locale/bn-IN/aboutTor.dtd | 0
{src/chrome => chrome}/locale/bn-IN/brand.dtd | 0
.../locale/bn-IN/brand.properties | 0
{src/chrome => chrome}/locale/bn-IN/torbutton.dtd | 0
.../locale/bn-IN/torbutton.properties | 0
{src/chrome => chrome}/locale/bn/aboutTor.dtd | 0
{src/chrome => chrome}/locale/bn/brand.dtd | 0
{src/chrome => chrome}/locale/bn/brand.properties | 0
{src/chrome => chrome}/locale/bn/torbutton.dtd | 0
.../locale/bn/torbutton.properties | 0
{src/chrome => chrome}/locale/bo/aboutTor.dtd | 0
{src/chrome => chrome}/locale/bo/brand.dtd | 0
{src/chrome => chrome}/locale/bo/brand.properties | 0
{src/chrome => chrome}/locale/bo/torbutton.dtd | 0
.../locale/bo/torbutton.properties | 0
{src/chrome => chrome}/locale/br/aboutTor.dtd | 0
{src/chrome => chrome}/locale/br/brand.dtd | 0
{src/chrome => chrome}/locale/br/brand.properties | 0
{src/chrome => chrome}/locale/br/torbutton.dtd | 0
.../locale/br/torbutton.properties | 0
{src/chrome => chrome}/locale/bs/aboutTor.dtd | 0
{src/chrome => chrome}/locale/bs/brand.dtd | 0
{src/chrome => chrome}/locale/bs/brand.properties | 0
.../locale/bs/securityLevel.properties | 0
{src/chrome => chrome}/locale/bs/torbutton.dtd | 0
.../locale/bs/torbutton.properties | 0
{src/chrome => chrome}/locale/ca/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/ca/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/ca/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ca/brand.dtd | 0
{src/chrome => chrome}/locale/ca/brand.properties | 0
.../locale/ca/browserOnboarding.properties | 0
.../locale/ca/securityLevel.properties | 0
{src/chrome => chrome}/locale/ca/torbutton.dtd | 0
.../locale/ca/torbutton.properties | 0
{src/chrome => chrome}/locale/cs/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/cs/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/cs/aboutTor.dtd | 0
{src/chrome => chrome}/locale/cs/brand.dtd | 0
{src/chrome => chrome}/locale/cs/brand.properties | 0
.../locale/cs/browserOnboarding.properties | 0
.../locale/cs/securityLevel.properties | 0
{src/chrome => chrome}/locale/cs/torbutton.dtd | 0
.../locale/cs/torbutton.properties | 0
{src/chrome => chrome}/locale/csb/aboutTor.dtd | 0
{src/chrome => chrome}/locale/csb/brand.dtd | 0
{src/chrome => chrome}/locale/csb/brand.properties | 0
{src/chrome => chrome}/locale/csb/torbutton.dtd | 0
.../locale/csb/torbutton.properties | 0
{src/chrome => chrome}/locale/cy/aboutTor.dtd | 0
{src/chrome => chrome}/locale/cy/brand.dtd | 0
{src/chrome => chrome}/locale/cy/brand.properties | 0
{src/chrome => chrome}/locale/cy/torbutton.dtd | 0
.../locale/cy/torbutton.properties | 0
{src/chrome => chrome}/locale/da/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/da/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/da/aboutTor.dtd | 0
{src/chrome => chrome}/locale/da/brand.dtd | 0
{src/chrome => chrome}/locale/da/brand.properties | 0
.../locale/da/browserOnboarding.properties | 0
.../locale/da/securityLevel.properties | 0
{src/chrome => chrome}/locale/da/torbutton.dtd | 0
.../locale/da/torbutton.properties | 0
{src/chrome => chrome}/locale/de/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/de/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/de/aboutTor.dtd | 0
{src/chrome => chrome}/locale/de/brand.dtd | 0
{src/chrome => chrome}/locale/de/brand.properties | 0
.../locale/de/browserOnboarding.properties | 0
.../locale/de/securityLevel.properties | 0
{src/chrome => chrome}/locale/de/torbutton.dtd | 0
.../locale/de/torbutton.properties | 0
{src/chrome => chrome}/locale/dz/aboutTor.dtd | 0
{src/chrome => chrome}/locale/dz/brand.dtd | 0
{src/chrome => chrome}/locale/dz/brand.properties | 0
{src/chrome => chrome}/locale/dz/torbutton.dtd | 0
.../locale/dz/torbutton.properties | 0
{src/chrome => chrome}/locale/el/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/el/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/el/aboutTor.dtd | 0
{src/chrome => chrome}/locale/el/brand.dtd | 0
{src/chrome => chrome}/locale/el/brand.properties | 0
.../locale/el/browserOnboarding.properties | 0
.../locale/el/securityLevel.properties | 0
{src/chrome => chrome}/locale/el/torbutton.dtd | 0
.../locale/el/torbutton.properties | 0
.../chrome => chrome}/locale/en-US/aboutDialog.dtd | 0
.../locale/en-US/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/en-US/aboutTor.dtd | 0
{src/chrome => chrome}/locale/en-US/brand.dtd | 0
.../locale/en-US/brand.properties | 0
.../locale/en-US/browserOnboarding.properties | 0
.../locale/en-US/securityLevel.properties | 0
{src/chrome => chrome}/locale/en-US/torbutton.dtd | 0
.../locale/en-US/torbutton.properties | 0
{src/chrome => chrome}/locale/eo/aboutTor.dtd | 0
{src/chrome => chrome}/locale/eo/brand.dtd | 0
{src/chrome => chrome}/locale/eo/brand.properties | 0
.../locale/eo/securityLevel.properties | 0
{src/chrome => chrome}/locale/eo/torbutton.dtd | 0
.../locale/eo/torbutton.properties | 0
.../chrome => chrome}/locale/es-AR/aboutDialog.dtd | 0
.../locale/es-AR/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/es-AR/aboutTor.dtd | 0
{src/chrome => chrome}/locale/es-AR/brand.dtd | 0
.../locale/es-AR/brand.properties | 0
.../locale/es-AR/browserOnboarding.properties | 0
.../locale/es-AR/securityLevel.properties | 0
{src/chrome => chrome}/locale/es-AR/torbutton.dtd | 0
.../locale/es-AR/torbutton.properties | 0
.../chrome => chrome}/locale/es-ES/aboutDialog.dtd | 0
.../locale/es-ES/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/es-ES/aboutTor.dtd | 0
{src/chrome => chrome}/locale/es-ES/brand.dtd | 0
.../locale/es-ES/brand.properties | 0
.../locale/es-ES/browserOnboarding.properties | 0
.../locale/es-ES/securityLevel.properties | 0
{src/chrome => chrome}/locale/es-ES/torbutton.dtd | 0
.../locale/es-ES/torbutton.properties | 0
{src/chrome => chrome}/locale/et/aboutTor.dtd | 0
{src/chrome => chrome}/locale/et/brand.dtd | 0
{src/chrome => chrome}/locale/et/brand.properties | 0
{src/chrome => chrome}/locale/et/torbutton.dtd | 0
.../locale/et/torbutton.properties | 0
{src/chrome => chrome}/locale/eu/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/eu/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/eu/aboutTor.dtd | 0
{src/chrome => chrome}/locale/eu/brand.dtd | 0
{src/chrome => chrome}/locale/eu/brand.properties | 0
.../locale/eu/browserOnboarding.properties | 0
.../locale/eu/securityLevel.properties | 0
{src/chrome => chrome}/locale/eu/torbutton.dtd | 0
.../locale/eu/torbutton.properties | 0
{src/chrome => chrome}/locale/fa/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/fa/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/fa/aboutTor.dtd | 0
{src/chrome => chrome}/locale/fa/brand.dtd | 0
{src/chrome => chrome}/locale/fa/brand.properties | 0
.../locale/fa/browserOnboarding.properties | 0
.../locale/fa/securityLevel.properties | 0
{src/chrome => chrome}/locale/fa/torbutton.dtd | 0
.../locale/fa/torbutton.properties | 0
{src/chrome => chrome}/locale/fi/aboutTor.dtd | 0
{src/chrome => chrome}/locale/fi/brand.dtd | 0
{src/chrome => chrome}/locale/fi/brand.properties | 0
.../locale/fi/securityLevel.properties | 0
{src/chrome => chrome}/locale/fi/torbutton.dtd | 0
.../locale/fi/torbutton.properties | 0
{src/chrome => chrome}/locale/fil/aboutTor.dtd | 0
{src/chrome => chrome}/locale/fil/brand.dtd | 0
{src/chrome => chrome}/locale/fil/brand.properties | 0
{src/chrome => chrome}/locale/fil/torbutton.dtd | 0
.../locale/fil/torbutton.properties | 0
{src/chrome => chrome}/locale/fo/aboutTor.dtd | 0
{src/chrome => chrome}/locale/fo/brand.dtd | 0
{src/chrome => chrome}/locale/fo/brand.properties | 0
{src/chrome => chrome}/locale/fo/torbutton.dtd | 0
.../locale/fo/torbutton.properties | 0
{src/chrome => chrome}/locale/fr/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/fr/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/fr/aboutTor.dtd | 0
{src/chrome => chrome}/locale/fr/brand.dtd | 0
{src/chrome => chrome}/locale/fr/brand.properties | 0
.../locale/fr/browserOnboarding.properties | 0
.../locale/fr/securityLevel.properties | 0
{src/chrome => chrome}/locale/fr/torbutton.dtd | 0
.../locale/fr/torbutton.properties | 0
{src/chrome => chrome}/locale/fur/aboutTor.dtd | 0
{src/chrome => chrome}/locale/fur/brand.dtd | 0
{src/chrome => chrome}/locale/fur/brand.properties | 0
{src/chrome => chrome}/locale/fur/torbutton.dtd | 0
.../locale/fur/torbutton.properties | 0
{src/chrome => chrome}/locale/fy/aboutTor.dtd | 0
{src/chrome => chrome}/locale/fy/brand.dtd | 0
{src/chrome => chrome}/locale/fy/brand.properties | 0
{src/chrome => chrome}/locale/fy/torbutton.dtd | 0
.../locale/fy/torbutton.properties | 0
.../chrome => chrome}/locale/ga-IE/aboutDialog.dtd | 0
.../locale/ga-IE/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/ga-IE/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ga-IE/brand.dtd | 0
.../locale/ga-IE/brand.properties | 0
.../locale/ga-IE/browserOnboarding.properties | 0
.../locale/ga-IE/securityLevel.properties | 0
{src/chrome => chrome}/locale/ga-IE/torbutton.dtd | 0
.../locale/ga-IE/torbutton.properties | 0
{src/chrome => chrome}/locale/gl/aboutTor.dtd | 0
{src/chrome => chrome}/locale/gl/brand.dtd | 0
{src/chrome => chrome}/locale/gl/brand.properties | 0
.../locale/gl/securityLevel.properties | 0
{src/chrome => chrome}/locale/gl/torbutton.dtd | 0
.../locale/gl/torbutton.properties | 0
{src/chrome => chrome}/locale/gu/aboutTor.dtd | 0
{src/chrome => chrome}/locale/gu/brand.dtd | 0
{src/chrome => chrome}/locale/gu/brand.properties | 0
.../locale/gu/securityLevel.properties | 0
{src/chrome => chrome}/locale/gu/torbutton.dtd | 0
.../locale/gu/torbutton.properties | 0
{src/chrome => chrome}/locale/gun/aboutTor.dtd | 0
{src/chrome => chrome}/locale/gun/brand.dtd | 0
{src/chrome => chrome}/locale/gun/brand.properties | 0
{src/chrome => chrome}/locale/gun/torbutton.dtd | 0
.../locale/gun/torbutton.properties | 0
{src/chrome => chrome}/locale/ha/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ha/brand.dtd | 0
{src/chrome => chrome}/locale/ha/brand.properties | 0
{src/chrome => chrome}/locale/ha/torbutton.dtd | 0
.../locale/ha/torbutton.properties | 0
{src/chrome => chrome}/locale/he/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/he/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/he/aboutTor.dtd | 0
{src/chrome => chrome}/locale/he/brand.dtd | 0
{src/chrome => chrome}/locale/he/brand.properties | 0
.../locale/he/browserOnboarding.properties | 0
.../locale/he/securityLevel.properties | 0
{src/chrome => chrome}/locale/he/torbutton.dtd | 0
.../locale/he/torbutton.properties | 0
{src/chrome => chrome}/locale/hi/aboutTor.dtd | 0
{src/chrome => chrome}/locale/hi/brand.dtd | 0
{src/chrome => chrome}/locale/hi/brand.properties | 0
{src/chrome => chrome}/locale/hi/torbutton.dtd | 0
.../locale/hi/torbutton.properties | 0
{src/chrome => chrome}/locale/hr/aboutTor.dtd | 0
{src/chrome => chrome}/locale/hr/brand.dtd | 0
{src/chrome => chrome}/locale/hr/brand.properties | 0
{src/chrome => chrome}/locale/hr/torbutton.dtd | 0
.../locale/hr/torbutton.properties | 0
{src/chrome => chrome}/locale/ht/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ht/brand.dtd | 0
{src/chrome => chrome}/locale/ht/brand.properties | 0
{src/chrome => chrome}/locale/ht/torbutton.dtd | 0
.../locale/ht/torbutton.properties | 0
{src/chrome => chrome}/locale/hu/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/hu/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/hu/aboutTor.dtd | 0
{src/chrome => chrome}/locale/hu/brand.dtd | 0
{src/chrome => chrome}/locale/hu/brand.properties | 0
.../locale/hu/browserOnboarding.properties | 0
.../locale/hu/securityLevel.properties | 0
{src/chrome => chrome}/locale/hu/torbutton.dtd | 0
.../locale/hu/torbutton.properties | 0
{src/chrome => chrome}/locale/hy/aboutTor.dtd | 0
{src/chrome => chrome}/locale/hy/brand.dtd | 0
{src/chrome => chrome}/locale/hy/brand.properties | 0
{src/chrome => chrome}/locale/hy/torbutton.dtd | 0
.../locale/hy/torbutton.properties | 0
{src/chrome => chrome}/locale/id/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/id/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/id/aboutTor.dtd | 0
{src/chrome => chrome}/locale/id/brand.dtd | 0
{src/chrome => chrome}/locale/id/brand.properties | 0
.../locale/id/browserOnboarding.properties | 0
.../locale/id/securityLevel.properties | 0
{src/chrome => chrome}/locale/id/torbutton.dtd | 0
.../locale/id/torbutton.properties | 0
{src/chrome => chrome}/locale/is/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/is/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/is/aboutTor.dtd | 0
{src/chrome => chrome}/locale/is/brand.dtd | 0
{src/chrome => chrome}/locale/is/brand.properties | 0
.../locale/is/browserOnboarding.properties | 0
.../locale/is/securityLevel.properties | 0
{src/chrome => chrome}/locale/is/torbutton.dtd | 0
.../locale/is/torbutton.properties | 0
{src/chrome => chrome}/locale/it/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/it/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/it/aboutTor.dtd | 0
{src/chrome => chrome}/locale/it/brand.dtd | 0
{src/chrome => chrome}/locale/it/brand.properties | 0
.../locale/it/browserOnboarding.properties | 0
.../locale/it/securityLevel.properties | 0
{src/chrome => chrome}/locale/it/torbutton.dtd | 0
.../locale/it/torbutton.properties | 0
{src/chrome => chrome}/locale/ja/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/ja/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/ja/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ja/brand.dtd | 0
{src/chrome => chrome}/locale/ja/brand.properties | 0
.../locale/ja/browserOnboarding.properties | 0
.../locale/ja/securityLevel.properties | 0
{src/chrome => chrome}/locale/ja/torbutton.dtd | 0
.../locale/ja/torbutton.properties | 0
{src/chrome => chrome}/locale/jv/aboutTor.dtd | 0
{src/chrome => chrome}/locale/jv/brand.dtd | 0
{src/chrome => chrome}/locale/jv/brand.properties | 0
{src/chrome => chrome}/locale/jv/torbutton.dtd | 0
.../locale/jv/torbutton.properties | 0
{src/chrome => chrome}/locale/ka/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/ka/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/ka/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ka/brand.dtd | 0
{src/chrome => chrome}/locale/ka/brand.properties | 0
.../locale/ka/browserOnboarding.properties | 0
.../locale/ka/securityLevel.properties | 0
{src/chrome => chrome}/locale/ka/torbutton.dtd | 0
.../locale/ka/torbutton.properties | 0
{src/chrome => chrome}/locale/km/aboutTor.dtd | 0
{src/chrome => chrome}/locale/km/brand.dtd | 0
{src/chrome => chrome}/locale/km/brand.properties | 0
{src/chrome => chrome}/locale/km/torbutton.dtd | 0
.../locale/km/torbutton.properties | 0
{src/chrome => chrome}/locale/kn/aboutTor.dtd | 0
{src/chrome => chrome}/locale/kn/brand.dtd | 0
{src/chrome => chrome}/locale/kn/brand.properties | 0
{src/chrome => chrome}/locale/kn/torbutton.dtd | 0
.../locale/kn/torbutton.properties | 0
{src/chrome => chrome}/locale/ko/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/ko/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/ko/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ko/brand.dtd | 0
{src/chrome => chrome}/locale/ko/brand.properties | 0
.../locale/ko/browserOnboarding.properties | 0
.../locale/ko/securityLevel.properties | 0
{src/chrome => chrome}/locale/ko/torbutton.dtd | 0
.../locale/ko/torbutton.properties | 0
{src/chrome => chrome}/locale/ku/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ku/brand.dtd | 0
{src/chrome => chrome}/locale/ku/brand.properties | 0
{src/chrome => chrome}/locale/ku/torbutton.dtd | 0
.../locale/ku/torbutton.properties | 0
{src/chrome => chrome}/locale/kw/aboutTor.dtd | 0
{src/chrome => chrome}/locale/kw/brand.dtd | 0
{src/chrome => chrome}/locale/kw/brand.properties | 0
{src/chrome => chrome}/locale/kw/torbutton.dtd | 0
.../locale/kw/torbutton.properties | 0
{src/chrome => chrome}/locale/ky/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ky/brand.dtd | 0
{src/chrome => chrome}/locale/ky/brand.properties | 0
{src/chrome => chrome}/locale/ky/torbutton.dtd | 0
.../locale/ky/torbutton.properties | 0
{src/chrome => chrome}/locale/lb/aboutTor.dtd | 0
{src/chrome => chrome}/locale/lb/brand.dtd | 0
{src/chrome => chrome}/locale/lb/brand.properties | 0
{src/chrome => chrome}/locale/lb/torbutton.dtd | 0
.../locale/lb/torbutton.properties | 0
{src/chrome => chrome}/locale/lg/aboutTor.dtd | 0
{src/chrome => chrome}/locale/lg/torbutton.dtd | 0
.../locale/lg/torbutton.properties | 0
{src/chrome => chrome}/locale/ln/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ln/brand.dtd | 0
{src/chrome => chrome}/locale/ln/brand.properties | 0
{src/chrome => chrome}/locale/ln/torbutton.dtd | 0
.../locale/ln/torbutton.properties | 0
{src/chrome => chrome}/locale/lo/aboutTor.dtd | 0
{src/chrome => chrome}/locale/lo/brand.dtd | 0
{src/chrome => chrome}/locale/lo/brand.properties | 0
{src/chrome => chrome}/locale/lo/torbutton.dtd | 0
.../locale/lo/torbutton.properties | 0
{src/chrome => chrome}/locale/lt/aboutTor.dtd | 0
{src/chrome => chrome}/locale/lt/brand.dtd | 0
{src/chrome => chrome}/locale/lt/brand.properties | 0
.../locale/lt/securityLevel.properties | 0
{src/chrome => chrome}/locale/lt/torbutton.dtd | 0
.../locale/lt/torbutton.properties | 0
{src/chrome => chrome}/locale/lv/aboutTor.dtd | 0
{src/chrome => chrome}/locale/lv/brand.dtd | 0
{src/chrome => chrome}/locale/lv/brand.properties | 0
.../locale/lv/securityLevel.properties | 0
{src/chrome => chrome}/locale/lv/torbutton.dtd | 0
.../locale/lv/torbutton.properties | 0
{src/chrome => chrome}/locale/mg/aboutTor.dtd | 0
{src/chrome => chrome}/locale/mg/brand.dtd | 0
{src/chrome => chrome}/locale/mg/brand.properties | 0
{src/chrome => chrome}/locale/mg/torbutton.dtd | 0
.../locale/mg/torbutton.properties | 0
{src/chrome => chrome}/locale/mi/aboutTor.dtd | 0
{src/chrome => chrome}/locale/mi/brand.dtd | 0
{src/chrome => chrome}/locale/mi/brand.properties | 0
{src/chrome => chrome}/locale/mi/torbutton.dtd | 0
.../locale/mi/torbutton.properties | 0
{src/chrome => chrome}/locale/mk/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/mk/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/mk/aboutTor.dtd | 0
{src/chrome => chrome}/locale/mk/brand.dtd | 0
{src/chrome => chrome}/locale/mk/brand.properties | 0
.../locale/mk/browserOnboarding.properties | 0
.../locale/mk/securityLevel.properties | 0
{src/chrome => chrome}/locale/mk/torbutton.dtd | 0
.../locale/mk/torbutton.properties | 0
{src/chrome => chrome}/locale/ml/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ml/brand.dtd | 0
{src/chrome => chrome}/locale/ml/brand.properties | 0
{src/chrome => chrome}/locale/ml/torbutton.dtd | 0
.../locale/ml/torbutton.properties | 0
{src/chrome => chrome}/locale/mn/aboutTor.dtd | 0
{src/chrome => chrome}/locale/mn/brand.dtd | 0
{src/chrome => chrome}/locale/mn/brand.properties | 0
{src/chrome => chrome}/locale/mn/torbutton.dtd | 0
.../locale/mn/torbutton.properties | 0
{src/chrome => chrome}/locale/mr/aboutTor.dtd | 0
{src/chrome => chrome}/locale/mr/brand.dtd | 0
{src/chrome => chrome}/locale/mr/brand.properties | 0
{src/chrome => chrome}/locale/mr/torbutton.dtd | 0
.../locale/mr/torbutton.properties | 0
{src/chrome => chrome}/locale/ms/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ms/brand.dtd | 0
{src/chrome => chrome}/locale/ms/brand.properties | 0
{src/chrome => chrome}/locale/ms/torbutton.dtd | 0
.../locale/ms/torbutton.properties | 0
{src/chrome => chrome}/locale/mt/aboutTor.dtd | 0
{src/chrome => chrome}/locale/mt/brand.dtd | 0
{src/chrome => chrome}/locale/mt/brand.properties | 0
{src/chrome => chrome}/locale/mt/torbutton.dtd | 0
.../locale/mt/torbutton.properties | 0
{src/chrome => chrome}/locale/my/aboutTor.dtd | 0
{src/chrome => chrome}/locale/my/brand.dtd | 0
{src/chrome => chrome}/locale/my/brand.properties | 0
.../locale/my/securityLevel.properties | 0
{src/chrome => chrome}/locale/my/torbutton.dtd | 0
.../locale/my/torbutton.properties | 0
{src/chrome => chrome}/locale/nah/aboutTor.dtd | 0
{src/chrome => chrome}/locale/nah/brand.dtd | 0
{src/chrome => chrome}/locale/nah/brand.properties | 0
{src/chrome => chrome}/locale/nah/torbutton.dtd | 0
.../locale/nah/torbutton.properties | 0
{src/chrome => chrome}/locale/nap/aboutTor.dtd | 0
{src/chrome => chrome}/locale/nap/brand.dtd | 0
{src/chrome => chrome}/locale/nap/brand.properties | 0
{src/chrome => chrome}/locale/nap/torbutton.dtd | 0
.../locale/nap/torbutton.properties | 0
.../chrome => chrome}/locale/nb-NO/aboutDialog.dtd | 0
.../locale/nb-NO/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/nb-NO/aboutTor.dtd | 0
{src/chrome => chrome}/locale/nb-NO/brand.dtd | 0
.../locale/nb-NO/brand.properties | 0
.../locale/nb-NO/browserOnboarding.properties | 0
.../locale/nb-NO/securityLevel.properties | 0
{src/chrome => chrome}/locale/nb-NO/torbutton.dtd | 0
.../locale/nb-NO/torbutton.properties | 0
{src/chrome => chrome}/locale/ne/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ne/brand.dtd | 0
{src/chrome => chrome}/locale/ne/brand.properties | 0
{src/chrome => chrome}/locale/ne/torbutton.dtd | 0
.../locale/ne/torbutton.properties | 0
{src/chrome => chrome}/locale/nl/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/nl/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/nl/aboutTor.dtd | 0
{src/chrome => chrome}/locale/nl/brand.dtd | 0
{src/chrome => chrome}/locale/nl/brand.properties | 0
.../locale/nl/browserOnboarding.properties | 0
.../locale/nl/securityLevel.properties | 0
{src/chrome => chrome}/locale/nl/torbutton.dtd | 0
.../locale/nl/torbutton.properties | 0
{src/chrome => chrome}/locale/nn/aboutTor.dtd | 0
{src/chrome => chrome}/locale/nn/brand.dtd | 0
{src/chrome => chrome}/locale/nn/brand.properties | 0
{src/chrome => chrome}/locale/nn/torbutton.dtd | 0
.../locale/nn/torbutton.properties | 0
{src/chrome => chrome}/locale/nso/aboutTor.dtd | 0
{src/chrome => chrome}/locale/nso/brand.dtd | 0
{src/chrome => chrome}/locale/nso/brand.properties | 0
{src/chrome => chrome}/locale/nso/torbutton.dtd | 0
.../locale/nso/torbutton.properties | 0
{src/chrome => chrome}/locale/oc/aboutTor.dtd | 0
{src/chrome => chrome}/locale/oc/brand.dtd | 0
{src/chrome => chrome}/locale/oc/brand.properties | 0
{src/chrome => chrome}/locale/oc/torbutton.dtd | 0
.../locale/oc/torbutton.properties | 0
{src/chrome => chrome}/locale/or/aboutTor.dtd | 0
{src/chrome => chrome}/locale/or/brand.dtd | 0
{src/chrome => chrome}/locale/or/brand.properties | 0
{src/chrome => chrome}/locale/or/torbutton.dtd | 0
.../locale/or/torbutton.properties | 0
{src/chrome => chrome}/locale/pa/aboutTor.dtd | 0
{src/chrome => chrome}/locale/pa/brand.dtd | 0
{src/chrome => chrome}/locale/pa/brand.properties | 0
{src/chrome => chrome}/locale/pa/torbutton.dtd | 0
.../locale/pa/torbutton.properties | 0
{src/chrome => chrome}/locale/pap/aboutTor.dtd | 0
{src/chrome => chrome}/locale/pap/brand.dtd | 0
{src/chrome => chrome}/locale/pap/brand.properties | 0
{src/chrome => chrome}/locale/pap/torbutton.dtd | 0
.../locale/pap/torbutton.properties | 0
{src/chrome => chrome}/locale/pl/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/pl/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/pl/aboutTor.dtd | 0
{src/chrome => chrome}/locale/pl/brand.dtd | 0
{src/chrome => chrome}/locale/pl/brand.properties | 0
.../locale/pl/browserOnboarding.properties | 0
.../locale/pl/securityLevel.properties | 0
{src/chrome => chrome}/locale/pl/torbutton.dtd | 0
.../locale/pl/torbutton.properties | 0
{src/chrome => chrome}/locale/pms/aboutTor.dtd | 0
{src/chrome => chrome}/locale/pms/brand.dtd | 0
{src/chrome => chrome}/locale/pms/brand.properties | 0
{src/chrome => chrome}/locale/pms/torbutton.dtd | 0
.../locale/pms/torbutton.properties | 0
{src/chrome => chrome}/locale/ps/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ps/brand.dtd | 0
{src/chrome => chrome}/locale/ps/brand.properties | 0
{src/chrome => chrome}/locale/ps/torbutton.dtd | 0
.../locale/ps/torbutton.properties | 0
.../chrome => chrome}/locale/pt-BR/aboutDialog.dtd | 0
.../locale/pt-BR/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/pt-BR/aboutTor.dtd | 0
{src/chrome => chrome}/locale/pt-BR/brand.dtd | 0
.../locale/pt-BR/brand.properties | 0
.../locale/pt-BR/browserOnboarding.properties | 0
.../locale/pt-BR/securityLevel.properties | 0
{src/chrome => chrome}/locale/pt-BR/torbutton.dtd | 0
.../locale/pt-BR/torbutton.properties | 0
{src/chrome => chrome}/locale/pt/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/pt/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/pt/aboutTor.dtd | 0
{src/chrome => chrome}/locale/pt/brand.dtd | 0
{src/chrome => chrome}/locale/pt/brand.properties | 0
.../locale/pt/securityLevel.properties | 0
{src/chrome => chrome}/locale/pt/torbutton.dtd | 0
.../locale/pt/torbutton.properties | 0
{src/chrome => chrome}/locale/ro/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/ro/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/ro/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ro/brand.dtd | 0
{src/chrome => chrome}/locale/ro/brand.properties | 0
.../locale/ro/browserOnboarding.properties | 0
.../locale/ro/securityLevel.properties | 0
{src/chrome => chrome}/locale/ro/torbutton.dtd | 0
.../locale/ro/torbutton.properties | 0
{src/chrome => chrome}/locale/ru/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/ru/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/ru/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ru/brand.dtd | 0
{src/chrome => chrome}/locale/ru/brand.properties | 0
.../locale/ru/browserOnboarding.properties | 0
.../locale/ru/securityLevel.properties | 0
{src/chrome => chrome}/locale/ru/torbutton.dtd | 0
.../locale/ru/torbutton.properties | 0
{src/chrome => chrome}/locale/sco/aboutTor.dtd | 0
{src/chrome => chrome}/locale/sco/brand.dtd | 0
{src/chrome => chrome}/locale/sco/brand.properties | 0
{src/chrome => chrome}/locale/sco/torbutton.dtd | 0
.../locale/sco/torbutton.properties | 0
{src/chrome => chrome}/locale/sk/aboutTor.dtd | 0
{src/chrome => chrome}/locale/sk/brand.dtd | 0
{src/chrome => chrome}/locale/sk/brand.properties | 0
.../locale/sk/securityLevel.properties | 0
{src/chrome => chrome}/locale/sk/torbutton.dtd | 0
.../locale/sk/torbutton.properties | 0
{src/chrome => chrome}/locale/sl/aboutTor.dtd | 0
{src/chrome => chrome}/locale/sl/brand.dtd | 0
{src/chrome => chrome}/locale/sl/brand.properties | 0
.../locale/sl/securityLevel.properties | 0
{src/chrome => chrome}/locale/sl/torbutton.dtd | 0
.../locale/sl/torbutton.properties | 0
{src/chrome => chrome}/locale/so/aboutTor.dtd | 0
{src/chrome => chrome}/locale/so/brand.dtd | 0
{src/chrome => chrome}/locale/so/brand.properties | 0
{src/chrome => chrome}/locale/so/torbutton.dtd | 0
.../locale/so/torbutton.properties | 0
{src/chrome => chrome}/locale/son/aboutTor.dtd | 0
{src/chrome => chrome}/locale/son/brand.dtd | 0
{src/chrome => chrome}/locale/son/brand.properties | 0
{src/chrome => chrome}/locale/son/torbutton.dtd | 0
.../locale/son/torbutton.properties | 0
{src/chrome => chrome}/locale/sq/aboutTor.dtd | 0
{src/chrome => chrome}/locale/sq/brand.dtd | 0
{src/chrome => chrome}/locale/sq/brand.properties | 0
{src/chrome => chrome}/locale/sq/torbutton.dtd | 0
.../locale/sq/torbutton.properties | 0
{src/chrome => chrome}/locale/sr/aboutTor.dtd | 0
{src/chrome => chrome}/locale/sr/brand.dtd | 0
{src/chrome => chrome}/locale/sr/brand.properties | 0
.../locale/sr/securityLevel.properties | 0
{src/chrome => chrome}/locale/sr/torbutton.dtd | 0
.../locale/sr/torbutton.properties | 0
{src/chrome => chrome}/locale/st/aboutTor.dtd | 0
{src/chrome => chrome}/locale/st/brand.dtd | 0
{src/chrome => chrome}/locale/st/brand.properties | 0
{src/chrome => chrome}/locale/st/torbutton.dtd | 0
.../locale/st/torbutton.properties | 0
{src/chrome => chrome}/locale/su/aboutTor.dtd | 0
{src/chrome => chrome}/locale/su/brand.dtd | 0
{src/chrome => chrome}/locale/su/brand.properties | 0
{src/chrome => chrome}/locale/su/torbutton.dtd | 0
.../locale/su/torbutton.properties | 0
.../chrome => chrome}/locale/sv-SE/aboutDialog.dtd | 0
.../locale/sv-SE/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/sv-SE/aboutTor.dtd | 0
{src/chrome => chrome}/locale/sv-SE/brand.dtd | 0
.../locale/sv-SE/brand.properties | 0
.../locale/sv-SE/browserOnboarding.properties | 0
.../locale/sv-SE/securityLevel.properties | 0
{src/chrome => chrome}/locale/sv-SE/torbutton.dtd | 0
.../locale/sv-SE/torbutton.properties | 0
{src/chrome => chrome}/locale/sw/aboutTor.dtd | 0
{src/chrome => chrome}/locale/sw/brand.dtd | 0
{src/chrome => chrome}/locale/sw/brand.properties | 0
{src/chrome => chrome}/locale/sw/torbutton.dtd | 0
.../locale/sw/torbutton.properties | 0
{src/chrome => chrome}/locale/ta/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ta/brand.dtd | 0
{src/chrome => chrome}/locale/ta/brand.properties | 0
{src/chrome => chrome}/locale/ta/torbutton.dtd | 0
.../locale/ta/torbutton.properties | 0
{src/chrome => chrome}/locale/te/aboutTor.dtd | 0
{src/chrome => chrome}/locale/te/brand.dtd | 0
{src/chrome => chrome}/locale/te/brand.properties | 0
{src/chrome => chrome}/locale/te/torbutton.dtd | 0
.../locale/te/torbutton.properties | 0
{src/chrome => chrome}/locale/tg/aboutTor.dtd | 0
{src/chrome => chrome}/locale/tg/brand.dtd | 0
{src/chrome => chrome}/locale/tg/brand.properties | 0
{src/chrome => chrome}/locale/tg/torbutton.dtd | 0
.../locale/tg/torbutton.properties | 0
{src/chrome => chrome}/locale/th/aboutTor.dtd | 0
{src/chrome => chrome}/locale/th/brand.dtd | 0
{src/chrome => chrome}/locale/th/brand.properties | 0
{src/chrome => chrome}/locale/th/torbutton.dtd | 0
.../locale/th/torbutton.properties | 0
{src/chrome => chrome}/locale/ti/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ti/brand.dtd | 0
{src/chrome => chrome}/locale/ti/brand.properties | 0
{src/chrome => chrome}/locale/ti/torbutton.dtd | 0
.../locale/ti/torbutton.properties | 0
{src/chrome => chrome}/locale/tk/aboutTor.dtd | 0
{src/chrome => chrome}/locale/tk/brand.dtd | 0
{src/chrome => chrome}/locale/tk/brand.properties | 0
{src/chrome => chrome}/locale/tk/torbutton.dtd | 0
.../locale/tk/torbutton.properties | 0
{src/chrome => chrome}/locale/tr/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/tr/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/tr/aboutTor.dtd | 0
{src/chrome => chrome}/locale/tr/brand.dtd | 0
{src/chrome => chrome}/locale/tr/brand.properties | 0
.../locale/tr/browserOnboarding.properties | 0
.../locale/tr/securityLevel.properties | 0
{src/chrome => chrome}/locale/tr/torbutton.dtd | 0
.../locale/tr/torbutton.properties | 0
{src/chrome => chrome}/locale/uk/aboutTor.dtd | 0
{src/chrome => chrome}/locale/uk/brand.dtd | 0
{src/chrome => chrome}/locale/uk/brand.properties | 0
.../locale/uk/securityLevel.properties | 0
{src/chrome => chrome}/locale/uk/torbutton.dtd | 0
.../locale/uk/torbutton.properties | 0
{src/chrome => chrome}/locale/ur/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ur/brand.dtd | 0
{src/chrome => chrome}/locale/ur/brand.properties | 0
{src/chrome => chrome}/locale/ur/torbutton.dtd | 0
.../locale/ur/torbutton.properties | 0
{src/chrome => chrome}/locale/ve/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ve/brand.dtd | 0
{src/chrome => chrome}/locale/ve/brand.properties | 0
{src/chrome => chrome}/locale/ve/torbutton.dtd | 0
.../locale/ve/torbutton.properties | 0
{src/chrome => chrome}/locale/vi/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/vi/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/vi/aboutTor.dtd | 0
{src/chrome => chrome}/locale/vi/brand.dtd | 0
{src/chrome => chrome}/locale/vi/brand.properties | 0
.../locale/vi/browserOnboarding.properties | 0
.../locale/vi/securityLevel.properties | 0
{src/chrome => chrome}/locale/vi/torbutton.dtd | 0
.../locale/vi/torbutton.properties | 0
{src/chrome => chrome}/locale/wa/aboutTor.dtd | 0
{src/chrome => chrome}/locale/wa/brand.dtd | 0
{src/chrome => chrome}/locale/wa/brand.properties | 0
{src/chrome => chrome}/locale/wa/torbutton.dtd | 0
.../locale/wa/torbutton.properties | 0
{src/chrome => chrome}/locale/wo/aboutTor.dtd | 0
{src/chrome => chrome}/locale/wo/brand.dtd | 0
{src/chrome => chrome}/locale/wo/brand.properties | 0
{src/chrome => chrome}/locale/wo/torbutton.dtd | 0
.../locale/wo/torbutton.properties | 0
.../chrome => chrome}/locale/zh-CN/aboutDialog.dtd | 0
.../locale/zh-CN/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/zh-CN/aboutTor.dtd | 0
{src/chrome => chrome}/locale/zh-CN/brand.dtd | 0
.../locale/zh-CN/brand.properties | 0
.../locale/zh-CN/browserOnboarding.properties | 0
.../locale/zh-CN/securityLevel.properties | 0
{src/chrome => chrome}/locale/zh-CN/torbutton.dtd | 0
.../locale/zh-CN/torbutton.properties | 0
{src/chrome => chrome}/locale/zh-HK/aboutTor.dtd | 0
{src/chrome => chrome}/locale/zh-HK/brand.dtd | 0
.../locale/zh-HK/brand.properties | 0
{src/chrome => chrome}/locale/zh-HK/torbutton.dtd | 0
.../locale/zh-HK/torbutton.properties | 0
.../chrome => chrome}/locale/zh-TW/aboutDialog.dtd | 0
.../locale/zh-TW/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/zh-TW/aboutTor.dtd | 0
{src/chrome => chrome}/locale/zh-TW/brand.dtd | 0
.../locale/zh-TW/brand.properties | 0
.../locale/zh-TW/browserOnboarding.properties | 0
.../locale/zh-TW/securityLevel.properties | 0
{src/chrome => chrome}/locale/zh-TW/torbutton.dtd | 0
.../locale/zh-TW/torbutton.properties | 0
{src/chrome => chrome}/locale/zu/aboutTor.dtd | 0
{src/chrome => chrome}/locale/zu/brand.dtd | 0
{src/chrome => chrome}/locale/zu/brand.properties | 0
{src/chrome => chrome}/locale/zu/torbutton.dtd | 0
.../locale/zu/torbutton.properties | 0
{src/chrome => chrome}/skin/about-wordmark.png | Bin
{src/chrome => chrome}/skin/aboutDialog.css | 0
{src/chrome => chrome}/skin/aboutTor.css | 0
{src/chrome => chrome}/skin/forwardArrow.png | Bin
{src/chrome => chrome}/skin/icon-newsletter.png | Bin
.../chrome => chrome}/skin/icon_monthly_donors.png | Bin
{src/chrome => chrome}/skin/new_circuit.svg | 0
{src/chrome => chrome}/skin/preferences-mobile.css | 0
{src/chrome => chrome}/skin/preferences.css | 0
{src/chrome => chrome}/skin/searchLogo.png | Bin
.../chrome => chrome}/skin/tor-circuit-display.css | 0
{src/chrome => chrome}/skin/tor.png | Bin
.../skin/torbrowser_mobile_logo.png | Bin
.../skin/torbutton-update-needed.svg | 0
{src/chrome => chrome}/skin/torbutton.css | 0
{src/chrome => chrome}/skin/torbutton.svg | 0
.../cookie-jar-selector.js | 131 +-
{src/components => components}/domain-isolator.js | 19 +-
{src/components => components}/dragDropFilter.js | 16 +-
.../external-app-blocker.js | 13 +-
{src/components => components}/startup-observer.js | 7 -
{src/components => components}/torCheckService.js | 27 +-
{src/components => components}/torbutton-logger.js | 38 +-
.../preferences/preferences.js | 0
...mport-translations.sh => import-translations.sh | 2 +-
src/jar.mn => jar.mn | 13 -
makexpi.sh | 32 -
{src/modules => modules}/default-prefs.js | 2 +-
{src/modules => modules}/noscript-control.js | 50 +-
{src/modules => modules}/security-prefs.js | 9 +-
{src/modules => modules}/tor-control-port.js | 10 +-
{src/modules => modules}/utils.js | 16 +-
moz.build | 4 +-
src/CHANGELOG | 1392 ----------
src/LICENSE | 53 -
src/chrome.manifest.jar | 60 -
src/chrome.manifest.nojar | 60 -
src/chrome/content/aboutDialog.xul | 56 -
src/chrome/content/menu-items-overlay.xul | 31 -
src/chrome/content/menu-overlay.xul | 29 -
src/chrome/content/popup.xul | 43 -
src/chrome/content/pref-connection.xul | 10 -
src/chrome/content/tor-circuit-display.xul | 34 -
src/chrome/content/torbutton-extensions.xul | 28 -
src/chrome/content/torbutton.xul | 46 -
src/chrome/content/torbutton_tb.xul | 38 -
src/chrome/content/torcookie.js | 385 ---
src/chrome/content/torcookiedialog.xul | 72 -
src/components/aboutTor.js | 60 -
src/install.rdf | 24 -
trans_tools/old/mkmoz.sh | 20 -
trans_tools/old/mkpo.sh | 20 -
trans_tools/old/mvmoz.sh | 6 -
trans_tools/old/new_tb_strings.sh | 20 -
trans_tools/old/validate.py | 94 -
trans_tools/old/validate_all.sh | 7 -
update-unsigned.rdf | 392 ---
website/design/CHROME_NOTES | 120 -
website/design/FF35_AUDIT | 195 --
website/design/FF40_AUDIT | 50 -
website/design/MozillaBrownBag.odp | Bin 47062 -> 0 bytes
website/design/MozillaBrownBag.pdf | Bin 117892 -> 0 bytes
website/design/build.sh | 1 -
website/design/design.xml | 2901 --------------------
website/design/index.html.en | 1453 ----------
website/gimpy.css | 3 -
website/index.html.en | 532 ----
website/update.rdf | 173 --
837 files changed, 239 insertions(+), 8992 deletions(-)
diff --cc chrome/locale/mk/aboutDialog.dtd
index 6fb30ffe,00000000..6fb30ffe
mode 100644,000000..100644
--- a/chrome/locale/mk/aboutDialog.dtd
+++ b/chrome/locale/mk/aboutDialog.dtd
diff --cc chrome/locale/mk/aboutTBUpdate.dtd
index eb627510,00000000..eb627510
mode 100644,000000..100644
--- a/chrome/locale/mk/aboutTBUpdate.dtd
+++ b/chrome/locale/mk/aboutTBUpdate.dtd
diff --cc chrome/locale/mk/browserOnboarding.properties
index f7e732cc,00000000..f7e732cc
mode 100644,000000..100644
--- a/chrome/locale/mk/browserOnboarding.properties
+++ b/chrome/locale/mk/browserOnboarding.properties
diff --cc chrome/locale/ro/aboutDialog.dtd
index edd6a8c8,00000000..edd6a8c8
mode 100644,000000..100644
--- a/chrome/locale/ro/aboutDialog.dtd
+++ b/chrome/locale/ro/aboutDialog.dtd
diff --cc chrome/locale/ro/aboutTBUpdate.dtd
index 1a83bd50,00000000..1a83bd50
mode 100644,000000..100644
--- a/chrome/locale/ro/aboutTBUpdate.dtd
+++ b/chrome/locale/ro/aboutTBUpdate.dtd
diff --cc chrome/locale/ro/browserOnboarding.properties
index 102d2c51,00000000..102d2c51
mode 100644,000000..100644
--- a/chrome/locale/ro/browserOnboarding.properties
+++ b/chrome/locale/ro/browserOnboarding.properties
diff --cc chrome/skin/icon_monthly_donors.png
index 9505f471,00000000..9505f471
mode 100644,000000..100644
Binary files differ
1
0
commit 5426045ea02fb077b1d3c35f5c9f92c2f07facc3
Author: Alex Catarineu <acat(a)torproject.org>
Date: Mon May 13 18:14:46 2019 +0200
Move to new folder structure
---
src/CREDITS => CREDITS | 0
README | 23 -
src/chrome.manifest => chrome.manifest | 0
{src/chrome => chrome}/content/aboutDialog.xul | 0
.../content/aboutTor/aboutTor-content.js | 0
.../content/aboutTor/aboutTor.xhtml | 0
.../content/locale/non-localized.properties | 0
.../content/menu-items-overlay.xul | 0
{src/chrome => chrome}/content/menu-overlay.xul | 0
.../content/preferences-mobile.js | 0
{src/chrome => chrome}/content/preferences.xhtml | 0
.../content/tor-circuit-display.js | 0
.../content/tor-circuit-display.xul | 0
.../content/torbutton-extensions.xul | 0
{src/chrome => chrome}/content/torbutton.js | 0
{src/chrome => chrome}/content/torbutton.xul | 0
{src/chrome => chrome}/content/torbutton_util.js | 0
{src/chrome => chrome}/locale/af/aboutTor.dtd | 0
{src/chrome => chrome}/locale/af/brand.dtd | 0
{src/chrome => chrome}/locale/af/brand.properties | 0
{src/chrome => chrome}/locale/af/torbutton.dtd | 0
.../locale/af/torbutton.properties | 0
{src/chrome => chrome}/locale/ak/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ak/brand.dtd | 0
{src/chrome => chrome}/locale/ak/brand.properties | 0
{src/chrome => chrome}/locale/ak/torbutton.dtd | 0
.../locale/ak/torbutton.properties | 0
{src/chrome => chrome}/locale/am/aboutTor.dtd | 0
{src/chrome => chrome}/locale/am/brand.dtd | 0
{src/chrome => chrome}/locale/am/brand.properties | 0
{src/chrome => chrome}/locale/am/torbutton.dtd | 0
.../locale/am/torbutton.properties | 0
{src/chrome => chrome}/locale/ar/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/ar/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/ar/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ar/brand.dtd | 0
{src/chrome => chrome}/locale/ar/brand.properties | 0
.../locale/ar/browserOnboarding.properties | 0
.../locale/ar/securityLevel.properties | 0
{src/chrome => chrome}/locale/ar/torbutton.dtd | 0
.../locale/ar/torbutton.properties | 0
{src/chrome => chrome}/locale/arn/aboutTor.dtd | 0
{src/chrome => chrome}/locale/arn/brand.dtd | 0
{src/chrome => chrome}/locale/arn/brand.properties | 0
{src/chrome => chrome}/locale/arn/torbutton.dtd | 0
.../locale/arn/torbutton.properties | 0
{src/chrome => chrome}/locale/ast/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ast/brand.dtd | 0
{src/chrome => chrome}/locale/ast/brand.properties | 0
{src/chrome => chrome}/locale/ast/torbutton.dtd | 0
.../locale/ast/torbutton.properties | 0
{src/chrome => chrome}/locale/az/aboutTor.dtd | 0
{src/chrome => chrome}/locale/az/brand.dtd | 0
{src/chrome => chrome}/locale/az/brand.properties | 0
.../locale/az/securityLevel.properties | 0
{src/chrome => chrome}/locale/az/torbutton.dtd | 0
.../locale/az/torbutton.properties | 0
{src/chrome => chrome}/locale/be/aboutTor.dtd | 0
{src/chrome => chrome}/locale/be/brand.dtd | 0
{src/chrome => chrome}/locale/be/brand.properties | 0
{src/chrome => chrome}/locale/be/torbutton.dtd | 0
.../locale/be/torbutton.properties | 0
{src/chrome => chrome}/locale/bg/aboutTor.dtd | 0
{src/chrome => chrome}/locale/bg/brand.dtd | 0
{src/chrome => chrome}/locale/bg/brand.properties | 0
.../locale/bg/securityLevel.properties | 0
{src/chrome => chrome}/locale/bg/torbutton.dtd | 0
.../locale/bg/torbutton.properties | 0
{src/chrome => chrome}/locale/bms/aboutTor.dtd | 0
.../locale/bms/securityLevel.properties | 0
{src/chrome => chrome}/locale/bms/torbutton.dtd | 0
.../locale/bms/torbutton.properties | 0
.../chrome => chrome}/locale/bn-BD/aboutDialog.dtd | 0
.../locale/bn-BD/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/bn-BD/aboutTor.dtd | 0
{src/chrome => chrome}/locale/bn-BD/brand.dtd | 0
.../locale/bn-BD/brand.properties | 0
.../locale/bn-BD/browserOnboarding.properties | 0
.../locale/bn-BD/securityLevel.properties | 0
{src/chrome => chrome}/locale/bn-BD/torbutton.dtd | 0
.../locale/bn-BD/torbutton.properties | 0
{src/chrome => chrome}/locale/bn-IN/aboutTor.dtd | 0
{src/chrome => chrome}/locale/bn-IN/brand.dtd | 0
.../locale/bn-IN/brand.properties | 0
{src/chrome => chrome}/locale/bn-IN/torbutton.dtd | 0
.../locale/bn-IN/torbutton.properties | 0
{src/chrome => chrome}/locale/bn/aboutTor.dtd | 0
{src/chrome => chrome}/locale/bn/brand.dtd | 0
{src/chrome => chrome}/locale/bn/brand.properties | 0
{src/chrome => chrome}/locale/bn/torbutton.dtd | 0
.../locale/bn/torbutton.properties | 0
{src/chrome => chrome}/locale/bo/aboutTor.dtd | 0
{src/chrome => chrome}/locale/bo/brand.dtd | 0
{src/chrome => chrome}/locale/bo/brand.properties | 0
{src/chrome => chrome}/locale/bo/torbutton.dtd | 0
.../locale/bo/torbutton.properties | 0
{src/chrome => chrome}/locale/br/aboutTor.dtd | 0
{src/chrome => chrome}/locale/br/brand.dtd | 0
{src/chrome => chrome}/locale/br/brand.properties | 0
{src/chrome => chrome}/locale/br/torbutton.dtd | 0
.../locale/br/torbutton.properties | 0
{src/chrome => chrome}/locale/bs/aboutTor.dtd | 0
{src/chrome => chrome}/locale/bs/brand.dtd | 0
{src/chrome => chrome}/locale/bs/brand.properties | 0
.../locale/bs/securityLevel.properties | 0
{src/chrome => chrome}/locale/bs/torbutton.dtd | 0
.../locale/bs/torbutton.properties | 0
{src/chrome => chrome}/locale/ca/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/ca/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/ca/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ca/brand.dtd | 0
{src/chrome => chrome}/locale/ca/brand.properties | 0
.../locale/ca/browserOnboarding.properties | 0
.../locale/ca/securityLevel.properties | 0
{src/chrome => chrome}/locale/ca/torbutton.dtd | 0
.../locale/ca/torbutton.properties | 0
{src/chrome => chrome}/locale/cs/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/cs/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/cs/aboutTor.dtd | 0
{src/chrome => chrome}/locale/cs/brand.dtd | 0
{src/chrome => chrome}/locale/cs/brand.properties | 0
.../locale/cs/browserOnboarding.properties | 0
.../locale/cs/securityLevel.properties | 0
{src/chrome => chrome}/locale/cs/torbutton.dtd | 0
.../locale/cs/torbutton.properties | 0
{src/chrome => chrome}/locale/csb/aboutTor.dtd | 0
{src/chrome => chrome}/locale/csb/brand.dtd | 0
{src/chrome => chrome}/locale/csb/brand.properties | 0
{src/chrome => chrome}/locale/csb/torbutton.dtd | 0
.../locale/csb/torbutton.properties | 0
{src/chrome => chrome}/locale/cy/aboutTor.dtd | 0
{src/chrome => chrome}/locale/cy/brand.dtd | 0
{src/chrome => chrome}/locale/cy/brand.properties | 0
{src/chrome => chrome}/locale/cy/torbutton.dtd | 0
.../locale/cy/torbutton.properties | 0
{src/chrome => chrome}/locale/da/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/da/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/da/aboutTor.dtd | 0
{src/chrome => chrome}/locale/da/brand.dtd | 0
{src/chrome => chrome}/locale/da/brand.properties | 0
.../locale/da/browserOnboarding.properties | 0
.../locale/da/securityLevel.properties | 0
{src/chrome => chrome}/locale/da/torbutton.dtd | 0
.../locale/da/torbutton.properties | 0
{src/chrome => chrome}/locale/de/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/de/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/de/aboutTor.dtd | 0
{src/chrome => chrome}/locale/de/brand.dtd | 0
{src/chrome => chrome}/locale/de/brand.properties | 0
.../locale/de/browserOnboarding.properties | 0
.../locale/de/securityLevel.properties | 0
{src/chrome => chrome}/locale/de/torbutton.dtd | 0
.../locale/de/torbutton.properties | 0
{src/chrome => chrome}/locale/dz/aboutTor.dtd | 0
{src/chrome => chrome}/locale/dz/brand.dtd | 0
{src/chrome => chrome}/locale/dz/brand.properties | 0
{src/chrome => chrome}/locale/dz/torbutton.dtd | 0
.../locale/dz/torbutton.properties | 0
{src/chrome => chrome}/locale/el/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/el/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/el/aboutTor.dtd | 0
{src/chrome => chrome}/locale/el/brand.dtd | 0
{src/chrome => chrome}/locale/el/brand.properties | 0
.../locale/el/browserOnboarding.properties | 0
.../locale/el/securityLevel.properties | 0
{src/chrome => chrome}/locale/el/torbutton.dtd | 0
.../locale/el/torbutton.properties | 0
.../chrome => chrome}/locale/en-US/aboutDialog.dtd | 0
.../locale/en-US/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/en-US/aboutTor.dtd | 0
{src/chrome => chrome}/locale/en-US/brand.dtd | 0
.../locale/en-US/brand.properties | 0
.../locale/en-US/browserOnboarding.properties | 0
.../locale/en-US/securityLevel.properties | 0
{src/chrome => chrome}/locale/en-US/torbutton.dtd | 0
.../locale/en-US/torbutton.properties | 0
{src/chrome => chrome}/locale/eo/aboutTor.dtd | 0
{src/chrome => chrome}/locale/eo/brand.dtd | 0
{src/chrome => chrome}/locale/eo/brand.properties | 0
.../locale/eo/securityLevel.properties | 0
{src/chrome => chrome}/locale/eo/torbutton.dtd | 0
.../locale/eo/torbutton.properties | 0
.../chrome => chrome}/locale/es-AR/aboutDialog.dtd | 0
.../locale/es-AR/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/es-AR/aboutTor.dtd | 0
{src/chrome => chrome}/locale/es-AR/brand.dtd | 0
.../locale/es-AR/brand.properties | 0
.../locale/es-AR/browserOnboarding.properties | 0
.../locale/es-AR/securityLevel.properties | 0
{src/chrome => chrome}/locale/es-AR/torbutton.dtd | 0
.../locale/es-AR/torbutton.properties | 0
.../chrome => chrome}/locale/es-ES/aboutDialog.dtd | 0
.../locale/es-ES/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/es-ES/aboutTor.dtd | 0
{src/chrome => chrome}/locale/es-ES/brand.dtd | 0
.../locale/es-ES/brand.properties | 0
.../locale/es-ES/browserOnboarding.properties | 0
.../locale/es-ES/securityLevel.properties | 0
{src/chrome => chrome}/locale/es-ES/torbutton.dtd | 0
.../locale/es-ES/torbutton.properties | 0
{src/chrome => chrome}/locale/et/aboutTor.dtd | 0
{src/chrome => chrome}/locale/et/brand.dtd | 0
{src/chrome => chrome}/locale/et/brand.properties | 0
{src/chrome => chrome}/locale/et/torbutton.dtd | 0
.../locale/et/torbutton.properties | 0
{src/chrome => chrome}/locale/eu/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/eu/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/eu/aboutTor.dtd | 0
{src/chrome => chrome}/locale/eu/brand.dtd | 0
{src/chrome => chrome}/locale/eu/brand.properties | 0
.../locale/eu/browserOnboarding.properties | 0
.../locale/eu/securityLevel.properties | 0
{src/chrome => chrome}/locale/eu/torbutton.dtd | 0
.../locale/eu/torbutton.properties | 0
{src/chrome => chrome}/locale/fa/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/fa/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/fa/aboutTor.dtd | 0
{src/chrome => chrome}/locale/fa/brand.dtd | 0
{src/chrome => chrome}/locale/fa/brand.properties | 0
.../locale/fa/browserOnboarding.properties | 0
.../locale/fa/securityLevel.properties | 0
{src/chrome => chrome}/locale/fa/torbutton.dtd | 0
.../locale/fa/torbutton.properties | 0
{src/chrome => chrome}/locale/fi/aboutTor.dtd | 0
{src/chrome => chrome}/locale/fi/brand.dtd | 0
{src/chrome => chrome}/locale/fi/brand.properties | 0
.../locale/fi/securityLevel.properties | 0
{src/chrome => chrome}/locale/fi/torbutton.dtd | 0
.../locale/fi/torbutton.properties | 0
{src/chrome => chrome}/locale/fil/aboutTor.dtd | 0
{src/chrome => chrome}/locale/fil/brand.dtd | 0
{src/chrome => chrome}/locale/fil/brand.properties | 0
{src/chrome => chrome}/locale/fil/torbutton.dtd | 0
.../locale/fil/torbutton.properties | 0
{src/chrome => chrome}/locale/fo/aboutTor.dtd | 0
{src/chrome => chrome}/locale/fo/brand.dtd | 0
{src/chrome => chrome}/locale/fo/brand.properties | 0
{src/chrome => chrome}/locale/fo/torbutton.dtd | 0
.../locale/fo/torbutton.properties | 0
{src/chrome => chrome}/locale/fr/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/fr/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/fr/aboutTor.dtd | 0
{src/chrome => chrome}/locale/fr/brand.dtd | 0
{src/chrome => chrome}/locale/fr/brand.properties | 0
.../locale/fr/browserOnboarding.properties | 0
.../locale/fr/securityLevel.properties | 0
{src/chrome => chrome}/locale/fr/torbutton.dtd | 0
.../locale/fr/torbutton.properties | 0
{src/chrome => chrome}/locale/fur/aboutTor.dtd | 0
{src/chrome => chrome}/locale/fur/brand.dtd | 0
{src/chrome => chrome}/locale/fur/brand.properties | 0
{src/chrome => chrome}/locale/fur/torbutton.dtd | 0
.../locale/fur/torbutton.properties | 0
{src/chrome => chrome}/locale/fy/aboutTor.dtd | 0
{src/chrome => chrome}/locale/fy/brand.dtd | 0
{src/chrome => chrome}/locale/fy/brand.properties | 0
{src/chrome => chrome}/locale/fy/torbutton.dtd | 0
.../locale/fy/torbutton.properties | 0
.../chrome => chrome}/locale/ga-IE/aboutDialog.dtd | 0
.../locale/ga-IE/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/ga-IE/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ga-IE/brand.dtd | 0
.../locale/ga-IE/brand.properties | 0
.../locale/ga-IE/browserOnboarding.properties | 0
.../locale/ga-IE/securityLevel.properties | 0
{src/chrome => chrome}/locale/ga-IE/torbutton.dtd | 0
.../locale/ga-IE/torbutton.properties | 0
{src/chrome => chrome}/locale/gl/aboutTor.dtd | 0
{src/chrome => chrome}/locale/gl/brand.dtd | 0
{src/chrome => chrome}/locale/gl/brand.properties | 0
.../locale/gl/securityLevel.properties | 0
{src/chrome => chrome}/locale/gl/torbutton.dtd | 0
.../locale/gl/torbutton.properties | 0
{src/chrome => chrome}/locale/gu/aboutTor.dtd | 0
{src/chrome => chrome}/locale/gu/brand.dtd | 0
{src/chrome => chrome}/locale/gu/brand.properties | 0
.../locale/gu/securityLevel.properties | 0
{src/chrome => chrome}/locale/gu/torbutton.dtd | 0
.../locale/gu/torbutton.properties | 0
{src/chrome => chrome}/locale/gun/aboutTor.dtd | 0
{src/chrome => chrome}/locale/gun/brand.dtd | 0
{src/chrome => chrome}/locale/gun/brand.properties | 0
{src/chrome => chrome}/locale/gun/torbutton.dtd | 0
.../locale/gun/torbutton.properties | 0
{src/chrome => chrome}/locale/ha/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ha/brand.dtd | 0
{src/chrome => chrome}/locale/ha/brand.properties | 0
{src/chrome => chrome}/locale/ha/torbutton.dtd | 0
.../locale/ha/torbutton.properties | 0
{src/chrome => chrome}/locale/he/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/he/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/he/aboutTor.dtd | 0
{src/chrome => chrome}/locale/he/brand.dtd | 0
{src/chrome => chrome}/locale/he/brand.properties | 0
.../locale/he/browserOnboarding.properties | 0
.../locale/he/securityLevel.properties | 0
{src/chrome => chrome}/locale/he/torbutton.dtd | 0
.../locale/he/torbutton.properties | 0
{src/chrome => chrome}/locale/hi/aboutTor.dtd | 0
{src/chrome => chrome}/locale/hi/brand.dtd | 0
{src/chrome => chrome}/locale/hi/brand.properties | 0
{src/chrome => chrome}/locale/hi/torbutton.dtd | 0
.../locale/hi/torbutton.properties | 0
{src/chrome => chrome}/locale/hr/aboutTor.dtd | 0
{src/chrome => chrome}/locale/hr/brand.dtd | 0
{src/chrome => chrome}/locale/hr/brand.properties | 0
{src/chrome => chrome}/locale/hr/torbutton.dtd | 0
.../locale/hr/torbutton.properties | 0
{src/chrome => chrome}/locale/ht/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ht/brand.dtd | 0
{src/chrome => chrome}/locale/ht/brand.properties | 0
{src/chrome => chrome}/locale/ht/torbutton.dtd | 0
.../locale/ht/torbutton.properties | 0
{src/chrome => chrome}/locale/hu/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/hu/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/hu/aboutTor.dtd | 0
{src/chrome => chrome}/locale/hu/brand.dtd | 0
{src/chrome => chrome}/locale/hu/brand.properties | 0
.../locale/hu/browserOnboarding.properties | 0
.../locale/hu/securityLevel.properties | 0
{src/chrome => chrome}/locale/hu/torbutton.dtd | 0
.../locale/hu/torbutton.properties | 0
{src/chrome => chrome}/locale/hy/aboutTor.dtd | 0
{src/chrome => chrome}/locale/hy/brand.dtd | 0
{src/chrome => chrome}/locale/hy/brand.properties | 0
{src/chrome => chrome}/locale/hy/torbutton.dtd | 0
.../locale/hy/torbutton.properties | 0
{src/chrome => chrome}/locale/id/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/id/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/id/aboutTor.dtd | 0
{src/chrome => chrome}/locale/id/brand.dtd | 0
{src/chrome => chrome}/locale/id/brand.properties | 0
.../locale/id/browserOnboarding.properties | 0
.../locale/id/securityLevel.properties | 0
{src/chrome => chrome}/locale/id/torbutton.dtd | 0
.../locale/id/torbutton.properties | 0
{src/chrome => chrome}/locale/is/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/is/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/is/aboutTor.dtd | 0
{src/chrome => chrome}/locale/is/brand.dtd | 0
{src/chrome => chrome}/locale/is/brand.properties | 0
.../locale/is/browserOnboarding.properties | 0
.../locale/is/securityLevel.properties | 0
{src/chrome => chrome}/locale/is/torbutton.dtd | 0
.../locale/is/torbutton.properties | 0
{src/chrome => chrome}/locale/it/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/it/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/it/aboutTor.dtd | 0
{src/chrome => chrome}/locale/it/brand.dtd | 0
{src/chrome => chrome}/locale/it/brand.properties | 0
.../locale/it/browserOnboarding.properties | 0
.../locale/it/securityLevel.properties | 0
{src/chrome => chrome}/locale/it/torbutton.dtd | 0
.../locale/it/torbutton.properties | 0
{src/chrome => chrome}/locale/ja/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/ja/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/ja/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ja/brand.dtd | 0
{src/chrome => chrome}/locale/ja/brand.properties | 0
.../locale/ja/browserOnboarding.properties | 0
.../locale/ja/securityLevel.properties | 0
{src/chrome => chrome}/locale/ja/torbutton.dtd | 0
.../locale/ja/torbutton.properties | 0
{src/chrome => chrome}/locale/jv/aboutTor.dtd | 0
{src/chrome => chrome}/locale/jv/brand.dtd | 0
{src/chrome => chrome}/locale/jv/brand.properties | 0
{src/chrome => chrome}/locale/jv/torbutton.dtd | 0
.../locale/jv/torbutton.properties | 0
{src/chrome => chrome}/locale/ka/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/ka/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/ka/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ka/brand.dtd | 0
{src/chrome => chrome}/locale/ka/brand.properties | 0
.../locale/ka/browserOnboarding.properties | 0
.../locale/ka/securityLevel.properties | 0
{src/chrome => chrome}/locale/ka/torbutton.dtd | 0
.../locale/ka/torbutton.properties | 0
{src/chrome => chrome}/locale/km/aboutTor.dtd | 0
{src/chrome => chrome}/locale/km/brand.dtd | 0
{src/chrome => chrome}/locale/km/brand.properties | 0
{src/chrome => chrome}/locale/km/torbutton.dtd | 0
.../locale/km/torbutton.properties | 0
{src/chrome => chrome}/locale/kn/aboutTor.dtd | 0
{src/chrome => chrome}/locale/kn/brand.dtd | 0
{src/chrome => chrome}/locale/kn/brand.properties | 0
{src/chrome => chrome}/locale/kn/torbutton.dtd | 0
.../locale/kn/torbutton.properties | 0
{src/chrome => chrome}/locale/ko/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/ko/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/ko/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ko/brand.dtd | 0
{src/chrome => chrome}/locale/ko/brand.properties | 0
.../locale/ko/browserOnboarding.properties | 0
.../locale/ko/securityLevel.properties | 0
{src/chrome => chrome}/locale/ko/torbutton.dtd | 0
.../locale/ko/torbutton.properties | 0
{src/chrome => chrome}/locale/ku/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ku/brand.dtd | 0
{src/chrome => chrome}/locale/ku/brand.properties | 0
{src/chrome => chrome}/locale/ku/torbutton.dtd | 0
.../locale/ku/torbutton.properties | 0
{src/chrome => chrome}/locale/kw/aboutTor.dtd | 0
{src/chrome => chrome}/locale/kw/brand.dtd | 0
{src/chrome => chrome}/locale/kw/brand.properties | 0
{src/chrome => chrome}/locale/kw/torbutton.dtd | 0
.../locale/kw/torbutton.properties | 0
{src/chrome => chrome}/locale/ky/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ky/brand.dtd | 0
{src/chrome => chrome}/locale/ky/brand.properties | 0
{src/chrome => chrome}/locale/ky/torbutton.dtd | 0
.../locale/ky/torbutton.properties | 0
{src/chrome => chrome}/locale/lb/aboutTor.dtd | 0
{src/chrome => chrome}/locale/lb/brand.dtd | 0
{src/chrome => chrome}/locale/lb/brand.properties | 0
{src/chrome => chrome}/locale/lb/torbutton.dtd | 0
.../locale/lb/torbutton.properties | 0
{src/chrome => chrome}/locale/lg/aboutTor.dtd | 0
{src/chrome => chrome}/locale/lg/torbutton.dtd | 0
.../locale/lg/torbutton.properties | 0
{src/chrome => chrome}/locale/ln/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ln/brand.dtd | 0
{src/chrome => chrome}/locale/ln/brand.properties | 0
{src/chrome => chrome}/locale/ln/torbutton.dtd | 0
.../locale/ln/torbutton.properties | 0
{src/chrome => chrome}/locale/lo/aboutTor.dtd | 0
{src/chrome => chrome}/locale/lo/brand.dtd | 0
{src/chrome => chrome}/locale/lo/brand.properties | 0
{src/chrome => chrome}/locale/lo/torbutton.dtd | 0
.../locale/lo/torbutton.properties | 0
{src/chrome => chrome}/locale/lt/aboutTor.dtd | 0
{src/chrome => chrome}/locale/lt/brand.dtd | 0
{src/chrome => chrome}/locale/lt/brand.properties | 0
.../locale/lt/securityLevel.properties | 0
{src/chrome => chrome}/locale/lt/torbutton.dtd | 0
.../locale/lt/torbutton.properties | 0
{src/chrome => chrome}/locale/lv/aboutTor.dtd | 0
{src/chrome => chrome}/locale/lv/brand.dtd | 0
{src/chrome => chrome}/locale/lv/brand.properties | 0
.../locale/lv/securityLevel.properties | 0
{src/chrome => chrome}/locale/lv/torbutton.dtd | 0
.../locale/lv/torbutton.properties | 0
{src/chrome => chrome}/locale/mg/aboutTor.dtd | 0
{src/chrome => chrome}/locale/mg/brand.dtd | 0
{src/chrome => chrome}/locale/mg/brand.properties | 0
{src/chrome => chrome}/locale/mg/torbutton.dtd | 0
.../locale/mg/torbutton.properties | 0
{src/chrome => chrome}/locale/mi/aboutTor.dtd | 0
{src/chrome => chrome}/locale/mi/brand.dtd | 0
{src/chrome => chrome}/locale/mi/brand.properties | 0
{src/chrome => chrome}/locale/mi/torbutton.dtd | 0
.../locale/mi/torbutton.properties | 0
{src/chrome => chrome}/locale/mk/aboutTor.dtd | 0
{src/chrome => chrome}/locale/mk/brand.dtd | 0
{src/chrome => chrome}/locale/mk/brand.properties | 0
.../locale/mk/securityLevel.properties | 0
{src/chrome => chrome}/locale/mk/torbutton.dtd | 0
.../locale/mk/torbutton.properties | 0
{src/chrome => chrome}/locale/ml/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ml/brand.dtd | 0
{src/chrome => chrome}/locale/ml/brand.properties | 0
{src/chrome => chrome}/locale/ml/torbutton.dtd | 0
.../locale/ml/torbutton.properties | 0
{src/chrome => chrome}/locale/mn/aboutTor.dtd | 0
{src/chrome => chrome}/locale/mn/brand.dtd | 0
{src/chrome => chrome}/locale/mn/brand.properties | 0
{src/chrome => chrome}/locale/mn/torbutton.dtd | 0
.../locale/mn/torbutton.properties | 0
{src/chrome => chrome}/locale/mr/aboutTor.dtd | 0
{src/chrome => chrome}/locale/mr/brand.dtd | 0
{src/chrome => chrome}/locale/mr/brand.properties | 0
{src/chrome => chrome}/locale/mr/torbutton.dtd | 0
.../locale/mr/torbutton.properties | 0
{src/chrome => chrome}/locale/ms/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ms/brand.dtd | 0
{src/chrome => chrome}/locale/ms/brand.properties | 0
{src/chrome => chrome}/locale/ms/torbutton.dtd | 0
.../locale/ms/torbutton.properties | 0
{src/chrome => chrome}/locale/mt/aboutTor.dtd | 0
{src/chrome => chrome}/locale/mt/brand.dtd | 0
{src/chrome => chrome}/locale/mt/brand.properties | 0
{src/chrome => chrome}/locale/mt/torbutton.dtd | 0
.../locale/mt/torbutton.properties | 0
{src/chrome => chrome}/locale/my/aboutTor.dtd | 0
{src/chrome => chrome}/locale/my/brand.dtd | 0
{src/chrome => chrome}/locale/my/brand.properties | 0
.../locale/my/securityLevel.properties | 0
{src/chrome => chrome}/locale/my/torbutton.dtd | 0
.../locale/my/torbutton.properties | 0
{src/chrome => chrome}/locale/nah/aboutTor.dtd | 0
{src/chrome => chrome}/locale/nah/brand.dtd | 0
{src/chrome => chrome}/locale/nah/brand.properties | 0
{src/chrome => chrome}/locale/nah/torbutton.dtd | 0
.../locale/nah/torbutton.properties | 0
{src/chrome => chrome}/locale/nap/aboutTor.dtd | 0
{src/chrome => chrome}/locale/nap/brand.dtd | 0
{src/chrome => chrome}/locale/nap/brand.properties | 0
{src/chrome => chrome}/locale/nap/torbutton.dtd | 0
.../locale/nap/torbutton.properties | 0
.../chrome => chrome}/locale/nb-NO/aboutDialog.dtd | 0
.../locale/nb-NO/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/nb-NO/aboutTor.dtd | 0
{src/chrome => chrome}/locale/nb-NO/brand.dtd | 0
.../locale/nb-NO/brand.properties | 0
.../locale/nb-NO/browserOnboarding.properties | 0
.../locale/nb-NO/securityLevel.properties | 0
{src/chrome => chrome}/locale/nb-NO/torbutton.dtd | 0
.../locale/nb-NO/torbutton.properties | 0
{src/chrome => chrome}/locale/ne/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ne/brand.dtd | 0
{src/chrome => chrome}/locale/ne/brand.properties | 0
{src/chrome => chrome}/locale/ne/torbutton.dtd | 0
.../locale/ne/torbutton.properties | 0
{src/chrome => chrome}/locale/nl/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/nl/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/nl/aboutTor.dtd | 0
{src/chrome => chrome}/locale/nl/brand.dtd | 0
{src/chrome => chrome}/locale/nl/brand.properties | 0
.../locale/nl/browserOnboarding.properties | 0
.../locale/nl/securityLevel.properties | 0
{src/chrome => chrome}/locale/nl/torbutton.dtd | 0
.../locale/nl/torbutton.properties | 0
{src/chrome => chrome}/locale/nn/aboutTor.dtd | 0
{src/chrome => chrome}/locale/nn/brand.dtd | 0
{src/chrome => chrome}/locale/nn/brand.properties | 0
{src/chrome => chrome}/locale/nn/torbutton.dtd | 0
.../locale/nn/torbutton.properties | 0
{src/chrome => chrome}/locale/nso/aboutTor.dtd | 0
{src/chrome => chrome}/locale/nso/brand.dtd | 0
{src/chrome => chrome}/locale/nso/brand.properties | 0
{src/chrome => chrome}/locale/nso/torbutton.dtd | 0
.../locale/nso/torbutton.properties | 0
{src/chrome => chrome}/locale/oc/aboutTor.dtd | 0
{src/chrome => chrome}/locale/oc/brand.dtd | 0
{src/chrome => chrome}/locale/oc/brand.properties | 0
{src/chrome => chrome}/locale/oc/torbutton.dtd | 0
.../locale/oc/torbutton.properties | 0
{src/chrome => chrome}/locale/or/aboutTor.dtd | 0
{src/chrome => chrome}/locale/or/brand.dtd | 0
{src/chrome => chrome}/locale/or/brand.properties | 0
{src/chrome => chrome}/locale/or/torbutton.dtd | 0
.../locale/or/torbutton.properties | 0
{src/chrome => chrome}/locale/pa/aboutTor.dtd | 0
{src/chrome => chrome}/locale/pa/brand.dtd | 0
{src/chrome => chrome}/locale/pa/brand.properties | 0
{src/chrome => chrome}/locale/pa/torbutton.dtd | 0
.../locale/pa/torbutton.properties | 0
{src/chrome => chrome}/locale/pap/aboutTor.dtd | 0
{src/chrome => chrome}/locale/pap/brand.dtd | 0
{src/chrome => chrome}/locale/pap/brand.properties | 0
{src/chrome => chrome}/locale/pap/torbutton.dtd | 0
.../locale/pap/torbutton.properties | 0
{src/chrome => chrome}/locale/pl/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/pl/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/pl/aboutTor.dtd | 0
{src/chrome => chrome}/locale/pl/brand.dtd | 0
{src/chrome => chrome}/locale/pl/brand.properties | 0
.../locale/pl/browserOnboarding.properties | 0
.../locale/pl/securityLevel.properties | 0
{src/chrome => chrome}/locale/pl/torbutton.dtd | 0
.../locale/pl/torbutton.properties | 0
{src/chrome => chrome}/locale/pms/aboutTor.dtd | 0
{src/chrome => chrome}/locale/pms/brand.dtd | 0
{src/chrome => chrome}/locale/pms/brand.properties | 0
{src/chrome => chrome}/locale/pms/torbutton.dtd | 0
.../locale/pms/torbutton.properties | 0
{src/chrome => chrome}/locale/ps/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ps/brand.dtd | 0
{src/chrome => chrome}/locale/ps/brand.properties | 0
{src/chrome => chrome}/locale/ps/torbutton.dtd | 0
.../locale/ps/torbutton.properties | 0
.../chrome => chrome}/locale/pt-BR/aboutDialog.dtd | 0
.../locale/pt-BR/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/pt-BR/aboutTor.dtd | 0
{src/chrome => chrome}/locale/pt-BR/brand.dtd | 0
.../locale/pt-BR/brand.properties | 0
.../locale/pt-BR/browserOnboarding.properties | 0
.../locale/pt-BR/securityLevel.properties | 0
{src/chrome => chrome}/locale/pt-BR/torbutton.dtd | 0
.../locale/pt-BR/torbutton.properties | 0
{src/chrome => chrome}/locale/pt/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/pt/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/pt/aboutTor.dtd | 0
{src/chrome => chrome}/locale/pt/brand.dtd | 0
{src/chrome => chrome}/locale/pt/brand.properties | 0
.../locale/pt/securityLevel.properties | 0
{src/chrome => chrome}/locale/pt/torbutton.dtd | 0
.../locale/pt/torbutton.properties | 0
{src/chrome => chrome}/locale/ro/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ro/brand.dtd | 0
{src/chrome => chrome}/locale/ro/brand.properties | 0
.../locale/ro/securityLevel.properties | 0
{src/chrome => chrome}/locale/ro/torbutton.dtd | 0
.../locale/ro/torbutton.properties | 0
{src/chrome => chrome}/locale/ru/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/ru/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/ru/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ru/brand.dtd | 0
{src/chrome => chrome}/locale/ru/brand.properties | 0
.../locale/ru/browserOnboarding.properties | 0
.../locale/ru/securityLevel.properties | 0
{src/chrome => chrome}/locale/ru/torbutton.dtd | 0
.../locale/ru/torbutton.properties | 0
{src/chrome => chrome}/locale/sco/aboutTor.dtd | 0
{src/chrome => chrome}/locale/sco/brand.dtd | 0
{src/chrome => chrome}/locale/sco/brand.properties | 0
{src/chrome => chrome}/locale/sco/torbutton.dtd | 0
.../locale/sco/torbutton.properties | 0
{src/chrome => chrome}/locale/sk/aboutTor.dtd | 0
{src/chrome => chrome}/locale/sk/brand.dtd | 0
{src/chrome => chrome}/locale/sk/brand.properties | 0
.../locale/sk/securityLevel.properties | 0
{src/chrome => chrome}/locale/sk/torbutton.dtd | 0
.../locale/sk/torbutton.properties | 0
{src/chrome => chrome}/locale/sl/aboutTor.dtd | 0
{src/chrome => chrome}/locale/sl/brand.dtd | 0
{src/chrome => chrome}/locale/sl/brand.properties | 0
.../locale/sl/securityLevel.properties | 0
{src/chrome => chrome}/locale/sl/torbutton.dtd | 0
.../locale/sl/torbutton.properties | 0
{src/chrome => chrome}/locale/so/aboutTor.dtd | 0
{src/chrome => chrome}/locale/so/brand.dtd | 0
{src/chrome => chrome}/locale/so/brand.properties | 0
{src/chrome => chrome}/locale/so/torbutton.dtd | 0
.../locale/so/torbutton.properties | 0
{src/chrome => chrome}/locale/son/aboutTor.dtd | 0
{src/chrome => chrome}/locale/son/brand.dtd | 0
{src/chrome => chrome}/locale/son/brand.properties | 0
{src/chrome => chrome}/locale/son/torbutton.dtd | 0
.../locale/son/torbutton.properties | 0
{src/chrome => chrome}/locale/sq/aboutTor.dtd | 0
{src/chrome => chrome}/locale/sq/brand.dtd | 0
{src/chrome => chrome}/locale/sq/brand.properties | 0
{src/chrome => chrome}/locale/sq/torbutton.dtd | 0
.../locale/sq/torbutton.properties | 0
{src/chrome => chrome}/locale/sr/aboutTor.dtd | 0
{src/chrome => chrome}/locale/sr/brand.dtd | 0
{src/chrome => chrome}/locale/sr/brand.properties | 0
.../locale/sr/securityLevel.properties | 0
{src/chrome => chrome}/locale/sr/torbutton.dtd | 0
.../locale/sr/torbutton.properties | 0
{src/chrome => chrome}/locale/st/aboutTor.dtd | 0
{src/chrome => chrome}/locale/st/brand.dtd | 0
{src/chrome => chrome}/locale/st/brand.properties | 0
{src/chrome => chrome}/locale/st/torbutton.dtd | 0
.../locale/st/torbutton.properties | 0
{src/chrome => chrome}/locale/su/aboutTor.dtd | 0
{src/chrome => chrome}/locale/su/brand.dtd | 0
{src/chrome => chrome}/locale/su/brand.properties | 0
{src/chrome => chrome}/locale/su/torbutton.dtd | 0
.../locale/su/torbutton.properties | 0
.../chrome => chrome}/locale/sv-SE/aboutDialog.dtd | 0
.../locale/sv-SE/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/sv-SE/aboutTor.dtd | 0
{src/chrome => chrome}/locale/sv-SE/brand.dtd | 0
.../locale/sv-SE/brand.properties | 0
.../locale/sv-SE/browserOnboarding.properties | 0
.../locale/sv-SE/securityLevel.properties | 0
{src/chrome => chrome}/locale/sv-SE/torbutton.dtd | 0
.../locale/sv-SE/torbutton.properties | 0
{src/chrome => chrome}/locale/sw/aboutTor.dtd | 0
{src/chrome => chrome}/locale/sw/brand.dtd | 0
{src/chrome => chrome}/locale/sw/brand.properties | 0
{src/chrome => chrome}/locale/sw/torbutton.dtd | 0
.../locale/sw/torbutton.properties | 0
{src/chrome => chrome}/locale/ta/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ta/brand.dtd | 0
{src/chrome => chrome}/locale/ta/brand.properties | 0
{src/chrome => chrome}/locale/ta/torbutton.dtd | 0
.../locale/ta/torbutton.properties | 0
{src/chrome => chrome}/locale/te/aboutTor.dtd | 0
{src/chrome => chrome}/locale/te/brand.dtd | 0
{src/chrome => chrome}/locale/te/brand.properties | 0
{src/chrome => chrome}/locale/te/torbutton.dtd | 0
.../locale/te/torbutton.properties | 0
{src/chrome => chrome}/locale/tg/aboutTor.dtd | 0
{src/chrome => chrome}/locale/tg/brand.dtd | 0
{src/chrome => chrome}/locale/tg/brand.properties | 0
{src/chrome => chrome}/locale/tg/torbutton.dtd | 0
.../locale/tg/torbutton.properties | 0
{src/chrome => chrome}/locale/th/aboutTor.dtd | 0
{src/chrome => chrome}/locale/th/brand.dtd | 0
{src/chrome => chrome}/locale/th/brand.properties | 0
{src/chrome => chrome}/locale/th/torbutton.dtd | 0
.../locale/th/torbutton.properties | 0
{src/chrome => chrome}/locale/ti/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ti/brand.dtd | 0
{src/chrome => chrome}/locale/ti/brand.properties | 0
{src/chrome => chrome}/locale/ti/torbutton.dtd | 0
.../locale/ti/torbutton.properties | 0
{src/chrome => chrome}/locale/tk/aboutTor.dtd | 0
{src/chrome => chrome}/locale/tk/brand.dtd | 0
{src/chrome => chrome}/locale/tk/brand.properties | 0
{src/chrome => chrome}/locale/tk/torbutton.dtd | 0
.../locale/tk/torbutton.properties | 0
{src/chrome => chrome}/locale/tr/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/tr/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/tr/aboutTor.dtd | 0
{src/chrome => chrome}/locale/tr/brand.dtd | 0
{src/chrome => chrome}/locale/tr/brand.properties | 0
.../locale/tr/browserOnboarding.properties | 0
.../locale/tr/securityLevel.properties | 0
{src/chrome => chrome}/locale/tr/torbutton.dtd | 0
.../locale/tr/torbutton.properties | 0
{src/chrome => chrome}/locale/uk/aboutTor.dtd | 0
{src/chrome => chrome}/locale/uk/brand.dtd | 0
{src/chrome => chrome}/locale/uk/brand.properties | 0
.../locale/uk/securityLevel.properties | 0
{src/chrome => chrome}/locale/uk/torbutton.dtd | 0
.../locale/uk/torbutton.properties | 0
{src/chrome => chrome}/locale/ur/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ur/brand.dtd | 0
{src/chrome => chrome}/locale/ur/brand.properties | 0
{src/chrome => chrome}/locale/ur/torbutton.dtd | 0
.../locale/ur/torbutton.properties | 0
{src/chrome => chrome}/locale/ve/aboutTor.dtd | 0
{src/chrome => chrome}/locale/ve/brand.dtd | 0
{src/chrome => chrome}/locale/ve/brand.properties | 0
{src/chrome => chrome}/locale/ve/torbutton.dtd | 0
.../locale/ve/torbutton.properties | 0
{src/chrome => chrome}/locale/vi/aboutDialog.dtd | 0
{src/chrome => chrome}/locale/vi/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/vi/aboutTor.dtd | 0
{src/chrome => chrome}/locale/vi/brand.dtd | 0
{src/chrome => chrome}/locale/vi/brand.properties | 0
.../locale/vi/browserOnboarding.properties | 0
.../locale/vi/securityLevel.properties | 0
{src/chrome => chrome}/locale/vi/torbutton.dtd | 0
.../locale/vi/torbutton.properties | 0
{src/chrome => chrome}/locale/wa/aboutTor.dtd | 0
{src/chrome => chrome}/locale/wa/brand.dtd | 0
{src/chrome => chrome}/locale/wa/brand.properties | 0
{src/chrome => chrome}/locale/wa/torbutton.dtd | 0
.../locale/wa/torbutton.properties | 0
{src/chrome => chrome}/locale/wo/aboutTor.dtd | 0
{src/chrome => chrome}/locale/wo/brand.dtd | 0
{src/chrome => chrome}/locale/wo/brand.properties | 0
{src/chrome => chrome}/locale/wo/torbutton.dtd | 0
.../locale/wo/torbutton.properties | 0
.../chrome => chrome}/locale/zh-CN/aboutDialog.dtd | 0
.../locale/zh-CN/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/zh-CN/aboutTor.dtd | 0
{src/chrome => chrome}/locale/zh-CN/brand.dtd | 0
.../locale/zh-CN/brand.properties | 0
.../locale/zh-CN/browserOnboarding.properties | 0
.../locale/zh-CN/securityLevel.properties | 0
{src/chrome => chrome}/locale/zh-CN/torbutton.dtd | 0
.../locale/zh-CN/torbutton.properties | 0
{src/chrome => chrome}/locale/zh-HK/aboutTor.dtd | 0
{src/chrome => chrome}/locale/zh-HK/brand.dtd | 0
.../locale/zh-HK/brand.properties | 0
{src/chrome => chrome}/locale/zh-HK/torbutton.dtd | 0
.../locale/zh-HK/torbutton.properties | 0
.../chrome => chrome}/locale/zh-TW/aboutDialog.dtd | 0
.../locale/zh-TW/aboutTBUpdate.dtd | 0
{src/chrome => chrome}/locale/zh-TW/aboutTor.dtd | 0
{src/chrome => chrome}/locale/zh-TW/brand.dtd | 0
.../locale/zh-TW/brand.properties | 0
.../locale/zh-TW/browserOnboarding.properties | 0
.../locale/zh-TW/securityLevel.properties | 0
{src/chrome => chrome}/locale/zh-TW/torbutton.dtd | 0
.../locale/zh-TW/torbutton.properties | 0
{src/chrome => chrome}/locale/zu/aboutTor.dtd | 0
{src/chrome => chrome}/locale/zu/brand.dtd | 0
{src/chrome => chrome}/locale/zu/brand.properties | 0
{src/chrome => chrome}/locale/zu/torbutton.dtd | 0
.../locale/zu/torbutton.properties | 0
{src/chrome => chrome}/skin/about-wordmark.png | Bin
{src/chrome => chrome}/skin/aboutDialog.css | 0
{src/chrome => chrome}/skin/aboutTor.css | 0
{src/chrome => chrome}/skin/forwardArrow.png | Bin
{src/chrome => chrome}/skin/icon-newsletter.png | Bin
{src/chrome => chrome}/skin/new_circuit.svg | 0
{src/chrome => chrome}/skin/preferences-mobile.css | 0
{src/chrome => chrome}/skin/preferences.css | 0
{src/chrome => chrome}/skin/searchLogo.png | Bin
.../chrome => chrome}/skin/tor-circuit-display.css | 0
{src/chrome => chrome}/skin/tor.png | Bin
.../skin/torbrowser_mobile_logo.png | Bin
.../skin/torbutton-update-needed.svg | 0
{src/chrome => chrome}/skin/torbutton.css | 0
{src/chrome => chrome}/skin/torbutton.svg | 0
{src/components => components}/aboutTor.js | 0
.../cookie-jar-selector.js | 0
{src/components => components}/domain-isolator.js | 0
{src/components => components}/dragDropFilter.js | 0
.../external-app-blocker.js | 0
{src/components => components}/startup-observer.js | 0
{src/components => components}/torCheckService.js | 0
{src/components => components}/torbutton-logger.js | 0
.../preferences/preferences.js | 0
...mport-translations.sh => import-translations.sh | 2 +-
src/jar.mn => jar.mn | 0
{src/modules => modules}/default-prefs.js | 0
{src/modules => modules}/noscript-control.js | 0
{src/modules => modules}/security-prefs.js | 0
{src/modules => modules}/tor-control-port.js | 0
{src/modules => modules}/utils.js | 0
moz.build | 4 +-
src/CHANGELOG | 1366 ---------
src/LICENSE | 53 -
src/install.rdf | 24 -
trans_tools/old/mkmoz.sh | 20 -
trans_tools/old/mkpo.sh | 20 -
trans_tools/old/mvmoz.sh | 6 -
trans_tools/old/new_tb_strings.sh | 20 -
trans_tools/old/validate.py | 94 -
trans_tools/old/validate_all.sh | 7 -
website/design/CHROME_NOTES | 120 -
website/design/FF35_AUDIT | 195 --
website/design/FF40_AUDIT | 50 -
website/design/MozillaBrownBag.odp | Bin 47062 -> 0 bytes
website/design/MozillaBrownBag.pdf | Bin 117892 -> 0 bytes
website/design/build.sh | 1 -
website/design/design.xml | 2901 --------------------
website/design/index.html.en | 1453 ----------
website/gimpy.css | 3 -
website/index.html.en | 532 ----
website/update.rdf | 173 --
818 files changed, 3 insertions(+), 7064 deletions(-)
diff --git a/src/CREDITS b/CREDITS
similarity index 100%
rename from src/CREDITS
rename to CREDITS
diff --git a/README b/README
deleted file mode 100644
index f4dc12d4..00000000
--- a/README
+++ /dev/null
@@ -1,23 +0,0 @@
-Torbutton comes pre-installed with Tor Browser and we urge you not to change it.
-We do not recommend to install it to Firefox because this is not a sufficient
-way to surf anonymously.
-
-Torbutton guarantees that DNS requests are sent through the Tor instance that
-comes with Tor Browser. You should not change the proxy settings.
-
-It’s strongly discouraged to install new Add-ons in Tor Browser, because they
-can compromise both your privacy and your security. Plus, Tor Browser already
-comes installed with two add-ons — HTTPS Everywhere and NoScript — which give
-you a lot of added protection.
-
-You can read more about it here:
-https://www.torproject.org/projects/torbrowser/design/
-
-Also have a look at this page for already answered questions:
-https://trac.torproject.org/projects/tor/wiki/org/teams/CommunityTeam/Support_discuss
-
-For other issues you should know about have a look at this blog post:
-https://blog.torproject.org/toggle-or-not-toggle-end-torbutton
-
-For a list of all torbutton announcements see
-https://blog.torproject.org/category/tags/torbutton
diff --git a/src/chrome.manifest b/chrome.manifest
similarity index 100%
rename from src/chrome.manifest
rename to chrome.manifest
diff --git a/src/chrome/content/aboutDialog.xul b/chrome/content/aboutDialog.xul
similarity index 100%
rename from src/chrome/content/aboutDialog.xul
rename to chrome/content/aboutDialog.xul
diff --git a/src/chrome/content/aboutTor/aboutTor-content.js b/chrome/content/aboutTor/aboutTor-content.js
similarity index 100%
rename from src/chrome/content/aboutTor/aboutTor-content.js
rename to chrome/content/aboutTor/aboutTor-content.js
diff --git a/src/chrome/content/aboutTor/aboutTor.xhtml b/chrome/content/aboutTor/aboutTor.xhtml
similarity index 100%
rename from src/chrome/content/aboutTor/aboutTor.xhtml
rename to chrome/content/aboutTor/aboutTor.xhtml
diff --git a/src/chrome/content/locale/non-localized.properties b/chrome/content/locale/non-localized.properties
similarity index 100%
rename from src/chrome/content/locale/non-localized.properties
rename to chrome/content/locale/non-localized.properties
diff --git a/src/chrome/content/menu-items-overlay.xul b/chrome/content/menu-items-overlay.xul
similarity index 100%
rename from src/chrome/content/menu-items-overlay.xul
rename to chrome/content/menu-items-overlay.xul
diff --git a/src/chrome/content/menu-overlay.xul b/chrome/content/menu-overlay.xul
similarity index 100%
rename from src/chrome/content/menu-overlay.xul
rename to chrome/content/menu-overlay.xul
diff --git a/src/chrome/content/preferences-mobile.js b/chrome/content/preferences-mobile.js
similarity index 100%
rename from src/chrome/content/preferences-mobile.js
rename to chrome/content/preferences-mobile.js
diff --git a/src/chrome/content/preferences.xhtml b/chrome/content/preferences.xhtml
similarity index 100%
rename from src/chrome/content/preferences.xhtml
rename to chrome/content/preferences.xhtml
diff --git a/src/chrome/content/tor-circuit-display.js b/chrome/content/tor-circuit-display.js
similarity index 100%
rename from src/chrome/content/tor-circuit-display.js
rename to chrome/content/tor-circuit-display.js
diff --git a/src/chrome/content/tor-circuit-display.xul b/chrome/content/tor-circuit-display.xul
similarity index 100%
rename from src/chrome/content/tor-circuit-display.xul
rename to chrome/content/tor-circuit-display.xul
diff --git a/src/chrome/content/torbutton-extensions.xul b/chrome/content/torbutton-extensions.xul
similarity index 100%
rename from src/chrome/content/torbutton-extensions.xul
rename to chrome/content/torbutton-extensions.xul
diff --git a/src/chrome/content/torbutton.js b/chrome/content/torbutton.js
similarity index 100%
rename from src/chrome/content/torbutton.js
rename to chrome/content/torbutton.js
diff --git a/src/chrome/content/torbutton.xul b/chrome/content/torbutton.xul
similarity index 100%
rename from src/chrome/content/torbutton.xul
rename to chrome/content/torbutton.xul
diff --git a/src/chrome/content/torbutton_util.js b/chrome/content/torbutton_util.js
similarity index 100%
rename from src/chrome/content/torbutton_util.js
rename to chrome/content/torbutton_util.js
diff --git a/src/chrome/locale/af/aboutTor.dtd b/chrome/locale/af/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/af/aboutTor.dtd
rename to chrome/locale/af/aboutTor.dtd
diff --git a/src/chrome/locale/af/brand.dtd b/chrome/locale/af/brand.dtd
similarity index 100%
rename from src/chrome/locale/af/brand.dtd
rename to chrome/locale/af/brand.dtd
diff --git a/src/chrome/locale/af/brand.properties b/chrome/locale/af/brand.properties
similarity index 100%
rename from src/chrome/locale/af/brand.properties
rename to chrome/locale/af/brand.properties
diff --git a/src/chrome/locale/af/torbutton.dtd b/chrome/locale/af/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/af/torbutton.dtd
rename to chrome/locale/af/torbutton.dtd
diff --git a/src/chrome/locale/af/torbutton.properties b/chrome/locale/af/torbutton.properties
similarity index 100%
rename from src/chrome/locale/af/torbutton.properties
rename to chrome/locale/af/torbutton.properties
diff --git a/src/chrome/locale/ak/aboutTor.dtd b/chrome/locale/ak/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/ak/aboutTor.dtd
rename to chrome/locale/ak/aboutTor.dtd
diff --git a/src/chrome/locale/ak/brand.dtd b/chrome/locale/ak/brand.dtd
similarity index 100%
rename from src/chrome/locale/ak/brand.dtd
rename to chrome/locale/ak/brand.dtd
diff --git a/src/chrome/locale/ak/brand.properties b/chrome/locale/ak/brand.properties
similarity index 100%
rename from src/chrome/locale/ak/brand.properties
rename to chrome/locale/ak/brand.properties
diff --git a/src/chrome/locale/ak/torbutton.dtd b/chrome/locale/ak/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/ak/torbutton.dtd
rename to chrome/locale/ak/torbutton.dtd
diff --git a/src/chrome/locale/ak/torbutton.properties b/chrome/locale/ak/torbutton.properties
similarity index 100%
rename from src/chrome/locale/ak/torbutton.properties
rename to chrome/locale/ak/torbutton.properties
diff --git a/src/chrome/locale/am/aboutTor.dtd b/chrome/locale/am/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/am/aboutTor.dtd
rename to chrome/locale/am/aboutTor.dtd
diff --git a/src/chrome/locale/am/brand.dtd b/chrome/locale/am/brand.dtd
similarity index 100%
rename from src/chrome/locale/am/brand.dtd
rename to chrome/locale/am/brand.dtd
diff --git a/src/chrome/locale/am/brand.properties b/chrome/locale/am/brand.properties
similarity index 100%
rename from src/chrome/locale/am/brand.properties
rename to chrome/locale/am/brand.properties
diff --git a/src/chrome/locale/am/torbutton.dtd b/chrome/locale/am/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/am/torbutton.dtd
rename to chrome/locale/am/torbutton.dtd
diff --git a/src/chrome/locale/am/torbutton.properties b/chrome/locale/am/torbutton.properties
similarity index 100%
rename from src/chrome/locale/am/torbutton.properties
rename to chrome/locale/am/torbutton.properties
diff --git a/src/chrome/locale/ar/aboutDialog.dtd b/chrome/locale/ar/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/ar/aboutDialog.dtd
rename to chrome/locale/ar/aboutDialog.dtd
diff --git a/src/chrome/locale/ar/aboutTBUpdate.dtd b/chrome/locale/ar/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/ar/aboutTBUpdate.dtd
rename to chrome/locale/ar/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/ar/aboutTor.dtd b/chrome/locale/ar/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/ar/aboutTor.dtd
rename to chrome/locale/ar/aboutTor.dtd
diff --git a/src/chrome/locale/ar/brand.dtd b/chrome/locale/ar/brand.dtd
similarity index 100%
rename from src/chrome/locale/ar/brand.dtd
rename to chrome/locale/ar/brand.dtd
diff --git a/src/chrome/locale/ar/brand.properties b/chrome/locale/ar/brand.properties
similarity index 100%
rename from src/chrome/locale/ar/brand.properties
rename to chrome/locale/ar/brand.properties
diff --git a/src/chrome/locale/ar/browserOnboarding.properties b/chrome/locale/ar/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/ar/browserOnboarding.properties
rename to chrome/locale/ar/browserOnboarding.properties
diff --git a/src/chrome/locale/ar/securityLevel.properties b/chrome/locale/ar/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/ar/securityLevel.properties
rename to chrome/locale/ar/securityLevel.properties
diff --git a/src/chrome/locale/ar/torbutton.dtd b/chrome/locale/ar/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/ar/torbutton.dtd
rename to chrome/locale/ar/torbutton.dtd
diff --git a/src/chrome/locale/ar/torbutton.properties b/chrome/locale/ar/torbutton.properties
similarity index 100%
rename from src/chrome/locale/ar/torbutton.properties
rename to chrome/locale/ar/torbutton.properties
diff --git a/src/chrome/locale/arn/aboutTor.dtd b/chrome/locale/arn/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/arn/aboutTor.dtd
rename to chrome/locale/arn/aboutTor.dtd
diff --git a/src/chrome/locale/arn/brand.dtd b/chrome/locale/arn/brand.dtd
similarity index 100%
rename from src/chrome/locale/arn/brand.dtd
rename to chrome/locale/arn/brand.dtd
diff --git a/src/chrome/locale/arn/brand.properties b/chrome/locale/arn/brand.properties
similarity index 100%
rename from src/chrome/locale/arn/brand.properties
rename to chrome/locale/arn/brand.properties
diff --git a/src/chrome/locale/arn/torbutton.dtd b/chrome/locale/arn/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/arn/torbutton.dtd
rename to chrome/locale/arn/torbutton.dtd
diff --git a/src/chrome/locale/arn/torbutton.properties b/chrome/locale/arn/torbutton.properties
similarity index 100%
rename from src/chrome/locale/arn/torbutton.properties
rename to chrome/locale/arn/torbutton.properties
diff --git a/src/chrome/locale/ast/aboutTor.dtd b/chrome/locale/ast/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/ast/aboutTor.dtd
rename to chrome/locale/ast/aboutTor.dtd
diff --git a/src/chrome/locale/ast/brand.dtd b/chrome/locale/ast/brand.dtd
similarity index 100%
rename from src/chrome/locale/ast/brand.dtd
rename to chrome/locale/ast/brand.dtd
diff --git a/src/chrome/locale/ast/brand.properties b/chrome/locale/ast/brand.properties
similarity index 100%
rename from src/chrome/locale/ast/brand.properties
rename to chrome/locale/ast/brand.properties
diff --git a/src/chrome/locale/ast/torbutton.dtd b/chrome/locale/ast/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/ast/torbutton.dtd
rename to chrome/locale/ast/torbutton.dtd
diff --git a/src/chrome/locale/ast/torbutton.properties b/chrome/locale/ast/torbutton.properties
similarity index 100%
rename from src/chrome/locale/ast/torbutton.properties
rename to chrome/locale/ast/torbutton.properties
diff --git a/src/chrome/locale/az/aboutTor.dtd b/chrome/locale/az/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/az/aboutTor.dtd
rename to chrome/locale/az/aboutTor.dtd
diff --git a/src/chrome/locale/az/brand.dtd b/chrome/locale/az/brand.dtd
similarity index 100%
rename from src/chrome/locale/az/brand.dtd
rename to chrome/locale/az/brand.dtd
diff --git a/src/chrome/locale/az/brand.properties b/chrome/locale/az/brand.properties
similarity index 100%
rename from src/chrome/locale/az/brand.properties
rename to chrome/locale/az/brand.properties
diff --git a/src/chrome/locale/az/securityLevel.properties b/chrome/locale/az/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/az/securityLevel.properties
rename to chrome/locale/az/securityLevel.properties
diff --git a/src/chrome/locale/az/torbutton.dtd b/chrome/locale/az/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/az/torbutton.dtd
rename to chrome/locale/az/torbutton.dtd
diff --git a/src/chrome/locale/az/torbutton.properties b/chrome/locale/az/torbutton.properties
similarity index 100%
rename from src/chrome/locale/az/torbutton.properties
rename to chrome/locale/az/torbutton.properties
diff --git a/src/chrome/locale/be/aboutTor.dtd b/chrome/locale/be/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/be/aboutTor.dtd
rename to chrome/locale/be/aboutTor.dtd
diff --git a/src/chrome/locale/be/brand.dtd b/chrome/locale/be/brand.dtd
similarity index 100%
rename from src/chrome/locale/be/brand.dtd
rename to chrome/locale/be/brand.dtd
diff --git a/src/chrome/locale/be/brand.properties b/chrome/locale/be/brand.properties
similarity index 100%
rename from src/chrome/locale/be/brand.properties
rename to chrome/locale/be/brand.properties
diff --git a/src/chrome/locale/be/torbutton.dtd b/chrome/locale/be/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/be/torbutton.dtd
rename to chrome/locale/be/torbutton.dtd
diff --git a/src/chrome/locale/be/torbutton.properties b/chrome/locale/be/torbutton.properties
similarity index 100%
rename from src/chrome/locale/be/torbutton.properties
rename to chrome/locale/be/torbutton.properties
diff --git a/src/chrome/locale/bg/aboutTor.dtd b/chrome/locale/bg/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/bg/aboutTor.dtd
rename to chrome/locale/bg/aboutTor.dtd
diff --git a/src/chrome/locale/bg/brand.dtd b/chrome/locale/bg/brand.dtd
similarity index 100%
rename from src/chrome/locale/bg/brand.dtd
rename to chrome/locale/bg/brand.dtd
diff --git a/src/chrome/locale/bg/brand.properties b/chrome/locale/bg/brand.properties
similarity index 100%
rename from src/chrome/locale/bg/brand.properties
rename to chrome/locale/bg/brand.properties
diff --git a/src/chrome/locale/bg/securityLevel.properties b/chrome/locale/bg/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/bg/securityLevel.properties
rename to chrome/locale/bg/securityLevel.properties
diff --git a/src/chrome/locale/bg/torbutton.dtd b/chrome/locale/bg/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/bg/torbutton.dtd
rename to chrome/locale/bg/torbutton.dtd
diff --git a/src/chrome/locale/bg/torbutton.properties b/chrome/locale/bg/torbutton.properties
similarity index 100%
rename from src/chrome/locale/bg/torbutton.properties
rename to chrome/locale/bg/torbutton.properties
diff --git a/src/chrome/locale/bms/aboutTor.dtd b/chrome/locale/bms/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/bms/aboutTor.dtd
rename to chrome/locale/bms/aboutTor.dtd
diff --git a/src/chrome/locale/bms/securityLevel.properties b/chrome/locale/bms/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/bms/securityLevel.properties
rename to chrome/locale/bms/securityLevel.properties
diff --git a/src/chrome/locale/bms/torbutton.dtd b/chrome/locale/bms/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/bms/torbutton.dtd
rename to chrome/locale/bms/torbutton.dtd
diff --git a/src/chrome/locale/bms/torbutton.properties b/chrome/locale/bms/torbutton.properties
similarity index 100%
rename from src/chrome/locale/bms/torbutton.properties
rename to chrome/locale/bms/torbutton.properties
diff --git a/src/chrome/locale/bn-BD/aboutDialog.dtd b/chrome/locale/bn-BD/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/bn-BD/aboutDialog.dtd
rename to chrome/locale/bn-BD/aboutDialog.dtd
diff --git a/src/chrome/locale/bn-BD/aboutTBUpdate.dtd b/chrome/locale/bn-BD/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/bn-BD/aboutTBUpdate.dtd
rename to chrome/locale/bn-BD/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/bn-BD/aboutTor.dtd b/chrome/locale/bn-BD/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/bn-BD/aboutTor.dtd
rename to chrome/locale/bn-BD/aboutTor.dtd
diff --git a/src/chrome/locale/bn-BD/brand.dtd b/chrome/locale/bn-BD/brand.dtd
similarity index 100%
rename from src/chrome/locale/bn-BD/brand.dtd
rename to chrome/locale/bn-BD/brand.dtd
diff --git a/src/chrome/locale/bn-BD/brand.properties b/chrome/locale/bn-BD/brand.properties
similarity index 100%
rename from src/chrome/locale/bn-BD/brand.properties
rename to chrome/locale/bn-BD/brand.properties
diff --git a/src/chrome/locale/bn-BD/browserOnboarding.properties b/chrome/locale/bn-BD/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/bn-BD/browserOnboarding.properties
rename to chrome/locale/bn-BD/browserOnboarding.properties
diff --git a/src/chrome/locale/bn-BD/securityLevel.properties b/chrome/locale/bn-BD/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/bn-BD/securityLevel.properties
rename to chrome/locale/bn-BD/securityLevel.properties
diff --git a/src/chrome/locale/bn-BD/torbutton.dtd b/chrome/locale/bn-BD/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/bn-BD/torbutton.dtd
rename to chrome/locale/bn-BD/torbutton.dtd
diff --git a/src/chrome/locale/bn-BD/torbutton.properties b/chrome/locale/bn-BD/torbutton.properties
similarity index 100%
rename from src/chrome/locale/bn-BD/torbutton.properties
rename to chrome/locale/bn-BD/torbutton.properties
diff --git a/src/chrome/locale/bn-IN/aboutTor.dtd b/chrome/locale/bn-IN/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/bn-IN/aboutTor.dtd
rename to chrome/locale/bn-IN/aboutTor.dtd
diff --git a/src/chrome/locale/bn-IN/brand.dtd b/chrome/locale/bn-IN/brand.dtd
similarity index 100%
rename from src/chrome/locale/bn-IN/brand.dtd
rename to chrome/locale/bn-IN/brand.dtd
diff --git a/src/chrome/locale/bn-IN/brand.properties b/chrome/locale/bn-IN/brand.properties
similarity index 100%
rename from src/chrome/locale/bn-IN/brand.properties
rename to chrome/locale/bn-IN/brand.properties
diff --git a/src/chrome/locale/bn-IN/torbutton.dtd b/chrome/locale/bn-IN/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/bn-IN/torbutton.dtd
rename to chrome/locale/bn-IN/torbutton.dtd
diff --git a/src/chrome/locale/bn-IN/torbutton.properties b/chrome/locale/bn-IN/torbutton.properties
similarity index 100%
rename from src/chrome/locale/bn-IN/torbutton.properties
rename to chrome/locale/bn-IN/torbutton.properties
diff --git a/src/chrome/locale/bn/aboutTor.dtd b/chrome/locale/bn/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/bn/aboutTor.dtd
rename to chrome/locale/bn/aboutTor.dtd
diff --git a/src/chrome/locale/bn/brand.dtd b/chrome/locale/bn/brand.dtd
similarity index 100%
rename from src/chrome/locale/bn/brand.dtd
rename to chrome/locale/bn/brand.dtd
diff --git a/src/chrome/locale/bn/brand.properties b/chrome/locale/bn/brand.properties
similarity index 100%
rename from src/chrome/locale/bn/brand.properties
rename to chrome/locale/bn/brand.properties
diff --git a/src/chrome/locale/bn/torbutton.dtd b/chrome/locale/bn/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/bn/torbutton.dtd
rename to chrome/locale/bn/torbutton.dtd
diff --git a/src/chrome/locale/bn/torbutton.properties b/chrome/locale/bn/torbutton.properties
similarity index 100%
rename from src/chrome/locale/bn/torbutton.properties
rename to chrome/locale/bn/torbutton.properties
diff --git a/src/chrome/locale/bo/aboutTor.dtd b/chrome/locale/bo/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/bo/aboutTor.dtd
rename to chrome/locale/bo/aboutTor.dtd
diff --git a/src/chrome/locale/bo/brand.dtd b/chrome/locale/bo/brand.dtd
similarity index 100%
rename from src/chrome/locale/bo/brand.dtd
rename to chrome/locale/bo/brand.dtd
diff --git a/src/chrome/locale/bo/brand.properties b/chrome/locale/bo/brand.properties
similarity index 100%
rename from src/chrome/locale/bo/brand.properties
rename to chrome/locale/bo/brand.properties
diff --git a/src/chrome/locale/bo/torbutton.dtd b/chrome/locale/bo/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/bo/torbutton.dtd
rename to chrome/locale/bo/torbutton.dtd
diff --git a/src/chrome/locale/bo/torbutton.properties b/chrome/locale/bo/torbutton.properties
similarity index 100%
rename from src/chrome/locale/bo/torbutton.properties
rename to chrome/locale/bo/torbutton.properties
diff --git a/src/chrome/locale/br/aboutTor.dtd b/chrome/locale/br/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/br/aboutTor.dtd
rename to chrome/locale/br/aboutTor.dtd
diff --git a/src/chrome/locale/br/brand.dtd b/chrome/locale/br/brand.dtd
similarity index 100%
rename from src/chrome/locale/br/brand.dtd
rename to chrome/locale/br/brand.dtd
diff --git a/src/chrome/locale/br/brand.properties b/chrome/locale/br/brand.properties
similarity index 100%
rename from src/chrome/locale/br/brand.properties
rename to chrome/locale/br/brand.properties
diff --git a/src/chrome/locale/br/torbutton.dtd b/chrome/locale/br/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/br/torbutton.dtd
rename to chrome/locale/br/torbutton.dtd
diff --git a/src/chrome/locale/br/torbutton.properties b/chrome/locale/br/torbutton.properties
similarity index 100%
rename from src/chrome/locale/br/torbutton.properties
rename to chrome/locale/br/torbutton.properties
diff --git a/src/chrome/locale/bs/aboutTor.dtd b/chrome/locale/bs/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/bs/aboutTor.dtd
rename to chrome/locale/bs/aboutTor.dtd
diff --git a/src/chrome/locale/bs/brand.dtd b/chrome/locale/bs/brand.dtd
similarity index 100%
rename from src/chrome/locale/bs/brand.dtd
rename to chrome/locale/bs/brand.dtd
diff --git a/src/chrome/locale/bs/brand.properties b/chrome/locale/bs/brand.properties
similarity index 100%
rename from src/chrome/locale/bs/brand.properties
rename to chrome/locale/bs/brand.properties
diff --git a/src/chrome/locale/bs/securityLevel.properties b/chrome/locale/bs/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/bs/securityLevel.properties
rename to chrome/locale/bs/securityLevel.properties
diff --git a/src/chrome/locale/bs/torbutton.dtd b/chrome/locale/bs/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/bs/torbutton.dtd
rename to chrome/locale/bs/torbutton.dtd
diff --git a/src/chrome/locale/bs/torbutton.properties b/chrome/locale/bs/torbutton.properties
similarity index 100%
rename from src/chrome/locale/bs/torbutton.properties
rename to chrome/locale/bs/torbutton.properties
diff --git a/src/chrome/locale/ca/aboutDialog.dtd b/chrome/locale/ca/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/ca/aboutDialog.dtd
rename to chrome/locale/ca/aboutDialog.dtd
diff --git a/src/chrome/locale/ca/aboutTBUpdate.dtd b/chrome/locale/ca/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/ca/aboutTBUpdate.dtd
rename to chrome/locale/ca/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/ca/aboutTor.dtd b/chrome/locale/ca/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/ca/aboutTor.dtd
rename to chrome/locale/ca/aboutTor.dtd
diff --git a/src/chrome/locale/ca/brand.dtd b/chrome/locale/ca/brand.dtd
similarity index 100%
rename from src/chrome/locale/ca/brand.dtd
rename to chrome/locale/ca/brand.dtd
diff --git a/src/chrome/locale/ca/brand.properties b/chrome/locale/ca/brand.properties
similarity index 100%
rename from src/chrome/locale/ca/brand.properties
rename to chrome/locale/ca/brand.properties
diff --git a/src/chrome/locale/ca/browserOnboarding.properties b/chrome/locale/ca/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/ca/browserOnboarding.properties
rename to chrome/locale/ca/browserOnboarding.properties
diff --git a/src/chrome/locale/ca/securityLevel.properties b/chrome/locale/ca/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/ca/securityLevel.properties
rename to chrome/locale/ca/securityLevel.properties
diff --git a/src/chrome/locale/ca/torbutton.dtd b/chrome/locale/ca/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/ca/torbutton.dtd
rename to chrome/locale/ca/torbutton.dtd
diff --git a/src/chrome/locale/ca/torbutton.properties b/chrome/locale/ca/torbutton.properties
similarity index 100%
rename from src/chrome/locale/ca/torbutton.properties
rename to chrome/locale/ca/torbutton.properties
diff --git a/src/chrome/locale/cs/aboutDialog.dtd b/chrome/locale/cs/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/cs/aboutDialog.dtd
rename to chrome/locale/cs/aboutDialog.dtd
diff --git a/src/chrome/locale/cs/aboutTBUpdate.dtd b/chrome/locale/cs/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/cs/aboutTBUpdate.dtd
rename to chrome/locale/cs/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/cs/aboutTor.dtd b/chrome/locale/cs/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/cs/aboutTor.dtd
rename to chrome/locale/cs/aboutTor.dtd
diff --git a/src/chrome/locale/cs/brand.dtd b/chrome/locale/cs/brand.dtd
similarity index 100%
rename from src/chrome/locale/cs/brand.dtd
rename to chrome/locale/cs/brand.dtd
diff --git a/src/chrome/locale/cs/brand.properties b/chrome/locale/cs/brand.properties
similarity index 100%
rename from src/chrome/locale/cs/brand.properties
rename to chrome/locale/cs/brand.properties
diff --git a/src/chrome/locale/cs/browserOnboarding.properties b/chrome/locale/cs/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/cs/browserOnboarding.properties
rename to chrome/locale/cs/browserOnboarding.properties
diff --git a/src/chrome/locale/cs/securityLevel.properties b/chrome/locale/cs/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/cs/securityLevel.properties
rename to chrome/locale/cs/securityLevel.properties
diff --git a/src/chrome/locale/cs/torbutton.dtd b/chrome/locale/cs/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/cs/torbutton.dtd
rename to chrome/locale/cs/torbutton.dtd
diff --git a/src/chrome/locale/cs/torbutton.properties b/chrome/locale/cs/torbutton.properties
similarity index 100%
rename from src/chrome/locale/cs/torbutton.properties
rename to chrome/locale/cs/torbutton.properties
diff --git a/src/chrome/locale/csb/aboutTor.dtd b/chrome/locale/csb/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/csb/aboutTor.dtd
rename to chrome/locale/csb/aboutTor.dtd
diff --git a/src/chrome/locale/csb/brand.dtd b/chrome/locale/csb/brand.dtd
similarity index 100%
rename from src/chrome/locale/csb/brand.dtd
rename to chrome/locale/csb/brand.dtd
diff --git a/src/chrome/locale/csb/brand.properties b/chrome/locale/csb/brand.properties
similarity index 100%
rename from src/chrome/locale/csb/brand.properties
rename to chrome/locale/csb/brand.properties
diff --git a/src/chrome/locale/csb/torbutton.dtd b/chrome/locale/csb/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/csb/torbutton.dtd
rename to chrome/locale/csb/torbutton.dtd
diff --git a/src/chrome/locale/csb/torbutton.properties b/chrome/locale/csb/torbutton.properties
similarity index 100%
rename from src/chrome/locale/csb/torbutton.properties
rename to chrome/locale/csb/torbutton.properties
diff --git a/src/chrome/locale/cy/aboutTor.dtd b/chrome/locale/cy/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/cy/aboutTor.dtd
rename to chrome/locale/cy/aboutTor.dtd
diff --git a/src/chrome/locale/cy/brand.dtd b/chrome/locale/cy/brand.dtd
similarity index 100%
rename from src/chrome/locale/cy/brand.dtd
rename to chrome/locale/cy/brand.dtd
diff --git a/src/chrome/locale/cy/brand.properties b/chrome/locale/cy/brand.properties
similarity index 100%
rename from src/chrome/locale/cy/brand.properties
rename to chrome/locale/cy/brand.properties
diff --git a/src/chrome/locale/cy/torbutton.dtd b/chrome/locale/cy/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/cy/torbutton.dtd
rename to chrome/locale/cy/torbutton.dtd
diff --git a/src/chrome/locale/cy/torbutton.properties b/chrome/locale/cy/torbutton.properties
similarity index 100%
rename from src/chrome/locale/cy/torbutton.properties
rename to chrome/locale/cy/torbutton.properties
diff --git a/src/chrome/locale/da/aboutDialog.dtd b/chrome/locale/da/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/da/aboutDialog.dtd
rename to chrome/locale/da/aboutDialog.dtd
diff --git a/src/chrome/locale/da/aboutTBUpdate.dtd b/chrome/locale/da/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/da/aboutTBUpdate.dtd
rename to chrome/locale/da/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/da/aboutTor.dtd b/chrome/locale/da/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/da/aboutTor.dtd
rename to chrome/locale/da/aboutTor.dtd
diff --git a/src/chrome/locale/da/brand.dtd b/chrome/locale/da/brand.dtd
similarity index 100%
rename from src/chrome/locale/da/brand.dtd
rename to chrome/locale/da/brand.dtd
diff --git a/src/chrome/locale/da/brand.properties b/chrome/locale/da/brand.properties
similarity index 100%
rename from src/chrome/locale/da/brand.properties
rename to chrome/locale/da/brand.properties
diff --git a/src/chrome/locale/da/browserOnboarding.properties b/chrome/locale/da/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/da/browserOnboarding.properties
rename to chrome/locale/da/browserOnboarding.properties
diff --git a/src/chrome/locale/da/securityLevel.properties b/chrome/locale/da/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/da/securityLevel.properties
rename to chrome/locale/da/securityLevel.properties
diff --git a/src/chrome/locale/da/torbutton.dtd b/chrome/locale/da/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/da/torbutton.dtd
rename to chrome/locale/da/torbutton.dtd
diff --git a/src/chrome/locale/da/torbutton.properties b/chrome/locale/da/torbutton.properties
similarity index 100%
rename from src/chrome/locale/da/torbutton.properties
rename to chrome/locale/da/torbutton.properties
diff --git a/src/chrome/locale/de/aboutDialog.dtd b/chrome/locale/de/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/de/aboutDialog.dtd
rename to chrome/locale/de/aboutDialog.dtd
diff --git a/src/chrome/locale/de/aboutTBUpdate.dtd b/chrome/locale/de/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/de/aboutTBUpdate.dtd
rename to chrome/locale/de/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/de/aboutTor.dtd b/chrome/locale/de/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/de/aboutTor.dtd
rename to chrome/locale/de/aboutTor.dtd
diff --git a/src/chrome/locale/de/brand.dtd b/chrome/locale/de/brand.dtd
similarity index 100%
rename from src/chrome/locale/de/brand.dtd
rename to chrome/locale/de/brand.dtd
diff --git a/src/chrome/locale/de/brand.properties b/chrome/locale/de/brand.properties
similarity index 100%
rename from src/chrome/locale/de/brand.properties
rename to chrome/locale/de/brand.properties
diff --git a/src/chrome/locale/de/browserOnboarding.properties b/chrome/locale/de/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/de/browserOnboarding.properties
rename to chrome/locale/de/browserOnboarding.properties
diff --git a/src/chrome/locale/de/securityLevel.properties b/chrome/locale/de/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/de/securityLevel.properties
rename to chrome/locale/de/securityLevel.properties
diff --git a/src/chrome/locale/de/torbutton.dtd b/chrome/locale/de/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/de/torbutton.dtd
rename to chrome/locale/de/torbutton.dtd
diff --git a/src/chrome/locale/de/torbutton.properties b/chrome/locale/de/torbutton.properties
similarity index 100%
rename from src/chrome/locale/de/torbutton.properties
rename to chrome/locale/de/torbutton.properties
diff --git a/src/chrome/locale/dz/aboutTor.dtd b/chrome/locale/dz/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/dz/aboutTor.dtd
rename to chrome/locale/dz/aboutTor.dtd
diff --git a/src/chrome/locale/dz/brand.dtd b/chrome/locale/dz/brand.dtd
similarity index 100%
rename from src/chrome/locale/dz/brand.dtd
rename to chrome/locale/dz/brand.dtd
diff --git a/src/chrome/locale/dz/brand.properties b/chrome/locale/dz/brand.properties
similarity index 100%
rename from src/chrome/locale/dz/brand.properties
rename to chrome/locale/dz/brand.properties
diff --git a/src/chrome/locale/dz/torbutton.dtd b/chrome/locale/dz/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/dz/torbutton.dtd
rename to chrome/locale/dz/torbutton.dtd
diff --git a/src/chrome/locale/dz/torbutton.properties b/chrome/locale/dz/torbutton.properties
similarity index 100%
rename from src/chrome/locale/dz/torbutton.properties
rename to chrome/locale/dz/torbutton.properties
diff --git a/src/chrome/locale/el/aboutDialog.dtd b/chrome/locale/el/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/el/aboutDialog.dtd
rename to chrome/locale/el/aboutDialog.dtd
diff --git a/src/chrome/locale/el/aboutTBUpdate.dtd b/chrome/locale/el/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/el/aboutTBUpdate.dtd
rename to chrome/locale/el/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/el/aboutTor.dtd b/chrome/locale/el/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/el/aboutTor.dtd
rename to chrome/locale/el/aboutTor.dtd
diff --git a/src/chrome/locale/el/brand.dtd b/chrome/locale/el/brand.dtd
similarity index 100%
rename from src/chrome/locale/el/brand.dtd
rename to chrome/locale/el/brand.dtd
diff --git a/src/chrome/locale/el/brand.properties b/chrome/locale/el/brand.properties
similarity index 100%
rename from src/chrome/locale/el/brand.properties
rename to chrome/locale/el/brand.properties
diff --git a/src/chrome/locale/el/browserOnboarding.properties b/chrome/locale/el/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/el/browserOnboarding.properties
rename to chrome/locale/el/browserOnboarding.properties
diff --git a/src/chrome/locale/el/securityLevel.properties b/chrome/locale/el/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/el/securityLevel.properties
rename to chrome/locale/el/securityLevel.properties
diff --git a/src/chrome/locale/el/torbutton.dtd b/chrome/locale/el/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/el/torbutton.dtd
rename to chrome/locale/el/torbutton.dtd
diff --git a/src/chrome/locale/el/torbutton.properties b/chrome/locale/el/torbutton.properties
similarity index 100%
rename from src/chrome/locale/el/torbutton.properties
rename to chrome/locale/el/torbutton.properties
diff --git a/src/chrome/locale/en-US/aboutDialog.dtd b/chrome/locale/en-US/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/en-US/aboutDialog.dtd
rename to chrome/locale/en-US/aboutDialog.dtd
diff --git a/src/chrome/locale/en-US/aboutTBUpdate.dtd b/chrome/locale/en-US/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/en-US/aboutTBUpdate.dtd
rename to chrome/locale/en-US/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/en-US/aboutTor.dtd b/chrome/locale/en-US/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/en-US/aboutTor.dtd
rename to chrome/locale/en-US/aboutTor.dtd
diff --git a/src/chrome/locale/en-US/brand.dtd b/chrome/locale/en-US/brand.dtd
similarity index 100%
rename from src/chrome/locale/en-US/brand.dtd
rename to chrome/locale/en-US/brand.dtd
diff --git a/src/chrome/locale/en-US/brand.properties b/chrome/locale/en-US/brand.properties
similarity index 100%
rename from src/chrome/locale/en-US/brand.properties
rename to chrome/locale/en-US/brand.properties
diff --git a/src/chrome/locale/en-US/browserOnboarding.properties b/chrome/locale/en-US/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/en-US/browserOnboarding.properties
rename to chrome/locale/en-US/browserOnboarding.properties
diff --git a/src/chrome/locale/en-US/securityLevel.properties b/chrome/locale/en-US/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/en-US/securityLevel.properties
rename to chrome/locale/en-US/securityLevel.properties
diff --git a/src/chrome/locale/en-US/torbutton.dtd b/chrome/locale/en-US/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/en-US/torbutton.dtd
rename to chrome/locale/en-US/torbutton.dtd
diff --git a/src/chrome/locale/en-US/torbutton.properties b/chrome/locale/en-US/torbutton.properties
similarity index 100%
rename from src/chrome/locale/en-US/torbutton.properties
rename to chrome/locale/en-US/torbutton.properties
diff --git a/src/chrome/locale/eo/aboutTor.dtd b/chrome/locale/eo/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/eo/aboutTor.dtd
rename to chrome/locale/eo/aboutTor.dtd
diff --git a/src/chrome/locale/eo/brand.dtd b/chrome/locale/eo/brand.dtd
similarity index 100%
rename from src/chrome/locale/eo/brand.dtd
rename to chrome/locale/eo/brand.dtd
diff --git a/src/chrome/locale/eo/brand.properties b/chrome/locale/eo/brand.properties
similarity index 100%
rename from src/chrome/locale/eo/brand.properties
rename to chrome/locale/eo/brand.properties
diff --git a/src/chrome/locale/eo/securityLevel.properties b/chrome/locale/eo/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/eo/securityLevel.properties
rename to chrome/locale/eo/securityLevel.properties
diff --git a/src/chrome/locale/eo/torbutton.dtd b/chrome/locale/eo/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/eo/torbutton.dtd
rename to chrome/locale/eo/torbutton.dtd
diff --git a/src/chrome/locale/eo/torbutton.properties b/chrome/locale/eo/torbutton.properties
similarity index 100%
rename from src/chrome/locale/eo/torbutton.properties
rename to chrome/locale/eo/torbutton.properties
diff --git a/src/chrome/locale/es-AR/aboutDialog.dtd b/chrome/locale/es-AR/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/es-AR/aboutDialog.dtd
rename to chrome/locale/es-AR/aboutDialog.dtd
diff --git a/src/chrome/locale/es-AR/aboutTBUpdate.dtd b/chrome/locale/es-AR/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/es-AR/aboutTBUpdate.dtd
rename to chrome/locale/es-AR/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/es-AR/aboutTor.dtd b/chrome/locale/es-AR/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/es-AR/aboutTor.dtd
rename to chrome/locale/es-AR/aboutTor.dtd
diff --git a/src/chrome/locale/es-AR/brand.dtd b/chrome/locale/es-AR/brand.dtd
similarity index 100%
rename from src/chrome/locale/es-AR/brand.dtd
rename to chrome/locale/es-AR/brand.dtd
diff --git a/src/chrome/locale/es-AR/brand.properties b/chrome/locale/es-AR/brand.properties
similarity index 100%
rename from src/chrome/locale/es-AR/brand.properties
rename to chrome/locale/es-AR/brand.properties
diff --git a/src/chrome/locale/es-AR/browserOnboarding.properties b/chrome/locale/es-AR/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/es-AR/browserOnboarding.properties
rename to chrome/locale/es-AR/browserOnboarding.properties
diff --git a/src/chrome/locale/es-AR/securityLevel.properties b/chrome/locale/es-AR/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/es-AR/securityLevel.properties
rename to chrome/locale/es-AR/securityLevel.properties
diff --git a/src/chrome/locale/es-AR/torbutton.dtd b/chrome/locale/es-AR/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/es-AR/torbutton.dtd
rename to chrome/locale/es-AR/torbutton.dtd
diff --git a/src/chrome/locale/es-AR/torbutton.properties b/chrome/locale/es-AR/torbutton.properties
similarity index 100%
rename from src/chrome/locale/es-AR/torbutton.properties
rename to chrome/locale/es-AR/torbutton.properties
diff --git a/src/chrome/locale/es-ES/aboutDialog.dtd b/chrome/locale/es-ES/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/es-ES/aboutDialog.dtd
rename to chrome/locale/es-ES/aboutDialog.dtd
diff --git a/src/chrome/locale/es-ES/aboutTBUpdate.dtd b/chrome/locale/es-ES/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/es-ES/aboutTBUpdate.dtd
rename to chrome/locale/es-ES/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/es-ES/aboutTor.dtd b/chrome/locale/es-ES/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/es-ES/aboutTor.dtd
rename to chrome/locale/es-ES/aboutTor.dtd
diff --git a/src/chrome/locale/es-ES/brand.dtd b/chrome/locale/es-ES/brand.dtd
similarity index 100%
rename from src/chrome/locale/es-ES/brand.dtd
rename to chrome/locale/es-ES/brand.dtd
diff --git a/src/chrome/locale/es-ES/brand.properties b/chrome/locale/es-ES/brand.properties
similarity index 100%
rename from src/chrome/locale/es-ES/brand.properties
rename to chrome/locale/es-ES/brand.properties
diff --git a/src/chrome/locale/es-ES/browserOnboarding.properties b/chrome/locale/es-ES/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/es-ES/browserOnboarding.properties
rename to chrome/locale/es-ES/browserOnboarding.properties
diff --git a/src/chrome/locale/es-ES/securityLevel.properties b/chrome/locale/es-ES/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/es-ES/securityLevel.properties
rename to chrome/locale/es-ES/securityLevel.properties
diff --git a/src/chrome/locale/es-ES/torbutton.dtd b/chrome/locale/es-ES/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/es-ES/torbutton.dtd
rename to chrome/locale/es-ES/torbutton.dtd
diff --git a/src/chrome/locale/es-ES/torbutton.properties b/chrome/locale/es-ES/torbutton.properties
similarity index 100%
rename from src/chrome/locale/es-ES/torbutton.properties
rename to chrome/locale/es-ES/torbutton.properties
diff --git a/src/chrome/locale/et/aboutTor.dtd b/chrome/locale/et/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/et/aboutTor.dtd
rename to chrome/locale/et/aboutTor.dtd
diff --git a/src/chrome/locale/et/brand.dtd b/chrome/locale/et/brand.dtd
similarity index 100%
rename from src/chrome/locale/et/brand.dtd
rename to chrome/locale/et/brand.dtd
diff --git a/src/chrome/locale/et/brand.properties b/chrome/locale/et/brand.properties
similarity index 100%
rename from src/chrome/locale/et/brand.properties
rename to chrome/locale/et/brand.properties
diff --git a/src/chrome/locale/et/torbutton.dtd b/chrome/locale/et/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/et/torbutton.dtd
rename to chrome/locale/et/torbutton.dtd
diff --git a/src/chrome/locale/et/torbutton.properties b/chrome/locale/et/torbutton.properties
similarity index 100%
rename from src/chrome/locale/et/torbutton.properties
rename to chrome/locale/et/torbutton.properties
diff --git a/src/chrome/locale/eu/aboutDialog.dtd b/chrome/locale/eu/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/eu/aboutDialog.dtd
rename to chrome/locale/eu/aboutDialog.dtd
diff --git a/src/chrome/locale/eu/aboutTBUpdate.dtd b/chrome/locale/eu/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/eu/aboutTBUpdate.dtd
rename to chrome/locale/eu/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/eu/aboutTor.dtd b/chrome/locale/eu/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/eu/aboutTor.dtd
rename to chrome/locale/eu/aboutTor.dtd
diff --git a/src/chrome/locale/eu/brand.dtd b/chrome/locale/eu/brand.dtd
similarity index 100%
rename from src/chrome/locale/eu/brand.dtd
rename to chrome/locale/eu/brand.dtd
diff --git a/src/chrome/locale/eu/brand.properties b/chrome/locale/eu/brand.properties
similarity index 100%
rename from src/chrome/locale/eu/brand.properties
rename to chrome/locale/eu/brand.properties
diff --git a/src/chrome/locale/eu/browserOnboarding.properties b/chrome/locale/eu/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/eu/browserOnboarding.properties
rename to chrome/locale/eu/browserOnboarding.properties
diff --git a/src/chrome/locale/eu/securityLevel.properties b/chrome/locale/eu/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/eu/securityLevel.properties
rename to chrome/locale/eu/securityLevel.properties
diff --git a/src/chrome/locale/eu/torbutton.dtd b/chrome/locale/eu/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/eu/torbutton.dtd
rename to chrome/locale/eu/torbutton.dtd
diff --git a/src/chrome/locale/eu/torbutton.properties b/chrome/locale/eu/torbutton.properties
similarity index 100%
rename from src/chrome/locale/eu/torbutton.properties
rename to chrome/locale/eu/torbutton.properties
diff --git a/src/chrome/locale/fa/aboutDialog.dtd b/chrome/locale/fa/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/fa/aboutDialog.dtd
rename to chrome/locale/fa/aboutDialog.dtd
diff --git a/src/chrome/locale/fa/aboutTBUpdate.dtd b/chrome/locale/fa/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/fa/aboutTBUpdate.dtd
rename to chrome/locale/fa/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/fa/aboutTor.dtd b/chrome/locale/fa/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/fa/aboutTor.dtd
rename to chrome/locale/fa/aboutTor.dtd
diff --git a/src/chrome/locale/fa/brand.dtd b/chrome/locale/fa/brand.dtd
similarity index 100%
rename from src/chrome/locale/fa/brand.dtd
rename to chrome/locale/fa/brand.dtd
diff --git a/src/chrome/locale/fa/brand.properties b/chrome/locale/fa/brand.properties
similarity index 100%
rename from src/chrome/locale/fa/brand.properties
rename to chrome/locale/fa/brand.properties
diff --git a/src/chrome/locale/fa/browserOnboarding.properties b/chrome/locale/fa/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/fa/browserOnboarding.properties
rename to chrome/locale/fa/browserOnboarding.properties
diff --git a/src/chrome/locale/fa/securityLevel.properties b/chrome/locale/fa/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/fa/securityLevel.properties
rename to chrome/locale/fa/securityLevel.properties
diff --git a/src/chrome/locale/fa/torbutton.dtd b/chrome/locale/fa/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/fa/torbutton.dtd
rename to chrome/locale/fa/torbutton.dtd
diff --git a/src/chrome/locale/fa/torbutton.properties b/chrome/locale/fa/torbutton.properties
similarity index 100%
rename from src/chrome/locale/fa/torbutton.properties
rename to chrome/locale/fa/torbutton.properties
diff --git a/src/chrome/locale/fi/aboutTor.dtd b/chrome/locale/fi/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/fi/aboutTor.dtd
rename to chrome/locale/fi/aboutTor.dtd
diff --git a/src/chrome/locale/fi/brand.dtd b/chrome/locale/fi/brand.dtd
similarity index 100%
rename from src/chrome/locale/fi/brand.dtd
rename to chrome/locale/fi/brand.dtd
diff --git a/src/chrome/locale/fi/brand.properties b/chrome/locale/fi/brand.properties
similarity index 100%
rename from src/chrome/locale/fi/brand.properties
rename to chrome/locale/fi/brand.properties
diff --git a/src/chrome/locale/fi/securityLevel.properties b/chrome/locale/fi/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/fi/securityLevel.properties
rename to chrome/locale/fi/securityLevel.properties
diff --git a/src/chrome/locale/fi/torbutton.dtd b/chrome/locale/fi/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/fi/torbutton.dtd
rename to chrome/locale/fi/torbutton.dtd
diff --git a/src/chrome/locale/fi/torbutton.properties b/chrome/locale/fi/torbutton.properties
similarity index 100%
rename from src/chrome/locale/fi/torbutton.properties
rename to chrome/locale/fi/torbutton.properties
diff --git a/src/chrome/locale/fil/aboutTor.dtd b/chrome/locale/fil/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/fil/aboutTor.dtd
rename to chrome/locale/fil/aboutTor.dtd
diff --git a/src/chrome/locale/fil/brand.dtd b/chrome/locale/fil/brand.dtd
similarity index 100%
rename from src/chrome/locale/fil/brand.dtd
rename to chrome/locale/fil/brand.dtd
diff --git a/src/chrome/locale/fil/brand.properties b/chrome/locale/fil/brand.properties
similarity index 100%
rename from src/chrome/locale/fil/brand.properties
rename to chrome/locale/fil/brand.properties
diff --git a/src/chrome/locale/fil/torbutton.dtd b/chrome/locale/fil/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/fil/torbutton.dtd
rename to chrome/locale/fil/torbutton.dtd
diff --git a/src/chrome/locale/fil/torbutton.properties b/chrome/locale/fil/torbutton.properties
similarity index 100%
rename from src/chrome/locale/fil/torbutton.properties
rename to chrome/locale/fil/torbutton.properties
diff --git a/src/chrome/locale/fo/aboutTor.dtd b/chrome/locale/fo/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/fo/aboutTor.dtd
rename to chrome/locale/fo/aboutTor.dtd
diff --git a/src/chrome/locale/fo/brand.dtd b/chrome/locale/fo/brand.dtd
similarity index 100%
rename from src/chrome/locale/fo/brand.dtd
rename to chrome/locale/fo/brand.dtd
diff --git a/src/chrome/locale/fo/brand.properties b/chrome/locale/fo/brand.properties
similarity index 100%
rename from src/chrome/locale/fo/brand.properties
rename to chrome/locale/fo/brand.properties
diff --git a/src/chrome/locale/fo/torbutton.dtd b/chrome/locale/fo/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/fo/torbutton.dtd
rename to chrome/locale/fo/torbutton.dtd
diff --git a/src/chrome/locale/fo/torbutton.properties b/chrome/locale/fo/torbutton.properties
similarity index 100%
rename from src/chrome/locale/fo/torbutton.properties
rename to chrome/locale/fo/torbutton.properties
diff --git a/src/chrome/locale/fr/aboutDialog.dtd b/chrome/locale/fr/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/fr/aboutDialog.dtd
rename to chrome/locale/fr/aboutDialog.dtd
diff --git a/src/chrome/locale/fr/aboutTBUpdate.dtd b/chrome/locale/fr/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/fr/aboutTBUpdate.dtd
rename to chrome/locale/fr/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/fr/aboutTor.dtd b/chrome/locale/fr/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/fr/aboutTor.dtd
rename to chrome/locale/fr/aboutTor.dtd
diff --git a/src/chrome/locale/fr/brand.dtd b/chrome/locale/fr/brand.dtd
similarity index 100%
rename from src/chrome/locale/fr/brand.dtd
rename to chrome/locale/fr/brand.dtd
diff --git a/src/chrome/locale/fr/brand.properties b/chrome/locale/fr/brand.properties
similarity index 100%
rename from src/chrome/locale/fr/brand.properties
rename to chrome/locale/fr/brand.properties
diff --git a/src/chrome/locale/fr/browserOnboarding.properties b/chrome/locale/fr/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/fr/browserOnboarding.properties
rename to chrome/locale/fr/browserOnboarding.properties
diff --git a/src/chrome/locale/fr/securityLevel.properties b/chrome/locale/fr/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/fr/securityLevel.properties
rename to chrome/locale/fr/securityLevel.properties
diff --git a/src/chrome/locale/fr/torbutton.dtd b/chrome/locale/fr/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/fr/torbutton.dtd
rename to chrome/locale/fr/torbutton.dtd
diff --git a/src/chrome/locale/fr/torbutton.properties b/chrome/locale/fr/torbutton.properties
similarity index 100%
rename from src/chrome/locale/fr/torbutton.properties
rename to chrome/locale/fr/torbutton.properties
diff --git a/src/chrome/locale/fur/aboutTor.dtd b/chrome/locale/fur/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/fur/aboutTor.dtd
rename to chrome/locale/fur/aboutTor.dtd
diff --git a/src/chrome/locale/fur/brand.dtd b/chrome/locale/fur/brand.dtd
similarity index 100%
rename from src/chrome/locale/fur/brand.dtd
rename to chrome/locale/fur/brand.dtd
diff --git a/src/chrome/locale/fur/brand.properties b/chrome/locale/fur/brand.properties
similarity index 100%
rename from src/chrome/locale/fur/brand.properties
rename to chrome/locale/fur/brand.properties
diff --git a/src/chrome/locale/fur/torbutton.dtd b/chrome/locale/fur/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/fur/torbutton.dtd
rename to chrome/locale/fur/torbutton.dtd
diff --git a/src/chrome/locale/fur/torbutton.properties b/chrome/locale/fur/torbutton.properties
similarity index 100%
rename from src/chrome/locale/fur/torbutton.properties
rename to chrome/locale/fur/torbutton.properties
diff --git a/src/chrome/locale/fy/aboutTor.dtd b/chrome/locale/fy/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/fy/aboutTor.dtd
rename to chrome/locale/fy/aboutTor.dtd
diff --git a/src/chrome/locale/fy/brand.dtd b/chrome/locale/fy/brand.dtd
similarity index 100%
rename from src/chrome/locale/fy/brand.dtd
rename to chrome/locale/fy/brand.dtd
diff --git a/src/chrome/locale/fy/brand.properties b/chrome/locale/fy/brand.properties
similarity index 100%
rename from src/chrome/locale/fy/brand.properties
rename to chrome/locale/fy/brand.properties
diff --git a/src/chrome/locale/fy/torbutton.dtd b/chrome/locale/fy/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/fy/torbutton.dtd
rename to chrome/locale/fy/torbutton.dtd
diff --git a/src/chrome/locale/fy/torbutton.properties b/chrome/locale/fy/torbutton.properties
similarity index 100%
rename from src/chrome/locale/fy/torbutton.properties
rename to chrome/locale/fy/torbutton.properties
diff --git a/src/chrome/locale/ga-IE/aboutDialog.dtd b/chrome/locale/ga-IE/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/ga-IE/aboutDialog.dtd
rename to chrome/locale/ga-IE/aboutDialog.dtd
diff --git a/src/chrome/locale/ga-IE/aboutTBUpdate.dtd b/chrome/locale/ga-IE/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/ga-IE/aboutTBUpdate.dtd
rename to chrome/locale/ga-IE/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/ga-IE/aboutTor.dtd b/chrome/locale/ga-IE/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/ga-IE/aboutTor.dtd
rename to chrome/locale/ga-IE/aboutTor.dtd
diff --git a/src/chrome/locale/ga-IE/brand.dtd b/chrome/locale/ga-IE/brand.dtd
similarity index 100%
rename from src/chrome/locale/ga-IE/brand.dtd
rename to chrome/locale/ga-IE/brand.dtd
diff --git a/src/chrome/locale/ga-IE/brand.properties b/chrome/locale/ga-IE/brand.properties
similarity index 100%
rename from src/chrome/locale/ga-IE/brand.properties
rename to chrome/locale/ga-IE/brand.properties
diff --git a/src/chrome/locale/ga-IE/browserOnboarding.properties b/chrome/locale/ga-IE/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/ga-IE/browserOnboarding.properties
rename to chrome/locale/ga-IE/browserOnboarding.properties
diff --git a/src/chrome/locale/ga-IE/securityLevel.properties b/chrome/locale/ga-IE/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/ga-IE/securityLevel.properties
rename to chrome/locale/ga-IE/securityLevel.properties
diff --git a/src/chrome/locale/ga-IE/torbutton.dtd b/chrome/locale/ga-IE/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/ga-IE/torbutton.dtd
rename to chrome/locale/ga-IE/torbutton.dtd
diff --git a/src/chrome/locale/ga-IE/torbutton.properties b/chrome/locale/ga-IE/torbutton.properties
similarity index 100%
rename from src/chrome/locale/ga-IE/torbutton.properties
rename to chrome/locale/ga-IE/torbutton.properties
diff --git a/src/chrome/locale/gl/aboutTor.dtd b/chrome/locale/gl/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/gl/aboutTor.dtd
rename to chrome/locale/gl/aboutTor.dtd
diff --git a/src/chrome/locale/gl/brand.dtd b/chrome/locale/gl/brand.dtd
similarity index 100%
rename from src/chrome/locale/gl/brand.dtd
rename to chrome/locale/gl/brand.dtd
diff --git a/src/chrome/locale/gl/brand.properties b/chrome/locale/gl/brand.properties
similarity index 100%
rename from src/chrome/locale/gl/brand.properties
rename to chrome/locale/gl/brand.properties
diff --git a/src/chrome/locale/gl/securityLevel.properties b/chrome/locale/gl/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/gl/securityLevel.properties
rename to chrome/locale/gl/securityLevel.properties
diff --git a/src/chrome/locale/gl/torbutton.dtd b/chrome/locale/gl/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/gl/torbutton.dtd
rename to chrome/locale/gl/torbutton.dtd
diff --git a/src/chrome/locale/gl/torbutton.properties b/chrome/locale/gl/torbutton.properties
similarity index 100%
rename from src/chrome/locale/gl/torbutton.properties
rename to chrome/locale/gl/torbutton.properties
diff --git a/src/chrome/locale/gu/aboutTor.dtd b/chrome/locale/gu/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/gu/aboutTor.dtd
rename to chrome/locale/gu/aboutTor.dtd
diff --git a/src/chrome/locale/gu/brand.dtd b/chrome/locale/gu/brand.dtd
similarity index 100%
rename from src/chrome/locale/gu/brand.dtd
rename to chrome/locale/gu/brand.dtd
diff --git a/src/chrome/locale/gu/brand.properties b/chrome/locale/gu/brand.properties
similarity index 100%
rename from src/chrome/locale/gu/brand.properties
rename to chrome/locale/gu/brand.properties
diff --git a/src/chrome/locale/gu/securityLevel.properties b/chrome/locale/gu/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/gu/securityLevel.properties
rename to chrome/locale/gu/securityLevel.properties
diff --git a/src/chrome/locale/gu/torbutton.dtd b/chrome/locale/gu/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/gu/torbutton.dtd
rename to chrome/locale/gu/torbutton.dtd
diff --git a/src/chrome/locale/gu/torbutton.properties b/chrome/locale/gu/torbutton.properties
similarity index 100%
rename from src/chrome/locale/gu/torbutton.properties
rename to chrome/locale/gu/torbutton.properties
diff --git a/src/chrome/locale/gun/aboutTor.dtd b/chrome/locale/gun/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/gun/aboutTor.dtd
rename to chrome/locale/gun/aboutTor.dtd
diff --git a/src/chrome/locale/gun/brand.dtd b/chrome/locale/gun/brand.dtd
similarity index 100%
rename from src/chrome/locale/gun/brand.dtd
rename to chrome/locale/gun/brand.dtd
diff --git a/src/chrome/locale/gun/brand.properties b/chrome/locale/gun/brand.properties
similarity index 100%
rename from src/chrome/locale/gun/brand.properties
rename to chrome/locale/gun/brand.properties
diff --git a/src/chrome/locale/gun/torbutton.dtd b/chrome/locale/gun/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/gun/torbutton.dtd
rename to chrome/locale/gun/torbutton.dtd
diff --git a/src/chrome/locale/gun/torbutton.properties b/chrome/locale/gun/torbutton.properties
similarity index 100%
rename from src/chrome/locale/gun/torbutton.properties
rename to chrome/locale/gun/torbutton.properties
diff --git a/src/chrome/locale/ha/aboutTor.dtd b/chrome/locale/ha/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/ha/aboutTor.dtd
rename to chrome/locale/ha/aboutTor.dtd
diff --git a/src/chrome/locale/ha/brand.dtd b/chrome/locale/ha/brand.dtd
similarity index 100%
rename from src/chrome/locale/ha/brand.dtd
rename to chrome/locale/ha/brand.dtd
diff --git a/src/chrome/locale/ha/brand.properties b/chrome/locale/ha/brand.properties
similarity index 100%
rename from src/chrome/locale/ha/brand.properties
rename to chrome/locale/ha/brand.properties
diff --git a/src/chrome/locale/ha/torbutton.dtd b/chrome/locale/ha/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/ha/torbutton.dtd
rename to chrome/locale/ha/torbutton.dtd
diff --git a/src/chrome/locale/ha/torbutton.properties b/chrome/locale/ha/torbutton.properties
similarity index 100%
rename from src/chrome/locale/ha/torbutton.properties
rename to chrome/locale/ha/torbutton.properties
diff --git a/src/chrome/locale/he/aboutDialog.dtd b/chrome/locale/he/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/he/aboutDialog.dtd
rename to chrome/locale/he/aboutDialog.dtd
diff --git a/src/chrome/locale/he/aboutTBUpdate.dtd b/chrome/locale/he/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/he/aboutTBUpdate.dtd
rename to chrome/locale/he/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/he/aboutTor.dtd b/chrome/locale/he/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/he/aboutTor.dtd
rename to chrome/locale/he/aboutTor.dtd
diff --git a/src/chrome/locale/he/brand.dtd b/chrome/locale/he/brand.dtd
similarity index 100%
rename from src/chrome/locale/he/brand.dtd
rename to chrome/locale/he/brand.dtd
diff --git a/src/chrome/locale/he/brand.properties b/chrome/locale/he/brand.properties
similarity index 100%
rename from src/chrome/locale/he/brand.properties
rename to chrome/locale/he/brand.properties
diff --git a/src/chrome/locale/he/browserOnboarding.properties b/chrome/locale/he/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/he/browserOnboarding.properties
rename to chrome/locale/he/browserOnboarding.properties
diff --git a/src/chrome/locale/he/securityLevel.properties b/chrome/locale/he/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/he/securityLevel.properties
rename to chrome/locale/he/securityLevel.properties
diff --git a/src/chrome/locale/he/torbutton.dtd b/chrome/locale/he/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/he/torbutton.dtd
rename to chrome/locale/he/torbutton.dtd
diff --git a/src/chrome/locale/he/torbutton.properties b/chrome/locale/he/torbutton.properties
similarity index 100%
rename from src/chrome/locale/he/torbutton.properties
rename to chrome/locale/he/torbutton.properties
diff --git a/src/chrome/locale/hi/aboutTor.dtd b/chrome/locale/hi/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/hi/aboutTor.dtd
rename to chrome/locale/hi/aboutTor.dtd
diff --git a/src/chrome/locale/hi/brand.dtd b/chrome/locale/hi/brand.dtd
similarity index 100%
rename from src/chrome/locale/hi/brand.dtd
rename to chrome/locale/hi/brand.dtd
diff --git a/src/chrome/locale/hi/brand.properties b/chrome/locale/hi/brand.properties
similarity index 100%
rename from src/chrome/locale/hi/brand.properties
rename to chrome/locale/hi/brand.properties
diff --git a/src/chrome/locale/hi/torbutton.dtd b/chrome/locale/hi/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/hi/torbutton.dtd
rename to chrome/locale/hi/torbutton.dtd
diff --git a/src/chrome/locale/hi/torbutton.properties b/chrome/locale/hi/torbutton.properties
similarity index 100%
rename from src/chrome/locale/hi/torbutton.properties
rename to chrome/locale/hi/torbutton.properties
diff --git a/src/chrome/locale/hr/aboutTor.dtd b/chrome/locale/hr/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/hr/aboutTor.dtd
rename to chrome/locale/hr/aboutTor.dtd
diff --git a/src/chrome/locale/hr/brand.dtd b/chrome/locale/hr/brand.dtd
similarity index 100%
rename from src/chrome/locale/hr/brand.dtd
rename to chrome/locale/hr/brand.dtd
diff --git a/src/chrome/locale/hr/brand.properties b/chrome/locale/hr/brand.properties
similarity index 100%
rename from src/chrome/locale/hr/brand.properties
rename to chrome/locale/hr/brand.properties
diff --git a/src/chrome/locale/hr/torbutton.dtd b/chrome/locale/hr/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/hr/torbutton.dtd
rename to chrome/locale/hr/torbutton.dtd
diff --git a/src/chrome/locale/hr/torbutton.properties b/chrome/locale/hr/torbutton.properties
similarity index 100%
rename from src/chrome/locale/hr/torbutton.properties
rename to chrome/locale/hr/torbutton.properties
diff --git a/src/chrome/locale/ht/aboutTor.dtd b/chrome/locale/ht/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/ht/aboutTor.dtd
rename to chrome/locale/ht/aboutTor.dtd
diff --git a/src/chrome/locale/ht/brand.dtd b/chrome/locale/ht/brand.dtd
similarity index 100%
rename from src/chrome/locale/ht/brand.dtd
rename to chrome/locale/ht/brand.dtd
diff --git a/src/chrome/locale/ht/brand.properties b/chrome/locale/ht/brand.properties
similarity index 100%
rename from src/chrome/locale/ht/brand.properties
rename to chrome/locale/ht/brand.properties
diff --git a/src/chrome/locale/ht/torbutton.dtd b/chrome/locale/ht/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/ht/torbutton.dtd
rename to chrome/locale/ht/torbutton.dtd
diff --git a/src/chrome/locale/ht/torbutton.properties b/chrome/locale/ht/torbutton.properties
similarity index 100%
rename from src/chrome/locale/ht/torbutton.properties
rename to chrome/locale/ht/torbutton.properties
diff --git a/src/chrome/locale/hu/aboutDialog.dtd b/chrome/locale/hu/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/hu/aboutDialog.dtd
rename to chrome/locale/hu/aboutDialog.dtd
diff --git a/src/chrome/locale/hu/aboutTBUpdate.dtd b/chrome/locale/hu/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/hu/aboutTBUpdate.dtd
rename to chrome/locale/hu/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/hu/aboutTor.dtd b/chrome/locale/hu/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/hu/aboutTor.dtd
rename to chrome/locale/hu/aboutTor.dtd
diff --git a/src/chrome/locale/hu/brand.dtd b/chrome/locale/hu/brand.dtd
similarity index 100%
rename from src/chrome/locale/hu/brand.dtd
rename to chrome/locale/hu/brand.dtd
diff --git a/src/chrome/locale/hu/brand.properties b/chrome/locale/hu/brand.properties
similarity index 100%
rename from src/chrome/locale/hu/brand.properties
rename to chrome/locale/hu/brand.properties
diff --git a/src/chrome/locale/hu/browserOnboarding.properties b/chrome/locale/hu/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/hu/browserOnboarding.properties
rename to chrome/locale/hu/browserOnboarding.properties
diff --git a/src/chrome/locale/hu/securityLevel.properties b/chrome/locale/hu/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/hu/securityLevel.properties
rename to chrome/locale/hu/securityLevel.properties
diff --git a/src/chrome/locale/hu/torbutton.dtd b/chrome/locale/hu/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/hu/torbutton.dtd
rename to chrome/locale/hu/torbutton.dtd
diff --git a/src/chrome/locale/hu/torbutton.properties b/chrome/locale/hu/torbutton.properties
similarity index 100%
rename from src/chrome/locale/hu/torbutton.properties
rename to chrome/locale/hu/torbutton.properties
diff --git a/src/chrome/locale/hy/aboutTor.dtd b/chrome/locale/hy/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/hy/aboutTor.dtd
rename to chrome/locale/hy/aboutTor.dtd
diff --git a/src/chrome/locale/hy/brand.dtd b/chrome/locale/hy/brand.dtd
similarity index 100%
rename from src/chrome/locale/hy/brand.dtd
rename to chrome/locale/hy/brand.dtd
diff --git a/src/chrome/locale/hy/brand.properties b/chrome/locale/hy/brand.properties
similarity index 100%
rename from src/chrome/locale/hy/brand.properties
rename to chrome/locale/hy/brand.properties
diff --git a/src/chrome/locale/hy/torbutton.dtd b/chrome/locale/hy/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/hy/torbutton.dtd
rename to chrome/locale/hy/torbutton.dtd
diff --git a/src/chrome/locale/hy/torbutton.properties b/chrome/locale/hy/torbutton.properties
similarity index 100%
rename from src/chrome/locale/hy/torbutton.properties
rename to chrome/locale/hy/torbutton.properties
diff --git a/src/chrome/locale/id/aboutDialog.dtd b/chrome/locale/id/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/id/aboutDialog.dtd
rename to chrome/locale/id/aboutDialog.dtd
diff --git a/src/chrome/locale/id/aboutTBUpdate.dtd b/chrome/locale/id/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/id/aboutTBUpdate.dtd
rename to chrome/locale/id/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/id/aboutTor.dtd b/chrome/locale/id/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/id/aboutTor.dtd
rename to chrome/locale/id/aboutTor.dtd
diff --git a/src/chrome/locale/id/brand.dtd b/chrome/locale/id/brand.dtd
similarity index 100%
rename from src/chrome/locale/id/brand.dtd
rename to chrome/locale/id/brand.dtd
diff --git a/src/chrome/locale/id/brand.properties b/chrome/locale/id/brand.properties
similarity index 100%
rename from src/chrome/locale/id/brand.properties
rename to chrome/locale/id/brand.properties
diff --git a/src/chrome/locale/id/browserOnboarding.properties b/chrome/locale/id/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/id/browserOnboarding.properties
rename to chrome/locale/id/browserOnboarding.properties
diff --git a/src/chrome/locale/id/securityLevel.properties b/chrome/locale/id/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/id/securityLevel.properties
rename to chrome/locale/id/securityLevel.properties
diff --git a/src/chrome/locale/id/torbutton.dtd b/chrome/locale/id/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/id/torbutton.dtd
rename to chrome/locale/id/torbutton.dtd
diff --git a/src/chrome/locale/id/torbutton.properties b/chrome/locale/id/torbutton.properties
similarity index 100%
rename from src/chrome/locale/id/torbutton.properties
rename to chrome/locale/id/torbutton.properties
diff --git a/src/chrome/locale/is/aboutDialog.dtd b/chrome/locale/is/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/is/aboutDialog.dtd
rename to chrome/locale/is/aboutDialog.dtd
diff --git a/src/chrome/locale/is/aboutTBUpdate.dtd b/chrome/locale/is/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/is/aboutTBUpdate.dtd
rename to chrome/locale/is/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/is/aboutTor.dtd b/chrome/locale/is/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/is/aboutTor.dtd
rename to chrome/locale/is/aboutTor.dtd
diff --git a/src/chrome/locale/is/brand.dtd b/chrome/locale/is/brand.dtd
similarity index 100%
rename from src/chrome/locale/is/brand.dtd
rename to chrome/locale/is/brand.dtd
diff --git a/src/chrome/locale/is/brand.properties b/chrome/locale/is/brand.properties
similarity index 100%
rename from src/chrome/locale/is/brand.properties
rename to chrome/locale/is/brand.properties
diff --git a/src/chrome/locale/is/browserOnboarding.properties b/chrome/locale/is/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/is/browserOnboarding.properties
rename to chrome/locale/is/browserOnboarding.properties
diff --git a/src/chrome/locale/is/securityLevel.properties b/chrome/locale/is/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/is/securityLevel.properties
rename to chrome/locale/is/securityLevel.properties
diff --git a/src/chrome/locale/is/torbutton.dtd b/chrome/locale/is/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/is/torbutton.dtd
rename to chrome/locale/is/torbutton.dtd
diff --git a/src/chrome/locale/is/torbutton.properties b/chrome/locale/is/torbutton.properties
similarity index 100%
rename from src/chrome/locale/is/torbutton.properties
rename to chrome/locale/is/torbutton.properties
diff --git a/src/chrome/locale/it/aboutDialog.dtd b/chrome/locale/it/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/it/aboutDialog.dtd
rename to chrome/locale/it/aboutDialog.dtd
diff --git a/src/chrome/locale/it/aboutTBUpdate.dtd b/chrome/locale/it/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/it/aboutTBUpdate.dtd
rename to chrome/locale/it/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/it/aboutTor.dtd b/chrome/locale/it/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/it/aboutTor.dtd
rename to chrome/locale/it/aboutTor.dtd
diff --git a/src/chrome/locale/it/brand.dtd b/chrome/locale/it/brand.dtd
similarity index 100%
rename from src/chrome/locale/it/brand.dtd
rename to chrome/locale/it/brand.dtd
diff --git a/src/chrome/locale/it/brand.properties b/chrome/locale/it/brand.properties
similarity index 100%
rename from src/chrome/locale/it/brand.properties
rename to chrome/locale/it/brand.properties
diff --git a/src/chrome/locale/it/browserOnboarding.properties b/chrome/locale/it/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/it/browserOnboarding.properties
rename to chrome/locale/it/browserOnboarding.properties
diff --git a/src/chrome/locale/it/securityLevel.properties b/chrome/locale/it/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/it/securityLevel.properties
rename to chrome/locale/it/securityLevel.properties
diff --git a/src/chrome/locale/it/torbutton.dtd b/chrome/locale/it/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/it/torbutton.dtd
rename to chrome/locale/it/torbutton.dtd
diff --git a/src/chrome/locale/it/torbutton.properties b/chrome/locale/it/torbutton.properties
similarity index 100%
rename from src/chrome/locale/it/torbutton.properties
rename to chrome/locale/it/torbutton.properties
diff --git a/src/chrome/locale/ja/aboutDialog.dtd b/chrome/locale/ja/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/ja/aboutDialog.dtd
rename to chrome/locale/ja/aboutDialog.dtd
diff --git a/src/chrome/locale/ja/aboutTBUpdate.dtd b/chrome/locale/ja/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/ja/aboutTBUpdate.dtd
rename to chrome/locale/ja/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/ja/aboutTor.dtd b/chrome/locale/ja/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/ja/aboutTor.dtd
rename to chrome/locale/ja/aboutTor.dtd
diff --git a/src/chrome/locale/ja/brand.dtd b/chrome/locale/ja/brand.dtd
similarity index 100%
rename from src/chrome/locale/ja/brand.dtd
rename to chrome/locale/ja/brand.dtd
diff --git a/src/chrome/locale/ja/brand.properties b/chrome/locale/ja/brand.properties
similarity index 100%
rename from src/chrome/locale/ja/brand.properties
rename to chrome/locale/ja/brand.properties
diff --git a/src/chrome/locale/ja/browserOnboarding.properties b/chrome/locale/ja/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/ja/browserOnboarding.properties
rename to chrome/locale/ja/browserOnboarding.properties
diff --git a/src/chrome/locale/ja/securityLevel.properties b/chrome/locale/ja/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/ja/securityLevel.properties
rename to chrome/locale/ja/securityLevel.properties
diff --git a/src/chrome/locale/ja/torbutton.dtd b/chrome/locale/ja/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/ja/torbutton.dtd
rename to chrome/locale/ja/torbutton.dtd
diff --git a/src/chrome/locale/ja/torbutton.properties b/chrome/locale/ja/torbutton.properties
similarity index 100%
rename from src/chrome/locale/ja/torbutton.properties
rename to chrome/locale/ja/torbutton.properties
diff --git a/src/chrome/locale/jv/aboutTor.dtd b/chrome/locale/jv/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/jv/aboutTor.dtd
rename to chrome/locale/jv/aboutTor.dtd
diff --git a/src/chrome/locale/jv/brand.dtd b/chrome/locale/jv/brand.dtd
similarity index 100%
rename from src/chrome/locale/jv/brand.dtd
rename to chrome/locale/jv/brand.dtd
diff --git a/src/chrome/locale/jv/brand.properties b/chrome/locale/jv/brand.properties
similarity index 100%
rename from src/chrome/locale/jv/brand.properties
rename to chrome/locale/jv/brand.properties
diff --git a/src/chrome/locale/jv/torbutton.dtd b/chrome/locale/jv/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/jv/torbutton.dtd
rename to chrome/locale/jv/torbutton.dtd
diff --git a/src/chrome/locale/jv/torbutton.properties b/chrome/locale/jv/torbutton.properties
similarity index 100%
rename from src/chrome/locale/jv/torbutton.properties
rename to chrome/locale/jv/torbutton.properties
diff --git a/src/chrome/locale/ka/aboutDialog.dtd b/chrome/locale/ka/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/ka/aboutDialog.dtd
rename to chrome/locale/ka/aboutDialog.dtd
diff --git a/src/chrome/locale/ka/aboutTBUpdate.dtd b/chrome/locale/ka/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/ka/aboutTBUpdate.dtd
rename to chrome/locale/ka/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/ka/aboutTor.dtd b/chrome/locale/ka/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/ka/aboutTor.dtd
rename to chrome/locale/ka/aboutTor.dtd
diff --git a/src/chrome/locale/ka/brand.dtd b/chrome/locale/ka/brand.dtd
similarity index 100%
rename from src/chrome/locale/ka/brand.dtd
rename to chrome/locale/ka/brand.dtd
diff --git a/src/chrome/locale/ka/brand.properties b/chrome/locale/ka/brand.properties
similarity index 100%
rename from src/chrome/locale/ka/brand.properties
rename to chrome/locale/ka/brand.properties
diff --git a/src/chrome/locale/ka/browserOnboarding.properties b/chrome/locale/ka/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/ka/browserOnboarding.properties
rename to chrome/locale/ka/browserOnboarding.properties
diff --git a/src/chrome/locale/ka/securityLevel.properties b/chrome/locale/ka/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/ka/securityLevel.properties
rename to chrome/locale/ka/securityLevel.properties
diff --git a/src/chrome/locale/ka/torbutton.dtd b/chrome/locale/ka/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/ka/torbutton.dtd
rename to chrome/locale/ka/torbutton.dtd
diff --git a/src/chrome/locale/ka/torbutton.properties b/chrome/locale/ka/torbutton.properties
similarity index 100%
rename from src/chrome/locale/ka/torbutton.properties
rename to chrome/locale/ka/torbutton.properties
diff --git a/src/chrome/locale/km/aboutTor.dtd b/chrome/locale/km/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/km/aboutTor.dtd
rename to chrome/locale/km/aboutTor.dtd
diff --git a/src/chrome/locale/km/brand.dtd b/chrome/locale/km/brand.dtd
similarity index 100%
rename from src/chrome/locale/km/brand.dtd
rename to chrome/locale/km/brand.dtd
diff --git a/src/chrome/locale/km/brand.properties b/chrome/locale/km/brand.properties
similarity index 100%
rename from src/chrome/locale/km/brand.properties
rename to chrome/locale/km/brand.properties
diff --git a/src/chrome/locale/km/torbutton.dtd b/chrome/locale/km/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/km/torbutton.dtd
rename to chrome/locale/km/torbutton.dtd
diff --git a/src/chrome/locale/km/torbutton.properties b/chrome/locale/km/torbutton.properties
similarity index 100%
rename from src/chrome/locale/km/torbutton.properties
rename to chrome/locale/km/torbutton.properties
diff --git a/src/chrome/locale/kn/aboutTor.dtd b/chrome/locale/kn/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/kn/aboutTor.dtd
rename to chrome/locale/kn/aboutTor.dtd
diff --git a/src/chrome/locale/kn/brand.dtd b/chrome/locale/kn/brand.dtd
similarity index 100%
rename from src/chrome/locale/kn/brand.dtd
rename to chrome/locale/kn/brand.dtd
diff --git a/src/chrome/locale/kn/brand.properties b/chrome/locale/kn/brand.properties
similarity index 100%
rename from src/chrome/locale/kn/brand.properties
rename to chrome/locale/kn/brand.properties
diff --git a/src/chrome/locale/kn/torbutton.dtd b/chrome/locale/kn/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/kn/torbutton.dtd
rename to chrome/locale/kn/torbutton.dtd
diff --git a/src/chrome/locale/kn/torbutton.properties b/chrome/locale/kn/torbutton.properties
similarity index 100%
rename from src/chrome/locale/kn/torbutton.properties
rename to chrome/locale/kn/torbutton.properties
diff --git a/src/chrome/locale/ko/aboutDialog.dtd b/chrome/locale/ko/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/ko/aboutDialog.dtd
rename to chrome/locale/ko/aboutDialog.dtd
diff --git a/src/chrome/locale/ko/aboutTBUpdate.dtd b/chrome/locale/ko/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/ko/aboutTBUpdate.dtd
rename to chrome/locale/ko/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/ko/aboutTor.dtd b/chrome/locale/ko/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/ko/aboutTor.dtd
rename to chrome/locale/ko/aboutTor.dtd
diff --git a/src/chrome/locale/ko/brand.dtd b/chrome/locale/ko/brand.dtd
similarity index 100%
rename from src/chrome/locale/ko/brand.dtd
rename to chrome/locale/ko/brand.dtd
diff --git a/src/chrome/locale/ko/brand.properties b/chrome/locale/ko/brand.properties
similarity index 100%
rename from src/chrome/locale/ko/brand.properties
rename to chrome/locale/ko/brand.properties
diff --git a/src/chrome/locale/ko/browserOnboarding.properties b/chrome/locale/ko/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/ko/browserOnboarding.properties
rename to chrome/locale/ko/browserOnboarding.properties
diff --git a/src/chrome/locale/ko/securityLevel.properties b/chrome/locale/ko/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/ko/securityLevel.properties
rename to chrome/locale/ko/securityLevel.properties
diff --git a/src/chrome/locale/ko/torbutton.dtd b/chrome/locale/ko/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/ko/torbutton.dtd
rename to chrome/locale/ko/torbutton.dtd
diff --git a/src/chrome/locale/ko/torbutton.properties b/chrome/locale/ko/torbutton.properties
similarity index 100%
rename from src/chrome/locale/ko/torbutton.properties
rename to chrome/locale/ko/torbutton.properties
diff --git a/src/chrome/locale/ku/aboutTor.dtd b/chrome/locale/ku/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/ku/aboutTor.dtd
rename to chrome/locale/ku/aboutTor.dtd
diff --git a/src/chrome/locale/ku/brand.dtd b/chrome/locale/ku/brand.dtd
similarity index 100%
rename from src/chrome/locale/ku/brand.dtd
rename to chrome/locale/ku/brand.dtd
diff --git a/src/chrome/locale/ku/brand.properties b/chrome/locale/ku/brand.properties
similarity index 100%
rename from src/chrome/locale/ku/brand.properties
rename to chrome/locale/ku/brand.properties
diff --git a/src/chrome/locale/ku/torbutton.dtd b/chrome/locale/ku/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/ku/torbutton.dtd
rename to chrome/locale/ku/torbutton.dtd
diff --git a/src/chrome/locale/ku/torbutton.properties b/chrome/locale/ku/torbutton.properties
similarity index 100%
rename from src/chrome/locale/ku/torbutton.properties
rename to chrome/locale/ku/torbutton.properties
diff --git a/src/chrome/locale/kw/aboutTor.dtd b/chrome/locale/kw/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/kw/aboutTor.dtd
rename to chrome/locale/kw/aboutTor.dtd
diff --git a/src/chrome/locale/kw/brand.dtd b/chrome/locale/kw/brand.dtd
similarity index 100%
rename from src/chrome/locale/kw/brand.dtd
rename to chrome/locale/kw/brand.dtd
diff --git a/src/chrome/locale/kw/brand.properties b/chrome/locale/kw/brand.properties
similarity index 100%
rename from src/chrome/locale/kw/brand.properties
rename to chrome/locale/kw/brand.properties
diff --git a/src/chrome/locale/kw/torbutton.dtd b/chrome/locale/kw/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/kw/torbutton.dtd
rename to chrome/locale/kw/torbutton.dtd
diff --git a/src/chrome/locale/kw/torbutton.properties b/chrome/locale/kw/torbutton.properties
similarity index 100%
rename from src/chrome/locale/kw/torbutton.properties
rename to chrome/locale/kw/torbutton.properties
diff --git a/src/chrome/locale/ky/aboutTor.dtd b/chrome/locale/ky/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/ky/aboutTor.dtd
rename to chrome/locale/ky/aboutTor.dtd
diff --git a/src/chrome/locale/ky/brand.dtd b/chrome/locale/ky/brand.dtd
similarity index 100%
rename from src/chrome/locale/ky/brand.dtd
rename to chrome/locale/ky/brand.dtd
diff --git a/src/chrome/locale/ky/brand.properties b/chrome/locale/ky/brand.properties
similarity index 100%
rename from src/chrome/locale/ky/brand.properties
rename to chrome/locale/ky/brand.properties
diff --git a/src/chrome/locale/ky/torbutton.dtd b/chrome/locale/ky/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/ky/torbutton.dtd
rename to chrome/locale/ky/torbutton.dtd
diff --git a/src/chrome/locale/ky/torbutton.properties b/chrome/locale/ky/torbutton.properties
similarity index 100%
rename from src/chrome/locale/ky/torbutton.properties
rename to chrome/locale/ky/torbutton.properties
diff --git a/src/chrome/locale/lb/aboutTor.dtd b/chrome/locale/lb/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/lb/aboutTor.dtd
rename to chrome/locale/lb/aboutTor.dtd
diff --git a/src/chrome/locale/lb/brand.dtd b/chrome/locale/lb/brand.dtd
similarity index 100%
rename from src/chrome/locale/lb/brand.dtd
rename to chrome/locale/lb/brand.dtd
diff --git a/src/chrome/locale/lb/brand.properties b/chrome/locale/lb/brand.properties
similarity index 100%
rename from src/chrome/locale/lb/brand.properties
rename to chrome/locale/lb/brand.properties
diff --git a/src/chrome/locale/lb/torbutton.dtd b/chrome/locale/lb/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/lb/torbutton.dtd
rename to chrome/locale/lb/torbutton.dtd
diff --git a/src/chrome/locale/lb/torbutton.properties b/chrome/locale/lb/torbutton.properties
similarity index 100%
rename from src/chrome/locale/lb/torbutton.properties
rename to chrome/locale/lb/torbutton.properties
diff --git a/src/chrome/locale/lg/aboutTor.dtd b/chrome/locale/lg/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/lg/aboutTor.dtd
rename to chrome/locale/lg/aboutTor.dtd
diff --git a/src/chrome/locale/lg/torbutton.dtd b/chrome/locale/lg/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/lg/torbutton.dtd
rename to chrome/locale/lg/torbutton.dtd
diff --git a/src/chrome/locale/lg/torbutton.properties b/chrome/locale/lg/torbutton.properties
similarity index 100%
rename from src/chrome/locale/lg/torbutton.properties
rename to chrome/locale/lg/torbutton.properties
diff --git a/src/chrome/locale/ln/aboutTor.dtd b/chrome/locale/ln/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/ln/aboutTor.dtd
rename to chrome/locale/ln/aboutTor.dtd
diff --git a/src/chrome/locale/ln/brand.dtd b/chrome/locale/ln/brand.dtd
similarity index 100%
rename from src/chrome/locale/ln/brand.dtd
rename to chrome/locale/ln/brand.dtd
diff --git a/src/chrome/locale/ln/brand.properties b/chrome/locale/ln/brand.properties
similarity index 100%
rename from src/chrome/locale/ln/brand.properties
rename to chrome/locale/ln/brand.properties
diff --git a/src/chrome/locale/ln/torbutton.dtd b/chrome/locale/ln/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/ln/torbutton.dtd
rename to chrome/locale/ln/torbutton.dtd
diff --git a/src/chrome/locale/ln/torbutton.properties b/chrome/locale/ln/torbutton.properties
similarity index 100%
rename from src/chrome/locale/ln/torbutton.properties
rename to chrome/locale/ln/torbutton.properties
diff --git a/src/chrome/locale/lo/aboutTor.dtd b/chrome/locale/lo/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/lo/aboutTor.dtd
rename to chrome/locale/lo/aboutTor.dtd
diff --git a/src/chrome/locale/lo/brand.dtd b/chrome/locale/lo/brand.dtd
similarity index 100%
rename from src/chrome/locale/lo/brand.dtd
rename to chrome/locale/lo/brand.dtd
diff --git a/src/chrome/locale/lo/brand.properties b/chrome/locale/lo/brand.properties
similarity index 100%
rename from src/chrome/locale/lo/brand.properties
rename to chrome/locale/lo/brand.properties
diff --git a/src/chrome/locale/lo/torbutton.dtd b/chrome/locale/lo/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/lo/torbutton.dtd
rename to chrome/locale/lo/torbutton.dtd
diff --git a/src/chrome/locale/lo/torbutton.properties b/chrome/locale/lo/torbutton.properties
similarity index 100%
rename from src/chrome/locale/lo/torbutton.properties
rename to chrome/locale/lo/torbutton.properties
diff --git a/src/chrome/locale/lt/aboutTor.dtd b/chrome/locale/lt/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/lt/aboutTor.dtd
rename to chrome/locale/lt/aboutTor.dtd
diff --git a/src/chrome/locale/lt/brand.dtd b/chrome/locale/lt/brand.dtd
similarity index 100%
rename from src/chrome/locale/lt/brand.dtd
rename to chrome/locale/lt/brand.dtd
diff --git a/src/chrome/locale/lt/brand.properties b/chrome/locale/lt/brand.properties
similarity index 100%
rename from src/chrome/locale/lt/brand.properties
rename to chrome/locale/lt/brand.properties
diff --git a/src/chrome/locale/lt/securityLevel.properties b/chrome/locale/lt/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/lt/securityLevel.properties
rename to chrome/locale/lt/securityLevel.properties
diff --git a/src/chrome/locale/lt/torbutton.dtd b/chrome/locale/lt/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/lt/torbutton.dtd
rename to chrome/locale/lt/torbutton.dtd
diff --git a/src/chrome/locale/lt/torbutton.properties b/chrome/locale/lt/torbutton.properties
similarity index 100%
rename from src/chrome/locale/lt/torbutton.properties
rename to chrome/locale/lt/torbutton.properties
diff --git a/src/chrome/locale/lv/aboutTor.dtd b/chrome/locale/lv/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/lv/aboutTor.dtd
rename to chrome/locale/lv/aboutTor.dtd
diff --git a/src/chrome/locale/lv/brand.dtd b/chrome/locale/lv/brand.dtd
similarity index 100%
rename from src/chrome/locale/lv/brand.dtd
rename to chrome/locale/lv/brand.dtd
diff --git a/src/chrome/locale/lv/brand.properties b/chrome/locale/lv/brand.properties
similarity index 100%
rename from src/chrome/locale/lv/brand.properties
rename to chrome/locale/lv/brand.properties
diff --git a/src/chrome/locale/lv/securityLevel.properties b/chrome/locale/lv/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/lv/securityLevel.properties
rename to chrome/locale/lv/securityLevel.properties
diff --git a/src/chrome/locale/lv/torbutton.dtd b/chrome/locale/lv/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/lv/torbutton.dtd
rename to chrome/locale/lv/torbutton.dtd
diff --git a/src/chrome/locale/lv/torbutton.properties b/chrome/locale/lv/torbutton.properties
similarity index 100%
rename from src/chrome/locale/lv/torbutton.properties
rename to chrome/locale/lv/torbutton.properties
diff --git a/src/chrome/locale/mg/aboutTor.dtd b/chrome/locale/mg/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/mg/aboutTor.dtd
rename to chrome/locale/mg/aboutTor.dtd
diff --git a/src/chrome/locale/mg/brand.dtd b/chrome/locale/mg/brand.dtd
similarity index 100%
rename from src/chrome/locale/mg/brand.dtd
rename to chrome/locale/mg/brand.dtd
diff --git a/src/chrome/locale/mg/brand.properties b/chrome/locale/mg/brand.properties
similarity index 100%
rename from src/chrome/locale/mg/brand.properties
rename to chrome/locale/mg/brand.properties
diff --git a/src/chrome/locale/mg/torbutton.dtd b/chrome/locale/mg/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/mg/torbutton.dtd
rename to chrome/locale/mg/torbutton.dtd
diff --git a/src/chrome/locale/mg/torbutton.properties b/chrome/locale/mg/torbutton.properties
similarity index 100%
rename from src/chrome/locale/mg/torbutton.properties
rename to chrome/locale/mg/torbutton.properties
diff --git a/src/chrome/locale/mi/aboutTor.dtd b/chrome/locale/mi/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/mi/aboutTor.dtd
rename to chrome/locale/mi/aboutTor.dtd
diff --git a/src/chrome/locale/mi/brand.dtd b/chrome/locale/mi/brand.dtd
similarity index 100%
rename from src/chrome/locale/mi/brand.dtd
rename to chrome/locale/mi/brand.dtd
diff --git a/src/chrome/locale/mi/brand.properties b/chrome/locale/mi/brand.properties
similarity index 100%
rename from src/chrome/locale/mi/brand.properties
rename to chrome/locale/mi/brand.properties
diff --git a/src/chrome/locale/mi/torbutton.dtd b/chrome/locale/mi/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/mi/torbutton.dtd
rename to chrome/locale/mi/torbutton.dtd
diff --git a/src/chrome/locale/mi/torbutton.properties b/chrome/locale/mi/torbutton.properties
similarity index 100%
rename from src/chrome/locale/mi/torbutton.properties
rename to chrome/locale/mi/torbutton.properties
diff --git a/src/chrome/locale/mk/aboutTor.dtd b/chrome/locale/mk/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/mk/aboutTor.dtd
rename to chrome/locale/mk/aboutTor.dtd
diff --git a/src/chrome/locale/mk/brand.dtd b/chrome/locale/mk/brand.dtd
similarity index 100%
rename from src/chrome/locale/mk/brand.dtd
rename to chrome/locale/mk/brand.dtd
diff --git a/src/chrome/locale/mk/brand.properties b/chrome/locale/mk/brand.properties
similarity index 100%
rename from src/chrome/locale/mk/brand.properties
rename to chrome/locale/mk/brand.properties
diff --git a/src/chrome/locale/mk/securityLevel.properties b/chrome/locale/mk/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/mk/securityLevel.properties
rename to chrome/locale/mk/securityLevel.properties
diff --git a/src/chrome/locale/mk/torbutton.dtd b/chrome/locale/mk/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/mk/torbutton.dtd
rename to chrome/locale/mk/torbutton.dtd
diff --git a/src/chrome/locale/mk/torbutton.properties b/chrome/locale/mk/torbutton.properties
similarity index 100%
rename from src/chrome/locale/mk/torbutton.properties
rename to chrome/locale/mk/torbutton.properties
diff --git a/src/chrome/locale/ml/aboutTor.dtd b/chrome/locale/ml/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/ml/aboutTor.dtd
rename to chrome/locale/ml/aboutTor.dtd
diff --git a/src/chrome/locale/ml/brand.dtd b/chrome/locale/ml/brand.dtd
similarity index 100%
rename from src/chrome/locale/ml/brand.dtd
rename to chrome/locale/ml/brand.dtd
diff --git a/src/chrome/locale/ml/brand.properties b/chrome/locale/ml/brand.properties
similarity index 100%
rename from src/chrome/locale/ml/brand.properties
rename to chrome/locale/ml/brand.properties
diff --git a/src/chrome/locale/ml/torbutton.dtd b/chrome/locale/ml/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/ml/torbutton.dtd
rename to chrome/locale/ml/torbutton.dtd
diff --git a/src/chrome/locale/ml/torbutton.properties b/chrome/locale/ml/torbutton.properties
similarity index 100%
rename from src/chrome/locale/ml/torbutton.properties
rename to chrome/locale/ml/torbutton.properties
diff --git a/src/chrome/locale/mn/aboutTor.dtd b/chrome/locale/mn/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/mn/aboutTor.dtd
rename to chrome/locale/mn/aboutTor.dtd
diff --git a/src/chrome/locale/mn/brand.dtd b/chrome/locale/mn/brand.dtd
similarity index 100%
rename from src/chrome/locale/mn/brand.dtd
rename to chrome/locale/mn/brand.dtd
diff --git a/src/chrome/locale/mn/brand.properties b/chrome/locale/mn/brand.properties
similarity index 100%
rename from src/chrome/locale/mn/brand.properties
rename to chrome/locale/mn/brand.properties
diff --git a/src/chrome/locale/mn/torbutton.dtd b/chrome/locale/mn/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/mn/torbutton.dtd
rename to chrome/locale/mn/torbutton.dtd
diff --git a/src/chrome/locale/mn/torbutton.properties b/chrome/locale/mn/torbutton.properties
similarity index 100%
rename from src/chrome/locale/mn/torbutton.properties
rename to chrome/locale/mn/torbutton.properties
diff --git a/src/chrome/locale/mr/aboutTor.dtd b/chrome/locale/mr/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/mr/aboutTor.dtd
rename to chrome/locale/mr/aboutTor.dtd
diff --git a/src/chrome/locale/mr/brand.dtd b/chrome/locale/mr/brand.dtd
similarity index 100%
rename from src/chrome/locale/mr/brand.dtd
rename to chrome/locale/mr/brand.dtd
diff --git a/src/chrome/locale/mr/brand.properties b/chrome/locale/mr/brand.properties
similarity index 100%
rename from src/chrome/locale/mr/brand.properties
rename to chrome/locale/mr/brand.properties
diff --git a/src/chrome/locale/mr/torbutton.dtd b/chrome/locale/mr/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/mr/torbutton.dtd
rename to chrome/locale/mr/torbutton.dtd
diff --git a/src/chrome/locale/mr/torbutton.properties b/chrome/locale/mr/torbutton.properties
similarity index 100%
rename from src/chrome/locale/mr/torbutton.properties
rename to chrome/locale/mr/torbutton.properties
diff --git a/src/chrome/locale/ms/aboutTor.dtd b/chrome/locale/ms/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/ms/aboutTor.dtd
rename to chrome/locale/ms/aboutTor.dtd
diff --git a/src/chrome/locale/ms/brand.dtd b/chrome/locale/ms/brand.dtd
similarity index 100%
rename from src/chrome/locale/ms/brand.dtd
rename to chrome/locale/ms/brand.dtd
diff --git a/src/chrome/locale/ms/brand.properties b/chrome/locale/ms/brand.properties
similarity index 100%
rename from src/chrome/locale/ms/brand.properties
rename to chrome/locale/ms/brand.properties
diff --git a/src/chrome/locale/ms/torbutton.dtd b/chrome/locale/ms/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/ms/torbutton.dtd
rename to chrome/locale/ms/torbutton.dtd
diff --git a/src/chrome/locale/ms/torbutton.properties b/chrome/locale/ms/torbutton.properties
similarity index 100%
rename from src/chrome/locale/ms/torbutton.properties
rename to chrome/locale/ms/torbutton.properties
diff --git a/src/chrome/locale/mt/aboutTor.dtd b/chrome/locale/mt/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/mt/aboutTor.dtd
rename to chrome/locale/mt/aboutTor.dtd
diff --git a/src/chrome/locale/mt/brand.dtd b/chrome/locale/mt/brand.dtd
similarity index 100%
rename from src/chrome/locale/mt/brand.dtd
rename to chrome/locale/mt/brand.dtd
diff --git a/src/chrome/locale/mt/brand.properties b/chrome/locale/mt/brand.properties
similarity index 100%
rename from src/chrome/locale/mt/brand.properties
rename to chrome/locale/mt/brand.properties
diff --git a/src/chrome/locale/mt/torbutton.dtd b/chrome/locale/mt/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/mt/torbutton.dtd
rename to chrome/locale/mt/torbutton.dtd
diff --git a/src/chrome/locale/mt/torbutton.properties b/chrome/locale/mt/torbutton.properties
similarity index 100%
rename from src/chrome/locale/mt/torbutton.properties
rename to chrome/locale/mt/torbutton.properties
diff --git a/src/chrome/locale/my/aboutTor.dtd b/chrome/locale/my/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/my/aboutTor.dtd
rename to chrome/locale/my/aboutTor.dtd
diff --git a/src/chrome/locale/my/brand.dtd b/chrome/locale/my/brand.dtd
similarity index 100%
rename from src/chrome/locale/my/brand.dtd
rename to chrome/locale/my/brand.dtd
diff --git a/src/chrome/locale/my/brand.properties b/chrome/locale/my/brand.properties
similarity index 100%
rename from src/chrome/locale/my/brand.properties
rename to chrome/locale/my/brand.properties
diff --git a/src/chrome/locale/my/securityLevel.properties b/chrome/locale/my/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/my/securityLevel.properties
rename to chrome/locale/my/securityLevel.properties
diff --git a/src/chrome/locale/my/torbutton.dtd b/chrome/locale/my/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/my/torbutton.dtd
rename to chrome/locale/my/torbutton.dtd
diff --git a/src/chrome/locale/my/torbutton.properties b/chrome/locale/my/torbutton.properties
similarity index 100%
rename from src/chrome/locale/my/torbutton.properties
rename to chrome/locale/my/torbutton.properties
diff --git a/src/chrome/locale/nah/aboutTor.dtd b/chrome/locale/nah/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/nah/aboutTor.dtd
rename to chrome/locale/nah/aboutTor.dtd
diff --git a/src/chrome/locale/nah/brand.dtd b/chrome/locale/nah/brand.dtd
similarity index 100%
rename from src/chrome/locale/nah/brand.dtd
rename to chrome/locale/nah/brand.dtd
diff --git a/src/chrome/locale/nah/brand.properties b/chrome/locale/nah/brand.properties
similarity index 100%
rename from src/chrome/locale/nah/brand.properties
rename to chrome/locale/nah/brand.properties
diff --git a/src/chrome/locale/nah/torbutton.dtd b/chrome/locale/nah/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/nah/torbutton.dtd
rename to chrome/locale/nah/torbutton.dtd
diff --git a/src/chrome/locale/nah/torbutton.properties b/chrome/locale/nah/torbutton.properties
similarity index 100%
rename from src/chrome/locale/nah/torbutton.properties
rename to chrome/locale/nah/torbutton.properties
diff --git a/src/chrome/locale/nap/aboutTor.dtd b/chrome/locale/nap/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/nap/aboutTor.dtd
rename to chrome/locale/nap/aboutTor.dtd
diff --git a/src/chrome/locale/nap/brand.dtd b/chrome/locale/nap/brand.dtd
similarity index 100%
rename from src/chrome/locale/nap/brand.dtd
rename to chrome/locale/nap/brand.dtd
diff --git a/src/chrome/locale/nap/brand.properties b/chrome/locale/nap/brand.properties
similarity index 100%
rename from src/chrome/locale/nap/brand.properties
rename to chrome/locale/nap/brand.properties
diff --git a/src/chrome/locale/nap/torbutton.dtd b/chrome/locale/nap/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/nap/torbutton.dtd
rename to chrome/locale/nap/torbutton.dtd
diff --git a/src/chrome/locale/nap/torbutton.properties b/chrome/locale/nap/torbutton.properties
similarity index 100%
rename from src/chrome/locale/nap/torbutton.properties
rename to chrome/locale/nap/torbutton.properties
diff --git a/src/chrome/locale/nb-NO/aboutDialog.dtd b/chrome/locale/nb-NO/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/nb-NO/aboutDialog.dtd
rename to chrome/locale/nb-NO/aboutDialog.dtd
diff --git a/src/chrome/locale/nb-NO/aboutTBUpdate.dtd b/chrome/locale/nb-NO/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/nb-NO/aboutTBUpdate.dtd
rename to chrome/locale/nb-NO/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/nb-NO/aboutTor.dtd b/chrome/locale/nb-NO/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/nb-NO/aboutTor.dtd
rename to chrome/locale/nb-NO/aboutTor.dtd
diff --git a/src/chrome/locale/nb-NO/brand.dtd b/chrome/locale/nb-NO/brand.dtd
similarity index 100%
rename from src/chrome/locale/nb-NO/brand.dtd
rename to chrome/locale/nb-NO/brand.dtd
diff --git a/src/chrome/locale/nb-NO/brand.properties b/chrome/locale/nb-NO/brand.properties
similarity index 100%
rename from src/chrome/locale/nb-NO/brand.properties
rename to chrome/locale/nb-NO/brand.properties
diff --git a/src/chrome/locale/nb-NO/browserOnboarding.properties b/chrome/locale/nb-NO/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/nb-NO/browserOnboarding.properties
rename to chrome/locale/nb-NO/browserOnboarding.properties
diff --git a/src/chrome/locale/nb-NO/securityLevel.properties b/chrome/locale/nb-NO/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/nb-NO/securityLevel.properties
rename to chrome/locale/nb-NO/securityLevel.properties
diff --git a/src/chrome/locale/nb-NO/torbutton.dtd b/chrome/locale/nb-NO/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/nb-NO/torbutton.dtd
rename to chrome/locale/nb-NO/torbutton.dtd
diff --git a/src/chrome/locale/nb-NO/torbutton.properties b/chrome/locale/nb-NO/torbutton.properties
similarity index 100%
rename from src/chrome/locale/nb-NO/torbutton.properties
rename to chrome/locale/nb-NO/torbutton.properties
diff --git a/src/chrome/locale/ne/aboutTor.dtd b/chrome/locale/ne/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/ne/aboutTor.dtd
rename to chrome/locale/ne/aboutTor.dtd
diff --git a/src/chrome/locale/ne/brand.dtd b/chrome/locale/ne/brand.dtd
similarity index 100%
rename from src/chrome/locale/ne/brand.dtd
rename to chrome/locale/ne/brand.dtd
diff --git a/src/chrome/locale/ne/brand.properties b/chrome/locale/ne/brand.properties
similarity index 100%
rename from src/chrome/locale/ne/brand.properties
rename to chrome/locale/ne/brand.properties
diff --git a/src/chrome/locale/ne/torbutton.dtd b/chrome/locale/ne/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/ne/torbutton.dtd
rename to chrome/locale/ne/torbutton.dtd
diff --git a/src/chrome/locale/ne/torbutton.properties b/chrome/locale/ne/torbutton.properties
similarity index 100%
rename from src/chrome/locale/ne/torbutton.properties
rename to chrome/locale/ne/torbutton.properties
diff --git a/src/chrome/locale/nl/aboutDialog.dtd b/chrome/locale/nl/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/nl/aboutDialog.dtd
rename to chrome/locale/nl/aboutDialog.dtd
diff --git a/src/chrome/locale/nl/aboutTBUpdate.dtd b/chrome/locale/nl/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/nl/aboutTBUpdate.dtd
rename to chrome/locale/nl/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/nl/aboutTor.dtd b/chrome/locale/nl/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/nl/aboutTor.dtd
rename to chrome/locale/nl/aboutTor.dtd
diff --git a/src/chrome/locale/nl/brand.dtd b/chrome/locale/nl/brand.dtd
similarity index 100%
rename from src/chrome/locale/nl/brand.dtd
rename to chrome/locale/nl/brand.dtd
diff --git a/src/chrome/locale/nl/brand.properties b/chrome/locale/nl/brand.properties
similarity index 100%
rename from src/chrome/locale/nl/brand.properties
rename to chrome/locale/nl/brand.properties
diff --git a/src/chrome/locale/nl/browserOnboarding.properties b/chrome/locale/nl/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/nl/browserOnboarding.properties
rename to chrome/locale/nl/browserOnboarding.properties
diff --git a/src/chrome/locale/nl/securityLevel.properties b/chrome/locale/nl/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/nl/securityLevel.properties
rename to chrome/locale/nl/securityLevel.properties
diff --git a/src/chrome/locale/nl/torbutton.dtd b/chrome/locale/nl/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/nl/torbutton.dtd
rename to chrome/locale/nl/torbutton.dtd
diff --git a/src/chrome/locale/nl/torbutton.properties b/chrome/locale/nl/torbutton.properties
similarity index 100%
rename from src/chrome/locale/nl/torbutton.properties
rename to chrome/locale/nl/torbutton.properties
diff --git a/src/chrome/locale/nn/aboutTor.dtd b/chrome/locale/nn/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/nn/aboutTor.dtd
rename to chrome/locale/nn/aboutTor.dtd
diff --git a/src/chrome/locale/nn/brand.dtd b/chrome/locale/nn/brand.dtd
similarity index 100%
rename from src/chrome/locale/nn/brand.dtd
rename to chrome/locale/nn/brand.dtd
diff --git a/src/chrome/locale/nn/brand.properties b/chrome/locale/nn/brand.properties
similarity index 100%
rename from src/chrome/locale/nn/brand.properties
rename to chrome/locale/nn/brand.properties
diff --git a/src/chrome/locale/nn/torbutton.dtd b/chrome/locale/nn/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/nn/torbutton.dtd
rename to chrome/locale/nn/torbutton.dtd
diff --git a/src/chrome/locale/nn/torbutton.properties b/chrome/locale/nn/torbutton.properties
similarity index 100%
rename from src/chrome/locale/nn/torbutton.properties
rename to chrome/locale/nn/torbutton.properties
diff --git a/src/chrome/locale/nso/aboutTor.dtd b/chrome/locale/nso/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/nso/aboutTor.dtd
rename to chrome/locale/nso/aboutTor.dtd
diff --git a/src/chrome/locale/nso/brand.dtd b/chrome/locale/nso/brand.dtd
similarity index 100%
rename from src/chrome/locale/nso/brand.dtd
rename to chrome/locale/nso/brand.dtd
diff --git a/src/chrome/locale/nso/brand.properties b/chrome/locale/nso/brand.properties
similarity index 100%
rename from src/chrome/locale/nso/brand.properties
rename to chrome/locale/nso/brand.properties
diff --git a/src/chrome/locale/nso/torbutton.dtd b/chrome/locale/nso/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/nso/torbutton.dtd
rename to chrome/locale/nso/torbutton.dtd
diff --git a/src/chrome/locale/nso/torbutton.properties b/chrome/locale/nso/torbutton.properties
similarity index 100%
rename from src/chrome/locale/nso/torbutton.properties
rename to chrome/locale/nso/torbutton.properties
diff --git a/src/chrome/locale/oc/aboutTor.dtd b/chrome/locale/oc/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/oc/aboutTor.dtd
rename to chrome/locale/oc/aboutTor.dtd
diff --git a/src/chrome/locale/oc/brand.dtd b/chrome/locale/oc/brand.dtd
similarity index 100%
rename from src/chrome/locale/oc/brand.dtd
rename to chrome/locale/oc/brand.dtd
diff --git a/src/chrome/locale/oc/brand.properties b/chrome/locale/oc/brand.properties
similarity index 100%
rename from src/chrome/locale/oc/brand.properties
rename to chrome/locale/oc/brand.properties
diff --git a/src/chrome/locale/oc/torbutton.dtd b/chrome/locale/oc/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/oc/torbutton.dtd
rename to chrome/locale/oc/torbutton.dtd
diff --git a/src/chrome/locale/oc/torbutton.properties b/chrome/locale/oc/torbutton.properties
similarity index 100%
rename from src/chrome/locale/oc/torbutton.properties
rename to chrome/locale/oc/torbutton.properties
diff --git a/src/chrome/locale/or/aboutTor.dtd b/chrome/locale/or/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/or/aboutTor.dtd
rename to chrome/locale/or/aboutTor.dtd
diff --git a/src/chrome/locale/or/brand.dtd b/chrome/locale/or/brand.dtd
similarity index 100%
rename from src/chrome/locale/or/brand.dtd
rename to chrome/locale/or/brand.dtd
diff --git a/src/chrome/locale/or/brand.properties b/chrome/locale/or/brand.properties
similarity index 100%
rename from src/chrome/locale/or/brand.properties
rename to chrome/locale/or/brand.properties
diff --git a/src/chrome/locale/or/torbutton.dtd b/chrome/locale/or/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/or/torbutton.dtd
rename to chrome/locale/or/torbutton.dtd
diff --git a/src/chrome/locale/or/torbutton.properties b/chrome/locale/or/torbutton.properties
similarity index 100%
rename from src/chrome/locale/or/torbutton.properties
rename to chrome/locale/or/torbutton.properties
diff --git a/src/chrome/locale/pa/aboutTor.dtd b/chrome/locale/pa/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/pa/aboutTor.dtd
rename to chrome/locale/pa/aboutTor.dtd
diff --git a/src/chrome/locale/pa/brand.dtd b/chrome/locale/pa/brand.dtd
similarity index 100%
rename from src/chrome/locale/pa/brand.dtd
rename to chrome/locale/pa/brand.dtd
diff --git a/src/chrome/locale/pa/brand.properties b/chrome/locale/pa/brand.properties
similarity index 100%
rename from src/chrome/locale/pa/brand.properties
rename to chrome/locale/pa/brand.properties
diff --git a/src/chrome/locale/pa/torbutton.dtd b/chrome/locale/pa/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/pa/torbutton.dtd
rename to chrome/locale/pa/torbutton.dtd
diff --git a/src/chrome/locale/pa/torbutton.properties b/chrome/locale/pa/torbutton.properties
similarity index 100%
rename from src/chrome/locale/pa/torbutton.properties
rename to chrome/locale/pa/torbutton.properties
diff --git a/src/chrome/locale/pap/aboutTor.dtd b/chrome/locale/pap/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/pap/aboutTor.dtd
rename to chrome/locale/pap/aboutTor.dtd
diff --git a/src/chrome/locale/pap/brand.dtd b/chrome/locale/pap/brand.dtd
similarity index 100%
rename from src/chrome/locale/pap/brand.dtd
rename to chrome/locale/pap/brand.dtd
diff --git a/src/chrome/locale/pap/brand.properties b/chrome/locale/pap/brand.properties
similarity index 100%
rename from src/chrome/locale/pap/brand.properties
rename to chrome/locale/pap/brand.properties
diff --git a/src/chrome/locale/pap/torbutton.dtd b/chrome/locale/pap/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/pap/torbutton.dtd
rename to chrome/locale/pap/torbutton.dtd
diff --git a/src/chrome/locale/pap/torbutton.properties b/chrome/locale/pap/torbutton.properties
similarity index 100%
rename from src/chrome/locale/pap/torbutton.properties
rename to chrome/locale/pap/torbutton.properties
diff --git a/src/chrome/locale/pl/aboutDialog.dtd b/chrome/locale/pl/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/pl/aboutDialog.dtd
rename to chrome/locale/pl/aboutDialog.dtd
diff --git a/src/chrome/locale/pl/aboutTBUpdate.dtd b/chrome/locale/pl/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/pl/aboutTBUpdate.dtd
rename to chrome/locale/pl/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/pl/aboutTor.dtd b/chrome/locale/pl/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/pl/aboutTor.dtd
rename to chrome/locale/pl/aboutTor.dtd
diff --git a/src/chrome/locale/pl/brand.dtd b/chrome/locale/pl/brand.dtd
similarity index 100%
rename from src/chrome/locale/pl/brand.dtd
rename to chrome/locale/pl/brand.dtd
diff --git a/src/chrome/locale/pl/brand.properties b/chrome/locale/pl/brand.properties
similarity index 100%
rename from src/chrome/locale/pl/brand.properties
rename to chrome/locale/pl/brand.properties
diff --git a/src/chrome/locale/pl/browserOnboarding.properties b/chrome/locale/pl/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/pl/browserOnboarding.properties
rename to chrome/locale/pl/browserOnboarding.properties
diff --git a/src/chrome/locale/pl/securityLevel.properties b/chrome/locale/pl/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/pl/securityLevel.properties
rename to chrome/locale/pl/securityLevel.properties
diff --git a/src/chrome/locale/pl/torbutton.dtd b/chrome/locale/pl/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/pl/torbutton.dtd
rename to chrome/locale/pl/torbutton.dtd
diff --git a/src/chrome/locale/pl/torbutton.properties b/chrome/locale/pl/torbutton.properties
similarity index 100%
rename from src/chrome/locale/pl/torbutton.properties
rename to chrome/locale/pl/torbutton.properties
diff --git a/src/chrome/locale/pms/aboutTor.dtd b/chrome/locale/pms/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/pms/aboutTor.dtd
rename to chrome/locale/pms/aboutTor.dtd
diff --git a/src/chrome/locale/pms/brand.dtd b/chrome/locale/pms/brand.dtd
similarity index 100%
rename from src/chrome/locale/pms/brand.dtd
rename to chrome/locale/pms/brand.dtd
diff --git a/src/chrome/locale/pms/brand.properties b/chrome/locale/pms/brand.properties
similarity index 100%
rename from src/chrome/locale/pms/brand.properties
rename to chrome/locale/pms/brand.properties
diff --git a/src/chrome/locale/pms/torbutton.dtd b/chrome/locale/pms/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/pms/torbutton.dtd
rename to chrome/locale/pms/torbutton.dtd
diff --git a/src/chrome/locale/pms/torbutton.properties b/chrome/locale/pms/torbutton.properties
similarity index 100%
rename from src/chrome/locale/pms/torbutton.properties
rename to chrome/locale/pms/torbutton.properties
diff --git a/src/chrome/locale/ps/aboutTor.dtd b/chrome/locale/ps/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/ps/aboutTor.dtd
rename to chrome/locale/ps/aboutTor.dtd
diff --git a/src/chrome/locale/ps/brand.dtd b/chrome/locale/ps/brand.dtd
similarity index 100%
rename from src/chrome/locale/ps/brand.dtd
rename to chrome/locale/ps/brand.dtd
diff --git a/src/chrome/locale/ps/brand.properties b/chrome/locale/ps/brand.properties
similarity index 100%
rename from src/chrome/locale/ps/brand.properties
rename to chrome/locale/ps/brand.properties
diff --git a/src/chrome/locale/ps/torbutton.dtd b/chrome/locale/ps/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/ps/torbutton.dtd
rename to chrome/locale/ps/torbutton.dtd
diff --git a/src/chrome/locale/ps/torbutton.properties b/chrome/locale/ps/torbutton.properties
similarity index 100%
rename from src/chrome/locale/ps/torbutton.properties
rename to chrome/locale/ps/torbutton.properties
diff --git a/src/chrome/locale/pt-BR/aboutDialog.dtd b/chrome/locale/pt-BR/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/pt-BR/aboutDialog.dtd
rename to chrome/locale/pt-BR/aboutDialog.dtd
diff --git a/src/chrome/locale/pt-BR/aboutTBUpdate.dtd b/chrome/locale/pt-BR/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/pt-BR/aboutTBUpdate.dtd
rename to chrome/locale/pt-BR/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/pt-BR/aboutTor.dtd b/chrome/locale/pt-BR/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/pt-BR/aboutTor.dtd
rename to chrome/locale/pt-BR/aboutTor.dtd
diff --git a/src/chrome/locale/pt-BR/brand.dtd b/chrome/locale/pt-BR/brand.dtd
similarity index 100%
rename from src/chrome/locale/pt-BR/brand.dtd
rename to chrome/locale/pt-BR/brand.dtd
diff --git a/src/chrome/locale/pt-BR/brand.properties b/chrome/locale/pt-BR/brand.properties
similarity index 100%
rename from src/chrome/locale/pt-BR/brand.properties
rename to chrome/locale/pt-BR/brand.properties
diff --git a/src/chrome/locale/pt-BR/browserOnboarding.properties b/chrome/locale/pt-BR/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/pt-BR/browserOnboarding.properties
rename to chrome/locale/pt-BR/browserOnboarding.properties
diff --git a/src/chrome/locale/pt-BR/securityLevel.properties b/chrome/locale/pt-BR/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/pt-BR/securityLevel.properties
rename to chrome/locale/pt-BR/securityLevel.properties
diff --git a/src/chrome/locale/pt-BR/torbutton.dtd b/chrome/locale/pt-BR/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/pt-BR/torbutton.dtd
rename to chrome/locale/pt-BR/torbutton.dtd
diff --git a/src/chrome/locale/pt-BR/torbutton.properties b/chrome/locale/pt-BR/torbutton.properties
similarity index 100%
rename from src/chrome/locale/pt-BR/torbutton.properties
rename to chrome/locale/pt-BR/torbutton.properties
diff --git a/src/chrome/locale/pt/aboutDialog.dtd b/chrome/locale/pt/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/pt/aboutDialog.dtd
rename to chrome/locale/pt/aboutDialog.dtd
diff --git a/src/chrome/locale/pt/aboutTBUpdate.dtd b/chrome/locale/pt/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/pt/aboutTBUpdate.dtd
rename to chrome/locale/pt/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/pt/aboutTor.dtd b/chrome/locale/pt/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/pt/aboutTor.dtd
rename to chrome/locale/pt/aboutTor.dtd
diff --git a/src/chrome/locale/pt/brand.dtd b/chrome/locale/pt/brand.dtd
similarity index 100%
rename from src/chrome/locale/pt/brand.dtd
rename to chrome/locale/pt/brand.dtd
diff --git a/src/chrome/locale/pt/brand.properties b/chrome/locale/pt/brand.properties
similarity index 100%
rename from src/chrome/locale/pt/brand.properties
rename to chrome/locale/pt/brand.properties
diff --git a/src/chrome/locale/pt/securityLevel.properties b/chrome/locale/pt/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/pt/securityLevel.properties
rename to chrome/locale/pt/securityLevel.properties
diff --git a/src/chrome/locale/pt/torbutton.dtd b/chrome/locale/pt/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/pt/torbutton.dtd
rename to chrome/locale/pt/torbutton.dtd
diff --git a/src/chrome/locale/pt/torbutton.properties b/chrome/locale/pt/torbutton.properties
similarity index 100%
rename from src/chrome/locale/pt/torbutton.properties
rename to chrome/locale/pt/torbutton.properties
diff --git a/src/chrome/locale/ro/aboutTor.dtd b/chrome/locale/ro/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/ro/aboutTor.dtd
rename to chrome/locale/ro/aboutTor.dtd
diff --git a/src/chrome/locale/ro/brand.dtd b/chrome/locale/ro/brand.dtd
similarity index 100%
rename from src/chrome/locale/ro/brand.dtd
rename to chrome/locale/ro/brand.dtd
diff --git a/src/chrome/locale/ro/brand.properties b/chrome/locale/ro/brand.properties
similarity index 100%
rename from src/chrome/locale/ro/brand.properties
rename to chrome/locale/ro/brand.properties
diff --git a/src/chrome/locale/ro/securityLevel.properties b/chrome/locale/ro/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/ro/securityLevel.properties
rename to chrome/locale/ro/securityLevel.properties
diff --git a/src/chrome/locale/ro/torbutton.dtd b/chrome/locale/ro/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/ro/torbutton.dtd
rename to chrome/locale/ro/torbutton.dtd
diff --git a/src/chrome/locale/ro/torbutton.properties b/chrome/locale/ro/torbutton.properties
similarity index 100%
rename from src/chrome/locale/ro/torbutton.properties
rename to chrome/locale/ro/torbutton.properties
diff --git a/src/chrome/locale/ru/aboutDialog.dtd b/chrome/locale/ru/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/ru/aboutDialog.dtd
rename to chrome/locale/ru/aboutDialog.dtd
diff --git a/src/chrome/locale/ru/aboutTBUpdate.dtd b/chrome/locale/ru/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/ru/aboutTBUpdate.dtd
rename to chrome/locale/ru/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/ru/aboutTor.dtd b/chrome/locale/ru/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/ru/aboutTor.dtd
rename to chrome/locale/ru/aboutTor.dtd
diff --git a/src/chrome/locale/ru/brand.dtd b/chrome/locale/ru/brand.dtd
similarity index 100%
rename from src/chrome/locale/ru/brand.dtd
rename to chrome/locale/ru/brand.dtd
diff --git a/src/chrome/locale/ru/brand.properties b/chrome/locale/ru/brand.properties
similarity index 100%
rename from src/chrome/locale/ru/brand.properties
rename to chrome/locale/ru/brand.properties
diff --git a/src/chrome/locale/ru/browserOnboarding.properties b/chrome/locale/ru/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/ru/browserOnboarding.properties
rename to chrome/locale/ru/browserOnboarding.properties
diff --git a/src/chrome/locale/ru/securityLevel.properties b/chrome/locale/ru/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/ru/securityLevel.properties
rename to chrome/locale/ru/securityLevel.properties
diff --git a/src/chrome/locale/ru/torbutton.dtd b/chrome/locale/ru/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/ru/torbutton.dtd
rename to chrome/locale/ru/torbutton.dtd
diff --git a/src/chrome/locale/ru/torbutton.properties b/chrome/locale/ru/torbutton.properties
similarity index 100%
rename from src/chrome/locale/ru/torbutton.properties
rename to chrome/locale/ru/torbutton.properties
diff --git a/src/chrome/locale/sco/aboutTor.dtd b/chrome/locale/sco/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/sco/aboutTor.dtd
rename to chrome/locale/sco/aboutTor.dtd
diff --git a/src/chrome/locale/sco/brand.dtd b/chrome/locale/sco/brand.dtd
similarity index 100%
rename from src/chrome/locale/sco/brand.dtd
rename to chrome/locale/sco/brand.dtd
diff --git a/src/chrome/locale/sco/brand.properties b/chrome/locale/sco/brand.properties
similarity index 100%
rename from src/chrome/locale/sco/brand.properties
rename to chrome/locale/sco/brand.properties
diff --git a/src/chrome/locale/sco/torbutton.dtd b/chrome/locale/sco/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/sco/torbutton.dtd
rename to chrome/locale/sco/torbutton.dtd
diff --git a/src/chrome/locale/sco/torbutton.properties b/chrome/locale/sco/torbutton.properties
similarity index 100%
rename from src/chrome/locale/sco/torbutton.properties
rename to chrome/locale/sco/torbutton.properties
diff --git a/src/chrome/locale/sk/aboutTor.dtd b/chrome/locale/sk/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/sk/aboutTor.dtd
rename to chrome/locale/sk/aboutTor.dtd
diff --git a/src/chrome/locale/sk/brand.dtd b/chrome/locale/sk/brand.dtd
similarity index 100%
rename from src/chrome/locale/sk/brand.dtd
rename to chrome/locale/sk/brand.dtd
diff --git a/src/chrome/locale/sk/brand.properties b/chrome/locale/sk/brand.properties
similarity index 100%
rename from src/chrome/locale/sk/brand.properties
rename to chrome/locale/sk/brand.properties
diff --git a/src/chrome/locale/sk/securityLevel.properties b/chrome/locale/sk/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/sk/securityLevel.properties
rename to chrome/locale/sk/securityLevel.properties
diff --git a/src/chrome/locale/sk/torbutton.dtd b/chrome/locale/sk/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/sk/torbutton.dtd
rename to chrome/locale/sk/torbutton.dtd
diff --git a/src/chrome/locale/sk/torbutton.properties b/chrome/locale/sk/torbutton.properties
similarity index 100%
rename from src/chrome/locale/sk/torbutton.properties
rename to chrome/locale/sk/torbutton.properties
diff --git a/src/chrome/locale/sl/aboutTor.dtd b/chrome/locale/sl/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/sl/aboutTor.dtd
rename to chrome/locale/sl/aboutTor.dtd
diff --git a/src/chrome/locale/sl/brand.dtd b/chrome/locale/sl/brand.dtd
similarity index 100%
rename from src/chrome/locale/sl/brand.dtd
rename to chrome/locale/sl/brand.dtd
diff --git a/src/chrome/locale/sl/brand.properties b/chrome/locale/sl/brand.properties
similarity index 100%
rename from src/chrome/locale/sl/brand.properties
rename to chrome/locale/sl/brand.properties
diff --git a/src/chrome/locale/sl/securityLevel.properties b/chrome/locale/sl/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/sl/securityLevel.properties
rename to chrome/locale/sl/securityLevel.properties
diff --git a/src/chrome/locale/sl/torbutton.dtd b/chrome/locale/sl/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/sl/torbutton.dtd
rename to chrome/locale/sl/torbutton.dtd
diff --git a/src/chrome/locale/sl/torbutton.properties b/chrome/locale/sl/torbutton.properties
similarity index 100%
rename from src/chrome/locale/sl/torbutton.properties
rename to chrome/locale/sl/torbutton.properties
diff --git a/src/chrome/locale/so/aboutTor.dtd b/chrome/locale/so/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/so/aboutTor.dtd
rename to chrome/locale/so/aboutTor.dtd
diff --git a/src/chrome/locale/so/brand.dtd b/chrome/locale/so/brand.dtd
similarity index 100%
rename from src/chrome/locale/so/brand.dtd
rename to chrome/locale/so/brand.dtd
diff --git a/src/chrome/locale/so/brand.properties b/chrome/locale/so/brand.properties
similarity index 100%
rename from src/chrome/locale/so/brand.properties
rename to chrome/locale/so/brand.properties
diff --git a/src/chrome/locale/so/torbutton.dtd b/chrome/locale/so/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/so/torbutton.dtd
rename to chrome/locale/so/torbutton.dtd
diff --git a/src/chrome/locale/so/torbutton.properties b/chrome/locale/so/torbutton.properties
similarity index 100%
rename from src/chrome/locale/so/torbutton.properties
rename to chrome/locale/so/torbutton.properties
diff --git a/src/chrome/locale/son/aboutTor.dtd b/chrome/locale/son/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/son/aboutTor.dtd
rename to chrome/locale/son/aboutTor.dtd
diff --git a/src/chrome/locale/son/brand.dtd b/chrome/locale/son/brand.dtd
similarity index 100%
rename from src/chrome/locale/son/brand.dtd
rename to chrome/locale/son/brand.dtd
diff --git a/src/chrome/locale/son/brand.properties b/chrome/locale/son/brand.properties
similarity index 100%
rename from src/chrome/locale/son/brand.properties
rename to chrome/locale/son/brand.properties
diff --git a/src/chrome/locale/son/torbutton.dtd b/chrome/locale/son/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/son/torbutton.dtd
rename to chrome/locale/son/torbutton.dtd
diff --git a/src/chrome/locale/son/torbutton.properties b/chrome/locale/son/torbutton.properties
similarity index 100%
rename from src/chrome/locale/son/torbutton.properties
rename to chrome/locale/son/torbutton.properties
diff --git a/src/chrome/locale/sq/aboutTor.dtd b/chrome/locale/sq/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/sq/aboutTor.dtd
rename to chrome/locale/sq/aboutTor.dtd
diff --git a/src/chrome/locale/sq/brand.dtd b/chrome/locale/sq/brand.dtd
similarity index 100%
rename from src/chrome/locale/sq/brand.dtd
rename to chrome/locale/sq/brand.dtd
diff --git a/src/chrome/locale/sq/brand.properties b/chrome/locale/sq/brand.properties
similarity index 100%
rename from src/chrome/locale/sq/brand.properties
rename to chrome/locale/sq/brand.properties
diff --git a/src/chrome/locale/sq/torbutton.dtd b/chrome/locale/sq/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/sq/torbutton.dtd
rename to chrome/locale/sq/torbutton.dtd
diff --git a/src/chrome/locale/sq/torbutton.properties b/chrome/locale/sq/torbutton.properties
similarity index 100%
rename from src/chrome/locale/sq/torbutton.properties
rename to chrome/locale/sq/torbutton.properties
diff --git a/src/chrome/locale/sr/aboutTor.dtd b/chrome/locale/sr/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/sr/aboutTor.dtd
rename to chrome/locale/sr/aboutTor.dtd
diff --git a/src/chrome/locale/sr/brand.dtd b/chrome/locale/sr/brand.dtd
similarity index 100%
rename from src/chrome/locale/sr/brand.dtd
rename to chrome/locale/sr/brand.dtd
diff --git a/src/chrome/locale/sr/brand.properties b/chrome/locale/sr/brand.properties
similarity index 100%
rename from src/chrome/locale/sr/brand.properties
rename to chrome/locale/sr/brand.properties
diff --git a/src/chrome/locale/sr/securityLevel.properties b/chrome/locale/sr/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/sr/securityLevel.properties
rename to chrome/locale/sr/securityLevel.properties
diff --git a/src/chrome/locale/sr/torbutton.dtd b/chrome/locale/sr/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/sr/torbutton.dtd
rename to chrome/locale/sr/torbutton.dtd
diff --git a/src/chrome/locale/sr/torbutton.properties b/chrome/locale/sr/torbutton.properties
similarity index 100%
rename from src/chrome/locale/sr/torbutton.properties
rename to chrome/locale/sr/torbutton.properties
diff --git a/src/chrome/locale/st/aboutTor.dtd b/chrome/locale/st/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/st/aboutTor.dtd
rename to chrome/locale/st/aboutTor.dtd
diff --git a/src/chrome/locale/st/brand.dtd b/chrome/locale/st/brand.dtd
similarity index 100%
rename from src/chrome/locale/st/brand.dtd
rename to chrome/locale/st/brand.dtd
diff --git a/src/chrome/locale/st/brand.properties b/chrome/locale/st/brand.properties
similarity index 100%
rename from src/chrome/locale/st/brand.properties
rename to chrome/locale/st/brand.properties
diff --git a/src/chrome/locale/st/torbutton.dtd b/chrome/locale/st/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/st/torbutton.dtd
rename to chrome/locale/st/torbutton.dtd
diff --git a/src/chrome/locale/st/torbutton.properties b/chrome/locale/st/torbutton.properties
similarity index 100%
rename from src/chrome/locale/st/torbutton.properties
rename to chrome/locale/st/torbutton.properties
diff --git a/src/chrome/locale/su/aboutTor.dtd b/chrome/locale/su/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/su/aboutTor.dtd
rename to chrome/locale/su/aboutTor.dtd
diff --git a/src/chrome/locale/su/brand.dtd b/chrome/locale/su/brand.dtd
similarity index 100%
rename from src/chrome/locale/su/brand.dtd
rename to chrome/locale/su/brand.dtd
diff --git a/src/chrome/locale/su/brand.properties b/chrome/locale/su/brand.properties
similarity index 100%
rename from src/chrome/locale/su/brand.properties
rename to chrome/locale/su/brand.properties
diff --git a/src/chrome/locale/su/torbutton.dtd b/chrome/locale/su/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/su/torbutton.dtd
rename to chrome/locale/su/torbutton.dtd
diff --git a/src/chrome/locale/su/torbutton.properties b/chrome/locale/su/torbutton.properties
similarity index 100%
rename from src/chrome/locale/su/torbutton.properties
rename to chrome/locale/su/torbutton.properties
diff --git a/src/chrome/locale/sv-SE/aboutDialog.dtd b/chrome/locale/sv-SE/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/sv-SE/aboutDialog.dtd
rename to chrome/locale/sv-SE/aboutDialog.dtd
diff --git a/src/chrome/locale/sv-SE/aboutTBUpdate.dtd b/chrome/locale/sv-SE/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/sv-SE/aboutTBUpdate.dtd
rename to chrome/locale/sv-SE/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/sv-SE/aboutTor.dtd b/chrome/locale/sv-SE/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/sv-SE/aboutTor.dtd
rename to chrome/locale/sv-SE/aboutTor.dtd
diff --git a/src/chrome/locale/sv-SE/brand.dtd b/chrome/locale/sv-SE/brand.dtd
similarity index 100%
rename from src/chrome/locale/sv-SE/brand.dtd
rename to chrome/locale/sv-SE/brand.dtd
diff --git a/src/chrome/locale/sv-SE/brand.properties b/chrome/locale/sv-SE/brand.properties
similarity index 100%
rename from src/chrome/locale/sv-SE/brand.properties
rename to chrome/locale/sv-SE/brand.properties
diff --git a/src/chrome/locale/sv-SE/browserOnboarding.properties b/chrome/locale/sv-SE/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/sv-SE/browserOnboarding.properties
rename to chrome/locale/sv-SE/browserOnboarding.properties
diff --git a/src/chrome/locale/sv-SE/securityLevel.properties b/chrome/locale/sv-SE/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/sv-SE/securityLevel.properties
rename to chrome/locale/sv-SE/securityLevel.properties
diff --git a/src/chrome/locale/sv-SE/torbutton.dtd b/chrome/locale/sv-SE/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/sv-SE/torbutton.dtd
rename to chrome/locale/sv-SE/torbutton.dtd
diff --git a/src/chrome/locale/sv-SE/torbutton.properties b/chrome/locale/sv-SE/torbutton.properties
similarity index 100%
rename from src/chrome/locale/sv-SE/torbutton.properties
rename to chrome/locale/sv-SE/torbutton.properties
diff --git a/src/chrome/locale/sw/aboutTor.dtd b/chrome/locale/sw/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/sw/aboutTor.dtd
rename to chrome/locale/sw/aboutTor.dtd
diff --git a/src/chrome/locale/sw/brand.dtd b/chrome/locale/sw/brand.dtd
similarity index 100%
rename from src/chrome/locale/sw/brand.dtd
rename to chrome/locale/sw/brand.dtd
diff --git a/src/chrome/locale/sw/brand.properties b/chrome/locale/sw/brand.properties
similarity index 100%
rename from src/chrome/locale/sw/brand.properties
rename to chrome/locale/sw/brand.properties
diff --git a/src/chrome/locale/sw/torbutton.dtd b/chrome/locale/sw/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/sw/torbutton.dtd
rename to chrome/locale/sw/torbutton.dtd
diff --git a/src/chrome/locale/sw/torbutton.properties b/chrome/locale/sw/torbutton.properties
similarity index 100%
rename from src/chrome/locale/sw/torbutton.properties
rename to chrome/locale/sw/torbutton.properties
diff --git a/src/chrome/locale/ta/aboutTor.dtd b/chrome/locale/ta/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/ta/aboutTor.dtd
rename to chrome/locale/ta/aboutTor.dtd
diff --git a/src/chrome/locale/ta/brand.dtd b/chrome/locale/ta/brand.dtd
similarity index 100%
rename from src/chrome/locale/ta/brand.dtd
rename to chrome/locale/ta/brand.dtd
diff --git a/src/chrome/locale/ta/brand.properties b/chrome/locale/ta/brand.properties
similarity index 100%
rename from src/chrome/locale/ta/brand.properties
rename to chrome/locale/ta/brand.properties
diff --git a/src/chrome/locale/ta/torbutton.dtd b/chrome/locale/ta/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/ta/torbutton.dtd
rename to chrome/locale/ta/torbutton.dtd
diff --git a/src/chrome/locale/ta/torbutton.properties b/chrome/locale/ta/torbutton.properties
similarity index 100%
rename from src/chrome/locale/ta/torbutton.properties
rename to chrome/locale/ta/torbutton.properties
diff --git a/src/chrome/locale/te/aboutTor.dtd b/chrome/locale/te/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/te/aboutTor.dtd
rename to chrome/locale/te/aboutTor.dtd
diff --git a/src/chrome/locale/te/brand.dtd b/chrome/locale/te/brand.dtd
similarity index 100%
rename from src/chrome/locale/te/brand.dtd
rename to chrome/locale/te/brand.dtd
diff --git a/src/chrome/locale/te/brand.properties b/chrome/locale/te/brand.properties
similarity index 100%
rename from src/chrome/locale/te/brand.properties
rename to chrome/locale/te/brand.properties
diff --git a/src/chrome/locale/te/torbutton.dtd b/chrome/locale/te/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/te/torbutton.dtd
rename to chrome/locale/te/torbutton.dtd
diff --git a/src/chrome/locale/te/torbutton.properties b/chrome/locale/te/torbutton.properties
similarity index 100%
rename from src/chrome/locale/te/torbutton.properties
rename to chrome/locale/te/torbutton.properties
diff --git a/src/chrome/locale/tg/aboutTor.dtd b/chrome/locale/tg/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/tg/aboutTor.dtd
rename to chrome/locale/tg/aboutTor.dtd
diff --git a/src/chrome/locale/tg/brand.dtd b/chrome/locale/tg/brand.dtd
similarity index 100%
rename from src/chrome/locale/tg/brand.dtd
rename to chrome/locale/tg/brand.dtd
diff --git a/src/chrome/locale/tg/brand.properties b/chrome/locale/tg/brand.properties
similarity index 100%
rename from src/chrome/locale/tg/brand.properties
rename to chrome/locale/tg/brand.properties
diff --git a/src/chrome/locale/tg/torbutton.dtd b/chrome/locale/tg/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/tg/torbutton.dtd
rename to chrome/locale/tg/torbutton.dtd
diff --git a/src/chrome/locale/tg/torbutton.properties b/chrome/locale/tg/torbutton.properties
similarity index 100%
rename from src/chrome/locale/tg/torbutton.properties
rename to chrome/locale/tg/torbutton.properties
diff --git a/src/chrome/locale/th/aboutTor.dtd b/chrome/locale/th/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/th/aboutTor.dtd
rename to chrome/locale/th/aboutTor.dtd
diff --git a/src/chrome/locale/th/brand.dtd b/chrome/locale/th/brand.dtd
similarity index 100%
rename from src/chrome/locale/th/brand.dtd
rename to chrome/locale/th/brand.dtd
diff --git a/src/chrome/locale/th/brand.properties b/chrome/locale/th/brand.properties
similarity index 100%
rename from src/chrome/locale/th/brand.properties
rename to chrome/locale/th/brand.properties
diff --git a/src/chrome/locale/th/torbutton.dtd b/chrome/locale/th/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/th/torbutton.dtd
rename to chrome/locale/th/torbutton.dtd
diff --git a/src/chrome/locale/th/torbutton.properties b/chrome/locale/th/torbutton.properties
similarity index 100%
rename from src/chrome/locale/th/torbutton.properties
rename to chrome/locale/th/torbutton.properties
diff --git a/src/chrome/locale/ti/aboutTor.dtd b/chrome/locale/ti/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/ti/aboutTor.dtd
rename to chrome/locale/ti/aboutTor.dtd
diff --git a/src/chrome/locale/ti/brand.dtd b/chrome/locale/ti/brand.dtd
similarity index 100%
rename from src/chrome/locale/ti/brand.dtd
rename to chrome/locale/ti/brand.dtd
diff --git a/src/chrome/locale/ti/brand.properties b/chrome/locale/ti/brand.properties
similarity index 100%
rename from src/chrome/locale/ti/brand.properties
rename to chrome/locale/ti/brand.properties
diff --git a/src/chrome/locale/ti/torbutton.dtd b/chrome/locale/ti/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/ti/torbutton.dtd
rename to chrome/locale/ti/torbutton.dtd
diff --git a/src/chrome/locale/ti/torbutton.properties b/chrome/locale/ti/torbutton.properties
similarity index 100%
rename from src/chrome/locale/ti/torbutton.properties
rename to chrome/locale/ti/torbutton.properties
diff --git a/src/chrome/locale/tk/aboutTor.dtd b/chrome/locale/tk/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/tk/aboutTor.dtd
rename to chrome/locale/tk/aboutTor.dtd
diff --git a/src/chrome/locale/tk/brand.dtd b/chrome/locale/tk/brand.dtd
similarity index 100%
rename from src/chrome/locale/tk/brand.dtd
rename to chrome/locale/tk/brand.dtd
diff --git a/src/chrome/locale/tk/brand.properties b/chrome/locale/tk/brand.properties
similarity index 100%
rename from src/chrome/locale/tk/brand.properties
rename to chrome/locale/tk/brand.properties
diff --git a/src/chrome/locale/tk/torbutton.dtd b/chrome/locale/tk/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/tk/torbutton.dtd
rename to chrome/locale/tk/torbutton.dtd
diff --git a/src/chrome/locale/tk/torbutton.properties b/chrome/locale/tk/torbutton.properties
similarity index 100%
rename from src/chrome/locale/tk/torbutton.properties
rename to chrome/locale/tk/torbutton.properties
diff --git a/src/chrome/locale/tr/aboutDialog.dtd b/chrome/locale/tr/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/tr/aboutDialog.dtd
rename to chrome/locale/tr/aboutDialog.dtd
diff --git a/src/chrome/locale/tr/aboutTBUpdate.dtd b/chrome/locale/tr/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/tr/aboutTBUpdate.dtd
rename to chrome/locale/tr/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/tr/aboutTor.dtd b/chrome/locale/tr/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/tr/aboutTor.dtd
rename to chrome/locale/tr/aboutTor.dtd
diff --git a/src/chrome/locale/tr/brand.dtd b/chrome/locale/tr/brand.dtd
similarity index 100%
rename from src/chrome/locale/tr/brand.dtd
rename to chrome/locale/tr/brand.dtd
diff --git a/src/chrome/locale/tr/brand.properties b/chrome/locale/tr/brand.properties
similarity index 100%
rename from src/chrome/locale/tr/brand.properties
rename to chrome/locale/tr/brand.properties
diff --git a/src/chrome/locale/tr/browserOnboarding.properties b/chrome/locale/tr/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/tr/browserOnboarding.properties
rename to chrome/locale/tr/browserOnboarding.properties
diff --git a/src/chrome/locale/tr/securityLevel.properties b/chrome/locale/tr/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/tr/securityLevel.properties
rename to chrome/locale/tr/securityLevel.properties
diff --git a/src/chrome/locale/tr/torbutton.dtd b/chrome/locale/tr/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/tr/torbutton.dtd
rename to chrome/locale/tr/torbutton.dtd
diff --git a/src/chrome/locale/tr/torbutton.properties b/chrome/locale/tr/torbutton.properties
similarity index 100%
rename from src/chrome/locale/tr/torbutton.properties
rename to chrome/locale/tr/torbutton.properties
diff --git a/src/chrome/locale/uk/aboutTor.dtd b/chrome/locale/uk/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/uk/aboutTor.dtd
rename to chrome/locale/uk/aboutTor.dtd
diff --git a/src/chrome/locale/uk/brand.dtd b/chrome/locale/uk/brand.dtd
similarity index 100%
rename from src/chrome/locale/uk/brand.dtd
rename to chrome/locale/uk/brand.dtd
diff --git a/src/chrome/locale/uk/brand.properties b/chrome/locale/uk/brand.properties
similarity index 100%
rename from src/chrome/locale/uk/brand.properties
rename to chrome/locale/uk/brand.properties
diff --git a/src/chrome/locale/uk/securityLevel.properties b/chrome/locale/uk/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/uk/securityLevel.properties
rename to chrome/locale/uk/securityLevel.properties
diff --git a/src/chrome/locale/uk/torbutton.dtd b/chrome/locale/uk/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/uk/torbutton.dtd
rename to chrome/locale/uk/torbutton.dtd
diff --git a/src/chrome/locale/uk/torbutton.properties b/chrome/locale/uk/torbutton.properties
similarity index 100%
rename from src/chrome/locale/uk/torbutton.properties
rename to chrome/locale/uk/torbutton.properties
diff --git a/src/chrome/locale/ur/aboutTor.dtd b/chrome/locale/ur/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/ur/aboutTor.dtd
rename to chrome/locale/ur/aboutTor.dtd
diff --git a/src/chrome/locale/ur/brand.dtd b/chrome/locale/ur/brand.dtd
similarity index 100%
rename from src/chrome/locale/ur/brand.dtd
rename to chrome/locale/ur/brand.dtd
diff --git a/src/chrome/locale/ur/brand.properties b/chrome/locale/ur/brand.properties
similarity index 100%
rename from src/chrome/locale/ur/brand.properties
rename to chrome/locale/ur/brand.properties
diff --git a/src/chrome/locale/ur/torbutton.dtd b/chrome/locale/ur/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/ur/torbutton.dtd
rename to chrome/locale/ur/torbutton.dtd
diff --git a/src/chrome/locale/ur/torbutton.properties b/chrome/locale/ur/torbutton.properties
similarity index 100%
rename from src/chrome/locale/ur/torbutton.properties
rename to chrome/locale/ur/torbutton.properties
diff --git a/src/chrome/locale/ve/aboutTor.dtd b/chrome/locale/ve/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/ve/aboutTor.dtd
rename to chrome/locale/ve/aboutTor.dtd
diff --git a/src/chrome/locale/ve/brand.dtd b/chrome/locale/ve/brand.dtd
similarity index 100%
rename from src/chrome/locale/ve/brand.dtd
rename to chrome/locale/ve/brand.dtd
diff --git a/src/chrome/locale/ve/brand.properties b/chrome/locale/ve/brand.properties
similarity index 100%
rename from src/chrome/locale/ve/brand.properties
rename to chrome/locale/ve/brand.properties
diff --git a/src/chrome/locale/ve/torbutton.dtd b/chrome/locale/ve/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/ve/torbutton.dtd
rename to chrome/locale/ve/torbutton.dtd
diff --git a/src/chrome/locale/ve/torbutton.properties b/chrome/locale/ve/torbutton.properties
similarity index 100%
rename from src/chrome/locale/ve/torbutton.properties
rename to chrome/locale/ve/torbutton.properties
diff --git a/src/chrome/locale/vi/aboutDialog.dtd b/chrome/locale/vi/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/vi/aboutDialog.dtd
rename to chrome/locale/vi/aboutDialog.dtd
diff --git a/src/chrome/locale/vi/aboutTBUpdate.dtd b/chrome/locale/vi/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/vi/aboutTBUpdate.dtd
rename to chrome/locale/vi/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/vi/aboutTor.dtd b/chrome/locale/vi/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/vi/aboutTor.dtd
rename to chrome/locale/vi/aboutTor.dtd
diff --git a/src/chrome/locale/vi/brand.dtd b/chrome/locale/vi/brand.dtd
similarity index 100%
rename from src/chrome/locale/vi/brand.dtd
rename to chrome/locale/vi/brand.dtd
diff --git a/src/chrome/locale/vi/brand.properties b/chrome/locale/vi/brand.properties
similarity index 100%
rename from src/chrome/locale/vi/brand.properties
rename to chrome/locale/vi/brand.properties
diff --git a/src/chrome/locale/vi/browserOnboarding.properties b/chrome/locale/vi/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/vi/browserOnboarding.properties
rename to chrome/locale/vi/browserOnboarding.properties
diff --git a/src/chrome/locale/vi/securityLevel.properties b/chrome/locale/vi/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/vi/securityLevel.properties
rename to chrome/locale/vi/securityLevel.properties
diff --git a/src/chrome/locale/vi/torbutton.dtd b/chrome/locale/vi/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/vi/torbutton.dtd
rename to chrome/locale/vi/torbutton.dtd
diff --git a/src/chrome/locale/vi/torbutton.properties b/chrome/locale/vi/torbutton.properties
similarity index 100%
rename from src/chrome/locale/vi/torbutton.properties
rename to chrome/locale/vi/torbutton.properties
diff --git a/src/chrome/locale/wa/aboutTor.dtd b/chrome/locale/wa/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/wa/aboutTor.dtd
rename to chrome/locale/wa/aboutTor.dtd
diff --git a/src/chrome/locale/wa/brand.dtd b/chrome/locale/wa/brand.dtd
similarity index 100%
rename from src/chrome/locale/wa/brand.dtd
rename to chrome/locale/wa/brand.dtd
diff --git a/src/chrome/locale/wa/brand.properties b/chrome/locale/wa/brand.properties
similarity index 100%
rename from src/chrome/locale/wa/brand.properties
rename to chrome/locale/wa/brand.properties
diff --git a/src/chrome/locale/wa/torbutton.dtd b/chrome/locale/wa/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/wa/torbutton.dtd
rename to chrome/locale/wa/torbutton.dtd
diff --git a/src/chrome/locale/wa/torbutton.properties b/chrome/locale/wa/torbutton.properties
similarity index 100%
rename from src/chrome/locale/wa/torbutton.properties
rename to chrome/locale/wa/torbutton.properties
diff --git a/src/chrome/locale/wo/aboutTor.dtd b/chrome/locale/wo/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/wo/aboutTor.dtd
rename to chrome/locale/wo/aboutTor.dtd
diff --git a/src/chrome/locale/wo/brand.dtd b/chrome/locale/wo/brand.dtd
similarity index 100%
rename from src/chrome/locale/wo/brand.dtd
rename to chrome/locale/wo/brand.dtd
diff --git a/src/chrome/locale/wo/brand.properties b/chrome/locale/wo/brand.properties
similarity index 100%
rename from src/chrome/locale/wo/brand.properties
rename to chrome/locale/wo/brand.properties
diff --git a/src/chrome/locale/wo/torbutton.dtd b/chrome/locale/wo/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/wo/torbutton.dtd
rename to chrome/locale/wo/torbutton.dtd
diff --git a/src/chrome/locale/wo/torbutton.properties b/chrome/locale/wo/torbutton.properties
similarity index 100%
rename from src/chrome/locale/wo/torbutton.properties
rename to chrome/locale/wo/torbutton.properties
diff --git a/src/chrome/locale/zh-CN/aboutDialog.dtd b/chrome/locale/zh-CN/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/zh-CN/aboutDialog.dtd
rename to chrome/locale/zh-CN/aboutDialog.dtd
diff --git a/src/chrome/locale/zh-CN/aboutTBUpdate.dtd b/chrome/locale/zh-CN/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/zh-CN/aboutTBUpdate.dtd
rename to chrome/locale/zh-CN/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/zh-CN/aboutTor.dtd b/chrome/locale/zh-CN/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/zh-CN/aboutTor.dtd
rename to chrome/locale/zh-CN/aboutTor.dtd
diff --git a/src/chrome/locale/zh-CN/brand.dtd b/chrome/locale/zh-CN/brand.dtd
similarity index 100%
rename from src/chrome/locale/zh-CN/brand.dtd
rename to chrome/locale/zh-CN/brand.dtd
diff --git a/src/chrome/locale/zh-CN/brand.properties b/chrome/locale/zh-CN/brand.properties
similarity index 100%
rename from src/chrome/locale/zh-CN/brand.properties
rename to chrome/locale/zh-CN/brand.properties
diff --git a/src/chrome/locale/zh-CN/browserOnboarding.properties b/chrome/locale/zh-CN/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/zh-CN/browserOnboarding.properties
rename to chrome/locale/zh-CN/browserOnboarding.properties
diff --git a/src/chrome/locale/zh-CN/securityLevel.properties b/chrome/locale/zh-CN/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/zh-CN/securityLevel.properties
rename to chrome/locale/zh-CN/securityLevel.properties
diff --git a/src/chrome/locale/zh-CN/torbutton.dtd b/chrome/locale/zh-CN/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/zh-CN/torbutton.dtd
rename to chrome/locale/zh-CN/torbutton.dtd
diff --git a/src/chrome/locale/zh-CN/torbutton.properties b/chrome/locale/zh-CN/torbutton.properties
similarity index 100%
rename from src/chrome/locale/zh-CN/torbutton.properties
rename to chrome/locale/zh-CN/torbutton.properties
diff --git a/src/chrome/locale/zh-HK/aboutTor.dtd b/chrome/locale/zh-HK/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/zh-HK/aboutTor.dtd
rename to chrome/locale/zh-HK/aboutTor.dtd
diff --git a/src/chrome/locale/zh-HK/brand.dtd b/chrome/locale/zh-HK/brand.dtd
similarity index 100%
rename from src/chrome/locale/zh-HK/brand.dtd
rename to chrome/locale/zh-HK/brand.dtd
diff --git a/src/chrome/locale/zh-HK/brand.properties b/chrome/locale/zh-HK/brand.properties
similarity index 100%
rename from src/chrome/locale/zh-HK/brand.properties
rename to chrome/locale/zh-HK/brand.properties
diff --git a/src/chrome/locale/zh-HK/torbutton.dtd b/chrome/locale/zh-HK/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/zh-HK/torbutton.dtd
rename to chrome/locale/zh-HK/torbutton.dtd
diff --git a/src/chrome/locale/zh-HK/torbutton.properties b/chrome/locale/zh-HK/torbutton.properties
similarity index 100%
rename from src/chrome/locale/zh-HK/torbutton.properties
rename to chrome/locale/zh-HK/torbutton.properties
diff --git a/src/chrome/locale/zh-TW/aboutDialog.dtd b/chrome/locale/zh-TW/aboutDialog.dtd
similarity index 100%
rename from src/chrome/locale/zh-TW/aboutDialog.dtd
rename to chrome/locale/zh-TW/aboutDialog.dtd
diff --git a/src/chrome/locale/zh-TW/aboutTBUpdate.dtd b/chrome/locale/zh-TW/aboutTBUpdate.dtd
similarity index 100%
rename from src/chrome/locale/zh-TW/aboutTBUpdate.dtd
rename to chrome/locale/zh-TW/aboutTBUpdate.dtd
diff --git a/src/chrome/locale/zh-TW/aboutTor.dtd b/chrome/locale/zh-TW/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/zh-TW/aboutTor.dtd
rename to chrome/locale/zh-TW/aboutTor.dtd
diff --git a/src/chrome/locale/zh-TW/brand.dtd b/chrome/locale/zh-TW/brand.dtd
similarity index 100%
rename from src/chrome/locale/zh-TW/brand.dtd
rename to chrome/locale/zh-TW/brand.dtd
diff --git a/src/chrome/locale/zh-TW/brand.properties b/chrome/locale/zh-TW/brand.properties
similarity index 100%
rename from src/chrome/locale/zh-TW/brand.properties
rename to chrome/locale/zh-TW/brand.properties
diff --git a/src/chrome/locale/zh-TW/browserOnboarding.properties b/chrome/locale/zh-TW/browserOnboarding.properties
similarity index 100%
rename from src/chrome/locale/zh-TW/browserOnboarding.properties
rename to chrome/locale/zh-TW/browserOnboarding.properties
diff --git a/src/chrome/locale/zh-TW/securityLevel.properties b/chrome/locale/zh-TW/securityLevel.properties
similarity index 100%
rename from src/chrome/locale/zh-TW/securityLevel.properties
rename to chrome/locale/zh-TW/securityLevel.properties
diff --git a/src/chrome/locale/zh-TW/torbutton.dtd b/chrome/locale/zh-TW/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/zh-TW/torbutton.dtd
rename to chrome/locale/zh-TW/torbutton.dtd
diff --git a/src/chrome/locale/zh-TW/torbutton.properties b/chrome/locale/zh-TW/torbutton.properties
similarity index 100%
rename from src/chrome/locale/zh-TW/torbutton.properties
rename to chrome/locale/zh-TW/torbutton.properties
diff --git a/src/chrome/locale/zu/aboutTor.dtd b/chrome/locale/zu/aboutTor.dtd
similarity index 100%
rename from src/chrome/locale/zu/aboutTor.dtd
rename to chrome/locale/zu/aboutTor.dtd
diff --git a/src/chrome/locale/zu/brand.dtd b/chrome/locale/zu/brand.dtd
similarity index 100%
rename from src/chrome/locale/zu/brand.dtd
rename to chrome/locale/zu/brand.dtd
diff --git a/src/chrome/locale/zu/brand.properties b/chrome/locale/zu/brand.properties
similarity index 100%
rename from src/chrome/locale/zu/brand.properties
rename to chrome/locale/zu/brand.properties
diff --git a/src/chrome/locale/zu/torbutton.dtd b/chrome/locale/zu/torbutton.dtd
similarity index 100%
rename from src/chrome/locale/zu/torbutton.dtd
rename to chrome/locale/zu/torbutton.dtd
diff --git a/src/chrome/locale/zu/torbutton.properties b/chrome/locale/zu/torbutton.properties
similarity index 100%
rename from src/chrome/locale/zu/torbutton.properties
rename to chrome/locale/zu/torbutton.properties
diff --git a/src/chrome/skin/about-wordmark.png b/chrome/skin/about-wordmark.png
similarity index 100%
rename from src/chrome/skin/about-wordmark.png
rename to chrome/skin/about-wordmark.png
diff --git a/src/chrome/skin/aboutDialog.css b/chrome/skin/aboutDialog.css
similarity index 100%
rename from src/chrome/skin/aboutDialog.css
rename to chrome/skin/aboutDialog.css
diff --git a/src/chrome/skin/aboutTor.css b/chrome/skin/aboutTor.css
similarity index 100%
rename from src/chrome/skin/aboutTor.css
rename to chrome/skin/aboutTor.css
diff --git a/src/chrome/skin/forwardArrow.png b/chrome/skin/forwardArrow.png
similarity index 100%
rename from src/chrome/skin/forwardArrow.png
rename to chrome/skin/forwardArrow.png
diff --git a/src/chrome/skin/icon-newsletter.png b/chrome/skin/icon-newsletter.png
similarity index 100%
rename from src/chrome/skin/icon-newsletter.png
rename to chrome/skin/icon-newsletter.png
diff --git a/src/chrome/skin/new_circuit.svg b/chrome/skin/new_circuit.svg
similarity index 100%
rename from src/chrome/skin/new_circuit.svg
rename to chrome/skin/new_circuit.svg
diff --git a/src/chrome/skin/preferences-mobile.css b/chrome/skin/preferences-mobile.css
similarity index 100%
rename from src/chrome/skin/preferences-mobile.css
rename to chrome/skin/preferences-mobile.css
diff --git a/src/chrome/skin/preferences.css b/chrome/skin/preferences.css
similarity index 100%
rename from src/chrome/skin/preferences.css
rename to chrome/skin/preferences.css
diff --git a/src/chrome/skin/searchLogo.png b/chrome/skin/searchLogo.png
similarity index 100%
rename from src/chrome/skin/searchLogo.png
rename to chrome/skin/searchLogo.png
diff --git a/src/chrome/skin/tor-circuit-display.css b/chrome/skin/tor-circuit-display.css
similarity index 100%
rename from src/chrome/skin/tor-circuit-display.css
rename to chrome/skin/tor-circuit-display.css
diff --git a/src/chrome/skin/tor.png b/chrome/skin/tor.png
similarity index 100%
rename from src/chrome/skin/tor.png
rename to chrome/skin/tor.png
diff --git a/src/chrome/skin/torbrowser_mobile_logo.png b/chrome/skin/torbrowser_mobile_logo.png
similarity index 100%
rename from src/chrome/skin/torbrowser_mobile_logo.png
rename to chrome/skin/torbrowser_mobile_logo.png
diff --git a/src/chrome/skin/torbutton-update-needed.svg b/chrome/skin/torbutton-update-needed.svg
similarity index 100%
rename from src/chrome/skin/torbutton-update-needed.svg
rename to chrome/skin/torbutton-update-needed.svg
diff --git a/src/chrome/skin/torbutton.css b/chrome/skin/torbutton.css
similarity index 100%
rename from src/chrome/skin/torbutton.css
rename to chrome/skin/torbutton.css
diff --git a/src/chrome/skin/torbutton.svg b/chrome/skin/torbutton.svg
similarity index 100%
rename from src/chrome/skin/torbutton.svg
rename to chrome/skin/torbutton.svg
diff --git a/src/components/aboutTor.js b/components/aboutTor.js
similarity index 100%
rename from src/components/aboutTor.js
rename to components/aboutTor.js
diff --git a/src/components/cookie-jar-selector.js b/components/cookie-jar-selector.js
similarity index 100%
rename from src/components/cookie-jar-selector.js
rename to components/cookie-jar-selector.js
diff --git a/src/components/domain-isolator.js b/components/domain-isolator.js
similarity index 100%
rename from src/components/domain-isolator.js
rename to components/domain-isolator.js
diff --git a/src/components/dragDropFilter.js b/components/dragDropFilter.js
similarity index 100%
rename from src/components/dragDropFilter.js
rename to components/dragDropFilter.js
diff --git a/src/components/external-app-blocker.js b/components/external-app-blocker.js
similarity index 100%
rename from src/components/external-app-blocker.js
rename to components/external-app-blocker.js
diff --git a/src/components/startup-observer.js b/components/startup-observer.js
similarity index 100%
rename from src/components/startup-observer.js
rename to components/startup-observer.js
diff --git a/src/components/torCheckService.js b/components/torCheckService.js
similarity index 100%
rename from src/components/torCheckService.js
rename to components/torCheckService.js
diff --git a/src/components/torbutton-logger.js b/components/torbutton-logger.js
similarity index 100%
rename from src/components/torbutton-logger.js
rename to components/torbutton-logger.js
diff --git a/src/defaults/preferences/preferences.js b/defaults/preferences/preferences.js
similarity index 100%
rename from src/defaults/preferences/preferences.js
rename to defaults/preferences/preferences.js
diff --git a/trans_tools/import-translations.sh b/import-translations.sh
similarity index 98%
rename from trans_tools/import-translations.sh
rename to import-translations.sh
index c5724011..26826090 100755
--- a/trans_tools/import-translations.sh
+++ b/import-translations.sh
@@ -12,7 +12,7 @@ BUNDLE_LOCALES="ar ca cs da de el es-AR es-ES fa fr ga-IE he hu id is it ja ka k
# 26498 and #29257. Others might want to fix, build, and use it, though.
BUNDLE_LOCALES="$BUNDLE_LOCALES eu bn-BD"
-LOCALE_DIR=../src/chrome/locale
+LOCALE_DIR=./chrome/locale
# FILEMAP is an array of "localeFile:translationBranch" strings.
FILEMAP=( "aboutDialog.dtd:torbutton-aboutdialogdtd"
diff --git a/src/jar.mn b/jar.mn
similarity index 100%
rename from src/jar.mn
rename to jar.mn
diff --git a/src/modules/default-prefs.js b/modules/default-prefs.js
similarity index 100%
rename from src/modules/default-prefs.js
rename to modules/default-prefs.js
diff --git a/src/modules/noscript-control.js b/modules/noscript-control.js
similarity index 100%
rename from src/modules/noscript-control.js
rename to modules/noscript-control.js
diff --git a/src/modules/security-prefs.js b/modules/security-prefs.js
similarity index 100%
rename from src/modules/security-prefs.js
rename to modules/security-prefs.js
diff --git a/src/modules/tor-control-port.js b/modules/tor-control-port.js
similarity index 100%
rename from src/modules/tor-control-port.js
rename to modules/tor-control-port.js
diff --git a/src/modules/utils.js b/modules/utils.js
similarity index 100%
rename from src/modules/utils.js
rename to modules/utils.js
diff --git a/moz.build b/moz.build
index 28f592f8..843cee0d 100644
--- a/moz.build
+++ b/moz.build
@@ -3,7 +3,7 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-JAR_MANIFESTS += ['src/jar.mn']
+JAR_MANIFESTS += ['jar.mn']
JS_PREFERENCE_FILES += [
- 'src/defaults/preferences/preferences.js',
+ 'defaults/preferences/preferences.js',
]
diff --git a/src/CHANGELOG b/src/CHANGELOG
deleted file mode 100644
index 858e8f53..00000000
--- a/src/CHANGELOG
+++ /dev/null
@@ -1,1366 +0,0 @@
-2.1.7
- * Bug 30388: Make sure the updated intermediate certificate keeps working
-
-2.0.13
- * Bug 30388: Make sure the updated intermediate certificate is working
-
-2.1.6
- * Bug 22538+22513: Fix new circuit button for error pages
- * Bug 29825: Intelligently add new Security Level button to taskbar
- * Bug 29903: No WebGL click-to-play on the standard security level
- * Bug 27484: Improve navigation within onboarding (strings)
- * Bug 29768: Introduce new features to users (strings)
- * Bug 29943: Use locales in AB-CD scheme to match Mozilla
- * Bug 26498: Add locale: es-AR
- * Bug 29973: Remove remaining stopOpenSecuritySettingsObserver() pieces
- * Translations update
-
-2.1.5
- * Bug 25658: Replace security slider with security level UI
- * Bug 28628: Change onboarding Security panel to open new Security Level panel
- * Bug 29440: Update about:tor when Tor Browser is updated
- * Bug 27478: Improved Torbutton icons for dark theme
- * Bug 29021: Tell NoScript it is running within Tor Browser
- * Bug 29239: Don't ship the Torbutton .xpi on mobile
- * Translations update
-
-2.0.11
- * Bug 29021: Tell NoScript it is running within Tor Browser
-
-2.1.4
- * Bug 25702: Update Tor Browser icon to follow design guidelines
- * Bug 21805: Add click-to-play button for WebGL
- * Bug 28836: Links on about:tor are not clickable
- * Bug 29035: Clean up our donation campaign and add newsletter sign-up link
- * Translations update
- * Code clean-up
-
-2.0.10
- * Bug 29035: Clean up our donation campaign and add newsletter sign-up link
- * Bug 27175: Add pref to allow users to persist custom noscript settings
-
-2.1.3
- * Bug 28540: Use new text for 2018 donation banner
- * Bug 27290: Remove WebGL pref for min capability mode
- * Bug 28075: Tone down missing SOCKS credential warning
- * Bug 28747: Remove NoScript (XPCOM) related unused code
- * Translations update
-
-2.0.9
- * Bug 28540: Use new text for 2018 donation banner
- * Bug 28515: Use en-US for english Torbutton strings
- * Translations update
-
-2.1.2
- * Bug 25013: Integrate Torbutton into tor-browser for Android
- * Bug 27111: Update about:tor desktop version to work on mobile
- * Bug 28093: Update donation banner style to make it fit in small screens
- * Bug 28543: about:tor has scroll bar between widths 900px and 1000px
- * Bug 28039: Enable dump() if log method is 0
- * Bug 27701: Don't show App Blocker dialog on Android
- * Bug 28187: Change tor circuit icon to torbutton.svg
- * Bug 28515: Use en-US for english Torbutton strings
- * Translations update
-
-2.1.1
- * Bug 23925+27959: Donation banner for year end 2018 campaign
- * Bug 24172: Donation banner clobbers Tor Browser version string
- * Bug 28082: Add locales cs, el, hu, ka
- * Translations update
-
-2.0.8
- * Bug 23925+27959: Donation banner for year end 2018 campaign
- * Bug 24172: Donation banner clobbers Tor Browser version string
- * Bug 27760: Use new NoScript API for IPC and fix about:blank issue
- * Translations update
-
-2.1
- * Bug 27175: Add pref to allow users to persist custom noscript settings
- * Bug 27760: Use new NoScript API for IPC and fix about:blank issue
- * Bug 21263: Remove outdated information from the README
-
-2.0.7
- * Bug 27097: Tor News signup banner
- * Bug 27663: Add New Identity menuitem again
- * Bug 26624: Only block OBJECT on highest slider level
- * Bug 26555: Don't show IP address for meek or snowflake
- * Bug 27478: Torbutton icons for dark theme
- * Bug 27506+14520: Move status version to upper left corner for RTL locales
- * Bug 27427: Fix NoScript IPC for about:blank by whitelisting messages
- * Bug 27558: Update the link to "Your Guard note may not change" text
- * Translations update
-
-2.0.6
- * Bug 27401: Start listening for NoScript before it loads
-
-2.0.5
- * Bug 26962: Circuit display onboarding
- * Bug 26520: Fix sec slider/NoScript for TOR_SKIP_LAUNCH=1
- * Bug 26490: Remove the security slider notification
- * Bug 27301: Improve about:tor behavior and appearance
- * Bug 27214: Improve the onboarding text
- * Translations update
-
-2.0.4
- * Bug 27276: Adapt to new NoScript messaging protocol
- * Bug 27097: Add text for Tor News signup widget
- * Translations update
-
-2.0.3
- * Bug 26884: Use Torbutton to provide security slider on mobile
- * Translations update
-
-2.0.2
- * Bug 26960: Implement new about:tor start page
- * Bug 26961: Implement new user onboarding
- * Bug 26321: Move 'New Identity', 'New Circuit' to File, hamburger menus
- * Bug 26590: Use new svg.disabled pref in security slider
- * Bug 26655: Adjust color and size of onion button
- * Bug 26500: Reposition circuit display relay icon for RTL locales
- * Bug 26409: Remove spoofed locale implementation
- * Bug 26189: Remove content-policy.js
- * Bug 26544: Images are not centered anymore
- * Bug 27129: Add locales ca, ga, id, is, nb
- * Translations update
-
-2.0.1
- * Bug 26100: Adapt Torbutton to Firefox 60 ESR
- * Bug 26430: New Torbutton icon
- * Bug 24309: Move circuit display to the identity popup
- * Bug 26128: Adapt security slider to the WebExtensions version of NoScript
- * Bug 23247: Show security state of .onions
- * Bug 26129: Show our about:tor page on startup
- * Bug 26235: Hide new unusable items from help menu
- * Bug 26058: Remove workaround for hiding 'sign in to sync' button
- * Bug 20628: Add locales bn-BD, da, he, sv, zh-TW
- * Translations update
-
-1.9.9.1
- * Bug 25126: Make about:tor layout responsive
- * Translations update
-
-1.9.9
- * Bug 24159: Version check does not deal with platform specific checks
- * Bug 25016: Remove 2017 donation banner
- * Translations update
-
-1.9.8.5
- * Bug 21245: Add da translation to Torbutton and keep track of it
- * Bug 24702: Remove Mozilla text from banner
- * Translations update
-
-1.9.8.4
- * Bug 21847: Update copy for security slider
- * Bug 10573: Replace deprecated nsILocalFile with nsIFile (code clean-up)
- * Translations update
-
-1.9.8.3
- * Bug 23997: Add link to Tor Browser manual for de, nl, tr, vi
- * Bug 23949: Fix donation banner display
- * Update locales with translated banner
- * Translations update
-
-1.9.7.10
- * Bug 23997: Add link to Tor Browser manual for de, nl, tr, vi
- * Translations update
-
-1.9.7.9
- * Bug 23949: Fix donation banner display
- * Update locales with translated banner
- * Translations update
-
-1.9.8.2
- * Bug 23887: Update banner locales and Mozilla text
- * Translations update
-
-1.9.7.8
- * Bug 23887: Update banner locales and Mozilla text
- * Bug 23526: Add 2017 Donation banner text
- * Bug 23483: Donation banner on about:tor for 2017 (testing mode)
- * Bug 22610: Avoid crashes when canceling external helper app related downloads
- * Bug 22472: Fix FTP downloads when external helper app dialog is shown
- * Bug 22471: Downloading pdf files via the PDF viewer download button is broken
- * Bug 22618: Downloading pdf file via file:/// is stalling
- * Translations update
-
-1.9.8.1
- * Bug 20375: Warn users after entering fullscreen mode
- * Bug 22989: Fix dimensions of new windows on macOS
- * Bug 23526: Add 2017 Donation banner text
- * Bug 23483: Donation banner on about:tor for 2017 (testing mode)
- * Translations Update
-
-1.9.7.7
- * Bug 22542: Security Settings window too small on macOS 10.12 (fixup)
- * Bug 20375: Warn users after entering fullscreen mode
-
-1.9.7.6
- * Bug 22989: Fix dimensions of new windows on macOS
- * Translations update
-
-1.9.8
- * Bug 22610: Avoid crashes when canceling external helper app related downloads
- * Bug 22472: Fix FTP downloads when external helper app dialog is shown
- * Bug 22471: Downloading pdf files via the PDF viewer download button is broken
- * Bug 22618: Downloading pdf file via file:/// is stalling
- * Bug 22542: Resize slider window to work without scrollbars
- * Bug 21999: Fix display of language prompt in non-en-US locales
- * Bug 18193: Don't let about:tor have chrome privileges
- * Bug 22535: Search on about:tor discards search query
- * Bug 21948: Going back to about:tor page gives "Address isn't valid" error
- * Code clean-up
- * Translations update
-
-1.9.7.5
- * Bug 21999: Fix display of language prompt in non-en-US locales
- * Bug 18193: Don't let about:tor have chrome privileges
- * Bug 22535: Search on about:tor discards search query
- * Bug 21948: Going back to about:tor page gives "Address isn't valid" error
- * Code clean-up
- * Translations update
-
-1.9.7.4
- * Bug 22542: Security Settings window too small on macOS 10.12
-
-1.9.7.3
- * Bug 22104: Adjust our content policy whitelist for ff52-esr
- * Bug 22457: Allow resources loaded by view-source://
- * Bug 21627: Ignore HTTP 304 responses when checking redirects
- * Bug 22459: Adapt our use of the nsIContentPolicy to e10s mode
- * Translations update
-
-1.9.7.2
- * Bug 21865: Update our JIT preferences in the security slider
- * Bug 21747: Make 'New Tor Circuit for this Site' work in ESR52
- * Bug 21745: Fix handling of catch-all circuit
- * Bug 21547: Fix circuit display under e10s
- * Bug 21268: e10s compatibility for New Identity
- * Bug 21267: Remove window resize implementation for now
- * Bug 21201: Make Torbutton multiprocess compatible
- * Translation updates
-
-1.9.7.1
- * Bug 21396: Allow leaking of resource/chrome URIs (off by default)
- * Bug 21574: Add link for zh manual and create manual links dynamically
- * Bug 21330: Non-usable scrollbar appears in tor browser security settings
- * Bug 21324: Don't update NoScript button with timer update
- * Translation updates
-
-1.9.7
- * Bug 19898: Use DuckDuckGo on about:tor
- * Bug 21091: Hide the update check menu entry when running under the sandbox
- * Bug 21243: Add links to es, fr, and pt Tor Browser manual
- * Bug 21194: Show snowflake in the circuit display
- * Bug 21131: Remove 2016 donation banner
- * Translation updates
-
-1.9.6.12
- * Bug 20951: Back out Unix domain socket related patches for Tor Browser 6.5
- * Bug 19898: Use DuckDuckGo on about:tor
- * Bug 21243: Add links to es, fr, and pt Tor Browser manual
- * Bug 21091: Hide the update check menu entry when running under the sandbox
- * Bug 21131: Remove 2016 donation banner
- * Bug 14429: Make sure the automatic resizing is disabled
- * Translation updates
-
-1.9.6.9
- * Bug 20947: Donation banner improvements
-
-1.9.5.13
- * Bug 20947: Donation banner improvements
-
-1.9.6.8
- * Bug 16622: Timezone spoofing moved to tor-browser.git
- * Bug 20701: Allow the directory listing stylesheet in the content policy
- * Bug 20556: Use pt-BR strings from now on
- * Bug 20614: Add links to Tor Browser User Manual
- * Bug 20414: Fix non-rendering arrow on OS X
- * Bug 20728: Fix bad preferences.xul dimensions
- * Bug 20318: Remove helpdesk link from about:tor
- * Bug 20753: Remove obsolete StartPage locale strings
- * Translation updates
-
-1.9.6.7
- * Bug 20414: Add donation banner on about:tor for 2016 campaign
- * Bug 20111: use Unix domain sockets for SOCKS port by default
- * Bug 19459: Move resizing code to tor-browser.git
- * Bug 20264: Change security slider to 3 options
- * Bug 20347: Enhance security slider's custom mode
- * Bug 20123: Disable remote jar on all security levels
- * Bug 20244: Move privacy checkboxes to about:preferences#privacy
- * Bug 17546: Add tooltips to explain our privacy checkboxes
- * Bug 17904: Allow security settings dialog to resize
- * Bug 18093: Remove 'Restore Defaults' button
- * Bug 20373: Prevent redundant dialogs opening
- * Bug 20388+20399+20394: Code clean-up
- * Translation updates
-
-1.9.5.12
- * Bug 20414: Add donation banner on about:tor for 2016 campaign
- * Translation updates
-
-1.9.6.4
- * Bug 17334: Move referrer spoofing for .onion domains into tor-browser.git
- * Bug 17767: Make "JavaScript disabled" more visible in Security Slider
-
-1.9.6.2
- * Bug 18589: Clear site security settings during New Identity
- * Bug 19906: "Maximizing Tor Browser" Notification can exist multiple times
- * Bug 19837: Whitelist internal URLs that Firefox requires for media
- * Bug 15852: Remove/synchronize Torbutton SOCKS pref logic
- * Bug 19733: GETINFO response parser doesn't handle AF_UNIX entries + IPv6
- * Bug 14271: Make Torbutton work with Unix Domain Socket option
- * Translation updates
-
-1.9.5.7
- * Bug 18589: Clear site security settings during New Identity
- * Bug 19906: "Maximizing Tor Browser" Notification can exist multiple times
-
-1.9.6.1
- * Bug 19206: Avoid SOCKS auth and NEWNYM collisions when sharing a tor client
- * Bug 19417: Disable asm.js (but add code to clear on New Identity if enabled)
- * Bug 19689: Plugin usage prompt is parented to wrong window
- * Bug 19273: Improve external app launch handling and associated warnings
- * Bug 8725: Block addon resource and url fingerprinting with nsIContentPolicy
-
-1.9.5.6
- * Bug 19417: Disable asmjs for now
- * Bug 19689: Use proper parent windows for plugin prompt
-
-1.9.5.5
- * Bug 19417: Clear asmjscache
-
-1.9.6
- * Bug 18743: Pref to hide 'Sign in to Sync' button in hamburger menu
- * Bug 18905: Hide unusable items from help menu
- * Bug 17599: Provide shortcuts for New Identity and New Circuit
- * Bug 18980: Remove obsolete toolbar button code
- * Bug 18238: Remove unused Torbutton code and strings
- * Translation updates
- * Code clean-up
-
-1.9.5.4
- * Bug 18466: Make Torbutton compatible with Firefox ESR 45
- * Bug 18743: Pref to hide 'Sign in to Sync' button in hamburger menu
- * Bug 18905: Hide unusable items from help menu
- * Bug 16017: Allow users to more easily set a non-tor SSH proxy
- * Bug 17599: Provide shortcuts for New Identity and New Circuit
- * Bug 18980: Remove obsolete toolbar button code
- * Bug 14429: Make sure the automatic resizing is disabled
- * Translation updates
- * Code clean-up
-
-1.9.5.3
- * Bug 18466: Make Torbutton compatible with Firefox ESR 45
- * Translation updates
-
-1.9.5.2
- * Bug 18557: Exempt Graphite preference from Security Slider
-
-1.9.4.5
- * Bug 18557: Exempt Graphite preference from Security Slider
-
-1.9.5.1
- * Bug 16990: Don't mishandle multiline commands
- * Bug 18144: about:tor update arrow position is wrong
- * Bug 16725: Allow resizing with non-default homepage
- * Bug 16017: Allow users to more easily set a non-tor SSH proxy
- * Translation updates
-
-1.9.4.4
- * Bug 16990: Don't mishandle multiline commands
- * Bug 18144: about:tor update arrow position is wrong
- * Bug 16725: Allow resizing with non-default homepage
- * Translation updates
-
-1.9.5
- * Bug 16990: Show circuit display for connections using multi-party channels
- * Bug 18019: Avoid empty prompt shown after non-en-US update
- * Bug 18004: Remove Tor fundraising donation banner
- * Code cleanup
- * Translation updates
-
-1.9.4.3
- * Bug 16990: Show circuit display for connections using multi-party channels
- * Bug 18019: Avoid empty prompt shown after non-en-US update
- * Bug 18004: Remove Tor fundraising donation banner
- * Bug 16940: After update, load local change notes
- * Bug 17108: Polish about:tor appearance
- * Bug 17568: Clean up tor-control-port.js
- * Bug 16620: Move window.name handling into a Firefox patch
- * Bug 17351: Code cleanup
- * Translation updates
-
-1.9.4.2
- * Bug 16940: After update, load local change notes
- * Bug 16990: Avoid matching '250 ' to the end of node name
- * Bug 17108: Polish about:tor appearance
- * Bug 17565: Tor fundraising campaign donation banner
- * Bug 17568: Clean up tor-control-port.js
- * Bug 17770: Fix alignments on donation banner
- * Bug 17792: Include donation banner in some non en-US Tor Browsers
- * Translation updates
-
-1.9.4.1
- * Bug 9623: Spoof Referer when leaving a .onion domain
- * Bug 16620: Move window.name handling into a Firefox patch
- * Bug 17164: Don't show text-select cursor on circuit display
- * Bug 17351: Remove unused code
- * Translation updates
-
-1.9.4
- * Bug 16937: Don't translate the hompepage/spellchecker dictionary string
- * Bug 16735: about:tor should accommodate different fonts/font sizes
- * Bug 16887: Update intl.accept_languages value
- * Bug 15493: Update circuit display on new circuit info
- * Bug 16797: brandShorterName is missing from brand.properties
- * Translation updates
-
-1.9.3.7
- * Bug 16990: Avoid matching '250 ' to the end of node name
- * Bug 17565: Tor fundraising campaign donation banner
- * Bug 17770: Fix alignments on donation banner
- * Bug 17792: Include donation banner in some non en-US Tor Browsers
- * Translation updates
-
-1.9.3.5
- * Bug 9623: Spoof Referer when leaving a .onion domain
- * Bug 16735: about:tor should accommodate different fonts/font sizes
- * Bug 16937: Don't translate the hompepage/spellchecker dictionary string
- * Bug 17164: Don't show text-select cursor on circuit display
- * Bug 17351: Remove unused code
- * Translation updates
-
-1.9.3.4
- * Bug 16887: Update intl.accept_languages value
- * Bug 15493: Update circuit display on new circuit info
- * Bug 16797: brandShorterName is missing from brand.properties
- * Bug 14429: Make sure the automatic resizing is disabled
- * Translation updates
-
-1.9.3.3
- * Bug 14429: Make sure the automatic resizing is enabled
-
-1.9.3.2
- * Bug 16731: TBB 5.0 a3/a4 fails to download a file on right click
- * Bug 16730: Reset NoScript whitelist on upgrade
- * Bug 16722: Prevent "Tiles" feature from being enabled after upgrade
- * Bug 16488: Remove "Sign in to Sync" from the browser menu (fixup)
- * Bug 14429: Make sure the automatic resizing is disabled
- * Translation updates
-
-1.9.3.1
- * Bug 16268: Show Tor Browser logo on About page
- * Bug 16639: Check for Updates menu item can cause update failure
- * Bug 15781: Remove the sessionstore filter
- * Bug 15656: Sync privacy.resistFingerprinting with Torbutton pref
-
-1.9.3.0
- * Bug 16427: Use internal update URL
- * Bug 16200: Update Cache API usage and prefs for FF38
- * Bug 16357: Use Mozilla API to wipe permissions db
-
-1.9.2.8
- * Bug 16403: Set search parameters for Disconnect
- * Bug 14429: Make sure the automatic resizing is disabled
- * Translation updates
-
-1.9.2.7
- * Bug 14429: Make sure the automatic resizing is enabled
-
-1.9.2.6
- * Bug 15984: Disabling Torbutton breaks the Add-ons Manager
- * Bug 14429: Make sure the automatic resizing is disabled
- * Translation updates
-
-1.9.2.5
- * Translation updates
-
-1.9.2.4
- * Bug 14429: Improved automatic window resizing
-
-1.9.2.3:
- * Bug 15837: Show descriptions if unchecking custom mode
- * Bug 15927: Force update of the NoScript UI when changing security level
- * Bug 15915: Hide circuit display if it is disabled.
-
-1.9.2.2:
- * Bug 15795: Some security slider prefs do not trigger custom checkbox
-
-1.9.2.1:
- * Bug 14429: Disable window resizing for now.
-
-1.9.2.0:
- * Bug 15562: Bind SharedWorkers to thirdparty pref
- * Bug 15533: Restore default security level when restoring defaults
- * Bug 15510: Close Tor Circuit UI control port connections on New Identity
- * Bug 15472: Make node text black in circuit status UI.
- * Bug 15502: Wipe blob URIs on New Identity
-
-1.9.1.0:
- * Bug 9387: "Security Slider 1.0"
- * Include descriptions and tooltip hints for security levels
- * Notify users that the security slider exists
- * Flip slider so that "low" is on the bottom
- * Make use of new SVG and MathML prefs
- * Bug 13766: Set a 10 minute circuit lifespan for non-content requests
- * Bug 15460: Ensure FTP urls use content-window circuit isolation
- * Bug 13650: Clip initial window height to 1000px
- * Bug 14429: Ensure windows can only be resized to 200x100px multiples
- * Bug 15334: Display Cookie Protections menu if disk records are enabled
- * Bug 14324: Show HS circuit in Tor circuit display
- * Bug 15086: Handle RTL text in Tor circuit display
- * Bug 15085: Fix about:tor RTL text alignment problems
- * Bug 10216: Add a pref to disable the local tor control port test
- * Bug 14937: Show meek and flashproxy bridges in tor circuit display
- * Bugs 13891+15207: Fix exceptions/errors in circuit display with bridges
- * Bug 13019: Change locale hiding pref to boolean
- * Bug 7255: Warn users about maximizing windows
- * Bug 14631: Improve profile access error msgs (strings).
-
-1.9.0.0
- * Bug 13882: Fix display of bridges after bridge settings have been changed
- * Bug 5698: Use "Tor Browser" branding in "About Tor Browser" dialog
- * Bug 10280: Strings and pref for preventing plugin initialization.
- * Bug 14866: Show correct circuit when more than one exists for a given domain
- * Bug 9442: Add New Circuit button to Torbutton menu
- * Bug 9906: Warn users before closing all windows and performing new identity.
- * Bug 8400: Prompt for restart if disk records are enabled/disabled.
- * Bug 14630: Hide Torbutton's proxy settings tab.
- * Bug 14632: Disable Cookie Manager until we get it working.
- * Bug 11175: Remove "About Torbutton" from onion menu.
- * Bug 13900: Remove SafeCache code.
- * Bug 14490: Use Disconnect search in about:tor search box
- * Bug 14392: Don't steal input focus in about:tor search box
- * Bug 11236: Don't set omnibox order in Torbutton (to prevent translation)
- * Bug 13406: Stop directing users to download-easy.html.en on update
- * Bug 9387: Handle "custom" mode better in Security Slider
- * Bug 12430: Bind jar: pref to Security Slider
- * Bug 14448: Restore Torbutton menu operation on non-English localizations
-
-1.8.1.3
- * Bug 13998: Handle changes in NoScript 2.6.9.8+
- * Bug 14100: Option to hide NetworkSettings menuitem
- * Bug 13079: Option to skip control port verification
- * Bug 13835: Option to change default Tor Browser homepage
- * Bug 11449: Fix new identity error if NoScript is not enabled
- * Bug 13881: Localize strings for tor circuit display
- * Bug 9387: Incorporate user feedback
- * Bug 13671: Fixup for circuit display if bridges are used
- * Translation updates
-
-1.8.1.2
- * Bug 13672: Make circuit display optional
- * Bug 13671: Make bridges visible on circuit display
- * Bug 9387: Incorporate user feedback
- * Bug 13784: Remove third party authentication tokens
-
-1.8.1.1
- * Bug 13751: Remove remaining SafeCache code.
-
-1.8.1.0
- * Bug 13746: Properly link Torbutton UI to thirdparty pref.
- * Bug 13742: Remove SafeCache code (in favor of C++ implementation)
-
-1.8.0.3
- * misc: Translation imports for security slider
-
-1.8.0.2
- * Bug 13666: Various fixes for circuit status display
-
-1.8.0.1
- * Bug 13651: Fix hangs associated with circuit status UI from #8641.
-
-1.8.0.0
- * Bug 9387: Provide a "Security Slider" for vulnerability surface reduction
- * Bug 13019: Synchronize locale spoofing pref with our Firefox patch
- * Bug 3455: Use SOCKS user+pass to isolate all requests from the same url domain
- * Bug 8641: Create browser UI to indicate current tab's Tor circuit IPs
-
-1.7.0.2
- * Bug 13019: Synchronize locale spoofing pref with our Firefox patch
- * Bug 13746: Properly link Torbutton UI to thirdparty pref.
-
-1.7.0.1
- * Bug 13378: Prevent addon reordering in toolbars on first-run.
-
-1.7.0.0
- 9 Oct 2014
- * Bug 10751: Adapt Torbutton to ESR31's Australis UI.
- * Bug 13138: ESR31-about:tor shows "Tor is not working"
- * Bug 12947: Adapt session storage blocker to ESR 31.
- * Bug 10716: Take care of drag/drop events in ESR 31.
- * Bug 13366: Fix cert exemption dialog when disk storage is enabled.
-
-1.6.12.3
- 23 Sep 2014
- * Bug 10804: Workaround for some TBB startup hangs
-
-1.6.12.2
- 22 Sep 2014
- * Bug 13091: Use "Tor Browser" everywhere
-
-1.6.12.1
- 1 Sep 2014
- * Bug 12684: Add `canvas.notNow` UI strings to torbutton.properties file.
- * Bug 8940: Move RecommendedTBBVersions file to www.torproject.org.
-
-1.6.12.0
- 4 Aug 2014
- * Bug 9531: Workaround to avoid rare hangs during New Identity
-
-1.6.11.1
- 24 Jul 2014
- * Bug 11472: Adjust about:tor font and logo positioning to avoid overlap
- * Bug 12680: Fix Torbutton about url.
-
-1.6.11.0
- 27 Jun 2014
- * Bug 10819: Bind new third party isolation pref to Torbutton security UI
- * Bug 9268: Fix some window resizing corner cases with DPI and taskbar size.
-
-1.6.10.1
- 26 Jun 2014
- * Bug #12221: Remove obsolete Javascript components from the toggle era
-
-1.6.10.0
- 5 Jun 2014
- * Bug 11510: about:tor should not report success if tor proxy is unreachable
- * Bug 11783: Avoid b.webProgress error when double-clicking on New Identity
- * Bug 11722: Add hidden pref to force remote Tor check
- * Bug 11763: Fix pref dialog double-click race that caused settings to be reset
-
-1.6.9.0:
- 25 Apr 2014
- * Bug 7439: Improve download warning dialog text.
- * Bug 11384: Completely remove hidden toggle menu item.
-
-1.6.8.0:
- 7 Apr 2014:
- * Bug 9010: Add Turkish to update locales.
- * Bug 11242: Fix improper "update needed" message after in-place upgrade.
- * Bug 10398: Ease translation of about:tor page elements
-
-1.6.7.0:
- 7 Mar 2014:
- * Bug 9901: Fix browser freeze due to content type sniffing
- * Bug 10611: Add Swedish (sv) to extra locales to update
-
-1.6.6.0:
- 3 Feb 2014
- * Bug 10800: Prevent exception in New Identity
- * Bug 10640: Fix about:tor's pointer position for RTL languages.
- * Bug 10095: Make inner window a multiple of 200x100
- * Bug 10285: Clear permissions on New Identity
- * Bug 9738: Fix for auto-maximizing on browser start
- * Bug 10682: Workaround to really disable updates for Torbutton.
- * Bug 10419: Don't allow connections to localhost
- * Bug 10140: Move Japanese to extra locales
- * Bug 10687: Add Basque (eu) to extra locales
-
-1.6.5.5:
- 20 Jan 2014
- * Bug 9486: Properly clear NoScript Temporary Permissions
-
-1.6.5.4:
- 14 Jan 2014
- * Bug 10537: Include Arabic locale in Torbutton.
-
-1.6.5.3:
- 23 Dec 2013
- * Bug 9486: Clear NoScript Temporary Permissions on New Identity
-
-1.6.5.2:
- 17 Dec 2013
- * Misc: Change the default update download link back to download-easy
-
-1.6.5.1:
- 10 Dec 2013
- * Bug 10352: Clear FF24 Private Browsing Mode data during New Identity
-
-1.6.5:
- 9 Dec 2013
- * Bug 8167: Update cache isolation to use getFirstPartyURIFromChannel() for FF24
- * Bug 10201: FF ESR 24 hangs during exit on Mac OS.
- * Bug 10078: Properly clear crypto tokens during New Identity on FF24
- * Bug 9454: Support changes to Private Browsing Mode and plugin APIs in FF24
-
-1.6.4.1:
- 15 Nov 2013
- * Bug 10002: Make the TBB3.0 blog tag our update download url for now.
-
-1.6.4:
- 29 Oct 2013
- * Bug 9144: Workaround for missing translation properties
-
-1.6.3:
- 11 Oct 2013:
- * Bug 9224: Support multiple Tor socks ports for about:tor status check
- * Bug 9587: Add TBB version number to about:tor
-
-1.6.2.1:
- 23 Sep 2013:
- * Bug 8839: Switch about:tor search link to unfiltered startpage link
-
-1.6.2:
- 18 Sep 2013
- * bug 9492: Fix Torbutton logo on OSX and Windows (and related
- initialization code)
-
-1.6.1:
- 01 Aug 2013
- * bug 8478: Change when window resizing code fires to avoid rounding errors
- * bug 9331: Hack an update URL for the next TBB release
- * bug 9144: Change an aboutTor.dtd string to something transifex might accept
-
-1.6.0:
- 05 Jun 2013
- * bug 7494: Create a local home page for TBB as about:tor
- * misc: Perform a control port test of proper Tor configuration by default.
- Only use check.torproject.org if the control port is unavailable.
- * misc: Add an icon menu option for Tor Launcher's Network Settings
- * misc: Add branding string overrides (primarily controls browser name and
- homepage)
-
-1.5.2:
- 22 Apr 2013
- * bug 8457: Allow session restore if the user allows disk actvity
- * bug 8301: Remove the Display Settings panel and associated locales
- * bug 6566: Fix "Transparent Torification" option.
- * bug 8642: Fix a hang on New Identity.
-
-1.5.1:
- 07 Mar 2013
- * bug 8324: Fix Drag+Drop crash by using a new TBB drag observer
- * bug 6202: Fix XML/E4X errors with Cookie Protections
- * bug 8423: Don't clear cookies at shutdown if user wants disk history
- * bug 8382: Leave IndexedDB and Offline Storage disabled.
- * bug 8422: Clear DOM localStorage on New Identity.
- * bug 8335: Don't strip "third party" HTTP auth from favicons
- * bug 5183: Localize the "Spoof english" button strings
- * bug 8313: Ask user for confirmation before enabling plugins
- * misc: Emit private browsing session clearing event on "New Identity"
-
-1.5.0
- 18 Feb 2013
- * bug 5279: Remove old toggle observers and related code
- * bug 3100: Simplify Security Preference UI and associated pref updates
- * bug 1305: Eliminate redundancy in our Flash/plugin disabling code
- * bug 3944: Leave most preferences under Tor Browser's control
- * bug 7974: Disable toggle-on-startup and crash detection logic
- * bug 5279: Disable/remove toggle-mode code and related observers
- * bug 6431: Add menu hint to Torbutton icon
- * bug 7495: Make Torbutton icon flash a warning symbol if TBB is out of date
- * bug 6096: Perform version check every time there's a new tab.
- * bug 6156: Rate limit version check queries to once every 1.5hrs max.
- * misc: Allow WebGL and DOM storage.
- * misc: Disable independent Torbutton updates
- * misc: Change the recommended SOCKSPort to 9150 (to match TBB)
-
-1.4.6.3
- 9 Oct 2012
- * bug 5856: Disable JS hooks to make way for direct Firefox patch
-
-1.4.6.2
- 12 Sep 2012
- * bug 6803: Set proxy settings earlier to fix broken homepage load on FF15
- * bug 6254: Support transparent Tor mode through TOR_TRANSPROXY=1 env var.
-
-1.4.6.1
- 30 Aug 2012
- * Bug 6737: Disable window.screen hooks for FF15+ (fixes exception alert)
-
-1.4.6
- 30 May 2012
- * Bug 5710: Prevent all sessionstore data saving in TBB
- * Bug 5715: Explicitly clear image cache on TBB New Identity
- * Bug 4660: Clear search and find boxes on TBB New Identity
- * Bug 5729: Make New Identity and New Window a multiple of 200x100px
- * Bug 4755: Spoof screen coordinates for DOM MouseEvents
- * Bug 4718: Make TBB version check happen on New Window+New Identity
- * Bug 5758: Disable WebSockets and IndexedDB for non-TBB users
- * Bug 5863: Remove the ability to toggle Torbutton (to prevent leaks)
- * Bug 3838: Inform Torbutton users about TBB
- * Bug 5092: Sign Torbutton Updates
- * Bugs 5673+5732: Change captcha redirect to startpage.com
- * Bug 3845: Bump Firefox user agent to 10.0-ESR
-
-1.4.5.1
- 17 Dec 2011
- * bug 4722: Fix ability to drag tabs on Windows (due to #4517)
-
-1.4.5
- 14 Dec 2011
- * bug 4517: Disable external drag and drop (prevents proxy bypass)
- * bug 4099: Disable TLS session tickets to prevent linkability
- * bug 4603: Lower HTTP keep-alive timeout to reduce linkability
- * bug 4611: Notify user if "New Identity" fails
- * bug 4667: Close keep-alive connections on "New Identity" (TBB only)
- * bug 4453: Reset SOCKS host and port only when using "recommended settings"
- * misc: Perform versioncheck at startup regardless of session restore status
-
-1.4.4.1
- 11 Oct 2011
- * misc: Fix a homepage load error on Windows TBB first-run
-
-1.4.4
- 9 Oct 2011
- * bug 4197: Allow Torbutton formfill blocking to be disabled
- * bug 4058: Fix yet more issues with links opening in new tabs
- * bug 4161: Make TBB version check work w/ SocksPort auto builds
- * bug 3686: Fix loading of localized homepage on Debian
- * bug 4016: Resize window on "New Identity"
- * bug 3928: Implement CookieAuthFile password reading
- * misc: Fix scoping issue for some stream variables
-
-1.4.3
- 9 Sep 2011
- * bug 3933: Don't touch app.update.auto in TBB
- * bug 3960: Don't disable zoom.siteSpecific on TBB
- * bug 3928: Fix auto-scroll on twitter
- * bug 3649: Make permissions and disk errors human-readable
-
-1.4.2
- 3 Sep 2011
- * bug 3879: Fix broken framed sites (yopmail, gmane, gmaps, etc)
- * bug 3337: Fetch check.tp.o page to check versions (TBB only)
- * Bug 3754: Fix SafeCache OCSP errors (fix for TBB only)
-
-1.4.1
- 28 Aug 2011
- * bug 523: Implement New Identity (for TBB only)
- * bug 3580: Fix hotmail/live breakage (TBB only)
- * bug 3748: Disable 3rd party HTTP auth
- * bug 3665: Fix several corner cases SafeCache isolation
- * bug 3739: Fix https->http CORS failure for SafeCache
- * bug 3414: Isolate window.name based on referrer policy
- * bug 3809: Disable referer spoofing (fixes navigation issues)
- * bug 3819: Fix API issue with cookie protections
- * bug 3820: Fix warning w/ session store filter
-
-1.4.0
- 30 Jun 2011
- * bug 3101: Disable WebGL. Too many unknowns for now.
- * bug 3345: Make Google Captcha redirect work again.
- * bug 3399: Fix a reversed exception check found by arno.
- * bug 3177: Update torbutton to use new TorBrowser prefs.
- * bug 2843: Update proxy preferences window to support env var.
- * bug 2338: Force toggle at startup if tor is enabled
- * bug 3554: Make Cookie protections obey disk settings
- * bug 3441: Enable cookie protection UI by default.
- * bug 3446: We're Firefox 5.0, we swear.
- * bug #3506: Remove window resize event listener.
- * bug #1282: Set fixed window size for each new window.
- * bug #3508: Apply Stanford SafeCache patch (thanks Edward, Collin et al).
- * bug #2361: Make about window work again on FF4+.
- * bug #3436: T(A)ILS was renamed to Tails.
- * bugfix: Fix a transparent context menu issue on Linux FF4+.
- * misc: Squelch exception from app launcher in error console.
- * misc: Make DuckDuckGo the default Google Captcha redirect destination.
- * misc: Make it harder to accidentally toggle torbutton.
-
-1.3.3-alpha
- 01 May 2011
- * bug 2777: Clear OCSP cache on tor toggle
- * bug 2832: Update spoofed user agent to Firefox 4.0
- * bug 2838: Make cookie protections dialog work
- * bug 2819: Move JS hooks to new JS1.8.5 hooking support on FF4.
- * bug 3042: Fix version compatibility issue with FF4.0.1+
-
-1.3.2-alpha
- 21 Mar 2011
- * bug 1624: Use nsIDOMCrypto::logout() instead of the SSLv2 pref hack
- * bug 1999: Disable tor:// urls by default
- * bug 1968: Reset window.name on tor toggle
- * bug 2148: Make refspoofing more uniform
- * bug 2359: Fix XHTML DTD errors on FF4
- * bugs 2465+2421: Fix javascript hook exceptions+issues in FF4.0
- * bug 2458: Opt out of Firefox addon usage pings
- * bug 2377: Limit the Google captcha cookies copied between google TLDs
- * bug 2491: Clean up checks for when to jar protected cookies
- * bug 1110: Add popup to ask if we should spoof English Accept: headers
- * misc: Remove a noisy FF2 nsICookieManager2 fallback check.
-
-1.3.1-alpha
- 03 Jan 2011
- * bugfix: bug 1894: Amnesia is now called TAILS (patch from intrigeri)
- * bugfix: bug 2315: Remove reference to TorVM (patch from intrigeri)
- * bugfix: bug 2011: Fix preference dialog issues (patch from chrisdoble)
- * bugfix: Fix some incorrect log lines in RefSpoofer
- * new: Support Firefox 4.0 (many changes)
- * new: Place button in the nav-bar (FF4 killed the status-bar)
- * misc: No longer reimplement the session store, use new APIs instead
- * misc: Simplify crash detection and startup mode settings
-
-1.3.0-alpha
- 30 Sep 2010
- * new: Support for transparent proxies in settings
- (patch from Jacob Appelbaum and Kory Kirk)
- * new: tor:// and tors:// url support to auto-toggle into tor mode
- (patch from Kory Kirk)
- * new: Cookie manager to allow individual Cookie protection
- (patch from Kory Kirk)
- * new: Add referrer spoofing based on modified same origin policy
- (patch from Kory Kirk)
- * new: Add DuckDuckGo.com as a Google captcha redirect destination
- (patch from aiden tighe)
- * bugfix: bug 1911: Fix broken useragent locale string on debian
- (patch from lunar)
- * bugfix: Fix captcha detection for encrypted.google.com
-
-1.2.5
- 08 Apr 2010
- * bugfix: bug 1169: Fix blank popup conflict with CoolPreviews
- * bugfix: bug 1246: Fix IST and other HH:30 timezone issues.
- * bugfix: bug 1219: Fix the toggle warning loop issue on settings change.
- * bugfix: bug 1321: Fix a session restore bug when closing the last window
- * bugfix: bug 1302: Update useragent to FF3.6.3 on WinNT6.
- * bugfix: bug 1157: Add logic to handle torbutton crashed state conflicts
- * bugfix: bug 1235: Improve the 'changed-state' refresh warning message
- * bugfix: bug 1337: Bind alert windows to correct browser window
- * bugfix: bug 1055: Make the error console the default log output location
- * bugfix: bug 1032: Fix an exception in the localhost proxy filter
- * misc: Always tell a website our window size is rounded even if it's not
- * misc: Add some suggestions to warning about loading external content
- * new: Add option to always update Torbutton via Tor. On by default
- * new: Redirect Google queries elsewhere on captcha (default ixquick)
- * new: Strip identifying info off of Google searchbox queries
-
-1.2.4
- 16 Dec 2009
- * bugfix: bug 1169: Fix blank popup conflict with Google Toolbar
- * bugfix: bug 1171: Properly store and set network.dns.disablePrefetch
- * bugfix: bug 1165: Fix an exception on toggle in FF3.6
- * bugfix: bug 1163: Fix history loss in FF3.6
- * bugfix: Fix a typo error during logging
- * bugfix: Properly handle session restore in FF3.6
- * misc: Kill a warning message about missing properties in window-mapper.js
- * new: Add a new pref to disable Livemark updates during Tor usage (FF3.5+)
-
-1.2.3
- 02 Dec 2009
- * bugfix: bug 950: Preserve useragent and download settings across toggle
- * bugfix: bug 1014: Fix XML Parsing Error on XHTML sites in Tor mode
- * bugfix: bug 1041: Preserve tab history in FF3.5
- * bugfix: bug 1047: Fix spurious user agent change notice
- * bugfix: bug 1053: Partial fix for 'TypeError: browser is undefined' error
- * bugfix: bug 1084: Preserve HTTP accept language for Non-Tor usage
- * bugfix: bug 1085: Fix test settings issues with dead privoxy
- * bugfix: bug 1088: Clean up some namespace issues in the main chrome window
- * bugfix: bug 1091: Fix a lockup when 'Ask Every Time' cookie pref is set
- * bugfix: bug 1093: Fix cert acceptance dialogs in Firefox 3.5
- * bugfix: bug 1146: Fixes for properly handling tab restore in FF3.5
- * bugfix: bug 1152: Close tabs on toggle prevents toggling in FF3.5"
- * bugfix: bug 1154: Clarify "Last Tor test failed" message
- * misc: Disable geolocation in FF3.5 during Tor mode
- * misc: Disable DNS prefetch in FF3.5 in Tor mode and for Tor-loaded tabs
- * misc: Disable offline app cache during Tor mode
- * misc: Disable specific site zoom settings during Tor mode
- * new: Transfer Google cookies between country-code domains. This should
- make it such that captchas only need to be solved once per Tor session,
- as opposed to for each country.
-
-1.2.2
- 09 Aug 2009
- * bugfix: Workaround Firefox Bug 440892 to prevent external apps from
- being launched (and thus bypassing proxy settings) without user
- confirmation. Independently reported by Greg Fleischer and optimist.
- * bugfix: Create a separate "No Proxy For" option and remove the
- string "localhost" from proxy exemptions. Prevents a theoretical
- proxy bypass condition discovered by optimist. Fix based on patch from
- optimist.
- * bugfix: bug 970: Purge undo tab list on Tor toggle.
- * bugfix: bug 1040: Scrub URLs from log level 4 and higher log messages.
- Mac OS writes Firefox console messages to disk by default.
- * bugfix: bug 1033: Fix FoxyProxy conflict that caused some FoxyProxy
- strings to fail to display.
- * misc: bug 1006: Pop up a more specific failure message for pref
- changing errors during Tor toggle.
- * misc: Fix a couple of strict javascript warns on FF3.5
- * misc: Add chrome url protection call to conceal other addons during
- non-Tor usage. Patch by Sebastian Lisken.
- * misc: Remove torbutton log system init message that may have scared some
- paranoids.
-
-1.2.1
- 21 Mar 2009
- * bugfix: bug 773: Fixed Noscript conflict issue.
- * bugfix: bug 866: Fixed conflict with ZoTero
- * bugfix: bug 908: Make UserAgentSwitcher's 'default' button restore
- Torbutton's spoofed user agent if Tor is enabled.
- * bugfix: bug 909: Get Torbutton to "properly" react to users changing
- their Firefox cookie lifetime settings as opposed to using the Torbutton
- interface.
- * bugfix: bug 834: Fix session saving and startup issues
- * bugfix: bug 875: Removed docShell == null popup during toggle for
- some users
- * bugfix: bug 910: fixed a locale spoofing issue in navigator.appVersion
- * bugfix: bug 747: Attempt to fix 'fullscreen' resizing issues.
- * bugfix: Stop-gap timezone spoofing fix for Linux and Mac
- for FF3. Requires a one-line patch to Firefox for Windows to work.
- * bugfix: Clear SSL Session IDs on toggle. (See FF Bug 448747)
- * misc: bug 931: Added a socks v4 vs v5 version choice to custom prefs.
- * misc: bug 836: redesign startup preference window to make it more
- understandable
- * misc: Torbutton now presents itself as Windows FF3.0.7.
- * misc: Change RDF to allow Torbutton to run on FF3.1 betas.
-
-1.2.0
- 30 Jul 2008
- * bugfix: bug 777: Fix issue with locale spoofing breaking translations.
- * bugfix: bug 778: Preserve locale in spoofed version if user does not want
- locale spoofing.
- * bugfix: bug 780: Keep session cookies during Tor toggle.
- * bugfix: Potential fix for some PKCS#12 issues.
- * bugfix: Fix crash recovery and uninstall/upgrade to avoid cookie loss.
- * misc: Translation updates.
-
-1.2.0rc6:
- 12 Jul 2008
- * bugfix: Fix bug causing Firefox history to get cleared in some situations
- * bugfix: bug 753: Fix exception thrown during Tor toggle in some instances
- * bugfix: bug 758: Fix resize issue where 0x0 windows could be created
- * bugfix: Fix some potential permission denied issues with cookie jars
- * bugfix: bug 520: Fix issue where Javascript stayed disabled in some tabs
- * bugfix: Apply cookie lifetime settings to Tor settings on first install.
- * bugfix: Don't disable Firefox preferences when Torbutton is uninstalled
- * misc: Allow automatic updates in FF3 by default. They are secure now.
- * misc: Translation updates
-
-1.2.0rc5
- 06 Jul 2008
- * bugfix: bug 734: Fix exception with clearing history on toggle
- * bugfix: bug 735: Fix exception with blocking Non-Tor history writes
- * bugfix: bug 720: FF3 cookie jar fix submitted by arno
- * misc: translation updates for French, Farsi, and others
- * misc: demote "mapper check" log message to info
- * new: Option to not write cookie jars to disk submitted by arno
-
-1.2.0rc4
- 27 Jun 2008
- * misc: Refuse to jar cookies under Firefox 3. Lame workaround for Firefox
- Bug 439384, but it's the best we can do. At least we won't destroy
- cookies anymore.
- * misc: Some strings were present twice in the en-US locale. Didn't seem
- to cause any problems, but probably should be fixed.
-
-1.2.0rc3
- 27 Jun 2008
- * bugfix: Lots of compatibility updates with other extensions. Issues
- with SpeedDial, Google Notebook, TabMixPlus, and others have been fixed.
- * bugfix: Fix bug with first window/tab after restart being partially
- prevented from performing network activity and/or history access.
- * bugfix: Add an additional pref for blocking Non-Tor file url network
- activity. Off by default. This should fix issues with Sage addon in
- Non-Tor mode.
- * bugfix: Be better about saving all sorts of Firefox prefs that we touch
- so that users' Non-Tor preferences are remembered.
- * bugfix: Fix potential issues with FF3 sessionstore by updating component,
- and performing version detection.
- * bugfix: Separate toggle into a 3 stage process to eliminate potential
- race conditions and issues with javascript and other functionality
- not working after Tor toggle.
- * new: Added 'Test Settings' button to Proxy Preferences that uses
- check.torproject.org to verify Tor status.
- * misc: Improve 'Restore Defaults' to reset all prefs that we touch.
- * misc: Fix logging system to be more user-legible.
-
-1.2.0rc2
- 08 Jun 2008
- * bugfix: MacOS: Fix broken Tor state/toggle issues when all windows are
- closed but app stays open
- * misc: Potential performance improvements when many windows+tabs are open
- * new: Add 'locked mode' pref to allow users to disable one-click toggling
- * new: Add prefs to start Firefox with a specific Tor state.
-
-1.2.0rc1
- 01 Jun 2008
- * general: FF3 should now be functional, but timezone masking is not
- operational
- * bugfix: Fix Places/history component hooking in FF3
- * bugfix: Disable Places database in FF3 via browser.history_expire_days=0
- if history writes are disabled.
- * bugfix: General component hooking fixes for FF3
- * bugfix: Block favicon leaking in FF3
- * bugfix: Enable safebrowsing updates in FF3 (it's finally HMACd. Yay).
- * bugfix: Use Greg Fleischer's new useragent prefs in FF3.
- * bugfix: Properly reset cookie lifetime policy when user changes cookie
- handling options.
- * bugfix: Fix 'Restore defaults' button issues with custom proxy settings
- * bugfix: navigator.oscpu hooking was broken in 1.1.18
- * bugfix: Try to prevent alleged 0x0 windows on crash recovery
- * bugfix: Attempt to block livemarks updates during Tor. Only partial fix.
- Not possible to cancel existing Livemarks timer (one fetch will still
- happen via Tor before disable). See Firefox Bug 436250
- * misc: Set plugin.disable_full_page_plugin_for_types for all plugin
- mimetypes just in case our custom full page blocking code fails
-
-1.1.18
- 17 Apr 2008
- * bugfix: Fix Gmail exceptions involving window.navigator that made Gmail
- unusable after recent updates by Google.
- * bugfix: Fix an exception in the content policy that may have prevented
- some AJAX page elements from loading.
- * bugfix: Fix regression on cross-state favicon leak introduced in 1.1.17
- * bugfix: Fix to make clear private data work again by fixing up history
- hooking (may also help FF3 compatibility).
- * bugfix: Fix Yahoo email account creation (broken due to Date.valueOf()
- weirdness).
- * bugfix: Fix to allow plugins if the user unchecks the plugin blocking
- preference
- * bugfix: Fix bug 638: eliminate cross-state history popup on session
- restore
- * bugfix: Only resize windows on document load. Hopefully this will make
- the resizing code less annoying, and drift less.
- * bugfix: Fix Object.prototype extensions involving the Date object
- (observed on LiveJournal)
- * bugfix: Fix javascript debugger compatibility issues involving source
- window display and other functionality.
- * misc: Prevent blocked popups from opening blank, unusable windows
- * misc: Updated firefox version to 2.0.0.14
- * new: New translations for French, Russian, Farsi, Italian, and Spanish.
-
-1.1.17
- 15 Mar 2008
- * bugfix: Improve chrome disclosure protection (patch from Greg Fleischer)
- * bugfix: Block network access from file urls to workaround Firefox
- 'Content-Disposition' file stealing attack (found/fixed by Greg)
- * bugfix: Apply Javascript hooks to javascript: urls (found by Greg)
- * bugfix: Improve Torbutton chrome concealment (found by Greg)
- * bugfix: Use 127.0.0.1 instead of localhost for IPv6 users
- * bugfix: Don't resize maximized windows
- * misc: Improve window resizing to only resize on document load,
- and to try to address drift by remembering window sizes
- * misc: Clear session history if clear history on tor toggle is set
- * new: Remove history hooks in favor of nsISHistoryListeners that
- prevent history navigation from alternate Tor states
-
-1.1.16
- 03 Mar 2008
- * bugfix: Fix yet more javascript unmasking issues found by Greg.
- Date is still unmaskable.
- * bugfix: Close tabs *before* toggling proxy settings if pref is set.
- * bugfix: Fix a couple exceptions thrown on resizing and plugin canceling
-
-1.1.15
- 26 Feb 2008
- * bugfix: Fix hook unmasking of window.screen, window.history,
- and window.navigator discovered by Greg Fleischer. window.Date
- unmasking is still unfixed. window.history unmasking represents
- potential IP disclosure due to Firefox Bug 409737.
- * bugfix: Fix view-source extension disclosure bug found by Greg
- Fleischer.
- * bugfix: Fix javascript and about links. Found by Greg Fleischer.
- * new: Attempt to prevent window sizes from drifting during resize.
-
-1.1.14
- 24 Feb 2008
- * bugfix: set general.useragent.locale if user wants to spoof an English
- browser. This handles navigator.locale
- * bugfix: Mask navigator.buildID. Reported by Greg Fleischer
- * Initial Firefox 3 work. Functionality still broken due to FF Bug 413682
- * bug 580: Resize preferences window to fit in 640x480 displays
- * new: Spoof window.screen to mask desktop resolution and resize the
- browser to multiples of 50px while tor is enabled.
- * new: Block content window access to chrome urls if Tor is enabled,
- and hide Torbutton if Tor is disabled. Thanks to Greg Fleischer for
- reporting the chrome disclosure issues
- * new: Added option to close all opened tabs on a Tor toggle. Useful
- for general convenience and also as a backup protection against
- Bug 409737.
- * new: Add Tor ports to the list of banned ports for Firefox. Should
- prevent http-ping based fingerprinting attacks.
- * new: Finally add support for automatic updates.
-
-1.1.13
- 01 Feb 2008
- * bugfix: Implement workarounds to disable Javascript network access
- for Firefox Bug 409737
- * bugfix: Improved plugin-disabling workarounds for Firefox Bug 401296
- * misc: Set network.protocol-handler.warn-external.* to warn on external
- app handlers during Tor usage
- * misc: Disable browser.safebrowsing.enabled during Tor usage since it
- retrieves some information in plaintext.
- * misc: Disable browser.send_pings.
- * misc: Block Javascript back/forward manipulation if Tor is enabled
- * new: Option to clear HTTP auth on Tor toggle
-
-1.1.12
- 26 Nov 2007
- * bugfix: bug 520: Fix some content policy/tagging issues. Not sure if this
- is the whole bug.
- * bugfix: Fix a nasty bug where torbutton mostly broke if the first Firefox
- window was closed (introduced in 1.1.11)
- * bugfix: Fix a favicon proxy-leak discussed in onionland
-
-1.1.11
- 16 Nov 2007
- * bugfix: Fix a scope issue with the JS hooks that caused problems with
- some sites (gmail, others?)
- * misc: Performance enhancements for speeding up toggle
- * new: Prevent Tor cookies from being written to disk if the user wants
- them cleared.
-
-1.1.10
- 06 Nov 2007
- * bugfix: bug 522: Try harder to kill plugins before they do any network IO
- (discovered by goldy)
- * bugfix: bug 460: Remove hook verification. Attempt to apply hooks at every
- location event.
- * misc: New logging system
- * new: Have user choose between starting in Tor or Non-Tor after crash.
- Leaving it to Firefox is non-deterministic and should not be an option.
-
-1.1.9.1
- 23 Oct 2007
- * bugfix: 1.1.9 killed all plugins. Bring them back to life.
-
-1.1.9
- 21 Oct 2007
- * bugfix: bug 519: Fix Ubuntu Gutsy hang on startup.
- * bugfix: bug 521: Fix yet more false positive popups introduced in 1.1.8
- * bugfix: bug 522: Block loading of direct clicks of plugin-handled content
- (discovered by goldy).
-
-1.1.8
- 01 Oct 2007
- * bugfix: bug 503: Prevent sessionstore from writing Tor tabs to disk
- * bugfix: bug 510: Decouple cookie clearing from Clear Private Data settings
- * bugfix: bug 474: Decouple password+form saving from history writing
- * bugfix: bug 460: Rework handling of hooking based on global events+window
- lookup
- * bugfix: Hooking fixes for pages with nested frames/iframes
- * bugfix: Cookies are now properly synced before storing into a jar
- * misc: Tightened up the alerts a bit more for the javascript hooking
- * misc: Changed defaults to be less intrusive to non-tor usage
- * new: Added options to start in Tor and reload cookies after browser crash
- * new: Added ability to have both tor and non-tor cookie jars
-
-1.1.7
- 20 Sep 2007
- * bugfix: bug 495: couple of memory leaks found and fixed by arno
- * bugfix: bug 497: uninstall exception found and fixed by arno
- * bugfix: bug 460: No more alerts should happen. But does that mean its
- fixed? Outlook uncertain...
- * bugfix: bugs 461+489: verbosity+macos logging issues resolved
- * bugfix: if javascript is disabled, the hooking code no longer complains
- * misc: Update spoofed Firefox version to 2.0.0.6
- * new: "Restore Defaults" button added to the preferences window
-
-1.1.6
- 30 Jul 2007
- * bugfix: Fix an exception that may have messed up cookie/cache clearing
- if you allowed Tor to write history URLs (possibly kills bug #457)
- * bugfix: Use only sub-browsers for tagging. Could fix some Date hooking
- misses (possibly kills bug #460)
- * misc: Clean up annoying false positives with date hooking checks
-
-1.1.5
- 17 Jul 2007
- * bugfix: Reset shutdown option if user wants to manually manage cookies
- * misc: Add code to detect date hooking failures to zero in on Bug #460
- * new: Pref to disable "DOM Storage" during Tor usage
-
-1.1.4 - Defcon CD Release
- 6 Jul 2007
- * bugfix: Make plugin state tied to tab load state also
- * bugfix: Date hooking bug. getUTCYear is not defined. Must call getYear..
- * new: Add options to spoof charset and language headers
- * new: Add option to disable referer header. This can break some sites.
- Seems to break digg in particular.
- * new: Copy English strings to all language DTDs so they are at least
- functional.
-
-1.1.3 - Black Hat CD Release
- 30 Jun 2007
- * bugfix: Fully disable session store if option is set. Otherwise it
- can save Tor tabs and cause them to be reloaded during Tor usage!
- * new: Differentiate between crucial and recommended settings in preferences
-
-1.1.2
- 22 Jun 2007
- * bugfix: Make js hooking a bit more invisible
- * bugfix: Improve navigator.* hooking for user agent spoofing
- * new: Block session saving during tor usage
- * new: Add options to clear cookies during Tor/Non-Tor shutdowns
-
-1.1.1
- 20 Jun 2007
- * bugfix: Remove Date hooks from DOM after inserted. Fixes some sites
- who expect a fixed DOM structure.
- * new: Integrated Collin Jackson's history blocking+cookie jar code, adapted
- it to handle various Tor States+read/write differentiation.
- * new: Allow users to manually manage cookies
- * new: Mark tabs as having been fetched via Tor or in the clear
- * new: Add code to only enable javascript on tabs with the same Tor load
- state as the current
- * new: options to clear the cache, block disk cache, or block all caching
- * new: Created options tabbox
- * new: Option to block updates if Tor was enabled
- * new: Add nsIContentPolicy to block CSS popups from pages with a different
- load state than current Tor State.
- * new: Added user agent spoofing code
- * new: Support FireFox 2.0 only
- * new: Disable "safe browsing" remote lookups
- * new: block session saving
-
-
-1.1.0 - Security Development begins (Alpha branch)
- 31 Mar 2007
- * new: Option to disable all plugins during Tor usage
- * new: Javascript hooking to mask timezone for Date Object, attempted CSS fix
- * new: Options to clear history and cookies on Tor toggle
- * bugfix: Fix logging to use error console if logger extension not present
-
-1.0.5
- 18 Nov 2006
- * bugfix: fix the about box in firefox 1.0
- * bugfix: set the toolbar button to the correct state upon insertion into
- the toolbar (ff >= 1.5 only)
- * bugfix: clarify the wording of the one-liner extension description
- * bugfix: bypassing privoxy with Firefox <= 1.0 is not recommended
- * bugfix: remember previous "custom" proxy settings
- * misc: new icons
- * misc: keyboard shortcut re-assigned to ctrl-2
- * new: previous proxy settings are restored after exiting tor mode
- * new: if the torbutton proxy settings are changed while torbutton is
- enabled, then the active proxy settings are updated to reflect it
- * new: added twelve locales
-
-1.0.4
- 01 Jun 2006
- * bugfix: without-privoxy settings were incorrect
- * bugfix: https settings did not take effect until firefox restart
- * bugfix: let firefox generate our about box, so it will include the version
-
-1.0.3
- 31 May 2006
- * bugfix: statusbar style would reset to text after firefox restart
-
-1.0.2
- 23 May 2006
- * bugfix: fixed problem with socks_remote_dns
- * new: mozilla thunderbird support
- * new: user may customize proxy settings for nonstandard configurations
- * new: option to not use privoxy in the standard configuration
- * new: slovenian translation
- * new: french translation
- * new: keyboard shortcut (control-shift-t, changeable via keyconfig)
- * new: context menu for toolbar button and statusbar panel
- * new: attractive tor icons
- * new: about dialog
- * new: option to display statusbar as an icon instead of text
-
-1.0.1
- 16 Mar 2006
- * bugfix: toolbar button tooltips now display the correct status
- * bugfix: set socks5 proxy to tor port (9050) instead of privoxy (8118)
- * bugfix: allow user to change proxy exclusion list ("no proxy for")
- * new: use socks_remote_dns on firefox versions that have it
- * new: added update functionality through the extensions manager
- * new: added preference: display statusbar panel (yes/no)
- * new: added compatibility with firefox 1.0 and 0.9
-
-1.0
- 07 Mar 2006
- * initial release
diff --git a/src/LICENSE b/src/LICENSE
deleted file mode 100644
index c6bc6921..00000000
--- a/src/LICENSE
+++ /dev/null
@@ -1,53 +0,0 @@
-Copyright (c) 2006 Scott Squires, Oleg Ivanov
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
---------------------------------------------------------------------------------
-
-Date: Fri, 3 Mar 2006 03:16:21 +0200
-From: Oleg Ivanov
-To: Scott Squires
-Subject: Re: ProxyButton licensing question
-
-Hello Scott,
-
-I'm glad to support your project so you can use the Proxybutton in any way you
-need under any open source license as it's stated in mozdev's copyright policy.
-I'll just ask you to put in the Tor or it's source code any credits with
-references to me and the original Proxybutton. Feel free to ask if you have
-any questions regarding the extension - I'll be glad to help you.
-
-On Thursday 02 March 2006 05:01, you wrote:
-> Hello,
->
-> I am a volunteer for the Tor project, which is a network proxy with strong
-> anonymnity. We would like to make it easier for users to install and
-> configure the software, and would like a firefox button to enable/disable
-> Tor. Your extension is very close to what we need, our version would just
-> set the proxy for the user instead of the user needing to enter the
-> information. So I was wondering what license your software is released under
-> and whether we can use it as a base for this extension.
->
-> Thanks!
-> --Scott
-
---
-Oleg Ivanov
-mailto: saruman(a)unigsm.com
-ICQ #69991809
diff --git a/src/install.rdf b/src/install.rdf
deleted file mode 100644
index 637483c3..00000000
--- a/src/install.rdf
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0"?>
-<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:em="http://www.mozilla.org/2004/em-rdf#">
-
- <Description about="urn:mozilla:install-manifest">
- <em:name>Torbutton</em:name>
- <em:creator>Mike Perry</em:creator>
- <em:id>torbutton(a)torproject.org</em:id>
- <em:version>2.1.6</em:version>
- <em:multiprocessCompatible>true</em:multiprocessCompatible>
- <em:homepageURL>https://www.torproject.org/projects/torbrowser.html.en</em:homepageURL>
- <em:iconURL>chrome://torbutton/skin/tor.png</em:iconURL>
- <em:updateURL>data:text/plain,</em:updateURL>
- <em:updateKey>-</em:updateKey>
- <!-- firefox -->
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>60.0</em:minVersion>
- <em:maxVersion>10000.0</em:maxVersion>
- </Description>
- </em:targetApplication>
- </Description>
-</RDF>
diff --git a/trans_tools/old/mkmoz.sh b/trans_tools/old/mkmoz.sh
deleted file mode 100755
index 1f2986bc..00000000
--- a/trans_tools/old/mkmoz.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/bash -x
-#
-
-LOCALEDIR="../src/chrome/locale"
-
-poDir="po"
-directories="`ls -1 ./$poDir|tr _ -`"
-mozDir="moz"
-input="en"
-template="torbutton.dtd"
-
-for dir in $directories
-do
- pootleDir="`echo $dir|tr - _`";
- echo "$pootleDir"
- mkdir -p $mozDir/$dir/
- po2moz -i $poDir/$pootleDir/ -t ${LOCALEDIR}/${input}/ -o $mozDir/$dir/
- #po2moz -i $poDir/$pootleDir/ -t pootle/templates/ -o $mozDir/$dir/
-done
-
diff --git a/trans_tools/old/mkpo.sh b/trans_tools/old/mkpo.sh
deleted file mode 100755
index 5e06757a..00000000
--- a/trans_tools/old/mkpo.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/bash -x
-#
-
-LOCALEDIR="../src/chrome/locale/"
-
-directories="ar de-DE es hr-HR nl-NL pt-BR sl-SI de-AT el-GR fa-IR it-IT pl-PL zh-CN de-CH fr-FR ru zh-TW"
-outdir="po"
-#input="en-US/torbutton.dtd"
-input="en"
-template="torbutton.dtd"
-
-for dir in $directories
-do
- pootleDir="`echo $dir|tr - _`";
- mkdir -p $outdir/$pootleDir/
- #moz2po -i $dir/$template -t $input -o $outdir/$pootleDir/torbutton.po
- moz2po -i $LOCALEDIR/$dir/ -t $LOCALEDIR/$input/ -o $outdir/$pootleDir/
-done
-
-
diff --git a/trans_tools/old/mvmoz.sh b/trans_tools/old/mvmoz.sh
deleted file mode 100755
index 64ff4360..00000000
--- a/trans_tools/old/mvmoz.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-
-for locale in `ls -1 moz/`;
-do
- mv -v moz/$locale/*.{dtd,properties} ../src/chrome/locale/$locale/
-done
diff --git a/trans_tools/old/new_tb_strings.sh b/trans_tools/old/new_tb_strings.sh
deleted file mode 100755
index b0b4e30a..00000000
--- a/trans_tools/old/new_tb_strings.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/bash
-
-moz2po -P -i ../src/chrome/locale/en/ -o po/templates/
-
-for i in `ls -1 po`
-do
- msgmerge -U ./po/$i/torbutton.dtd.po ./po/templates/torbutton.dtd.pot
- msgmerge -U ./po/$i/torbutton.properties.po ./po/templates/torbutton.properties.pot
- msgmerge -U ./po/$i/browser.dtd.po ./po/templates/browser.dtd.pot
- msgmerge -U ./po/$i/browser.properties.po ./po/templates/browser.properties.pot
-done
-
-svn diff po
-svn commit po
-
-cd po
-tx push --source
-tx push --translation
-cd ..
-
diff --git a/trans_tools/old/validate.py b/trans_tools/old/validate.py
deleted file mode 100755
index 179e7b0f..00000000
--- a/trans_tools/old/validate.py
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/usr/bin/python
-
-from __future__ import unicode_literals, print_function
-
-import polib
-import sys
-import getopt
-
-symbols = [
- '(', ')', '<', '>', '{',
- '}', '[', ']', '\"', ';'
- ]
-
-counts = {}
-
-def reset():
- for s in symbols:
- counts[s] = 0
-
-def parse_orig_string(string):
- for ch in string:
- if ch in symbols:
- counts[ch] += 1
-
-def parse_trans_string(string):
- for ch in string:
- if ch in symbols:
- counts[ch] -= 1
-
-def get_strings(file):
- entries = []
- po = polib.pofile(file, autodetect_encoding=True)
-
- for entry in po:
- entries.append((entry.msgid, entry.msgstr, 0))
-
- return entries
-
-def warn():
- for s in symbols:
- if counts[s] < 0:
- return True
- return False
-
-def usage():
- print("Usage: %s -i/--input=<file.po> -l/--logfile=<logfile>" % sys.argv[0])
-
-def log(string, file_to_check, log_file, linenum = -1):
- f = log_file
- if linenum == -1:
- f.write(("%s: %s\n" % (file_to_check, string)).encode("utf-8"))
- else:
- f.write(("%s (%s): %s\n" % (file_to_check, linenum, string)).encode("utf-8"))
- #f.close()
-
-def check(file_to_check, log_file):
- errors = 0
-
- strings = get_strings(file_to_check)
- for (orig, trans, linenum) in strings:
- reset()
- parse_orig_string(orig)
- parse_trans_string(trans)
- if warn():
- errors += 1
- log(trans, file_to_check, log_file, linenum)
-
- if errors != 0:
- log("Total count of warnings %d\n" % errors, file_to_check, log_file)
-
-if __name__ == '__main__':
- try:
- opts, args = getopt.getopt(sys.argv[1:], "i:hl:", ["input=", "help", "logfile="])
- except getopt.GetoptError, err:
- print(str(err))
- sys.exit(2)
-
- file_to_check = None
- log_file = sys.stdout
-
- for opt, arg in opts:
- if opt in ("-i", "--input"):
- file_to_check = arg
- elif opt in ("-h", "--help"):
- usage()
- sys.exit()
- elif opt in ("-l", "--logfile"):
- log_file = arg
-
- if file_to_check is None or log_file is None:
- print("ERROR: You need to specify both the input and the logfile")
- sys.exit(2)
-
- check(file_to_check, log_file)
diff --git a/trans_tools/old/validate_all.sh b/trans_tools/old/validate_all.sh
deleted file mode 100755
index 47bb6e62..00000000
--- a/trans_tools/old/validate_all.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/bash
-
-for i in `ls -1 ./po`
-do
- ./validate.py --input=./po/$i/torbutton.dtd.po
- ./validate.py --input=./po/$i/torbutton.properties.po
-done
diff --git a/website/design/CHROME_NOTES b/website/design/CHROME_NOTES
deleted file mode 100644
index 5142453e..00000000
--- a/website/design/CHROME_NOTES
+++ /dev/null
@@ -1,120 +0,0 @@
-- Investigation of Privacy Mode:
- - Good:
- - Cookies Cleared+memory only
- - Cache cleared and memory-only
- - History not available via javascript or CSS
- - Safe because currently unsupported:
- - Geolocation not supported in browser
- - DOM Storage not supported
- - HTML5 Storage not supported
- - Http auth is cleared
- - Do they have a session store?
- - Yes. It is disabled.
- - Form history disabled
- - But non-private entries still available
- - Malware and phishing protection
- - Per-url check?
- - Doesn't seem like it..
- - Bad:
- - RLZ Identifier sent with all queries even in Incognito mode
- - http://www.google.com/support/chrome/bin/answer.py?hl=en&answer=107684
- - Flash cookies not cleared
- - Google gears are still available
- - Do they have their own storage?
- - Yes. Completely ignores private mode.
- - Safebrowsing API key not cleared?
- - but updates may not happen "under" the incognito window
- - Desktop resolution available
- - Browser resolution is available
- - SSL session keys
- - Not cleared!
- - They clear trusted certs tho
- - Timezone not spoofed
-
-- Misc Features we definitely need:
- - Incognito-specific proxy settings
- - Browser proxy settings currently do not apply immediately
- - Plugin enable/disable controls
- - Spoof user agent
- - Referer alteration API
- - Autolaunching of remote apps needs to be disabled
- - API to opt-out of all the opt-in tracking for incognito mode
- - Cookie API would be nice
- - Need network.security.ports.banned
- - http://www.remote.org/jochen/sec/hfpa/hfpa.pdf
- - Resize windows (content-window side possibly ok)
-
-- Future investigation
- - Non-private form history still available
- - Forms seem to not be auto-filled, but this may be different
- for some fields?
- - How evil is google update? will it happen over incognito?
- - http://en.wikipedia.org/wiki/Google_Updater#Google_Updater
- - http://en.wikipedia.org/wiki/SRWare_Iron#Differences_from_Chrome
- - http://foliovision.com/2008/12/09/adwords-ppc-organic-rlz/
- - Test in more detail with sysinternals for disk writes
- - What about safebrowsing requests? Can they bypass proxy?
- - Video tag supports H264 and ogg via ffmpeg
- - Hrmm.. proxy bypass ability?
-
-- Test results. Used Incognito Mode with the test suites from:
- https://www.torproject.org/torbutton/design/#SingleStateTesting
- - Decloak.net:
- - Recovers IP and DNS via Java
- - Recovers IP via flash
- - Deanonymizer.com
- - Failed NNTP and FTP quicktime
- - JohnDo's hated some headers
- - Mr. T got a lot of shit wrong...
- - http://labs.isecpartners.com/breadcrumbs/breadcrumbs.html
-
-- Comparison with Torora
- - http://github.com/mwenge/torora/tree/master/doc/DESIGN.torora
- - Good ideas for both chrome and torbutton:
- - Cache/Cookie expiry every 24hrs
- - Random preturbation on Date() object..
- - No longer possible without js hooks :/
- - Possible if Chrome allows non-delatable shadowing of window.Date()
- from user scripts. ECMA says it should
-
-==========================================
-
-- Incognito Issues:
- - SSL session keys
- - Not cleared!
- - Flash cookies not cleared
- - Better Privacy? Permissions?
- - Google gears are still available
- - Do they have their own storage?
- - Yes. Completely ignores private mode.
- - RLZ override/disable for incognito
- - Opt out of opt-in tracking?
- - Source code:
- http://src.chromium.org/viewvc/chrome/trunk/src/chrome/browser/profile.cc
-
-- Privacy Enhancing API Wishlist (remove existing items):
- - http://code.google.com/chrome/extensions/devguide.html
- - Prefs (copy-on-write for incognito mode)
- - Incognito-specific proxy settings
- - Should not be used for safebrowsing or app/addon update
- - pref to disable autolaunch of apps/warn user
- - network.security.ports.banned
- - User agent (that also govern navigator.*)
- - could be done (better) via http headers and good hook support
- - Core APIs:
- - Per-Plugin enable/disable controls
- - Cookie API
- - Cache control
- - HTTP header alteration ("on-modify-request")
- - Referrer, accept, user agent
- - Javascript hooks:
- - http://code.google.com/chrome/extensions/content_scripts.html
- - Bleh, these suck... Too limited.
- - ECMA compliance
- - desktop+screen resolution
- - Date hooking
- - navigator.* hooking
-
-- Posted at:
- - http://groups.google.com/group/chromium-extensions/t/ceba26ca9e2f6a78
-
diff --git a/website/design/FF35_AUDIT b/website/design/FF35_AUDIT
deleted file mode 100644
index 35a9fbf4..00000000
--- a/website/design/FF35_AUDIT
+++ /dev/null
@@ -1,195 +0,0 @@
-First pass: Quick Review of Firefox Features
-- Video Tag
- - Docs:
- - https://developer.mozilla.org/En/HTML/Element/Audio
- - https://developer.mozilla.org/En/HTML/Element/Video
- - https://developer.mozilla.org/En/HTML/Element/Source
- - https://developer.mozilla.org/En/Manipulating_video_using_canvas
- - https://developer.mozilla.org/En/nsIDOMHTMLMediaElement
- - https://developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_v…
- - http://en.flossmanuals.net/TheoraCookbook
- - nsIContentPolicy is checked on load
- - Uses NSIChannels for initial load
- - Wrapped in nsHTMLMediaElement::mDecoder
- - is nsOggDecoder() or nsWaveDecoder()
- - liboggplay
- - Governed by media.* prefs
- - Preliminary audit shows they do not use the liboggplay tcp functions
-- Geolocation
- - Wifi:
- - https://developer.mozilla.org/En/Monitoring_WiFi_access_points
- - Requires security policy to allow. Then still prompted
- - navigator.geolocation
- - Governed by geo.enabled
- - "2 week access token" is set
- - geo.wifi.access_token.. Clearing is prob a good idea
- - http://mxr.mozilla.org/mozilla1.9.1/source/dom/src/geolocation/NetworkGeolo…
- - https://developer.mozilla.org/En/Using_geolocation
-- DNS prefetching after toggle
- - prefetch pref? Always disable for now?
- - network.dns.disablePrefetch
- - Also disabled in netwerk/dns/src/nsDNSService2.cpp when manual proxies
- are set..
- - This should prevent prefetching of non-tor urls in tor mode..
- - But the reverse is unclear.
- - DocShell attribute!!1 YAY
- - http://www.oxymoronical.com/experiments/apidocs/interface/nsIDocShell
- - "Takes effect for the NEXT document loaded...."
- - Do we win this race? hrmm.. If we do, the tor->nontor direction
- should also be safe.
- - Content policy called?
- - No. See content/html/content/src/nsHTMLDNSPrefetch.cpp
-- Storage
- - https://developer.mozilla.org/en/Storage
- - "It is available to trusted callers, meaning extensions and Firefox
- components only."
-- New content policy
- - Content Security Policy. Addon-only
-- "Offline resources"
- - https://developer.mozilla.org/en/Offline_resources_in_Firefox
- - https://developer.mozilla.org/en/nsIApplicationCache
- - browser.cache.offline.enable toggles
- - browser.cache.disk.enable does not apply. Seperate "device".
- - Does our normal cache clearing mechanism apply?
- - We call nsICacheService.evictEntries()
- - May need: nsOfflineCacheDevice::EvictEntries(NULL)
- - Code is smart enough to behave cleanly if we simply set
- browser.cache.offline.enable or enable private browsing.
-- Mouse gesture and other new DOM events
-- Fonts
- - Remote fonts obey content policy. Good.
- - XXX: Are they cached independent of regular cache? Prob not.
- - Hrmm can probe for installed fonts:
- http://remysharp.com/2008/07/08/how-to-detect-if-a-font-is-installed-only-u…
- http://www.lalit.org/lab/javascript-css-font-detect
- http://www.ajaxupdates.com/cssjavascript-font-detector/
- http://code.google.com/p/jquery-fontavailable/
-- Drag and drop
- - https://developer.mozilla.org/En/DragDrop/Drag_and_Drop
- - https://developer.mozilla.org/En/DragDrop/Drag_Operations
- - https://developer.mozilla.org/En/DragDrop/Dragging_and_Dropping_Multiple_It…
- - https://developer.mozilla.org/En/DragDrop/Recommended_Drag_Types
- - https://developer.mozilla.org/En/DragDrop/DataTransfer
- - Should be no different than normal url handling..
-- Local Storage
- - https://developer.mozilla.org/en/DOM/Storage#localStorage
- - Disabled by dom storage pref..
- - Private browsing mode has its own DB
- - Memory only?
- - Disk Avoidance of gStorage and local storage:
- - mSessionOnly set via nsDOMStorage::CanUseStorage()
- - Seems to be set to true if cookies are session-only or private
- browsing mode
- - Our cookies are NOT session-only with dual cookie jars
- - but this is ok if we clear the session storage..
- - XXX: Technically clearing session storage may break
- sites if cookies remain though
- - nsDOMStoragePersistentDB not used if mSessionOnly
- - Can clear with nsDOMStorage::ClearAll() or nsIDOMStorage2::clear()?
- - These only work for a particular storage. There's both global now
- and per-origin storage instances
- - Each docshell has tons of storages for each origin contained in it
- - Toggling dom.storage.enabled does not clear existing storage
- - Oh HOT! cookie-changed to clear cookies clears all storages!
- - happens for both ff3.0 and 3.5 in dom/src/storage/nsDOMStorage.cpp
- - Conclusion:
- - can safely enable dom storage
- - May have minor buggy usability issues unless we preserve it
- when user is preserving cookies..
-
-Second Pass: Verification of all Torbutton Assumptions
-- "Better privacy controls"
- - Basically UI stuff for prefs we set already
- - address bar search disable option is interesting, but not
- torbutton's job to toggle. Users will hate us.
-- Private browsing
- - https://developer.mozilla.org/En/Supporting_private_browsing_mode
- - We should consider an option (off by default) to enable PBM during
- toggle
- - It is a good idea because it will let our users use DOM storage
- safely and also may cause their plugins and other addons to be
- safe
- - Doing it always will cause the user to lose fine-grained control
- of many settings
- - Also we'll need to prevent them from leaving without toggling tor
- - Stuff the emit does (grep for NS_PRIVATE_BROWSING_SWITCH_TOPIC and
- "private-browsing")
- - XXX: clear mozilla.org/security/sdr;1. We should too! Wtf is it??
- - Neg. Best to let them handle this. Users will be annoyed
- at having to re-enter their passwords..
- - They also clear the console service..
- - Recommend watching private-browsing-cancel-vote and blocking if
- we are performing a db operation
- - Maybe we want to block transitions during our toggle for safety
- - XXX: They also clear general.open_location.last_url
- - XXX: mozilla.org/permissionmanager
- - XXX: mozilla.org/content-pref/service
- - XXX: Sets browser.zoom.siteSpecific to false
- - Interesting.. They clear their titles.. I wonder if some
- window managers log titles.. But that level of surveillance is
- unbeatable..
- - XXX: Unless there is some way for flash or script to read titles?
- - They empty the clipboard..
- - Can js access the clipboard?? ...
- - Yes, but needs special pref+confirmation box
- - http://www.dynamic-tools.net/toolbox/copyToClipboard/
- - They clear cache..
- - Cookies:
- - Use in-memory table that is different than their default
- - This could fuck up our cookie storage options
- - We could maybe prevent them from getting this
- event by wrapping nsCookieService::Observe(). Lullz..
- - NavHistory:
- - XXX: nsNavHistory::AutoCompleteFeedback() doesn't track
- awesomebar choices for feedback.. Is this done on disk?
- - Don't add history entries
- - We should block this observe event too if we can..
- - The session store stops storing tabs
- - We could block this observe
- - XXX: They expunge private temporary files on exit from PMB
- - This is not done normally until browser exit or
- "on-profile-change"
- - emits browser:purge-domain-data.. Mostly just for session
- editing it appears
- - Direct component query for pbs.privateBrowsingEnabled
- - This is where we have no ability to provide certain option
- control
- - browser.js seems to prevent user from allowing blocked
- popups?
- - Some items in some places context menu get blocked:
- - Can't delete items from history? placesContext_deleteHost
- - nsCookiePermission::InPrivateBrowsing() calls direct
- - but is irellevant
- - Form history cannot be saved while in PBM.. :(
- - User won't be prompted for adding login passwords..
- - Can't remember prefs on content types
- - Many components read this value upon init:
- - This fucks up our observer game if tor starts enabled
- - NavHistory and cookie and dl manager
- - We could just wrap the bool on startup and lie
- and emit later... :/
- - Or! emit an exit and an enter always at startup if tor is
- enabled.
- - Read iSec report
- - Compare to Chrome
- - API use cases
-- SessionStore
- - Has been reworked with observers and write methods. Should use those.
-- security.enable_ssl2 to clear session id
- - Still cleared
-- browser.sessionstore.max_tabs_undo
- - Yep.
-- SafeBrowsing Update Key removed on cookie clear still?
- - Yep.
-- Livemark updates have kill events now
-- Test if nsICertStore is still buggy...
-
-Third Pass: Exploit Auditing
-- Remote fonts
-- SVG with HTML
-- Javascript threads+locking
-- Ogg theora and vorbis codecs
-- SQLite
-
-
-- https://developer.mozilla.org/en/Firefox_3_for_developers
diff --git a/website/design/FF40_AUDIT b/website/design/FF40_AUDIT
deleted file mode 100644
index 7830eb34..00000000
--- a/website/design/FF40_AUDIT
+++ /dev/null
@@ -1,50 +0,0 @@
-- Review of https://developer.mozilla.org/en/Firefox_4_for_developers
- - Potential proxy issues
- - DocShell and plugins inside createHTMLDocument?
- - https://developer.mozilla.org/en/DOM/DOMImplementation.createHTMLDocument
- - WebSockets?
- - Media attributes?
- - "buffered"
- - "preload"
- - new codecs?
- - What the hell is a blob url?
- - https://developer.mozilla.org/en/DOM/window.createBlobURL
- - https://developer.mozilla.org/en/DOM/window.revokeBlobURL
- - Seems only relevent to FS injection..
- - WebThreads are OK:
- - https://developer.mozilla.org/En/Using_web_workers
- - Network activity blocked by content policy
- - Fingerprinting issues:
- - New screen attributes
- - https://developer.mozilla.org/en/DOM/window.mozInnerScreenX, Y
- - High Res Animation Timers:
- - https://developer.mozilla.org/en/DOM/window.mozAnimationStartTime
- - https://developer.mozilla.org/en/DOM/Animations_using_MozBeforePaint
- - 50-60hz max.. Can we leverage this?
- - timeStamps on keystroke events
- - https://developer.mozilla.org/en/DOM/event.timeStamp
- - Bounding rectangles -> window sizes?
- - Maybe not display sizes, but seems possible to fingerprint rendered
- content size.. ugh.
- - https://developer.mozilla.org/en/DOM/element.getBoundingClientRect
- - https://developer.mozilla.org/en/dom:range
- - CSS resize, media queries, etc..
- - WebGL may also expose screen properties and video card properties:
- - https://developer.mozilla.org/en/WebGL
- - https://www.khronos.org/registry/webgl/specs/1.0/#5.2
- - https://www.khronos.org/registry/webgl/specs/1.0/#5.11
- - SVG needs auditing. It may also expose absolute coords, but appears OK
- - https://developer.mozilla.org/en/SVG/SVG_animation_with_SMIL
- - Mouse events reveal desktop coordinates
- - https://bugzilla.mozilla.org/show_bug.cgi?id=503943
- - https://developer.mozilla.org/en/DOM/Event/UIEvent/MouseEvent
- - Actual screen dimensions not exposed
- - Identifier Storage
- - Content Secuity Properties may need clearing:
- - https://developer.mozilla.org/en/Security/CSP
- - STS cache needs clearing
- - New window.history functions may allow state smuggling
- - https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history
-
-- New Javascript hooking options may help improve Date() hooks:
- - https://developer.mozilla.org/en/JavaScript/New_in_JavaScript/1.8.5
diff --git a/website/design/MozillaBrownBag.odp b/website/design/MozillaBrownBag.odp
deleted file mode 100644
index bf844061..00000000
Binary files a/website/design/MozillaBrownBag.odp and /dev/null differ
diff --git a/website/design/MozillaBrownBag.pdf b/website/design/MozillaBrownBag.pdf
deleted file mode 100644
index ebcd3418..00000000
Binary files a/website/design/MozillaBrownBag.pdf and /dev/null differ
diff --git a/website/design/build.sh b/website/design/build.sh
deleted file mode 100755
index 6531077e..00000000
--- a/website/design/build.sh
+++ /dev/null
@@ -1 +0,0 @@
-xsltproc --output index.html.en --stringparam section.autolabel.max.depth 2 --stringparam section.autolabel 1 /usr/share/sgml/docbook/xsl-stylesheets-1.75.2/xhtml/docbook.xsl design.xml
diff --git a/website/design/design.xml b/website/design/design.xml
deleted file mode 100644
index bc0d5b89..00000000
--- a/website/design/design.xml
+++ /dev/null
@@ -1,2901 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
- "file:///usr/share/sgml/docbook/xml-dtd-4.4-1.0-30.1/docbookx.dtd">
-
-<article id="design">
- <articleinfo>
- <title>Torbutton Design Documentation</title>
- <author>
- <firstname>Mike</firstname><surname>Perry</surname>
- <affiliation>
- <address><email>mikeperry.fscked/org</email></address>
- </affiliation>
- </author>
- <pubdate>Apr 10 2011</pubdate>
- </articleinfo>
-
-<sect1>
- <title>Introduction</title>
- <para>
-
-This document describes the goals, operation, and testing procedures of the
-Torbutton Firefox extension. It is current as of Torbutton 1.3.2.
-
- </para>
- <sect2 id="adversary">
- <title>Adversary Model</title>
- <para>
-
-A Tor web browser adversary has a number of goals, capabilities, and attack
-types that can be used to guide us towards a set of requirements for the
-Torbutton extension. Let's start with the goals.
-
- </para>
- <sect3 id="adversarygoals">
- <title>Adversary Goals</title>
- <orderedlist>
-<!-- These aren't really commands.. But it's the closest I could find in an
-acceptable style.. Don't really want to make my own stylesheet -->
- <listitem><command>Bypassing proxy settings</command>
- <para>The adversary's primary goal is direct compromise and bypass of
-Tor, causing the user to directly connect to an IP of the adversary's
-choosing.</para>
- </listitem>
- <listitem><command>Correlation of Tor vs Non-Tor Activity</command>
- <para>If direct proxy bypass is not possible, the adversary will likely
-happily settle for the ability to correlate something a user did via Tor with
-their non-Tor activity. This can be done with cookies, cache identifiers,
-javascript events, and even CSS. Sometimes the fact that a user uses Tor may
-be enough for some authorities.</para>
- </listitem>
- <listitem><command>History disclosure</command>
- <para>
-The adversary may also be interested in history disclosure: the ability to
-query a user's history to see if they have issued certain censored search
-queries, or visited censored sites.
- </para>
- </listitem>
- <listitem><command>Location information</command>
- <para>
-
-Location information such as timezone and locality can be useful for the
-adversary to determine if a user is in fact originating from one of the
-regions they are attempting to control, or to zero-in on the geographical
-location of a particular dissident or whistleblower.
-
- </para>
- </listitem>
- <listitem><command>Miscellaneous anonymity set reduction</command>
- <para>
-
-Anonymity set reduction is also useful in attempting to zero in on a
-particular individual. If the dissident or whistleblower is using a rare build
-of Firefox for an obscure operating system, this can be very useful
-information for tracking them down, or at least <link
-linkend="fingerprinting">tracking their activities</link>.
-
- </para>
- </listitem>
- <listitem><command>History records and other on-disk
-information</command>
- <para>
-In some cases, the adversary may opt for a heavy-handed approach, such as
-seizing the computers of all Tor users in an area (especially after narrowing
-the field by the above two pieces of information). History records and cache
-data are the primary goals here.
- </para>
- </listitem>
- </orderedlist>
- </sect3>
-
- <sect3 id="adversarypositioning">
- <title>Adversary Capabilities - Positioning</title>
- <para>
-The adversary can position themselves at a number of different locations in
-order to execute their attacks.
- </para>
- <orderedlist>
- <listitem><command>Exit Node or Upstream Router</command>
- <para>
-The adversary can run exit nodes, or alternatively, they may control routers
-upstream of exit nodes. Both of these scenarios have been observed in the
-wild.
- </para>
- </listitem>
- <listitem><command>Adservers and/or Malicious Websites</command>
- <para>
-The adversary can also run websites, or more likely, they can contract out
-ad space from a number of different adservers and inject content that way. For
-some users, the adversary may be the adservers themselves. It is not
-inconceivable that adservers may try to subvert or reduce a user's anonymity
-through Tor for marketing purposes.
- </para>
- </listitem>
- <listitem><command>Local Network/ISP/Upstream Router</command>
- <para>
-The adversary can also inject malicious content at the user's upstream router
-when they have Tor disabled, in an attempt to correlate their Tor and Non-Tor
-activity.
- </para>
- </listitem>
- <listitem><command>Physical Access</command>
- <para>
-Some users face adversaries with intermittent or constant physical access.
-Users in Internet cafes, for example, face such a threat. In addition, in
-countries where simply using tools like Tor is illegal, users may face
-confiscation of their computer equipment for excessive Tor usage or just
-general suspicion.
- </para>
- </listitem>
- </orderedlist>
- </sect3>
-
- <sect3 id="attacks">
- <title>Adversary Capabilities - Attacks</title>
- <para>
-
-The adversary can perform the following attacks from a number of different
-positions to accomplish various aspects of their goals. It should be noted
-that many of these attacks (especially those involving IP address leakage) are
-often performed by accident by websites that simply have Javascript, dynamic
-CSS elements, and plugins. Others are performed by adservers seeking to
-correlate users' activity across different IP addresses, and still others are
-performed by malicious agents on the Tor network and at national firewalls.
-
- </para>
- <orderedlist>
- <listitem><command>Inserting Javascript</command>
- <para>
-If not properly disabled, Javascript event handlers and timers
-can cause the browser to perform network activity after Tor has been disabled,
-thus allowing the adversary to correlate Tor and Non-Tor activity and reveal
-a user's non-Tor IP address. Javascript
-also allows the adversary to execute <ulink
-url="http://whattheinternetknowsaboutyou.com/">history disclosure attacks</ulink>:
-to query the history via the different attributes of 'visited' links to search
-for particular Google queries, sites, or even to <ulink
-url="http://www.mikeonads.com/2008/07/13/using-your-browser-url-history-estimate…">profile
-users based on gender and other classifications</ulink>. Finally,
-Javascript can be used to query the user's timezone via the
-<function>Date()</function> object, and to reduce the anonymity set by querying
-the <function>navigator</function> object for operating system, CPU, locale,
-and user agent information.
- </para>
- </listitem>
-
- <listitem><command>Inserting Plugins</command>
- <para>
-
-Plugins are abysmal at obeying the proxy settings of the browser. Every plugin
-capable of performing network activity that the author has
-investigated is also capable of performing network activity independent of
-browser proxy settings - and often independent of its own proxy settings.
-Sites that have plugin content don't even have to be malicious to obtain a
-user's
-Non-Tor IP (it usually leaks by itself), though <ulink
-url="http://decloak.net">plenty of active
-exploits</ulink> are possible as well. In addition, plugins can be used to store unique identifiers that are more
-difficult to clear than standard cookies.
-<ulink url="http://epic.org/privacy/cookies/flash.html">Flash-based
-cookies</ulink> fall into this category, but there are likely numerous other
-examples.
-
- </para>
- </listitem>
- <listitem><command>Inserting CSS</command>
- <para>
-
-CSS can also be used to correlate Tor and Non-Tor activity and reveal a user's
-Non-Tor IP address, via the usage of
-<ulink url="http://www.tjkdesign.com/articles/css%20pop%20ups/">CSS
-popups</ulink> - essentially CSS-based event handlers that fetch content via
-CSS's onmouseover attribute. If these popups are allowed to perform network
-activity in a different Tor state than they were loaded in, they can easily
-correlate Tor and Non-Tor activity and reveal a user's IP address. In
-addition, CSS can also be used without Javascript to perform <ulink
-url="http://ha.ckers.org/weird/CSS-history.cgi">CSS-only history disclosure
-attacks</ulink>.
- </para>
- </listitem>
- <listitem><command>Read and insert cookies</command>
- <para>
-
-An adversary in a position to perform MITM content alteration can inject
-document content elements to both read and inject cookies for
-arbitrary domains. In fact, many "SSL secured" websites are vulnerable to this
-sort of <ulink url="http://seclists.org/bugtraq/2007/Aug/0070.html">active
-sidejacking</ulink>.
-
- </para>
- </listitem>
- <listitem><command>Create arbitrary cached content</command>
- <para>
-
-Likewise, the browser cache can also be used to <ulink
-url="http://crypto.stanford.edu/sameorigin/safecachetest.html">store unique
-identifiers</ulink>. Since by default the cache has no same-origin policy,
-these identifiers can be read by any domain, making them an ideal target for
-adserver-class adversaries.
-
- </para>
- </listitem>
-
- <listitem id="fingerprinting"><command>Fingerprint users based on browser
-attributes</command>
-<para>
-
-There is an absurd amount of information available to websites via attributes
-of the browser. This information can be used to reduce anonymity set, or even
-<ulink url="http://mandark.fr/0x000000/articles/Total_Recall_On_Firefox..html">uniquely
-fingerprint individual users</ulink>. </para>
-<para>
-For illustration, let's perform a
-back-of-the-envelope calculation on the number of anonymity sets for just the
-resolution information available in the <ulink
-url="http://developer.mozilla.org/en/docs/DOM:window">window</ulink> and
-<ulink
-url="http://developer.mozilla.org/en/docs/DOM:window.screen">window.screen</ulink>
-objects.
-
-
-
-Browser window resolution information provides something like
-(1280-640)*(1024-480)=348160 different anonymity sets. Desktop resolution
-information contributes about another factor of 5 (for about 5 resolutions in
-typical use). In addition, the dimensions and position of the desktop taskbar
-are available, which can reveal hints on OS information. This boosts the count
-by a factor of 5 (for each of the major desktop taskbars - Windows, OSX, KDE
-and Gnome, and None). Subtracting the browser content window
-size from the browser outer window size provide yet more information.
-Firefox toolbar presence gives about a factor of 8 (3 toolbars on/off give
-2<superscript>3</superscript>=8). Interface effects such as title bar font size
-and window manager settings gives a factor of about 9 (say 3 common font sizes
-for the title bar and 3 common sizes for browser GUI element fonts).
-Multiply this all out, and you have (1280-640)*(1024-480)*5*5*8*9 ~=
-2<superscript>29</superscript>, or a 29 bit identifier based on resolution
-information alone. </para>
-
-<para>
-
-Of course, this space is non-uniform in user density and prone to incremental
-changes. The <ulink
-url="https://wiki.mozilla.org/Fingerprinting#Data">Panopticlick study
-done</ulink> by the EFF attempts to measure the actual entropy - the number of
-identifying bits of information encoded in browser properties. Their result
-data is definitely useful, and the metric is probably the appropriate one for
-determining how identifying a particular browser property is. However, some
-quirks of their study means that they do not extract as much information as
-they could from display information: they only use desktop resolution (which
-Torbutton reports as the window resolution) and do not attempt to infer the
-size of toolbars.
-
-</para>
-<!--
-FIXME: This is no longer true. Only certain addons are now discoverable, and
-only if they want to be:
-http://webdevwonders.com/detecting-firefox-add-ons/
-https://developer.mozilla.org/en/Updating_web_applications_for_Firefox_3#section_7
-
-<para>
-
-To add insult to injury, <ulink
-url="http://pseudo-flaw.net/content/tor/torbutton/">chrome URL disclosure
-attacks</ulink> mean that each and every extension on <ulink
-url="https://addons.mozilla.org">addons.mozilla.org</ulink> adds another bit
-to that 2<superscript>29</superscript>. With hundreds of popular extensions
-and thousands of extensions total, it is easy to see that this sort of
-information is an impressively powerful identifier if used properly by a
-competent and determined adversary such as an ad network. Again, a
-nearest-neighbor bit vector space approach here would also gracefully handle
-incremental changes to installed extensions.
-
-</para>
--->
- </listitem>
- <listitem><command>Remotely or locally exploit browser and/or
-OS</command>
- <para>
-Last, but definitely not least, the adversary can exploit either general
-browser vulnerabilities, plugin vulnerabilities, or OS vulnerabilities to
-install malware and surveillance software. An adversary with physical access
-can perform similar actions. Regrettably, this last attack capability is
-outside of Torbutton's ability to defend against, but it is worth mentioning
-for completeness.
- </para>
- </listitem>
- </orderedlist>
- </sect3>
-
- </sect2>
-
- <sect2 id="requirements">
- <title>Torbutton Requirements</title>
-<note>
-
-Since many settings satisfy multiple requirements, this design document is
-organized primarily by Torbutton components and settings. However, if you are
-the type that would rather read the document from the requirements
-perspective, it is in fact possible to search for each of the following
-requirement phrases in the text to find the relevant features that help meet
-that requirement.
-
-</note>
- <para>
-
-From the above Adversary Model, a number of requirements become clear.
-
- </para>
-
-<orderedlist>
-<!-- These aren't really commands.. But it's the closest I could find in an
-acceptable style.. Don't really want to make my own stylesheet -->
- <listitem id="proxy"><command>Proxy Obedience</command>
- <para>The browser
-MUST NOT bypass Tor proxy settings for any content.</para></listitem>
- <listitem id="state"><command>State Separation</command>
- <para>Browser state (cookies, cache, history, 'DOM storage'), accumulated in
- one Tor state MUST NOT be accessible via the network in
- another Tor state.</para></listitem>
- <listitem id="isolation"><command>Network Isolation</command>
- <para>Pages MUST NOT perform any network activity in a Tor state different
- from the state they were originally loaded in.</para>
- <para>Note that this requirement is
-being de-emphasized due to the coming shift to supporting only the Tor Browser
-Bundles, which do not support a Toggle operation.</para></listitem>
- <listitem id="undiscoverability"><command>Tor Undiscoverability</command><para>With
-the advent of bridge support in Tor 0.2.0.x, there are now a class of Tor
-users whose network fingerprint does not obviously betray the fact that they
-are using Tor. This should extend to the browser as well - Torbutton MUST NOT
-reveal its presence while Tor is disabled.
-</para>
- <para>Note that this requirement is
-being de-emphasized due to the coming shift to supporting only the Tor Browser
-Bundles, which do not support a Toggle operation.</para>
-</listitem>
- <listitem id="disk"><command>Disk Avoidance</command><para>The browser SHOULD NOT write any Tor-related state to disk, or store it
- in memory beyond the duration of one Tor toggle.</para></listitem>
- <listitem id="location"><command>Location Neutrality</command><para>The browser SHOULD NOT leak location-specific information, such as
- timezone or locale via Tor.</para></listitem>
- <listitem id="setpreservation"><command>Anonymity Set
-Preservation</command><para>The browser SHOULD NOT leak any other anonymity
-set reducing or fingerprinting information
- (such as user agent, extension presence, and resolution information)
-automatically via Tor. The assessment of the attacks above should make it clear
-that anonymity set reduction is a very powerful method of tracking and
-eventually identifying anonymous users.
-</para></listitem>
- <listitem id="updates"><command>Update Safety</command><para>The browser
-SHOULD NOT perform unauthenticated updates or upgrades via Tor.</para></listitem>
- <listitem id="interoperate"><command>Interoperability</command><para>Torbutton SHOULD interoperate with third-party proxy switchers that
- enable the user to switch between a number of different proxies. It MUST
- provide full Tor protection in the event a third-party proxy switcher has
- enabled the Tor proxy settings.</para></listitem>
-</orderedlist>
- </sect2>
- <sect2 id="layout">
- <title>Extension Layout</title>
-
-<para>Firefox extensions consist of two main categories of code: 'Components' and
-'Chrome'. Components are a fancy name for classes that implement a given
-interface or interfaces. In Firefox, components <ulink
-url="https://developer.mozilla.org/en/XPCOM">can be
-written</ulink> in C++,
-Javascript, or a mixture of both. Components have two identifiers: their
-'<ulink
-url="http://www.mozilla.org/projects/xpcom/book/cxc/html/quicktour2.html#1005005">Contract
-ID</ulink>' (a human readable path-like string), and their '<ulink
-url="http://www.mozilla.org/projects/xpcom/book/cxc/html/quicktour2.html#1005329">Class
-ID</ulink>' (a GUID hex-string). In addition, the interfaces they implement each have a hex
-'Interface ID'. It is possible to 'hook' system components - to reimplement
-their interface members with your own wrappers - but only if the rest of the
-browser refers to the component by its Contract ID. If the browser refers to
-the component by Class ID, it bypasses your hooks in that use case.
-Technically, it may be possible to hook Class IDs by unregistering the
-original component, and then re-registering your own, but this relies on
-obsolete and deprecated interfaces and has proved to be less than
-stable.</para>
-
-<para>'Chrome' is a combination of XML and Javascript used to describe a window.
-Extensions are allowed to create 'overlays' that are 'bound' to existing XML
-window definitions, or they can create their own windows. The DTD for this XML
-is called <ulink
-url="http://developer.mozilla.org/en/docs/XUL_Reference">XUL</ulink>.</para>
- </sect2>
-</sect1>
-<sect1 id="components">
- <title>Components</title>
- <para>
-
-Torbutton installs components for two purposes: hooking existing components to
-reimplement their interfaces; and creating new components that provide
-services to other pieces of the extension.
-
- </para>
-
- <sect2 id="hookedxpcom">
- <title>Hooked Components</title>
-
-<para>Torbutton makes extensive use of Contract ID hooking, and implements some
-of its own standalone components as well. Let's discuss the hooked components
-first.</para>
-
-<sect3 id="appblocker">
- <title><ulink
-url="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/c…">@mozilla.org/uriloader/external-protocol-service;1
-</ulink>, <ulink
-url="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/c…">@mozilla.org/uriloader/external-helper-app-service;1</ulink>,
-and <ulink url="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/c…">@mozilla.org/mime;1</ulink>
-- <ulink
- url="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…">components/external-app-blocker.js</ulink></title>
- <para>
-Due to <link linkend="FirefoxBugs">Firefox Bug</link> <ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=440892">440892</ulink> allowing Firefox 3.x to automatically launch some
-applications without user intervention, Torbutton had to wrap the three
-components involved in launching external applications to provide user
-confirmation before doing so while Tor is enabled. Since external applications
-do not obey proxy settings, they can be manipulated to automatically connect
-back to arbitrary servers outside of Tor with no user intervention. Fixing
-this issue helps to satisfy Torbutton's <link linkend="proxy">Proxy
-Obedience</link> Requirement.
- </para>
-</sect3>
-<sect3>
-<title><ulink url="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/c…">@mozilla.org/browser/global-history;2</ulink>
-- <ulink
- url="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…">components/ignore-history.js</ulink></title>
-
-<para>This component was contributed by <ulink
-url="http://www.collinjackson.com/">Collin Jackson</ulink> as a method for defeating
-CSS and Javascript-based methods of history disclosure. The global-history
-component is what is used by Firefox to determine if a link was visited or not
-(to apply the appropriate style to the link). By hooking the <ulink
-url="https://developer.mozilla.org/en/nsIGlobalHistory2#isVisited.28.29">isVisited</ulink>
-and <ulink
-url="https://developer.mozilla.org/en/nsIGlobalHistory2#addURI.28.29">addURI</ulink>
-methods, Torbutton is able to selectively prevent history items from being
-added or being displayed as visited, depending on the Tor state and the user's
-preferences.
-</para>
-<para>
-This component helps satisfy the <link linkend="state">State Separation</link>
-and <link linkend="disk">Disk Avoidance</link> requirements of Torbutton. It
-is only needed for Firefox 3.x. On Firefox 4, we omit this component in favor
-of the <ulink
-url="https://developer.mozilla.org/en/CSS/Privacy_and_the_%3avisited_selector">built-in
-history protections</ulink>.
-</para>
-</sect3>
-<sect3 id="livemarks">
-<title><ulink
-url="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/c…">@mozilla.org/browser/livemark-service;2</ulink>
-- <ulink
- url="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…">components/block-livemarks.js</ulink></title>
-<para>
-
-The <ulink
-url="http://www.mozilla.com/en-US/firefox/livebookmarks.html">livemark</ulink> service
-is started by a timer that runs 5 seconds after Firefox
-startup. As a result, we cannot simply call the stopUpdateLivemarks() method to
-disable it. We must wrap the component to prevent this start() call from
-firing in the event the browser starts in Tor mode.
-
-</para>
-<para>
-This component helps satisfy the <link linkend="isolation">Network
-Isolation</link> and <link linkend="setpreservation">Anonymity Set
-Preservation</link> requirements.
-</para>
-</sect3>
-</sect2>
-<sect2>
-<title>New Components</title>
-
-<para>Torbutton creates four new components that are used throughout the
-extension. These components do not hook any interfaces, nor are they used
-anywhere besides Torbutton itself.</para>
-
-<sect3 id="cookiejar">
-<title><ulink
-url="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…">@torproject.org/cookie-jar-selector;2
-- components/cookie-jar-selector.js</ulink></title>
-
-<para>The cookie jar selector (also based on code from <ulink
-url="http://www.collinjackson.com/">Collin
-Jackson</ulink>) is used by the Torbutton chrome to switch between
-Tor and Non-Tor cookies. It stores an XML representation of the current
-cookie state in memory and/or on disk. When Tor is toggled, it syncs the
-current cookies to this XML store, and then loads the cookies for the other
-state from the XML store.
-</para>
-
-<para>
-This component helps to address the <link linkend="state">State
-Isolation</link> requirement of Torbutton.
-</para>
-
-</sect3>
-<sect3>
-<title><ulink
-url="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…">@torproject.org/torbutton-logger;1
-- components/torbutton-logger.js</ulink></title>
-
-<para>The torbutton logger component allows on-the-fly redirection of torbutton
-logging messages to either Firefox stderr
-(<command>extensions.torbutton.logmethod=0</command>), the Javascript error console
-(<command>extensions.torbutton.logmethod=1</command>), or the DebugLogger extension (if
-available - <command>extensions.torbutton.logmethod=2</command>). It also allows you to
-change the loglevel on the fly by changing
-<command>extensions.torbutton.loglevel</command> (1-5, 1 is most verbose).
-</para>
-</sect3>
-<sect3 id="windowmapper">
-
-<title><ulink
-url="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…">@torproject.org/content-window-mapper;1
-- components/window-mapper.js</ulink></title>
-
-<para>Torbutton tags Firefox <ulink
-url="https://developer.mozilla.org/en/XUL_Tutorial/Tabboxes">tabs</ulink> with a special variable that indicates the Tor
-state the tab was most recently used under to fetch a page. The problem is
-that for many Firefox events, it is not possible to determine the tab that is
-actually receiving the event. The Torbutton window mapper allows the Torbutton
-chrome and other components to look up a <ulink
-url="https://developer.mozilla.org/en/XUL/tabbrowser">browser
-tab</ulink> for a given <ulink
-url="https://developer.mozilla.org/en/nsIDOMWindow">HTML content
-window</ulink>. It does this by traversing all windows and all browsers, until it
-finds the browser with the requested <ulink
-url="https://developer.mozilla.org/en/XUL/tabbrowser#p-contentWindow">contentWindow</ulink> element. Since the content policy
-and page loading in general can generate hundreds of these lookups, this
-result is cached inside the component.
-</para>
-</sect3>
-<sect3 id="crashobserver">
- <title><ulink
-url="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…">@torproject.org/crash-observer;1</ulink></title>
- <para>
-
-This component detects when Firefox crashes by altering Firefox prefs during
-runtime and checking for the same values at startup. It <ulink
-url="https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIPrefService#s…">synchronizes
-the preference service</ulink> to ensure the altered prefs are written to disk
-immediately.
-
- </para>
-</sect3>
-<sect3 id="tbsessionstore">
- <title><ulink
-url="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…">@torproject.org/torbutton-ss-blocker;1</ulink></title>
- <para>
-
-This component subscribes to the Firefox <ulink
-url="https://developer.mozilla.org/en/Observer_Notifications#Session_Store">sessionstore-state-write</ulink>
-observer event to filter out URLs from tabs loaded during Tor, to prevent them
-from being written to disk. To do this, it checks the
-<command>__tb_tor_fetched</command> tag of tab objects before writing them out. If
-the tag is from a blocked Tor state, the tab is not written to disk. This is
-a rather expensive operation that involves potentially very large JSON
-evaluations and object tree traversals, but it preferable to replacing the
-Firefox session store with our own implementation, which is what was done in
-years past.
-
- </para>
-</sect3>
-
-<sect3 id="refspoofer">
- <title><ulink
-url="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…">@torproject.org/torRefSpoofer;1</ulink></title>
- <para>
-This component handles optional referer spoofing for Torbutton. It implements a
-form of "smart" referer spoofing using <ulink
-url="https://developer.mozilla.org/en/Setting_HTTP_request_headers">http-on-modify-request</ulink>
-to modify the Referer header. The code sends the default browser referer
-header only if the destination domain is a suffix of the source, or if the
-source is a suffix of the destination. Otherwise, it sends no referer. This
-strange suffix logic is used as a heuristic: some rare sites on the web block
-requests without proper referer headers, and this logic is an attempt to cater
-to them. Unfortunately, it may not be enough. For example, google.fr will not
-send a referer to google.com using this logic. Hence, it is off by default.
- </para>
-</sect3>
-
-<!-- FIXME: tor-protocol, tors-protocol need documenting, but
-they are disabled by default for now, so no reason to add the
-clutter+confusion. -->
-
-<sect3 id="contentpolicy">
-<title><ulink
-url="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…">@torproject.org/cssblocker;1
-- components/cssblocker.js</ulink></title>
-
-<para>This is a key component to Torbutton's security measures. When Tor is
-toggled, Javascript is disabled, and pages are instructed to stop loading.
-However, CSS is still able to perform network operations by loading styles for
-onmouseover events and other operations. In addition, favicons can still be
-loaded by the browser. The cssblocker component prevents this by implementing
-and registering an <ulink
-url="https://developer.mozilla.org/en/nsIContentPolicy">nsIContentPolicy</ulink>.
-When an nsIContentPolicy is registered, Firefox checks every attempted network
-request against its <ulink
-url="https://developer.mozilla.org/en/nsIContentPolicy#shouldLoad()">shouldLoad</ulink>
-member function to determine if the load should proceed. In Torbutton's case,
-the content policy looks up the appropriate browser tab using the <link
-linkend="windowmapper">window mapper</link>,
-and checks that tab's load tag against the current Tor state. If the tab was
-loaded in a different state than the current state, the fetch is denied.
-Otherwise, it is allowed.</para> This helps to achieve the <link
-linkend="isolation">Network
-Isolation</link> requirements of Torbutton.
-
-<para>In addition, the content policy also blocks website javascript from
-<ulink
-url="http://webdevwonders.com/detecting-firefox-add-ons/">querying for
-versions and existence of extension chrome</ulink> while Tor is enabled, and
-also masks the presence of Torbutton to website javascript while Tor is
-disabled. </para>
-
-<para>
-
-Finally, some of the work that logically belongs to the content policy is
-instead handled by the <command>torbutton_http_observer</command> and
-<command>torbutton_weblistener</command> in <ulink
-url="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/chrome/con…">torbutton.js</ulink>. These two objects handle blocking of
-Firefox 3 favicon loads, popups, and full page plugins, which for whatever
-reason are not passed to the Firefox content policy itself (see Firefox Bugs
-<ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=437014">437014</ulink> and
-<ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=401296">401296</ulink>).
-
-</para>
-
-<!--
-FIXME: Hrmm, the content policy doesn't really lend itself well to display
-this way.. People looking for this much detail should consult the source.
-
-<para>
- <table rowheader="firstcol" frame='all'><title>Access Permissions Table</title>
- <tgroup cols='5' align='left' colsep='1' rowsep='1'>
- <tbody>
- <row>
- <entry></entry>
- <entry>chrome/resource</entry>
- <entry>a3</entry>
- <entry>a4</entry>
- <entry>a5</entry>
- </row>
- <row>
- <entry>file</entry>
- <entry>b2</entry>
- <entry>b3</entry>
- <entry>b4</entry>
- <entry>b5</entry>
- </row>
- <row>
- <entry>c1</entry>
- <entry>c2</entry>
- <entry>c3</entry>
- <entry>c4</entry>
- <entry>c5</entry>
- </row>
- <row>
- <entry>d1</entry>
- <entry>d2</entry>
- <entry>d3</entry>
- <entry>d4</entry>
- <entry>d5</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-</para>
--->
-
-<para>
-
-This helps to fulfill both the <link
-linkend="setpreservation">Anonymity Set Preservation</link> and the <link
-linkend="undiscoverability">Tor Undiscoverability</link> requirements of
-Torbutton.</para>
-
-</sect3>
-</sect2>
-</sect1>
-<sect1>
- <title>Chrome</title>
-
-<para>The chrome is where all the torbutton graphical elements and windows are
-located. </para>
-<sect2>
- <title>XUL Windows and Overlays</title>
-<para>
-Each window is described as an <ulink
-url="http://developer.mozilla.org/en/docs/XUL_Reference">XML file</ulink>, with zero or more Javascript
-files attached. The scope of these Javascript files is their containing
-window. XUL files that add new elements and script to existing Firefox windows
-are called overlays.</para>
-
-<sect3 id="browseroverlay">
-<title>Browser Overlay - <ulink
-url="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/chrome/con…">torbutton.xul</ulink></title>
-
-<para>The browser overlay, torbutton.xul, defines the toolbar button, the status
-bar, and events for toggling the button. The overlay code is in <ulink
-url="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/chrome/con…">chrome/content/torbutton.js</ulink>.
-It contains event handlers for preference update, shutdown, upgrade, and
-location change events.</para>
-
-</sect3>
-<sect3>
- <title>Preferences Window - <ulink
-url="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/chrome/con…">preferences.xul</ulink></title>
-
-<para>The preferences window of course lays out the Torbutton preferences, with
-handlers located in <ulink
-url="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/chrome/con…">chrome/content/preferences.js</ulink>.</para>
-</sect3>
-<sect3>
- <title>Other Windows</title>
-
-<para>There are additional windows that describe popups for right clicking on
-the status bar, the toolbutton, and the about page.</para>
-
-</sect3>
-</sect2>
-<sect2>
- <title>Major Chrome Observers</title>
- <para>
-In addition to the <link linkend="components">components described
-above</link>, Torbutton also instantiates several observers in the browser
-overlay window. These mostly grew due to scoping convenience, and many should
-probably be relocated into their own components.
- </para>
- <orderedlist>
- <listitem><command>torbutton_window_pref_observer</command>
- <para>
-This is an observer that listens for Torbutton state changes, for the purposes
-of updating the Torbutton button graphic as the Tor state changes.
- </para>
- </listitem>
-
- <listitem><command>torbutton_unique_pref_observer</command>
- <para>
-
-This is an observer that only runs in one window, called the main window. It
-listens for changes to all of the Torbutton preferences, as well as Torbutton
-controlled Firefox preferences. It is what carries out the toggle path when
-the proxy settings change. When the main window is closed, the
-torbutton_close_window event handler runs to dub a new window the "main
-window".
-
- </para>
- </listitem>
-
- <listitem><command>tbHistoryListener</command>
- <para>
-The tbHistoryListener exists to prevent client window Javascript from
-interacting with window.history to forcibly navigate a user to a tab session
-history entry from a different Tor state. It also expunges the window.history
-entries during toggle. This listener helps Torbutton
-satisfy the <link linkend="isolation">Network Isolation</link> requirement as
-well as the <link linkend="state">State Separation</link> requirement.
-
- </para>
- </listitem>
-
- <listitem><command>torbutton_http_observer</command>
- <para>
-
-The torbutton_http_observer performs some of the work that logically belongs
-to the content policy. This handles blocking of
-Firefox 3 favicon loads, which for whatever
-reason are not passed to the Firefox content policy itself (see Firefox Bugs
-<ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=437014">437014</ulink> and
-<ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=401296">401296</ulink>).
-
- </para>
- <para>
-The observer is also responsible for redirecting users to alternate
-search engines when Google presents them with a Captcha, as well as copying
-Google Captcha-related cookies between international Google domains.
- </para>
- </listitem>
-
- <listitem><command>torbutton_proxyservice</command>
- <para>
-The Torbutton proxy service handles redirecting Torbutton-related update
-checks on addons.mozilla.org through Tor. This is done to help satisfy the
-<link linkend="undiscoverability">Tor Undiscoverability</link> requirement.
- </para>
- </listitem>
-
- <listitem><command>torbutton_weblistener</command>
-<para>The <ulink
-url="https://developer.mozilla.org/en/nsIWebProgressListener#onLocationChange">location
-change</ulink> <ulink
-url="https://developer.mozilla.org/en/nsIWebProgress">webprogress
-listener</ulink>, <command>torbutton_weblistener</command> is one of the most
-important parts of the chrome from a security standpoint. It is a <ulink
-url="https://developer.mozilla.org/en/nsIWebProgressListener">webprogress
-listener</ulink> that handles receiving an event every time a page load or
-iframe load occurs. This class eventually calls down to
-<function>torbutton_update_tags()</function> and
-<function>torbutton_hookdoc()</function>, which apply the browser Tor load
-state tags, plugin permissions, and install the Javascript hooks to hook the
-<ulink
-url="https://developer.mozilla.org/en/DOM/window.screen">window.screen</ulink>
-object to obfuscate browser and desktop resolution information.
-
-</para>
- </listitem>
-
- </orderedlist>
- </sect2>
-</sect1>
-
-<sect1>
- <title>Toggle Code Path</title>
- <para>
-
-The act of toggling is connected to <function>torbutton_toggle()</function>
-via the <ulink
-url="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/chrome/con…">torbutton.xul</ulink>
-and <ulink
-url="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/chrome/con…">popup.xul</ulink>
-overlay files. Most of the work in the toggling process is present in <ulink
-url="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/chrome/con…">torbutton.js</ulink>
-
-</para>
-<para>
-
-Toggling is a 3 stage process: Button Click, Proxy Update, and
-Settings Update. These stages are reflected in the prefs
-<command>extensions.torbutton.tor_enabled</command>,
-<command>extensions.torbutton.proxies_applied</command>, and
-<command>extensions.torbutton.settings_applied</command>. The reason for the
-three stage preference update is to ensure immediate enforcement of <link
-linkend="isolation">Network Isolation</link> via the <link
-linkend="contentpolicy">content policy</link>. Since the content window
-javascript runs on a different thread than the chrome javascript, it is
-important to properly convey the stages to the content policy to avoid race
-conditions and leakage, especially with <ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=409737">Firefox Bug
-409737</ulink> unfixed. The content policy does not allow any network activity
-whatsoever during this three stage transition.
-
- </para>
- <sect2>
- <title>Button Click</title>
- <para>
-
-This is the first step in the toggling process. When the user clicks the
-toggle button or the toolbar, <function>torbutton_toggle()</function> is
-called. This function checks the current Tor status by comparing the current
-proxy settings to the selected Tor settings, and then sets the proxy settings
-to the opposite state, and sets the pref
-<command>extensions.torbutton.tor_enabled</command> to reflect the new state.
-It is this proxy pref update that gives notification via the <ulink
-url="https://developer.mozilla.org/en/NsIPrefBranch2#addObserver.28.29">pref
-observer</ulink>
-<command>torbutton_unique_pref_observer</command> to perform the rest of the
-toggle.
-
- </para>
- </sect2>
- <sect2>
- <title>Proxy Update</title>
- <para>
-
-When Torbutton receives any proxy change notifications via its
-<command>torbutton_unique_pref_observer</command>, it calls
-<function>torbutton_set_status()</function> which checks against the Tor
-settings to see if the Tor proxy settings match the current settings. If so,
-it calls <function>torbutton_update_status()</function>, which determines if
-the Tor state has actually changed, and sets
-<command>extensions.torbutton.proxies_applied</command> to the appropriate Tor
-state value, and ensures that
-<command>extensions.torbutton.tor_enabled</command> is also set to the correct
-value. This is decoupled from the button click functionality via the pref
-observer so that other addons (such as SwitchProxy) can switch the proxy
-settings between multiple proxies.
-
- </para>
- </sect2>
-<!-- FIXME: Describe tab tagging and other state clearing hacks? -->
- <sect2>
- <title>Settings Update</title>
- <para>
-
-The next stage is also handled by
-<function>torbutton_update_status()</function>. This function sets scores of
-Firefox preferences, saving the original values to prefs under
-<command>extensions.torbutton.saved.*</command>, and performs the <link
-linkend="cookiejar">cookie jarring</link>, state clearing (such as window.name
-and DOM storage), and <link linkend="preferences">preference
-toggling</link><!--, and ssl certificate jaring work of Torbutton-->. At the
-end of its work, it sets
-<command>extensions.torbutton.settings_applied</command>, which signifies the
-completion of the toggle operation to the <link
-linkend="contentpolicy">content policy</link>.
-
- </para>
- </sect2>
-<sect2 id="preferences">
-<title>Firefox preferences touched during Toggle</title>
-<para>
-There are also a number of Firefox preferences set in
-<function>torbutton_update_status()</function> that aren't governed by any
-Torbutton setting. These are:
-</para>
-<orderedlist>
-
-<!--
-Not set any more.
- <listitem><ulink
-url="http://kb.mozillazine.org/Browser.bookmarks.livemark_refresh_seconds">browser.bookmarks.livemark_refresh_seconds</ulink>
-<para>
-This pref is set in an attempt to disable the fetching of LiveBookmarks via
-Tor. Since users can potentially collect a large amount of live bookmarks to
-very personal sites (blogs of friends, wikipedia articles they maintain,
-comment feeds of their own blog), it is not possible to cleanly isolate these
-fetches and they are simply disabled during Tor usage.
-This helps to address the <link
-linkend="state">State Separation</link> requirement.
-Unfortunately <ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=436250">Firefox Bug
-436250</ulink> prevents this from
-functioning completely correctly.
-</para>
- </listitem>
--->
-
- <listitem><ulink
-url="http://kb.mozillazine.org/Network.security.ports.banned">network.security.ports.banned</ulink>
- <para>
-Torbutton sets this setting to add ports 8123, 8118, 9050 and 9051 (which it
-reads from <command>extensions.torbutton.banned_ports</command>) to the list
-of ports Firefox is forbidden to access. These ports are Polipo, Privoxy, Tor,
-and the Tor control port, respectively. This is set for both Tor and Non-Tor
-usage, and prevents websites from attempting to do http fetches from these
-ports to see if they are open, which addresses the <link
-linkend="undiscoverability">Tor Undiscoverability</link> requirement.
- </para>
- </listitem>
- <listitem><ulink url="http://kb.mozillazine.org/Browser.send_pings">browser.send_pings</ulink>
- <para>
-This setting is currently always disabled. If anyone ever complains saying
-that they *want* their browser to be able to send ping notifications to a
-page or arbitrary link, I'll make this a pref or Tor-only. But I'm not holding
-my breath. I haven't checked if the content policy is called for pings, but if
-not, this setting helps with meeting the <link linkend="isolation">Network
-Isolation</link> requirement.
- </para>
- </listitem>
- <listitem><ulink
-url="http://kb.mozillazine.org/Browser.safebrowsing.remoteLookups">browser.safebrowsing.remoteLookups</ulink>
- <para>
-Likewise for this setting. I find it hard to imagine anyone who wants to ask
-Google in real time if each URL they visit is safe, especially when the list
-of unsafe URLs is downloaded anyway. This helps fulfill the <link
-linkend="disk">Disk Avoidance</link> requirement, by preventing your entire
-browsing history from ending up on Google's disks.
- </para>
- </listitem>
- <listitem><ulink
-url="http://kb.mozillazine.org/Browser.safebrowsing.enabled">browser.safebrowsing.enabled</ulink>
- <para>
-Safebrowsing does <ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=360387">unauthenticated
-updates under Firefox 2</ulink>, so it is disabled during Tor usage.
-This helps fulfill the <link linkend="updates">Update
-Safety</link> requirement. Firefox 3 has the fix for that bug, and so
-safebrowsing updates are enabled during Tor usage.
- </para>
- </listitem>
- <listitem><ulink
-url="http://kb.mozillazine.org/Network.protocol-handler.warn-external.%28protoco…">network.protocol-handler.warn-external.(protocol)</ulink>
- <para>
-If Tor is enabled, we need to prevent random external applications from
-launching without at least warning the user. This group of settings only
-partially accomplishes this, however. Applications can still be launched via
-plugins. The mechanisms for handling this are described under the "Disable
-Plugins During Tor Usage" preference. This helps fulfill the <link
-linkend="proxy">Proxy Obedience</link> requirement, by preventing external
-applications from accessing network resources at the command of Tor-fetched
-pages. Unfortunately, due to <link linkend="FirefoxBugs">Firefox Bug</link>
-<ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=440892">440892</ulink>,
-these prefs are no longer obeyed. They are set still anyway out of respect for
-the dead.
- </para>
-</listitem>
- <listitem><ulink
-url="http://kb.mozillazine.org/Browser.sessionstore.max_tabs_undo">browser.sessionstore.max_tabs_undo</ulink>
- <para>
-
-To help satisfy the Torbutton <link linkend="state">State Separation</link>
-and <link linkend="isolation">Network Isolation</link> requirements,
-Torbutton needs to purge the Undo Tab history on toggle to prevent repeat
-"Undo Close" operations from accidentally restoring tabs from a different Tor
-State. This purge is accomplished by setting this preference to 0 and then
-restoring it to the previous user value upon toggle.
-
- </para>
- </listitem>
-
- <listitem><command>security.enable_ssl2</command> or <ulink
-url="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/i…">nsIDOMCrypto::logout()</ulink>
- <para>
-TLS Session IDs can persist for an indefinite duration, providing an
-identifier that is sent to TLS sites that can be used to link activity. This
-is particularly troublesome now that we have certificate verification in place
-in Firefox 3: The OCSP server can use this Session ID to build a history of
-TLS sites someone visits, and also correlate their activity as users move from
-network to network (such as home to work to coffee shop, etc), inside and
-outside of Tor. To handle this and to help satisfy our <link
-linkend="state">State Separation Requirement</link>, we call the logout()
-function of nsIDOMCrypto. Since this may be absent, or may fail, we fall back
-to toggling
-<command>security.enable_ssl2</command>, which clears the SSL Session ID
-cache via the pref observer at <ulink
-url="http://mxr.mozilla.org/security/source/security/manager/ssl/src/nsNSSCompon…">nsNSSComponent.cpp</ulink>.
- </para>
- </listitem>
- <listitem><command>security.OCSP.enabled</command>
- <para>
-Similarly, we toggle <command>security.OCSP.enabled</command>, which clears the OCSP certificate
-validation cache via the pref observer at <ulink
-url="http://mxr.mozilla.org/security/source/security/manager/ssl/src/nsNSSCompon…">nsNSSComponent.cpp</ulink>.
-In this way, exit nodes will not be able to fingerprint you
-based the fact that non-Tor OCSP lookups were obviously previously cached.
-To handle this and to help satisfy our <link
-linkend="state">State Separation Requirement</link>,
- </para>
- </listitem>
- <listitem><command><ulink
-url="http://kb.mozillazine.org/Updating_extensions#Disabling_update_checks_for_i…">extensions.e0204bd5-9d31-402b-a99d-a6aa8ffebdca.getAddons.cache.enabled</ulink></command>
- <para>
-We permanently disable addon usage statistic reporting to the
-addons.mozilla.org statistics engine. These statistics send version
-information about Torbutton users via non-Tor, allowing their Tor use to be
-uncovered. Disabling this reporting helps Torbutton to satisfy its <link
-linkend="undiscoverability">Tor Undiscoverability</link> requirement.
-
- </para>
- </listitem>
-
- <listitem><command><ulink url="http://www.mozilla.com/en-US/firefox/geolocation/">geo.enabled</ulink></command>
- <para>
-
-Torbutton disables Geolocation support in Firefox 3.5 and above whenever tor
-is enabled. This helps Torbutton maintain its
-<link linkend="location">Location Neutrality</link> requirement.
-While Firefox does prompt before divulging geolocational information,
-the assumption is that Tor users will never want to give their
-location away during Tor usage, and even allowing websites to prompt
-them to do so will only cause confusion and accidents to happen. Moreover,
-just because users may approve a site to know their location in non-Tor mode
-does not mean they want it divulged during Tor mode.
-
- </para>
- </listitem>
-
- <listitem><command><ulink
-url="http://kb.mozillazine.org/Browser.zoom.siteSpecific">browser.zoom.siteSpecific</ulink></command>
- <para>
-
-Firefox actually remembers your zoom settings for certain sites. CSS
-and Javascript rule can use this to recognize previous visitors to a site.
-This helps Torbutton fulfill its <link linkend="state">State Separation</link>
-requirement.
-
- </para>
- </listitem>
-
- <listitem><command><ulink
-url="https://developer.mozilla.org/en/controlling_dns_prefetching">network.dns.disablePrefetch</ulink></command>
- <para>
-
-Firefox 3.5 and above implement prefetching of DNS resolution for hostnames in
-links on a page to decrease page load latency. While Firefox does typically
-disable this behavior when proxies are enabled, we set this pref for added
-safety during Tor usage. Additionally, to prevent Tor-loaded tabs from having
-their links prefetched after a toggle to Non-Tor mode occurs,
-we also set the docShell attribute
-<ulink
-url="http://www.oxymoronical.com/experiments/apidocs/interface/nsIDocShell">
-allowDNSPrefetch</ulink> to false on Tor loaded tabs. This happens in the same
-positions in the code as those for disabling plugins via the allowPlugins
-docShell attribute. This helps Torbutton fulfill its <link
-linkend="isolation">Network Isolation</link> requirement.
-
- </para>
- </listitem>
-
- <listitem><command><ulink
-url="http://kb.mozillazine.org/Browser.cache.offline.enable">browser.cache.offline.enable</ulink></command>
- <para>
-
-Firefox has the ability to store web applications in a special cache to allow
-them to continue to operate while the user is offline. Since this subsystem
-is actually different than the normal disk cache, it must be dealt with
-separately. Thus, Torbutton sets this preference to false whenever Tor is
-enabled. This helps Torbutton fulfill its <link linkend="disk">Disk
-Avoidance</link> and <link linkend="state">State Separation</link>
-requirements.
-
- </para>
- </listitem>
-
-<!-- FIXME: We should make it possible to search for ALL modified FF prefs -->
-
-</orderedlist>
-</sect2>
-
-</sect1>
-
-<sect1>
- <title>Description of Options</title>
-<para>This section provides a detailed description of Torbutton's options. Each
-option is presented as the string from the preferences window, a summary, the
-preferences it touches, and the effect this has on the components, chrome, and
-browser properties.</para>
-<!-- FIXME: figure out how to give subsections # ids or make this into a
-listitem -->
- <sect2>
- <title>Proxy Settings</title>
- <sect3>
- <title>Test Settings</title>
- <para>
-This button under the Proxy Settings tab provides a way to verify that the
-proxy settings are correct, and actually do route through the Tor network. It
-performs this check by issuing an <ulink
-url="http://developer.mozilla.org/en/docs/XMLHttpRequest">XMLHTTPRequest</ulink>
-for <ulink
-url="https://check.torproject.org/?TorButton=True">https://check.torproject.org/?Torbutton=True</ulink>.
-This is a special page that returns very simple, yet well-formed XHTML that
-Torbutton can easily inspect for a hidden link with an id of
-<command>TorCheckResult</command> and a target of <command>success</command>
-or <command>failure</command> to indicate if the
-user hit the page from a Tor IP, a non-Tor IP. This check is handled in
-<function>torbutton_test_settings()</function> in <ulink
-url="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/chrome/con…">torbutton.js</ulink>.
-Presenting the results to the user is handled by the <ulink
-url="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/chrome/con…">preferences
-window</ulink>
-callback <function>torbutton_prefs_test_settings()</function> in <ulink
-url="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/chrome/con…">preferences.js</ulink>.
-
- </para>
- </sect3>
- </sect2>
- <sect2>
- <title>Dynamic Content Settings</title>
- <sect3 id="plugins">
- <title>Disable plugins on Tor Usage (crucial)</title>
- <para>Option: <command>extensions.torbutton.no_tor_plugins</command></para>
-
- <para>Java and plugins <ulink
-url="http://java.sun.com/j2se/1.5.0/docs/api/java/net/class-use/NetworkInterface…">can query</ulink> the <ulink
-url="http://www.rgagnon.com/javadetails/java-0095.html">local IP
-address</ulink> and report it back to the
-remote site. They can also <ulink
-url="http://decloak.net">bypass proxy settings</ulink> and directly connect to a
-remote site without Tor. Every browser plugin we have tested with Firefox has
-some form of network capability, and every one ignores proxy settings or worse - only
-partially obeys them. This includes but is not limited to:
-QuickTime, Windows Media Player, RealPlayer, mplayerplug-in, AcroRead, and
-Flash.
-
- </para>
- <para>
-Enabling this preference causes the above mentioned Torbutton chrome web progress
- listener <command>torbutton_weblistener</command> to disable Java via <command>security.enable_java</command> and to disable
- plugins via the browser <ulink
- url="https://developer.mozilla.org/en/XUL%3aProperty%3adocShell">docShell</ulink>
- attribute <command>allowPlugins</command>. These flags are set every time a new window is
- created (<function>torbutton_tag_new_browser()</function>), every time a web
-load
-event occurs
- (<function>torbutton_update_tags()</function>), and every time the tor state is changed
- (<function>torbutton_update_status()</function>). As a backup measure, plugins are also
- prevented from loading by the content policy in <ulink
-url="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…">@torproject.org/cssblocker;1</ulink> if Tor is
- enabled and this option is set.
- </para>
-
- <para>All of this turns out to be insufficient if the user directly clicks
-on a plugin-handled mime-type. <ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=401296">In this case</ulink>,
-the browser decides that maybe it should ignore all these other settings and
-load the plugin anyways, because maybe the user really did want to load it
-(never mind this same load-style could happen automatically with meta-refresh
-or any number of other ways..). To handle these cases, Torbutton stores a list
-of plugin-handled mime-types, and sets the pref
-<command>plugin.disable_full_page_plugin_for_types</command> to this list.
-Additionally, (since nothing can be assumed when relying on Firefox
-preferences and internals) if it detects a load of one of them from the web
-progress listener, it cancels the request, tells the associated DOMWindow to
-stop loading, clears the document, AND throws an exception. Anything short of
-all this and the plugin managed to find some way to load.
- </para>
-
-<!--
-
-FIXME: Hrmm, technically this behavior is not covered by this pref.
-
- <para>
-Furthermore, with version 3.0 and above, Firefox
-<ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=440892">began ignoring</ulink>
-
-<ulink
-url="http://kb.mozillazine.org/Network.protocol-handler.warn-external.%28protoco…">network.protocol-handler.warn-external.(protocol)</ulink>
-prefs, which caused us to have to <link linkend="appblocker">wrap the external
-app launcher components</link> to prevent external apps from being loaded to
-bypass proxy settings.
- </para>
--->
-
- <para>
- All this could be avoided, of course, if Firefox would either <ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=401296">obey
- allowPlugins</ulink> for directly visited URLs, or notify its content policy for such
- loads either <ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=309524">via</ulink> <ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=380556">shouldProcess</ulink> or shouldLoad. The fact that it does not is
- not very encouraging.
- </para>
-
-
- <para>
-
-Since most plugins completely ignore browser proxy settings, the actions
-performed by this setting are crucial to satisfying the <link
-linkend="proxy">Proxy Obedience</link> requirement.
-
- </para>
-</sect3>
-<sect3>
- <title>Isolate Dynamic Content to Tor State (crucial)</title>
-
- <para>Option: <command>extensions.torbutton.isolate_content</command></para>
-
-<para>Enabling this preference is what enables the <ulink
-url="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…">@torproject.org/cssblocker;1</ulink> content policy
-mentioned above, and causes it to block content load attempts in pages an
-opposite Tor state from the current state. Freshly loaded <ulink
-url="https://developer.mozilla.org/en/XUL/tabbrowser">browser
-tabs</ulink> are tagged
-with a <command>__tb_load_state</command> member in
-<function>torbutton_update_tags()</function> and this
-value is compared against the current tor state in the content policy.</para>
-
-<para>It also kills all Javascript in each page loaded under that state by
-toggling the <command>allowJavascript</command> <ulink
-url="https://developer.mozilla.org/en/XUL%3aProperty%3adocShell">docShell</ulink> property, and issues a
-<ulink
-url="https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIWebNavigation…">webNavigation.stop(webNavigation.STOP_ALL)</ulink> to each browser tab (the
-equivalent of hitting the STOP button).</para>
-
-<para>
-
-Unfortunately, <ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=409737">Firefox bug
-409737</ulink> prevents <command>docShell.allowJavascript</command> from killing
-all event handlers, and event handlers registered with <ulink
-url="http://developer.mozilla.org/en/docs/DOM:element.addEventListener">addEventListener()</ulink>
-are still able to execute. The <link linkend="contentpolicy">Torbutton Content
-Policy</link> should prevent such code from performing network activity within
-the current tab, but activity that happens via a popup window or via a
-Javascript redirect can still slip by. For this reason, Torbutton blocks
-popups by checking for a valid <ulink
-url="http://developer.mozilla.org/en/docs/DOM:window.opener">window.opener</ulink>
-attribute in <function>torbutton_check_progress()</function>. If the window
-has an opener from a different Tor state, its load is blocked. The content
-policy also takes similar action to prevent Javascript redirects. This also
-has the side effect/feature of preventing the user from following any links
-from a page loaded in an opposite Tor state.
-
-</para>
-
-<para>
-This setting is responsible for satisfying the <link
-linkend="isolation">Network Isolation</link> requirement.
-</para>
-
-</sect3>
-<sect3 id="jshooks">
-
-<title>Hook Dangerous Javascript</title>
-
- <para>Option: <command>extensions.torbutton.kill_bad_js</command></para>
-
-<para>This setting enables injection of the <ulink
-url="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/chrome/con…">Javascript
-hooking code</ulink>. This is done in the chrome in
-<function>torbutton_hookdoc()</function>, which is called ultimately by both the
-<ulink
-url="https://developer.mozilla.org/en/nsIWebProgressListener">webprogress
-listener</ulink> <command>torbutton_weblistener</command> and the <link
-linkend="contentpolicy">content policy</link> (the latter being a hack to handle
-javascript: urls).
-
-In the Firefox 2 days, this option did a lot more than
-it does now. It used to be responsible for timezone and improved useragent
-spoofing, and history object cloaking. However, now it only provides
-obfuscation of the <ulink
-url="https://developer.mozilla.org/en/DOM/window.screen">window.screen</ulink>
-object to mask your browser and desktop resolution.
-The resolution hooks
-effectively make the Firefox browser window appear to websites as if the renderable area
-takes up the entire desktop, has no toolbar or other GUI element space, and
-the desktop itself has no toolbars.
-These hooks drastically reduce the amount of information available to do <link
-linkend="fingerprinting">anonymity set reduction attacks</link> and help to
-meet the <link linkend="setpreservation">Anonymity Set Preservation</link>
-requirements. Unfortunately, Gregory Fleischer discovered it is still possible
-to retrieve the original screen values by using <ulink
-url="http://pseudo-flaw.net/tor/torbutton/unmask-sandbox-xpcnativewrapper.html">XPCNativeWrapper</ulink>
-or <ulink
-url="http://pseudo-flaw.net/tor/torbutton/unmask-components-lookupmethod.html">Components.lookupMethod</ulink>.
-We are still looking for a workaround as of Torbutton 1.3.2.
-
-<!-- FIXME: Don't forget to update this -->
-<!-- XXX: Date() issue now fixed by TZ variable! -->
-
-</para>
-</sect3>
-<sect3>
-<title>Resize windows to multiples of 50px during Tor usage (recommended)</title>
-
- <para>Option: <command>extensions.torbutton.resize_windows</command></para>
-
-<para>
-
-This option drastically cuts down on the number of distinct anonymity sets
-that divide the Tor web userbase. Without this setting, the dimensions for a
-typical browser window range from 600-1200 horizontal pixels and 400-1000
-vertical pixels, or about 600x600 = 360000 different sets. Resizing the
-browser window to multiples of 50 on each side reduces the number of sets by
-50^2, bringing the total number of sets to 144. Of course, the distribution
-among these sets are not uniform, but scaling by 50 will improve the situation
-due to this non-uniformity for users in the less common resolutions.
-Obviously the ideal situation would be to lie entirely about the browser
-window size, but this will likely cause all sorts of rendering issues, and is
-also not implementable in a foolproof way from extension land.
-
-</para>
-<para>
-
-The implementation of this setting is spread across a couple of different
-locations in the Torbutton javascript <link linkend="browseroverlay">browser
-overlay</link>. Since resizing minimized windows causes them to be restored,
-and since maximized windows remember their previous size to the pixel, windows
-must be resized before every document load (at the time of browser tagging)
-via <function>torbutton_check_round()</function>, called by
-<function>torbutton_update_tags()</function>. To prevent drift, the extension
-tracks the original values of the windows and uses this to perform the
-rounding on document load. In addition, to prevent the user from resizing a
-window to a non-50px multiple, a resize listener
-(<function>torbutton_do_resize()</function>) is installed on every new browser
-window to record the new size and round it to a 50px multiple while Tor is
-enabled. In all cases, the browser's contentWindow.innerWidth and innerHeight
-are set. This ensures that there is no discrepancy between the 50 pixel cutoff
-and the actual renderable area of the browser (so that it is not possible to
-infer toolbar size/presence by the distance to the nearest 50 pixel roundoff).
-
-</para>
-<para>
-This setting helps to meet the <link
-linkend="setpreservation">Anonymity Set Preservation</link> requirements.
-</para>
-</sect3>
-<sect3>
-
-<title>Disable Search Suggestions during Tor (recommended)</title>
-
- <para>Option: <command>extensions.torbutton.no_search</command></para>
-
-<para>
-This setting causes Torbutton to disable <ulink
-url="http://kb.mozillazine.org/Browser.search.suggest.enabled"><command>browser.search.suggest.enabled</command></ulink>
-during Tor usage.
-This governs if you get Google search suggestions during Tor
-usage. Your Google cookie is transmitted with google search suggestions, hence
-this is recommended to be disabled.
-
-</para>
-<para>
-While this setting doesn't satisfy any Torbutton requirements, the fact that
-cookies are transmitted for partially typed queries does not seem desirable
-for Tor usage.
-</para>
-</sect3>
-
-
-<sect3>
-<title>Disable Updates During Tor</title>
-
- <para>Option: <command>extensions.torbutton.no_updates</command></para>
-
- <para>This setting causes Torbutton to disable the four <ulink
-url="http://wiki.mozilla.org/Update:Users/Checking_For_Updates#Preference_Contro…">Firefox
-update settings</ulink> during Tor
- usage: <command>extensions.update.enabled</command>,
-<command>app.update.enabled</command>,
- <command>app.update.auto</command>, and
-<command>browser.search.update</command>. These prevent the
- browser from updating extensions, checking for Firefox upgrades, and
- checking for search plugin updates while Tor is enabled.
- </para>
-<para>
-This setting satisfies the <link
-linkend="updates">Update Safety</link> requirement.
-</para>
-</sect3>
-<sect3>
-<title>Redirect Torbutton Updates Via Tor (recommended)</title>
-
- <para>Option: <command>extensions.torbutton.update_torbutton_via_tor</command></para>
-
- <para>This setting causes Torbutton to install an
-
-<ulink
-url="https://developer.mozilla.org/en/nsIProtocolProxyFilter">nsIProtocolProxyFilter</ulink>
-in order to redirect all version update checks and Torbutton update downloads
-via Tor, regardless of if Tor is enabled or not. This was done both to address
-concerns about data retention done by <ulink
-url="https://www.addons.mozilla.org">addons.mozilla.org</ulink>, as well as to
-help censored users meet the <link linkend="undiscoverability">Tor
-Undiscoverability</link> requirement.
-
- </para>
-</sect3>
-
-<sect3>
-<title>Disable livemarks updates during Tor usage (recommended)</title>
- <para>Option:
- <simplelist>
- <member><command>extensions.torbutton.disable_livemarks</command></member>
- </simplelist>
- </para>
-
-<para>
-
-This option causes Torbutton to prevent Firefox from loading <ulink
-url="http://www.mozilla.com/firefox/livebookmarks.html">Livemarks</ulink> during
-Tor usage. Because people often have very personalized Livemarks (such as RSS
-feeds of Wikipedia articles they maintain, etc). This is accomplished both by
-<link linkend="livemarks">wrapping the livemark-service component</link> and
-by calling stopUpdateLivemarks() on the <ulink
-url="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/c…">Livemark
-service</ulink> when Tor is enabled.
-
-</para>
-
-<para>
-This helps satisfy the <link linkend="isolation">Network
-Isolation</link> and <link linkend="setpreservation">Anonymity Set
-Preservation</link> requirements.
-</para>
-
-</sect3>
-<sect3>
-<title>Block Tor/Non-Tor access to network from file:// urls (recommended)</title>
- <para>Options:
- <simplelist>
- <member><command>extensions.torbutton.block_tor_file_net</command></member>
- <member><command>extensions.torbutton.block_nontor_file_net</command></member>
- </simplelist>
- </para>
-
-<para>
-
-These settings prevent file urls from performing network operations during the
-respective Tor states. Firefox 2's implementation of same origin policy allows
-file urls to read and <ulink
-url="http://www.gnucitizen.org/blog/content-disposition-hacking/">submit
-arbitrary files from the local filesystem</ulink> to arbitrary websites. To
-make matters worse, the 'Content-Disposition' header can be injected
-arbitrarily by exit nodes to trick users into running arbitrary html files in
-the local context. These preferences cause the <link
-linkend="contentpolicy">content policy</link> to block access to any network
-resources from File urls during the appropriate Tor state.
-
-</para>
-<para>
-
-This preference helps to ensure Tor's <link linkend="isolation">Network
-Isolation</link> requirement, by preventing file urls from executing network
-operations in opposite Tor states. Also, allowing pages to submit arbitrary
-files to arbitrary sites just generally seems like a bad idea.
-
-</para>
-</sect3>
-
-<sect3>
-
-<title>Close all Tor/Non-Tor tabs and windows on toggle (optional)</title>
-
- <para>Options:
- <simplelist>
- <member><command>extensions.torbutton.close_nontor</command></member>
- <member><command>extensions.torbutton.close_tor</command></member>
- </simplelist>
- </para>
-
-<para>
-
-These settings cause Torbutton to enumerate through all windows and close all
-tabs in each window for the appropriate Tor state. This code can be found in
-<function>torbutton_update_status()</function>. The main reason these settings
-exist is as a backup mechanism in the event of any Javascript or content policy
-leaks due to <ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=409737">Firefox Bug
-409737</ulink>. Torbutton currently tries to block all Javascript network
-activity via the content policy, but until that bug is fixed, there is some
-risk that there are alternate ways to bypass the policy. This option is
-available as an extra assurance of <link linkend="isolation">Network
-Isolation</link> for those who would like to be sure that when Tor is toggled
-all page activity has ceased. It also serves as a potential future workaround
-in the event a content policy failure is discovered, and provides an additional
-level of protection for the <link linkend="disk">Disk Avoidance</link>
-protection so that browser state is not sitting around waiting to be swapped
-out longer than necessary.
-
-</para>
-<para>
-While this setting doesn't satisfy any Torbutton requirements, the fact that
-cookies are transmitted for partially typed queries does not seem desirable
-for Tor usage.
-</para>
-</sect3>
- </sect2>
- <sect2>
- <title>History and Forms Settings</title>
-<sect3>
-<title>Isolate Access to History navigation to Tor state (crucial)</title>
- <para>Option: <command>extensions.torbutton.block_js_history</command></para>
- <para>
-This setting determines if Torbutton installs an <ulink
-url="http://www.oxymoronical.com/experiments/apidocs/interface/nsISHistoryListen…">nsISHistoryListener</ulink>
-attached to the <ulink
-url="http://www.oxymoronical.com/experiments/apidocs/interface/nsISHistory">sessionHistory</ulink> of
-of each browser's <ulink
-url="https://developer.mozilla.org/en/XUL%3aProperty%3awebNavigation">webNavigatator</ulink>.
-The nsIShistoryListener is instantiated with a reference to the containing
-browser window and blocks the back, forward, and reload buttons on the browser
-navigation bar when Tor is in an opposite state than the one to load the
-current tab. In addition, Tor clears the session history during a new document
-load if this setting is enabled.
-
- </para>
- <para>
-
-This is marked as a crucial setting in part
-because Javascript access to the history object is indistinguishable from
-user clicks, and because
-<ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=409737">Firefox Bug
-409737</ulink> allows javascript to execute in opposite Tor states, javascript
-can issue reloads after Tor toggle to reveal your original IP. Even without
-this bug, however, Javascript is still able to access previous pages in your
-session history that may have been loaded under a different Tor state, to
-attempt to correlate your activity.
-
- </para>
- <para>
-
-This setting helps to fulfill Torbutton's <link linkend="state">State
-Separation</link> and (until Bug 409737 is fixed) <link linkend="isolation">Network Isolation</link>
-requirements.
-
- </para>
-</sect3>
-
-
-<sect3>
-<title>History Access Settings</title>
-
- <para>Options:
- <simplelist>
- <member><command>extensions.torbutton.block_thread</command></member>
- <member><command>extensions.torbutton.block_nthread</command></member>
- <member><command>extensions.torbutton.block_thwrite</command></member>
- <member><command>extensions.torbutton.block_nthwrite</command></member>
- </simplelist>
- </para>
-
-<para>On Firefox 3.x, these four settings govern the behavior of the <ulink
-url="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…">components/ignore-history.js</ulink>
-history blocker component mentioned above. By hooking the browser's view of
-the history itself via the <ulink
-url="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/c…">@mozilla.org/browser/global-history;2</ulink>
-and <ulink
-url="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/c…">@mozilla.org/browser/nav-history-service;1</ulink>
-components, this mechanism defeats all document-based <ulink
-url="http://whattheinternetknowsaboutyou.com/">history disclosure
-attacks</ulink>, including <ulink
-url="http://ha.ckers.org/weird/CSS-history.cgi">CSS-only attacks</ulink>.
-
-The component also hooks functions involved in writing history to disk via
-both the <ulink
-url="http://developer.mozilla.org/en/docs/Places_migration_guide#History">Places
-Database</ulink> and the older Firefox 2 mechanisms.
-
-</para>
-
-<para>
-On Firefox 4, Mozilla finally <ulink
-url="https://developer.mozilla.org/en/CSS/Privacy_and_the_%3avisited_selector">addressed
-these issues</ulink>, so we can effectively ignore the "read" pair of the
-above prefs. We then only need to link the write prefs to
-<command>places.history.enabled</command>, which disabled writing to the
-history store while set.
-</para>
-
-<para>
-This setting helps to satisfy the <link
-linkend="state">State Separation</link> and <link
-linkend="disk">Disk Avoidance</link> requirements.
-</para>
-
-</sect3>
-<sect3>
-
-<title>Clear History During Tor Toggle (optional)</title>
-
-<para>Option: <command>extensions.torbutton.clear_history</command></para>
-
-<para>This setting governs if Torbutton calls
-<ulink
-url="https://developer.mozilla.org/en/nsIBrowserHistory#removeAllPages.28.29">nsIBrowserHistory.removeAllPages</ulink>
-and <ulink
-url="http://www.oxymoronical.com/experiments/apidocs/interface/nsISHistory">nsISHistory.PurgeHistory</ulink>
-for each tab on Tor toggle.</para>
-<para>
-This setting is an optional way to help satisfy the <link
-linkend="state">State Separation</link> requirement.
-</para>
-
-</sect3>
-<sect3>
-<title>Block Password+Form saving during Tor/Non-Tor</title>
-
-<para>Options:
- <simplelist>
- <member><command>extensions.torbutton.block_tforms</command></member>
- <member><command>extensions.torbutton.block_ntforms</command></member>
- </simplelist>
- </para>
-
-<para>These settings govern if Torbutton disables
-<command>browser.formfill.enable</command>
-and <command>signon.rememberSignons</command> during Tor and Non-Tor usage.
-Since form fields can be read at any time by Javascript, this setting is a lot
-more important than it seems.
-</para>
-
-<para>
-This setting helps to satisfy the <link
-linkend="state">State Separation</link> and <link
-linkend="disk">Disk Avoidance</link> requirements.
-</para>
-
-</sect3>
- </sect2>
- <sect2>
- <title>Cache Settings</title>
-<sect3>
- <title>Block Tor disk cache and clear all cache on Tor Toggle</title>
-
- <para>Option: <command>extensions.torbutton.clear_cache</command>
- </para>
-
-<para>This option causes Torbutton to call <ulink
-url="https://developer.mozilla.org/en/nsICacheService#evictEntries.28.29">nsICacheService.evictEntries(0)</ulink>
-on Tor toggle to remove all entries from the cache. In addition, this setting
-causes Torbutton to set <ulink
-url="http://kb.mozillazine.org/Browser.cache.disk.enable">browser.cache.disk.enable</ulink> to false.
-</para>
-<para>
-This setting helps to satisfy the <link
-linkend="state">State Separation</link> and <link
-linkend="disk">Disk Avoidance</link> requirements.
-</para>
-
-</sect3>
-<sect3>
- <title>Block disk and memory cache during Tor</title>
-
-<para>Option: <command>extensions.torbutton.block_cache</command></para>
-
-<para>This setting
-causes Torbutton to set <ulink
-url="http://kb.mozillazine.org/Browser.cache.memory.enable">browser.cache.memory.enable</ulink>,
-<ulink
-url="http://kb.mozillazine.org/Browser.cache.disk.enable">browser.cache.disk.enable</ulink> and
-<ulink
-url="http://kb.mozillazine.org/Network.http.use-cache">network.http.use-cache</ulink> to false during tor usage.
-</para>
-<para>
-This setting helps to satisfy the <link
-linkend="state">State Separation</link> and <link
-linkend="disk">Disk Avoidance</link> requirements.
-</para>
-
-</sect3>
- </sect2>
- <sect2>
- <title>Cookie and Auth Settings</title>
-<sect3>
- <title>Clear Cookies on Tor Toggle</title>
-
-<para>Option: <command>extensions.torbutton.clear_cookies</command>
- </para>
-
-<para>
-
-This setting causes Torbutton to call <ulink
-url="https://developer.mozilla.org/en/nsICookieManager#removeAll.28.29">nsICookieManager.removeAll()</ulink> on
-every Tor toggle. In addition, this sets <ulink
-url="http://kb.mozillazine.org/Network.cookie.lifetimePolicy">network.cookie.lifetimePolicy</ulink>
-to 2 for Tor usage, which causes all cookies to be demoted to session cookies,
-which prevents them from being written to disk.
-
-</para>
-<para>
-This setting helps to satisfy the <link
-linkend="state">State Separation</link> and <link
-linkend="disk">Disk Avoidance</link> requirements.
-</para>
-
-</sect3>
-<sect3>
-
- <title>Store Non-Tor cookies in a protected jar</title>
-
-<para>Option: <command>extensions.torbutton.cookie_jars</command>
- </para>
-
-<para>
-
-This setting causes Torbutton to use <ulink
-url="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…">@torproject.org/cookie-jar-selector;2</ulink> to store
-non-tor cookies in a cookie jar during Tor usage, and clear the Tor cookies
-before restoring the jar.
-</para>
-<para>
-This setting also sets <ulink
-url="http://kb.mozillazine.org/Network.cookie.lifetimePolicy">network.cookie.lifetimePolicy</ulink>
-to 2 for Tor usage, which causes all cookies to be demoted to session cookies,
-which prevents them from being written to disk.
-
-</para>
-
-<para>
-This setting helps to satisfy the <link
-linkend="state">State Separation</link> and <link
-linkend="disk">Disk Avoidance</link> requirements.
-</para>
-
-
-</sect3>
-<sect3>
-
- <title>Store both Non-Tor and Tor cookies in a protected jar (dangerous)</title>
-
-<para>Option: <command>extensions.torbutton.dual_cookie_jars</command>
- </para>
-
-<para>
-
-This setting causes Torbutton to use <ulink
-url="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…">@torproject.org/cookie-jar-selector;2</ulink> to store
-both Tor and Non-Tor cookies into protected jars.
-</para>
-
-<para>
-This setting helps to satisfy the <link
-linkend="state">State Separation</link> requirement.
-</para>
-
-
-</sect3>
-
-<!-- FIXME: If we decide to keep it, document the cookie protections dialog
--->
-
-<sect3>
-
- <title>Manage My Own Cookies (dangerous)</title>
-
-<para>Options: None</para>
-<para>This setting disables all Torbutton cookie handling by setting the above
-cookie prefs all to false.</para>
-</sect3>
-<sect3>
-
-<sect3>
- <title>Do not write Tor/Non-Tor cookies to disk</title>
- <para>Options:
- <simplelist>
- <member><command>extensions.torbutton.tor_memory_jar</command></member>
- <member><command>extensions.torbutton.nontor_memory_jar</command></member>
- </simplelist>
- </para>
-
-<para>
-These settings (contributed by arno) cause Torbutton to set <ulink
-url="http://kb.mozillazine.org/Network.cookie.lifetimePolicy">network.cookie.lifetimePolicy</ulink>
-to 2 during the appropriate Tor state, and to store cookies acquired in that
-state into a Javascript
-<ulink
-url="http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Guide:Processing_X…">E4X</ulink>
-object as opposed to writing them to disk.
-</para>
-
-<para>
-This allows Torbutton to provide an option to preserve a user's
-cookies while still satisfying the <link linkend="disk">Disk Avoidance</link>
-requirement.
-</para>
-</sect3>
-
-
- <title>Disable DOM Storage during Tor usage (crucial)</title>
-
-<para>Option: <command>extensions.torbutton.disable_domstorage</command>
- </para>
-
-<para>
-
-This setting causes Torbutton to toggle <command>dom.storage.enabled</command> during Tor
-usage to prevent
-<ulink
- url="http://developer.mozilla.org/en/docs/DOM:Storage">DOM Storage</ulink> from
- being used to store persistent information across Tor states.</para>
-<para>
-This setting helps to satisfy the <link
-linkend="state">State Separation</link> requirement.
-</para>
-
-</sect3>
-
-<sect3>
- <title>Clear HTTP Auth on Tor Toggle (recommended)</title>
-<para>Option: <command>extensions.torbutton.clear_http_auth</command>
- </para>
-
-<para>
-This setting causes Torbutton to call <ulink
-url="http://www.oxymoronical.com/experiments/apidocs/interface/nsIHttpAuthManager">nsIHttpAuthManager.clearAll()</ulink>
-every time Tor is toggled.
-</para>
-
-<para>
-This setting helps to satisfy the <link
-linkend="state">State Separation</link> requirement.
-</para>
-</sect3>
- </sect2>
- <sect2>
- <title>Startup Settings</title>
-<sect3>
- <title>On Browser Startup, set Tor state to: Tor, Non-Tor</title>
- <para>Options:
- <command>extensions.torbutton.restore_tor</command>
- </para>
-
- <para>This option governs what Tor state tor is loaded in to.
-<function>torbutton_set_initial_state()</function> covers the case where the
-browser did not crash, and <function>torbutton_crash_recover()</function>
-covers the case where the <link linkend="crashobserver">crash observer</link>
-detected a crash.
-</para>
-<para>
-
-Since the Tor state after a Firefox crash is unknown/indeterminate, this
-setting helps to satisfy the <link linkend="state">State Separation</link>
-requirement in the event of Firefox crashes by ensuring all cookies,
-settings and saved sessions are reloaded from a fixed Tor state.
-
-</para>
-</sect3>
-
-
-<sect3>
- <title>Prevent session store from saving Non-Tor/Tor-loaded tabs</title>
-
- <para>Options:
- <simplelist>
- <member><command>extensions.torbutton.nonontor_sessionstore</command></member>
- <member><command>extensions.torbutton.notor_sessionstore</command></member>
- </simplelist>
- </para>
-
- <para>If these options are enabled, the <link
-linkend="tbsessionstore">tbSessionStore.js</link> component uses the session
-store listeners to filter out the appropriate tabs before writing the session
-store data to disk.
-</para>
-<para>
-This setting helps to satisfy the <link linkend="disk">Disk Avoidance</link>
-requirement, and also helps to satisfy the <link
-linkend="state">State Separation</link> requirement in the event of Firefox
-crashes.
-
-</para>
-
-</sect3>
- </sect2>
- <sect2>
- <title>Shutdown Settings</title>
-<sect3>
-
- <title>Clear cookies on Tor/Non-Tor shutdown</title>
-
-<para>Option: <command>extensions.torbutton.shutdown_method</command>
- </para>
-
-<para> This option variable can actually take 3 values: 0, 1, and 2. 0 means no
-cookie clearing, 1 means clear only during Tor-enabled shutdown, and 2 means
-clear for both Tor and Non-Tor shutdown. When set to 1 or 2, Torbutton listens
-for the <ulink
-url="http://developer.mozilla.org/en/docs/Observer_Notifications#Application_shu…">quit-application-granted</ulink> event in
-<link linkend="crashobserver">crash-observer.js</link> and use <ulink
-url="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…">@torproject.org/cookie-jar-selector;2</ulink>
-to clear out all cookies and all cookie jars upon shutdown.
-</para>
-<para>
-This setting helps to satisfy the <link
-linkend="state">State Separation</link> requirement.
-</para>
-
-
-</sect3>
- </sect2>
- <sect2>
- <title>Header Settings</title>
-<sect3>
-
- <title>Set user agent during Tor usage (crucial)</title>
- <para>Options:
- <simplelist>
- <member><command>extensions.torbutton.set_uagent</command></member>
- <member><command>extensions.torbutton.platform_override</command></member>
- <member><command>extensions.torbutton.oscpu_override</command></member>
- <member><command>extensions.torbutton.buildID_override</command></member>
- <member><command>extensions.torbutton.productsub_override</command></member>
- <member><command>extensions.torbutton.appname_override</command></member>
- <member><command>extensions.torbutton.appversion_override</command></member>
- <member><command>extensions.torbutton.useragent_override</command></member>
- <member><command>extensions.torbutton.useragent_vendor</command></member>
- <member><command>extensions.torbutton.useragent_vendorSub</command></member>
- </simplelist>
- </para>
-
-<para>On face, user agent switching appears to be straight-forward in Firefox.
-It provides several options for controlling the browser user agent string:
-<command>general.appname.override</command>,
-<command>general.appversion.override</command>,
-<command>general.platform.override</command>,
-<command>general.oscpu.override</command>,
-<command>general.productSub.override</command>,
-<command>general.buildID.override</command>,
-<command>general.useragent.override</command>,
-<command>general.useragent.vendor</command>, and
-<command>general.useragent.vendorSub</command>. If
-the Torbutton preference <command>extensions.torbutton.set_uagent</command> is
-true, Torbutton copies all of the other above prefs into their corresponding
-browser preferences during Tor usage.</para>
-
-
-<para>
-
-It also turns out that it is possible to detect the original Firefox version
-by <ulink url="http://ha.ckers.org/blog/20070516/read-firefox-settings-poc/">inspecting
-certain resource:// files</ulink>. These cases are handled by Torbutton's
-<link linkend="contentpolicy">content policy</link>.
-
-</para>
-
-<para>
-This setting helps to satisfy the <link
-linkend="setpreservation">Anonymity Set Preservation</link> requirement.
-</para>
-
-
-</sect3>
-<sect3>
-
- <title>Spoof US English Browser</title>
-<para>Options:
-<simplelist>
- <member><command>extensions.torbutton.spoof_english</command></member>
- <member><command>extensions.torbutton.spoof_charset</command></member>
- <member><command>extensions.torbutton.spoof_language</command></member>
-</simplelist>
-</para>
-
-<para> This option causes Torbutton to set
-<command>general.useragent.locale</command>
-<command>intl.accept_languages</command> to the value specified in
-<command>extensions.torbutton.spoof_locale</command>,
-<command>extensions.torbutton.spoof_charset</command> and
-<command>extensions.torbutton.spoof_language</command> during Tor usage, as
-well as hooking <command>navigator.language</command> via its <link
-linkend="jshooks">javascript hooks</link>.
- </para>
-<para>
-This setting helps to satisfy the <link
-linkend="setpreservation">Anonymity Set Preservation</link> and <link
-linkend="location">Location Neutrality</link> requirements.
-</para>
-
-</sect3>
-
-<sect3>
- <title>Referer Spoofing Options</title>
-
-<para>Option: <command>extensions.torbutton.refererspoof</command>
-</para>
-
-<para>
-This option variable has three values. If it is 0, "smart" referer spoofing is
-enabled. If it is 1, the referer behaves as normal. If it is 2, no referer is
-sent. The default value is 1. The smart referer spoofing is implemented by the
-<link linkend="refspoofer">torRefSpoofer</link> component.
-
-</para>
-<para>
-This setting also does not directly satisfy any Torbutton requirement, but
-some may desire to mask their referer for general privacy concerns.
-</para>
-</sect3>
-
-<sect3>
- <title>Automatically use an alternate search engine when presented with a
-Google Captcha</title>
-
-<para>Options:
-<simplelist>
- <member><command>extensions.torbutton.asked_google_captcha</command></member>
- <member><command>extensions.torbutton.dodge_google_captcha</command></member>
- <member><command>extensions.torbutton.google_redir_url</command></member>
-</simplelist>
-</para>
-
-<para>
-
-Google's search engine has rate limiting features that cause it to
-<ulink
-url="http://googleonlinesecurity.blogspot.com/2007/07/reason-behind-were-sorry-m…">present
-captchas</ulink> and sometimes even outright ban IPs that issue large numbers
-of search queries, especially if a lot of these queries appear to be searching
-for software vulnerabilities or unprotected comment areas.
-
-</para>
-<para>
-
-Despite multiple discussions with Google, we were unable to come to a solution
-or any form of compromise that would reduce the number of captchas and
-outright bans seen by Tor users issuing regular queries.
-
-</para>
-<para>
-As a result, we've implemented this option as an <ulink
-url="https://developer.mozilla.org/en/XUL_School/Intercepting_Page_Loads#HTTP_Ob…">'http-on-modify-request'</ulink>
-http observer to optionally redirect banned or captcha-triggering Google
-queries to search engines that do not rate limit Tor users. The current
-options are duckduckgo.com, ixquick.com, bing.com, yahoo.com and scroogle.org. These are
-encoded in the preferences
-<command>extensions.torbutton.redir_url.[1-5]</command>.
-
-</para>
-</sect3>
-
-<sect3>
-
- <title>Store SSL/CA Certs in separate jars for Tor/Non-Tor (recommended)</title>
-
-<para>Options:
-<simplelist>
- <member><command>extensions.torbutton.jar_certs</command></member>
- <member><command>extensions.torbutton.jar_ca_certs</command></member>
-</simplelist>
-</para>
-<para>
-
-These settings govern if Torbutton attempts to isolate the user's SSL
-certificates into separate jars for each Tor state. This isolation is
-implemented in <function>torbutton_jar_certs()</function> in <ulink
-url="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/chrome/con…">chrome/content/torbutton.js</ulink>,
-which calls <function>torbutton_jar_cert_type()</function> and
-<function>torbutton_unjar_cert_type()</function> for each certificate type in
-the <ulink
-url="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/c…">@mozilla.org/security/nsscertcache;1</ulink>.
-Certificates are deleted from and imported to the <ulink
-url="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/c…">@mozilla.org/security/x509certdb;1</ulink>.
-</para>
-
-<para>
-The first time this pref is used, a backup of the user's certificates is
-created in their profile directory under the name
-<filename>cert8.db.bak</filename>. This file can be copied back to
-<filename>cert8.db</filename> to fully restore the original state of the
-user's certificates in the event of any error.
-</para>
-
-<para>
-Since exit nodes and malicious sites can insert content elements sourced to
-specific SSL sites to query if a user has a certain certificate,
-this setting helps to satisfy the <link linkend="state">State
-Separation</link> requirement of Torbutton. Unfortunately, <ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=435159">Firefox Bug
-435159</ulink> prevents it from functioning correctly in the event of rapid Tor toggle, so it
-is currently not exposed via the preferences UI.
-
-</para>
-
-</sect3>
-
-
-</sect2>
-</sect1>
-
-<sect1 id="FirefoxBugs">
- <title>Relevant Firefox Bugs</title>
- <para>
-Future releases of Torbutton are going to be designed around supporting only
-<ulink url="https://www.torproject.org/projects/torbrowser.html.en">Tor
-Browser Bundle</ulink>, which greatly simplifies the number and nature of Firefox
-bugs we must fix. This allows us to abandon the complexities of <link
-linkend="state">State
-Separation</link> and <link linkend="isolation">Network Isolation</link> requirements
-associated with the Toggle Model.
- </para>
- <sect2 id="TorBrowserBugs">
- <title>Tor Browser Bugs</title>
- <para>
-The list of Firefox patches we must create to improve privacy on the
-Tor Browser Bundle are collected in the Tor Bug Tracker under <ulink
-url="https://trac.torproject.org/projects/tor/ticket/2871">ticket
-#2871</ulink>. These bugs are also applicable to the Toggle Model, and
-should be considered higher priority than all Toggle Model specific bugs
-below.
- </para>
- </sect2>
- <sect2 id="ToggleModelBugs">
- <title>Toggle Model Bugs</title>
- <para>
-In addition to the Tor Browser bugs, the Torbutton Toggle Model suffers from
-additional bugs specific to the need to isolate state across the toggle.
-Toggle model bugs are considered a lower priority than the bugs against the
-Tor Browser model.
- </para>
- <sect3 id="FirefoxSecurity">
- <title>Bugs impacting security</title>
- <para>
-
-Torbutton has to work around a number of Firefox bugs that impact its
-security. Most of these are mentioned elsewhere in this document, but they
-have also been gathered here for reference. In order of decreasing severity,
-they are:
-
- </para>
- <orderedlist>
-<!--
-Duplicated in toggle model.
- <listitem><ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=429070">Bug 429070 - exposing
-Components.interfaces to untrusted content leaks information about installed
-extensions</ulink>
- <para>
-<ulink url="http://pseudo-flaw.net/">Gregory Fleischer</ulink> demonstrated at Defcon 17 that these interfaces can
-also be used to <ulink
-url="http://pseudo-flaw.net/tor/torbutton/fingerprint-firefox.html">fingerprint
-Firefox down the to the minor version</ulink>. Note that his test has not been
-updated since 3.5.3, hence it reports 3.5.3 for more recent Firefoxes. This
-bug interferes with Torbutton's ability to satisfy its <link
-linkend="setpreservation">Anonymity Set Preservation</link> requirement.
- </para>
- </listitem>
- <listitem><ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=280661">Bug 280661 - SOCKS proxy server
-connection timeout hard-coded</ulink>
- <para>
-
-This bug prevents us from using the Firefox SOCKS layer directly, and
-currently requires us to ship an auxiliary HTTP proxy called <ulink
-url="http://www.pps.jussieu.fr/~jch/software/polipo/">Polipo</ulink>. If this
-patch were landed, we would no longer need to ship Polipo, which has a number
-of privacy and security issues of its own (in addition to being unmaintained).
-
- </para>
- </listitem>
- <listitem><ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=418986">Bug 418986 - window.screen
-provides a large amount of identifiable information</ulink>
- <para>
-
-As <link linkend="fingerprinting">mentioned above</link>, a large amount of
-information is available from <ulink
-url="http://developer.mozilla.org/en/docs/DOM:window.screen">window.screen</ulink>.
-The most sensitive data to anonymity is actually that which is not used in
-rendering - such as desktop resolution, and window decoration size.
-Currently, there is no way to obscure this information without Javascript
-hooking. In addition, many of this same desktop and window decoration
-resolution information is available via <ulink
-url="https://developer.mozilla.org/En/CSS/Media_queries">CSS Media
-Queries</ulink>, so perhaps some more lower-level rendering controls or
-preferences need to be provided. These issues interfere with Torbutton's
-ability to fulfill its <link linkend="setpreservation">Anonymity Set
-Preservation</link> requirement.
-
- </para>
- </listitem>
--->
- <listitem><ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=435159">Bug 435159 -
-nsNSSCertificateDB::DeleteCertificate has race conditions</ulink>
- <para>
-
-In Torbutton 1.2.0rc1, code was added to attempt to isolate SSL certificates
-the user has installed. Unfortunately, the method call to delete a certificate
-from the current certificate database acts lazily: it only sets a variable
-that marks a cert for deletion later, and it is not cleared if that
-certificate is re-added. This means that if the Tor state is toggled quickly,
-that certificate could remain present until it is re-inserted (causing an
-error dialog), and worse, it would still be deleted after that. The lack of
-this functionality is considered a Torbutton security bug because cert
-isolation is considered a <link linkend="state">State Separation</link>
-feature.
-
- </para>
- </listitem>
- <listitem>Give more visibility into and control over TLS
-negotiation
- <para>
-
-There are several <ulink
-url="https://trac.torproject.org/projects/tor/ticket/2482">TLS issues
-impacting Torbutton security</ulink>. It is not clear if these should be one
-Firefox bug or several, but in particular we need better control over various
-aspects of TLS connections. Firefox currently provides no observer capable of
-extracting TLS parameters or certificates early enough to cancel a TLS
-request. We would like to be able to provide <ulink
-url="https://www.eff.org/https-everywhere">HTTPS-Everywhere</ulink> users with
-the ability to <ulink
-url="https://trac.torproject.org/projects/tor/wiki/HTTPSEverywhere/SSLObservator…">have
-their certificates audited</ulink> by a <ulink
-url="http://www.networknotary.org/">Perspectives</ulink>-style set of
-notaries. The problem with this is that the API observer points do not exist
-for any Firefox addon to actually block authentication token submission over a
-TLS channel, so every addon to date (including Perspectives) is actually
-providing users with notification *after* their authentication tokens have
-already been compromised. This obviously needs to be fixed.
- </para>
- </listitem>
-<!--
-This is under the Tor Browser model.
- <listitem><ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=575230">Bug 575230 - Provide option to
-reduce precision of Date()</ulink>
- <para>
-
-Currently it is possible to <ulink
-url="http://arstechnica.com/tech-policy/news/2010/02/firm-uses-typing-cadence-to…">fingerprint
-users based on their typing cadence</ulink> using the high precision timer
-available to javascript. Using this same precision, it is possible to compute
-an identifier based upon the clock drift of the client from some nominal
-source. The latter is not much of a concern for Tor users, as the variable
-delay to load and run a page is measured on the order of seconds, but the high
-precision timer can still be used to fingerprint aspects of a browser's
-javascript engine and processor, and apparently also a user's typing cadence.
-This bug hinders Torbutton's ability to satisfy its <link
-linkend="setpreservation">Anonymity Set Preservation</link> requirement.
-
- </para>
- </listitem>
--->
- <listitem><ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=122752">Bug 122752 - SOCKS
-Username/Password Support</ulink>
- <para>
-We need <ulink url="https://developer.mozilla.org/en/nsIProxyInfo">Firefox
-APIs</ulink> or about:config settings to control the SOCKS Username and
-Password fields. The reason why we need this support is to utilize an (as yet
-unimplemented) scheme to separate Tor traffic based <ulink
-url="https://gitweb.torproject.org/torspec.git/blob_plain/HEAD:/proposals/171-se…">on
-SOCKS username/password</ulink>.
- </para>
- </listitem>
-
- <listitem><ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=409737">Bug 409737 -
-javascript.enabled and docShell.allowJavascript do not disable all event
-handlers</ulink>
- <para>
-
-This bug allows pages to execute javascript via addEventListener and perhaps
-other callbacks. In order to prevent this bug from enabling an attacker to
-break the <link linkend="isolation">Network Isolation</link> requirement,
-Torbutton 1.1.13 began blocking popups and history manipulation from different
-Tor states. So long as there are no ways to open popups or redirect the user
-to a new page, the <link linkend="contentpolicy">Torbutton content
-policy</link> should block Javascript network access. However, if there are
-ways to open popups or perform redirects such that Torbutton cannot block
-them, pages may still have free reign to break that requirement and reveal a
-user's original IP address.
-
- </para>
- </listitem>
- <listitem><ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=448743">Bug 448743 -
-Decouple general.useragent.locale from spoofing of navigator.language</ulink>
- <para>
-
-Currently, Torbutton spoofs the <command>navigator.language</command>
-attribute via <link linkend="jshooks">Javascript hooks</link>. Unfortunately,
-these do not work on Firefox 3. It would be ideal to have
-a pref to set this value (something like a
-<command>general.useragent.override.locale</command>),
-to avoid fragmenting the anonymity set of users of foreign locales. This issue
-impedes Torbutton from fully meeting its <link
-linkend="setpreservation">Anonymity Set Preservation</link>
-requirement on Firefox 3.
-
- </para>
- </listitem>
- </orderedlist>
- </sect3>
-<!-- XXX: Need to create a bug for DOM storage APIs at some point -->
- <sect3 id="FirefoxWishlist">
- <title>Bugs blocking functionality</title>
- <para>
-The following bugs impact Torbutton and similar extensions' functionality.
- </para>
-
- <orderedlist>
-
-<!--
- <listitem><ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=445696">Bug 445696 -
-Extensions cannot determine if Firefox is full screen</ulink>
- <para>
-
-The windowState property of <ulink
-url="https://developer.mozilla.org/en/XUL/window">ChromeWindows</ulink> does not accurately reflect the true
-state of the window in some cases on Linux. This causes Torbutton to attempt
-to resize maximized and minimized windows when it should not.
-
- </para>
- </listitem>
--->
- <listitem><ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=629820">Bug 629820 - nsIContentPolicy::shouldLoad not
-called for web request in Firefox Mobile</ulink>
- <para>
-
-The new <ulink
-url="https://wiki.mozilla.org/Mobile/Fennec/Extensions/Electrolysis">Electrolysis</ulink>
-multiprocess system appears to have some pretty rough edge cases with respect
-to registering XPCOM category managers such as the nsIContentPolicy, which
-make it difficult to do a straight-forward port of Torbutton or
-HTTPS-Everywhere to Firefox Mobile. It probably also has similar issues with
-wrapping existing <link linkend="hookedxpcom">Firefox XPCOM components</link>,
-which will also cause more problems for porting Torbutton.
-
- </para>
- </listitem>
-<!--
- <listitem><ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=290456">Bug 290456 -
-Block/clear Flash MX "cookies" as well</ulink>
- <para>
-
-Today, it is possible to allow plugins if you have a transparent proxy such as
-<ulink url="http://anonymityanywhere.com/incognito/">Incognito</ulink> to prevent proxy bypass. However, flash cookies can still be used to
-link your Tor and Non-Tor activity, and this reveal your IP to an adversary
-that does so. This can be solved by manually removing your flash cookies (like
-<ulink
-url="https://addons.mozilla.org/en-US/firefox/addon/6623">BetterPrivacy</ulink> does), but
-it would be nice if there was a standard way to do this from a Firefox API.
-
- </para>
- </listitem>
--->
- <listitem><ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=417869">Bug 417869 -
-Browser context is difficult to obtain from many XPCOM callbacks</ulink>
- <para>
-
-It is difficult to determine which tabbrowser many XPCOM callbacks originate
-from, and in some cases absolutely no context information is provided at all.
-While this doesn't have much of an effect on Torbutton, it does make writing
-extensions that would like to do per-tab settings and content filters (such as
-FoxyProxy) difficult to impossible to implement securely.
-
- </para>
- </listitem>
-<!--
-FIXME: This doesn't really apply anymore.
- <listitem><ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=418321">Bug 418321 -
-Components do not expose disk interfaces</ulink>
- <para>
-
-Several components currently provide no way of reimplementing their disk
-access to easily satisfy Torbutton's <link linkend="disk">Disk
-Avoidance</link> requirements. Workarounds exist, but they are <link
-linkend="sessionstore">clunky</link>, and
-some of them involve disabling functionality during Tor usage.
-
- </para>
- </listitem>
--->
-
-<!--
-FIXME: Need to use new observer methods if possible
- <listitem><ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=448741">Bug 448741 -
-nsISessionStore uses private methods and is not extensible</ulink>
- <para>
-
-Similar to the above bug, in the specific case of the sessionstore component,
-the API is not amenable to Contract ID hooking, and this requires that
-Torbutton include modified copies of this component for Firefox 2 and 3, which
-has <ulink
-url="https://bugs.torproject.org/flyspray/index.php?do=details&id=722">raised
-objections</ulink> from some developers.
-
- </para>
- </listitem>
- <listitem><ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=439384">Bug 439384 -
-"profile-do-change" event does not cause cookie table reload</ulink>
- <para>
-
-In Firefox 3, the change to the new SQLlite database for cookie storage has a
-bug that prevents Torbutton's cookie jaring from working properly. The
-"profile-do-change" observer event no longer properly causes either a sync or
-reload of the cookie database from disk after it is copied into place.
-Torbutton currently works around this by issuing the SQLLite queries manually
-to store and rebuild the cookie database.
-
- </para>
- </listitem>
-
- <listitem><ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=248970">Bug 248970 (PrivateBrowsing) - Private Browsing mode (global toggle for
-saving/caching everything)</ulink>
- <para>
-
-This bug catalogs the discussion of a 'Private Mode' in Firefox that would
-perform many, but not all, of the activities of Torbutton. It would be useful
-to leverage the resulting setting to simplify Torbutton. This bug is listed so
-we can track this progress and ensure that it doesn't end up defining
-behaviors contrary to and incompatible with Torbutton's requirements (though a
-subset of the <link linkend="requirements">requirements</link> is of course fine).
-
- </para>
- </listitem>
--->
-
-
-
- </orderedlist>
- </sect3>
- <sect3 id="FirefoxMiscBugs">
- <title>Low Priority Bugs</title>
- <para>
-The following bugs have an effect upon Torbutton, but are superseded by more
-practical and more easily fixable variant bugs above; or have stable, simple
-workarounds.
- </para>
-
- <orderedlist>
-<!--
- <listitem><ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=435151">Bug 435151 - XPCSafeJSObjectWrapper breaks evalInSandbox</ulink>
- <para>
-
-Under Firefox 3, the XPCSafeJSObjectWrapper breaks when you try to use
-constructors of classes defined from within the scope of the sandbox, among
-other things. This prevents Torbutton from applying the Timezone hooks under
-Firefox 3, but a better solution for Torbutton's specific date hooking needs
-would be a fix for the above mentioned Bug 392274. Of course, many more
-extensions may be interested in the sandbox hooking functionality working
-properly though.
-
- </para>
- </listitem>
--->
- <listitem><ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=440892">Bug 440892 -
-network.protocol-handler.warn-external are ignored</ulink>
- <para>
-
-Sometime in the Firefox 3 development cycle, the preferences that governed
-warning a user when external apps were launched got disconnected from the code
-that does the launching. Torbutton depended on these prefs to prevent websites
-from launching specially crafted documents and application arguments that
-caused Proxy Bypass. We currently work around this issue by <link
-linkend="appblocker">wrapping the app launching components</link> to present a
-popup before launching external apps while Tor is enabled. While this works,
-it would be nice if these prefs were either fixed or removed.
-
- </para>
- </listitem>
- <listitem><ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=437014">Bug 437014 -
-nsIContentPolicy::shouldLoad no longer called for favicons</ulink>
- <para>
-
-Firefox 3.0 stopped calling the shouldLoad call of content policy for favicon
-loads. Torbutton had relied on this call to block favicon loads for opposite
-Tor states. The workaround it employs for Firefox 3 is to cancel the request
-when it arrives in the <command>torbutton_http_observer</command> used for
-blocking full page plugin loads. This seems to work just fine, but is a bit
-dirty.
-
- </para>
- </listitem>
-<!--
- <listitem><ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=437016">Bug 437016 -
-nsIContentPolicy::shouldLoad not called for livemarks</ulink>
- <para>
-
-An alternative fix for the livemarks bug above would be to block livemarks
-fetches from the content policy. Unfortunately shouldLoad is not called for
-livemarks fetches.
-
- </para>
- </listitem>
--->
-
- <listitem><ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=309524">Bug 309524</ulink>
-and <ulink url="https://bugzilla.mozilla.org/show_bug.cgi?id=380556">Bug
-380556</ulink> - nsIContentPolicy::shouldProcess is not called.
- <para>
-
-This is a call that would be useful to develop a better workaround for the
-allowPlugins issue above. If the content policy were called before a URL was
-handed over to a plugin or helper app, it would make the workaround for the
-above allowPlugins bug a lot cleaner. Obviously this bug is not as severe as
-the others though, but it might be nice to have this API as a backup.
-
- </para>
- </listitem>
-
- <listitem><ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=401296">Bug 401296 - docShell.allowPlugins
-not honored for direct links</ulink> (Perhaps subset of <ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=282106">Bug 282106</ulink>?)
- <para>
-
-Similar to the javascript plugin disabling attribute, the plugin disabling
-attribute is also not perfect — it is ignored for direct links to plugin
-handled content, as well as meta-refreshes to plugin handled content. This
-requires Torbutton to listen to a number of different http events to intercept
-plugin-related mime type URLs and cancel their requests. Again, since plugins
-are quite horrible about obeying proxy settings, loading a plugin pretty much
-ensures a way to break the <link linkend="isolation">Network Isolation</link>
-requirement and reveal a user's original IP address. Torbutton's code to
-perform this workaround has been subverted at least once already by Kyle
-Williams.
-
- </para>
- </listitem>
-<!--
-Actually, ECMAScript 5 handles this correctly now.
- <listitem><ulink
-url="https://bugzilla.mozilla.org/show_bug.cgi?id=419598">Bug 419598 - 'var
-Date' is deletable</ulink>
- <para>
-
-Based on Page 62 of the <ulink
-url="http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf">ECMA-262
-Javascript spec</ulink>, it seems like it should be possible to do something
-like the following to prevent the Date object from being unmasked:
-<screen>
-with(window) {
- var Date = fakeDate;
- var otherVariable = 42;
-}
-
-delete window.Date; // Should fail. Instead succeeds, revealing original Date.
-delete window.otherVariable; // Fails, leaving window.otherVariable set to 42.
-</screen>
-
-From the ECMA-262 spec:
-
-<blockquote>
-If the variable statement occurs inside a FunctionDeclaration, the variables
-are defined with function-local scope in that function, as described in
-s10.1.3. Otherwise, they are defined with global scope (that is, they are
-created as members of the global object, as described in 10.1.3) using
-property attributes { DontDelete }. Variables are created when the execution
-scope is entered. A Block does not define a new execution scope. Only Program
-and FunctionDeclaration produce a new scope. Variables are initialized to
-undefined when created. A variable with an Initialiser is assigned the value
-of its AssignmentExpression when the VariableStatement is executed, not when
-the variable is created.
-</blockquote>
-
-In fact, this is exactly how the with statement with a variable declaration
-behaves <emphasis>for all other variables other than ones that shadow system
-variables</emphasis>. Some variables (such as
-<command>window.screen</command>, and <command>window.history</command>) can't
-even be shadowed in this way, and give an error about lacking a setter. If
-such shadowing were possible, it would greatly simplify the Javascript hooking
-code, which currently relies on undocumented semantics of
-<command>__proto__</command> to copy the original values in the event of a
-delete. This <command>__proto__</command> hack unfortunately does not work for
-the Date object though.
-
- </para>
- </listitem>
--->
- </orderedlist>
- </sect3>
- </sect2>
-</sect1>
-
-<sect1 id="TestPlan">
- <title>Testing</title>
- <para>
-
-The purpose of this section is to cover all the known ways that Tor browser
-security can be subverted from a penetration testing perspective. The hope
-is that it will be useful both for creating a "Tor Safety Check"
-page, and for developing novel tests and actively attacking Torbutton with the
-goal of finding vulnerabilities in either it or the Mozilla components,
-interfaces and settings upon which it relies.
-
- </para>
- <sect2 id="SingleStateTesting">
- <title>Single state testing</title>
- <para>
-
-Torbutton is a complicated piece of software. During development, changes to
-one component can affect a whole slough of unrelated features. A number of
-aggregated test suites exist that can be used to test for regressions in
-Torbutton and to help aid in the development of Torbutton-like addons and
-other privacy modifications of other browsers. Some of these test suites exist
-as a single automated page, while others are a series of pages you must visit
-individually. They are provided here for reference and future regression
-testing, and also in the hope that some brave soul will one day decide to
-combine them into a comprehensive automated test suite.
-
- <orderedlist>
- <listitem><ulink url="http://decloak.net/">Decloak.net</ulink>
- <para>
-
-Decloak.net is the canonical source of plugin and external-application based
-proxy-bypass exploits. It is a fully automated test suite maintained by <ulink
-url="http://digitaloffense.net/">HD Moore</ulink> as a service for people to
-use to test their anonymity systems.
-
- </para>
- </listitem>
- <listitem><ulink url="http://deanonymizer.com/">Deanonymizer.com</ulink>
- <para>
-
-Deanonymizer.com is another automated test suite that tests for proxy bypass
-and other information disclosure vulnerabilities. It is maintained by Kyle
-Williams, the author of <ulink url="http://www.janusvm.com/">JanusVM</ulink>
-and <ulink url="http://www.januspa.com/">JanusPA</ulink>.
-
- </para>
- </listitem>
- <listitem><ulink url="https://www.jondos.de/en/anontest">JonDos
-AnonTest</ulink>
- <para>
-
-The <ulink url="https://www.jondos.de">JonDos people</ulink> also provide an
-anonymity tester. It is more focused on HTTP headers than plugin bypass, and
-points out a couple of headers Torbutton could do a better job with
-obfuscating.
-
- </para>
- </listitem>
- <listitem><ulink url="http://browserspy.dk">Browserspy.dk</ulink>
- <para>
-
-Browserspy.dk provides a tremendous collection of browser fingerprinting and
-general privacy tests. Unfortunately they are only available one page at a
-time, and there is not really solid feedback on good vs bad behavior in
-the test results.
-
- </para>
- </listitem>
- <listitem><ulink url="http://analyze.privacy.net/">Privacy
-Analyzer</ulink>
- <para>
-
-The Privacy Analyzer provides a dump of all sorts of browser attributes and
-settings that it detects, including some information on your origin IP
-address. Its page layout and lack of good vs bad test result feedback makes it
-not as useful as a user-facing testing tool, but it does provide some
-interesting checks in a single page.
-
- </para>
- </listitem>
- <listitem><ulink url="http://ha.ckers.org/mr-t/">Mr. T</ulink>
- <para>
-
-Mr. T is a collection of browser fingerprinting and deanonymization exploits
-discovered by the <ulink url="http://ha.ckers.org">ha.ckers.org</ulink> crew
-and others. It is also not as user friendly as some of the above tests, but it
-is a useful collection.
-
- </para>
- </listitem>
- <listitem>Gregory Fleischer's <ulink
-url="http://pseudo-flaw.net/content/tor/torbutton/">Torbutton</ulink> and
-<ulink
-url="http://pseudo-flaw.net/content/defcon/dc-17-demos/d.html">Defcon
-17</ulink> Test Cases
- <para>
-
-Gregory Fleischer has been hacking and testing Firefox and Torbutton privacy
-issues for the past 2 years. He has an excellent collection of all his test
-cases that can be used for regression testing. In his Defcon work, he
-demonstrates ways to infer Firefox version based on arcane browser properties.
-We are still trying to determine the best way to address some of those test
-cases.
-
- </para>
- </listitem>
- <listitem><ulink url="https://torcheck.xenobite.eu/index.php">Xenobite's
-TorCheck Page</ulink>
- <para>
-
-This page checks to ensure you are using a valid Tor exit node and checks for
-some basic browser properties related to privacy. It is not very fine-grained
-or complete, but it is automated and could be turned into something useful
-with a bit of work.
-
- </para>
- </listitem>
- </orderedlist>
- </para>
- </sect2>
- <sect2>
- <title>Multi-state testing</title>
- <para>
-
-The tests in this section are geared towards a page that would instruct the
-user to toggle their Tor state after the fetch and perform some operations:
-mouseovers, stray clicks, and potentially reloads.
-
- </para>
- <sect3>
- <title>Cookies and Cache Correlation</title>
- <para>
-The most obvious test is to set a cookie, ask the user to toggle tor, and then
-have them reload the page. The cookie should no longer be set if they are
-using the default Torbutton settings. In addition, it is possible to leverage
-the cache to <ulink
-url="http://crypto.stanford.edu/sameorigin/safecachetest.html">store unique
-identifiers</ulink>. The default settings of Torbutton should also protect
-against these from persisting across Tor Toggle.
-
- </para>
- </sect3>
- <sect3>
- <title>Javascript timers and event handlers</title>
- <para>
-
-Javascript can set timers and register event handlers in the hopes of fetching
-URLs after the user has toggled Torbutton.
- </para>
- </sect3>
- <sect3>
- <title>CSS Popups and non-script Dynamic Content</title>
- <para>
-
-Even if Javascript is disabled, CSS is still able to
-<ulink url="http://www.tjkdesign.com/articles/css%20pop%20ups/">create popup-like
-windows</ulink>
-via the 'onmouseover' CSS attribute, which can cause arbitrary browser
-activity as soon as the mouse enters into the content window. It is also
-possible for meta-refresh tags to set timers long enough to make it likely
-that the user has toggled Tor before fetching content.
-
- </para>
- </sect3>
- </sect2>
- <sect2 id="HackTorbutton">
- <title>Active testing (aka How to Hack Torbutton)</title>
- <para>
-
-The idea behind active testing is to discover vulnerabilities in Torbutton to
-bypass proxy settings, run script in an opposite Tor state, store unique
-identifiers, leak location information, or otherwise violate <link
-linkend="requirements">its requirements</link>. Torbutton has ventured out
-into a strange and new security landscape. It depends on Firefox mechanisms
-that haven't necessarily been audited for security, certainly not for the
-threat model that Torbutton seeks to address. As such, it and the interfaces
-it depends upon still need a 'trial by fire' typical of new technologies. This
-section of the document was written with the intention of making that period
-as fast as possible. Please help us get through this period by considering
-these attacks, playing with them, and reporting what you find (and potentially
-submitting the test cases back to be run in the standard batch of Torbutton
-tests.
-
- </para>
- <sect3>
- <title>Some suggested vectors to investigate</title>
- <para>
- <itemizedlist>
- <listitem>Strange ways to register Javascript <ulink
-url="http://en.wikipedia.org/wiki/DOM_Events">events</ulink> and <ulink
-url="http://www.devshed.com/c/a/JavaScript/Using-Timers-in-JavaScript/">timeouts</ulink> should
-be verified to actually be ineffective after Tor has been toggled.</listitem>
- <listitem>Other ways to cause Javascript to be executed after
-<command>javascript.enabled</command> has been toggled off.</listitem>
- <listitem>Odd ways to attempt to load plugins. Kyle Williams has had
-some success with direct loads/meta-refreshes of plugin-handled URLs.</listitem>
- <listitem>The Date and Timezone hooks should be verified to work with
-crazy combinations of iframes, nested iframes, iframes in frames, frames in
-iframes, and popups being loaded and
-reloaded in rapid succession, and/or from one another. Think race conditions and deep,
-parallel nesting, involving iframes from both <ulink
-url="http://en.wikipedia.org/wiki/Same_origin_policy">same-origin and
-non-same-origin</ulink> domains.</listitem>
- <listitem>In addition, there may be alternate ways and other
-methods to query the timezone, or otherwise use some of the Date object's
-methods in combination to deduce the timezone offset. Of course, the author
-tried his best to cover all the methods he could foresee, but it's always good
-to have another set of eyes try it out.</listitem>
- <listitem>Similarly, is there any way to confuse the <link
-linkend="contentpolicy">content policy</link>
-mentioned above to cause it to allow certain types of page fetches? For
-example, it was recently discovered that favicons are not fetched by the
-content, but the chrome itself, hence the content policy did not look up the
-correct window to determine the current Tor tag for the favicon fetch. Are
-there other things that can do this? Popups? Bookmarklets? Active bookmarks? </listitem>
- <listitem>Alternate ways to store and fetch unique identifiers. For example, <ulink
-url="http://developer.mozilla.org/en/docs/DOM:Storage">DOM Storage</ulink>
-caught us off guard.
-It was
-also discovered by <ulink url="http://pseudo-flaw.net">Gregory
-Fleischer</ulink> that <ulink
-url="http://pseudo-flaw.net/content/tor/torbutton/">content window access to
-chrome</ulink> can be used to build <link linkend="fingerprinting">unique
-identifiers</link>.
-Are there any other
-arcane or experimental ways that Firefox provides to create and store unique
-identifiers? Or perhaps unique identifiers can be queried or derived from
-properties of the machine/browser that Javascript has access to? How unique
-can these identifiers be?
- </listitem>
- <listitem>Is it possible to get the browser to write some history to disk
-(aside from swap) that can be retrieved later? By default, Torbutton should
-write no history, cookie, or other browsing activity information to the
-harddisk.</listitem>
- <listitem>Do popup windows make it easier to break any of the above
-behavior? Are javascript events still canceled in popups? What about recursive
-popups from Javascript, data, and other funky URL types? What about CSS
-popups? Are they still blocked after Tor is toggled?</listitem>
- <listitem>Chrome-escalation attacks. The interaction between the
-Torbutton chrome Javascript and the client content window javascript is pretty
-well-defined and carefully constructed, but perhaps there is a way to smuggle
-javascript back in a return value, or otherwise inject network-loaded
-javascript into the chrome (and thus gain complete control of the browser).
-</listitem>
-</itemizedlist>
-
- </para>
- </sect3>
- </sect2>
-</sect1>
-</article>
diff --git a/website/design/index.html.en b/website/design/index.html.en
deleted file mode 100644
index 88f305d2..00000000
--- a/website/design/index.html.en
+++ /dev/null
@@ -1,1453 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Torbutton Design Documentation</title><meta name="generator" content="DocBook XSL Stylesheets V1.75.2" /></head><body><div class="article" title="Torbutton Design Documentation"><div class="titlepage"><div><div><h2 class="title"><a id="design"></a>Torbutton Design Documentation</h2></div><div><div class="author"><h3 class="author"><span class="firstname">Mike</span> <span class="surname">Perry</span></h3><div class="affiliation"><div class="address"><p><code class="email"><<a class="email" href="mailto:mikeperry.fscked/org">mikeperry.fscked/org</a>></code></p></div></div></div></div><div><p class="pubdate">Apr 10 2011</p></div></div><hr /></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="sect1"><a href="#id2666923">1. Introduction</a></span></dt><dd><dl><dt><span class="sect2"><a href="#adversary">1.1. Adversary Model</a></span><
/dt><dt><span class="sect2"><a href="#requirements">1.2. Torbutton Requirements</a></span></dt><dt><span class="sect2"><a href="#layout">1.3. Extension Layout</a></span></dt></dl></dd><dt><span class="sect1"><a href="#components">2. Components</a></span></dt><dd><dl><dt><span class="sect2"><a href="#hookedxpcom">2.1. Hooked Components</a></span></dt><dt><span class="sect2"><a href="#id2690319">2.2. New Components</a></span></dt></dl></dd><dt><span class="sect1"><a href="#id2681735">3. Chrome</a></span></dt><dd><dl><dt><span class="sect2"><a href="#id2702019">3.1. XUL Windows and Overlays</a></span></dt><dt><span class="sect2"><a href="#id2694797">3.2. Major Chrome Observers</a></span></dt></dl></dd><dt><span class="sect1"><a href="#id2696524">4. Toggle Code Path</a></span></dt><dd><dl><dt><span class="sect2"><a href="#id2699452">4.1. Button Click</a></span></dt><dt><span class="sect2"><a href="#id2697978">4.2. Proxy Update</a></span></dt><dt><span class="sect2"><a href="#id2697015">
4.3. Settings Update</a></span></dt><dt><span class="sect2"><a href="#preferences">4.4. Firefox preferences touched during Toggle</a></span></dt></dl></dd><dt><span class="sect1"><a href="#id2702702">5. Description of Options</a></span></dt><dd><dl><dt><span class="sect2"><a href="#id2704948">5.1. Proxy Settings</a></span></dt><dt><span class="sect2"><a href="#id2686645">5.2. Dynamic Content Settings</a></span></dt><dt><span class="sect2"><a href="#id2705261">5.3. History and Forms Settings</a></span></dt><dt><span class="sect2"><a href="#id2705577">5.4. Cache Settings</a></span></dt><dt><span class="sect2"><a href="#id2705686">5.5. Cookie and Auth Settings</a></span></dt><dt><span class="sect2"><a href="#id2705999">5.6. Startup Settings</a></span></dt><dt><span class="sect2"><a href="#id2706113">5.7. Shutdown Settings</a></span></dt><dt><span class="sect2"><a href="#id2706173">5.8. Header Settings</a></span></dt></dl></dd><dt><span class="sect1"><a href="#FirefoxBugs">6. Relevant F
irefox Bugs</a></span></dt><dd><dl><dt><span class="sect2"><a href="#TorBrowserBugs">6.1. Tor Browser Bugs</a></span></dt><dt><span class="sect2"><a href="#ToggleModelBugs">6.2. Toggle Model Bugs</a></span></dt></dl></dd><dt><span class="sect1"><a href="#TestPlan">7. Testing</a></span></dt><dd><dl><dt><span class="sect2"><a href="#SingleStateTesting">7.1. Single state testing</a></span></dt><dt><span class="sect2"><a href="#id2707624">7.2. Multi-state testing</a></span></dt><dt><span class="sect2"><a href="#HackTorbutton">7.3. Active testing (aka How to Hack Torbutton)</a></span></dt></dl></dd></dl></div><div class="sect1" title="1. Introduction"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="id2666923"></a>1. Introduction</h2></div></div></div><p>
-
-This document describes the goals, operation, and testing procedures of the
-Torbutton Firefox extension. It is current as of Torbutton 1.3.2.
-
- </p><div class="sect2" title="1.1. Adversary Model"><div class="titlepage"><div><div><h3 class="title"><a id="adversary"></a>1.1. Adversary Model</h3></div></div></div><p>
-
-A Tor web browser adversary has a number of goals, capabilities, and attack
-types that can be used to guide us towards a set of requirements for the
-Torbutton extension. Let's start with the goals.
-
- </p><div class="sect3" title="Adversary Goals"><div class="titlepage"><div><div><h4 class="title"><a id="adversarygoals"></a>Adversary Goals</h4></div></div></div><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><span class="command"><strong>Bypassing proxy settings</strong></span><p>The adversary's primary goal is direct compromise and bypass of
-Tor, causing the user to directly connect to an IP of the adversary's
-choosing.</p></li><li class="listitem"><span class="command"><strong>Correlation of Tor vs Non-Tor Activity</strong></span><p>If direct proxy bypass is not possible, the adversary will likely
-happily settle for the ability to correlate something a user did via Tor with
-their non-Tor activity. This can be done with cookies, cache identifiers,
-javascript events, and even CSS. Sometimes the fact that a user uses Tor may
-be enough for some authorities.</p></li><li class="listitem"><span class="command"><strong>History disclosure</strong></span><p>
-The adversary may also be interested in history disclosure: the ability to
-query a user's history to see if they have issued certain censored search
-queries, or visited censored sites.
- </p></li><li class="listitem"><span class="command"><strong>Location information</strong></span><p>
-
-Location information such as timezone and locality can be useful for the
-adversary to determine if a user is in fact originating from one of the
-regions they are attempting to control, or to zero-in on the geographical
-location of a particular dissident or whistleblower.
-
- </p></li><li class="listitem"><span class="command"><strong>Miscellaneous anonymity set reduction</strong></span><p>
-
-Anonymity set reduction is also useful in attempting to zero in on a
-particular individual. If the dissident or whistleblower is using a rare build
-of Firefox for an obscure operating system, this can be very useful
-information for tracking them down, or at least <a class="link" href="#fingerprinting">tracking their activities</a>.
-
- </p></li><li class="listitem"><span class="command"><strong>History records and other on-disk
-information</strong></span><p>
-In some cases, the adversary may opt for a heavy-handed approach, such as
-seizing the computers of all Tor users in an area (especially after narrowing
-the field by the above two pieces of information). History records and cache
-data are the primary goals here.
- </p></li></ol></div></div><div class="sect3" title="Adversary Capabilities - Positioning"><div class="titlepage"><div><div><h4 class="title"><a id="adversarypositioning"></a>Adversary Capabilities - Positioning</h4></div></div></div><p>
-The adversary can position themselves at a number of different locations in
-order to execute their attacks.
- </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><span class="command"><strong>Exit Node or Upstream Router</strong></span><p>
-The adversary can run exit nodes, or alternatively, they may control routers
-upstream of exit nodes. Both of these scenarios have been observed in the
-wild.
- </p></li><li class="listitem"><span class="command"><strong>Adservers and/or Malicious Websites</strong></span><p>
-The adversary can also run websites, or more likely, they can contract out
-ad space from a number of different adservers and inject content that way. For
-some users, the adversary may be the adservers themselves. It is not
-inconceivable that adservers may try to subvert or reduce a user's anonymity
-through Tor for marketing purposes.
- </p></li><li class="listitem"><span class="command"><strong>Local Network/ISP/Upstream Router</strong></span><p>
-The adversary can also inject malicious content at the user's upstream router
-when they have Tor disabled, in an attempt to correlate their Tor and Non-Tor
-activity.
- </p></li><li class="listitem"><span class="command"><strong>Physical Access</strong></span><p>
-Some users face adversaries with intermittent or constant physical access.
-Users in Internet cafes, for example, face such a threat. In addition, in
-countries where simply using tools like Tor is illegal, users may face
-confiscation of their computer equipment for excessive Tor usage or just
-general suspicion.
- </p></li></ol></div></div><div class="sect3" title="Adversary Capabilities - Attacks"><div class="titlepage"><div><div><h4 class="title"><a id="attacks"></a>Adversary Capabilities - Attacks</h4></div></div></div><p>
-
-The adversary can perform the following attacks from a number of different
-positions to accomplish various aspects of their goals. It should be noted
-that many of these attacks (especially those involving IP address leakage) are
-often performed by accident by websites that simply have Javascript, dynamic
-CSS elements, and plugins. Others are performed by adservers seeking to
-correlate users' activity across different IP addresses, and still others are
-performed by malicious agents on the Tor network and at national firewalls.
-
- </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><span class="command"><strong>Inserting Javascript</strong></span><p>
-If not properly disabled, Javascript event handlers and timers
-can cause the browser to perform network activity after Tor has been disabled,
-thus allowing the adversary to correlate Tor and Non-Tor activity and reveal
-a user's non-Tor IP address. Javascript
-also allows the adversary to execute <a class="ulink" href="http://whattheinternetknowsaboutyou.com/" target="_top">history disclosure attacks</a>:
-to query the history via the different attributes of 'visited' links to search
-for particular Google queries, sites, or even to <a class="ulink" href="http://www.mikeonads.com/2008/07/13/using-your-browser-url-history-estimate…" target="_top">profile
-users based on gender and other classifications</a>. Finally,
-Javascript can be used to query the user's timezone via the
-<code class="function">Date()</code> object, and to reduce the anonymity set by querying
-the <code class="function">navigator</code> object for operating system, CPU, locale,
-and user agent information.
- </p></li><li class="listitem"><span class="command"><strong>Inserting Plugins</strong></span><p>
-
-Plugins are abysmal at obeying the proxy settings of the browser. Every plugin
-capable of performing network activity that the author has
-investigated is also capable of performing network activity independent of
-browser proxy settings - and often independent of its own proxy settings.
-Sites that have plugin content don't even have to be malicious to obtain a
-user's
-Non-Tor IP (it usually leaks by itself), though <a class="ulink" href="http://decloak.net" target="_top">plenty of active
-exploits</a> are possible as well. In addition, plugins can be used to store unique identifiers that are more
-difficult to clear than standard cookies.
-<a class="ulink" href="http://epic.org/privacy/cookies/flash.html" target="_top">Flash-based
-cookies</a> fall into this category, but there are likely numerous other
-examples.
-
- </p></li><li class="listitem"><span class="command"><strong>Inserting CSS</strong></span><p>
-
-CSS can also be used to correlate Tor and Non-Tor activity and reveal a user's
-Non-Tor IP address, via the usage of
-<a class="ulink" href="http://www.tjkdesign.com/articles/css%20pop%20ups/" target="_top">CSS
-popups</a> - essentially CSS-based event handlers that fetch content via
-CSS's onmouseover attribute. If these popups are allowed to perform network
-activity in a different Tor state than they were loaded in, they can easily
-correlate Tor and Non-Tor activity and reveal a user's IP address. In
-addition, CSS can also be used without Javascript to perform <a class="ulink" href="http://ha.ckers.org/weird/CSS-history.cgi" target="_top">CSS-only history disclosure
-attacks</a>.
- </p></li><li class="listitem"><span class="command"><strong>Read and insert cookies</strong></span><p>
-
-An adversary in a position to perform MITM content alteration can inject
-document content elements to both read and inject cookies for
-arbitrary domains. In fact, many "SSL secured" websites are vulnerable to this
-sort of <a class="ulink" href="http://seclists.org/bugtraq/2007/Aug/0070.html" target="_top">active
-sidejacking</a>.
-
- </p></li><li class="listitem"><span class="command"><strong>Create arbitrary cached content</strong></span><p>
-
-Likewise, the browser cache can also be used to <a class="ulink" href="http://crypto.stanford.edu/sameorigin/safecachetest.html" target="_top">store unique
-identifiers</a>. Since by default the cache has no same-origin policy,
-these identifiers can be read by any domain, making them an ideal target for
-adserver-class adversaries.
-
- </p></li><li class="listitem"><a id="fingerprinting"></a><span class="command"><strong>Fingerprint users based on browser
-attributes</strong></span><p>
-
-There is an absurd amount of information available to websites via attributes
-of the browser. This information can be used to reduce anonymity set, or even
-<a class="ulink" href="http://mandark.fr/0x000000/articles/Total_Recall_On_Firefox..html" target="_top">uniquely
-fingerprint individual users</a>. </p><p>
-For illustration, let's perform a
-back-of-the-envelope calculation on the number of anonymity sets for just the
-resolution information available in the <a class="ulink" href="http://developer.mozilla.org/en/docs/DOM:window" target="_top">window</a> and
-<a class="ulink" href="http://developer.mozilla.org/en/docs/DOM:window.screen" target="_top">window.screen</a>
-objects.
-
-
-
-Browser window resolution information provides something like
-(1280-640)*(1024-480)=348160 different anonymity sets. Desktop resolution
-information contributes about another factor of 5 (for about 5 resolutions in
-typical use). In addition, the dimensions and position of the desktop taskbar
-are available, which can reveal hints on OS information. This boosts the count
-by a factor of 5 (for each of the major desktop taskbars - Windows, OSX, KDE
-and Gnome, and None). Subtracting the browser content window
-size from the browser outer window size provide yet more information.
-Firefox toolbar presence gives about a factor of 8 (3 toolbars on/off give
-2<sup>3</sup>=8). Interface effects such as title bar font size
-and window manager settings gives a factor of about 9 (say 3 common font sizes
-for the title bar and 3 common sizes for browser GUI element fonts).
-Multiply this all out, and you have (1280-640)*(1024-480)*5*5*8*9 ~=
-2<sup>29</sup>, or a 29 bit identifier based on resolution
-information alone. </p><p>
-
-Of course, this space is non-uniform in user density and prone to incremental
-changes. The <a class="ulink" href="https://wiki.mozilla.org/Fingerprinting#Data" target="_top">Panopticlick study
-done</a> by the EFF attempts to measure the actual entropy - the number of
-identifying bits of information encoded in browser properties. Their result
-data is definitely useful, and the metric is probably the appropriate one for
-determining how identifying a particular browser property is. However, some
-quirks of their study means that they do not extract as much information as
-they could from display information: they only use desktop resolution (which
-Torbutton reports as the window resolution) and do not attempt to infer the
-size of toolbars.
-
-</p></li><li class="listitem"><span class="command"><strong>Remotely or locally exploit browser and/or
-OS</strong></span><p>
-Last, but definitely not least, the adversary can exploit either general
-browser vulnerabilities, plugin vulnerabilities, or OS vulnerabilities to
-install malware and surveillance software. An adversary with physical access
-can perform similar actions. Regrettably, this last attack capability is
-outside of Torbutton's ability to defend against, but it is worth mentioning
-for completeness.
- </p></li></ol></div></div></div><div class="sect2" title="1.2. Torbutton Requirements"><div class="titlepage"><div><div><h3 class="title"><a id="requirements"></a>1.2. Torbutton Requirements</h3></div></div></div><div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3>
-
-Since many settings satisfy multiple requirements, this design document is
-organized primarily by Torbutton components and settings. However, if you are
-the type that would rather read the document from the requirements
-perspective, it is in fact possible to search for each of the following
-requirement phrases in the text to find the relevant features that help meet
-that requirement.
-
-</div><p>
-
-From the above Adversary Model, a number of requirements become clear.
-
- </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><a id="proxy"></a><span class="command"><strong>Proxy Obedience</strong></span><p>The browser
-MUST NOT bypass Tor proxy settings for any content.</p></li><li class="listitem"><a id="state"></a><span class="command"><strong>State Separation</strong></span><p>Browser state (cookies, cache, history, 'DOM storage'), accumulated in
- one Tor state MUST NOT be accessible via the network in
- another Tor state.</p></li><li class="listitem"><a id="isolation"></a><span class="command"><strong>Network Isolation</strong></span><p>Pages MUST NOT perform any network activity in a Tor state different
- from the state they were originally loaded in.</p><p>Note that this requirement is
-being de-emphasized due to the coming shift to supporting only the Tor Browser
-Bundles, which do not support a Toggle operation.</p></li><li class="listitem"><a id="undiscoverability"></a><span class="command"><strong>Tor Undiscoverability</strong></span><p>With
-the advent of bridge support in Tor 0.2.0.x, there are now a class of Tor
-users whose network fingerprint does not obviously betray the fact that they
-are using Tor. This should extend to the browser as well - Torbutton MUST NOT
-reveal its presence while Tor is disabled.
-</p><p>Note that this requirement is
-being de-emphasized due to the coming shift to supporting only the Tor Browser
-Bundles, which do not support a Toggle operation.</p></li><li class="listitem"><a id="disk"></a><span class="command"><strong>Disk Avoidance</strong></span><p>The browser SHOULD NOT write any Tor-related state to disk, or store it
- in memory beyond the duration of one Tor toggle.</p></li><li class="listitem"><a id="location"></a><span class="command"><strong>Location Neutrality</strong></span><p>The browser SHOULD NOT leak location-specific information, such as
- timezone or locale via Tor.</p></li><li class="listitem"><a id="setpreservation"></a><span class="command"><strong>Anonymity Set
-Preservation</strong></span><p>The browser SHOULD NOT leak any other anonymity
-set reducing or fingerprinting information
- (such as user agent, extension presence, and resolution information)
-automatically via Tor. The assessment of the attacks above should make it clear
-that anonymity set reduction is a very powerful method of tracking and
-eventually identifying anonymous users.
-</p></li><li class="listitem"><a id="updates"></a><span class="command"><strong>Update Safety</strong></span><p>The browser
-SHOULD NOT perform unauthenticated updates or upgrades via Tor.</p></li><li class="listitem"><a id="interoperate"></a><span class="command"><strong>Interoperability</strong></span><p>Torbutton SHOULD interoperate with third-party proxy switchers that
- enable the user to switch between a number of different proxies. It MUST
- provide full Tor protection in the event a third-party proxy switcher has
- enabled the Tor proxy settings.</p></li></ol></div></div><div class="sect2" title="1.3. Extension Layout"><div class="titlepage"><div><div><h3 class="title"><a id="layout"></a>1.3. Extension Layout</h3></div></div></div><p>Firefox extensions consist of two main categories of code: 'Components' and
-'Chrome'. Components are a fancy name for classes that implement a given
-interface or interfaces. In Firefox, components <a class="ulink" href="https://developer.mozilla.org/en/XPCOM" target="_top">can be
-written</a> in C++,
-Javascript, or a mixture of both. Components have two identifiers: their
-'<a class="ulink" href="http://www.mozilla.org/projects/xpcom/book/cxc/html/quicktour2.html#1005005" target="_top">Contract
-ID</a>' (a human readable path-like string), and their '<a class="ulink" href="http://www.mozilla.org/projects/xpcom/book/cxc/html/quicktour2.html#1005329" target="_top">Class
-ID</a>' (a GUID hex-string). In addition, the interfaces they implement each have a hex
-'Interface ID'. It is possible to 'hook' system components - to reimplement
-their interface members with your own wrappers - but only if the rest of the
-browser refers to the component by its Contract ID. If the browser refers to
-the component by Class ID, it bypasses your hooks in that use case.
-Technically, it may be possible to hook Class IDs by unregistering the
-original component, and then re-registering your own, but this relies on
-obsolete and deprecated interfaces and has proved to be less than
-stable.</p><p>'Chrome' is a combination of XML and Javascript used to describe a window.
-Extensions are allowed to create 'overlays' that are 'bound' to existing XML
-window definitions, or they can create their own windows. The DTD for this XML
-is called <a class="ulink" href="http://developer.mozilla.org/en/docs/XUL_Reference" target="_top">XUL</a>.</p></div></div><div class="sect1" title="2. Components"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="components"></a>2. Components</h2></div></div></div><p>
-
-Torbutton installs components for two purposes: hooking existing components to
-reimplement their interfaces; and creating new components that provide
-services to other pieces of the extension.
-
- </p><div class="sect2" title="2.1. Hooked Components"><div class="titlepage"><div><div><h3 class="title"><a id="hookedxpcom"></a>2.1. Hooked Components</h3></div></div></div><p>Torbutton makes extensive use of Contract ID hooking, and implements some
-of its own standalone components as well. Let's discuss the hooked components
-first.</p><div class="sect3" title="@mozilla.org/uriloader/external-protocol-service;1 , @mozilla.org/uriloader/external-helper-app-service;1, and @mozilla.org/mime;1 - components/external-app-blocker.js"><div class="titlepage"><div><div><h4 class="title"><a id="appblocker"></a><a class="ulink" href="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/c…" target="_top">@mozilla.org/uriloader/external-protocol-service;1
-</a>, <a class="ulink" href="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/c…" target="_top">@mozilla.org/uriloader/external-helper-app-service;1</a>,
-and <a class="ulink" href="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/c…" target="_top">@mozilla.org/mime;1</a>
-- <a class="ulink" href="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…" target="_top">components/external-app-blocker.js</a></h4></div></div></div><p>
-Due to <a class="link" href="#FirefoxBugs" title="6. Relevant Firefox Bugs">Firefox Bug</a> <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=440892" target="_top">440892</a> allowing Firefox 3.x to automatically launch some
-applications without user intervention, Torbutton had to wrap the three
-components involved in launching external applications to provide user
-confirmation before doing so while Tor is enabled. Since external applications
-do not obey proxy settings, they can be manipulated to automatically connect
-back to arbitrary servers outside of Tor with no user intervention. Fixing
-this issue helps to satisfy Torbutton's <a class="link" href="#proxy">Proxy
-Obedience</a> Requirement.
- </p></div><div class="sect3" title="@mozilla.org/browser/global-history;2 - components/ignore-history.js"><div class="titlepage"><div><div><h4 class="title"><a id="id2696239"></a><a class="ulink" href="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/c…" target="_top">@mozilla.org/browser/global-history;2</a>
-- <a class="ulink" href="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…" target="_top">components/ignore-history.js</a></h4></div></div></div><p>This component was contributed by <a class="ulink" href="http://www.collinjackson.com/" target="_top">Collin Jackson</a> as a method for defeating
-CSS and Javascript-based methods of history disclosure. The global-history
-component is what is used by Firefox to determine if a link was visited or not
-(to apply the appropriate style to the link). By hooking the <a class="ulink" href="https://developer.mozilla.org/en/nsIGlobalHistory2#isVisited.28.29" target="_top">isVisited</a>
-and <a class="ulink" href="https://developer.mozilla.org/en/nsIGlobalHistory2#addURI.28.29" target="_top">addURI</a>
-methods, Torbutton is able to selectively prevent history items from being
-added or being displayed as visited, depending on the Tor state and the user's
-preferences.
-</p><p>
-This component helps satisfy the <a class="link" href="#state">State Separation</a>
-and <a class="link" href="#disk">Disk Avoidance</a> requirements of Torbutton. It
-is only needed for Firefox 3.x. On Firefox 4, we omit this component in favor
-of the <a class="ulink" href="https://developer.mozilla.org/en/CSS/Privacy_and_the_%3avisited_selector" target="_top">built-in
-history protections</a>.
-</p></div><div class="sect3" title="@mozilla.org/browser/livemark-service;2 - components/block-livemarks.js"><div class="titlepage"><div><div><h4 class="title"><a id="livemarks"></a><a class="ulink" href="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/c…" target="_top">@mozilla.org/browser/livemark-service;2</a>
-- <a class="ulink" href="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…" target="_top">components/block-livemarks.js</a></h4></div></div></div><p>
-
-The <a class="ulink" href="http://www.mozilla.com/en-US/firefox/livebookmarks.html" target="_top">livemark</a> service
-is started by a timer that runs 5 seconds after Firefox
-startup. As a result, we cannot simply call the stopUpdateLivemarks() method to
-disable it. We must wrap the component to prevent this start() call from
-firing in the event the browser starts in Tor mode.
-
-</p><p>
-This component helps satisfy the <a class="link" href="#isolation">Network
-Isolation</a> and <a class="link" href="#setpreservation">Anonymity Set
-Preservation</a> requirements.
-</p></div></div><div class="sect2" title="2.2. New Components"><div class="titlepage"><div><div><h3 class="title"><a id="id2690319"></a>2.2. New Components</h3></div></div></div><p>Torbutton creates four new components that are used throughout the
-extension. These components do not hook any interfaces, nor are they used
-anywhere besides Torbutton itself.</p><div class="sect3" title="@torproject.org/cookie-jar-selector;2 - components/cookie-jar-selector.js"><div class="titlepage"><div><div><h4 class="title"><a id="cookiejar"></a><a class="ulink" href="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…" target="_top">@torproject.org/cookie-jar-selector;2
-- components/cookie-jar-selector.js</a></h4></div></div></div><p>The cookie jar selector (also based on code from <a class="ulink" href="http://www.collinjackson.com/" target="_top">Collin
-Jackson</a>) is used by the Torbutton chrome to switch between
-Tor and Non-Tor cookies. It stores an XML representation of the current
-cookie state in memory and/or on disk. When Tor is toggled, it syncs the
-current cookies to this XML store, and then loads the cookies for the other
-state from the XML store.
-</p><p>
-This component helps to address the <a class="link" href="#state">State
-Isolation</a> requirement of Torbutton.
-</p></div><div class="sect3" title="@torproject.org/torbutton-logger;1 - components/torbutton-logger.js"><div class="titlepage"><div><div><h4 class="title"><a id="id2683534"></a><a class="ulink" href="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…" target="_top">@torproject.org/torbutton-logger;1
-- components/torbutton-logger.js</a></h4></div></div></div><p>The torbutton logger component allows on-the-fly redirection of torbutton
-logging messages to either Firefox stderr
-(<span class="command"><strong>extensions.torbutton.logmethod=0</strong></span>), the Javascript error console
-(<span class="command"><strong>extensions.torbutton.logmethod=1</strong></span>), or the DebugLogger extension (if
-available - <span class="command"><strong>extensions.torbutton.logmethod=2</strong></span>). It also allows you to
-change the loglevel on the fly by changing
-<span class="command"><strong>extensions.torbutton.loglevel</strong></span> (1-5, 1 is most verbose).
-</p></div><div class="sect3" title="@torproject.org/content-window-mapper;1 - components/window-mapper.js"><div class="titlepage"><div><div><h4 class="title"><a id="windowmapper"></a><a class="ulink" href="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…" target="_top">@torproject.org/content-window-mapper;1
-- components/window-mapper.js</a></h4></div></div></div><p>Torbutton tags Firefox <a class="ulink" href="https://developer.mozilla.org/en/XUL_Tutorial/Tabboxes" target="_top">tabs</a> with a special variable that indicates the Tor
-state the tab was most recently used under to fetch a page. The problem is
-that for many Firefox events, it is not possible to determine the tab that is
-actually receiving the event. The Torbutton window mapper allows the Torbutton
-chrome and other components to look up a <a class="ulink" href="https://developer.mozilla.org/en/XUL/tabbrowser" target="_top">browser
-tab</a> for a given <a class="ulink" href="https://developer.mozilla.org/en/nsIDOMWindow" target="_top">HTML content
-window</a>. It does this by traversing all windows and all browsers, until it
-finds the browser with the requested <a class="ulink" href="https://developer.mozilla.org/en/XUL/tabbrowser#p-contentWindow" target="_top">contentWindow</a> element. Since the content policy
-and page loading in general can generate hundreds of these lookups, this
-result is cached inside the component.
-</p></div><div class="sect3" title="@torproject.org/crash-observer;1"><div class="titlepage"><div><div><h4 class="title"><a id="crashobserver"></a><a class="ulink" href="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…" target="_top">@torproject.org/crash-observer;1</a></h4></div></div></div><p>
-
-This component detects when Firefox crashes by altering Firefox prefs during
-runtime and checking for the same values at startup. It <a class="ulink" href="https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIPrefService#s…" target="_top">synchronizes
-the preference service</a> to ensure the altered prefs are written to disk
-immediately.
-
- </p></div><div class="sect3" title="@torproject.org/torbutton-ss-blocker;1"><div class="titlepage"><div><div><h4 class="title"><a id="tbsessionstore"></a><a class="ulink" href="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…" target="_top">@torproject.org/torbutton-ss-blocker;1</a></h4></div></div></div><p>
-
-This component subscribes to the Firefox <a class="ulink" href="https://developer.mozilla.org/en/Observer_Notifications#Session_Store" target="_top">sessionstore-state-write</a>
-observer event to filter out URLs from tabs loaded during Tor, to prevent them
-from being written to disk. To do this, it checks the
-<span class="command"><strong>__tb_tor_fetched</strong></span> tag of tab objects before writing them out. If
-the tag is from a blocked Tor state, the tab is not written to disk. This is
-a rather expensive operation that involves potentially very large JSON
-evaluations and object tree traversals, but it preferable to replacing the
-Firefox session store with our own implementation, which is what was done in
-years past.
-
- </p></div><div class="sect3" title="@torproject.org/torRefSpoofer;1"><div class="titlepage"><div><div><h4 class="title"><a id="refspoofer"></a><a class="ulink" href="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…" target="_top">@torproject.org/torRefSpoofer;1</a></h4></div></div></div><p>
-This component handles optional referer spoofing for Torbutton. It implements a
-form of "smart" referer spoofing using <a class="ulink" href="https://developer.mozilla.org/en/Setting_HTTP_request_headers" target="_top">http-on-modify-request</a>
-to modify the Referer header. The code sends the default browser referer
-header only if the destination domain is a suffix of the source, or if the
-source is a suffix of the destination. Otherwise, it sends no referer. This
-strange suffix logic is used as a heuristic: some rare sites on the web block
-requests without proper referer headers, and this logic is an attempt to cater
-to them. Unfortunately, it may not be enough. For example, google.fr will not
-send a referer to google.com using this logic. Hence, it is off by default.
- </p></div><div class="sect3" title="@torproject.org/cssblocker;1 - components/cssblocker.js"><div class="titlepage"><div><div><h4 class="title"><a id="contentpolicy"></a><a class="ulink" href="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…" target="_top">@torproject.org/cssblocker;1
-- components/cssblocker.js</a></h4></div></div></div><p>This is a key component to Torbutton's security measures. When Tor is
-toggled, Javascript is disabled, and pages are instructed to stop loading.
-However, CSS is still able to perform network operations by loading styles for
-onmouseover events and other operations. In addition, favicons can still be
-loaded by the browser. The cssblocker component prevents this by implementing
-and registering an <a class="ulink" href="https://developer.mozilla.org/en/nsIContentPolicy" target="_top">nsIContentPolicy</a>.
-When an nsIContentPolicy is registered, Firefox checks every attempted network
-request against its <a class="ulink" href="https://developer.mozilla.org/en/nsIContentPolicy#shouldLoad()" target="_top">shouldLoad</a>
-member function to determine if the load should proceed. In Torbutton's case,
-the content policy looks up the appropriate browser tab using the <a class="link" href="#windowmapper" title="@torproject.org/content-window-mapper;1 - components/window-mapper.js">window mapper</a>,
-and checks that tab's load tag against the current Tor state. If the tab was
-loaded in a different state than the current state, the fetch is denied.
-Otherwise, it is allowed.</p> This helps to achieve the <a class="link" href="#isolation">Network
-Isolation</a> requirements of Torbutton.
-
-<p>In addition, the content policy also blocks website javascript from
-<a class="ulink" href="http://webdevwonders.com/detecting-firefox-add-ons/" target="_top">querying for
-versions and existence of extension chrome</a> while Tor is enabled, and
-also masks the presence of Torbutton to website javascript while Tor is
-disabled. </p><p>
-
-Finally, some of the work that logically belongs to the content policy is
-instead handled by the <span class="command"><strong>torbutton_http_observer</strong></span> and
-<span class="command"><strong>torbutton_weblistener</strong></span> in <a class="ulink" href="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/chrome/con…" target="_top">torbutton.js</a>. These two objects handle blocking of
-Firefox 3 favicon loads, popups, and full page plugins, which for whatever
-reason are not passed to the Firefox content policy itself (see Firefox Bugs
-<a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=437014" target="_top">437014</a> and
-<a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=401296" target="_top">401296</a>).
-
-</p><p>
-
-This helps to fulfill both the <a class="link" href="#setpreservation">Anonymity Set Preservation</a> and the <a class="link" href="#undiscoverability">Tor Undiscoverability</a> requirements of
-Torbutton.</p></div></div></div><div class="sect1" title="3. Chrome"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="id2681735"></a>3. Chrome</h2></div></div></div><p>The chrome is where all the torbutton graphical elements and windows are
-located. </p><div class="sect2" title="3.1. XUL Windows and Overlays"><div class="titlepage"><div><div><h3 class="title"><a id="id2702019"></a>3.1. XUL Windows and Overlays</h3></div></div></div><p>
-Each window is described as an <a class="ulink" href="http://developer.mozilla.org/en/docs/XUL_Reference" target="_top">XML file</a>, with zero or more Javascript
-files attached. The scope of these Javascript files is their containing
-window. XUL files that add new elements and script to existing Firefox windows
-are called overlays.</p><div class="sect3" title="Browser Overlay - torbutton.xul"><div class="titlepage"><div><div><h4 class="title"><a id="browseroverlay"></a>Browser Overlay - <a class="ulink" href="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/chrome/con…" target="_top">torbutton.xul</a></h4></div></div></div><p>The browser overlay, torbutton.xul, defines the toolbar button, the status
-bar, and events for toggling the button. The overlay code is in <a class="ulink" href="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/chrome/con…" target="_top">chrome/content/torbutton.js</a>.
-It contains event handlers for preference update, shutdown, upgrade, and
-location change events.</p></div><div class="sect3" title="Preferences Window - preferences.xul"><div class="titlepage"><div><div><h4 class="title"><a id="id2704559"></a>Preferences Window - <a class="ulink" href="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/chrome/con…" target="_top">preferences.xul</a></h4></div></div></div><p>The preferences window of course lays out the Torbutton preferences, with
-handlers located in <a class="ulink" href="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/chrome/con…" target="_top">chrome/content/preferences.js</a>.</p></div><div class="sect3" title="Other Windows"><div class="titlepage"><div><div><h4 class="title"><a id="id2669673"></a>Other Windows</h4></div></div></div><p>There are additional windows that describe popups for right clicking on
-the status bar, the toolbutton, and the about page.</p></div></div><div class="sect2" title="3.2. Major Chrome Observers"><div class="titlepage"><div><div><h3 class="title"><a id="id2694797"></a>3.2. Major Chrome Observers</h3></div></div></div><p>
-In addition to the <a class="link" href="#components" title="2. Components">components described
-above</a>, Torbutton also instantiates several observers in the browser
-overlay window. These mostly grew due to scoping convenience, and many should
-probably be relocated into their own components.
- </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><span class="command"><strong>torbutton_window_pref_observer</strong></span><p>
-This is an observer that listens for Torbutton state changes, for the purposes
-of updating the Torbutton button graphic as the Tor state changes.
- </p></li><li class="listitem"><span class="command"><strong>torbutton_unique_pref_observer</strong></span><p>
-
-This is an observer that only runs in one window, called the main window. It
-listens for changes to all of the Torbutton preferences, as well as Torbutton
-controlled Firefox preferences. It is what carries out the toggle path when
-the proxy settings change. When the main window is closed, the
-torbutton_close_window event handler runs to dub a new window the "main
-window".
-
- </p></li><li class="listitem"><span class="command"><strong>tbHistoryListener</strong></span><p>
-The tbHistoryListener exists to prevent client window Javascript from
-interacting with window.history to forcibly navigate a user to a tab session
-history entry from a different Tor state. It also expunges the window.history
-entries during toggle. This listener helps Torbutton
-satisfy the <a class="link" href="#isolation">Network Isolation</a> requirement as
-well as the <a class="link" href="#state">State Separation</a> requirement.
-
- </p></li><li class="listitem"><span class="command"><strong>torbutton_http_observer</strong></span><p>
-
-The torbutton_http_observer performs some of the work that logically belongs
-to the content policy. This handles blocking of
-Firefox 3 favicon loads, which for whatever
-reason are not passed to the Firefox content policy itself (see Firefox Bugs
-<a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=437014" target="_top">437014</a> and
-<a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=401296" target="_top">401296</a>).
-
- </p><p>
-The observer is also responsible for redirecting users to alternate
-search engines when Google presents them with a Captcha, as well as copying
-Google Captcha-related cookies between international Google domains.
- </p></li><li class="listitem"><span class="command"><strong>torbutton_proxyservice</strong></span><p>
-The Torbutton proxy service handles redirecting Torbutton-related update
-checks on addons.mozilla.org through Tor. This is done to help satisfy the
-<a class="link" href="#undiscoverability">Tor Undiscoverability</a> requirement.
- </p></li><li class="listitem"><span class="command"><strong>torbutton_weblistener</strong></span><p>The <a class="ulink" href="https://developer.mozilla.org/en/nsIWebProgressListener#onLocationChange" target="_top">location
-change</a> <a class="ulink" href="https://developer.mozilla.org/en/nsIWebProgress" target="_top">webprogress
-listener</a>, <span class="command"><strong>torbutton_weblistener</strong></span> is one of the most
-important parts of the chrome from a security standpoint. It is a <a class="ulink" href="https://developer.mozilla.org/en/nsIWebProgressListener" target="_top">webprogress
-listener</a> that handles receiving an event every time a page load or
-iframe load occurs. This class eventually calls down to
-<code class="function">torbutton_update_tags()</code> and
-<code class="function">torbutton_hookdoc()</code>, which apply the browser Tor load
-state tags, plugin permissions, and install the Javascript hooks to hook the
-<a class="ulink" href="https://developer.mozilla.org/en/DOM/window.screen" target="_top">window.screen</a>
-object to obfuscate browser and desktop resolution information.
-
-</p></li></ol></div></div></div><div class="sect1" title="4. Toggle Code Path"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="id2696524"></a>4. Toggle Code Path</h2></div></div></div><p>
-
-The act of toggling is connected to <code class="function">torbutton_toggle()</code>
-via the <a class="ulink" href="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/chrome/con…" target="_top">torbutton.xul</a>
-and <a class="ulink" href="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/chrome/con…" target="_top">popup.xul</a>
-overlay files. Most of the work in the toggling process is present in <a class="ulink" href="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/chrome/con…" target="_top">torbutton.js</a>
-
-</p><p>
-
-Toggling is a 3 stage process: Button Click, Proxy Update, and
-Settings Update. These stages are reflected in the prefs
-<span class="command"><strong>extensions.torbutton.tor_enabled</strong></span>,
-<span class="command"><strong>extensions.torbutton.proxies_applied</strong></span>, and
-<span class="command"><strong>extensions.torbutton.settings_applied</strong></span>. The reason for the
-three stage preference update is to ensure immediate enforcement of <a class="link" href="#isolation">Network Isolation</a> via the <a class="link" href="#contentpolicy" title="@torproject.org/cssblocker;1 - components/cssblocker.js">content policy</a>. Since the content window
-javascript runs on a different thread than the chrome javascript, it is
-important to properly convey the stages to the content policy to avoid race
-conditions and leakage, especially with <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=409737" target="_top">Firefox Bug
-409737</a> unfixed. The content policy does not allow any network activity
-whatsoever during this three stage transition.
-
- </p><div class="sect2" title="4.1. Button Click"><div class="titlepage"><div><div><h3 class="title"><a id="id2699452"></a>4.1. Button Click</h3></div></div></div><p>
-
-This is the first step in the toggling process. When the user clicks the
-toggle button or the toolbar, <code class="function">torbutton_toggle()</code> is
-called. This function checks the current Tor status by comparing the current
-proxy settings to the selected Tor settings, and then sets the proxy settings
-to the opposite state, and sets the pref
-<span class="command"><strong>extensions.torbutton.tor_enabled</strong></span> to reflect the new state.
-It is this proxy pref update that gives notification via the <a class="ulink" href="https://developer.mozilla.org/en/NsIPrefBranch2#addObserver.28.29" target="_top">pref
-observer</a>
-<span class="command"><strong>torbutton_unique_pref_observer</strong></span> to perform the rest of the
-toggle.
-
- </p></div><div class="sect2" title="4.2. Proxy Update"><div class="titlepage"><div><div><h3 class="title"><a id="id2697978"></a>4.2. Proxy Update</h3></div></div></div><p>
-
-When Torbutton receives any proxy change notifications via its
-<span class="command"><strong>torbutton_unique_pref_observer</strong></span>, it calls
-<code class="function">torbutton_set_status()</code> which checks against the Tor
-settings to see if the Tor proxy settings match the current settings. If so,
-it calls <code class="function">torbutton_update_status()</code>, which determines if
-the Tor state has actually changed, and sets
-<span class="command"><strong>extensions.torbutton.proxies_applied</strong></span> to the appropriate Tor
-state value, and ensures that
-<span class="command"><strong>extensions.torbutton.tor_enabled</strong></span> is also set to the correct
-value. This is decoupled from the button click functionality via the pref
-observer so that other addons (such as SwitchProxy) can switch the proxy
-settings between multiple proxies.
-
- </p></div><div class="sect2" title="4.3. Settings Update"><div class="titlepage"><div><div><h3 class="title"><a id="id2697015"></a>4.3. Settings Update</h3></div></div></div><p>
-
-The next stage is also handled by
-<code class="function">torbutton_update_status()</code>. This function sets scores of
-Firefox preferences, saving the original values to prefs under
-<span class="command"><strong>extensions.torbutton.saved.*</strong></span>, and performs the <a class="link" href="#cookiejar" title="@torproject.org/cookie-jar-selector;2 - components/cookie-jar-selector.js">cookie jarring</a>, state clearing (such as window.name
-and DOM storage), and <a class="link" href="#preferences" title="4.4. Firefox preferences touched during Toggle">preference
-toggling</a>. At the
-end of its work, it sets
-<span class="command"><strong>extensions.torbutton.settings_applied</strong></span>, which signifies the
-completion of the toggle operation to the <a class="link" href="#contentpolicy" title="@torproject.org/cssblocker;1 - components/cssblocker.js">content policy</a>.
-
- </p></div><div class="sect2" title="4.4. Firefox preferences touched during Toggle"><div class="titlepage"><div><div><h3 class="title"><a id="preferences"></a>4.4. Firefox preferences touched during Toggle</h3></div></div></div><p>
-There are also a number of Firefox preferences set in
-<code class="function">torbutton_update_status()</code> that aren't governed by any
-Torbutton setting. These are:
-</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><a class="ulink" href="http://kb.mozillazine.org/Network.security.ports.banned" target="_top">network.security.ports.banned</a><p>
-Torbutton sets this setting to add ports 8123, 8118, 9050 and 9051 (which it
-reads from <span class="command"><strong>extensions.torbutton.banned_ports</strong></span>) to the list
-of ports Firefox is forbidden to access. These ports are Polipo, Privoxy, Tor,
-and the Tor control port, respectively. This is set for both Tor and Non-Tor
-usage, and prevents websites from attempting to do http fetches from these
-ports to see if they are open, which addresses the <a class="link" href="#undiscoverability">Tor Undiscoverability</a> requirement.
- </p></li><li class="listitem"><a class="ulink" href="http://kb.mozillazine.org/Browser.send_pings" target="_top">browser.send_pings</a><p>
-This setting is currently always disabled. If anyone ever complains saying
-that they *want* their browser to be able to send ping notifications to a
-page or arbitrary link, I'll make this a pref or Tor-only. But I'm not holding
-my breath. I haven't checked if the content policy is called for pings, but if
-not, this setting helps with meeting the <a class="link" href="#isolation">Network
-Isolation</a> requirement.
- </p></li><li class="listitem"><a class="ulink" href="http://kb.mozillazine.org/Browser.safebrowsing.remoteLookups" target="_top">browser.safebrowsing.remoteLookups</a><p>
-Likewise for this setting. I find it hard to imagine anyone who wants to ask
-Google in real time if each URL they visit is safe, especially when the list
-of unsafe URLs is downloaded anyway. This helps fulfill the <a class="link" href="#disk">Disk Avoidance</a> requirement, by preventing your entire
-browsing history from ending up on Google's disks.
- </p></li><li class="listitem"><a class="ulink" href="http://kb.mozillazine.org/Browser.safebrowsing.enabled" target="_top">browser.safebrowsing.enabled</a><p>
-Safebrowsing does <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=360387" target="_top">unauthenticated
-updates under Firefox 2</a>, so it is disabled during Tor usage.
-This helps fulfill the <a class="link" href="#updates">Update
-Safety</a> requirement. Firefox 3 has the fix for that bug, and so
-safebrowsing updates are enabled during Tor usage.
- </p></li><li class="listitem"><a class="ulink" href="http://kb.mozillazine.org/Network.protocol-handler.warn-external.%28protoco…" target="_top">network.protocol-handler.warn-external.(protocol)</a><p>
-If Tor is enabled, we need to prevent random external applications from
-launching without at least warning the user. This group of settings only
-partially accomplishes this, however. Applications can still be launched via
-plugins. The mechanisms for handling this are described under the "Disable
-Plugins During Tor Usage" preference. This helps fulfill the <a class="link" href="#proxy">Proxy Obedience</a> requirement, by preventing external
-applications from accessing network resources at the command of Tor-fetched
-pages. Unfortunately, due to <a class="link" href="#FirefoxBugs" title="6. Relevant Firefox Bugs">Firefox Bug</a>
-<a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=440892" target="_top">440892</a>,
-these prefs are no longer obeyed. They are set still anyway out of respect for
-the dead.
- </p></li><li class="listitem"><a class="ulink" href="http://kb.mozillazine.org/Browser.sessionstore.max_tabs_undo" target="_top">browser.sessionstore.max_tabs_undo</a><p>
-
-To help satisfy the Torbutton <a class="link" href="#state">State Separation</a>
-and <a class="link" href="#isolation">Network Isolation</a> requirements,
-Torbutton needs to purge the Undo Tab history on toggle to prevent repeat
-"Undo Close" operations from accidentally restoring tabs from a different Tor
-State. This purge is accomplished by setting this preference to 0 and then
-restoring it to the previous user value upon toggle.
-
- </p></li><li class="listitem"><span class="command"><strong>security.enable_ssl2</strong></span> or <a class="ulink" href="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/i…" target="_top">nsIDOMCrypto::logout()</a><p>
-TLS Session IDs can persist for an indefinite duration, providing an
-identifier that is sent to TLS sites that can be used to link activity. This
-is particularly troublesome now that we have certificate verification in place
-in Firefox 3: The OCSP server can use this Session ID to build a history of
-TLS sites someone visits, and also correlate their activity as users move from
-network to network (such as home to work to coffee shop, etc), inside and
-outside of Tor. To handle this and to help satisfy our <a class="link" href="#state">State Separation Requirement</a>, we call the logout()
-function of nsIDOMCrypto. Since this may be absent, or may fail, we fall back
-to toggling
-<span class="command"><strong>security.enable_ssl2</strong></span>, which clears the SSL Session ID
-cache via the pref observer at <a class="ulink" href="http://mxr.mozilla.org/security/source/security/manager/ssl/src/nsNSSCompon…" target="_top">nsNSSComponent.cpp</a>.
- </p></li><li class="listitem"><span class="command"><strong>security.OCSP.enabled</strong></span><p>
-Similarly, we toggle <span class="command"><strong>security.OCSP.enabled</strong></span>, which clears the OCSP certificate
-validation cache via the pref observer at <a class="ulink" href="http://mxr.mozilla.org/security/source/security/manager/ssl/src/nsNSSCompon…" target="_top">nsNSSComponent.cpp</a>.
-In this way, exit nodes will not be able to fingerprint you
-based the fact that non-Tor OCSP lookups were obviously previously cached.
-To handle this and to help satisfy our <a class="link" href="#state">State Separation Requirement</a>,
- </p></li><li class="listitem"><span class="command"><strong><a class="ulink" href="http://kb.mozillazine.org/Updating_extensions#Disabling_update_checks_for_i…" target="_top">extensions.e0204bd5-9d31-402b-a99d-a6aa8ffebdca.getAddons.cache.enabled</a></strong></span><p>
-We permanently disable addon usage statistic reporting to the
-addons.mozilla.org statistics engine. These statistics send version
-information about Torbutton users via non-Tor, allowing their Tor use to be
-uncovered. Disabling this reporting helps Torbutton to satisfy its <a class="link" href="#undiscoverability">Tor Undiscoverability</a> requirement.
-
- </p></li><li class="listitem"><span class="command"><strong><a class="ulink" href="http://www.mozilla.com/en-US/firefox/geolocation/" target="_top">geo.enabled</a></strong></span><p>
-
-Torbutton disables Geolocation support in Firefox 3.5 and above whenever tor
-is enabled. This helps Torbutton maintain its
-<a class="link" href="#location">Location Neutrality</a> requirement.
-While Firefox does prompt before divulging geolocational information,
-the assumption is that Tor users will never want to give their
-location away during Tor usage, and even allowing websites to prompt
-them to do so will only cause confusion and accidents to happen. Moreover,
-just because users may approve a site to know their location in non-Tor mode
-does not mean they want it divulged during Tor mode.
-
- </p></li><li class="listitem"><span class="command"><strong><a class="ulink" href="http://kb.mozillazine.org/Browser.zoom.siteSpecific" target="_top">browser.zoom.siteSpecific</a></strong></span><p>
-
-Firefox actually remembers your zoom settings for certain sites. CSS
-and Javascript rule can use this to recognize previous visitors to a site.
-This helps Torbutton fulfill its <a class="link" href="#state">State Separation</a>
-requirement.
-
- </p></li><li class="listitem"><span class="command"><strong><a class="ulink" href="https://developer.mozilla.org/en/controlling_dns_prefetching" target="_top">network.dns.disablePrefetch</a></strong></span><p>
-
-Firefox 3.5 and above implement prefetching of DNS resolution for hostnames in
-links on a page to decrease page load latency. While Firefox does typically
-disable this behavior when proxies are enabled, we set this pref for added
-safety during Tor usage. Additionally, to prevent Tor-loaded tabs from having
-their links prefetched after a toggle to Non-Tor mode occurs,
-we also set the docShell attribute
-<a class="ulink" href="http://www.oxymoronical.com/experiments/apidocs/interface/nsIDocShell" target="_top">
-allowDNSPrefetch</a> to false on Tor loaded tabs. This happens in the same
-positions in the code as those for disabling plugins via the allowPlugins
-docShell attribute. This helps Torbutton fulfill its <a class="link" href="#isolation">Network Isolation</a> requirement.
-
- </p></li><li class="listitem"><span class="command"><strong><a class="ulink" href="http://kb.mozillazine.org/Browser.cache.offline.enable" target="_top">browser.cache.offline.enable</a></strong></span><p>
-
-Firefox has the ability to store web applications in a special cache to allow
-them to continue to operate while the user is offline. Since this subsystem
-is actually different than the normal disk cache, it must be dealt with
-separately. Thus, Torbutton sets this preference to false whenever Tor is
-enabled. This helps Torbutton fulfill its <a class="link" href="#disk">Disk
-Avoidance</a> and <a class="link" href="#state">State Separation</a>
-requirements.
-
- </p></li></ol></div></div></div><div class="sect1" title="5. Description of Options"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="id2702702"></a>5. Description of Options</h2></div></div></div><p>This section provides a detailed description of Torbutton's options. Each
-option is presented as the string from the preferences window, a summary, the
-preferences it touches, and the effect this has on the components, chrome, and
-browser properties.</p><div class="sect2" title="5.1. Proxy Settings"><div class="titlepage"><div><div><h3 class="title"><a id="id2704948"></a>5.1. Proxy Settings</h3></div></div></div><div class="sect3" title="Test Settings"><div class="titlepage"><div><div><h4 class="title"><a id="id2683681"></a>Test Settings</h4></div></div></div><p>
-This button under the Proxy Settings tab provides a way to verify that the
-proxy settings are correct, and actually do route through the Tor network. It
-performs this check by issuing an <a class="ulink" href="http://developer.mozilla.org/en/docs/XMLHttpRequest" target="_top">XMLHTTPRequest</a>
-for <a class="ulink" href="https://check.torproject.org/?TorButton=True" target="_top">https://check.torproject.org/?Torbutton=True</a>.
-This is a special page that returns very simple, yet well-formed XHTML that
-Torbutton can easily inspect for a hidden link with an id of
-<span class="command"><strong>TorCheckResult</strong></span> and a target of <span class="command"><strong>success</strong></span>
-or <span class="command"><strong>failure</strong></span> to indicate if the
-user hit the page from a Tor IP, a non-Tor IP. This check is handled in
-<code class="function">torbutton_test_settings()</code> in <a class="ulink" href="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/chrome/con…" target="_top">torbutton.js</a>.
-Presenting the results to the user is handled by the <a class="ulink" href="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/chrome/con…" target="_top">preferences
-window</a>
-callback <code class="function">torbutton_prefs_test_settings()</code> in <a class="ulink" href="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/chrome/con…" target="_top">preferences.js</a>.
-
- </p></div></div><div class="sect2" title="5.2. Dynamic Content Settings"><div class="titlepage"><div><div><h3 class="title"><a id="id2686645"></a>5.2. Dynamic Content Settings</h3></div></div></div><div class="sect3" title="Disable plugins on Tor Usage (crucial)"><div class="titlepage"><div><div><h4 class="title"><a id="plugins"></a>Disable plugins on Tor Usage (crucial)</h4></div></div></div><p>Option: <span class="command"><strong>extensions.torbutton.no_tor_plugins</strong></span></p><p>Java and plugins <a class="ulink" href="http://java.sun.com/j2se/1.5.0/docs/api/java/net/class-use/NetworkInterface…" target="_top">can query</a> the <a class="ulink" href="http://www.rgagnon.com/javadetails/java-0095.html" target="_top">local IP
-address</a> and report it back to the
-remote site. They can also <a class="ulink" href="http://decloak.net" target="_top">bypass proxy settings</a> and directly connect to a
-remote site without Tor. Every browser plugin we have tested with Firefox has
-some form of network capability, and every one ignores proxy settings or worse - only
-partially obeys them. This includes but is not limited to:
-QuickTime, Windows Media Player, RealPlayer, mplayerplug-in, AcroRead, and
-Flash.
-
- </p><p>
-Enabling this preference causes the above mentioned Torbutton chrome web progress
- listener <span class="command"><strong>torbutton_weblistener</strong></span> to disable Java via <span class="command"><strong>security.enable_java</strong></span> and to disable
- plugins via the browser <a class="ulink" href="https://developer.mozilla.org/en/XUL%3aProperty%3adocShell" target="_top">docShell</a>
- attribute <span class="command"><strong>allowPlugins</strong></span>. These flags are set every time a new window is
- created (<code class="function">torbutton_tag_new_browser()</code>), every time a web
-load
-event occurs
- (<code class="function">torbutton_update_tags()</code>), and every time the tor state is changed
- (<code class="function">torbutton_update_status()</code>). As a backup measure, plugins are also
- prevented from loading by the content policy in <a class="ulink" href="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…" target="_top">@torproject.org/cssblocker;1</a> if Tor is
- enabled and this option is set.
- </p><p>All of this turns out to be insufficient if the user directly clicks
-on a plugin-handled mime-type. <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=401296" target="_top">In this case</a>,
-the browser decides that maybe it should ignore all these other settings and
-load the plugin anyways, because maybe the user really did want to load it
-(never mind this same load-style could happen automatically with meta-refresh
-or any number of other ways..). To handle these cases, Torbutton stores a list
-of plugin-handled mime-types, and sets the pref
-<span class="command"><strong>plugin.disable_full_page_plugin_for_types</strong></span> to this list.
-Additionally, (since nothing can be assumed when relying on Firefox
-preferences and internals) if it detects a load of one of them from the web
-progress listener, it cancels the request, tells the associated DOMWindow to
-stop loading, clears the document, AND throws an exception. Anything short of
-all this and the plugin managed to find some way to load.
- </p><p>
- All this could be avoided, of course, if Firefox would either <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=401296" target="_top">obey
- allowPlugins</a> for directly visited URLs, or notify its content policy for such
- loads either <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=309524" target="_top">via</a> <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=380556" target="_top">shouldProcess</a> or shouldLoad. The fact that it does not is
- not very encouraging.
- </p><p>
-
-Since most plugins completely ignore browser proxy settings, the actions
-performed by this setting are crucial to satisfying the <a class="link" href="#proxy">Proxy Obedience</a> requirement.
-
- </p></div><div class="sect3" title="Isolate Dynamic Content to Tor State (crucial)"><div class="titlepage"><div><div><h4 class="title"><a id="id2688604"></a>Isolate Dynamic Content to Tor State (crucial)</h4></div></div></div><p>Option: <span class="command"><strong>extensions.torbutton.isolate_content</strong></span></p><p>Enabling this preference is what enables the <a class="ulink" href="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…" target="_top">@torproject.org/cssblocker;1</a> content policy
-mentioned above, and causes it to block content load attempts in pages an
-opposite Tor state from the current state. Freshly loaded <a class="ulink" href="https://developer.mozilla.org/en/XUL/tabbrowser" target="_top">browser
-tabs</a> are tagged
-with a <span class="command"><strong>__tb_load_state</strong></span> member in
-<code class="function">torbutton_update_tags()</code> and this
-value is compared against the current tor state in the content policy.</p><p>It also kills all Javascript in each page loaded under that state by
-toggling the <span class="command"><strong>allowJavascript</strong></span> <a class="ulink" href="https://developer.mozilla.org/en/XUL%3aProperty%3adocShell" target="_top">docShell</a> property, and issues a
-<a class="ulink" href="https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIWebNavigation…" target="_top">webNavigation.stop(webNavigation.STOP_ALL)</a> to each browser tab (the
-equivalent of hitting the STOP button).</p><p>
-
-Unfortunately, <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=409737" target="_top">Firefox bug
-409737</a> prevents <span class="command"><strong>docShell.allowJavascript</strong></span> from killing
-all event handlers, and event handlers registered with <a class="ulink" href="http://developer.mozilla.org/en/docs/DOM:element.addEventListener" target="_top">addEventListener()</a>
-are still able to execute. The <a class="link" href="#contentpolicy" title="@torproject.org/cssblocker;1 - components/cssblocker.js">Torbutton Content
-Policy</a> should prevent such code from performing network activity within
-the current tab, but activity that happens via a popup window or via a
-Javascript redirect can still slip by. For this reason, Torbutton blocks
-popups by checking for a valid <a class="ulink" href="http://developer.mozilla.org/en/docs/DOM:window.opener" target="_top">window.opener</a>
-attribute in <code class="function">torbutton_check_progress()</code>. If the window
-has an opener from a different Tor state, its load is blocked. The content
-policy also takes similar action to prevent Javascript redirects. This also
-has the side effect/feature of preventing the user from following any links
-from a page loaded in an opposite Tor state.
-
-</p><p>
-This setting is responsible for satisfying the <a class="link" href="#isolation">Network Isolation</a> requirement.
-</p></div><div class="sect3" title="Hook Dangerous Javascript"><div class="titlepage"><div><div><h4 class="title"><a id="jshooks"></a>Hook Dangerous Javascript</h4></div></div></div><p>Option: <span class="command"><strong>extensions.torbutton.kill_bad_js</strong></span></p><p>This setting enables injection of the <a class="ulink" href="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/chrome/con…" target="_top">Javascript
-hooking code</a>. This is done in the chrome in
-<code class="function">torbutton_hookdoc()</code>, which is called ultimately by both the
-<a class="ulink" href="https://developer.mozilla.org/en/nsIWebProgressListener" target="_top">webprogress
-listener</a> <span class="command"><strong>torbutton_weblistener</strong></span> and the <a class="link" href="#contentpolicy" title="@torproject.org/cssblocker;1 - components/cssblocker.js">content policy</a> (the latter being a hack to handle
-javascript: urls).
-
-In the Firefox 2 days, this option did a lot more than
-it does now. It used to be responsible for timezone and improved useragent
-spoofing, and history object cloaking. However, now it only provides
-obfuscation of the <a class="ulink" href="https://developer.mozilla.org/en/DOM/window.screen" target="_top">window.screen</a>
-object to mask your browser and desktop resolution.
-The resolution hooks
-effectively make the Firefox browser window appear to websites as if the renderable area
-takes up the entire desktop, has no toolbar or other GUI element space, and
-the desktop itself has no toolbars.
-These hooks drastically reduce the amount of information available to do <a class="link" href="#fingerprinting">anonymity set reduction attacks</a> and help to
-meet the <a class="link" href="#setpreservation">Anonymity Set Preservation</a>
-requirements. Unfortunately, Gregory Fleischer discovered it is still possible
-to retrieve the original screen values by using <a class="ulink" href="http://pseudo-flaw.net/tor/torbutton/unmask-sandbox-xpcnativewrapper.html" target="_top">XPCNativeWrapper</a>
-or <a class="ulink" href="http://pseudo-flaw.net/tor/torbutton/unmask-components-lookupmethod.html" target="_top">Components.lookupMethod</a>.
-We are still looking for a workaround as of Torbutton 1.3.2.
-
-
-
-
-</p></div><div class="sect3" title="Resize windows to multiples of 50px during Tor usage (recommended)"><div class="titlepage"><div><div><h4 class="title"><a id="id2663307"></a>Resize windows to multiples of 50px during Tor usage (recommended)</h4></div></div></div><p>Option: <span class="command"><strong>extensions.torbutton.resize_windows</strong></span></p><p>
-
-This option drastically cuts down on the number of distinct anonymity sets
-that divide the Tor web userbase. Without this setting, the dimensions for a
-typical browser window range from 600-1200 horizontal pixels and 400-1000
-vertical pixels, or about 600x600 = 360000 different sets. Resizing the
-browser window to multiples of 50 on each side reduces the number of sets by
-50^2, bringing the total number of sets to 144. Of course, the distribution
-among these sets are not uniform, but scaling by 50 will improve the situation
-due to this non-uniformity for users in the less common resolutions.
-Obviously the ideal situation would be to lie entirely about the browser
-window size, but this will likely cause all sorts of rendering issues, and is
-also not implementable in a foolproof way from extension land.
-
-</p><p>
-
-The implementation of this setting is spread across a couple of different
-locations in the Torbutton javascript <a class="link" href="#browseroverlay" title="Browser Overlay - torbutton.xul">browser
-overlay</a>. Since resizing minimized windows causes them to be restored,
-and since maximized windows remember their previous size to the pixel, windows
-must be resized before every document load (at the time of browser tagging)
-via <code class="function">torbutton_check_round()</code>, called by
-<code class="function">torbutton_update_tags()</code>. To prevent drift, the extension
-tracks the original values of the windows and uses this to perform the
-rounding on document load. In addition, to prevent the user from resizing a
-window to a non-50px multiple, a resize listener
-(<code class="function">torbutton_do_resize()</code>) is installed on every new browser
-window to record the new size and round it to a 50px multiple while Tor is
-enabled. In all cases, the browser's contentWindow.innerWidth and innerHeight
-are set. This ensures that there is no discrepancy between the 50 pixel cutoff
-and the actual renderable area of the browser (so that it is not possible to
-infer toolbar size/presence by the distance to the nearest 50 pixel roundoff).
-
-</p><p>
-This setting helps to meet the <a class="link" href="#setpreservation">Anonymity Set Preservation</a> requirements.
-</p></div><div class="sect3" title="Disable Search Suggestions during Tor (recommended)"><div class="titlepage"><div><div><h4 class="title"><a id="id2663391"></a>Disable Search Suggestions during Tor (recommended)</h4></div></div></div><p>Option: <span class="command"><strong>extensions.torbutton.no_search</strong></span></p><p>
-This setting causes Torbutton to disable <a class="ulink" href="http://kb.mozillazine.org/Browser.search.suggest.enabled" target="_top"><span class="command"><strong>browser.search.suggest.enabled</strong></span></a>
-during Tor usage.
-This governs if you get Google search suggestions during Tor
-usage. Your Google cookie is transmitted with google search suggestions, hence
-this is recommended to be disabled.
-
-</p><p>
-While this setting doesn't satisfy any Torbutton requirements, the fact that
-cookies are transmitted for partially typed queries does not seem desirable
-for Tor usage.
-</p></div><div class="sect3" title="Disable Updates During Tor"><div class="titlepage"><div><div><h4 class="title"><a id="id2663430"></a>Disable Updates During Tor</h4></div></div></div><p>Option: <span class="command"><strong>extensions.torbutton.no_updates</strong></span></p><p>This setting causes Torbutton to disable the four <a class="ulink" href="http://wiki.mozilla.org/Update:Users/Checking_For_Updates#Preference_Contro…" target="_top">Firefox
-update settings</a> during Tor
- usage: <span class="command"><strong>extensions.update.enabled</strong></span>,
-<span class="command"><strong>app.update.enabled</strong></span>,
- <span class="command"><strong>app.update.auto</strong></span>, and
-<span class="command"><strong>browser.search.update</strong></span>. These prevent the
- browser from updating extensions, checking for Firefox upgrades, and
- checking for search plugin updates while Tor is enabled.
- </p><p>
-This setting satisfies the <a class="link" href="#updates">Update Safety</a> requirement.
-</p></div><div class="sect3" title="Redirect Torbutton Updates Via Tor (recommended)"><div class="titlepage"><div><div><h4 class="title"><a id="id2663492"></a>Redirect Torbutton Updates Via Tor (recommended)</h4></div></div></div><p>Option: <span class="command"><strong>extensions.torbutton.update_torbutton_via_tor</strong></span></p><p>This setting causes Torbutton to install an
-
-<a class="ulink" href="https://developer.mozilla.org/en/nsIProtocolProxyFilter" target="_top">nsIProtocolProxyFilter</a>
-in order to redirect all version update checks and Torbutton update downloads
-via Tor, regardless of if Tor is enabled or not. This was done both to address
-concerns about data retention done by <a class="ulink" href="https://www.addons.mozilla.org" target="_top">addons.mozilla.org</a>, as well as to
-help censored users meet the <a class="link" href="#undiscoverability">Tor
-Undiscoverability</a> requirement.
-
- </p></div><div class="sect3" title="Disable livemarks updates during Tor usage (recommended)"><div class="titlepage"><div><div><h4 class="title"><a id="id2663536"></a>Disable livemarks updates during Tor usage (recommended)</h4></div></div></div><p>Option:
- </p><table border="0" summary="Simple list" class="simplelist"><tr><td><span class="command"><strong>extensions.torbutton.disable_livemarks</strong></span></td></tr></table><p>
- </p><p>
-
-This option causes Torbutton to prevent Firefox from loading <a class="ulink" href="http://www.mozilla.com/firefox/livebookmarks.html" target="_top">Livemarks</a> during
-Tor usage. Because people often have very personalized Livemarks (such as RSS
-feeds of Wikipedia articles they maintain, etc). This is accomplished both by
-<a class="link" href="#livemarks" title="@mozilla.org/browser/livemark-service;2 - components/block-livemarks.js">wrapping the livemark-service component</a> and
-by calling stopUpdateLivemarks() on the <a class="ulink" href="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/c…" target="_top">Livemark
-service</a> when Tor is enabled.
-
-</p><p>
-This helps satisfy the <a class="link" href="#isolation">Network
-Isolation</a> and <a class="link" href="#setpreservation">Anonymity Set
-Preservation</a> requirements.
-</p></div><div class="sect3" title="Block Tor/Non-Tor access to network from file:// urls (recommended)"><div class="titlepage"><div><div><h4 class="title"><a id="id2663607"></a>Block Tor/Non-Tor access to network from file:// urls (recommended)</h4></div></div></div><p>Options:
- </p><table border="0" summary="Simple list" class="simplelist"><tr><td><span class="command"><strong>extensions.torbutton.block_tor_file_net</strong></span></td></tr><tr><td><span class="command"><strong>extensions.torbutton.block_nontor_file_net</strong></span></td></tr></table><p>
- </p><p>
-
-These settings prevent file urls from performing network operations during the
-respective Tor states. Firefox 2's implementation of same origin policy allows
-file urls to read and <a class="ulink" href="http://www.gnucitizen.org/blog/content-disposition-hacking/" target="_top">submit
-arbitrary files from the local filesystem</a> to arbitrary websites. To
-make matters worse, the 'Content-Disposition' header can be injected
-arbitrarily by exit nodes to trick users into running arbitrary html files in
-the local context. These preferences cause the <a class="link" href="#contentpolicy" title="@torproject.org/cssblocker;1 - components/cssblocker.js">content policy</a> to block access to any network
-resources from File urls during the appropriate Tor state.
-
-</p><p>
-
-This preference helps to ensure Tor's <a class="link" href="#isolation">Network
-Isolation</a> requirement, by preventing file urls from executing network
-operations in opposite Tor states. Also, allowing pages to submit arbitrary
-files to arbitrary sites just generally seems like a bad idea.
-
-</p></div><div class="sect3" title="Close all Tor/Non-Tor tabs and windows on toggle (optional)"><div class="titlepage"><div><div><h4 class="title"><a id="id2663679"></a>Close all Tor/Non-Tor tabs and windows on toggle (optional)</h4></div></div></div><p>Options:
- </p><table border="0" summary="Simple list" class="simplelist"><tr><td><span class="command"><strong>extensions.torbutton.close_nontor</strong></span></td></tr><tr><td><span class="command"><strong>extensions.torbutton.close_tor</strong></span></td></tr></table><p>
- </p><p>
-
-These settings cause Torbutton to enumerate through all windows and close all
-tabs in each window for the appropriate Tor state. This code can be found in
-<code class="function">torbutton_update_status()</code>. The main reason these settings
-exist is as a backup mechanism in the event of any Javascript or content policy
-leaks due to <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=409737" target="_top">Firefox Bug
-409737</a>. Torbutton currently tries to block all Javascript network
-activity via the content policy, but until that bug is fixed, there is some
-risk that there are alternate ways to bypass the policy. This option is
-available as an extra assurance of <a class="link" href="#isolation">Network
-Isolation</a> for those who would like to be sure that when Tor is toggled
-all page activity has ceased. It also serves as a potential future workaround
-in the event a content policy failure is discovered, and provides an additional
-level of protection for the <a class="link" href="#disk">Disk Avoidance</a>
-protection so that browser state is not sitting around waiting to be swapped
-out longer than necessary.
-
-</p><p>
-While this setting doesn't satisfy any Torbutton requirements, the fact that
-cookies are transmitted for partially typed queries does not seem desirable
-for Tor usage.
-</p></div></div><div class="sect2" title="5.3. History and Forms Settings"><div class="titlepage"><div><div><h3 class="title"><a id="id2705261"></a>5.3. History and Forms Settings</h3></div></div></div><div class="sect3" title="Isolate Access to History navigation to Tor state (crucial)"><div class="titlepage"><div><div><h4 class="title"><a id="id2705267"></a>Isolate Access to History navigation to Tor state (crucial)</h4></div></div></div><p>Option: <span class="command"><strong>extensions.torbutton.block_js_history</strong></span></p><p>
-This setting determines if Torbutton installs an <a class="ulink" href="http://www.oxymoronical.com/experiments/apidocs/interface/nsISHistoryListen…" target="_top">nsISHistoryListener</a>
-attached to the <a class="ulink" href="http://www.oxymoronical.com/experiments/apidocs/interface/nsISHistory" target="_top">sessionHistory</a> of
-of each browser's <a class="ulink" href="https://developer.mozilla.org/en/XUL%3aProperty%3awebNavigation" target="_top">webNavigatator</a>.
-The nsIShistoryListener is instantiated with a reference to the containing
-browser window and blocks the back, forward, and reload buttons on the browser
-navigation bar when Tor is in an opposite state than the one to load the
-current tab. In addition, Tor clears the session history during a new document
-load if this setting is enabled.
-
- </p><p>
-
-This is marked as a crucial setting in part
-because Javascript access to the history object is indistinguishable from
-user clicks, and because
-<a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=409737" target="_top">Firefox Bug
-409737</a> allows javascript to execute in opposite Tor states, javascript
-can issue reloads after Tor toggle to reveal your original IP. Even without
-this bug, however, Javascript is still able to access previous pages in your
-session history that may have been loaded under a different Tor state, to
-attempt to correlate your activity.
-
- </p><p>
-
-This setting helps to fulfill Torbutton's <a class="link" href="#state">State
-Separation</a> and (until Bug 409737 is fixed) <a class="link" href="#isolation">Network Isolation</a>
-requirements.
-
- </p></div><div class="sect3" title="History Access Settings"><div class="titlepage"><div><div><h4 class="title"><a id="id2705344"></a>History Access Settings</h4></div></div></div><p>Options:
- </p><table border="0" summary="Simple list" class="simplelist"><tr><td><span class="command"><strong>extensions.torbutton.block_thread</strong></span></td></tr><tr><td><span class="command"><strong>extensions.torbutton.block_nthread</strong></span></td></tr><tr><td><span class="command"><strong>extensions.torbutton.block_thwrite</strong></span></td></tr><tr><td><span class="command"><strong>extensions.torbutton.block_nthwrite</strong></span></td></tr></table><p>
- </p><p>On Firefox 3.x, these four settings govern the behavior of the <a class="ulink" href="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…" target="_top">components/ignore-history.js</a>
-history blocker component mentioned above. By hooking the browser's view of
-the history itself via the <a class="ulink" href="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/c…" target="_top">@mozilla.org/browser/global-history;2</a>
-and <a class="ulink" href="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/c…" target="_top">@mozilla.org/browser/nav-history-service;1</a>
-components, this mechanism defeats all document-based <a class="ulink" href="http://whattheinternetknowsaboutyou.com/" target="_top">history disclosure
-attacks</a>, including <a class="ulink" href="http://ha.ckers.org/weird/CSS-history.cgi" target="_top">CSS-only attacks</a>.
-
-The component also hooks functions involved in writing history to disk via
-both the <a class="ulink" href="http://developer.mozilla.org/en/docs/Places_migration_guide#History" target="_top">Places
-Database</a> and the older Firefox 2 mechanisms.
-
-</p><p>
-On Firefox 4, Mozilla finally <a class="ulink" href="https://developer.mozilla.org/en/CSS/Privacy_and_the_%3avisited_selector" target="_top">addressed
-these issues</a>, so we can effectively ignore the "read" pair of the
-above prefs. We then only need to link the write prefs to
-<span class="command"><strong>places.history.enabled</strong></span>, which disabled writing to the
-history store while set.
-</p><p>
-This setting helps to satisfy the <a class="link" href="#state">State Separation</a> and <a class="link" href="#disk">Disk Avoidance</a> requirements.
-</p></div><div class="sect3" title="Clear History During Tor Toggle (optional)"><div class="titlepage"><div><div><h4 class="title"><a id="id2705472"></a>Clear History During Tor Toggle (optional)</h4></div></div></div><p>Option: <span class="command"><strong>extensions.torbutton.clear_history</strong></span></p><p>This setting governs if Torbutton calls
-<a class="ulink" href="https://developer.mozilla.org/en/nsIBrowserHistory#removeAllPages.28.29" target="_top">nsIBrowserHistory.removeAllPages</a>
-and <a class="ulink" href="http://www.oxymoronical.com/experiments/apidocs/interface/nsISHistory" target="_top">nsISHistory.PurgeHistory</a>
-for each tab on Tor toggle.</p><p>
-This setting is an optional way to help satisfy the <a class="link" href="#state">State Separation</a> requirement.
-</p></div><div class="sect3" title="Block Password+Form saving during Tor/Non-Tor"><div class="titlepage"><div><div><h4 class="title"><a id="id2705515"></a>Block Password+Form saving during Tor/Non-Tor</h4></div></div></div><p>Options:
- </p><table border="0" summary="Simple list" class="simplelist"><tr><td><span class="command"><strong>extensions.torbutton.block_tforms</strong></span></td></tr><tr><td><span class="command"><strong>extensions.torbutton.block_ntforms</strong></span></td></tr></table><p>
- </p><p>These settings govern if Torbutton disables
-<span class="command"><strong>browser.formfill.enable</strong></span>
-and <span class="command"><strong>signon.rememberSignons</strong></span> during Tor and Non-Tor usage.
-Since form fields can be read at any time by Javascript, this setting is a lot
-more important than it seems.
-</p><p>
-This setting helps to satisfy the <a class="link" href="#state">State Separation</a> and <a class="link" href="#disk">Disk Avoidance</a> requirements.
-</p></div></div><div class="sect2" title="5.4. Cache Settings"><div class="titlepage"><div><div><h3 class="title"><a id="id2705577"></a>5.4. Cache Settings</h3></div></div></div><div class="sect3" title="Block Tor disk cache and clear all cache on Tor Toggle"><div class="titlepage"><div><div><h4 class="title"><a id="id2705582"></a>Block Tor disk cache and clear all cache on Tor Toggle</h4></div></div></div><p>Option: <span class="command"><strong>extensions.torbutton.clear_cache</strong></span>
- </p><p>This option causes Torbutton to call <a class="ulink" href="https://developer.mozilla.org/en/nsICacheService#evictEntries.28.29" target="_top">nsICacheService.evictEntries(0)</a>
-on Tor toggle to remove all entries from the cache. In addition, this setting
-causes Torbutton to set <a class="ulink" href="http://kb.mozillazine.org/Browser.cache.disk.enable" target="_top">browser.cache.disk.enable</a> to false.
-</p><p>
-This setting helps to satisfy the <a class="link" href="#state">State Separation</a> and <a class="link" href="#disk">Disk Avoidance</a> requirements.
-</p></div><div class="sect3" title="Block disk and memory cache during Tor"><div class="titlepage"><div><div><h4 class="title"><a id="id2705632"></a>Block disk and memory cache during Tor</h4></div></div></div><p>Option: <span class="command"><strong>extensions.torbutton.block_cache</strong></span></p><p>This setting
-causes Torbutton to set <a class="ulink" href="http://kb.mozillazine.org/Browser.cache.memory.enable" target="_top">browser.cache.memory.enable</a>,
-<a class="ulink" href="http://kb.mozillazine.org/Browser.cache.disk.enable" target="_top">browser.cache.disk.enable</a> and
-<a class="ulink" href="http://kb.mozillazine.org/Network.http.use-cache" target="_top">network.http.use-cache</a> to false during tor usage.
-</p><p>
-This setting helps to satisfy the <a class="link" href="#state">State Separation</a> and <a class="link" href="#disk">Disk Avoidance</a> requirements.
-</p></div></div><div class="sect2" title="5.5. Cookie and Auth Settings"><div class="titlepage"><div><div><h3 class="title"><a id="id2705686"></a>5.5. Cookie and Auth Settings</h3></div></div></div><div class="sect3" title="Clear Cookies on Tor Toggle"><div class="titlepage"><div><div><h4 class="title"><a id="id2705691"></a>Clear Cookies on Tor Toggle</h4></div></div></div><p>Option: <span class="command"><strong>extensions.torbutton.clear_cookies</strong></span>
- </p><p>
-
-This setting causes Torbutton to call <a class="ulink" href="https://developer.mozilla.org/en/nsICookieManager#removeAll.28.29" target="_top">nsICookieManager.removeAll()</a> on
-every Tor toggle. In addition, this sets <a class="ulink" href="http://kb.mozillazine.org/Network.cookie.lifetimePolicy" target="_top">network.cookie.lifetimePolicy</a>
-to 2 for Tor usage, which causes all cookies to be demoted to session cookies,
-which prevents them from being written to disk.
-
-</p><p>
-This setting helps to satisfy the <a class="link" href="#state">State Separation</a> and <a class="link" href="#disk">Disk Avoidance</a> requirements.
-</p></div><div class="sect3" title="Store Non-Tor cookies in a protected jar"><div class="titlepage"><div><div><h4 class="title"><a id="id2705742"></a>Store Non-Tor cookies in a protected jar</h4></div></div></div><p>Option: <span class="command"><strong>extensions.torbutton.cookie_jars</strong></span>
- </p><p>
-
-This setting causes Torbutton to use <a class="ulink" href="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…" target="_top">@torproject.org/cookie-jar-selector;2</a> to store
-non-tor cookies in a cookie jar during Tor usage, and clear the Tor cookies
-before restoring the jar.
-</p><p>
-This setting also sets <a class="ulink" href="http://kb.mozillazine.org/Network.cookie.lifetimePolicy" target="_top">network.cookie.lifetimePolicy</a>
-to 2 for Tor usage, which causes all cookies to be demoted to session cookies,
-which prevents them from being written to disk.
-
-</p><p>
-This setting helps to satisfy the <a class="link" href="#state">State Separation</a> and <a class="link" href="#disk">Disk Avoidance</a> requirements.
-</p></div><div class="sect3" title="Store both Non-Tor and Tor cookies in a protected jar (dangerous)"><div class="titlepage"><div><div><h4 class="title"><a id="id2705799"></a>Store both Non-Tor and Tor cookies in a protected jar (dangerous)</h4></div></div></div><p>Option: <span class="command"><strong>extensions.torbutton.dual_cookie_jars</strong></span>
- </p><p>
-
-This setting causes Torbutton to use <a class="ulink" href="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…" target="_top">@torproject.org/cookie-jar-selector;2</a> to store
-both Tor and Non-Tor cookies into protected jars.
-</p><p>
-This setting helps to satisfy the <a class="link" href="#state">State Separation</a> requirement.
-</p></div><div class="sect3" title="Manage My Own Cookies (dangerous)"><div class="titlepage"><div><div><h4 class="title"><a id="id2705841"></a>Manage My Own Cookies (dangerous)</h4></div></div></div><p>Options: None</p><p>This setting disables all Torbutton cookie handling by setting the above
-cookie prefs all to false.</p></div><div class="sect3" title="Disable DOM Storage during Tor usage (crucial)"><div class="titlepage"><div><div><h4 class="title"><a id="id2705856"></a>Disable DOM Storage during Tor usage (crucial)</h4></div></div></div><div class="sect3" title="Do not write Tor/Non-Tor cookies to disk"><div class="titlepage"><div><div><h4 class="title"><a id="id2705859"></a>Do not write Tor/Non-Tor cookies to disk</h4></div></div></div><p>Options:
- </p><table border="0" summary="Simple list" class="simplelist"><tr><td><span class="command"><strong>extensions.torbutton.tor_memory_jar</strong></span></td></tr><tr><td><span class="command"><strong>extensions.torbutton.nontor_memory_jar</strong></span></td></tr></table><p>
- </p><p>
-These settings (contributed by arno) cause Torbutton to set <a class="ulink" href="http://kb.mozillazine.org/Network.cookie.lifetimePolicy" target="_top">network.cookie.lifetimePolicy</a>
-to 2 during the appropriate Tor state, and to store cookies acquired in that
-state into a Javascript
-<a class="ulink" href="http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Guide:Processing_X…" target="_top">E4X</a>
-object as opposed to writing them to disk.
-</p><p>
-This allows Torbutton to provide an option to preserve a user's
-cookies while still satisfying the <a class="link" href="#disk">Disk Avoidance</a>
-requirement.
-</p></div><p>Option: <span class="command"><strong>extensions.torbutton.disable_domstorage</strong></span>
- </p><p>
-
-This setting causes Torbutton to toggle <span class="command"><strong>dom.storage.enabled</strong></span> during Tor
-usage to prevent
-<a class="ulink" href="http://developer.mozilla.org/en/docs/DOM:Storage" target="_top">DOM Storage</a> from
- being used to store persistent information across Tor states.</p><p>
-This setting helps to satisfy the <a class="link" href="#state">State Separation</a> requirement.
-</p></div><div class="sect3" title="Clear HTTP Auth on Tor Toggle (recommended)"><div class="titlepage"><div><div><h4 class="title"><a id="id2705960"></a>Clear HTTP Auth on Tor Toggle (recommended)</h4></div></div></div><p>Option: <span class="command"><strong>extensions.torbutton.clear_http_auth</strong></span>
- </p><p>
-This setting causes Torbutton to call <a class="ulink" href="http://www.oxymoronical.com/experiments/apidocs/interface/nsIHttpAuthManager" target="_top">nsIHttpAuthManager.clearAll()</a>
-every time Tor is toggled.
-</p><p>
-This setting helps to satisfy the <a class="link" href="#state">State Separation</a> requirement.
-</p></div></div><div class="sect2" title="5.6. Startup Settings"><div class="titlepage"><div><div><h3 class="title"><a id="id2705999"></a>5.6. Startup Settings</h3></div></div></div><div class="sect3" title="On Browser Startup, set Tor state to: Tor, Non-Tor"><div class="titlepage"><div><div><h4 class="title"><a id="id2706004"></a>On Browser Startup, set Tor state to: Tor, Non-Tor</h4></div></div></div><p>Options:
- <span class="command"><strong>extensions.torbutton.restore_tor</strong></span>
- </p><p>This option governs what Tor state tor is loaded in to.
-<code class="function">torbutton_set_initial_state()</code> covers the case where the
-browser did not crash, and <code class="function">torbutton_crash_recover()</code>
-covers the case where the <a class="link" href="#crashobserver" title="@torproject.org/crash-observer;1">crash observer</a>
-detected a crash.
-</p><p>
-
-Since the Tor state after a Firefox crash is unknown/indeterminate, this
-setting helps to satisfy the <a class="link" href="#state">State Separation</a>
-requirement in the event of Firefox crashes by ensuring all cookies,
-settings and saved sessions are reloaded from a fixed Tor state.
-
-</p></div><div class="sect3" title="Prevent session store from saving Non-Tor/Tor-loaded tabs"><div class="titlepage"><div><div><h4 class="title"><a id="id2706055"></a>Prevent session store from saving Non-Tor/Tor-loaded tabs</h4></div></div></div><p>Options:
- </p><table border="0" summary="Simple list" class="simplelist"><tr><td><span class="command"><strong>extensions.torbutton.nonontor_sessionstore</strong></span></td></tr><tr><td><span class="command"><strong>extensions.torbutton.notor_sessionstore</strong></span></td></tr></table><p>
- </p><p>If these options are enabled, the <a class="link" href="#tbsessionstore" title="@torproject.org/torbutton-ss-blocker;1">tbSessionStore.js</a> component uses the session
-store listeners to filter out the appropriate tabs before writing the session
-store data to disk.
-</p><p>
-This setting helps to satisfy the <a class="link" href="#disk">Disk Avoidance</a>
-requirement, and also helps to satisfy the <a class="link" href="#state">State Separation</a> requirement in the event of Firefox
-crashes.
-
-</p></div></div><div class="sect2" title="5.7. Shutdown Settings"><div class="titlepage"><div><div><h3 class="title"><a id="id2706113"></a>5.7. Shutdown Settings</h3></div></div></div><div class="sect3" title="Clear cookies on Tor/Non-Tor shutdown"><div class="titlepage"><div><div><h4 class="title"><a id="id2706119"></a>Clear cookies on Tor/Non-Tor shutdown</h4></div></div></div><p>Option: <span class="command"><strong>extensions.torbutton.shutdown_method</strong></span>
- </p><p> This option variable can actually take 3 values: 0, 1, and 2. 0 means no
-cookie clearing, 1 means clear only during Tor-enabled shutdown, and 2 means
-clear for both Tor and Non-Tor shutdown. When set to 1 or 2, Torbutton listens
-for the <a class="ulink" href="http://developer.mozilla.org/en/docs/Observer_Notifications#Application_shu…" target="_top">quit-application-granted</a> event in
-<a class="link" href="#crashobserver" title="@torproject.org/crash-observer;1">crash-observer.js</a> and use <a class="ulink" href="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/components…" target="_top">@torproject.org/cookie-jar-selector;2</a>
-to clear out all cookies and all cookie jars upon shutdown.
-</p><p>
-This setting helps to satisfy the <a class="link" href="#state">State Separation</a> requirement.
-</p></div></div><div class="sect2" title="5.8. Header Settings"><div class="titlepage"><div><div><h3 class="title"><a id="id2706173"></a>5.8. Header Settings</h3></div></div></div><div class="sect3" title="Set user agent during Tor usage (crucial)"><div class="titlepage"><div><div><h4 class="title"><a id="id2706179"></a>Set user agent during Tor usage (crucial)</h4></div></div></div><p>Options:
- </p><table border="0" summary="Simple list" class="simplelist"><tr><td><span class="command"><strong>extensions.torbutton.set_uagent</strong></span></td></tr><tr><td><span class="command"><strong>extensions.torbutton.platform_override</strong></span></td></tr><tr><td><span class="command"><strong>extensions.torbutton.oscpu_override</strong></span></td></tr><tr><td><span class="command"><strong>extensions.torbutton.buildID_override</strong></span></td></tr><tr><td><span class="command"><strong>extensions.torbutton.productsub_override</strong></span></td></tr><tr><td><span class="command"><strong>extensions.torbutton.appname_override</strong></span></td></tr><tr><td><span class="command"><strong>extensions.torbutton.appversion_override</strong></span></td></tr><tr><td><span class="command"><strong>extensions.torbutton.useragent_override</strong></span></td></tr><tr><td><span class="command"><strong>extensions.torbutton.useragent_vendor</strong></span></td></tr><tr><td><span class="
command"><strong>extensions.torbutton.useragent_vendorSub</strong></span></td></tr></table><p>
- </p><p>On face, user agent switching appears to be straight-forward in Firefox.
-It provides several options for controlling the browser user agent string:
-<span class="command"><strong>general.appname.override</strong></span>,
-<span class="command"><strong>general.appversion.override</strong></span>,
-<span class="command"><strong>general.platform.override</strong></span>,
-<span class="command"><strong>general.oscpu.override</strong></span>,
-<span class="command"><strong>general.productSub.override</strong></span>,
-<span class="command"><strong>general.buildID.override</strong></span>,
-<span class="command"><strong>general.useragent.override</strong></span>,
-<span class="command"><strong>general.useragent.vendor</strong></span>, and
-<span class="command"><strong>general.useragent.vendorSub</strong></span>. If
-the Torbutton preference <span class="command"><strong>extensions.torbutton.set_uagent</strong></span> is
-true, Torbutton copies all of the other above prefs into their corresponding
-browser preferences during Tor usage.</p><p>
-
-It also turns out that it is possible to detect the original Firefox version
-by <a class="ulink" href="http://ha.ckers.org/blog/20070516/read-firefox-settings-poc/" target="_top">inspecting
-certain resource:// files</a>. These cases are handled by Torbutton's
-<a class="link" href="#contentpolicy" title="@torproject.org/cssblocker;1 - components/cssblocker.js">content policy</a>.
-
-</p><p>
-This setting helps to satisfy the <a class="link" href="#setpreservation">Anonymity Set Preservation</a> requirement.
-</p></div><div class="sect3" title="Spoof US English Browser"><div class="titlepage"><div><div><h4 class="title"><a id="id2706353"></a>Spoof US English Browser</h4></div></div></div><p>Options:
-</p><table border="0" summary="Simple list" class="simplelist"><tr><td><span class="command"><strong>extensions.torbutton.spoof_english</strong></span></td></tr><tr><td><span class="command"><strong>extensions.torbutton.spoof_charset</strong></span></td></tr><tr><td><span class="command"><strong>extensions.torbutton.spoof_language</strong></span></td></tr></table><p>
-</p><p> This option causes Torbutton to set
-<span class="command"><strong>general.useragent.locale</strong></span>
-<span class="command"><strong>intl.accept_languages</strong></span> to the value specified in
-<span class="command"><strong>extensions.torbutton.spoof_locale</strong></span>,
-<span class="command"><strong>extensions.torbutton.spoof_charset</strong></span> and
-<span class="command"><strong>extensions.torbutton.spoof_language</strong></span> during Tor usage, as
-well as hooking <span class="command"><strong>navigator.language</strong></span> via its <a class="link" href="#jshooks" title="Hook Dangerous Javascript">javascript hooks</a>.
- </p><p>
-This setting helps to satisfy the <a class="link" href="#setpreservation">Anonymity Set Preservation</a> and <a class="link" href="#location">Location Neutrality</a> requirements.
-</p></div><div class="sect3" title="Referer Spoofing Options"><div class="titlepage"><div><div><h4 class="title"><a id="id2706446"></a>Referer Spoofing Options</h4></div></div></div><p>Option: <span class="command"><strong>extensions.torbutton.refererspoof</strong></span>
-</p><p>
-This option variable has three values. If it is 0, "smart" referer spoofing is
-enabled. If it is 1, the referer behaves as normal. If it is 2, no referer is
-sent. The default value is 1. The smart referer spoofing is implemented by the
-<a class="link" href="#refspoofer" title="@torproject.org/torRefSpoofer;1">torRefSpoofer</a> component.
-
-</p><p>
-This setting also does not directly satisfy any Torbutton requirement, but
-some may desire to mask their referer for general privacy concerns.
-</p></div><div class="sect3" title="Automatically use an alternate search engine when presented with a Google Captcha"><div class="titlepage"><div><div><h4 class="title"><a id="id2706521"></a>Automatically use an alternate search engine when presented with a
-Google Captcha</h4></div></div></div><p>Options:
-</p><table border="0" summary="Simple list" class="simplelist"><tr><td><span class="command"><strong>extensions.torbutton.asked_google_captcha</strong></span></td></tr><tr><td><span class="command"><strong>extensions.torbutton.dodge_google_captcha</strong></span></td></tr><tr><td><span class="command"><strong>extensions.torbutton.google_redir_url</strong></span></td></tr></table><p>
-</p><p>
-
-Google's search engine has rate limiting features that cause it to
-<a class="ulink" href="http://googleonlinesecurity.blogspot.com/2007/07/reason-behind-were-sorry-m…" target="_top">present
-captchas</a> and sometimes even outright ban IPs that issue large numbers
-of search queries, especially if a lot of these queries appear to be searching
-for software vulnerabilities or unprotected comment areas.
-
-</p><p>
-
-Despite multiple discussions with Google, we were unable to come to a solution
-or any form of compromise that would reduce the number of captchas and
-outright bans seen by Tor users issuing regular queries.
-
-</p><p>
-As a result, we've implemented this option as an <a class="ulink" href="https://developer.mozilla.org/en/XUL_School/Intercepting_Page_Loads#HTTP_Ob…" target="_top">'http-on-modify-request'</a>
-http observer to optionally redirect banned or captcha-triggering Google
-queries to search engines that do not rate limit Tor users. The current
-options are duckduckgo.com, ixquick.com, bing.com, yahoo.com and scroogle.org. These are
-encoded in the preferences
-<span class="command"><strong>extensions.torbutton.redir_url.[1-5]</strong></span>.
-
-</p></div><div class="sect3" title="Store SSL/CA Certs in separate jars for Tor/Non-Tor (recommended)"><div class="titlepage"><div><div><h4 class="title"><a id="id2706601"></a>Store SSL/CA Certs in separate jars for Tor/Non-Tor (recommended)</h4></div></div></div><p>Options:
-</p><table border="0" summary="Simple list" class="simplelist"><tr><td><span class="command"><strong>extensions.torbutton.jar_certs</strong></span></td></tr><tr><td><span class="command"><strong>extensions.torbutton.jar_ca_certs</strong></span></td></tr></table><p>
-</p><p>
-
-These settings govern if Torbutton attempts to isolate the user's SSL
-certificates into separate jars for each Tor state. This isolation is
-implemented in <code class="function">torbutton_jar_certs()</code> in <a class="ulink" href="https://gitweb.torproject.org/torbutton.git/blob_plain/HEAD:/src/chrome/con…" target="_top">chrome/content/torbutton.js</a>,
-which calls <code class="function">torbutton_jar_cert_type()</code> and
-<code class="function">torbutton_unjar_cert_type()</code> for each certificate type in
-the <a class="ulink" href="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/c…" target="_top">@mozilla.org/security/nsscertcache;1</a>.
-Certificates are deleted from and imported to the <a class="ulink" href="http://www.oxymoronical.com/experiments/xpcomref/applications/Firefox/3.5/c…" target="_top">@mozilla.org/security/x509certdb;1</a>.
-</p><p>
-The first time this pref is used, a backup of the user's certificates is
-created in their profile directory under the name
-<code class="filename">cert8.db.bak</code>. This file can be copied back to
-<code class="filename">cert8.db</code> to fully restore the original state of the
-user's certificates in the event of any error.
-</p><p>
-Since exit nodes and malicious sites can insert content elements sourced to
-specific SSL sites to query if a user has a certain certificate,
-this setting helps to satisfy the <a class="link" href="#state">State
-Separation</a> requirement of Torbutton. Unfortunately, <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=435159" target="_top">Firefox Bug
-435159</a> prevents it from functioning correctly in the event of rapid Tor toggle, so it
-is currently not exposed via the preferences UI.
-
-</p></div></div></div><div class="sect1" title="6. Relevant Firefox Bugs"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="FirefoxBugs"></a>6. Relevant Firefox Bugs</h2></div></div></div><p>
-Future releases of Torbutton are going to be designed around supporting only
-<a class="ulink" href="https://www.torproject.org/projects/torbrowser.html.en" target="_top">Tor
-Browser Bundle</a>, which greatly simplifies the number and nature of Firefox
-bugs we must fix. This allows us to abandon the complexities of <a class="link" href="#state">State
-Separation</a> and <a class="link" href="#isolation">Network Isolation</a> requirements
-associated with the Toggle Model.
- </p><div class="sect2" title="6.1. Tor Browser Bugs"><div class="titlepage"><div><div><h3 class="title"><a id="TorBrowserBugs"></a>6.1. Tor Browser Bugs</h3></div></div></div><p>
-The list of Firefox patches we must create to improve privacy on the
-Tor Browser Bundle are collected in the Tor Bug Tracker under <a class="ulink" href="https://trac.torproject.org/projects/tor/ticket/2871" target="_top">ticket
-#2871</a>. These bugs are also applicable to the Toggle Model, and
-should be considered higher priority than all Toggle Model specific bugs
-below.
- </p></div><div class="sect2" title="6.2. Toggle Model Bugs"><div class="titlepage"><div><div><h3 class="title"><a id="ToggleModelBugs"></a>6.2. Toggle Model Bugs</h3></div></div></div><p>
-In addition to the Tor Browser bugs, the Torbutton Toggle Model suffers from
-additional bugs specific to the need to isolate state across the toggle.
-Toggle model bugs are considered a lower priority than the bugs against the
-Tor Browser model.
- </p><div class="sect3" title="Bugs impacting security"><div class="titlepage"><div><div><h4 class="title"><a id="FirefoxSecurity"></a>Bugs impacting security</h4></div></div></div><p>
-
-Torbutton has to work around a number of Firefox bugs that impact its
-security. Most of these are mentioned elsewhere in this document, but they
-have also been gathered here for reference. In order of decreasing severity,
-they are:
-
- </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=435159" target="_top">Bug 435159 -
-nsNSSCertificateDB::DeleteCertificate has race conditions</a><p>
-
-In Torbutton 1.2.0rc1, code was added to attempt to isolate SSL certificates
-the user has installed. Unfortunately, the method call to delete a certificate
-from the current certificate database acts lazily: it only sets a variable
-that marks a cert for deletion later, and it is not cleared if that
-certificate is re-added. This means that if the Tor state is toggled quickly,
-that certificate could remain present until it is re-inserted (causing an
-error dialog), and worse, it would still be deleted after that. The lack of
-this functionality is considered a Torbutton security bug because cert
-isolation is considered a <a class="link" href="#state">State Separation</a>
-feature.
-
- </p></li><li class="listitem">Give more visibility into and control over TLS
-negotiation
- <p>
-
-There are several <a class="ulink" href="https://trac.torproject.org/projects/tor/ticket/2482" target="_top">TLS issues
-impacting Torbutton security</a>. It is not clear if these should be one
-Firefox bug or several, but in particular we need better control over various
-aspects of TLS connections. Firefox currently provides no observer capable of
-extracting TLS parameters or certificates early enough to cancel a TLS
-request. We would like to be able to provide <a class="ulink" href="https://www.eff.org/https-everywhere" target="_top">HTTPS-Everywhere</a> users with
-the ability to <a class="ulink" href="https://trac.torproject.org/projects/tor/wiki/HTTPSEverywhere/SSLObservator…" target="_top">have
-their certificates audited</a> by a <a class="ulink" href="http://www.networknotary.org/" target="_top">Perspectives</a>-style set of
-notaries. The problem with this is that the API observer points do not exist
-for any Firefox addon to actually block authentication token submission over a
-TLS channel, so every addon to date (including Perspectives) is actually
-providing users with notification *after* their authentication tokens have
-already been compromised. This obviously needs to be fixed.
- </p></li><li class="listitem"><a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=122752" target="_top">Bug 122752 - SOCKS
-Username/Password Support</a><p>
-We need <a class="ulink" href="https://developer.mozilla.org/en/nsIProxyInfo" target="_top">Firefox
-APIs</a> or about:config settings to control the SOCKS Username and
-Password fields. The reason why we need this support is to utilize an (as yet
-unimplemented) scheme to separate Tor traffic based <a class="ulink" href="https://gitweb.torproject.org/torspec.git/blob_plain/HEAD:/proposals/171-se…" target="_top">on
-SOCKS username/password</a>.
- </p></li><li class="listitem"><a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=409737" target="_top">Bug 409737 -
-javascript.enabled and docShell.allowJavascript do not disable all event
-handlers</a><p>
-
-This bug allows pages to execute javascript via addEventListener and perhaps
-other callbacks. In order to prevent this bug from enabling an attacker to
-break the <a class="link" href="#isolation">Network Isolation</a> requirement,
-Torbutton 1.1.13 began blocking popups and history manipulation from different
-Tor states. So long as there are no ways to open popups or redirect the user
-to a new page, the <a class="link" href="#contentpolicy" title="@torproject.org/cssblocker;1 - components/cssblocker.js">Torbutton content
-policy</a> should block Javascript network access. However, if there are
-ways to open popups or perform redirects such that Torbutton cannot block
-them, pages may still have free reign to break that requirement and reveal a
-user's original IP address.
-
- </p></li><li class="listitem"><a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=448743" target="_top">Bug 448743 -
-Decouple general.useragent.locale from spoofing of navigator.language</a><p>
-
-Currently, Torbutton spoofs the <span class="command"><strong>navigator.language</strong></span>
-attribute via <a class="link" href="#jshooks" title="Hook Dangerous Javascript">Javascript hooks</a>. Unfortunately,
-these do not work on Firefox 3. It would be ideal to have
-a pref to set this value (something like a
-<span class="command"><strong>general.useragent.override.locale</strong></span>),
-to avoid fragmenting the anonymity set of users of foreign locales. This issue
-impedes Torbutton from fully meeting its <a class="link" href="#setpreservation">Anonymity Set Preservation</a>
-requirement on Firefox 3.
-
- </p></li></ol></div></div><div class="sect3" title="Bugs blocking functionality"><div class="titlepage"><div><div><h4 class="title"><a id="FirefoxWishlist"></a>Bugs blocking functionality</h4></div></div></div><p>
-The following bugs impact Torbutton and similar extensions' functionality.
- </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=629820" target="_top">Bug 629820 - nsIContentPolicy::shouldLoad not
-called for web request in Firefox Mobile</a><p>
-
-The new <a class="ulink" href="https://wiki.mozilla.org/Mobile/Fennec/Extensions/Electrolysis" target="_top">Electrolysis</a>
-multiprocess system appears to have some pretty rough edge cases with respect
-to registering XPCOM category managers such as the nsIContentPolicy, which
-make it difficult to do a straight-forward port of Torbutton or
-HTTPS-Everywhere to Firefox Mobile. It probably also has similar issues with
-wrapping existing <a class="link" href="#hookedxpcom" title="2.1. Hooked Components">Firefox XPCOM components</a>,
-which will also cause more problems for porting Torbutton.
-
- </p></li><li class="listitem"><a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=417869" target="_top">Bug 417869 -
-Browser context is difficult to obtain from many XPCOM callbacks</a><p>
-
-It is difficult to determine which tabbrowser many XPCOM callbacks originate
-from, and in some cases absolutely no context information is provided at all.
-While this doesn't have much of an effect on Torbutton, it does make writing
-extensions that would like to do per-tab settings and content filters (such as
-FoxyProxy) difficult to impossible to implement securely.
-
- </p></li></ol></div></div><div class="sect3" title="Low Priority Bugs"><div class="titlepage"><div><div><h4 class="title"><a id="FirefoxMiscBugs"></a>Low Priority Bugs</h4></div></div></div><p>
-The following bugs have an effect upon Torbutton, but are superseded by more
-practical and more easily fixable variant bugs above; or have stable, simple
-workarounds.
- </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=440892" target="_top">Bug 440892 -
-network.protocol-handler.warn-external are ignored</a><p>
-
-Sometime in the Firefox 3 development cycle, the preferences that governed
-warning a user when external apps were launched got disconnected from the code
-that does the launching. Torbutton depended on these prefs to prevent websites
-from launching specially crafted documents and application arguments that
-caused Proxy Bypass. We currently work around this issue by <a class="link" href="#appblocker" title="@mozilla.org/uriloader/external-protocol-service;1 , @mozilla.org/uriloader/external-helper-app-service;1, and @mozilla.org/mime;1 - components/external-app-blocker.js">wrapping the app launching components</a> to present a
-popup before launching external apps while Tor is enabled. While this works,
-it would be nice if these prefs were either fixed or removed.
-
- </p></li><li class="listitem"><a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=437014" target="_top">Bug 437014 -
-nsIContentPolicy::shouldLoad no longer called for favicons</a><p>
-
-Firefox 3.0 stopped calling the shouldLoad call of content policy for favicon
-loads. Torbutton had relied on this call to block favicon loads for opposite
-Tor states. The workaround it employs for Firefox 3 is to cancel the request
-when it arrives in the <span class="command"><strong>torbutton_http_observer</strong></span> used for
-blocking full page plugin loads. This seems to work just fine, but is a bit
-dirty.
-
- </p></li><li class="listitem"><a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=309524" target="_top">Bug 309524</a>
-and <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=380556" target="_top">Bug
-380556</a> - nsIContentPolicy::shouldProcess is not called.
- <p>
-
-This is a call that would be useful to develop a better workaround for the
-allowPlugins issue above. If the content policy were called before a URL was
-handed over to a plugin or helper app, it would make the workaround for the
-above allowPlugins bug a lot cleaner. Obviously this bug is not as severe as
-the others though, but it might be nice to have this API as a backup.
-
- </p></li><li class="listitem"><a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=401296" target="_top">Bug 401296 - docShell.allowPlugins
-not honored for direct links</a> (Perhaps subset of <a class="ulink" href="https://bugzilla.mozilla.org/show_bug.cgi?id=282106" target="_top">Bug 282106</a>?)
- <p>
-
-Similar to the javascript plugin disabling attribute, the plugin disabling
-attribute is also not perfect — it is ignored for direct links to plugin
-handled content, as well as meta-refreshes to plugin handled content. This
-requires Torbutton to listen to a number of different http events to intercept
-plugin-related mime type URLs and cancel their requests. Again, since plugins
-are quite horrible about obeying proxy settings, loading a plugin pretty much
-ensures a way to break the <a class="link" href="#isolation">Network Isolation</a>
-requirement and reveal a user's original IP address. Torbutton's code to
-perform this workaround has been subverted at least once already by Kyle
-Williams.
-
- </p></li></ol></div></div></div></div><div class="sect1" title="7. Testing"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="TestPlan"></a>7. Testing</h2></div></div></div><p>
-
-The purpose of this section is to cover all the known ways that Tor browser
-security can be subverted from a penetration testing perspective. The hope
-is that it will be useful both for creating a "Tor Safety Check"
-page, and for developing novel tests and actively attacking Torbutton with the
-goal of finding vulnerabilities in either it or the Mozilla components,
-interfaces and settings upon which it relies.
-
- </p><div class="sect2" title="7.1. Single state testing"><div class="titlepage"><div><div><h3 class="title"><a id="SingleStateTesting"></a>7.1. Single state testing</h3></div></div></div><p>
-
-Torbutton is a complicated piece of software. During development, changes to
-one component can affect a whole slough of unrelated features. A number of
-aggregated test suites exist that can be used to test for regressions in
-Torbutton and to help aid in the development of Torbutton-like addons and
-other privacy modifications of other browsers. Some of these test suites exist
-as a single automated page, while others are a series of pages you must visit
-individually. They are provided here for reference and future regression
-testing, and also in the hope that some brave soul will one day decide to
-combine them into a comprehensive automated test suite.
-
- </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><a class="ulink" href="http://decloak.net/" target="_top">Decloak.net</a><p>
-
-Decloak.net is the canonical source of plugin and external-application based
-proxy-bypass exploits. It is a fully automated test suite maintained by <a class="ulink" href="http://digitaloffense.net/" target="_top">HD Moore</a> as a service for people to
-use to test their anonymity systems.
-
- </p></li><li class="listitem"><a class="ulink" href="http://deanonymizer.com/" target="_top">Deanonymizer.com</a><p>
-
-Deanonymizer.com is another automated test suite that tests for proxy bypass
-and other information disclosure vulnerabilities. It is maintained by Kyle
-Williams, the author of <a class="ulink" href="http://www.janusvm.com/" target="_top">JanusVM</a>
-and <a class="ulink" href="http://www.januspa.com/" target="_top">JanusPA</a>.
-
- </p></li><li class="listitem"><a class="ulink" href="https://www.jondos.de/en/anontest" target="_top">JonDos
-AnonTest</a><p>
-
-The <a class="ulink" href="https://www.jondos.de" target="_top">JonDos people</a> also provide an
-anonymity tester. It is more focused on HTTP headers than plugin bypass, and
-points out a couple of headers Torbutton could do a better job with
-obfuscating.
-
- </p></li><li class="listitem"><a class="ulink" href="http://browserspy.dk" target="_top">Browserspy.dk</a><p>
-
-Browserspy.dk provides a tremendous collection of browser fingerprinting and
-general privacy tests. Unfortunately they are only available one page at a
-time, and there is not really solid feedback on good vs bad behavior in
-the test results.
-
- </p></li><li class="listitem"><a class="ulink" href="http://analyze.privacy.net/" target="_top">Privacy
-Analyzer</a><p>
-
-The Privacy Analyzer provides a dump of all sorts of browser attributes and
-settings that it detects, including some information on your origin IP
-address. Its page layout and lack of good vs bad test result feedback makes it
-not as useful as a user-facing testing tool, but it does provide some
-interesting checks in a single page.
-
- </p></li><li class="listitem"><a class="ulink" href="http://ha.ckers.org/mr-t/" target="_top">Mr. T</a><p>
-
-Mr. T is a collection of browser fingerprinting and deanonymization exploits
-discovered by the <a class="ulink" href="http://ha.ckers.org" target="_top">ha.ckers.org</a> crew
-and others. It is also not as user friendly as some of the above tests, but it
-is a useful collection.
-
- </p></li><li class="listitem">Gregory Fleischer's <a class="ulink" href="http://pseudo-flaw.net/content/tor/torbutton/" target="_top">Torbutton</a> and
-<a class="ulink" href="http://pseudo-flaw.net/content/defcon/dc-17-demos/d.html" target="_top">Defcon
-17</a> Test Cases
- <p>
-
-Gregory Fleischer has been hacking and testing Firefox and Torbutton privacy
-issues for the past 2 years. He has an excellent collection of all his test
-cases that can be used for regression testing. In his Defcon work, he
-demonstrates ways to infer Firefox version based on arcane browser properties.
-We are still trying to determine the best way to address some of those test
-cases.
-
- </p></li><li class="listitem"><a class="ulink" href="https://torcheck.xenobite.eu/index.php" target="_top">Xenobite's
-TorCheck Page</a><p>
-
-This page checks to ensure you are using a valid Tor exit node and checks for
-some basic browser properties related to privacy. It is not very fine-grained
-or complete, but it is automated and could be turned into something useful
-with a bit of work.
-
- </p></li></ol></div><p>
- </p></div><div class="sect2" title="7.2. Multi-state testing"><div class="titlepage"><div><div><h3 class="title"><a id="id2707624"></a>7.2. Multi-state testing</h3></div></div></div><p>
-
-The tests in this section are geared towards a page that would instruct the
-user to toggle their Tor state after the fetch and perform some operations:
-mouseovers, stray clicks, and potentially reloads.
-
- </p><div class="sect3" title="Cookies and Cache Correlation"><div class="titlepage"><div><div><h4 class="title"><a id="id2707636"></a>Cookies and Cache Correlation</h4></div></div></div><p>
-The most obvious test is to set a cookie, ask the user to toggle tor, and then
-have them reload the page. The cookie should no longer be set if they are
-using the default Torbutton settings. In addition, it is possible to leverage
-the cache to <a class="ulink" href="http://crypto.stanford.edu/sameorigin/safecachetest.html" target="_top">store unique
-identifiers</a>. The default settings of Torbutton should also protect
-against these from persisting across Tor Toggle.
-
- </p></div><div class="sect3" title="Javascript timers and event handlers"><div class="titlepage"><div><div><h4 class="title"><a id="id2707658"></a>Javascript timers and event handlers</h4></div></div></div><p>
-
-Javascript can set timers and register event handlers in the hopes of fetching
-URLs after the user has toggled Torbutton.
- </p></div><div class="sect3" title="CSS Popups and non-script Dynamic Content"><div class="titlepage"><div><div><h4 class="title"><a id="id2707671"></a>CSS Popups and non-script Dynamic Content</h4></div></div></div><p>
-
-Even if Javascript is disabled, CSS is still able to
-<a class="ulink" href="http://www.tjkdesign.com/articles/css%20pop%20ups/" target="_top">create popup-like
-windows</a>
-via the 'onmouseover' CSS attribute, which can cause arbitrary browser
-activity as soon as the mouse enters into the content window. It is also
-possible for meta-refresh tags to set timers long enough to make it likely
-that the user has toggled Tor before fetching content.
-
- </p></div></div><div class="sect2" title="7.3. Active testing (aka How to Hack Torbutton)"><div class="titlepage"><div><div><h3 class="title"><a id="HackTorbutton"></a>7.3. Active testing (aka How to Hack Torbutton)</h3></div></div></div><p>
-
-The idea behind active testing is to discover vulnerabilities in Torbutton to
-bypass proxy settings, run script in an opposite Tor state, store unique
-identifiers, leak location information, or otherwise violate <a class="link" href="#requirements" title="1.2. Torbutton Requirements">its requirements</a>. Torbutton has ventured out
-into a strange and new security landscape. It depends on Firefox mechanisms
-that haven't necessarily been audited for security, certainly not for the
-threat model that Torbutton seeks to address. As such, it and the interfaces
-it depends upon still need a 'trial by fire' typical of new technologies. This
-section of the document was written with the intention of making that period
-as fast as possible. Please help us get through this period by considering
-these attacks, playing with them, and reporting what you find (and potentially
-submitting the test cases back to be run in the standard batch of Torbutton
-tests.
-
- </p><div class="sect3" title="Some suggested vectors to investigate"><div class="titlepage"><div><div><h4 class="title"><a id="id2707726"></a>Some suggested vectors to investigate</h4></div></div></div><p>
- </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">Strange ways to register Javascript <a class="ulink" href="http://en.wikipedia.org/wiki/DOM_Events" target="_top">events</a> and <a class="ulink" href="http://www.devshed.com/c/a/JavaScript/Using-Timers-in-JavaScript/" target="_top">timeouts</a> should
-be verified to actually be ineffective after Tor has been toggled.</li><li class="listitem">Other ways to cause Javascript to be executed after
-<span class="command"><strong>javascript.enabled</strong></span> has been toggled off.</li><li class="listitem">Odd ways to attempt to load plugins. Kyle Williams has had
-some success with direct loads/meta-refreshes of plugin-handled URLs.</li><li class="listitem">The Date and Timezone hooks should be verified to work with
-crazy combinations of iframes, nested iframes, iframes in frames, frames in
-iframes, and popups being loaded and
-reloaded in rapid succession, and/or from one another. Think race conditions and deep,
-parallel nesting, involving iframes from both <a class="ulink" href="http://en.wikipedia.org/wiki/Same_origin_policy" target="_top">same-origin and
-non-same-origin</a> domains.</li><li class="listitem">In addition, there may be alternate ways and other
-methods to query the timezone, or otherwise use some of the Date object's
-methods in combination to deduce the timezone offset. Of course, the author
-tried his best to cover all the methods he could foresee, but it's always good
-to have another set of eyes try it out.</li><li class="listitem">Similarly, is there any way to confuse the <a class="link" href="#contentpolicy" title="@torproject.org/cssblocker;1 - components/cssblocker.js">content policy</a>
-mentioned above to cause it to allow certain types of page fetches? For
-example, it was recently discovered that favicons are not fetched by the
-content, but the chrome itself, hence the content policy did not look up the
-correct window to determine the current Tor tag for the favicon fetch. Are
-there other things that can do this? Popups? Bookmarklets? Active bookmarks? </li><li class="listitem">Alternate ways to store and fetch unique identifiers. For example, <a class="ulink" href="http://developer.mozilla.org/en/docs/DOM:Storage" target="_top">DOM Storage</a>
-caught us off guard.
-It was
-also discovered by <a class="ulink" href="http://pseudo-flaw.net" target="_top">Gregory
-Fleischer</a> that <a class="ulink" href="http://pseudo-flaw.net/content/tor/torbutton/" target="_top">content window access to
-chrome</a> can be used to build <a class="link" href="#fingerprinting">unique
-identifiers</a>.
-Are there any other
-arcane or experimental ways that Firefox provides to create and store unique
-identifiers? Or perhaps unique identifiers can be queried or derived from
-properties of the machine/browser that Javascript has access to? How unique
-can these identifiers be?
- </li><li class="listitem">Is it possible to get the browser to write some history to disk
-(aside from swap) that can be retrieved later? By default, Torbutton should
-write no history, cookie, or other browsing activity information to the
-harddisk.</li><li class="listitem">Do popup windows make it easier to break any of the above
-behavior? Are javascript events still canceled in popups? What about recursive
-popups from Javascript, data, and other funky URL types? What about CSS
-popups? Are they still blocked after Tor is toggled?</li><li class="listitem">Chrome-escalation attacks. The interaction between the
-Torbutton chrome Javascript and the client content window javascript is pretty
-well-defined and carefully constructed, but perhaps there is a way to smuggle
-javascript back in a return value, or otherwise inject network-loaded
-javascript into the chrome (and thus gain complete control of the browser).
-</li></ul></div><p>
-
- </p></div></div></div></div></body></html>
diff --git a/website/gimpy.css b/website/gimpy.css
deleted file mode 100644
index 277f0160..00000000
--- a/website/gimpy.css
+++ /dev/null
@@ -1,3 +0,0 @@
-LI:first-line {
- font-weight: bold
-}
diff --git a/website/index.html.en b/website/index.html.en
deleted file mode 100644
index 5909b26e..00000000
--- a/website/index.html.en
+++ /dev/null
@@ -1,532 +0,0 @@
-<html>
-<head>
-<title>Torbutton - Quickly toggle Firefox's use of the Tor network</title>
-<LINK REL="stylesheet" TYPE="text/css" HREF="gimpy.css">
-
-<link rel="search" type="application/opensearchdescription+xml" title="Google Canada" href="search/google-ca.xml">
-<link rel="search" type="application/opensearchdescription+xml" title="Google UK" href="http://torbutton.torproject.org/dev/search/google-uk.xml">
-<link rel="search" type="application/opensearchdescription+xml" title="Google USA" href="search/google-us.xml">
-<script>
-
-function addSearchProvider(prov) {
-
-try {
-window.external.AddSearchProvider(prov);
-}
-
-catch (e) {
-alert("Search plugins require Firefox 2");
-return;
-}
-}
-
-function addEngine(name,ext,cat,pid)
-{
- if ((typeof window.sidebar == "object") && (typeof window.sidebar.addSearchEngine == "function")) {
- window.sidebar.addSearchEngine(
- "http://mycroft.mozdev.org/install.php/" + pid + "/" + name + ".src",
- "http://mycroft.mozdev.org/install.php/" + pid + "/" + name + "."+ ext, name, cat );
- } else {
- alert("You will need a browser which supports Sherlock to install this plugin.");
- }
-}
-
-function addOpenSearch(name,ext,cat,pid,meth)
-{
- if ((typeof window.external == "object") && ((typeof window.external.AddSearchProvider == "unknown") || (typeof window.external.AddSearchProvider == "function"))) {
- if ((typeof window.external.AddSearchProvider == "unknown") && meth == "p") {
- alert("This plugin uses POST which is not currently supported by Internet Explorer's implementation of OpenSearch.");
- } else {
- window.external.AddSearchProvider(
- "http://mycroft.mozdev.org/installos.php/" + pid + "/" + name + ".xml");
- }
- } else {
- alert("You will need a browser which supports OpenSearch to install this plugin.");
- }
-}
-
-function addOpenSearch2(name,ext,cat,pid,meth)
-{
- if ((typeof window.external == "object") && ((typeof window.external.AddSearchProvider == "unknown") || (typeof window.external.AddSearchProvider == "function"))) {
- if ((typeof window.external.AddSearchProvider == "unknown") && meth == "p") {
- alert("This plugin uses POST which is not currently supported by Internet Explorer's implementation of OpenSearch.");
- } else {
- window.external.AddSearchProvider(
- "http://torbutton.torproject.org/dev/search/" + name + ".xml");
- }
- } else {
- alert("You will need a browser which supports OpenSearch to install this plugin.");
- }
-}
-
-function install (aEvent)
-{
- var params = {
- "Torbutton": { URL: aEvent.target.href,
- Hash: aEvent.target.getAttribute("hash"),
- toString: function () { return this.URL; }
- }
- };
- InstallTrigger.install(params);
-
- return false;
-}
-
-
-</script>
-</head>
-<body>
-
-<h1>Torbutton Development Branch</h1>
-<strong>Current version:</strong> 1.2.0rc6 (12 Jul 2008)<br/>
-<br/>
-<strong>Authors:</strong> Scott Squires & Mike Perry<br>
-<strong>Email:</strong> squires at freehaven dot net, mikeperry (o) fscked/org<br/>
-<br/>
-<strong>Install:</strong>
-<a href="http://torbutton.torproject.org/dev/torbutton-current.xpi"
- hash="sha1:7f01c577641b6222781cd880c9825d6f50ff1cc4"
- onclick="return install(event);">Local (Javascript verified)</a><br/>
-<strong>Past Releases:</strong> <a href="releases/">Local (non-https)</a><br/>
-<strong>Developer Documentation:</strong> <a href="design/">Torbutton Design Document</a> and <a href="design/MozillaBrownBag.pdf">Slides (Not actively updated)</a><br/>
-<strong>Extras:</strong>
-
-Google search plugins for
-
-<a href="/jsreq.html" title="Ref: 14938 (googleCA)"
- onClick="addOpenSearch('GoogleCanada','ico','General','14937','g');return false">Google CA</a>, and
-
-<a href="/jsreq.html" title="Ref: 14938 (googleCA)"
- onClick="addOpenSearch('googleuk_web','png','General','14445','g');return false">Google UK</a>.
-<br/>
-<!--
-<strong>Install:</strong> <a href="torbutton-1.0.4.xpi">torbutton-1.0.4.xpi</a><br/>
--->
-<strong>Source:</strong> You can <a href="https://tor-svn.freehaven.net/svn/torbutton/trunk/">browse the repository</a> or simply unzip the xpi.
-<br/>
-<strong>Bug Reports:</strong> <a href="https://bugs.torproject.org/flyspray/index.php?tasks=all&project=5">Torproject flyspray</a><br/>
-<strong>Documents:</strong> <b>[</b> <a href="#FAQ">FAQ</a> <b>|</b> <a href="CHANGELOG">changelog</a> <b>|</b> <a href="LICENSE">license</a> <b>|</b> <a href="CREDITS">credits</a> <b>]</b><br/>
-<h2>About</h2>
-<p>
-Torbutton is a 1-click way for Firefox users to enable or disable the browser's use of <a href="https://www.torproject.org/">Tor</a>. It adds a panel to the statusbar that says "Tor Enabled" (in green) or "Tor Disabled" (in red). The user may click on the panel to toggle the status. If the user (or some other extension) changes the proxy settings, the change is automatically reflected in the statusbar.
-</p><p>
-Some users may prefer a toolbar button instead of a statusbar panel. Such a button is included, and one adds it to the toolbar by right-clicking on the desired toolbar, selecting "Customize...", and then dragging the Torbutton icon onto the toolbar. There is an option in the preferences to hide the statusbar panel (Tools->Extensions, select Torbutton, and click on Preferences).
-</p>
-<p>
-Newer Firefoxes have the ability to send DNS resolves through the socks proxy, and Torbutton will make use of this feature if it is available in your version of Firefox.
-</p>
-
-<a id="FAQ"></a><h2>FAQ</h2>
-
-<strong>I can't click on links or hit reload after I toggle Tor! Why?</strong>
-<p>
-
-Due to <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=409737">Firefox
-Bug 409737</a>, pages can still open popups and perform Javascript redirects
-and history access after Tor has been toggled. These popups and redirects can
-be blocked, but unfortunately they are indistinguishable from normal user
-interactions with the page (such as clicking on links, opening them in new
-tabs/windows, or using the history buttons), and so those are blocked as a
-side effect. Once that Firefox bug is fixed, this degree of isolation will
-become optional (for people who do not want to accidentally click on links and
-give away information via referrers). A workaround is to right click on the
-link, and open it in a new tab or window. The tab or window won't load
-automatically, but you can hit enter in the URL bar, and it will begin
-loading. Hitting enter in the URL bar will also reload the page without
-clicking the reload button.
-
-</p>
-
-<strong>My browser is in some weird state where nothing works right!</strong>
-<p>
-
-Try to disable Tor by clicking on the button, and then open a new window. If
-that doesn't fix the issue, go to the preferences page and hit 'Restore
-Defaults'. This should reset the extension and Firefox to a known good
-configuration. If you can manage to reproduce whatever issue gets your
-Firefox wedged, please file details at <a
-href="https://bugs.torproject.org/flyspray/index.php?tasks=all&project=5">the
-bug tracker</a>.
-
-</p>
-
-<strong>When I toggle Tor, my sites that use javascript stop working. Why?</strong>
-<p>
-
-Javascript can do things like wait until you have disabled Tor before trying
-to contact its source site, thus revealing your IP address. As such, Torbutton
-must disable Javascript, Meta-Refresh tags, and certain CSS behavior when Tor
-state changes from the state that was used to load a given page. These features
-are re-enabled when Torbutton goes back into the state that was used to load
-the page, but in some cases (particularly with Javascript and CSS) it is
-sometimes not possible to fully recover from the resulting errors, and the
-page is broken. Unfortunately, the only thing you can do (and still remain
-safe from having your IP address leak) is to reload the page when you toggle
-Tor, or just ensure you do all your work in a page before switching tor state.
-
-</p>
-
-
-<strong>When I use Tor, Firefox is no longer filling in logins/search boxes
-for me. Why?</strong>
-<p>
-
-Currently, this is tied to the "<b>Block history writes during Tor</b>"
-setting. If you have enabled that setting, all formfill functionality (both
-saving and reading) is disabled. If this bothers you, you can uncheck that
-option, but both history and forms will be saved. To prevent history
-disclosure attacks via Non-Tor usage, it is recommended you disable Non-Tor
-history reads if you allow history writing during Tor.
-
-</p>
-
-
-<strong>Which Firefox extensions should I avoid using?</strong>
-<p>
-
-This is a tough one. There are thousands of Firefox extensions: making a
-complete list of ones that are bad for anonymity is near impossible. However,
-here are a few examples that should get you started as to what sorts of
-behavior are dangerous.
-
-<ol>
- <li>StumbleUpon, et al</li>
- These extensions will send all sorts of information about the websites you
- visit to the stumbleupon servers, and correlate this information with a
- unique identifier. This is obviously terrible for your anonymity.
- More generally, any sort of extension that requires registration, or even
- extensions that provide information about websites you visit should be
- suspect.
-
- <li>FoxyProxy</li>
-
-While FoxyProxy is a nice idea in theory, in practice it is impossible to
-configure securely for Tor usage without Torbutton. Like all vanilla third
-party proxy plugins, the main risks are <a
-href="http://www.metasploit.com/research/projects/decloak/">plugin leakage</a>
-and <a href="http://ha.ckers.org/weird/CSS-history.cgi">history
-disclosure</a>, followed closely by cookie theft by exit nodes and tracking by
-adservers (see the <a href="design/index.html#adversary">Torbutton Adversary
-Model</a> for more information). However, even with Torbutton installed in
-tandem and always enabled, it is still very difficult (though not impossible)
-to configure FoxyProxy securely. Since FoxyProxy's 'Patterns' mode only
-applies to specific urls, and not to an entire tab, setting FoxyProxy to only
-send specific sites through Tor will still allow adservers to still learn your
-real IP. Worse, if those sites use offsite logging services such as Google
-Analytics, you may still end up in their logs with your real IP. Malicious
-exit nodes can also cooperate with sites to inject images into pages that
-bypass your filters. Setting FoxyProxy to only send certain URLs via Non-Tor
-is much more viable, but be very careful with the filters you allow. For
-example, something as simple as allowing *google* to go via Non-Tor will still
-cause you to end up in all the logs of all websites that use Google Analytics!
-See <a href="http://foxyproxy.mozdev.org/faq.html#privacy-01">this
-question</a> on the FoxyProxy FAQ for more information.
-
- <li>NoScript</li>
- Torbutton currently mitigates all known anonymity issues with Javascript.
- While it may be tempting to get better security by disabling Javascript for
- certain sites, you are far better off with an all-or-nothing approach.
- NoScript is exceedingly complicated, and has many subtleties that can surprise
- even advanced users. For example, addons.mozilla.org verifies extension
- integrity via Javascript over https, but downloads them in the clear. Not
- adding it to your whitelist effectively
- means you are pulling down unverified extensions. Worse still, using NoScript
- can actually disable protections that Torbutton itself provides via
- Javascript, yet still allow malicious exit nodes to compromise your
- anonymity via the default whitelist (which they can spoof to inject any script they want).
-
-</ol>
-
-</p>
-
-<strong>Which Firefox extensions do you recommend?</strong>
-<p>
-<ol>
- <li><a href="https://addons.mozilla.org/en-US/firefox/addon/953">RefControl</a></li>
- Mentioned above, this extension allows more fine-grained referrer spoofing
-than Torbutton currently provides. It should break less sites than Torbutton's
-referrer spoofing option.
- <li><a href="https://addons.mozilla.org/en-US/firefox/addon/1474">SafeCache</a></li>
- If you use Tor excessively, and rarely disable it, you probably want to
-install this extension to minimize the ability of sites to store long term
-identifiers in your cache. This extension applies same origin policy to the
-cache, so that elements are retrieved from the cache only if they are fetched
-from a document in the same origin domain as the cached element.
-</ol>
-
-</p>
-
-<strong>Are there any other issues I should be concerned about?</strong>
-<p>
-
-There is currently one known unfixed security issue with Torbutton: it is
-possible to unmask the javascript hooks that wrap the Date object to conceal
-your timezone in Firefox 2, and the timezone masking code does not work at all
-on Firefox 3. We are working with the Firefox team to fix one of <a
-href="https://bugzilla.mozilla.org/show_bug.cgi?id=392274">Bug 399274</a> or
-<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=419598">Bug 419598</a>
-to address this. In the meantime, it is possible to set the <b>TZ</b>
-environment variable to <b>UTC</b> to cause the browser to use UTC as your
-timezone. Under Linux, you can add an <b>export TZ=UTC</b> to the
-/usr/bin/firefox script, or edit your system bashrc to do the same. Under
-Windows, you can set either a <a
-href="http://support.microsoft.com/kb/310519">User or System Environment
-Variable</a> for TZ via My Computer's properties. In MacOS, the situation is
-<a
-href="http://developer.apple.com/documentation/MacOSX/Conceptual/BPRuntimeConfig/…">a
-lot more complicated</a>, unfortunately.
-
-</p>
-
-<p>
-
-In addition, RSS readers such as Firefox Livemarks can perform
-periodic fetches. Due to <a
-href="https://bugzilla.mozilla.org/show_bug.cgi?id=436250">Firefox Bug
-436250</a>, there is no way to disable Livemark fetches during Tor. This can
-be a problem if you have a lot of custom Livemark urls that can give away
-information about your identity.
-
-</p>
-
-<h2>Description of Options</h2>
-
-<p>The development branch of Torbutton adds several new security features to
-protect your anonymity from all the major threats the author is aware of. The
-defaults should be fine for most people, but in case you are the tweaker type,
-or if you prefer to try to outsource some options to more flexible extensions,
-here is the complete list. (In an ideal world, these descriptions should all be
-tooltips in the extension itself, but Firefox bugs <a
-href="https://bugzilla.mozilla.org/show_bug.cgi?id=45375">45375</a> and <a
-href="https://bugzilla.mozilla.org/show_bug.cgi?id=218223">218223</a> currently
-prevent this).</p>
-
-<ul>
- <li>Disable plugins on Tor Usage (crucial)</li>
-
- This option is key to Tor security. Plugins perform their own networking
-independent of the browser, and many plugins only partially obey even their own
-proxy settings.
-
- <li>Isolate Dynamic Content to Tor State (crucial)</li>
-
- Another crucial option, this setting causes the plugin to disable Javascript
- on tabs that are loaded during a Tor state different than the current one,
- to prevent delayed fetches of injected URLs that contain unique identifiers,
- and to prevent meta-refresh tags from revealing your IP when you turn off
- Tor. It also prevents all fetches from tabs loaded with an opposite Tor
- state. This serves to block non-Javascript dynamic content such as CSS
- popups from revealing your IP address if you disable Tor.
-
- <li>Hook Dangerous Javascript (crucial)</li>
-
-This setting enables the Javascript hooking code. Javascript is injected into
-pages to hook the Date object to mask your timezone, and to hook the navigator
-object to mask OS and user agent properties not handled by the standard
-Firefox user agent override settings.
-
- <li>Resize window dimensions to multiples of 50px on toggle (recommended)</li>
-
-To cut down on the amount of state available to fingerprint users uniquely,
-this pref causes windows to be resized to a multiple of 50 pixels on each
-side when Tor is enabled and pages are loaded.
-
- <li>Disable Updates During Tor (recommended)</li>
-
-Under Firefox 2, many extension authors did not update their extensions from
-SSL-enabled websites. It is possible for malicious Tor nodes to hijack these extensions and replace them with malicious ones, or add malicious code to
-existing extensions. Since Firefox 3 now enforces encrypted and/or
-authenticated updates, this setting is no longer as important as it once
-was (though updates do leak information about which extensions you have, it is
-fairly infrequent).
-
- <li>Disable Search Suggestions during Tor (optional)</li>
-
-This optional setting governs if you get Google search suggestions during Tor
-usage. Since no cookie is transmitted during search suggestions, this is a
-relatively benign behavior.
-
- <li>Block Tor/Non-Tor access to network from file:// urls (recommended)</li>
-
-These settings prevent local html documents from transmitting local files to
-arbitrary websites <a href="http://www.gnucitizen.org/blog/content-disposition-hacking/">under Firefox 2</a>. Since exit nodes can insert headers that
-force the browser to save arbitrary pages locally (and also inject script into
-arbitrary html files you save to disk via Tor), it is probably a good idea to
-leave this setting on.
-
- <li>Close all Non-Tor/Tor windows and tabs on toggle (optional)</li>
-
-These two settings allow you to obtain a greater degree of assurance that
-after you toggle out of Tor, the pages are really gone and can't perform any
-extra network activity. Currently, there is no known way that pages can still
-perform activity after toggle, but these options exist as a backup measure
-just in case a flaw is discovered. They can also serve as a handy 'Boss
-Button' feature for clearing all Tor browsing off your screen in a hurry.
-
- <li>Isolate access to history navigation to Tor state (crucial)</li>
-
-This setting prevents both Javascript and accidental user clicks from causing
-the session history to load pages that were fetched in a different Tor state
-than the current one. Since this can be used to correlate Tor and Non-Tor
-activity and thus determine your IP address, it is marked as a crucial
-setting.
-
- <li>Block History Reads during Tor (crucial)</li>
-
- Based on code contributed by <a href="http://www.collinjackson.com/">Collin
- Jackson</a>, when enabled and Tor is enabled, this setting prevents the
-rendering engine from knowing if certain links were visited. This mechanism
-defeats all document-based history disclosure attacks, including CSS-only
-attacks.
-
- <li>Block History Reads during Non-Tor (recommended)</li>
-
- This setting accomplishes the same but for your Non-Tor activity.
-
- <li>Block History Writes during Tor (recommended)</li>
-
- This setting prevents the rendering engine from recording visited URLs, and
-also disables download manager history. Note that if you allow writing of Tor history,
-it is recommended that you disable non-Tor history reads, since malicious
-websites you visit without Tor can query your history for .onion sites and
-other history recorded during Tor usage (such as Google queries).
-
- <li>Block History Writes during Non-Tor (optional)</li>
-
-This setting also disables recording any history information during Non-Tor
-usage.
-
-<li>Clear History During Tor Toggle (optional)</li>
-
- This is an alternate setting to use instead of (or in addition to) blocking
-history reads or writes.
-
- <li>Block Password+Form saving during Tor/Non-Tor</li>
-
- These options govern if the browser writes your passwords and search
- submissions to disk for the given state.
-
- <li>Block Tor disk cache and clear all cache on Tor Toggle</li>
-
- Since the browser cache can be leveraged to store unique identifiers, cache
-must not persist across Tor sessions. This option keeps the memory cache active
-during Tor usage for performance, but blocks disk access for caching.
-
- <li>Block disk and memory cache during Tor</li>
-
- This setting entirely blocks the cache during Tor, but preserves it for
-Non-Tor usage.
-
- <li>Clear Cookies on Tor Toggle</li>
-
- Fully clears all cookies on Tor toggle.
-
- <li>Store Non-Tor cookies in a protected jar</li>
-
- This option stores your persistent Non-Tor cookies in a special cookie jar
- file, in case you wish to preserve some cookies. Based on code contributed
- by <a href="http://www.collinjackson.com/">Collin Jackson</a>. It is
- compatible with third party extensions that you use to manage your Non-Tor
- cookies. Your Tor cookies will be cleared on toggle, of course.
-
- <li>Store both Non-Tor and Tor cookies in a protected jar (dangerous)</li>
-
- This option stores your persistent Tor and Non-Tor cookies
- separate cookie jar files. Note that it is a bad idea to keep Tor
- cookies around for any length of time, as they can be retrieved by exit
- nodes that inject spoofed forms into plaintext pages you fetch.
-
- <li>Manage My Own Cookies (dangerous)</li>
-
- This setting allows you to manage your own cookies with an alternate
-extension, such as <a href="https://addons.mozilla.org/firefox/addon/82">CookieCuller</a>. Note that this is particularly dangerous,
-since malicious exit nodes can spoof document elements that appear to be from
-sites you have preserved cookies for (and can then do things like fetch your
-entire gmail inbox, even if you were not using gmail or visiting any google
-pages at the time!).
-
- <li>Do not write Tor/Non-Tor cookies to disk</li>
-
- These settings prevent Firefox from writing any cookies to disk during the
- corresponding Tor state. If cookie jars are enabled, those jars will
- exist in memory only, and will be cleared when Firefox exits.
-
- <li>Disable DOM Storage during Tor usage (crucial)</li>
-
- Firefox has recently added the ability to store additional state and
- identifiers in persistent tables, called <a
- href="http://developer.mozilla.org/en/docs/DOM:Storage">DOM Storage</a>.
- Obviously this can compromise your anonymity if stored content can be
- fetched across Tor-state.
-
- <li>Clear HTTP auth sessions (recommended)</li>
-
- HTTP authentication credentials can be probed by exit nodes and used to both confirm that you visit a certain site that uses HTTP auth, and also impersonate you on this site.
-
- <li>Clear cookies on Tor/Non-Tor shutdown</li>
-
- These settings install a shutdown handler to clear cookies on Tor
-and/or Non-Tor browser shutdown. It is independent of your Clear Private Data
-settings, and does in fact clear the corresponding cookie jars.
-
- <li>Prevent session store from saving Tor-loaded tabs (recommended)</li>
-
- This option augments the session store to prevent it from writing out
- Tor-loaded tabs to disk. Unfortunately, this also disables your ability to
- undo closed tabs. The reason why this setting is recommended is because
- after a session crash, your browser will be in an undefined Tor state, and
- can potentially load a bunch of Tor tabs without Tor. The following option
- is another alternative to protect against this.
-
- <li>On normal startup, set state to: Tor, Non-Tor, Shutdown State</li>
-
- This setting allows you to choose which Tor state you want the browser to
- start in normally: Tor, Non-Tor, or whatever state the browser shut down in.
-
- <li>On crash recovery or session restored startup, restore via: Tor, Non-Tor</li>
-
- When Firefox crashes, the Tor state upon restart usually is completely
- random, and depending on your choice for the above option, may load
- a bunch of tabs in the wrong state. This setting allows you to choose
- which state the crashed session should always be restored in to.
-
- <li>Prevent session store from saving Non-Tor/Tor-loaded tabs</li>
-
- These two settings allow you to control what the Firefox Session Store
- writes to disk. Since the session store state is used to automatically
- load websites after a crash or upgrade, it is advisable not to allow
- Tor tabs to be written to disk, or they may get loaded in Non-Tor
- after a crash (or the reverse, depending upon the crash recovery setting,
- of course).
-
- <li>Set user agent during Tor usage (crucial)</li>
-
- User agent masking is done with the idea of making all Tor users appear
-uniform. A recent Firefox 2.0.0.4 Windows build was chosen to mimic for this
-string and supporting navigator.* properties, and this version will remain the
-same for all TorButton versions until such time as specific incompatibility
-issues are demonstrated. Uniformity of this value is obviously very important
-to anonymity. Note that for this option to have full effectiveness, the user
-must also allow Hook Dangerous Javascript ensure that the navigator.*
-properties are reset correctly. The browser does not set some of them via the
-exposed user agent override preferences.
-
- <li>Spoof US English Browser</li>
-
-This option causes Firefox to send http headers as if it were an English
-browser. Useful for internationalized users.
-
- <li>Don't send referrer during Tor Usage</li>
-
-This option disables the referrer header, preventing sites from determining
-where you came from to visit them. This can break some sites, however. <a
-href="http://www.digg.com">Digg</a> in particular seemed to be broken by this.
-A more streamlined, less intrusive version of this option should be available
-eventually. In the meantime, <a
-href="https://addons.mozilla.org/en-US/firefox/addon/953">RefControl</a> can
-provide this functionality via a default option of <b>Forge</b>.
-</ul>
-
-
-</body>
-</html>
diff --git a/website/update.rdf b/website/update.rdf
deleted file mode 100644
index fc876730..00000000
--- a/website/update.rdf
+++ /dev/null
@@ -1,173 +0,0 @@
-<?xml version="1.0"?>
-
-<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:em="http://www.mozilla.org/2004/em-rdf#">
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}">
- <em:updates>
- <Seq>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.1.14-alpha"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.1.15-alpha"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.1.16-alpha"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.1.17-alpha"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.1.18alpha"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.0rc1"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.0rc2"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.0rc3"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.0rc4"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.0rc5"/>
- <li resource="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.0rc6"/>
- </Seq>
- </em:updates>
-
-
- <!-- following two lines for Firefox 0.9. Specify the most recent version here -->
- <em:version>1.2.0rc6</em:version>
- <em:updateLink>https://torbutton.torproject.org/dev/releases/torbutton-1.2.0rc6.xpi</em:updateLink>
- </Description>
-
- <!-- version 1.1.14 -->
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.1.14-alpha">
- <em:version>1.1.14-alpha</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>3.0b*</em:maxVersion>
- <em:updateLink>https://torbutton.torproject.org/dev/releases/torbutton-1.1.14-alpha.xpi</em:updateLink>
- <em:updateHash>sha1:b316f9d84930ecf23b0797f93a6433334a4c38d5</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.1.15-alpha">
- <em:version>1.1.15-alpha</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>3.0b*</em:maxVersion>
- <em:updateLink>https://torbutton.torproject.org/dev/releases/torbutton-1.1.15-alpha.xpi</em:updateLink>
- <em:updateHash>sha1:fa0d47c98d258ba904d828bea15b140ab438eb56</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.1.16-alpha">
- <em:version>1.1.16-alpha</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>3.0b*</em:maxVersion>
- <em:updateLink>https://torbutton.torproject.org/dev/releases/torbutton-1.1.16-alpha.xpi</em:updateLink>
- <em:updateHash>sha1:f892dac7e5da8c63005f896c9aa1436e3f77ab4b</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.1.17-alpha">
- <em:version>1.1.17-alpha</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>3.0b*</em:maxVersion>
- <em:updateLink>https://torbutton.torproject.org/dev/releases/torbutton-1.1.17-alpha.xpi</em:updateLink>
- <em:updateHash>sha1:93e17f955655eb31e5a6ff9f71dfde479a5b7a6d</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.1.18alpha">
- <em:version>1.1.18alpha</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>3.0b*</em:maxVersion>
- <em:updateLink>https://torbutton.torproject.org/dev/releases/torbutton-1.1.18alpha.xpi</em:updateLink>
- <em:updateHash>sha1:6fdcebcb1e6cc694b45065c2b6df07ffb12ea164</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.0rc1">
- <em:version>1.2.0rc1</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>3.1a1pre</em:maxVersion>
- <em:updateLink>https://torbutton.torproject.org/dev/releases/torbutton-1.2.0rc1.xpi</em:updateLink>
- <em:updateHash>sha1:8c8cb5e7e3844b8310151c5b56fb622134ea67f6</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.0rc2">
- <em:version>1.2.0rc2</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>3.1a1pre</em:maxVersion>
- <em:updateLink>https://torbutton.torproject.org/dev/releases/torbutton-1.2.0rc2.xpi</em:updateLink>
- <em:updateHash>sha1:f0d6e121e2b0fbd4d1db7c3f333b8d7ab5c1d906</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.0rc3">
- <em:version>1.2.0rc3</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>3.1a1pre</em:maxVersion>
- <em:updateLink>https://torbutton.torproject.org/dev/releases/torbutton-1.2.0rc3.xpi</em:updateLink>
- <em:updateHash>sha1:184294b480119bb7b943ede116345c52ee7772fc</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.0rc4">
- <em:version>1.2.0rc4</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>3.1a1pre</em:maxVersion>
- <em:updateLink>https://torbutton.torproject.org/dev/releases/torbutton-1.2.0rc4.xpi</em:updateLink>
- <em:updateHash>sha1:23df6a12c7140b5817338136da1cd7737412bbbb</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.0rc5">
- <em:version>1.2.0rc5</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>3.1a1pre</em:maxVersion>
- <em:updateLink>https://torbutton.torproject.org/dev/releases/torbutton-1.2.0rc5.xpi</em:updateLink>
- <em:updateHash>sha1:050925e2c02e61f2f0ceb4683600fc0c58a835bb</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
- <Description about="urn:mozilla:extension:{e0204bd5-9d31-402b-a99d-a6aa8ffebdca}:1.2.0rc6">
- <em:version>1.2.0rc6</em:version>
- <em:targetApplication>
- <Description>
- <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
- <em:minVersion>0.9</em:minVersion>
- <em:maxVersion>3.1a1pre</em:maxVersion>
- <em:updateLink>https://torbutton.torproject.org/dev/releases/torbutton-1.2.0rc6.xpi</em:updateLink>
- <em:updateHash>sha1:7f01c577641b6222781cd880c9825d6f50ff1cc4</em:updateHash>
- </Description>
- </em:targetApplication>
- </Description>
-
-</RDF>
1
0

[tor-launcher/master] Bug 29197: Remove use of overlays (ESR68 compatibility).
by gk@torproject.org 07 Aug '19
by gk@torproject.org 07 Aug '19
07 Aug '19
commit 8bc4a8869936cfc782d1f4c749f7608ead6ddf18
Author: Kathy Brade <brade(a)pearlcrescent.com>
Date: Tue Jul 30 16:34:27 2019 -0400
Bug 29197: Remove use of overlays (ESR68 compatibility).
Use the window.MozXULElement.parseXULToFragment() function to
parse shared XUL.
---
src/chrome/content/localePicker.xul | 4 +-
...ings-overlay.xul => network-settings-shared.js} | 48 +++++++++++-----------
src/chrome/content/network-settings-wizard.xul | 10 ++---
src/chrome/content/network-settings.js | 36 ++++++++++++++++
src/chrome/content/network-settings.xul | 18 ++++----
5 files changed, 76 insertions(+), 40 deletions(-)
diff --git a/src/chrome/content/localePicker.xul b/src/chrome/content/localePicker.xul
index 6030468..1d0987c 100644
--- a/src/chrome/content/localePicker.xul
+++ b/src/chrome/content/localePicker.xul
@@ -9,9 +9,7 @@
<?xml-stylesheet href="chrome://torlauncher/skin/network-settings.css"
type="text/css"?>
-<!DOCTYPE overlay SYSTEM "chrome://torlauncher/locale/network-settings.dtd">
-
-<?xul-overlay href="chrome://torlauncher/content/network-settings-overlay.xul"?>
+<!DOCTYPE wizard SYSTEM "chrome://torlauncher/locale/network-settings.dtd">
<wizard id="TorLauncherLocalePicker"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
diff --git a/src/chrome/content/network-settings-overlay.xul b/src/chrome/content/network-settings-shared.js
similarity index 91%
rename from src/chrome/content/network-settings-overlay.xul
rename to src/chrome/content/network-settings-shared.js
index 35b9fc7..206872b 100644
--- a/src/chrome/content/network-settings-overlay.xul
+++ b/src/chrome/content/network-settings-shared.js
@@ -1,16 +1,9 @@
-<?xml version="1.0"?>
-<!--
- - Copyright (c) 2018, The Tor Project, Inc.
- - See LICENSE for licensing information.
- - vim: set sw=2 sts=2 ts=8 et syntax=xml:
- -->
-
-<!DOCTYPE overlay SYSTEM "chrome://torlauncher/locale/network-settings.dtd">
-
-<overlay id="TorNetworkSettingsOverlay"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- xmlns:html="http://www.w3.org/1999/xhtml">
+// Copyright (c) 2019, The Tor Project, Inc.
+// See LICENSE for licensing information.
+//
+// vim: set sw=2 sts=2 ts=8 et syntax=javascript:
+var proxySettings = `
<vbox id="proxySettings">
<hbox align="center">
<checkbox id="useProxy" groupboxID="proxySpecificSettings"
@@ -73,20 +66,16 @@
</grid>
</groupbox>
</vbox>
+`;
- <vbox id="proxyHelpContent">
+var proxyHelpContent = `
+ <vbox id="proxyHelpContent" hidden="true">
<hbox align="middle"><label>&torsettings.proxyHelpTitle;</label></hbox>
<description>&torsettings.proxyHelp1;</description>
</vbox>
+`;
- <groupbox id="firewallSpecificSettings">
- <hbox align="center">
- <label value="&torsettings.firewall.allowedPorts;"
- control="firewallAllowedPorts"/>
- <textbox id="firewallAllowedPorts" value="80,443"/>
- </hbox>
- </groupbox>
-
+var bridgeSettings = `
<vbox id="bridgeSettings">
<checkbox id="useBridges" groupboxID="bridgeSpecificSettings"
label="&torsettings.useBridges.checkbox;"
@@ -139,13 +128,17 @@
</vbox>
</groupbox>
</vbox>
+`;
- <vbox id="bridgeHelpContent">
+var bridgeHelpContent = `
+ <vbox id="bridgeHelpContent" hidden="true">
<hbox align="middle"><label>&torsettings.bridgeHelpTitle;</label></hbox>
<description>&torsettings.bridgeHelp1;</description>
<description>&torsettings.bridgeHelp2;</description>
</vbox>
+`;
+var progressContent = `
<vbox id="progressContent">
<hbox class="tbb-header" pack="center">
<image class="tbb-logo"/>
@@ -159,7 +152,9 @@
value="&torsettings.reconfigTor;"/>
</vbox>
</vbox>
+`;
+var restartContent = `
<vbox id="restartContent">
<hbox pack="center">
<description id="restartPanelMessage" flex="1"/>
@@ -170,7 +165,9 @@
oncommand="onRestartTor()"/>
</hbox>
</vbox>
+`;
+var bridgeDBRequestOverlayContent = `
<vbox id="bridgeDBRequestOverlayContent" align="center">
<vbox>
<label id="bridgeDBPrompt"/>
@@ -200,7 +197,9 @@
</hbox>
</vbox>
</vbox>
+`;
+var errorOverlayContent = `
<vbox id="errorOverlayContent">
<hbox pack="center">
<description errorElemId="message" flex="1"/>
@@ -211,10 +210,11 @@
oncommand="onDismissErrorOverlay()"/>
</hbox>
</vbox>
+`;
+var copyLogFeedbackPanel = `
<panel id="copyLogFeedbackPanel" type="arrow" fade="slow"
onclick="closeCopyLogFeedbackPanel()">
<description flex="1"/>
</panel>
-</overlay>
-
+`;
diff --git a/src/chrome/content/network-settings-wizard.xul b/src/chrome/content/network-settings-wizard.xul
index 00145a8..2eb6d6d 100644
--- a/src/chrome/content/network-settings-wizard.xul
+++ b/src/chrome/content/network-settings-wizard.xul
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<!--
- - Copyright (c) 2018, The Tor Project, Inc.
+ - Copyright (c) 2019, The Tor Project, Inc.
- See LICENSE for licensing information.
- vim: set sw=2 sts=2 ts=8 et syntax=xml:
-->
@@ -9,9 +9,7 @@
<?xml-stylesheet href="chrome://torlauncher/skin/network-settings.css"
type="text/css"?>
-<!DOCTYPE overlay SYSTEM "chrome://torlauncher/locale/network-settings.dtd">
-
-<?xul-overlay href="chrome://torlauncher/content/network-settings-overlay.xul"?>
+<!DOCTYPE wizard SYSTEM "chrome://torlauncher/locale/network-settings.dtd">
<wizard id="TorNetworkSettings"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
@@ -127,8 +125,8 @@
<wizardpage class="help" pageid="helpPanel" next="notUsed"
onpageadvanced="closeHelp(); return false;">
- <vbox id="bridgeHelpContent" hidden="true"/>
- <vbox id="proxyHelpContent" hidden="true"/>
+ <vbox id="bridgeHelpContent"/>
+ <vbox id="proxyHelpContent"/>
</wizardpage>
<hbox pack="start">
diff --git a/src/chrome/content/network-settings.js b/src/chrome/content/network-settings.js
index b39a194..85dade2 100644
--- a/src/chrome/content/network-settings.js
+++ b/src/chrome/content/network-settings.js
@@ -10,6 +10,7 @@ const Ci = Components.interfaces;
const Cu = Components.utils;
const Cr = Components.results;
+Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "TorLauncherUtil",
"resource://torlauncher/modules/tl-util.jsm");
@@ -116,6 +117,8 @@ var gBridgeDBRequestEventListeners = [];
function initDialogCommon()
{
+ loadSharedXUL();
+
gObsService = Cc["@mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
@@ -158,6 +161,39 @@ function initDialogCommon()
}
+function loadSharedXUL()
+{
+ let ctxt = {};
+ Services.scriptloader.loadSubScript(
+ "chrome://torlauncher/content/network-settings-shared.js", ctxt);
+
+ let elementIDs =
+ [
+ "proxySettings",
+ "proxyHelpContent",
+ "bridgeSettings",
+ "bridgeHelpContent",
+ "progressContent",
+ "restartContent",
+ "bridgeDBRequestOverlayContent",
+ "errorOverlayContent",
+ "copyLogFeedbackPanel",
+ ];
+
+ let entityURLs = ["chrome://torlauncher/locale/network-settings.dtd"];
+ elementIDs.forEach(aID =>
+ {
+ let node = document.getElementById(aID);
+ if (node)
+ {
+ let xulStr = ctxt[aID];
+ let frag = window.MozXULElement.parseXULToFragment(xulStr, entityURLs);
+ node.parentNode.replaceChild(frag, node);
+ }
+ });
+}
+
+
function resizeDialogToFitContent()
{
// Resize this window to fit content. sizeToContent() alone will not do
diff --git a/src/chrome/content/network-settings.xul b/src/chrome/content/network-settings.xul
index 6f95183..2ba0741 100644
--- a/src/chrome/content/network-settings.xul
+++ b/src/chrome/content/network-settings.xul
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<!--
- - Copyright (c) 2018, The Tor Project, Inc.
+ - Copyright (c) 2019, The Tor Project, Inc.
- See LICENSE for licensing information.
- vim: set sw=2 sts=2 ts=8 et syntax=xml:
-->
@@ -9,9 +9,7 @@
<?xml-stylesheet href="chrome://torlauncher/skin/network-settings.css"
type="text/css"?>
-<!DOCTYPE overlay SYSTEM "chrome://torlauncher/locale/network-settings.dtd">
-
-<?xul-overlay href="chrome://torlauncher/content/network-settings-overlay.xul"?>
+<!DOCTYPE dialog SYSTEM "chrome://torlauncher/locale/network-settings.dtd">
<dialog id="TorNetworkSettings"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
@@ -41,7 +39,13 @@
groupboxID="firewallSpecificSettings"
label="&torsettings.firewall.checkbox;"
oncommand="toggleElemUI(this)"/>
- <groupbox id="firewallSpecificSettings"/>
+ <groupbox id="firewallSpecificSettings">
+ <hbox align="center">
+ <label value="&torsettings.firewall.allowedPorts;"
+ control="firewallAllowedPorts"/>
+ <textbox id="firewallAllowedPorts" value="80,443"/>
+ </hbox>
+ </groupbox>
</vbox>
</vbox>
@@ -60,8 +64,8 @@
</vbox>
<vbox id="helpPanel" class="help">
- <vbox id="bridgeHelpContent" hidden="true"/>
- <vbox id="proxyHelpContent" hidden="true"/>
+ <vbox id="bridgeHelpContent"/>
+ <vbox id="proxyHelpContent"/>
</vbox>
<vbox id="restartPanel" class="messagePanel" pack="center">
1
0

[tor-launcher/master] Bug 31300: Modify Tor Launcher so it is compatible with ESR68
by gk@torproject.org 07 Aug '19
by gk@torproject.org 07 Aug '19
07 Aug '19
commit 1af54380f289426fea9dfa24c4fd6cf171046723
Author: Kathy Brade <brade(a)pearlcrescent.com>
Date: Fri Aug 2 10:23:31 2019 -0400
Bug 31300: Modify Tor Launcher so it is compatible with ESR68
Replace some wizard and dialog "on" attributes with event handlers.
Replace the XUL listbox element (which was removed by Mozilla) with
richlistbox.
Replace the XUL progressmeter element (which was removed by Mozilla) with
an HTML progress element.
Define our own CSS rules for groupbox elements (Mozilla removed the
built-in styles).
Fix some minor CSS incompatibilities.
---
src/chrome/content/localePicker.xul | 6 +-
src/chrome/content/network-settings-shared.js | 8 +--
src/chrome/content/network-settings-wizard.xul | 24 +++-----
src/chrome/content/network-settings.js | 76 +++++++++++++++++++++++---
src/chrome/content/network-settings.xul | 3 -
src/chrome/skin/network-settings.css | 14 +++--
6 files changed, 92 insertions(+), 39 deletions(-)
diff --git a/src/chrome/content/localePicker.xul b/src/chrome/content/localePicker.xul
index 1d0987c..152b54c 100644
--- a/src/chrome/content/localePicker.xul
+++ b/src/chrome/content/localePicker.xul
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<!--
- - Copyright (c) 2017, The Tor Project, Inc.
+ - Copyright (c) 2019, The Tor Project, Inc.
- See LICENSE for licensing information.
- vim: set sw=2 sts=2 ts=8 et syntax=xml:
-->
@@ -16,8 +16,6 @@
title="&torlauncher.localePicker.title;"
windowtype="TorLauncher:LocalePicker"
persist="screenX screenY"
- onwizardfinish="return setLocale();"
- onwizardcancel="return onCancel();"
onload="initLocaleDialog();">
<script type="application/x-javascript"
@@ -31,7 +29,7 @@
<vbox>
<label class="question">&torlauncher.localePicker.prompt;</label>
<separator/>
- <listbox id="localeList" ondblclick="onLocaleListDoubleClick()"/>
+ <richlistbox id="localeList" ondblclick="onLocaleListDoubleClick()"/>
</vbox>
</wizardpage>
diff --git a/src/chrome/content/network-settings-shared.js b/src/chrome/content/network-settings-shared.js
index 206872b..f1bdb91 100644
--- a/src/chrome/content/network-settings-shared.js
+++ b/src/chrome/content/network-settings-shared.js
@@ -20,7 +20,7 @@ var proxySettings = `
<rows>
<row align="center">
<label value="&torsettings.useProxy.type;" control="proxyType"
- style="text-align:right"/>
+ class="rightAlign"/>
<hbox align="center">
<menulist id="proxyType" sizetopopup="always"
placeholder="&torsettings.useProxy.type.placeholder;"
@@ -38,7 +38,7 @@ var proxySettings = `
</row>
<row align="center">
<label value="&torsettings.useProxy.address;" control="proxyAddr"
- style="text-align:right"/>
+ class="rightAlign"/>
<hbox align="center">
<textbox id="proxyAddr" size="20" flex="1"
placeholder="&torsettings.useProxy.address.placeholder;"/>
@@ -50,7 +50,7 @@ var proxySettings = `
<row align="center">
<label id="proxyUsernameLabel"
value="&torsettings.useProxy.username;"
- control="proxyUsername" style="text-align:right"/>
+ control="proxyUsername" class="rightAlign"/>
<hbox align="center">
<textbox id="proxyUsername" size="14" flex="1"
placeholder="&torsettings.optional;"/>
@@ -146,7 +146,7 @@ var progressContent = `
<vbox flex="1">
<description id="progressPleaseWait"
hidden="true">&torprogress.pleaseWait;</description>
- <progressmeter id="progressMeter" mode="determined" value="0"/>
+ <html:progress id="progressMeter" value="0" max="100"/>
<description id="progressDesc" errorElemId="message"/>
<label id="progressReconfigureLabel" hidden="true"
value="&torsettings.reconfigTor;"/>
diff --git a/src/chrome/content/network-settings-wizard.xul b/src/chrome/content/network-settings-wizard.xul
index 2eb6d6d..ec48bd0 100644
--- a/src/chrome/content/network-settings-wizard.xul
+++ b/src/chrome/content/network-settings-wizard.xul
@@ -1,4 +1,3 @@
-<?xml version="1.0"?>
<!--
- Copyright (c) 2019, The Tor Project, Inc.
- See LICENSE for licensing information.
@@ -17,15 +16,13 @@
windowtype="TorLauncher:NetworkSettings"
persist="screenX screenY"
buttonlabelextra2="&torsettings.copyLog;"
- onwizardfinish="return onWizardFinish();"
- onwizardcancel="return onCancel();"
onload="initDialog();"
onunload="deinitDialog();">
<script type="application/x-javascript"
src="chrome://torlauncher/content/network-settings.js"/>
- <wizardpage pageid="first" next="configureSettings" onextra2="onCopyLog();"
+ <wizardpage pageid="first" next="configureSettings"
torShowNavButtons="false">
<hbox class="tbb-header" pack="center">
<image class="tbb-logo"/>
@@ -44,7 +41,7 @@
</vbox>
</wizardpage>
- <wizardpage pageid="configureSettings" onextra2="onCopyLog();"
+ <wizardpage pageid="configureSettings"
windowtitle="&torsettings.wizard.title.configure;"
torShowNavButtons="true">
<stack flex="1">
@@ -63,11 +60,9 @@
</stack>
</wizardpage>
- <wizardpage pageid="progress" onextra2="onCopyLog();"
+ <wizardpage pageid="progress"
windowtitle="&torsettings.wizard.title.connecting;"
- torShowNavButtons="false"
- onpageshow="onShowProgressPanel();"
- onpagehide="return resetProgressNavButtons();">
+ torShowNavButtons="false">
<vbox id="progressContent"/>
</wizardpage>
@@ -86,12 +81,12 @@
</wizardpage>
<wizardpage pageid="restartPanel" class="messagePanel" next="notUsed"
- pack="center" torShowNavButtons="false" onextra2="onCopyLog();">
+ pack="center" torShowNavButtons="false">
<vbox id="restartContent"/>
</wizardpage>
<wizardpage pageid="errorPanel" class="messagePanel" next="notUsed"
- torShowNavButtons="false" onextra2="onCopyLog();">
+ torShowNavButtons="false">
<spring flex="1"/>
<hbox pack="center">
<description errorElemId="message" flex="1"/>
@@ -104,8 +99,8 @@
<spring flex="1"/>
</wizardpage>
- <wizardpage pageid="discardSettings" next="notUsed" torShowNavButtons="false"
- onextra2="onCopyLog();">
+ <wizardpage pageid="discardSettings" next="notUsed"
+ torShowNavButtons="false">
<hbox class="tbb-header" pack="center">
<image class="tbb-logo"/>
</hbox>
@@ -123,8 +118,7 @@
<spring flex="1"/>
</wizardpage>
- <wizardpage class="help" pageid="helpPanel" next="notUsed"
- onpageadvanced="closeHelp(); return false;">
+ <wizardpage class="help" pageid="helpPanel" next="notUsed">
<vbox id="bridgeHelpContent"/>
<vbox id="proxyHelpContent"/>
</wizardpage>
diff --git a/src/chrome/content/network-settings.js b/src/chrome/content/network-settings.js
index 85dade2..a4f2866 100644
--- a/src/chrome/content/network-settings.js
+++ b/src/chrome/content/network-settings.js
@@ -157,6 +157,51 @@ function initDialogCommon()
.getService(Ci.nsIEnvironment);
if (env.exists("TOR_HIDE_BROWSER_LOGO"))
wizardElem.setAttribute("tor_hide_browser_logo", true);
+
+ // Add wizard event listeners.
+ document.addEventListener("wizardcancel", (aEvent) => {
+ if (!onCancel())
+ aEvent.preventDefault();
+ });
+
+ document.addEventListener("pageadvanced", (aEvent) => {
+ if ("helpPanel" == wizardElem.currentPage.pageid)
+ {
+ closeHelp();
+ aEvent.preventDefault();
+ }
+ });
+
+ document.addEventListener("pageshow", (aEvent) => {
+ if (kWizardProgressPageID == wizardElem.currentPage.pageid)
+ onShowProgressPanel();
+ });
+
+ document.addEventListener("pagehide", (aEvent) => {
+ if (kWizardProgressPageID == wizardElem.currentPage.pageid)
+ resetProgressNavButtons();
+ });
+
+ document.addEventListener("extra2", (aEvent) => {
+ onCopyLog();
+ });
+ }
+ else
+ {
+ // Add network settings dialog event listeners.
+ document.addEventListener("dialogaccept", (aEvent) => {
+ if (!onNetworkSettingsFinish())
+ aEvent.preventDefault();
+ });
+
+ document.addEventListener("dialogcancel", (aEvent) => {
+ if (!onCancel())
+ aEvent.preventDefault();
+ });
+
+ document.addEventListener("dialogextra2", (aEvent) => {
+ onCopyLog();
+ });
}
}
@@ -239,6 +284,12 @@ function initDialog()
let haveWizard = (wizardElem != null);
if (haveWizard)
{
+ // Add wizardfinish event handler.
+ document.addEventListener("wizardfinish", (aEvent) => {
+ if (!onWizardFinish())
+ aEvent.preventDefault();
+ });
+
// Relabel the accept button to be "Connect"
let okBtn = document.documentElement.getButton("accept");
if (okBtn)
@@ -316,6 +367,11 @@ function initLocaleDialog()
{
initDialogCommon();
+ // Add wizardfinish event handler.
+ document.addEventListener("wizardfinish", (aEvent) => {
+ setLocale();
+ });
+
// Replace the finish button's label ("Done") with the next button's
// label ("Next" or "Continue").
let nextBtn = document.documentElement.getButton("next");
@@ -324,7 +380,8 @@ function initLocaleDialog()
doneBtn.label = nextBtn.label;
let { AddonManager } = Cu.import("resource://gre/modules/AddonManager.jsm");
- AddonManager.getAddonsByTypes(["locale"], function(aLangPackAddons)
+ let addonsPromise = AddonManager.getAddonsByTypes(["locale"]);
+ addonsPromise.then(aLangPackAddons =>
{
populateLocaleList(aLangPackAddons);
resizeDialogToFitContent();
@@ -421,13 +478,15 @@ function populateLocaleList(aLangPackAddons)
langInfo.splice(0, 0,
{ langCode: code, langName: name, isSelected: isSelected });
- // Populate the XUL listbox.
+ // Populate the XUL richlistbox.
let localeList = document.getElementById(kLocaleList);
for (let infoObj of langInfo)
{
- let listItem = document.createElement("listitem");
+ let listItem = document.createElement("richlistitem");
listItem.setAttribute("value", infoObj.langCode);
- listItem.setAttribute("label", infoObj.langName);
+ let label = document.createElement("label");
+ label.value = infoObj.langName;
+ listItem.appendChild(label);
localeList.appendChild(listItem);
if (infoObj.isSelected)
localeList.selectedItem = listItem;
@@ -807,7 +866,6 @@ function resetProgressNavButtons()
restoreButtonLabel("finish");
showOrHideButton("cancel", true, false);
- return true;
}
@@ -905,7 +963,7 @@ function updateBootstrapProgress(aStatusObj)
let meter = document.getElementById("progressMeter");
if (meter)
{
- meter.value = percentComplete;
+ meter.setAttribute("value", percentComplete);
showProgressMeterIfNoError();
}
@@ -1968,7 +2026,7 @@ function showProgressPanel()
let meter = document.getElementById("progressMeter");
if (meter)
{
- meter.value = 0;
+ meter.setAttribute("value", 0);
meter.style.visibility = "hidden";
}
@@ -2428,7 +2486,7 @@ function setElemValue(aID, aValue)
}
// fallthru
case "menulist":
- case "listbox":
+ case "richlistbox":
case "label":
elem.value = (val) ? val : "";
break;
@@ -2482,7 +2540,7 @@ function getElemValue(aID, aDefaultValue)
break;
case "textbox":
case "menulist":
- case "listbox":
+ case "richlistbox":
rv = elem.value;
break;
}
diff --git a/src/chrome/content/network-settings.xul b/src/chrome/content/network-settings.xul
index 2ba0741..6a8fac4 100644
--- a/src/chrome/content/network-settings.xul
+++ b/src/chrome/content/network-settings.xul
@@ -18,9 +18,6 @@
persist="screenX screenY"
buttons="accept,cancel,extra2"
buttonlabelextra2="&torsettings.copyLog;"
- ondialogaccept="return onNetworkSettingsFinish();"
- ondialogcancel="return onCancel();"
- ondialogextra2="onCopyLog();"
onload="initDialog();"
onunload="deinitDialog();">
diff --git a/src/chrome/skin/network-settings.css b/src/chrome/skin/network-settings.css
index 40ca0f0..9fed4f2 100644
--- a/src/chrome/skin/network-settings.css
+++ b/src/chrome/skin/network-settings.css
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, The Tor Project, Inc.
+ * Copyright (c) 2019, The Tor Project, Inc.
* See LICENSE for licensing information.
*
* vim: set sw=2 sts=2 ts=8 et syntax=css:
@@ -47,8 +47,14 @@ wizard label {
margin: 0px;
}
-wizard radiogroup {
- margin: 5px 0px 8px 25px;
+.rightAlign {
+ text-align: right;
+}
+
+groupbox {
+ margin-left: 16px;
+ padding: 8px;
+ border: 1px solid GrayText;
}
.tbb-header groupbox {
@@ -57,7 +63,7 @@ wizard radiogroup {
margin-bottom: 0px;
}
-.firstResponses label {
+.firstResponses > label {
text-align: center;
margin-top: 1.2em;
}
1
0

[tor-browser/tor-browser-60.8.0esr-9.0-1] Bug 31344: Actually register SecurityLevelPreference's 'unload' callback in privacy.js
by gk@torproject.org 07 Aug '19
by gk@torproject.org 07 Aug '19
07 Aug '19
commit d48c3fa6ace654296c78210e370838bcaaf4078c
Author: Richard Pospesel <richard(a)torproject.org>
Date: Mon Aug 5 15:44:15 2019 -0700
Bug 31344: Actually register SecurityLevelPreference's 'unload' callback in privacy.js
---
browser/components/preferences/in-content/privacy.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/browser/components/preferences/in-content/privacy.js b/browser/components/preferences/in-content/privacy.js
index d2229d136261..3997f22d63ad 100644
--- a/browser/components/preferences/in-content/privacy.js
+++ b/browser/components/preferences/in-content/privacy.js
@@ -161,6 +161,7 @@ var gPrivacyPane = {
window.removeEventListener("unload", unload);
SecurityLevelPreferences.uninit();
};
+ window.addEventListener("unload", unload);
},
/**
1
0

[tor-browser-build/master] Bug 30736: Install yasm from wheezy-backports
by gk@torproject.org 07 Aug '19
by gk@torproject.org 07 Aug '19
07 Aug '19
commit 0a8ab5b289753683cf9a5bfae3bd6e24b463eeb1
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Fri Aug 2 06:01:54 2019 +0200
Bug 30736: Install yasm from wheezy-backports
---
projects/firefox/config | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/projects/firefox/config b/projects/firefox/config
index 0b340f5..14be6ef 100644
--- a/projects/firefox/config
+++ b/projects/firefox/config
@@ -58,6 +58,15 @@ targets:
arch_deps:
- openjdk-8-jdk
+ linux:
+ var:
+ post_pkginst: |
+ # Firefox ESR68 needs Yasm >= 1.2.0 which Debian Wheezy ships in backports.
+ echo 'deb http://archive.debian.org/debian/ wheezy-backports main' >> /etc/apt/sources.list
+ export DEBIAN_FRONTEND=noninteractive
+ apt-get update
+ apt-get install -t wheezy-backports -y yasm
+
linux-x86_64:
var:
martools_filename: mar-tools-linux64.zip
1
0

02 Aug '19
commit 2a34a082c587eb21e5880406a5fd6ac8c8425234
Author: Georg Koppen <gk(a)torproject.org>
Date: Fri May 31 16:50:24 2019 +0000
Bug 30701: Adding node project
---
projects/node/build | 24 ++++++++++++++++++++++++
projects/node/config | 17 +++++++++++++++++
2 files changed, 41 insertions(+)
diff --git a/projects/node/build b/projects/node/build
new file mode 100644
index 0000000..0e6ca04
--- /dev/null
+++ b/projects/node/build
@@ -0,0 +1,24 @@
+#!/bin/bash
+[% c("var/set_default_env") -%]
+[% IF c("var/linux") %]
+ # We need a link to our GCC, otherwise the system cc gets used which points to
+ # /usr/bin/gcc.
+ [% pc('gcc', 'var/setup', { compiler_tarfile => c('input_files_by_name/gcc'),
+ hardened_gcc => 0 }) %]
+ ln -s gcc /var/tmp/dist/gcc/bin/cc
+ tar -C /var/tmp/dist -xf $rootdir/[% c('input_files_by_name/binutils') %]
+ export PATH="/var/tmp/dist/binutils/bin:$PATH"
+[% END -%]
+distdir=/var/tmp/dist/[% project %]
+tar -xf [% project %]-[% c('version') %].tar.xz
+cd [% project %]-[% c('version') %]
+
+./configure --prefix=$distdir
+make -j[% c("buildconf/num_procs") %]
+make install
+
+cd /var/tmp/dist
+[% c('tar', {
+ tar_src => [ project ],
+ tar_args => '-czf ' _ dest_dir _ '/' _ c('filename'),
+ }) %]
diff --git a/projects/node/config b/projects/node/config
new file mode 100644
index 0000000..e023380
--- /dev/null
+++ b/projects/node/config
@@ -0,0 +1,17 @@
+# vim: filetype=yaml sw=2
+version: v10.16.0
+filename: '[% project %]-[% c("version") %]-[% c("var/build_id") %].tar.gz'
+var:
+ container:
+ use_container: 1
+
+input_files:
+ - project: container-image
+ - project: binutils
+ name: binutils
+ enable: '[% c("var/linux") %]'
+ - project: '[% c("var/compiler") %]'
+ name: '[% c("var/compiler") %]'
+ enable: '[% c("var/linux") %]'
+ - URL: 'https://nodejs.org/download/release/[% c("version") %]/node-[% c("version") %].tar.xz'
+ sha256sum: 18e37f891d10ea7fbc8f6410c444c2b1d9cc3cbbb1d35aa9c41f761816956608
1
0

02 Aug '19
commit 460d5ef80d2bb7ebf808574d21ec7fe43dd9dd01
Author: Georg Koppen <gk(a)torproject.org>
Date: Sun Jun 2 20:33:22 2019 +0000
Bug 30734: Add nasm project
---
projects/nasm/build | 24 ++++++++++++++++++++++++
projects/nasm/config | 17 +++++++++++++++++
2 files changed, 41 insertions(+)
diff --git a/projects/nasm/build b/projects/nasm/build
new file mode 100644
index 0000000..0e6ca04
--- /dev/null
+++ b/projects/nasm/build
@@ -0,0 +1,24 @@
+#!/bin/bash
+[% c("var/set_default_env") -%]
+[% IF c("var/linux") %]
+ # We need a link to our GCC, otherwise the system cc gets used which points to
+ # /usr/bin/gcc.
+ [% pc('gcc', 'var/setup', { compiler_tarfile => c('input_files_by_name/gcc'),
+ hardened_gcc => 0 }) %]
+ ln -s gcc /var/tmp/dist/gcc/bin/cc
+ tar -C /var/tmp/dist -xf $rootdir/[% c('input_files_by_name/binutils') %]
+ export PATH="/var/tmp/dist/binutils/bin:$PATH"
+[% END -%]
+distdir=/var/tmp/dist/[% project %]
+tar -xf [% project %]-[% c('version') %].tar.xz
+cd [% project %]-[% c('version') %]
+
+./configure --prefix=$distdir
+make -j[% c("buildconf/num_procs") %]
+make install
+
+cd /var/tmp/dist
+[% c('tar', {
+ tar_src => [ project ],
+ tar_args => '-czf ' _ dest_dir _ '/' _ c('filename'),
+ }) %]
diff --git a/projects/nasm/config b/projects/nasm/config
new file mode 100644
index 0000000..ff82004
--- /dev/null
+++ b/projects/nasm/config
@@ -0,0 +1,17 @@
+# vim: filetype=yaml sw=2
+version: 2.14.02
+filename: '[% project %]-[% c("version") %]-[% c("var/build_id") %].tar.gz'
+var:
+ container:
+ use_container: 1
+
+input_files:
+ - project: container-image
+ - project: binutils
+ name: binutils
+ enable: '[% c("var/linux") %]'
+ - project: '[% c("var/compiler") %]'
+ name: '[% c("var/compiler") %]'
+ enable: '[% c("var/linux") %]'
+ - URL: 'https://www.nasm.us/pub/nasm/releasebuilds/[% c("version") %]/nasm-[% c("version") %].tar.xz'
+ sha256sum: e24ade3e928f7253aa8c14aa44726d1edf3f98643f87c9d72ec1df44b26be8f5
1
0

[tor-browser/tor-browser-60.8.0esr-9.0-1] Bug 31251: Security Level button UI polish
by gk@torproject.org 01 Aug '19
by gk@torproject.org 01 Aug '19
01 Aug '19
commit 0bed1d181d0839f058e311c01dbdb263a96270fd
Author: Richard Pospesel <richard(a)torproject.org>
Date: Tue Jul 30 11:32:31 2019 -0700
Bug 31251: Security Level button UI polish
Changed the anchor to toolbarbutton's anonymous child toolbarbutton-icon
xul:image element so that the security level panel has the same vertical
alignment as other built-in toolbar buttons. Also needed to add the
badged-button class to our toolbar button for this to align properly.
Now setting and deleting the "open" attribute from the toolbarbutton
element so that it maintains the "pushed" style while the security level
panel is open.
Changed the toolbarbutton's oncommand callback to onmousedown to match
the behaviour of firefox's other toolbarbuttons. Security level panel
now opens on mouse press rather than on mouse press and release.
Slightly re-arranged the ordering of the SecurityLevelPanel object's
method definitions so that callbacks appear in a contiguous block to
better match the other objects defined in securityLevel.js
Removed unnecessary async modifier from
SecurityLevelPanel.openAdvancedSecuritySettings().
Fixed a few typos, improved comments, and removed trailing whitespace.
---
.../securitylevel/content/securityLevel.js | 92 ++++++++++++++++------
.../content/securityLevelButton.inc.xul | 4 +-
.../content/securityLevelPanel.inc.xul | 5 +-
3 files changed, 73 insertions(+), 28 deletions(-)
diff --git a/browser/components/securitylevel/content/securityLevel.js b/browser/components/securitylevel/content/securityLevel.js
index e37f2d49175b..25f6423bc6d3 100644
--- a/browser/components/securitylevel/content/securityLevel.js
+++ b/browser/components/securitylevel/content/securityLevel.js
@@ -124,7 +124,7 @@ const SecurityLevelPrefs = {
set securityCustom(val) {
Services.prefs.setBoolPref(this.security_custom_pref, val);
},
-};
+}; /* Security Level Prefs */
/*
Security Level Button Code
@@ -134,6 +134,8 @@ const SecurityLevelPrefs = {
const SecurityLevelButton = {
_securityPrefsBranch : null,
+ _button : null,
+ _anchor : null,
_populateXUL : function(securityLevelButton) {
if (securityLevelButton != null) {
@@ -164,11 +166,38 @@ const SecurityLevelButton = {
}
},
+ get button() {
+ if (this._button) {
+ return this._button;
+ }
+
+ let button = document.getElementById("security-level-button");
+ if (!button) {
+ return null;
+ }
+
+ return this._button = button;
+ },
+
+ get anchor() {
+ if (this._anchor) {
+ return this._anchor;
+ }
+
+ let anchor = document.getAnonymousElementByAttribute(this.button, "class",
+ "toolbarbutton-icon");
+ if (!anchor) {
+ return null;
+ }
+
+ anchor.setAttribute("consumeanchor", SecurityLevelButton.button.id);
+ return this._anchor = anchor;
+ },
+
init : function() {
// set the initial class based off of the current pref
- let button = document.getElementById("security-level-button");
- this._populateXUL(button);
- this._configUIFromPrefs(button);
+ this._populateXUL(this.button);
+ this._configUIFromPrefs(this.button);
this._securityPrefsBranch = Services.prefs.getBranch("extensions.torbutton.");
this._securityPrefsBranch.addObserver("", this, false);
@@ -191,13 +220,13 @@ const SecurityLevelButton = {
switch(topic) {
case "nsPref:changed":
if (data == "security_slider") {
- this._configUIFromPrefs(document.getElementById("security-level-button"));
+ this._configUIFromPrefs(this.button);
}
break;
}
},
- // callbacks for entering the 'Customize Firefox' screen to set icon
+ // callback for entering the 'Customize Firefox' screen to set icon
onCustomizeStart : function(window) {
let navigatorToolbox = document.getElementById("navigator-toolbox");
let button = navigatorToolbox.palette.querySelector("#security-level-button");
@@ -210,14 +239,20 @@ const SecurityLevelButton = {
if (aNode.id == "security-level-button" && !aWasRemoval) {
this._populateXUL(aNode);
this._configUIFromPrefs(aNode);
+ // clear out our cached elements as they seem to be recreated when the UI is customized
+ delete this._button;
+ delete this._anchor;
}
},
// when toolbar button is pressed
- onCommand : function(anchor, event) {
- SecurityLevelPanel.show(anchor);
+ onCommand : function(event) {
+ // we need to set this attribute for the button to be shaded correctly to look like it is pressed
+ // while the security level panel is open
+ this.button.setAttribute("open", "true");
+ SecurityLevelPanel.show(event);
},
-};
+}; /* Security Level Button */
/*
Security Level Panel Code
@@ -305,19 +340,16 @@ const SecurityLevelPanel = {
this._securityPrefsBranch = null;
},
- show : function(anchor) {
+ show : function() {
// we have to defer this until after the browser has finished init'ing before
// we can populate the panel
if (!this._populated) {
this._populateXUL();
}
- // save off anchor in case we want to show from our own code
- this._anchor = anchor;
-
let panel = document.getElementById("securityLevel-panel");
panel.hidden = false;
- PanelMultiView.openPopup(panel, anchor, "bottomcenter topright",
+ PanelMultiView.openPopup(panel, SecurityLevelButton.anchor, "bottomcenter topright",
0, 0, false, null).catch(Cu.reportError);
},
@@ -326,7 +358,19 @@ const SecurityLevelPanel = {
PanelMultiView.hidePopup(panel);
},
- // when prefs change
+ restoreDefaults : function() {
+ SecurityLevelPrefs.securityCustom = false;
+ // hide and reshow so that layout re-renders properly
+ this.hide();
+ this.show(this._anchor);
+ },
+
+ openAdvancedSecuritySettings : function() {
+ openPreferences("privacy-securitylevel");
+ this.hide();
+ },
+
+ // callback when prefs change
observe : function(subject, topic, data) {
switch(topic) {
case "nsPref:changed":
@@ -337,18 +381,16 @@ const SecurityLevelPanel = {
}
},
- restoreDefaults : function() {
- SecurityLevelPrefs.securityCustom = false;
- // hide and reshow so that layout re-renders properly
- this.hide();
- this.show(this._anchor);
+ // callback when the panel is displayed
+ onPopupShown : function(event) {
+ SecurityLevelButton.button.setAttribute("open", "true");
},
- openAdvancedSecuritySettings : async function() {
- openPreferences("privacy-securitylevel");
- this.hide();
+ // callback when the panel is hidden
+ onPopupHidden : function(event) {
+ SecurityLevelButton.button.removeAttribute("open");
}
-};
+}; /* Security Level Panel */
/*
Security Level Preferences Code
@@ -507,7 +549,7 @@ const SecurityLevelPreferences =
restoreDefaults : function() {
SecurityLevelPrefs.securityCustom = false;
},
-};
+}; /* Security Level Prefereces */
Object.defineProperty(this, "SecurityLevelButton", {
value: SecurityLevelButton,
diff --git a/browser/components/securitylevel/content/securityLevelButton.inc.xul b/browser/components/securitylevel/content/securityLevelButton.inc.xul
index 4ad26f4142bd..579a55f46d4a 100644
--- a/browser/components/securitylevel/content/securityLevelButton.inc.xul
+++ b/browser/components/securitylevel/content/securityLevelButton.inc.xul
@@ -1,5 +1,5 @@
-<toolbarbutton id="security-level-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
+<toolbarbutton id="security-level-button" class="toolbarbutton-1 chromeclass-toolbar-additional badged-button"
removable="true"
- oncommand="SecurityLevelButton.onCommand(this, event);"
+ onmousedown="SecurityLevelButton.onCommand();"
closemenu="none"
cui-areatype="toolbar"/>
diff --git a/browser/components/securitylevel/content/securityLevelPanel.inc.xul b/browser/components/securitylevel/content/securityLevelPanel.inc.xul
index 532e8dd98b32..6a00e811a6ac 100644
--- a/browser/components/securitylevel/content/securityLevelPanel.inc.xul
+++ b/browser/components/securitylevel/content/securityLevelPanel.inc.xul
@@ -3,7 +3,10 @@
type="arrow"
orient="vertical"
level="top"
- hidden="true">
+ hidden="true"
+ onpopupshown="SecurityLevelPanel.onPopupShown(event);"
+ onpopuphidden="SecurityLevelPanel.onPopupHidden(event);"
+ >
<panelmultiview mainViewId="securityLevel-panelview">
<panelview id="securityLevel-panelview" descriptionheightworkaround="true">
<vbox class="panel-subview-body">
1
0

[tor-browser-build/master] Merge remote-tracking branch 'boklm/bug_30585_v2'
by gk@torproject.org 31 Jul '19
by gk@torproject.org 31 Jul '19
31 Jul '19
commit 7b6444dd34d7a9e32d619c194e078464529fd5c1
Merge: 525e93a 4c2b3a9
Author: Georg Koppen <gk(a)torproject.org>
Date: Wed Jul 31 09:27:04 2019 +0000
Merge remote-tracking branch 'boklm/bug_30585_v2'
keyring/clang.gpg | Bin 0 -> 7186 bytes
projects/clang/build | 45 ++
projects/clang/config | 45 ++
projects/clang/win-patches/llvm-objcopy-1.patch | 27 +
projects/clang/win-patches/llvm-objcopy-10.patch | 28 +
projects/clang/win-patches/llvm-objcopy-11.patch | 377 +++++++++++++
projects/clang/win-patches/llvm-objcopy-12.patch | 43 ++
projects/clang/win-patches/llvm-objcopy-2.patch | 665 +++++++++++++++++++++++
projects/clang/win-patches/llvm-objcopy-3.patch | 160 ++++++
projects/clang/win-patches/llvm-objcopy-4.patch | 222 ++++++++
projects/clang/win-patches/llvm-objcopy-5.patch | 61 +++
projects/clang/win-patches/llvm-objcopy-6.patch | 242 +++++++++
projects/clang/win-patches/llvm-objcopy-7.patch | 224 ++++++++
projects/clang/win-patches/llvm-objcopy-8.patch | 330 +++++++++++
projects/clang/win-patches/llvm-objcopy-9.patch | 260 +++++++++
15 files changed, 2729 insertions(+)
1
0

[tor-browser-build/master] Bug 30585: Provide clang 8 for Tor Browser 9
by gk@torproject.org 31 Jul '19
by gk@torproject.org 31 Jul '19
31 Jul '19
commit 4c2b3a98e04605ce7fcbd1c2c7c4864c6a5125a2
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu May 23 12:02:51 2019 +0000
Bug 30585: Provide clang 8 for Tor Browser 9
Adding a clang project is mainly motivated by getting our
mingw-w64/clang toolchain for Windows set up (#28716). Clang is a
separate project and will replace the llvm one (which we use in parallel
for now) as we don't want to build the clang part every time, say, the
ming-w64 commit gets updated. Moreover, we need a recent enough clang on
the host system for building at least the Stylo part in Firefox anyway.
The patches for Windows and general set up is more or less following
build/build-clang/clang-8-mingw.json on the mozilla-esr68 branch.
---
keyring/clang.gpg | Bin 0 -> 7186 bytes
projects/clang/build | 45 ++
projects/clang/config | 45 ++
projects/clang/win-patches/llvm-objcopy-1.patch | 27 +
projects/clang/win-patches/llvm-objcopy-10.patch | 28 +
projects/clang/win-patches/llvm-objcopy-11.patch | 377 +++++++++++++
projects/clang/win-patches/llvm-objcopy-12.patch | 43 ++
projects/clang/win-patches/llvm-objcopy-2.patch | 665 +++++++++++++++++++++++
projects/clang/win-patches/llvm-objcopy-3.patch | 160 ++++++
projects/clang/win-patches/llvm-objcopy-4.patch | 222 ++++++++
projects/clang/win-patches/llvm-objcopy-5.patch | 61 +++
projects/clang/win-patches/llvm-objcopy-6.patch | 242 +++++++++
projects/clang/win-patches/llvm-objcopy-7.patch | 224 ++++++++
projects/clang/win-patches/llvm-objcopy-8.patch | 330 +++++++++++
projects/clang/win-patches/llvm-objcopy-9.patch | 260 +++++++++
15 files changed, 2729 insertions(+)
diff --git a/keyring/clang.gpg b/keyring/clang.gpg
new file mode 100644
index 0000000..15f0d8a
Binary files /dev/null and b/keyring/clang.gpg differ
diff --git a/projects/clang/build b/projects/clang/build
new file mode 100644
index 0000000..50576b4
--- /dev/null
+++ b/projects/clang/build
@@ -0,0 +1,45 @@
+#!/bin/bash
+[% c("var/set_default_env") -%]
+distdir=/var/tmp/dist/[% project %]
+mkdir -p /var/tmp/dist
+tar -C /var/tmp/dist -xf [% c('input_files_by_name/cmake') %]
+export PATH="/var/tmp/dist/cmake/bin:$PATH"
+[% IF c("var/linux") %]
+ # We need a link to our GCC, otherwise the system cc gets used which points to
+ # /usr/bin/gcc.
+ [% pc('gcc', 'var/setup', { compiler_tarfile => c('input_files_by_name/gcc'),
+ hardened_gcc => 0 }) %]
+ ln -s gcc /var/tmp/dist/gcc/bin/cc
+[% END -%]
+mkdir -p /var/tmp/build
+cd /var/tmp/build
+tar -xf $rootdir/[% c('input_files_by_name/llvm') %]
+tar -xf $rootdir/[% c('input_files_by_name/cfe') %]
+tar -xf $rootdir/[% c('input_files_by_name/libcxx') %]
+tar -xf $rootdir/[% c('input_files_by_name/libcxxabi') %]
+tar -xf $rootdir/[% c('input_files_by_name/lld') %]
+tar -xf $rootdir/[% c('input_files_by_name/compiler-rt') %]
+mv llvm-* llvm
+mv cfe-* llvm/tools/clang
+mv libcxx-* llvm/projects/libcxx
+mv libcxxabi-* llvm/projects/libcxxabi
+mv lld-* llvm/tools/lld
+mv compiler-rt-* llvm/projects/compiler-rt
+[% IF c("var/windows") -%]
+ # Patch order is important here
+ for i in {1..12}
+ do git apply $rootdir/win-patches/llvm-objcopy-$i.patch
+ done
+[% END %]
+cd llvm
+export LLVM_HOME=$(pwd)
+mkdir build
+cd build
+cmake .. -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=$distdir -DCMAKE_BUILD_TYPE:STRING=Release $LLVM_HOME
+make -j[% c("buildconf/num_procs") %]
+make install
+cd /var/tmp/dist
+[% c('tar', {
+ tar_src => [ project ],
+ tar_args => '-czf ' _ dest_dir _ '/' _ c('filename'),
+ }) %]
diff --git a/projects/clang/config b/projects/clang/config
new file mode 100644
index 0000000..f439cf7
--- /dev/null
+++ b/projects/clang/config
@@ -0,0 +1,45 @@
+# vim: filetype=yaml sw=2
+version: 8.0.0
+filename: '[% project %]-[% c("version") %]-[% c("var/build_id") %].tar.gz'
+gpg_keyring: clang.gpg
+sig_ext: sig
+
+var:
+ container:
+ use_container: 1
+
+targets:
+ windows:
+ var:
+ arch_deps:
+ # We use git to apply patches
+ - git
+
+
+input_files:
+ - project: container-image
+ - name: '[% c("var/compiler") %]'
+ project: '[% c("var/compiler") %]'
+ enable: '[% c("var/linux") %]'
+ - project: cmake
+ name: cmake
+ - URL: 'https://releases.llvm.org/[% c("version") %]/llvm-[% c("version") %].src.tar.xz'
+ name: llvm
+ file_gpg_id: 1
+ - URL: 'https://releases.llvm.org/[% c("version") %]/cfe-[% c("version") %].src.tar.xz'
+ name: cfe
+ file_gpg_id: 1
+ - URL: 'https://releases.llvm.org/[% c("version") %]/libcxx-[% c("version") %].src.tar.xz'
+ name: libcxx
+ file_gpg_id: 1
+ - URL: 'https://releases.llvm.org/[% c("version") %]/libcxxabi-[% c("version") %].src.tar.xz'
+ name: libcxxabi
+ file_gpg_id: 1
+ - URL: 'https://releases.llvm.org/[% c("version") %]/lld-[% c("version") %].src.tar.xz'
+ name: lld
+ file_gpg_id: 1
+ - URL: 'https://releases.llvm.org/[% c("version") %]/compiler-rt-[% c("version") %].src.tar.xz'
+ name: compiler-rt
+ file_gpg_id: 1
+ - filename: win-patches
+ enable: '[% c("var/windows") %]'
diff --git a/projects/clang/win-patches/llvm-objcopy-1.patch b/projects/clang/win-patches/llvm-objcopy-1.patch
new file mode 100644
index 0000000..9c9f250
--- /dev/null
+++ b/projects/clang/win-patches/llvm-objcopy-1.patch
@@ -0,0 +1,27 @@
+From a495c9ae6fb3367e6b59d8d245273ed3669754f0 Mon Sep 17 00:00:00 2001
+From: Martin Storsjo <martin(a)martin.st>
+Date: Sat, 19 Jan 2019 19:42:23 +0000
+Subject: [PATCH] [llvm-objcopy] [COFF] Remove a superfluous namespace
+ qualification. NFC.
+
+git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351658 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ tools/llvm-objcopy/COFF/COFFObjcopy.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+index ceebf600b3a..437dccbd3d5 100644
+--- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+@@ -78,7 +78,7 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
+ }
+
+ void executeObjcopyOnBinary(const CopyConfig &Config,
+- object::COFFObjectFile &In, Buffer &Out) {
++ COFFObjectFile &In, Buffer &Out) {
+ COFFReader Reader(In);
+ Expected<std::unique_ptr<Object>> ObjOrErr = Reader.create();
+ if (!ObjOrErr)
+--
+2.17.1
+
diff --git a/projects/clang/win-patches/llvm-objcopy-10.patch b/projects/clang/win-patches/llvm-objcopy-10.patch
new file mode 100644
index 0000000..4aca911
--- /dev/null
+++ b/projects/clang/win-patches/llvm-objcopy-10.patch
@@ -0,0 +1,28 @@
+From 1284ee3c47bab17ec081b5169633aea4f8abfd30 Mon Sep 17 00:00:00 2001
+From: Martin Storsjo <martin(a)martin.st>
+Date: Wed, 23 Jan 2019 09:12:53 +0000
+Subject: [PATCH] [llvm-objcopy] [COFF] Clear the unwritten tail of
+ coff_section::Header::Name
+
+This should fix the add-gnu-debuglink test on all buildbots.
+
+git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351934 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ tools/llvm-objcopy/COFF/Writer.cpp | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.cpp b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
+index 05e46291c39..db897e2ff33 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Writer.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
+@@ -121,6 +121,7 @@ size_t COFFWriter::finalizeStringTable() {
+
+ for (auto &S : Obj.getMutableSections()) {
+ if (S.Name.size() > COFF::NameSize) {
++ memset(S.Header.Name, 0, sizeof(S.Header.Name));
+ snprintf(S.Header.Name, sizeof(S.Header.Name), "/%d",
+ (int)StrTabBuilder.getOffset(S.Name));
+ } else {
+--
+2.17.1
+
diff --git a/projects/clang/win-patches/llvm-objcopy-11.patch b/projects/clang/win-patches/llvm-objcopy-11.patch
new file mode 100644
index 0000000..9149b80
--- /dev/null
+++ b/projects/clang/win-patches/llvm-objcopy-11.patch
@@ -0,0 +1,377 @@
+From 74c7d422cba163635394ec32f2b243b1de502a18 Mon Sep 17 00:00:00 2001
+From: Martin Storsjo <martin(a)martin.st>
+Date: Wed, 23 Jan 2019 11:54:51 +0000
+Subject: [PATCH] [llvm-objcopy] [COFF] Fix handling of aux symbols for big
+ objects
+
+The aux symbols were stored in an opaque std::vector<uint8_t>,
+with contents interpreted according to the rest of the symbol.
+
+All aux symbol types but one fit in 18 bytes (sizeof(coff_symbol16)),
+and if written to a bigobj, two extra padding bytes are written (as
+sizeof(coff_symbol32) is 20). In the storage agnostic intermediate
+representation, store the aux symbols as a series of coff_symbol16
+sized opaque blobs. (In practice, all such aux symbols only consist
+of one aux symbol, so this is more flexible than what reality needs.)
+
+The special case is the file aux symbols, which are written in
+potentially more than one aux symbol slot, without any padding,
+as one single long string. This can't be stored in the same opaque
+vector of fixed sized aux symbol entries. The file aux symbols will
+occupy a different number of aux symbol slots depending on the type
+of output object file. As nothing in the intermediate process needs
+to have accurate raw symbol indices, updating that is moved into the
+writer class.
+
+Differential Revision: https://reviews.llvm.org/D57009
+
+git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351947 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ .../llvm-objcopy/COFF/Inputs/bigobj.o.gz | Bin 0 -> 7841 bytes
+ test/tools/llvm-objcopy/COFF/bigobj.test | 35 +++++++++++++
+ .../llvm-objcopy/ELF/auto-remove-shndx.test | 2 +-
+ .../tools/llvm-objcopy/ELF/many-sections.test | 2 +-
+ test/tools/llvm-objcopy/ELF/remove-shndx.test | 2 +-
+ .../tools/llvm-objcopy/ELF/strict-no-add.test | 2 +-
+ .../llvm-objcopy/{ELF => }/Inputs/ungzip.py | 0
+ tools/llvm-objcopy/COFF/COFFObjcopy.cpp | 6 +--
+ tools/llvm-objcopy/COFF/Object.cpp | 6 +--
+ tools/llvm-objcopy/COFF/Object.h | 18 ++++++-
+ tools/llvm-objcopy/COFF/Reader.cpp | 21 ++++++--
+ tools/llvm-objcopy/COFF/Writer.cpp | 49 +++++++++++++-----
+ tools/llvm-objcopy/COFF/Writer.h | 2 +-
+ 13 files changed, 115 insertions(+), 30 deletions(-)
+ create mode 100644 test/tools/llvm-objcopy/COFF/Inputs/bigobj.o.gz
+ create mode 100644 test/tools/llvm-objcopy/COFF/bigobj.test
+ rename test/tools/llvm-objcopy/{ELF => }/Inputs/ungzip.py (100%)
+
+diff --git a/llvm/test/tools/llvm-objcopy/COFF/Inputs/bigobj.o.gz b/llvm/test/tools/llvm-objcopy/COFF/Inputs/bigobj.o.gz
+new file mode 100644
+index 0000000000000000000000000000000000000000..6435f4785ff76e0c6bca12f3e57bc6ad8888bece
+GIT binary patch
+literal 7841
+zcmb2|=3r3v^@w3&etUMmo^zoH`-kGKM_vfJsF<z%6+Sz#g6qq)pf0Hj#_r`4B7DML
+zW(h1l`+!x)t@&W-R@I~lyKmU3Ti&1Z=iKur;uBMy1MR!_ywlsouYY&-*4H1mU!Qw=
+z`RpIDkw;!V4(WOF_)B3`(Vt|~S>?L-b)Wx@^wig`HIMAw|N8V<v65oeyETs611{)_
+zm27RwTe)ENN|7SLgM~83N6}~qjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mk
+zz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kgRokHNw|D97mKRo|%+Z6Ym
+z*X{Ku$4#4*Vqm}gyYR^b^Sc?_E*<<cFE#Q=*rt6OBmJeLZ=aoe_u9R>-w!^l5biDe
+p{d@nvw*mU6<NG83=jxn4_wt_G?yUy#YeOF~KhH^=cj<;Y0{~9Br>p<~
+
+literal 0
+HcmV?d00001
+
+diff --git a/llvm/test/tools/llvm-objcopy/COFF/bigobj.test b/llvm/test/tools/llvm-objcopy/COFF/bigobj.test
+new file mode 100644
+index 00000000000..17968f12b8a
+--- /dev/null
++++ b/llvm/test/tools/llvm-objcopy/COFF/bigobj.test
+@@ -0,0 +1,35 @@
++RUN: %python %p/../Inputs/ungzip.py %p/Inputs/bigobj.o.gz > %t.in.o
++
++RUN: llvm-objdump -t %t.in.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-BIG,SYMBOLS-ORIG
++
++# Do a plain copy, to check that section numbers in symbols referring
++# to sections outside of the small object format are handled correctly.
++RUN: llvm-objcopy -R '.text$4' %t.in.o %t.small.o
++RUN: llvm-objdump -t %t.in.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-BIG,SYMBOLS-ORIG
++
++# Remove a section, making the section count fit into a small object.
++RUN: llvm-objcopy -R '.text$4' %t.in.o %t.small.o
++RUN: llvm-objdump -t %t.small.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-SMALL,SYMBOLS-REMOVED-SMALL
++
++# Add a .gnu_debuglink section, forcing the object back to big format.
++RUN: llvm-objcopy --add-gnu-debuglink=%t.in.o %t.small.o %t.big.o
++ llvm-objdump -t %t.big.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-BIG,SYMBOLS-REMOVED-BIG
++
++# In big object format, the .file symbol occupies one symbol table entry for
++# the auxillary data, but needs two entries in the small format, forcing the
++# raw symbol indices of later symbols to change.
++SYMBOLS: SYMBOL TABLE:
++SYMBOLS-NEXT: [ 0]{{.*}} (nx 1) {{.*}} .text
++SYMBOLS-NEXT: AUX scnlen
++SYMBOLS-SMALL-NEXT: [ 2]{{.*}} (nx 2) {{.*}} .file
++SYMBOLS-BIG-NEXT: [ 2]{{.*}} (nx 1) {{.*}} .file
++SYMBOLS-NEXT: AUX abcdefghijklmnopqrs
++SYMBOLS-SMALL-NEXT: [ 5]{{.*}} (nx 0) {{.*}} foo
++SYMBOLS-BIG-NEXT: [ 4]{{.*}} (nx 0) {{.*}} foo
++
++# Check that the section numbers outside of signed 16 bit int range
++# are represented properly. After removing one section, the section
++# numbers decrease.
++SYMBOLS-ORIG: [ 5](sec 65280){{.*}} symbol65280
++SYMBOLS-REMOVED-SMALL: [ 6](sec 65279){{.*}} symbol65280
++SYMBOLS-REMOVED-BIG: [ 5](sec 65279){{.*}} symbol65280
+diff --git a/llvm/test/tools/llvm-objcopy/ELF/auto-remove-shndx.test b/llvm/test/tools/llvm-objcopy/ELF/auto-remove-shndx.test
+index 5a23493fa94..8e6c788bf48 100644
+--- a/llvm/test/tools/llvm-objcopy/ELF/auto-remove-shndx.test
++++ b/llvm/test/tools/llvm-objcopy/ELF/auto-remove-shndx.test
+@@ -1,4 +1,4 @@
+-# RUN: %python %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t
++# RUN: %python %p/../Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t
+ # RUN: llvm-objcopy -R .text -R s0 -R s1 -R s2 -R s3 -R s4 -R s5 -R s6 %t %t2
+ # RUN: llvm-readobj --sections %t2 | FileCheck --check-prefix=SECS %s
+
+diff --git a/llvm/test/tools/llvm-objcopy/ELF/many-sections.test b/llvm/test/tools/llvm-objcopy/ELF/many-sections.test
+index 57239f32e4a..1dd41cfb10c 100644
+--- a/llvm/test/tools/llvm-objcopy/ELF/many-sections.test
++++ b/llvm/test/tools/llvm-objcopy/ELF/many-sections.test
+@@ -1,4 +1,4 @@
+-RUN: %python %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t
++RUN: %python %p/../Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t
+ RUN: llvm-objcopy %t %t2
+ RUN: llvm-readobj --file-headers %t2 | FileCheck --check-prefix=EHDR %s
+ RUN: llvm-readobj --sections %t2 | FileCheck --check-prefix=SECS %s
+diff --git a/llvm/test/tools/llvm-objcopy/ELF/remove-shndx.test b/llvm/test/tools/llvm-objcopy/ELF/remove-shndx.test
+index 6cc3a1a291f..53ca8e7f220 100644
+--- a/llvm/test/tools/llvm-objcopy/ELF/remove-shndx.test
++++ b/llvm/test/tools/llvm-objcopy/ELF/remove-shndx.test
+@@ -1,6 +1,6 @@
+ # This test checks to see that a .symtab_shndx section is added to any binary
+ # that needs it, even if the original was removed.
+-RUN: %python %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t
++RUN: %python %p/../Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t
+ RUN: llvm-objcopy -R .symtab_shndx %t %t2
+ RUN: llvm-readobj --sections %t2 | FileCheck %s
+
+diff --git a/llvm/test/tools/llvm-objcopy/ELF/strict-no-add.test b/llvm/test/tools/llvm-objcopy/ELF/strict-no-add.test
+index 4f24df31bf9..348ab7c4fbd 100644
+--- a/llvm/test/tools/llvm-objcopy/ELF/strict-no-add.test
++++ b/llvm/test/tools/llvm-objcopy/ELF/strict-no-add.test
+@@ -1,7 +1,7 @@
+ # This test makes sure that sections added at the end that don't have symbols
+ # defined in them don't trigger the creation of a large index table.
+
+-RUN: %python %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t.0
++RUN: %python %p/../Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t.0
+ RUN: cat %p/Inputs/alloc-symtab.o > %t
+ RUN: llvm-objcopy -R .text -R s0 -R s1 -R s2 -R s3 -R s4 -R s5 -R s6 %t.0 %t2
+ RUN: llvm-objcopy --add-section=.s0=%t --add-section=.s1=%t --add-section=.s2=%t %t2 %t2
+diff --git a/llvm/test/tools/llvm-objcopy/ELF/Inputs/ungzip.py b/llvm/test/tools/llvm-objcopy/Inputs/ungzip.py
+similarity index 100%
+rename from llvm/test/tools/llvm-objcopy/ELF/Inputs/ungzip.py
+rename to llvm/test/tools/llvm-objcopy/Inputs/ungzip.py
+diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+index 20adbe11e7a..64b4e79a4e0 100644
+--- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+@@ -37,7 +37,7 @@ static uint64_t getNextRVA(const Object &Obj) {
+ return 0;
+ const Section &Last = Obj.getSections().back();
+ return alignTo(Last.Header.VirtualAddress + Last.Header.VirtualSize,
+- Obj.PeHeader.SectionAlignment);
++ Obj.IsPE ? Obj.PeHeader.SectionAlignment : 1);
+ }
+
+ static uint32_t getCRC32(StringRef Data) {
+@@ -74,8 +74,8 @@ static void addGnuDebugLink(Object &Obj, StringRef DebugLinkFile) {
+ Sec.Name = ".gnu_debuglink";
+ Sec.Header.VirtualSize = Sec.getContents().size();
+ Sec.Header.VirtualAddress = StartRVA;
+- Sec.Header.SizeOfRawData =
+- alignTo(Sec.Header.VirtualSize, Obj.PeHeader.FileAlignment);
++ Sec.Header.SizeOfRawData = alignTo(Sec.Header.VirtualSize,
++ Obj.IsPE ? Obj.PeHeader.FileAlignment : 1);
+ // Sec.Header.PointerToRawData is filled in by the writer.
+ Sec.Header.PointerToRelocations = 0;
+ Sec.Header.PointerToLinenumbers = 0;
+diff --git a/llvm/tools/llvm-objcopy/COFF/Object.cpp b/llvm/tools/llvm-objcopy/COFF/Object.cpp
+index 8c382c1faef..0ad5a05a144 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Object.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Object.cpp
+@@ -26,12 +26,8 @@ void Object::addSymbols(ArrayRef<Symbol> NewSymbols) {
+
+ void Object::updateSymbols() {
+ SymbolMap = DenseMap<size_t, Symbol *>(Symbols.size());
+- size_t RawSymIndex = 0;
+- for (Symbol &Sym : Symbols) {
++ for (Symbol &Sym : Symbols)
+ SymbolMap[Sym.UniqueId] = &Sym;
+- Sym.RawIndex = RawSymIndex;
+- RawSymIndex += 1 + Sym.Sym.NumberOfAuxSymbols;
+- }
+ }
+
+ const Symbol *Object::findSymbol(size_t UniqueId) const {
+diff --git a/llvm/tools/llvm-objcopy/COFF/Object.h b/llvm/tools/llvm-objcopy/COFF/Object.h
+index afa272286ef..21475b06862 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Object.h
++++ b/llvm/tools/llvm-objcopy/COFF/Object.h
+@@ -66,10 +66,24 @@ private:
+ std::vector<uint8_t> OwnedContents;
+ };
+
++struct AuxSymbol {
++ AuxSymbol(ArrayRef<uint8_t> In) {
++ assert(In.size() == sizeof(Opaque));
++ std::copy(In.begin(), In.end(), Opaque);
++ }
++
++ ArrayRef<uint8_t> getRef() const {
++ return ArrayRef<uint8_t>(Opaque, sizeof(Opaque));
++ }
++
++ uint8_t Opaque[sizeof(object::coff_symbol16)];
++};
++
+ struct Symbol {
+ object::coff_symbol32 Sym;
+ StringRef Name;
+- std::vector<uint8_t> AuxData;
++ std::vector<AuxSymbol> AuxData;
++ StringRef AuxFile;
+ ssize_t TargetSectionId;
+ ssize_t AssociativeComdatTargetSectionId = 0;
+ Optional<size_t> WeakTargetSymbolId;
+@@ -132,7 +146,7 @@ private:
+
+ ssize_t NextSectionUniqueId = 1; // Allow a UniqueId 0 to mean undefined.
+
+- // Update SymbolMap and RawIndex in each Symbol.
++ // Update SymbolMap.
+ void updateSymbols();
+
+ // Update SectionMap and Index in each Section.
+diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.cpp b/llvm/tools/llvm-objcopy/COFF/Reader.cpp
+index 87dd60a43cf..7270bbf94de 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Reader.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Reader.cpp
+@@ -107,9 +107,24 @@ Error COFFReader::readSymbols(Object &Obj, bool IsBigObj) const {
+ *reinterpret_cast<const coff_symbol16 *>(SymRef.getRawPtr()));
+ if (auto EC = COFFObj.getSymbolName(SymRef, Sym.Name))
+ return errorCodeToError(EC);
+- Sym.AuxData = COFFObj.getSymbolAuxData(SymRef);
+- assert((Sym.AuxData.size() %
+- (IsBigObj ? sizeof(coff_symbol32) : sizeof(coff_symbol16))) == 0);
++
++ ArrayRef<uint8_t> AuxData = COFFObj.getSymbolAuxData(SymRef);
++ size_t SymSize = IsBigObj ? sizeof(coff_symbol32) : sizeof(coff_symbol16);
++ assert(AuxData.size() == SymSize * SymRef.getNumberOfAuxSymbols());
++ // The auxillary symbols are structs of sizeof(coff_symbol16) each.
++ // In the big object format (where symbols are coff_symbol32), each
++ // auxillary symbol is padded with 2 bytes at the end. Copy each
++ // auxillary symbol to the Sym.AuxData vector. For file symbols,
++ // the whole range of aux symbols are interpreted as one null padded
++ // string instead.
++ if (SymRef.isFileRecord())
++ Sym.AuxFile = StringRef(reinterpret_cast<const char *>(AuxData.data()),
++ AuxData.size())
++ .rtrim('\0');
++ else
++ for (size_t I = 0; I < SymRef.getNumberOfAuxSymbols(); I++)
++ Sym.AuxData.push_back(AuxData.slice(I * SymSize, sizeof(AuxSymbol)));
++
+ // Find the unique id of the section
+ if (SymRef.getSectionNumber() <=
+ 0) // Special symbol (undefined/absolute/debug)
+diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.cpp b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
+index db897e2ff33..6e69c597217 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Writer.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
+@@ -55,7 +55,8 @@ Error COFFWriter::finalizeSymbolContents() {
+ if (Sym.Sym.NumberOfAuxSymbols == 1 &&
+ Sym.Sym.StorageClass == IMAGE_SYM_CLASS_STATIC) {
+ coff_aux_section_definition *SD =
+- reinterpret_cast<coff_aux_section_definition *>(Sym.AuxData.data());
++ reinterpret_cast<coff_aux_section_definition *>(
++ Sym.AuxData[0].Opaque);
+ uint32_t SDSectionNumber;
+ if (Sym.AssociativeComdatTargetSectionId == 0) {
+ // Not a comdat associative section; just set the Number field to
+@@ -79,7 +80,7 @@ Error COFFWriter::finalizeSymbolContents() {
+ // we want to set. Only >= 1 would be required, but only == 1 makes sense.
+ if (Sym.WeakTargetSymbolId && Sym.Sym.NumberOfAuxSymbols == 1) {
+ coff_aux_weak_external *WE =
+- reinterpret_cast<coff_aux_weak_external *>(Sym.AuxData.data());
++ reinterpret_cast<coff_aux_weak_external *>(Sym.AuxData[0].Opaque);
+ const Symbol *Target = Obj.findSymbol(*Sym.WeakTargetSymbolId);
+ if (Target == nullptr)
+ return createStringError(object_error::invalid_symbol_index,
+@@ -141,13 +142,26 @@ size_t COFFWriter::finalizeStringTable() {
+
+ template <class SymbolTy>
+ std::pair<size_t, size_t> COFFWriter::finalizeSymbolTable() {
+- size_t SymTabSize = Obj.getSymbols().size() * sizeof(SymbolTy);
+- for (const auto &S : Obj.getSymbols())
+- SymTabSize += S.AuxData.size();
+- return std::make_pair(SymTabSize, sizeof(SymbolTy));
++ size_t RawSymIndex = 0;
++ for (auto &S : Obj.getMutableSymbols()) {
++ // Symbols normally have NumberOfAuxSymbols set correctly all the time.
++ // For file symbols, we need to know the output file's symbol size to be
++ // able to calculate the number of slots it occupies.
++ if (!S.AuxFile.empty())
++ S.Sym.NumberOfAuxSymbols =
++ alignTo(S.AuxFile.size(), sizeof(SymbolTy)) / sizeof(SymbolTy);
++ S.RawIndex = RawSymIndex;
++ RawSymIndex += 1 + S.Sym.NumberOfAuxSymbols;
++ }
++ return std::make_pair(RawSymIndex * sizeof(SymbolTy), sizeof(SymbolTy));
+ }
+
+ Error COFFWriter::finalize(bool IsBigObj) {
++ size_t SymTabSize, SymbolSize;
++ std::tie(SymTabSize, SymbolSize) = IsBigObj
++ ? finalizeSymbolTable<coff_symbol32>()
++ : finalizeSymbolTable<coff_symbol16>();
++
+ if (Error E = finalizeRelocTargets())
+ return E;
+ if (Error E = finalizeSymbolContents())
+@@ -199,10 +213,6 @@ Error COFFWriter::finalize(bool IsBigObj) {
+ }
+
+ size_t StrTabSize = finalizeStringTable();
+- size_t SymTabSize, SymbolSize;
+- std::tie(SymTabSize, SymbolSize) = IsBigObj
+- ? finalizeSymbolTable<coff_symbol32>()
+- : finalizeSymbolTable<coff_symbol16>();
+
+ size_t PointerToSymbolTable = FileSize;
+ // StrTabSize <= 4 is the size of an empty string table, only consisting
+@@ -312,8 +322,23 @@ template <class SymbolTy> void COFFWriter::writeSymbolStringTables() {
+ copySymbol<SymbolTy, coff_symbol32>(*reinterpret_cast<SymbolTy *>(Ptr),
+ S.Sym);
+ Ptr += sizeof(SymbolTy);
+- std::copy(S.AuxData.begin(), S.AuxData.end(), Ptr);
+- Ptr += S.AuxData.size();
++ if (!S.AuxFile.empty()) {
++ // For file symbols, just write the string into the aux symbol slots,
++ // assuming that the unwritten parts are initialized to zero in the memory
++ // mapped file.
++ std::copy(S.AuxFile.begin(), S.AuxFile.end(), Ptr);
++ Ptr += S.Sym.NumberOfAuxSymbols * sizeof(SymbolTy);
++ } else {
++ // For other auxillary symbols, write their opaque payload into one symbol
++ // table slot each. For big object files, the symbols are larger than the
++ // opaque auxillary symbol struct and we leave padding at the end of each
++ // entry.
++ for (const AuxSymbol &AuxSym : S.AuxData) {
++ ArrayRef<uint8_t> Ref = AuxSym.getRef();
++ std::copy(Ref.begin(), Ref.end(), Ptr);
++ Ptr += sizeof(SymbolTy);
++ }
++ }
+ }
+ if (StrTabBuilder.getSize() > 4 || !Obj.IsPE) {
+ // Always write a string table in object files, even an empty one.
+diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.h b/llvm/tools/llvm-objcopy/COFF/Writer.h
+index 9b1cfa91d00..681a8d5e4a6 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Writer.h
++++ b/llvm/tools/llvm-objcopy/COFF/Writer.h
+@@ -30,11 +30,11 @@ class COFFWriter {
+ size_t SizeOfInitializedData;
+ StringTableBuilder StrTabBuilder;
+
++ template <class SymbolTy> std::pair<size_t, size_t> finalizeSymbolTable();
+ Error finalizeRelocTargets();
+ Error finalizeSymbolContents();
+ void layoutSections();
+ size_t finalizeStringTable();
+- template <class SymbolTy> std::pair<size_t, size_t> finalizeSymbolTable();
+
+ Error finalize(bool IsBigObj);
+
+--
+2.17.1
+
diff --git a/projects/clang/win-patches/llvm-objcopy-12.patch b/projects/clang/win-patches/llvm-objcopy-12.patch
new file mode 100644
index 0000000..35dec30
--- /dev/null
+++ b/projects/clang/win-patches/llvm-objcopy-12.patch
@@ -0,0 +1,43 @@
+From abacd83232acf69d7cbacd53fc2f9aae66c1a32e Mon Sep 17 00:00:00 2001
+From: Martin Storsjo <martin(a)martin.st>
+Date: Wed, 23 Jan 2019 11:54:55 +0000
+Subject: [PATCH] [llvm-objcopy] [COFF] Error out on use of unhandled options
+
+Prefer erroring out than silently not doing what was requested.
+
+Differential Revision: https://reviews.llvm.org/D57045
+
+git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351948 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ tools/llvm-objcopy/COFF/COFFObjcopy.cpp | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+index 64b4e79a4e0..b7b3d3cb629 100644
+--- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+@@ -170,6 +170,21 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
+ if (!Config.AddGnuDebugLink.empty())
+ addGnuDebugLink(Obj, Config.AddGnuDebugLink);
+
++ if (!Config.BuildIdLinkDir.empty() || Config.BuildIdLinkInput ||
++ Config.BuildIdLinkOutput || !Config.SplitDWO.empty() ||
++ !Config.SymbolsPrefix.empty() || !Config.AddSection.empty() ||
++ !Config.DumpSection.empty() || !Config.KeepSection.empty() ||
++ !Config.SymbolsToGlobalize.empty() || !Config.SymbolsToKeep.empty() ||
++ !Config.SymbolsToLocalize.empty() || !Config.SymbolsToWeaken.empty() ||
++ !Config.SymbolsToKeepGlobal.empty() || !Config.SectionsToRename.empty() ||
++ !Config.SymbolsToRename.empty() || Config.ExtractDWO ||
++ Config.KeepFileSymbols || Config.LocalizeHidden || Config.PreserveDates ||
++ Config.StripDWO || Config.StripNonAlloc || Config.StripSections ||
++ Config.Weaken || Config.DecompressDebugSections) {
++ return createStringError(llvm::errc::invalid_argument,
++ "Option not supported by llvm-objcopy for COFF");
++ }
++
+ return Error::success();
+ }
+
+--
+2.17.1
+
diff --git a/projects/clang/win-patches/llvm-objcopy-2.patch b/projects/clang/win-patches/llvm-objcopy-2.patch
new file mode 100644
index 0000000..41e7a94
--- /dev/null
+++ b/projects/clang/win-patches/llvm-objcopy-2.patch
@@ -0,0 +1,665 @@
+From 2ccafacb7ddd740054dbee06655749ebc55a4d86 Mon Sep 17 00:00:00 2001
+From: Martin Storsjo <martin(a)martin.st>
+Date: Sat, 19 Jan 2019 19:42:35 +0000
+Subject: [PATCH] [llvm-objcopy] [COFF] Add support for removing sections
+
+Differential Revision: https://reviews.llvm.org/D56683
+
+git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351660 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ .../llvm-objcopy/COFF/remove-section.test | 210 ++++++++++++++++++
+ tools/llvm-objcopy/COFF/COFFObjcopy.cpp | 10 +-
+ tools/llvm-objcopy/COFF/Object.cpp | 63 ++++++
+ tools/llvm-objcopy/COFF/Object.h | 27 ++-
+ tools/llvm-objcopy/COFF/Reader.cpp | 31 ++-
+ tools/llvm-objcopy/COFF/Writer.cpp | 68 ++++--
+ tools/llvm-objcopy/COFF/Writer.h | 1 +
+ 7 files changed, 391 insertions(+), 19 deletions(-)
+ create mode 100644 test/tools/llvm-objcopy/COFF/remove-section.test
+
+diff --git a/llvm/test/tools/llvm-objcopy/COFF/remove-section.test b/llvm/test/tools/llvm-objcopy/COFF/remove-section.test
+new file mode 100644
+index 00000000000..b3dfb0b98cb
+--- /dev/null
++++ b/llvm/test/tools/llvm-objcopy/COFF/remove-section.test
+@@ -0,0 +1,210 @@
++# RUN: yaml2obj %s > %t.in.o
++#
++# RUN: llvm-objdump -section-headers %t.in.o | FileCheck %s --check-prefixes=SECTIONS-PRE
++# RUN: llvm-objdump -t %t.in.o | FileCheck %s --check-prefixes=SYMBOLS-PRE
++#
++# RUN: llvm-objcopy -R .bss %t.in.o %t.remove-bss.o
++# RUN: llvm-objdump -section-headers %t.remove-bss.o | FileCheck %s --check-prefix=SECTIONS-REMOVE-BSS
++# RUN: llvm-objdump -t %t.remove-bss.o | FileCheck %s --check-prefix=SYMBOLS-REMOVE-BSS
++#
++# RUN: llvm-objcopy --remove-section .bss %t.in.o %t.cmp.o
++# RUN: cmp %t.remove-bss.o %t.cmp.o
++#
++# RUN: llvm-objcopy -R .text %t.in.o %t.remove-text.o
++# RUN: llvm-objdump -section-headers %t.remove-text.o | FileCheck %s --check-prefix=SECTIONS-REMOVE-TEXT
++# RUN: llvm-objdump -t %t.remove-text.o | FileCheck %s --check-prefix=SYMBOLS-REMOVE-TEXT
++#
++# RUN: not llvm-objcopy -R .comdat %t.in.o %t.remove-comdat.o 2>&1 | FileCheck %s --check-prefix=ERROR-RELOC
++#
++# RUN: llvm-objcopy -R .text -R .comdat %t.in.o %t.remove-text-comdat.o
++# RUN: llvm-objdump -section-headers %t.remove-text-comdat.o | FileCheck %s --check-prefix=SECTIONS-REMOVE-TEXT-COMDAT
++# RUN: llvm-objdump -t %t.remove-text-comdat.o | FileCheck %s --check-prefix=SYMBOLS-REMOVE-TEXT-COMDAT
++#
++#
++# SECTIONS-PRE: Sections:
++# SECTIONS-PRE-NEXT: Idx Name
++# SECTIONS-PRE-NEXT: 0 .text
++# SECTIONS-PRE-NEXT: 1 .bss
++# SECTIONS-PRE-NEXT: 2 .comdat
++# SECTIONS-PRE-NEXT: 3 .associative
++# SECTIONS-PRE-EMPTY:
++#
++# SYMBOLS-PRE: SYMBOL TABLE:
++# SYMBOLS-PRE-NEXT: {{.*}}(sec -1){{.*}} @feat.00
++# SYMBOLS-PRE-NEXT: {{.*}}(sec 1){{.*}} .text
++# SYMBOLS-PRE-NEXT: AUX scnlen {{.*}} assoc 1 comdat 0
++# SYMBOLS-PRE-NEXT: {{.*}}(sec 2){{.*}} .bss
++# SYMBOLS-PRE-NEXT: AUX scnlen {{.*}} assoc 2 comdat 0
++# SYMBOLS-PRE-NEXT: {{.*}}(sec 4){{.*}} .associative
++# SYMBOLS-PRE-NEXT: AUX scnlen {{.*}} assoc 3 comdat 5
++# SYMBOLS-PRE-NEXT: {{.*}}(sec 3){{.*}} .comdat
++# SYMBOLS-PRE-NEXT: AUX scnlen {{.*}} assoc 3 comdat 2
++# SYMBOLS-PRE-NEXT: {{.*}}(sec 3){{.*}} foo
++# SYMBOLS-PRE-NEXT: {{.*}}(sec 1){{.*}} main
++# SYMBOLS-PRE-EMPTY:
++#
++#
++# Removing the .bss section removes one symbol and its aux symbol,
++# and updates the section indices in symbols pointing to later
++# symbols, including the aux section defintitions.
++#
++# Testing that the absolute symbol @feat.00 survives the section number
++# mangling.
++#
++# SECTIONS-REMOVE-BSS: Sections:
++# SECTIONS-REMOVE-BSS-NEXT: Idx Name
++# SECTIONS-REMOVE-BSS-NEXT: 0 .text
++# SECTIONS-REMOVE-BSS-NEXT: 1 .comdat
++# SECTIONS-REMOVE-BSS-NEXT: 2 .associative
++# SECTIONS-REMOVE-BSS-EMPTY:
++#
++# SYMBOLS-REMOVE-BSS: SYMBOL TABLE:
++# SYMBOLS-REMOVE-BSS-NEXT: {{.*}}(sec -1){{.*}} @feat.00
++# SYMBOLS-REMOVE-BSS-NEXT: {{.*}}(sec 1){{.*}} .text
++# SYMBOLS-REMOVE-BSS-NEXT: AUX scnlen {{.*}} assoc 1 comdat 0
++# SYMBOLS-REMOVE-BSS-NEXT: {{.*}}(sec 3){{.*}} .associative
++# SYMBOLS-REMOVE-BSS-NEXT: AUX scnlen {{.*}} assoc 2 comdat 5
++# SYMBOLS-REMOVE-BSS-NEXT: {{.*}}(sec 2){{.*}} .comdat
++# SYMBOLS-REMOVE-BSS-NEXT: AUX scnlen {{.*}} assoc 2 comdat 2
++# SYMBOLS-REMOVE-BSS-NEXT: {{.*}}(sec 2){{.*}} foo
++# SYMBOLS-REMOVE-BSS-NEXT: {{.*}}(sec 1){{.*}} main
++# SYMBOLS-REMOVE-BSS-EMPTY:
++#
++#
++# Removing the .text section is ok and just removes the external symbol
++# referring to it.
++#
++# SECTIONS-REMOVE-TEXT: Sections:
++# SECTIONS-REMOVE-TEXT-NEXT: Idx Name
++# SECTIONS-REMOVE-TEXT-NEXT: 0 .bss
++# SECTIONS-REMOVE-TEXT-NEXT: 1 .comdat
++# SECTIONS-REMOVE-TEXT-NEXT: 2 .associative
++# SECTIONS-REMOVE-TEXT-EMPTY:
++#
++# SYMBOLS-REMOVE-TEXT: SYMBOL TABLE:
++# SYMBOLS-REMOVE-TEXT-NEXT: {{.*}}(sec -1){{.*}} @feat.00
++# SYMBOLS-REMOVE-TEXT-NEXT: {{.*}}(sec 1){{.*}} .bss
++# SYMBOLS-REMOVE-TEXT-NEXT: AUX scnlen {{.*}} assoc 1 comdat 0
++# SYMBOLS-REMOVE-TEXT-NEXT: {{.*}}(sec 3){{.*}} .associative
++# SYMBOLS-REMOVE-TEXT-NEXT: AUX scnlen {{.*}} assoc 2 comdat 5
++# SYMBOLS-REMOVE-TEXT-NEXT: {{.*}}(sec 2){{.*}} .comdat
++# SYMBOLS-REMOVE-TEXT-NEXT: AUX scnlen {{.*}} assoc 2 comdat 2
++# SYMBOLS-REMOVE-TEXT-NEXT: {{.*}}(sec 2){{.*}} foo
++# SYMBOLS-REMOVE-TEXT-EMPTY:
++#
++#
++# Removing the .comdat section fails, since the .text section has relocations
++# against it.
++#
++# ERROR-RELOC: Relocation target foo ({{.*}}) not found
++#
++#
++# Removing the .comdat section and .text (with a relocation against .comdat)
++# works, as it also removes the .associative section transitively.
++#
++# SECTIONS-REMOVE-TEXT-COMDAT: Sections:
++# SECTIONS-REMOVE-TEXT-COMDAT-NEXT: Idx Name
++# SECTIONS-REMOVE-TEXT-COMDAT-NEXT: 0 .bss
++# SECTIONS-REMOVE-TEXT-COMDAT-EMPTY:
++#
++# SYMBOLS-REMOVE-TEXT-COMDAT: SYMBOL TABLE:
++# SYMBOLS-REMOVE-TEXT-COMDAT-NEXT: {{.*}}(sec -1){{.*}} @feat.00
++# SYMBOLS-REMOVE-TEXT-COMDAT-NEXT: {{.*}}(sec 1){{.*}} .bss
++# SYMBOLS-REMOVE-TEXT-COMDAT-NEXT: AUX scnlen {{.*}} assoc 1 comdat 0
++# SYMBOLS-REMOVE-TEXT-COMDAT-EMPTY:
++
++--- !COFF
++header:
++ Machine: IMAGE_FILE_MACHINE_AMD64
++ Characteristics: [ ]
++sections:
++ - Name: .text
++ Characteristics: [ ]
++ Alignment: 4
++ SectionData: 488B0500000000C3
++ Relocations:
++ - VirtualAddress: 3
++ SymbolName: foo
++ Type: IMAGE_REL_AMD64_REL32
++ - Name: .bss
++ Characteristics: [ ]
++ Alignment: 4
++ SectionData: ''
++ - Name: .comdat
++ Characteristics: [ IMAGE_SCN_LNK_COMDAT ]
++ Alignment: 1
++ SectionData: '2A000000'
++ - Name: .associative
++ Characteristics: [ IMAGE_SCN_LNK_COMDAT ]
++ Alignment: 1
++ SectionData: '0000000000000000'
++symbols:
++ - Name: '@feat.00'
++ Value: 0
++ SectionNumber: -1
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_NULL
++ StorageClass: IMAGE_SYM_CLASS_STATIC
++ - Name: .text
++ Value: 0
++ SectionNumber: 1
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_NULL
++ StorageClass: IMAGE_SYM_CLASS_STATIC
++ SectionDefinition:
++ Length: 8
++ NumberOfRelocations: 1
++ NumberOfLinenumbers: 0
++ CheckSum: 583624169
++ Number: 1
++ - Name: .bss
++ Value: 0
++ SectionNumber: 2
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_NULL
++ StorageClass: IMAGE_SYM_CLASS_STATIC
++ SectionDefinition:
++ Length: 0
++ NumberOfRelocations: 0
++ NumberOfLinenumbers: 0
++ CheckSum: 0
++ Number: 2
++ - Name: .associative
++ Value: 0
++ SectionNumber: 4
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_NULL
++ StorageClass: IMAGE_SYM_CLASS_STATIC
++ SectionDefinition:
++ Length: 8
++ NumberOfRelocations: 0
++ NumberOfLinenumbers: 0
++ CheckSum: 0
++ Number: 3
++ Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
++ - Name: .comdat
++ Value: 0
++ SectionNumber: 3
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_NULL
++ StorageClass: IMAGE_SYM_CLASS_STATIC
++ SectionDefinition:
++ Length: 4
++ NumberOfRelocations: 0
++ NumberOfLinenumbers: 0
++ CheckSum: 3482275674
++ Number: 3
++ Selection: IMAGE_COMDAT_SELECT_ANY
++ - Name: foo
++ Value: 0
++ SectionNumber: 3
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_NULL
++ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
++ - Name: main
++ Value: 0
++ SectionNumber: 1
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_NULL
++ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
++...
+diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+index 437dccbd3d5..dd2e4829218 100644
+--- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+@@ -27,9 +27,17 @@ using namespace object;
+ using namespace COFF;
+
+ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
++ // Perform the actual section removals.
++ Obj.removeSections([&Config](const Section &Sec) {
++ if (is_contained(Config.ToRemove, Sec.Name))
++ return true;
++
++ return false;
++ });
++
+ // StripAll removes all symbols and thus also removes all relocations.
+ if (Config.StripAll || Config.StripAllGNU)
+- for (Section &Sec : Obj.Sections)
++ for (Section &Sec : Obj.getMutableSections())
+ Sec.Relocs.clear();
+
+ // If we need to do per-symbol removals, initialize the Referenced field.
+diff --git a/llvm/tools/llvm-objcopy/COFF/Object.cpp b/llvm/tools/llvm-objcopy/COFF/Object.cpp
+index e58e161e7d2..e19cea6aa9d 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Object.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Object.cpp
+@@ -7,6 +7,7 @@
+ //===----------------------------------------------------------------------===//
+
+ #include "Object.h"
++#include "llvm/ADT/DenseSet.h"
+ #include <algorithm>
+
+ namespace llvm {
+@@ -64,6 +65,68 @@ Error Object::markSymbols() {
+ return Error::success();
+ }
+
++void Object::addSections(ArrayRef<Section> NewSections) {
++ for (Section S : NewSections) {
++ S.UniqueId = NextSectionUniqueId++;
++ Sections.emplace_back(S);
++ }
++ updateSections();
++}
++
++void Object::updateSections() {
++ SectionMap = DenseMap<ssize_t, Section *>(Sections.size());
++ size_t Index = 1;
++ for (Section &S : Sections) {
++ SectionMap[S.UniqueId] = &S;
++ S.Index = Index++;
++ }
++}
++
++const Section *Object::findSection(ssize_t UniqueId) const {
++ auto It = SectionMap.find(UniqueId);
++ if (It == SectionMap.end())
++ return nullptr;
++ return It->second;
++}
++
++void Object::removeSections(function_ref<bool(const Section &)> ToRemove) {
++ DenseSet<ssize_t> AssociatedSections;
++ auto RemoveAssociated = [&AssociatedSections](const Section &Sec) {
++ return AssociatedSections.count(Sec.UniqueId) == 1;
++ };
++ do {
++ DenseSet<ssize_t> RemovedSections;
++ Sections.erase(
++ std::remove_if(std::begin(Sections), std::end(Sections),
++ [ToRemove, &RemovedSections](const Section &Sec) {
++ bool Remove = ToRemove(Sec);
++ if (Remove)
++ RemovedSections.insert(Sec.UniqueId);
++ return Remove;
++ }),
++ std::end(Sections));
++ // Remove all symbols referring to the removed sections.
++ AssociatedSections.clear();
++ Symbols.erase(
++ std::remove_if(
++ std::begin(Symbols), std::end(Symbols),
++ [&RemovedSections, &AssociatedSections](const Symbol &Sym) {
++ // If there are sections that are associative to a removed
++ // section,
++ // remove those as well as nothing will include them (and we can't
++ // leave them dangling).
++ if (RemovedSections.count(Sym.AssociativeComdatTargetSectionId) ==
++ 1)
++ AssociatedSections.insert(Sym.TargetSectionId);
++ return RemovedSections.count(Sym.TargetSectionId) == 1;
++ }),
++ std::end(Symbols));
++ ToRemove = RemoveAssociated;
++ } while (!AssociatedSections.empty());
++ updateSections();
++ updateSymbols();
++}
++
+ } // end namespace coff
+ } // end namespace objcopy
+ } // end namespace llvm
+diff --git a/llvm/tools/llvm-objcopy/COFF/Object.h b/llvm/tools/llvm-objcopy/COFF/Object.h
+index e6147c40b7c..a73e93620d3 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Object.h
++++ b/llvm/tools/llvm-objcopy/COFF/Object.h
+@@ -37,12 +37,16 @@ struct Section {
+ ArrayRef<uint8_t> Contents;
+ std::vector<Relocation> Relocs;
+ StringRef Name;
++ ssize_t UniqueId;
++ size_t Index;
+ };
+
+ struct Symbol {
+ object::coff_symbol32 Sym;
+ StringRef Name;
+- ArrayRef<uint8_t> AuxData;
++ std::vector<uint8_t> AuxData;
++ ssize_t TargetSectionId;
++ ssize_t AssociativeComdatTargetSectionId = 0;
+ size_t UniqueId;
+ size_t RawIndex;
+ bool Referenced;
+@@ -61,7 +65,6 @@ struct Object {
+ uint32_t BaseOfData = 0; // pe32plus_header lacks this field.
+
+ std::vector<object::data_directory> DataDirectories;
+- std::vector<Section> Sections;
+
+ ArrayRef<Symbol> getSymbols() const { return Symbols; }
+ // This allows mutating individual Symbols, but not mutating the list
+@@ -79,14 +82,34 @@ struct Object {
+ // all sections.
+ Error markSymbols();
+
++ ArrayRef<Section> getSections() const { return Sections; }
++ // This allows mutating individual Sections, but not mutating the list
++ // of symbols itself.
++ iterator_range<std::vector<Section>::iterator> getMutableSections() {
++ return make_range(Sections.begin(), Sections.end());
++ }
++
++ const Section *findSection(ssize_t UniqueId) const;
++
++ void addSections(ArrayRef<Section> NewSections);
++ void removeSections(function_ref<bool(const Section &)> ToRemove);
++
+ private:
+ std::vector<Symbol> Symbols;
+ DenseMap<size_t, Symbol *> SymbolMap;
+
+ size_t NextSymbolUniqueId = 0;
+
++ std::vector<Section> Sections;
++ DenseMap<ssize_t, Section *> SectionMap;
++
++ ssize_t NextSectionUniqueId = 1; // Allow a UniqueId 0 to mean undefined.
++
+ // Update SymbolMap and RawIndex in each Symbol.
+ void updateSymbols();
++
++ // Update SectionMap and Index in each Section.
++ void updateSections();
+ };
+
+ // Copy between coff_symbol16 and coff_symbol32.
+diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.cpp b/llvm/tools/llvm-objcopy/COFF/Reader.cpp
+index d794042ae24..c8abe2913a2 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Reader.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Reader.cpp
+@@ -11,6 +11,7 @@
+ #include "llvm-objcopy.h"
+ #include "llvm/ADT/ArrayRef.h"
+ #include "llvm/ADT/StringRef.h"
++#include "llvm/BinaryFormat/COFF.h"
+ #include "llvm/Object/COFF.h"
+ #include "llvm/Support/ErrorHandling.h"
+ #include <cstddef>
+@@ -21,6 +22,7 @@ namespace objcopy {
+ namespace coff {
+
+ using namespace object;
++using namespace COFF;
+
+ Error COFFReader::readExecutableHeaders(Object &Obj) const {
+ const dos_header *DH = COFFObj.getDOSHeader();
+@@ -58,13 +60,14 @@ Error COFFReader::readExecutableHeaders(Object &Obj) const {
+ }
+
+ Error COFFReader::readSections(Object &Obj) const {
++ std::vector<Section> Sections;
+ // Section indexing starts from 1.
+ for (size_t I = 1, E = COFFObj.getNumberOfSections(); I <= E; I++) {
+ const coff_section *Sec;
+ if (auto EC = COFFObj.getSection(I, Sec))
+ return errorCodeToError(EC);
+- Obj.Sections.push_back(Section());
+- Section &S = Obj.Sections.back();
++ Sections.push_back(Section());
++ Section &S = Sections.back();
+ S.Header = *Sec;
+ if (auto EC = COFFObj.getSectionContents(Sec, S.Contents))
+ return errorCodeToError(EC);
+@@ -77,12 +80,14 @@ Error COFFReader::readSections(Object &Obj) const {
+ return make_error<StringError>("Extended relocations not supported yet",
+ object_error::parse_failed);
+ }
++ Obj.addSections(Sections);
+ return Error::success();
+ }
+
+ Error COFFReader::readSymbols(Object &Obj, bool IsBigObj) const {
+ std::vector<Symbol> Symbols;
+ Symbols.reserve(COFFObj.getRawNumberOfSymbols());
++ ArrayRef<Section> Sections = Obj.getSections();
+ for (uint32_t I = 0, E = COFFObj.getRawNumberOfSymbols(); I < E;) {
+ Expected<COFFSymbolRef> SymOrErr = COFFObj.getSymbol(I);
+ if (!SymOrErr)
+@@ -103,6 +108,26 @@ Error COFFReader::readSymbols(Object &Obj, bool IsBigObj) const {
+ Sym.AuxData = COFFObj.getSymbolAuxData(SymRef);
+ assert((Sym.AuxData.size() %
+ (IsBigObj ? sizeof(coff_symbol32) : sizeof(coff_symbol16))) == 0);
++ // Find the unique id of the section
++ if (SymRef.getSectionNumber() <=
++ 0) // Special symbol (undefined/absolute/debug)
++ Sym.TargetSectionId = SymRef.getSectionNumber();
++ else if (static_cast<uint32_t>(SymRef.getSectionNumber() - 1) <
++ Sections.size())
++ Sym.TargetSectionId = Sections[SymRef.getSectionNumber() - 1].UniqueId;
++ else
++ return make_error<StringError>("Section number out of range",
++ object_error::parse_failed);
++ // For section definitions, check if it is comdat associative, and if
++ // it is, find the target section unique id.
++ const coff_aux_section_definition *SD = SymRef.getSectionDefinition();
++ if (SD && SD->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
++ int32_t Index = SD->getNumber(IsBigObj);
++ if (Index <= 0 || static_cast<uint32_t>(Index - 1) >= Sections.size())
++ return make_error<StringError>("Unexpected associative section index",
++ object_error::parse_failed);
++ Sym.AssociativeComdatTargetSectionId = Sections[Index - 1].UniqueId;
++ }
+ I += 1 + SymRef.getNumberOfAuxSymbols();
+ }
+ Obj.addSymbols(Symbols);
+@@ -116,7 +141,7 @@ Error COFFReader::setRelocTargets(Object &Obj) const {
+ for (size_t I = 0; I < Sym.Sym.NumberOfAuxSymbols; I++)
+ RawSymbolTable.push_back(nullptr);
+ }
+- for (Section &Sec : Obj.Sections) {
++ for (Section &Sec : Obj.getMutableSections()) {
+ for (Relocation &R : Sec.Relocs) {
+ if (R.Reloc.SymbolTableIndex >= RawSymbolTable.size())
+ return make_error<StringError>("SymbolTableIndex out of range",
+diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.cpp b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
+index c347810dd24..9fb7812672b 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Writer.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
+@@ -25,7 +25,7 @@ using namespace object;
+ using namespace COFF;
+
+ Error COFFWriter::finalizeRelocTargets() {
+- for (Section &Sec : Obj.Sections) {
++ for (Section &Sec : Obj.getMutableSections()) {
+ for (Relocation &R : Sec.Relocs) {
+ const Symbol *Sym = Obj.findSymbol(R.Target);
+ if (Sym == nullptr)
+@@ -39,8 +39,48 @@ Error COFFWriter::finalizeRelocTargets() {
+ return Error::success();
+ }
+
++Error COFFWriter::finalizeSectionNumbers() {
++ for (Symbol &Sym : Obj.getMutableSymbols()) {
++ if (Sym.TargetSectionId <= 0) {
++ // Undefined, or a special kind of symbol. These negative values
++ // are stored in the SectionNumber field which is unsigned.
++ Sym.Sym.SectionNumber = static_cast<uint32_t>(Sym.TargetSectionId);
++ } else {
++ const Section *Sec = Obj.findSection(Sym.TargetSectionId);
++ if (Sec == nullptr)
++ return make_error<StringError>("Symbol " + Sym.Name +
++ " points to a removed section",
++ object_error::invalid_symbol_index);
++ Sym.Sym.SectionNumber = Sec->Index;
++
++ if (Sym.Sym.NumberOfAuxSymbols == 1 &&
++ Sym.Sym.StorageClass == IMAGE_SYM_CLASS_STATIC) {
++ coff_aux_section_definition *SD =
++ reinterpret_cast<coff_aux_section_definition *>(Sym.AuxData.data());
++ uint32_t SDSectionNumber;
++ if (Sym.AssociativeComdatTargetSectionId == 0) {
++ // Not a comdat associative section; just set the Number field to
++ // the number of the section itself.
++ SDSectionNumber = Sec->Index;
++ } else {
++ Sec = Obj.findSection(Sym.AssociativeComdatTargetSectionId);
++ if (Sec == nullptr)
++ return make_error<StringError>(
++ "Symbol " + Sym.Name + " is associative to a removed section",
++ object_error::invalid_symbol_index);
++ SDSectionNumber = Sec->Index;
++ }
++ // Update the section definition with the new section number.
++ SD->NumberLowPart = static_cast<uint16_t>(SDSectionNumber);
++ SD->NumberHighPart = static_cast<uint16_t>(SDSectionNumber >> 16);
++ }
++ }
++ }
++ return Error::success();
++}
++
+ void COFFWriter::layoutSections() {
+- for (auto &S : Obj.Sections) {
++ for (auto &S : Obj.getMutableSections()) {
+ if (S.Header.SizeOfRawData > 0)
+ S.Header.PointerToRawData = FileSize;
+ FileSize += S.Header.SizeOfRawData; // For executables, this is already
+@@ -57,7 +97,7 @@ void COFFWriter::layoutSections() {
+ }
+
+ size_t COFFWriter::finalizeStringTable() {
+- for (auto &S : Obj.Sections)
++ for (const auto &S : Obj.getSections())
+ if (S.Name.size() > COFF::NameSize)
+ StrTabBuilder.add(S.Name);
+
+@@ -67,7 +107,7 @@ size_t COFFWriter::finalizeStringTable() {
+
+ StrTabBuilder.finalize();
+
+- for (auto &S : Obj.Sections) {
++ for (auto &S : Obj.getMutableSections()) {
+ if (S.Name.size() > COFF::NameSize) {
+ snprintf(S.Header.Name, sizeof(S.Header.Name), "/%d",
+ (int)StrTabBuilder.getOffset(S.Name));
+@@ -97,6 +137,8 @@ std::pair<size_t, size_t> COFFWriter::finalizeSymbolTable() {
+ Error COFFWriter::finalize(bool IsBigObj) {
+ if (Error E = finalizeRelocTargets())
+ return E;
++ if (Error E = finalizeSectionNumbers())
++ return E;
+
+ size_t SizeOfHeaders = 0;
+ FileAlignment = 1;
+@@ -113,10 +155,10 @@ Error COFFWriter::finalize(bool IsBigObj) {
+ SizeOfHeaders +=
+ PeHeaderSize + sizeof(data_directory) * Obj.DataDirectories.size();
+ }
+- Obj.CoffFileHeader.NumberOfSections = Obj.Sections.size();
++ Obj.CoffFileHeader.NumberOfSections = Obj.getSections().size();
+ SizeOfHeaders +=
+ IsBigObj ? sizeof(coff_bigobj_file_header) : sizeof(coff_file_header);
+- SizeOfHeaders += sizeof(coff_section) * Obj.Sections.size();
++ SizeOfHeaders += sizeof(coff_section) * Obj.getSections().size();
+ SizeOfHeaders = alignTo(SizeOfHeaders, FileAlignment);
+
+ Obj.CoffFileHeader.SizeOfOptionalHeader =
+@@ -131,8 +173,8 @@ Error COFFWriter::finalize(bool IsBigObj) {
+ Obj.PeHeader.SizeOfHeaders = SizeOfHeaders;
+ Obj.PeHeader.SizeOfInitializedData = SizeOfInitializedData;
+
+- if (!Obj.Sections.empty()) {
+- const Section &S = Obj.Sections.back();
++ if (!Obj.getSections().empty()) {
++ const Section &S = Obj.getSections().back();
+ Obj.PeHeader.SizeOfImage =
+ alignTo(S.Header.VirtualAddress + S.Header.VirtualSize,
+ Obj.PeHeader.SectionAlignment);
+@@ -198,7 +240,7 @@ void COFFWriter::writeHeaders(bool IsBigObj) {
+ BigObjHeader.unused4 = 0;
+ // The value in Obj.CoffFileHeader.NumberOfSections is truncated, thus
+ // get the original one instead.
+- BigObjHeader.NumberOfSections = Obj.Sections.size();
++ BigObjHeader.NumberOfSections = Obj.getSections().size();
+ BigObjHeader.PointerToSymbolTable = Obj.CoffFileHeader.PointerToSymbolTable;
+ BigObjHeader.NumberOfSymbols = Obj.CoffFileHeader.NumberOfSymbols;
+
+@@ -223,14 +265,14 @@ void COFFWriter::writeHeaders(bool IsBigObj) {
+ Ptr += sizeof(DD);
+ }
+ }
+- for (const auto &S : Obj.Sections) {
++ for (const auto &S : Obj.getSections()) {
+ memcpy(Ptr, &S.Header, sizeof(S.Header));
+ Ptr += sizeof(S.Header);
+ }
+ }
+
+ void COFFWriter::writeSections() {
+- for (const auto &S : Obj.Sections) {
++ for (const auto &S : Obj.getSections()) {
+ uint8_t *Ptr = Buf.getBufferStart() + S.Header.PointerToRawData;
+ std::copy(S.Contents.begin(), S.Contents.end(), Ptr);
+
+@@ -295,7 +337,7 @@ Error COFFWriter::patchDebugDirectory() {
+ const data_directory *Dir = &Obj.DataDirectories[DEBUG_DIRECTORY];
+ if (Dir->Size <= 0)
+ return Error::success();
+- for (const auto &S : Obj.Sections) {
++ for (const auto &S : Obj.getSections()) {
+ if (Dir->RelativeVirtualAddress >= S.Header.VirtualAddress &&
+ Dir->RelativeVirtualAddress <
+ S.Header.VirtualAddress + S.Header.SizeOfRawData) {
+@@ -324,7 +366,7 @@ Error COFFWriter::patchDebugDirectory() {
+ }
+
+ Error COFFWriter::write() {
+- bool IsBigObj = Obj.Sections.size() > MaxNumberOfSections16;
++ bool IsBigObj = Obj.getSections().size() > MaxNumberOfSections16;
+ if (IsBigObj && Obj.IsPE)
+ return make_error<StringError>("Too many sections for executable",
+ object_error::parse_failed);
+diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.h b/llvm/tools/llvm-objcopy/COFF/Writer.h
+index 52fef385926..a967a103df9 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Writer.h
++++ b/llvm/tools/llvm-objcopy/COFF/Writer.h
+@@ -31,6 +31,7 @@ class COFFWriter {
+ StringTableBuilder StrTabBuilder;
+
+ Error finalizeRelocTargets();
++ Error finalizeSectionNumbers();
+ void layoutSections();
+ size_t finalizeStringTable();
+ template <class SymbolTy> std::pair<size_t, size_t> finalizeSymbolTable();
+--
+2.17.1
+
diff --git a/projects/clang/win-patches/llvm-objcopy-3.patch b/projects/clang/win-patches/llvm-objcopy-3.patch
new file mode 100644
index 0000000..6e303c0
--- /dev/null
+++ b/projects/clang/win-patches/llvm-objcopy-3.patch
@@ -0,0 +1,160 @@
+From 2b6e1b7585d6bd997ea4e4233c904a6d2c11ad33 Mon Sep 17 00:00:00 2001
+From: Martin Storsjo <martin(a)martin.st>
+Date: Sat, 19 Jan 2019 19:42:41 +0000
+Subject: [PATCH] [llvm-objcopy] [COFF] Implement --strip-debug
+
+Also remove sections similarly for --strip-all, --discard-all,
+--strip-unneeded.
+
+Differential Revision: https://reviews.llvm.org/D56839
+
+git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351661 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ test/tools/llvm-objcopy/COFF/strip-debug.test | 109 ++++++++++++++++++
+ tools/llvm-objcopy/COFF/COFFObjcopy.cpp | 11 ++
+ 2 files changed, 120 insertions(+)
+ create mode 100644 test/tools/llvm-objcopy/COFF/strip-debug.test
+
+diff --git a/llvm/test/tools/llvm-objcopy/COFF/strip-debug.test b/llvm/test/tools/llvm-objcopy/COFF/strip-debug.test
+new file mode 100644
+index 00000000000..97fa96aac70
+--- /dev/null
++++ b/llvm/test/tools/llvm-objcopy/COFF/strip-debug.test
+@@ -0,0 +1,109 @@
++# RUN: yaml2obj %s > %t.in.o
++#
++# RUN: llvm-objdump --section-headers %t.in.o | FileCheck %s --check-prefixes=SECTIONS,SECTIONS-PRE
++# RUN: llvm-objdump -t %t.in.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-PRE
++#
++# RUN: llvm-objcopy --strip-debug %t.in.o %t.out.o
++# RUN: llvm-objdump --section-headers %t.out.o | FileCheck %s --check-prefixes=SECTIONS
++# RUN: llvm-objdump -t %t.out.o | FileCheck %s --check-prefixes=SYMBOLS
++#
++# Test that --strip-all, --strip-all-gnu, --discard-all and --strip-unneeded,
++# plus llvm-strip without arguments all produce a similiar set of sections
++# (while they remove symbols differently).
++#
++# RUN: llvm-objcopy --strip-all %t.in.o %t.strip-all.o
++# RUN: llvm-objdump --section-headers %t.strip-all.o | FileCheck %s --check-prefixes=SECTIONS
++#
++# RUN: llvm-objcopy --strip-all-gnu %t.in.o %t.strip-all-gnu.o
++# RUN: llvm-objdump --section-headers %t.strip-all-gnu.o | FileCheck %s --check-prefixes=SECTIONS
++#
++# RUN: llvm-objcopy --discard-all %t.in.o %t.discard-all.o
++# RUN: llvm-objdump --section-headers %t.discard-all.o | FileCheck %s --check-prefixes=SECTIONS
++#
++# RUN: llvm-objcopy --discard-all %t.in.o %t.strip-unneeded.o
++# RUN: llvm-objdump --section-headers %t.strip-unneeded.o | FileCheck %s --check-prefixes=SECTIONS
++#
++# SECTIONS: Sections:
++# SECTIONS-NEXT: Idx Name
++# SECTIONS-NEXT: 0 .text
++# SECTIONS-NEXT: 1 .data
++# SECTIONS-NEXT: 2 .bss
++# SECTIONS-NEXT: 3 .xdata
++# SECTIONS-NEXT: 4 .reloc
++# SECTIONS-PRE-NEXT: 5 .debug_discardable
++# SECTIONS-NEXT: {{.*}} .debug_undiscardable
++# SECTIONS-NEXT: {{.*}} .llvm_addrsig
++# SECTIONS-EMPTY:
++#
++# Test that --strip-debug doesn't remove e.g. unreferenced local symbols.
++#
++# SYMBOLS: SYMBOL TABLE:
++# SYMBOLS-NEXT: external
++# SYMBOLS-NEXT: local_unreferenced
++# SYMBOLS-PRE-NEXT: debug_discardable_sym
++# SYMBOLS-NEXT: debug_undiscardable_sym
++# SYMBOLS-EMPTY:
++
++--- !COFF
++header:
++ Machine: IMAGE_FILE_MACHINE_AMD64
++ Characteristics: [ ]
++sections:
++ - Name: .text
++ Characteristics: [ ]
++ Alignment: 4
++ SectionData: 00000000
++ - Name: .data
++ Characteristics: [ ]
++ Alignment: 4
++ SectionData: 00000000
++ - Name: .bss
++ Characteristics: [ ]
++ Alignment: 4
++ SectionData: 00000000
++ - Name: .xdata
++ Characteristics: [ ]
++ Alignment: 4
++ SectionData: 00000000
++ - Name: .reloc
++ Characteristics: [ IMAGE_SCN_MEM_DISCARDABLE ]
++ Alignment: 4
++ SectionData: 00000000
++ - Name: .debug_discardable
++ Characteristics: [ IMAGE_SCN_MEM_DISCARDABLE ]
++ Alignment: 4
++ SectionData: 00000000
++ - Name: .debug_undiscardable
++ Characteristics: [ ]
++ Alignment: 4
++ SectionData: 00000000
++ - Name: .llvm_addrsig
++ Characteristics: [ IMAGE_SCN_LNK_REMOVE ]
++ Alignment: 4
++ SectionData: 00000000
++symbols:
++ - Name: external
++ Value: 0
++ SectionNumber: 1
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_NULL
++ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
++ - Name: local_unreferenced
++ Value: 0
++ SectionNumber: 1
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_NULL
++ StorageClass: IMAGE_SYM_CLASS_STATIC
++ - Name: debug_discardable_sym
++ Value: 0
++ SectionNumber: 6
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_NULL
++ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
++ - Name: debug_undiscardable_sym
++ Value: 0
++ SectionNumber: 7
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_NULL
++ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
++...
+diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+index dd2e4829218..13d8efde37c 100644
+--- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+@@ -26,9 +26,20 @@ namespace coff {
+ using namespace object;
+ using namespace COFF;
+
++static bool isDebugSection(const Section &Sec) {
++ return Sec.Name.startswith(".debug");
++}
++
+ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
+ // Perform the actual section removals.
+ Obj.removeSections([&Config](const Section &Sec) {
++ if (Config.StripDebug || Config.StripAll || Config.StripAllGNU ||
++ Config.DiscardAll || Config.StripUnneeded) {
++ if (isDebugSection(Sec) &&
++ (Sec.Header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE) != 0)
++ return true;
++ }
++
+ if (is_contained(Config.ToRemove, Sec.Name))
+ return true;
+
+--
+2.17.1
+
diff --git a/projects/clang/win-patches/llvm-objcopy-4.patch b/projects/clang/win-patches/llvm-objcopy-4.patch
new file mode 100644
index 0000000..e922384
--- /dev/null
+++ b/projects/clang/win-patches/llvm-objcopy-4.patch
@@ -0,0 +1,222 @@
+From 526aa2e94355b7feb3bf7774a6e1899f68e94ad8 Mon Sep 17 00:00:00 2001
+From: Martin Storsjo <martin(a)martin.st>
+Date: Sat, 19 Jan 2019 19:42:48 +0000
+Subject: [PATCH] [llvm-objcopy] [COFF] Implement --only-keep-debug
+
+Differential Revision: https://reviews.llvm.org/D56840
+
+git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351662 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ .../COFF/Inputs/only-keep-sections.yaml | 77 +++++++++++++++++++
+ .../llvm-objcopy/COFF/only-keep-debug.test | 58 ++++++++++++++
+ tools/llvm-objcopy/COFF/COFFObjcopy.cpp | 10 +++
+ tools/llvm-objcopy/COFF/Object.cpp | 10 +++
+ tools/llvm-objcopy/COFF/Object.h | 1 +
+ 5 files changed, 156 insertions(+)
+ create mode 100644 test/tools/llvm-objcopy/COFF/Inputs/only-keep-sections.yaml
+ create mode 100644 test/tools/llvm-objcopy/COFF/only-keep-debug.test
+
+diff --git a/llvm/test/tools/llvm-objcopy/COFF/Inputs/only-keep-sections.yaml b/llvm/test/tools/llvm-objcopy/COFF/Inputs/only-keep-sections.yaml
+new file mode 100644
+index 00000000000..b5437e10763
+--- /dev/null
++++ b/llvm/test/tools/llvm-objcopy/COFF/Inputs/only-keep-sections.yaml
+@@ -0,0 +1,77 @@
++--- !COFF
++OptionalHeader:
++ AddressOfEntryPoint: 4144
++ ImageBase: 1073741824
++ SectionAlignment: 4096
++ FileAlignment: 512
++ MajorOperatingSystemVersion: 6
++ MinorOperatingSystemVersion: 0
++ MajorImageVersion: 0
++ MinorImageVersion: 0
++ MajorSubsystemVersion: 6
++ MinorSubsystemVersion: 0
++ Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI
++ DLLCharacteristics: [ ]
++ SizeOfStackReserve: 1048576
++ SizeOfStackCommit: 4096
++ SizeOfHeapReserve: 1048576
++ SizeOfHeapCommit: 4096
++header:
++ Machine: IMAGE_FILE_MACHINE_AMD64
++ Characteristics: [ ]
++sections:
++ - Name: .text
++ Characteristics: [ IMAGE_SCN_CNT_CODE ]
++ VirtualAddress: 4096
++ VirtualSize: 4
++ SectionData: C3C3C3C3
++ - Name: .rdata
++ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA ]
++ VirtualAddress: 8192
++ VirtualSize: 4
++ SectionData: 2A000000
++ - Name: .buildid
++ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA ]
++ VirtualAddress: 12288
++ VirtualSize: 4
++ SectionData: 2B000000
++ - Name: .reloc
++ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE ]
++ VirtualAddress: 16384
++ VirtualSize: 4
++ SectionData: 2C000000
++ - Name: .debug_discardable
++ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE ]
++ VirtualAddress: 20480
++ VirtualSize: 4
++ SectionData: 2D000000
++ - Name: .debug_undiscardable
++ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA ]
++ VirtualAddress: 24576
++ VirtualSize: 4
++ SectionData: 2E000000
++ - Name: .unflagged
++ Characteristics: [ ]
++ VirtualAddress: 28672
++ VirtualSize: 4
++ SectionData: 2F000000
++symbols:
++ - Name: main
++ Value: 2
++ SectionNumber: 1
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
++ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
++ - Name: debug_discardable_sym
++ Value: 0
++ SectionNumber: 5
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
++ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
++ - Name: debug_undiscardable_sym
++ Value: 0
++ SectionNumber: 6
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
++ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
++...
+diff --git a/llvm/test/tools/llvm-objcopy/COFF/only-keep-debug.test b/llvm/test/tools/llvm-objcopy/COFF/only-keep-debug.test
+new file mode 100644
+index 00000000000..5518d4000fc
+--- /dev/null
++++ b/llvm/test/tools/llvm-objcopy/COFF/only-keep-debug.test
+@@ -0,0 +1,58 @@
++RUN: yaml2obj %p/Inputs/only-keep-sections.yaml > %t.in.exe
++
++RUN: llvm-objcopy --only-keep-debug %t.in.exe %t.out.exe
++RUN: llvm-readobj --sections %t.out.exe | FileCheck %s --check-prefix=SECTIONS
++RUN: llvm-objdump -t %t.out.exe | FileCheck %s --check-prefix=SYMBOLS
++
++Check that all non-debug/buildid sections with IMAGE_SCN_CNT_CODE
++or IMAGE_SCN_CNT_INITIALIZED_DATA are truncated, and no others.
++
++SECTIONS: Sections [
++SECTIONS-NEXT: Section {
++SECTIONS-NEXT: Number: 1
++SECTIONS-NEXT: Name: .text
++SECTIONS-NEXT: VirtualSize: 0x4
++SECTIONS-NEXT: VirtualAddress:
++SECTIONS-NEXT: RawDataSize: 0
++SECTIONS: Section {
++SECTIONS-NEXT: Number: 2
++SECTIONS-NEXT: Name: .rdata
++SECTIONS-NEXT: VirtualSize: 0x4
++SECTIONS-NEXT: VirtualAddress:
++SECTIONS-NEXT: RawDataSize: 0
++SECTIONS: Section {
++SECTIONS-NEXT: Number: 3
++SECTIONS-NEXT: Name: .buildid
++SECTIONS-NEXT: VirtualSize: 0x4
++SECTIONS-NEXT: VirtualAddress:
++SECTIONS-NEXT: RawDataSize: 512
++SECTIONS: Section {
++SECTIONS-NEXT: Number: 4
++SECTIONS-NEXT: Name: .reloc
++SECTIONS-NEXT: VirtualSize: 0x4
++SECTIONS-NEXT: VirtualAddress:
++SECTIONS-NEXT: RawDataSize: 0
++SECTIONS: Section {
++SECTIONS-NEXT: Number: 5
++SECTIONS-NEXT: Name: .debug_discardable
++SECTIONS-NEXT: VirtualSize: 0x4
++SECTIONS-NEXT: VirtualAddress:
++SECTIONS-NEXT: RawDataSize: 512
++SECTIONS: Section {
++SECTIONS-NEXT: Number: 6
++SECTIONS-NEXT: Name: .debug_undiscardable
++SECTIONS-NEXT: VirtualSize: 0x4
++SECTIONS-NEXT: VirtualAddress:
++SECTIONS-NEXT: RawDataSize: 512
++SECTIONS: Section {
++SECTIONS-NEXT: Number: 7
++SECTIONS-NEXT: Name: .unflagged
++SECTIONS-NEXT: VirtualSize: 0x4
++SECTIONS-NEXT: VirtualAddress:
++SECTIONS-NEXT: RawDataSize: 512
++
++SYMBOLS: SYMBOL TABLE:
++SYMBOLS-NEXT: main
++SYMBOLS-NEXT: debug_discardable_sym
++SYMBOLS-NEXT: debug_undiscardable_sym
++SYMBOLS-EMPTY:
+diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+index 13d8efde37c..60afbf7bb54 100644
+--- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+@@ -46,6 +46,16 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
+ return false;
+ });
+
++ if (Config.OnlyKeepDebug) {
++ // For --only-keep-debug, we keep all other sections, but remove their
++ // content. The VirtualSize field in the section header is kept intact.
++ Obj.truncateSections([](const Section &Sec) {
++ return !isDebugSection(Sec) && Sec.Name != ".buildid" &&
++ ((Sec.Header.Characteristics &
++ (IMAGE_SCN_CNT_CODE | IMAGE_SCN_CNT_INITIALIZED_DATA)) != 0);
++ });
++ }
++
+ // StripAll removes all symbols and thus also removes all relocations.
+ if (Config.StripAll || Config.StripAllGNU)
+ for (Section &Sec : Obj.getMutableSections())
+diff --git a/llvm/tools/llvm-objcopy/COFF/Object.cpp b/llvm/tools/llvm-objcopy/COFF/Object.cpp
+index e19cea6aa9d..fc87d9e574d 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Object.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Object.cpp
+@@ -127,6 +127,16 @@ void Object::removeSections(function_ref<bool(const Section &)> ToRemove) {
+ updateSymbols();
+ }
+
++void Object::truncateSections(function_ref<bool(const Section &)> ToTruncate) {
++ for (Section &Sec : Sections) {
++ if (ToTruncate(Sec)) {
++ Sec.Contents = ArrayRef<uint8_t>();
++ Sec.Relocs.clear();
++ Sec.Header.SizeOfRawData = 0;
++ }
++ }
++}
++
+ } // end namespace coff
+ } // end namespace objcopy
+ } // end namespace llvm
+diff --git a/llvm/tools/llvm-objcopy/COFF/Object.h b/llvm/tools/llvm-objcopy/COFF/Object.h
+index a73e93620d3..8e200369f0b 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Object.h
++++ b/llvm/tools/llvm-objcopy/COFF/Object.h
+@@ -93,6 +93,7 @@ struct Object {
+
+ void addSections(ArrayRef<Section> NewSections);
+ void removeSections(function_ref<bool(const Section &)> ToRemove);
++ void truncateSections(function_ref<bool(const Section &)> ToTruncate);
+
+ private:
+ std::vector<Symbol> Symbols;
+--
+2.17.1
+
diff --git a/projects/clang/win-patches/llvm-objcopy-5.patch b/projects/clang/win-patches/llvm-objcopy-5.patch
new file mode 100644
index 0000000..657c72a
--- /dev/null
+++ b/projects/clang/win-patches/llvm-objcopy-5.patch
@@ -0,0 +1,61 @@
+From 17dcf25b3ade15605ca27150e4440bcc75caed65 Mon Sep 17 00:00:00 2001
+From: Martin Storsjo <martin(a)martin.st>
+Date: Sat, 19 Jan 2019 19:42:54 +0000
+Subject: [PATCH] [llvm-objcopy] [COFF] Implement --only-section
+
+Differential Revision: https://reviews.llvm.org/D56873
+
+git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351663 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ .../tools/llvm-objcopy/COFF/only-section.test | 21 +++++++++++++++++++
+ tools/llvm-objcopy/COFF/COFFObjcopy.cpp | 6 ++++++
+ 2 files changed, 27 insertions(+)
+ create mode 100644 test/tools/llvm-objcopy/COFF/only-section.test
+
+diff --git a/llvm/test/tools/llvm-objcopy/COFF/only-section.test b/llvm/test/tools/llvm-objcopy/COFF/only-section.test
+new file mode 100644
+index 00000000000..42492ed80ff
+--- /dev/null
++++ b/llvm/test/tools/llvm-objcopy/COFF/only-section.test
+@@ -0,0 +1,21 @@
++RUN: yaml2obj %p/Inputs/only-keep-sections.yaml > %t.in.exe
++
++RUN: llvm-objcopy --only-section .debug_discardable %t.in.exe %t.out.exe
++RUN: llvm-objdump --section-headers -t %t.out.exe | FileCheck %s --check-prefixes=SECTIONS,SECTIONS-DEBUG,SYMBOLS,SYMBOLS-DEBUG
++
++Adding another section stripping option makes it return the intersection of
++kept sections - in this case keeping only .text.
++
++RUN: llvm-objcopy --only-section .debug_discardable --only-section .text --strip-debug %t.in.exe %t.combination.exe
++RUN: llvm-objdump --section-headers -t %t.combination.exe | FileCheck %s --check-prefixes=SECTIONS,SECTIONS-TEXT,SYMBOLS,SYMBOLS-TEXT
++
++SECTIONS: Sections:
++SECTIONS-NEXT: Idx Name
++SECTIONS-DEBUG-NEXT: .debug_discardable
++SECTIONS-TEXT-NEXT: .text
++SECTIONS-EMPTY:
++
++SYMBOLS: SYMBOL TABLE:
++SYMBOLS-DEBUG-NEXT: debug_discardable_sym
++SYMBOLS-TEXT-NEXT: main
++SYMBOLS-EMPTY:
+diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+index 60afbf7bb54..99929d10a1f 100644
+--- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+@@ -33,6 +33,12 @@ static bool isDebugSection(const Section &Sec) {
+ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
+ // Perform the actual section removals.
+ Obj.removeSections([&Config](const Section &Sec) {
++ // Contrary to --only-keep-debug, --only-section fully removes sections that
++ // aren't mentioned.
++ if (!Config.OnlySection.empty() &&
++ !is_contained(Config.OnlySection, Sec.Name))
++ return true;
++
+ if (Config.StripDebug || Config.StripAll || Config.StripAllGNU ||
+ Config.DiscardAll || Config.StripUnneeded) {
+ if (isDebugSection(Sec) &&
+--
+2.17.1
+
diff --git a/projects/clang/win-patches/llvm-objcopy-6.patch b/projects/clang/win-patches/llvm-objcopy-6.patch
new file mode 100644
index 0000000..e70f1b9
--- /dev/null
+++ b/projects/clang/win-patches/llvm-objcopy-6.patch
@@ -0,0 +1,242 @@
+From d3b89a1637cddee1c61e59257cfe92227ead29e5 Mon Sep 17 00:00:00 2001
+From: Martin Storsjo <martin(a)martin.st>
+Date: Tue, 22 Jan 2019 10:57:59 +0000
+Subject: [PATCH] [llvm-objcopy] Consistently use createStringError instead of
+ make_error<StringError>
+
+This was requested in the review of D57006.
+
+Also add missing quotes around symbol names in error messages.
+
+Differential Revision: https://reviews.llvm.org/D57014
+
+git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351799 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ .../llvm-objcopy/COFF/remove-section.test | 2 +-
+ tools/llvm-objcopy/COFF/COFFObjcopy.cpp | 8 ++---
+ tools/llvm-objcopy/COFF/Object.cpp | 5 ++-
+ tools/llvm-objcopy/COFF/Reader.cpp | 24 +++++++-------
+ tools/llvm-objcopy/COFF/Writer.cpp | 33 +++++++++----------
+ tools/llvm-objcopy/ELF/ELFObjcopy.cpp | 10 +++---
+ 6 files changed, 40 insertions(+), 42 deletions(-)
+
+diff --git a/llvm/test/tools/llvm-objcopy/COFF/remove-section.test b/llvm/test/tools/llvm-objcopy/COFF/remove-section.test
+index b3dfb0b98cb..6dc8f6a6c2e 100644
+--- a/llvm/test/tools/llvm-objcopy/COFF/remove-section.test
++++ b/llvm/test/tools/llvm-objcopy/COFF/remove-section.test
+@@ -96,7 +96,7 @@
+ # Removing the .comdat section fails, since the .text section has relocations
+ # against it.
+ #
+-# ERROR-RELOC: Relocation target foo ({{.*}}) not found
++# ERROR-RELOC: Relocation target 'foo' ({{.*}}) not found
+ #
+ #
+ # Removing the .comdat section and .text (with a relocation against .comdat)
+diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+index 99929d10a1f..8d8f53d13d8 100644
+--- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+@@ -84,10 +84,10 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
+ // Explicitly removing a referenced symbol is an error.
+ if (Sym.Referenced)
+ reportError(Config.OutputFilename,
+- make_error<StringError>(
+- "not stripping symbol '" + Sym.Name +
+- "' because it is named in a relocation.",
+- llvm::errc::invalid_argument));
++ createStringError(llvm::errc::invalid_argument,
++ "not stripping symbol '%s' because it is "
++ "named in a relocation.",
++ Sym.Name.str().c_str()));
+ return true;
+ }
+
+diff --git a/llvm/tools/llvm-objcopy/COFF/Object.cpp b/llvm/tools/llvm-objcopy/COFF/Object.cpp
+index fc87d9e574d..83435dffa98 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Object.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Object.cpp
+@@ -56,9 +56,8 @@ Error Object::markSymbols() {
+ for (const Relocation &R : Sec.Relocs) {
+ auto It = SymbolMap.find(R.Target);
+ if (It == SymbolMap.end())
+- return make_error<StringError>("Relocation target " + Twine(R.Target) +
+- " not found",
+- object_error::invalid_symbol_index);
++ return createStringError(object_error::invalid_symbol_index,
++ "Relocation target %zu not found", R.Target);
+ It->second->Referenced = true;
+ }
+ }
+diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.cpp b/llvm/tools/llvm-objcopy/COFF/Reader.cpp
+index c8abe2913a2..20ff32a59dc 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Reader.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Reader.cpp
+@@ -77,8 +77,8 @@ Error COFFReader::readSections(Object &Obj) const {
+ if (auto EC = COFFObj.getSectionName(Sec, S.Name))
+ return errorCodeToError(EC);
+ if (Sec->hasExtendedRelocations())
+- return make_error<StringError>("Extended relocations not supported yet",
+- object_error::parse_failed);
++ return createStringError(object_error::parse_failed,
++ "Extended relocations not supported yet");
+ }
+ Obj.addSections(Sections);
+ return Error::success();
+@@ -116,16 +116,16 @@ Error COFFReader::readSymbols(Object &Obj, bool IsBigObj) const {
+ Sections.size())
+ Sym.TargetSectionId = Sections[SymRef.getSectionNumber() - 1].UniqueId;
+ else
+- return make_error<StringError>("Section number out of range",
+- object_error::parse_failed);
++ return createStringError(object_error::parse_failed,
++ "Section number out of range");
+ // For section definitions, check if it is comdat associative, and if
+ // it is, find the target section unique id.
+ const coff_aux_section_definition *SD = SymRef.getSectionDefinition();
+ if (SD && SD->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
+ int32_t Index = SD->getNumber(IsBigObj);
+ if (Index <= 0 || static_cast<uint32_t>(Index - 1) >= Sections.size())
+- return make_error<StringError>("Unexpected associative section index",
+- object_error::parse_failed);
++ return createStringError(object_error::parse_failed,
++ "Unexpected associative section index");
+ Sym.AssociativeComdatTargetSectionId = Sections[Index - 1].UniqueId;
+ }
+ I += 1 + SymRef.getNumberOfAuxSymbols();
+@@ -144,12 +144,12 @@ Error COFFReader::setRelocTargets(Object &Obj) const {
+ for (Section &Sec : Obj.getMutableSections()) {
+ for (Relocation &R : Sec.Relocs) {
+ if (R.Reloc.SymbolTableIndex >= RawSymbolTable.size())
+- return make_error<StringError>("SymbolTableIndex out of range",
+- object_error::parse_failed);
++ return createStringError(object_error::parse_failed,
++ "SymbolTableIndex out of range");
+ const Symbol *Sym = RawSymbolTable[R.Reloc.SymbolTableIndex];
+ if (Sym == nullptr)
+- return make_error<StringError>("Invalid SymbolTableIndex",
+- object_error::parse_failed);
++ return createStringError(object_error::parse_failed,
++ "Invalid SymbolTableIndex");
+ R.Target = Sym->UniqueId;
+ R.TargetName = Sym->Name;
+ }
+@@ -169,8 +169,8 @@ Expected<std::unique_ptr<Object>> COFFReader::create() const {
+ Obj->CoffFileHeader = *CFH;
+ } else {
+ if (!CBFH)
+- return make_error<StringError>("No COFF file header returned",
+- object_error::parse_failed);
++ return createStringError(object_error::parse_failed,
++ "No COFF file header returned");
+ // Only copying the few fields from the bigobj header that we need
+ // and won't recreate in the end.
+ Obj->CoffFileHeader.Machine = CBFH->Machine;
+diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.cpp b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
+index 9fb7812672b..0321f94a896 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Writer.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
+@@ -29,10 +29,9 @@ Error COFFWriter::finalizeRelocTargets() {
+ for (Relocation &R : Sec.Relocs) {
+ const Symbol *Sym = Obj.findSymbol(R.Target);
+ if (Sym == nullptr)
+- return make_error<StringError>("Relocation target " + R.TargetName +
+- " (" + Twine(R.Target) +
+- ") not found",
+- object_error::invalid_symbol_index);
++ return createStringError(object_error::invalid_symbol_index,
++ "Relocation target '%s' (%zu) not found",
++ R.TargetName.str().c_str(), R.Target);
+ R.Reloc.SymbolTableIndex = Sym->RawIndex;
+ }
+ }
+@@ -48,9 +47,9 @@ Error COFFWriter::finalizeSectionNumbers() {
+ } else {
+ const Section *Sec = Obj.findSection(Sym.TargetSectionId);
+ if (Sec == nullptr)
+- return make_error<StringError>("Symbol " + Sym.Name +
+- " points to a removed section",
+- object_error::invalid_symbol_index);
++ return createStringError(object_error::invalid_symbol_index,
++ "Symbol '%s' points to a removed section",
++ Sym.Name.str().c_str());
+ Sym.Sym.SectionNumber = Sec->Index;
+
+ if (Sym.Sym.NumberOfAuxSymbols == 1 &&
+@@ -65,9 +64,10 @@ Error COFFWriter::finalizeSectionNumbers() {
+ } else {
+ Sec = Obj.findSection(Sym.AssociativeComdatTargetSectionId);
+ if (Sec == nullptr)
+- return make_error<StringError>(
+- "Symbol " + Sym.Name + " is associative to a removed section",
+- object_error::invalid_symbol_index);
++ return createStringError(
++ object_error::invalid_symbol_index,
++ "Symbol '%s' is associative to a removed section",
++ Sym.Name.str().c_str());
+ SDSectionNumber = Sec->Index;
+ }
+ // Update the section definition with the new section number.
+@@ -343,9 +343,8 @@ Error COFFWriter::patchDebugDirectory() {
+ S.Header.VirtualAddress + S.Header.SizeOfRawData) {
+ if (Dir->RelativeVirtualAddress + Dir->Size >
+ S.Header.VirtualAddress + S.Header.SizeOfRawData)
+- return make_error<StringError>(
+- "Debug directory extends past end of section",
+- object_error::parse_failed);
++ return createStringError(object_error::parse_failed,
++ "Debug directory extends past end of section");
+
+ size_t Offset = Dir->RelativeVirtualAddress - S.Header.VirtualAddress;
+ uint8_t *Ptr = Buf.getBufferStart() + S.Header.PointerToRawData + Offset;
+@@ -361,15 +360,15 @@ Error COFFWriter::patchDebugDirectory() {
+ return Error::success();
+ }
+ }
+- return make_error<StringError>("Debug directory not found",
+- object_error::parse_failed);
++ return createStringError(object_error::parse_failed,
++ "Debug directory not found");
+ }
+
+ Error COFFWriter::write() {
+ bool IsBigObj = Obj.getSections().size() > MaxNumberOfSections16;
+ if (IsBigObj && Obj.IsPE)
+- return make_error<StringError>("Too many sections for executable",
+- object_error::parse_failed);
++ return createStringError(object_error::parse_failed,
++ "Too many sections for executable");
+ return write(IsBigObj);
+ }
+
+diff --git a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
+index db0cd76ced4..a2996395c1f 100644
+--- a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
++++ b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
+@@ -185,9 +185,10 @@ static Error dumpSectionToFile(StringRef SecName, StringRef Filename,
+ for (auto &Sec : Obj.sections()) {
+ if (Sec.Name == SecName) {
+ if (Sec.OriginalData.empty())
+- return make_error<StringError>("Can't dump section \"" + SecName +
+- "\": it has no contents",
+- object_error::parse_failed);
++ return createStringError(
++ object_error::parse_failed,
++ "Can't dump section \"%s\": it has no contents",
++ SecName.str().c_str());
+ Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
+ FileOutputBuffer::create(Filename, Sec.OriginalData.size());
+ if (!BufferOrErr)
+@@ -200,8 +201,7 @@ static Error dumpSectionToFile(StringRef SecName, StringRef Filename,
+ return Error::success();
+ }
+ }
+- return make_error<StringError>("Section not found",
+- object_error::parse_failed);
++ return createStringError(object_error::parse_failed, "Section not found");
+ }
+
+ static bool isCompressed(const SectionBase &Section) {
+--
+2.17.1
+
diff --git a/projects/clang/win-patches/llvm-objcopy-7.patch b/projects/clang/win-patches/llvm-objcopy-7.patch
new file mode 100644
index 0000000..80e9785
--- /dev/null
+++ b/projects/clang/win-patches/llvm-objcopy-7.patch
@@ -0,0 +1,224 @@
+From d37f67c7311cd371d9ff1afd398bc92f309e6baf Mon Sep 17 00:00:00 2001
+From: Martin Storsjo <martin(a)martin.st>
+Date: Tue, 22 Jan 2019 10:58:09 +0000
+Subject: [PATCH] [llvm-objcopy] [COFF] Update symbol indices in weak externals
+
+Differential Revision: https://reviews.llvm.org/D57006
+
+git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351800 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ .../llvm-objcopy/COFF/weak-external.test | 49 +++++++++++++++++++
+ tools/llvm-objcopy/COFF/Object.h | 2 +
+ tools/llvm-objcopy/COFF/Reader.cpp | 24 ++++++++-
+ tools/llvm-objcopy/COFF/Reader.h | 2 +-
+ tools/llvm-objcopy/COFF/Writer.cpp | 16 +++++-
+ tools/llvm-objcopy/COFF/Writer.h | 2 +-
+ 6 files changed, 89 insertions(+), 6 deletions(-)
+ create mode 100644 test/tools/llvm-objcopy/COFF/weak-external.test
+
+diff --git a/llvm/test/tools/llvm-objcopy/COFF/weak-external.test b/llvm/test/tools/llvm-objcopy/COFF/weak-external.test
+new file mode 100644
+index 00000000000..d36a53b4eb1
+--- /dev/null
++++ b/llvm/test/tools/llvm-objcopy/COFF/weak-external.test
+@@ -0,0 +1,49 @@
++# RUN: yaml2obj %s > %t.in.o
++
++# RUN: llvm-objdump -t %t.in.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-PRE
++
++# RUN: llvm-objcopy -N func %t.in.o %t.out.o
++# RUN: llvm-objdump -t %t.out.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-POST
++
++# RUN: not llvm-objcopy -N .weak.foobar.file1 %t.in.o %t.err.o 2>&1 | FileCheck %s --check-prefix=ERROR
++
++# SYMBOLS: SYMBOL TABLE:
++# SYMBOLS-PRE-NEXT: func
++# SYMBOLS-NEXT: .weak.foobar.file1
++# SYMBOLS-NEXT: foobar
++# SYMBOLS-PRE-NEXT: AUX indx 1
++# SYMBOLS-POST-NEXT: AUX indx 0
++# SYMBOLS-EMPTY:
++
++# ERROR: Symbol 'foobar' is missing its weak target
++
++--- !COFF
++header:
++ Machine: IMAGE_FILE_MACHINE_AMD64
++ Characteristics: [ ]
++sections:
++ - Name: .text
++ Characteristics: [ ]
++symbols:
++ - Name: func
++ Value: 0
++ SectionNumber: 1
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_NULL
++ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
++ - Name: .weak.foobar.file1
++ Value: 1
++ SectionNumber: 1
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_NULL
++ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
++ - Name: foobar
++ Value: 0
++ SectionNumber: 0
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
++ StorageClass: IMAGE_SYM_CLASS_WEAK_EXTERNAL
++ WeakExternal:
++ TagIndex: 1
++ Characteristics: IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY
++...
+diff --git a/llvm/tools/llvm-objcopy/COFF/Object.h b/llvm/tools/llvm-objcopy/COFF/Object.h
+index 8e200369f0b..0630f9c5ff8 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Object.h
++++ b/llvm/tools/llvm-objcopy/COFF/Object.h
+@@ -11,6 +11,7 @@
+
+ #include "llvm/ADT/ArrayRef.h"
+ #include "llvm/ADT/DenseMap.h"
++#include "llvm/ADT/Optional.h"
+ #include "llvm/ADT/StringRef.h"
+ #include "llvm/ADT/iterator_range.h"
+ #include "llvm/BinaryFormat/COFF.h"
+@@ -47,6 +48,7 @@ struct Symbol {
+ std::vector<uint8_t> AuxData;
+ ssize_t TargetSectionId;
+ ssize_t AssociativeComdatTargetSectionId = 0;
++ Optional<size_t> WeakTargetSymbolId;
+ size_t UniqueId;
+ size_t RawIndex;
+ bool Referenced;
+diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.cpp b/llvm/tools/llvm-objcopy/COFF/Reader.cpp
+index 20ff32a59dc..2446277cc2b 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Reader.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Reader.cpp
+@@ -121,12 +121,18 @@ Error COFFReader::readSymbols(Object &Obj, bool IsBigObj) const {
+ // For section definitions, check if it is comdat associative, and if
+ // it is, find the target section unique id.
+ const coff_aux_section_definition *SD = SymRef.getSectionDefinition();
++ const coff_aux_weak_external *WE = SymRef.getWeakExternal();
+ if (SD && SD->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
+ int32_t Index = SD->getNumber(IsBigObj);
+ if (Index <= 0 || static_cast<uint32_t>(Index - 1) >= Sections.size())
+ return createStringError(object_error::parse_failed,
+ "Unexpected associative section index");
+ Sym.AssociativeComdatTargetSectionId = Sections[Index - 1].UniqueId;
++ } else if (WE) {
++ // This is a raw symbol index for now, but store it in the Symbol
++ // until we've added them to the Object, which assigns the final
++ // unique ids.
++ Sym.WeakTargetSymbolId = WE->TagIndex;
+ }
+ I += 1 + SymRef.getNumberOfAuxSymbols();
+ }
+@@ -134,13 +140,27 @@ Error COFFReader::readSymbols(Object &Obj, bool IsBigObj) const {
+ return Error::success();
+ }
+
+-Error COFFReader::setRelocTargets(Object &Obj) const {
++Error COFFReader::setSymbolTargets(Object &Obj) const {
+ std::vector<const Symbol *> RawSymbolTable;
+ for (const Symbol &Sym : Obj.getSymbols()) {
+ RawSymbolTable.push_back(&Sym);
+ for (size_t I = 0; I < Sym.Sym.NumberOfAuxSymbols; I++)
+ RawSymbolTable.push_back(nullptr);
+ }
++ for (Symbol &Sym : Obj.getMutableSymbols()) {
++ // Convert WeakTargetSymbolId from the original raw symbol index to
++ // a proper unique id.
++ if (Sym.WeakTargetSymbolId) {
++ if (*Sym.WeakTargetSymbolId >= RawSymbolTable.size())
++ return createStringError(object_error::parse_failed,
++ "Weak external reference out of range");
++ const Symbol *Target = RawSymbolTable[*Sym.WeakTargetSymbolId];
++ if (Target == nullptr)
++ return createStringError(object_error::parse_failed,
++ "Invalid SymbolTableIndex");
++ Sym.WeakTargetSymbolId = Target->UniqueId;
++ }
++ }
+ for (Section &Sec : Obj.getMutableSections()) {
+ for (Relocation &R : Sec.Relocs) {
+ if (R.Reloc.SymbolTableIndex >= RawSymbolTable.size())
+@@ -184,7 +204,7 @@ Expected<std::unique_ptr<Object>> COFFReader::create() const {
+ return std::move(E);
+ if (Error E = readSymbols(*Obj, IsBigObj))
+ return std::move(E);
+- if (Error E = setRelocTargets(*Obj))
++ if (Error E = setSymbolTargets(*Obj))
+ return std::move(E);
+
+ return std::move(Obj);
+diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.h b/llvm/tools/llvm-objcopy/COFF/Reader.h
+index 4493705e73c..ec15369db0b 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Reader.h
++++ b/llvm/tools/llvm-objcopy/COFF/Reader.h
+@@ -28,7 +28,7 @@ class COFFReader {
+ Error readExecutableHeaders(Object &Obj) const;
+ Error readSections(Object &Obj) const;
+ Error readSymbols(Object &Obj, bool IsBigObj) const;
+- Error setRelocTargets(Object &Obj) const;
++ Error setSymbolTargets(Object &Obj) const;
+
+ public:
+ explicit COFFReader(const COFFObjectFile &O) : COFFObj(O) {}
+diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.cpp b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
+index 0321f94a896..4f57131d5ab 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Writer.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
+@@ -38,7 +38,7 @@ Error COFFWriter::finalizeRelocTargets() {
+ return Error::success();
+ }
+
+-Error COFFWriter::finalizeSectionNumbers() {
++Error COFFWriter::finalizeSymbolContents() {
+ for (Symbol &Sym : Obj.getMutableSymbols()) {
+ if (Sym.TargetSectionId <= 0) {
+ // Undefined, or a special kind of symbol. These negative values
+@@ -75,6 +75,18 @@ Error COFFWriter::finalizeSectionNumbers() {
+ SD->NumberHighPart = static_cast<uint16_t>(SDSectionNumber >> 16);
+ }
+ }
++ // Check that we actually have got AuxData to match the weak symbol target
++ // we want to set. Only >= 1 would be required, but only == 1 makes sense.
++ if (Sym.WeakTargetSymbolId && Sym.Sym.NumberOfAuxSymbols == 1) {
++ coff_aux_weak_external *WE =
++ reinterpret_cast<coff_aux_weak_external *>(Sym.AuxData.data());
++ const Symbol *Target = Obj.findSymbol(*Sym.WeakTargetSymbolId);
++ if (Target == nullptr)
++ return createStringError(object_error::invalid_symbol_index,
++ "Symbol '%s' is missing its weak target",
++ Sym.Name.str().c_str());
++ WE->TagIndex = Target->RawIndex;
++ }
+ }
+ return Error::success();
+ }
+@@ -137,7 +149,7 @@ std::pair<size_t, size_t> COFFWriter::finalizeSymbolTable() {
+ Error COFFWriter::finalize(bool IsBigObj) {
+ if (Error E = finalizeRelocTargets())
+ return E;
+- if (Error E = finalizeSectionNumbers())
++ if (Error E = finalizeSymbolContents())
+ return E;
+
+ size_t SizeOfHeaders = 0;
+diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.h b/llvm/tools/llvm-objcopy/COFF/Writer.h
+index a967a103df9..9b1cfa91d00 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Writer.h
++++ b/llvm/tools/llvm-objcopy/COFF/Writer.h
+@@ -31,7 +31,7 @@ class COFFWriter {
+ StringTableBuilder StrTabBuilder;
+
+ Error finalizeRelocTargets();
+- Error finalizeSectionNumbers();
++ Error finalizeSymbolContents();
+ void layoutSections();
+ size_t finalizeStringTable();
+ template <class SymbolTy> std::pair<size_t, size_t> finalizeSymbolTable();
+--
+2.17.1
+
diff --git a/projects/clang/win-patches/llvm-objcopy-8.patch b/projects/clang/win-patches/llvm-objcopy-8.patch
new file mode 100644
index 0000000..6fd9776
--- /dev/null
+++ b/projects/clang/win-patches/llvm-objcopy-8.patch
@@ -0,0 +1,330 @@
+From 8cf7aa39d7c9461e2d765f6d4fa7e0925571695f Mon Sep 17 00:00:00 2001
+From: Jordan Rupprecht <rupprecht(a)google.com>
+Date: Tue, 22 Jan 2019 23:49:16 +0000
+Subject: [PATCH] [llvm-objcopy] Return Error from Buffer::allocate(),
+ [ELF]Writer::finalize(), and [ELF]Writer::commit()
+
+Summary:
+This patch changes a few methods to return Error instead of manually calling error/reportError to abort. This will make it easier to extract into a library.
+
+Note that error() takes just a string (this patch also adds an overload that takes an Error), while reportError() takes string + [error/code]. To help unify things, use FileError to associate a given filename with an error. Note that this takes some special care (for now), e.g. calling reportError(FileName, <something that could be FileError>) will duplicate the filename. The goal is to eventually remove reportError() and have every error associated with a file to be a FileError, and just one error handling block at the tool level.
+
+This change was suggested in D56806. I took it a little further than suggested, but completely fixing llvm-objcopy will take a couple more patches. If this approach looks good, I'll commit this and apply similar patche(s) for the rest.
+
+This change is NFC in terms of non-error related code, although the error message changes in one context.
+
+Reviewers: alexshap, jhenderson, jakehehrlich, mstorsjo, espindola
+
+Reviewed By: alexshap, jhenderson
+
+Subscribers: llvm-commits, emaste, arichardson
+
+Differential Revision: https://reviews.llvm.org/D56930
+
+git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351896 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ .../ELF/fail-no-output-directory.test | 2 +-
+ tools/llvm-objcopy/Buffer.cpp | 20 ++++++++++++-----
+ tools/llvm-objcopy/Buffer.h | 6 ++---
+ tools/llvm-objcopy/COFF/Writer.cpp | 3 ++-
+ tools/llvm-objcopy/ELF/ELFObjcopy.cpp | 18 ++++++++++-----
+ tools/llvm-objcopy/ELF/Object.cpp | 22 ++++++++++---------
+ tools/llvm-objcopy/ELF/Object.h | 12 +++++-----
+ tools/llvm-objcopy/llvm-objcopy.cpp | 15 +++++++++++--
+ tools/llvm-objcopy/llvm-objcopy.h | 1 +
+ 9 files changed, 64 insertions(+), 35 deletions(-)
+
+diff --git a/llvm/test/tools/llvm-objcopy/ELF/fail-no-output-directory.test b/llvm/test/tools/llvm-objcopy/ELF/fail-no-output-directory.test
+index f66b2e09fce..732046fa925 100644
+--- a/llvm/test/tools/llvm-objcopy/ELF/fail-no-output-directory.test
++++ b/llvm/test/tools/llvm-objcopy/ELF/fail-no-output-directory.test
+@@ -1,6 +1,6 @@
+ # RUN: yaml2obj %s > %t
+ # RUN: not llvm-objcopy %t no/such/dir 2>&1 | FileCheck %s
+-# CHECK: failed to open no/such/dir:
++# CHECK: error: 'no/such/dir': No such file or directory
+
+ !ELF
+ FileHeader:
+diff --git a/llvm/tools/llvm-objcopy/Buffer.cpp b/llvm/tools/llvm-objcopy/Buffer.cpp
+index 2da03dee1af..1789097f276 100644
+--- a/llvm/tools/llvm-objcopy/Buffer.cpp
++++ b/llvm/tools/llvm-objcopy/Buffer.cpp
+@@ -17,23 +17,31 @@ namespace objcopy {
+
+ Buffer::~Buffer() {}
+
+-void FileBuffer::allocate(size_t Size) {
++Error FileBuffer::allocate(size_t Size) {
+ Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
+ FileOutputBuffer::create(getName(), Size, FileOutputBuffer::F_executable);
+- handleAllErrors(BufferOrErr.takeError(), [this](const ErrorInfoBase &E) {
+- error("failed to open " + getName() + ": " + E.message());
+- });
++ // FileOutputBuffer::create() returns an Error that is just a wrapper around
++ // std::error_code. Wrap it in FileError to include the actual filename.
++ if (!BufferOrErr)
++ return createFileError(getName(), BufferOrErr.takeError());
+ Buf = std::move(*BufferOrErr);
++ return Error::success();
+ }
+
+-Error FileBuffer::commit() { return Buf->commit(); }
++Error FileBuffer::commit() {
++ Error Err = Buf->commit();
++ // FileOutputBuffer::commit() returns an Error that is just a wrapper around
++ // std::error_code. Wrap it in FileError to include the actual filename.
++ return Err ? createFileError(getName(), std::move(Err)) : std::move(Err);
++}
+
+ uint8_t *FileBuffer::getBufferStart() {
+ return reinterpret_cast<uint8_t *>(Buf->getBufferStart());
+ }
+
+-void MemBuffer::allocate(size_t Size) {
++Error MemBuffer::allocate(size_t Size) {
+ Buf = WritableMemoryBuffer::getNewMemBuffer(Size, getName());
++ return Error::success();
+ }
+
+ Error MemBuffer::commit() { return Error::success(); }
+diff --git a/llvm/tools/llvm-objcopy/Buffer.h b/llvm/tools/llvm-objcopy/Buffer.h
+index 482777fe05c..40670accac2 100644
+--- a/llvm/tools/llvm-objcopy/Buffer.h
++++ b/llvm/tools/llvm-objcopy/Buffer.h
+@@ -27,7 +27,7 @@ class Buffer {
+
+ public:
+ virtual ~Buffer();
+- virtual void allocate(size_t Size) = 0;
++ virtual Error allocate(size_t Size) = 0;
+ virtual uint8_t *getBufferStart() = 0;
+ virtual Error commit() = 0;
+
+@@ -39,7 +39,7 @@ class FileBuffer : public Buffer {
+ std::unique_ptr<FileOutputBuffer> Buf;
+
+ public:
+- void allocate(size_t Size) override;
++ Error allocate(size_t Size) override;
+ uint8_t *getBufferStart() override;
+ Error commit() override;
+
+@@ -50,7 +50,7 @@ class MemBuffer : public Buffer {
+ std::unique_ptr<WritableMemoryBuffer> Buf;
+
+ public:
+- void allocate(size_t Size) override;
++ Error allocate(size_t Size) override;
+ uint8_t *getBufferStart() override;
+ Error commit() override;
+
+diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.cpp b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
+index 4f57131d5ab..db3589bb119 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Writer.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
+@@ -324,7 +324,8 @@ Error COFFWriter::write(bool IsBigObj) {
+ if (Error E = finalize(IsBigObj))
+ return E;
+
+- Buf.allocate(FileSize);
++ if (Error E = Buf.allocate(FileSize))
++ return E;
+
+ writeHeaders(IsBigObj);
+ writeSections();
+diff --git a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
+index a2996395c1f..2a52f1f9951 100644
+--- a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
++++ b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
+@@ -176,8 +176,10 @@ static void splitDWOToFile(const CopyConfig &Config, const Reader &Reader,
+ DWOFile->Machine = Config.OutputArch.getValue().EMachine;
+ FileBuffer FB(File);
+ auto Writer = createWriter(Config, *DWOFile, FB, OutputElfType);
+- Writer->finalize();
+- Writer->write();
++ if (Error E = Writer->finalize())
++ error(std::move(E));
++ if (Error E = Writer->write())
++ error(std::move(E));
+ }
+
+ static Error dumpSectionToFile(StringRef SecName, StringRef Filename,
+@@ -542,8 +544,10 @@ void executeObjcopyOnRawBinary(const CopyConfig &Config, MemoryBuffer &In,
+ handleArgs(Config, *Obj, Reader, OutputElfType);
+ std::unique_ptr<Writer> Writer =
+ createWriter(Config, *Obj, Out, OutputElfType);
+- Writer->finalize();
+- Writer->write();
++ if (Error E = Writer->finalize())
++ error(std::move(E));
++ if (Error E = Writer->write())
++ error(std::move(E));
+ }
+
+ void executeObjcopyOnBinary(const CopyConfig &Config,
+@@ -570,8 +574,10 @@ void executeObjcopyOnBinary(const CopyConfig &Config,
+ handleArgs(Config, *Obj, Reader, OutputElfType);
+ std::unique_ptr<Writer> Writer =
+ createWriter(Config, *Obj, Out, OutputElfType);
+- Writer->finalize();
+- Writer->write();
++ if (Error E = Writer->finalize())
++ error(std::move(E));
++ if (Error E = Writer->write())
++ error(std::move(E));
+ if (!Config.BuildIdLinkDir.empty() && Config.BuildIdLinkOutput) {
+ linkToBuildIdDir(Config, Config.OutputFilename,
+ Config.BuildIdLinkOutput.getValue(), BuildIdBytes);
+diff --git a/llvm/tools/llvm-objcopy/ELF/Object.cpp b/llvm/tools/llvm-objcopy/ELF/Object.cpp
+index fecb752a39f..ef5dc5d7951 100644
+--- a/llvm/tools/llvm-objcopy/ELF/Object.cpp
++++ b/llvm/tools/llvm-objcopy/ELF/Object.cpp
+@@ -1488,17 +1488,16 @@ template <class ELFT> size_t ELFWriter<ELFT>::totalSize() const {
+ NullSectionSize;
+ }
+
+-template <class ELFT> void ELFWriter<ELFT>::write() {
++template <class ELFT> Error ELFWriter<ELFT>::write() {
+ writeEhdr();
+ writePhdrs();
+ writeSectionData();
+ if (WriteSectionHeaders)
+ writeShdrs();
+- if (auto E = Buf.commit())
+- reportError(Buf.getName(), errorToErrorCode(std::move(E)));
++ return Buf.commit();
+ }
+
+-template <class ELFT> void ELFWriter<ELFT>::finalize() {
++template <class ELFT> Error ELFWriter<ELFT>::finalize() {
+ // It could happen that SectionNames has been removed and yet the user wants
+ // a section header table output. We need to throw an error if a user tries
+ // to do that.
+@@ -1582,21 +1581,22 @@ template <class ELFT> void ELFWriter<ELFT>::finalize() {
+ Section.finalize();
+ }
+
+- Buf.allocate(totalSize());
++ if (Error E = Buf.allocate(totalSize()))
++ return E;
+ SecWriter = llvm::make_unique<ELFSectionWriter<ELFT>>(Buf);
++ return Error::success();
+ }
+
+-void BinaryWriter::write() {
++Error BinaryWriter::write() {
+ for (auto &Section : Obj.sections()) {
+ if ((Section.Flags & SHF_ALLOC) == 0)
+ continue;
+ Section.accept(*SecWriter);
+ }
+- if (auto E = Buf.commit())
+- reportError(Buf.getName(), errorToErrorCode(std::move(E)));
++ return Buf.commit();
+ }
+
+-void BinaryWriter::finalize() {
++Error BinaryWriter::finalize() {
+ // TODO: Create a filter range to construct OrderedSegments from so that this
+ // code can be deduped with assignOffsets above. This should also solve the
+ // todo below for LayoutSections.
+@@ -1675,8 +1675,10 @@ void BinaryWriter::finalize() {
+ TotalSize = std::max(TotalSize, Section->Offset + Section->Size);
+ }
+
+- Buf.allocate(TotalSize);
++ if (Error E = Buf.allocate(TotalSize))
++ return E;
+ SecWriter = llvm::make_unique<BinarySectionWriter>(Buf);
++ return Error::success();
+ }
+
+ template class ELFBuilder<ELF64LE>;
+diff --git a/llvm/tools/llvm-objcopy/ELF/Object.h b/llvm/tools/llvm-objcopy/ELF/Object.h
+index 0dcb0d888bc..9e2b64be9dc 100644
+--- a/llvm/tools/llvm-objcopy/ELF/Object.h
++++ b/llvm/tools/llvm-objcopy/ELF/Object.h
+@@ -193,8 +193,8 @@ protected:
+
+ public:
+ virtual ~Writer();
+- virtual void finalize() = 0;
+- virtual void write() = 0;
++ virtual Error finalize() = 0;
++ virtual Error write() = 0;
+
+ Writer(Object &O, Buffer &B) : Obj(O), Buf(B) {}
+ };
+@@ -226,8 +226,8 @@ public:
+ virtual ~ELFWriter() {}
+ bool WriteSectionHeaders = true;
+
+- void finalize() override;
+- void write() override;
++ Error finalize() override;
++ Error write() override;
+ ELFWriter(Object &Obj, Buffer &Buf, bool WSH)
+ : Writer(Obj, Buf), WriteSectionHeaders(WSH) {}
+ };
+@@ -240,8 +240,8 @@ private:
+
+ public:
+ ~BinaryWriter() {}
+- void finalize() override;
+- void write() override;
++ Error finalize() override;
++ Error write() override;
+ BinaryWriter(Object &Obj, Buffer &Buf) : Writer(Obj, Buf) {}
+ };
+
+diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
+index d27395f2ae0..75d513546b7 100644
+--- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
++++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
+@@ -56,6 +56,16 @@ LLVM_ATTRIBUTE_NORETURN void error(Twine Message) {
+ exit(1);
+ }
+
++LLVM_ATTRIBUTE_NORETURN void error(Error E) {
++ assert(E);
++ std::string Buf;
++ raw_string_ostream OS(Buf);
++ logAllUnhandledErrors(std::move(E), OS);
++ OS.flush();
++ WithColor::error(errs(), ToolName) << Buf;
++ exit(1);
++}
++
+ LLVM_ATTRIBUTE_NORETURN void reportError(StringRef File, std::error_code EC) {
+ assert(EC);
+ WithColor::error(errs(), ToolName)
+@@ -100,10 +110,11 @@ static Error deepWriteArchive(StringRef ArcName,
+ // NewArchiveMember still requires them even though writeArchive does not
+ // write them on disk.
+ FileBuffer FB(Member.MemberName);
+- FB.allocate(Member.Buf->getBufferSize());
++ if (Error E = FB.allocate(Member.Buf->getBufferSize()))
++ return E;
+ std::copy(Member.Buf->getBufferStart(), Member.Buf->getBufferEnd(),
+ FB.getBufferStart());
+- if (auto E = FB.commit())
++ if (Error E = FB.commit())
+ return E;
+ }
+ return Error::success();
+diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.h b/llvm/tools/llvm-objcopy/llvm-objcopy.h
+index 46d8339576c..18a789ca1f8 100644
+--- a/llvm/tools/llvm-objcopy/llvm-objcopy.h
++++ b/llvm/tools/llvm-objcopy/llvm-objcopy.h
+@@ -19,6 +19,7 @@ namespace llvm {
+ namespace objcopy {
+
+ LLVM_ATTRIBUTE_NORETURN extern void error(Twine Message);
++LLVM_ATTRIBUTE_NORETURN extern void error(Error E);
+ LLVM_ATTRIBUTE_NORETURN extern void reportError(StringRef File, Error E);
+ LLVM_ATTRIBUTE_NORETURN extern void reportError(StringRef File,
+ std::error_code EC);
+--
+2.17.1
+
diff --git a/projects/clang/win-patches/llvm-objcopy-9.patch b/projects/clang/win-patches/llvm-objcopy-9.patch
new file mode 100644
index 0000000..6cb4656
--- /dev/null
+++ b/projects/clang/win-patches/llvm-objcopy-9.patch
@@ -0,0 +1,260 @@
+From 840d70f854a1d550924ced1d00160efcc7b8549a Mon Sep 17 00:00:00 2001
+From: Martin Storsjo <martin(a)martin.st>
+Date: Wed, 23 Jan 2019 08:25:28 +0000
+Subject: [PATCH] Reapply: [llvm-objcopy] [COFF] Implement --add-gnu-debuglink
+
+This was reverted since it broke a couple buildbots. The reason
+for the breakage is not yet known, but this time, the test has
+got more diagnostics added, to hopefully allow figuring out
+what goes wrong.
+
+Differential Revision: https://reviews.llvm.org/D57007
+
+git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351931 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ .../llvm-objcopy/COFF/add-gnu-debuglink.test | 48 +++++++++++++++
+ tools/llvm-objcopy/COFF/COFFObjcopy.cpp | 61 +++++++++++++++++++
+ tools/llvm-objcopy/COFF/Object.cpp | 2 +-
+ tools/llvm-objcopy/COFF/Object.h | 26 +++++++-
+ tools/llvm-objcopy/COFF/Reader.cpp | 4 +-
+ tools/llvm-objcopy/COFF/Writer.cpp | 9 +--
+ 6 files changed, 143 insertions(+), 7 deletions(-)
+ create mode 100644 test/tools/llvm-objcopy/COFF/add-gnu-debuglink.test
+
+diff --git a/llvm/test/tools/llvm-objcopy/COFF/add-gnu-debuglink.test b/llvm/test/tools/llvm-objcopy/COFF/add-gnu-debuglink.test
+new file mode 100644
+index 00000000000..cf3a9bba920
+--- /dev/null
++++ b/llvm/test/tools/llvm-objcopy/COFF/add-gnu-debuglink.test
+@@ -0,0 +1,48 @@
++RUN: yaml2obj %p/Inputs/x86_64-exe.yaml > %t.in123.exe
++
++# Using a debuglink filename with a length that is a multiple of 4, to
++# showcase padding in CONTENTS below.
++
++RUN: llvm-objcopy --add-gnu-debuglink=%t.in123.exe %t.in123.exe %t.out.exe
++
++# Temporary debugging of issues with this test:
++RUN: ls -l %t.out.exe || true
++RUN: od -Ax -t x1 %t.out.exe || true
++RUN: llvm-readobj -sections %t.out.exe || true
++
++RUN: llvm-readobj -sections %t.out.exe | FileCheck %s --check-prefix=SECTIONS
++RUN: llvm-objdump -s %t.out.exe | FileCheck %s --check-prefix=CONTENTS
++
++# Show the last of the preexisting sections, which is used for choosing
++# a virtual address for the generated one.
++
++SECTIONS: Section {
++SECTIONS: Number: 4
++SECTIONS-NEXT: Name: .pdata
++SECTIONS-NEXT: VirtualSize: 0x18
++SECTIONS-NEXT: VirtualAddress: 0x4000
++SECTIONS-NEXT: RawDataSize: 512
++SECTIONS: Section {
++SECTIONS-NEXT: Number: 5
++SECTIONS-NEXT: Name: .gnu_debuglink
++SECTIONS-NEXT: VirtualSize: 0x2C
++SECTIONS-NEXT: VirtualAddress: 0x5000
++SECTIONS-NEXT: RawDataSize: 512
++SECTIONS-NEXT: PointerToRawData:
++SECTIONS-NEXT: PointerToRelocations:
++SECTIONS-NEXT: PointerToLineNumbers:
++SECTIONS-NEXT: RelocationCount:
++SECTIONS-NEXT: LineNumberCount:
++SECTIONS-NEXT: Characteristics [ (0x42000040)
++SECTIONS-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
++SECTIONS-NEXT: IMAGE_SCN_MEM_DISCARDABLE (0x2000000)
++SECTIONS-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
++SECTIONS-NEXT: ]
++
++# Note: The last 4 bytes here are the crc of the referenced file - if the
++# yaml2obj generated file changes, this crc changes.
++
++CONTENTS: Contents of section .gnu_debuglink:
++CONTENTS: 40005000 6164642d 676e752d 64656275 676c696e add-gnu-debuglin
++CONTENTS: 40005010 6b2e7465 73742e74 6d702e69 6e313233 k.test.tmp.in123
++CONTENTS: 40005020 2e657865 00000000 7929adc3 .exe
+diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+index 8d8f53d13d8..20adbe11e7a 100644
+--- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+@@ -17,6 +17,8 @@
+ #include "llvm/Object/Binary.h"
+ #include "llvm/Object/COFF.h"
+ #include "llvm/Support/Errc.h"
++#include "llvm/Support/JamCRC.h"
++#include "llvm/Support/Path.h"
+ #include <cassert>
+
+ namespace llvm {
+@@ -30,6 +32,61 @@ static bool isDebugSection(const Section &Sec) {
+ return Sec.Name.startswith(".debug");
+ }
+
++static uint64_t getNextRVA(const Object &Obj) {
++ if (Obj.getSections().empty())
++ return 0;
++ const Section &Last = Obj.getSections().back();
++ return alignTo(Last.Header.VirtualAddress + Last.Header.VirtualSize,
++ Obj.PeHeader.SectionAlignment);
++}
++
++static uint32_t getCRC32(StringRef Data) {
++ JamCRC CRC;
++ CRC.update(ArrayRef<char>(Data.data(), Data.size()));
++ // The CRC32 value needs to be complemented because the JamCRC dosn't
++ // finalize the CRC32 value. It also dosn't negate the initial CRC32 value
++ // but it starts by default at 0xFFFFFFFF which is the complement of zero.
++ return ~CRC.getCRC();
++}
++
++static std::vector<uint8_t> createGnuDebugLinkSectionContents(StringRef File) {
++ ErrorOr<std::unique_ptr<MemoryBuffer>> LinkTargetOrErr =
++ MemoryBuffer::getFile(File);
++ if (!LinkTargetOrErr)
++ error("'" + File + "': " + LinkTargetOrErr.getError().message());
++ auto LinkTarget = std::move(*LinkTargetOrErr);
++ uint32_t CRC32 = getCRC32(LinkTarget->getBuffer());
++
++ StringRef FileName = sys::path::filename(File);
++ size_t CRCPos = alignTo(FileName.size() + 1, 4);
++ std::vector<uint8_t> Data(CRCPos + 4);
++ memcpy(Data.data(), FileName.data(), FileName.size());
++ support::endian::write32le(Data.data() + CRCPos, CRC32);
++ return Data;
++}
++
++static void addGnuDebugLink(Object &Obj, StringRef DebugLinkFile) {
++ uint32_t StartRVA = getNextRVA(Obj);
++
++ std::vector<Section> Sections;
++ Section Sec;
++ Sec.setOwnedContents(createGnuDebugLinkSectionContents(DebugLinkFile));
++ Sec.Name = ".gnu_debuglink";
++ Sec.Header.VirtualSize = Sec.getContents().size();
++ Sec.Header.VirtualAddress = StartRVA;
++ Sec.Header.SizeOfRawData =
++ alignTo(Sec.Header.VirtualSize, Obj.PeHeader.FileAlignment);
++ // Sec.Header.PointerToRawData is filled in by the writer.
++ Sec.Header.PointerToRelocations = 0;
++ Sec.Header.PointerToLinenumbers = 0;
++ // Sec.Header.NumberOfRelocations is filled in by the writer.
++ Sec.Header.NumberOfLinenumbers = 0;
++ Sec.Header.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA |
++ IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE;
++ Sections.push_back(Sec);
++ Obj.addSections(Sections);
++}
++
+ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
+ // Perform the actual section removals.
+ Obj.removeSections([&Config](const Section &Sec) {
+@@ -109,6 +166,10 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
+
+ return false;
+ });
++
++ if (!Config.AddGnuDebugLink.empty())
++ addGnuDebugLink(Obj, Config.AddGnuDebugLink);
++
+ return Error::success();
+ }
+
+diff --git a/llvm/tools/llvm-objcopy/COFF/Object.cpp b/llvm/tools/llvm-objcopy/COFF/Object.cpp
+index 83435dffa98..8c382c1faef 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Object.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Object.cpp
+@@ -129,7 +129,7 @@ void Object::removeSections(function_ref<bool(const Section &)> ToRemove) {
+ void Object::truncateSections(function_ref<bool(const Section &)> ToTruncate) {
+ for (Section &Sec : Sections) {
+ if (ToTruncate(Sec)) {
+- Sec.Contents = ArrayRef<uint8_t>();
++ Sec.clearContents();
+ Sec.Relocs.clear();
+ Sec.Header.SizeOfRawData = 0;
+ }
+diff --git a/llvm/tools/llvm-objcopy/COFF/Object.h b/llvm/tools/llvm-objcopy/COFF/Object.h
+index 0630f9c5ff8..afa272286ef 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Object.h
++++ b/llvm/tools/llvm-objcopy/COFF/Object.h
+@@ -35,11 +35,35 @@ struct Relocation {
+
+ struct Section {
+ object::coff_section Header;
+- ArrayRef<uint8_t> Contents;
+ std::vector<Relocation> Relocs;
+ StringRef Name;
+ ssize_t UniqueId;
+ size_t Index;
++
++ ArrayRef<uint8_t> getContents() const {
++ if (!OwnedContents.empty())
++ return OwnedContents;
++ return ContentsRef;
++ }
++
++ void setContentsRef(ArrayRef<uint8_t> Data) {
++ OwnedContents.clear();
++ ContentsRef = Data;
++ }
++
++ void setOwnedContents(std::vector<uint8_t> &&Data) {
++ ContentsRef = ArrayRef<uint8_t>();
++ OwnedContents = std::move(Data);
++ }
++
++ void clearContents() {
++ ContentsRef = ArrayRef<uint8_t>();
++ OwnedContents.clear();
++ }
++
++private:
++ ArrayRef<uint8_t> ContentsRef;
++ std::vector<uint8_t> OwnedContents;
+ };
+
+ struct Symbol {
+diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.cpp b/llvm/tools/llvm-objcopy/COFF/Reader.cpp
+index 2446277cc2b..87dd60a43cf 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Reader.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Reader.cpp
+@@ -69,8 +69,10 @@ Error COFFReader::readSections(Object &Obj) const {
+ Sections.push_back(Section());
+ Section &S = Sections.back();
+ S.Header = *Sec;
+- if (auto EC = COFFObj.getSectionContents(Sec, S.Contents))
++ ArrayRef<uint8_t> Contents;
++ if (auto EC = COFFObj.getSectionContents(Sec, Contents))
+ return errorCodeToError(EC);
++ S.setContentsRef(Contents);
+ ArrayRef<coff_relocation> Relocs = COFFObj.getRelocations(Sec);
+ for (const coff_relocation &R : Relocs)
+ S.Relocs.push_back(R);
+diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.cpp b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
+index db3589bb119..05e46291c39 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Writer.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
+@@ -286,14 +286,15 @@ void COFFWriter::writeHeaders(bool IsBigObj) {
+ void COFFWriter::writeSections() {
+ for (const auto &S : Obj.getSections()) {
+ uint8_t *Ptr = Buf.getBufferStart() + S.Header.PointerToRawData;
+- std::copy(S.Contents.begin(), S.Contents.end(), Ptr);
++ ArrayRef<uint8_t> Contents = S.getContents();
++ std::copy(Contents.begin(), Contents.end(), Ptr);
+
+ // For executable sections, pad the remainder of the raw data size with
+ // 0xcc, which is int3 on x86.
+ if ((S.Header.Characteristics & IMAGE_SCN_CNT_CODE) &&
+- S.Header.SizeOfRawData > S.Contents.size())
+- memset(Ptr + S.Contents.size(), 0xcc,
+- S.Header.SizeOfRawData - S.Contents.size());
++ S.Header.SizeOfRawData > Contents.size())
++ memset(Ptr + Contents.size(), 0xcc,
++ S.Header.SizeOfRawData - Contents.size());
+
+ Ptr += S.Header.SizeOfRawData;
+ for (const auto &R : S.Relocs) {
+--
+2.17.1
+
1
0
commit 525e93a130757ab4df445888ecc211bace1122eb
Author: Georg Koppen <gk(a)torproject.org>
Date: Tue Jul 30 20:38:50 2019 +0000
Release prep for 9.0a5
We want to better test aarch64 support on Google Play before the 64bit
requirement on Aug 1 is getting enforced.
---
projects/firefox/config | 2 +-
projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt | 4 ++++
rbm.conf | 4 ++--
3 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/projects/firefox/config b/projects/firefox/config
index 9565b8e..0b340f5 100644
--- a/projects/firefox/config
+++ b/projects/firefox/config
@@ -1,7 +1,7 @@
# vim: filetype=yaml sw=2
version: '[% c("abbrev") %]'
filename: 'firefox-[% c("version") %]-[% c("var/osname") %]-[% c("var/build_id") %]'
-git_hash: 'tor-browser-[% c("var/firefox_version") %]-[% c("var/torbrowser_branch") %]-1-build1'
+git_hash: 'tor-browser-[% c("var/firefox_version") %]-[% c("var/torbrowser_branch") %]-1-build2'
tag_gpg_id: 1
git_url: https://git.torproject.org/tor-browser.git
git_submodule: 1
diff --git a/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt b/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
index ffab828..594225a 100644
--- a/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
+++ b/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
@@ -1,3 +1,7 @@
+Tor Browser 9.0a5 -- July 31 2019
+ * Android
+ * Bug 31260: Backport bug 1477259 for aarch64 support on Google Play
+
Tor Browser 9.0a4 -- July 9 2019
* All platforms
* Update Firefox to 60.8.0esr
diff --git a/rbm.conf b/rbm.conf
index 4f6e943..76695f3 100644
--- a/rbm.conf
+++ b/rbm.conf
@@ -24,8 +24,8 @@ buildconf:
git_signtag_opt: '-s'
var:
- torbrowser_version: '9.0a4'
- torbrowser_build: 'build2'
+ torbrowser_version: '9.0a5'
+ torbrowser_build: 'build1'
torbrowser_incremental_from:
- 9.0a3
project_name: tor-browser
1
0

[tor-browser/tor-browser-60.8.0esr-8.5-1] Bug 1477259 - Use separate version codes for 64-bit builds; r=nalexander
by gk@torproject.org 30 Jul '19
by gk@torproject.org 30 Jul '19
30 Jul '19
commit 3111f2ee9a389db8d4c4f025b34314f8fe42d865
Author: Jim Chen <nchen(a)mozilla.com>
Date: Thu Aug 30 21:51:18 2018 +0000
Bug 1477259 - Use separate version codes for 64-bit builds; r=nalexander
Use the unused 'p' bit in the version code to denote 64-bit builds, so
we have different version codes for 64-bit builds on aarch64 and x86-64.
Differential Revision: https://phabricator.services.mozilla.com/D4260
--HG--
extra : moz-landing-system : lando
---
python/mozbuild/mozbuild/android_version_code.py | 53 ++++++++++++------------
1 file changed, 27 insertions(+), 26 deletions(-)
diff --git a/python/mozbuild/mozbuild/android_version_code.py b/python/mozbuild/mozbuild/android_version_code.py
index 5e786b2358c0..92392d563c42 100644
--- a/python/mozbuild/mozbuild/android_version_code.py
+++ b/python/mozbuild/mozbuild/android_version_code.py
@@ -49,26 +49,24 @@ def android_version_code_v1(buildid, cpu_arch=None, min_sdk=0, max_sdk=0):
The bits labelled 'x', 'p', and 'g' are feature flags.
- The bit labelled 'x' is 1 if the build is for an x86 or ARM64 architecture,
- and 0 otherwise, which means the build is for a (32-bit) ARM architecture.
+ The bit labelled 'x' is 1 if the build is for an x86 or x86-64 architecture,
+ and 0 otherwise, which means the build is for an ARM or ARM64 architecture.
(Fennec no longer supports ARMv6, so ARM is equivalent to ARMv7.
ARM64 is also known as AArch64; it is logically ARMv8.)
- For the same release, x86 and ARM64 builds have higher version codes and
+ For the same release, x86 and x86_64 builds have higher version codes and
take precedence over ARM builds, so that they are preferred over ARM on
devices that have ARM emulation.
- The bit labelled 'p' is a placeholder that is always 0 (for now).
+ The bit labelled 'p' is 1 if the build is for a 64-bit architecture (x86-64
+ or ARM64), and 0 otherwise, which means the build is for a 32-bit
+ architecture (x86 or ARM). 64-bit builds have higher version codes so
+ they take precedence over 32-bit builds on devices that support 64-bit.
- Firefox no longer supports API 14 or earlier.
-
- This version code computation allows for a split on API levels that allowed
- us to ship builds specifically for Gingerbread (API 9-10); we preserve
- that functionality for sanity's sake, and to allow us to reintroduce a
- split in the future.
-
- At present, the bit labelled 'g' is 1 if the build is an ARM build
- targeting API 16+, which will always be the case.
+ The bit labelled 'g' is 1 if the build targets a recent API level, which
+ is currently always the case, because Firefox no longer ships releases that
+ are split by API levels. However, we may reintroduce a split in the future,
+ in which case the release that targets an older API level will
We throw an explanatory exception when we are within one calendar year of
running out of build events. This gives lots of time to update the version
@@ -113,24 +111,27 @@ def android_version_code_v1(buildid, cpu_arch=None, min_sdk=0, max_sdk=0):
# for architecture and APK splits.
version |= base << 3
- # None is interpreted as arm.
- if not cpu_arch or cpu_arch == 'armeabi-v7a':
- # 0 is interpreted as SDK 9.
- if not min_sdk or min_sdk == 9:
- pass
- # This used to compare to 11. The 16+ APK directly supersedes 11+, so
- # we reuse this check.
- elif min_sdk == 16:
- version |= 1 << 0
- else:
- raise ValueError("Don't know how to compute android:versionCode "
- "for CPU arch %s and min SDK %s" % (cpu_arch, min_sdk))
- elif cpu_arch in ['x86', 'arm64-v8a']:
+ # 'x' bit is 1 for x86/x86-64 architectures (`None` is interpreted as ARM).
+ if cpu_arch in ['x86', 'x86_64']:
version |= 1 << 2
+ elif not cpu_arch or cpu_arch in ['armeabi-v7a', 'arm64-v8a']:
+ pass
else:
raise ValueError("Don't know how to compute android:versionCode "
"for CPU arch %s" % cpu_arch)
+ # 'p' bit is 1 for 64-bit architectures.
+ if cpu_arch in ['arm64-v8a', 'x86_64']:
+ version |= 1 << 1
+ elif cpu_arch in ['armeabi-v7a', 'x86']:
+ pass
+ else:
+ raise ValueError("Don't know how to compute android:versionCode "
+ "for CPU arch %s" % cpu_arch)
+
+ # 'g' bit is currently always 1, but may depend on `min_sdk` in the future.
+ version |= 1 << 0
+
return version
def android_version_code(buildid, *args, **kwargs):
1
0

[tor-browser/tor-browser-60.8.0esr-9.0-1] Bug 1477259 - Use separate version codes for 64-bit builds; r=nalexander
by gk@torproject.org 30 Jul '19
by gk@torproject.org 30 Jul '19
30 Jul '19
commit c847e888cd2a4fb7cbddfe8fc890fe25a024faf7
Author: Jim Chen <nchen(a)mozilla.com>
Date: Thu Aug 30 21:51:18 2018 +0000
Bug 1477259 - Use separate version codes for 64-bit builds; r=nalexander
Use the unused 'p' bit in the version code to denote 64-bit builds, so
we have different version codes for 64-bit builds on aarch64 and x86-64.
Differential Revision: https://phabricator.services.mozilla.com/D4260
--HG--
extra : moz-landing-system : lando
---
python/mozbuild/mozbuild/android_version_code.py | 53 ++++++++++++------------
1 file changed, 27 insertions(+), 26 deletions(-)
diff --git a/python/mozbuild/mozbuild/android_version_code.py b/python/mozbuild/mozbuild/android_version_code.py
index 5e786b2358c0..92392d563c42 100644
--- a/python/mozbuild/mozbuild/android_version_code.py
+++ b/python/mozbuild/mozbuild/android_version_code.py
@@ -49,26 +49,24 @@ def android_version_code_v1(buildid, cpu_arch=None, min_sdk=0, max_sdk=0):
The bits labelled 'x', 'p', and 'g' are feature flags.
- The bit labelled 'x' is 1 if the build is for an x86 or ARM64 architecture,
- and 0 otherwise, which means the build is for a (32-bit) ARM architecture.
+ The bit labelled 'x' is 1 if the build is for an x86 or x86-64 architecture,
+ and 0 otherwise, which means the build is for an ARM or ARM64 architecture.
(Fennec no longer supports ARMv6, so ARM is equivalent to ARMv7.
ARM64 is also known as AArch64; it is logically ARMv8.)
- For the same release, x86 and ARM64 builds have higher version codes and
+ For the same release, x86 and x86_64 builds have higher version codes and
take precedence over ARM builds, so that they are preferred over ARM on
devices that have ARM emulation.
- The bit labelled 'p' is a placeholder that is always 0 (for now).
+ The bit labelled 'p' is 1 if the build is for a 64-bit architecture (x86-64
+ or ARM64), and 0 otherwise, which means the build is for a 32-bit
+ architecture (x86 or ARM). 64-bit builds have higher version codes so
+ they take precedence over 32-bit builds on devices that support 64-bit.
- Firefox no longer supports API 14 or earlier.
-
- This version code computation allows for a split on API levels that allowed
- us to ship builds specifically for Gingerbread (API 9-10); we preserve
- that functionality for sanity's sake, and to allow us to reintroduce a
- split in the future.
-
- At present, the bit labelled 'g' is 1 if the build is an ARM build
- targeting API 16+, which will always be the case.
+ The bit labelled 'g' is 1 if the build targets a recent API level, which
+ is currently always the case, because Firefox no longer ships releases that
+ are split by API levels. However, we may reintroduce a split in the future,
+ in which case the release that targets an older API level will
We throw an explanatory exception when we are within one calendar year of
running out of build events. This gives lots of time to update the version
@@ -113,24 +111,27 @@ def android_version_code_v1(buildid, cpu_arch=None, min_sdk=0, max_sdk=0):
# for architecture and APK splits.
version |= base << 3
- # None is interpreted as arm.
- if not cpu_arch or cpu_arch == 'armeabi-v7a':
- # 0 is interpreted as SDK 9.
- if not min_sdk or min_sdk == 9:
- pass
- # This used to compare to 11. The 16+ APK directly supersedes 11+, so
- # we reuse this check.
- elif min_sdk == 16:
- version |= 1 << 0
- else:
- raise ValueError("Don't know how to compute android:versionCode "
- "for CPU arch %s and min SDK %s" % (cpu_arch, min_sdk))
- elif cpu_arch in ['x86', 'arm64-v8a']:
+ # 'x' bit is 1 for x86/x86-64 architectures (`None` is interpreted as ARM).
+ if cpu_arch in ['x86', 'x86_64']:
version |= 1 << 2
+ elif not cpu_arch or cpu_arch in ['armeabi-v7a', 'arm64-v8a']:
+ pass
else:
raise ValueError("Don't know how to compute android:versionCode "
"for CPU arch %s" % cpu_arch)
+ # 'p' bit is 1 for 64-bit architectures.
+ if cpu_arch in ['arm64-v8a', 'x86_64']:
+ version |= 1 << 1
+ elif cpu_arch in ['armeabi-v7a', 'x86']:
+ pass
+ else:
+ raise ValueError("Don't know how to compute android:versionCode "
+ "for CPU arch %s" % cpu_arch)
+
+ # 'g' bit is currently always 1, but may depend on `min_sdk` in the future.
+ version |= 1 << 0
+
return version
def android_version_code(buildid, *args, **kwargs):
1
0
commit d249b24614605f02d76f7ceff02aba27f2ebdf6f
Author: Georg Koppen <gk(a)torproject.org>
Date: Fri Jul 19 10:00:45 2019 +0000
Fold in stable changelog
---
projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt b/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
index 63c6606..ffab828 100644
--- a/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
+++ b/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
@@ -24,6 +24,24 @@ Tor Browser 9.0a4 -- July 9 2019
* Android
* Bug 28119: Tor Browser for aarch64
+Tor Browser 8.5.4 -- July 9 2019
+ * All platforms
+ * Update Firefox to 60.8.0esr
+ * Update Torbutton to 2.1.12
+ * Bug 30577: Add Fundraising Banner
+ * Bug 31041: Stop syncing network.cookie.lifetimePolicy
+ * Translations update
+ * Update HTTPS Everywhere to 2019.6.27
+ * Bug 31055+31058: Remove four default bridges
+ * Bug 30712: Backport fix for Mozilla's bug 1552993
+ * Bug 30849: Backport fixes for Mozilla's bug 1552627 and 1549833
+ * Windows + OS X + Linux
+ * Update Tor to 0.4.0.5
+ * Update OpenSSL to 1.0.2s
+ * Bug 29045: Ensure that tor does not start up in dormant mode
+ * OS X
+ * Bug 30631: Blurry Tor Browser icon on macOS app switcher
+
Tor Browser 9.0a3 -- June 24 2019
* All platforms
* Pick up fixes for Mozilla's bug 1544386 and 1560192
1
0
commit 958c5fef2072692464417012c1cb551f1858bab4
Author: Georg Koppen <gk(a)torproject.org>
Date: Tue Jul 9 17:56:34 2019 +0000
Correct Changelog
It seems #30573 did not get solved in that alpha. Remove the entry.
---
projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt | 1 -
1 file changed, 1 deletion(-)
diff --git a/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt b/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
index 5a1a67a..63c6606 100644
--- a/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
+++ b/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
@@ -23,7 +23,6 @@ Tor Browser 9.0a4 -- July 9 2019
* Bug 30631: Blurry Tor Browser icon on macOS app switcher
* Android
* Bug 28119: Tor Browser for aarch64
- * Bug 30573: Sanitize old tabs and wait for tor before opening new tabs
Tor Browser 9.0a3 -- June 24 2019
* All platforms
1
0

08 Jul '19
commit 248aaaa5e02b5aff0b438e563b6a73692b4533f9
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Mon Jul 8 23:27:15 2019 +0200
Remove obfs3 tests
With #31055 we don't have default obfs3 bridges anymore.
---
TBBTestSuite/TestSuite/BrowserBundleTests.pm | 15 ---------------
tor-config/tor_obfs3.conf | 15 ---------------
tor-config/tor_obfs3_httpproxy.conf | 2 --
3 files changed, 32 deletions(-)
diff --git a/TBBTestSuite/TestSuite/BrowserBundleTests.pm b/TBBTestSuite/TestSuite/BrowserBundleTests.pm
index a7ad663..cf580f0 100644
--- a/TBBTestSuite/TestSuite/BrowserBundleTests.pm
+++ b/TBBTestSuite/TestSuite/BrowserBundleTests.pm
@@ -219,21 +219,6 @@ our @tests = (
run_once => 1,
},
{
- name => 'tor_obfs3',
- type => 'tor_bootstrap',
- descr => 'Access tor using obfs3',
- enable => sub { $OSNAME eq 'linux' && $options->{PTtests} },
- run_once => 1,
- },
- {
- name => 'tor_obfs3_httpproxy',
- type => 'tor_bootstrap',
- descr => 'Access tor using obfs3 and an http proxy',
- httpproxy => 1,
- enable => sub { $OSNAME eq 'linux' && $options->{PTtests} },
- run_once => 1,
- },
- {
name => 'tor_obfs4',
type => 'tor_bootstrap',
descr => 'Access tor using obfs4',
diff --git a/tor-config/tor_obfs3.conf b/tor-config/tor_obfs3.conf
deleted file mode 100644
index 42b9b14..0000000
--- a/tor-config/tor_obfs3.conf
+++ /dev/null
@@ -1,15 +0,0 @@
-[% INCLUDE main_config %]
-[% IF tbbinfos.os == 'Windows';
- SET bin_ext = 'exe';
- ELSE;
- SET bin_ext = 'bin';
- END;
--%]
-
-UseBridges 1
-Bridge obfs3 83.212.101.3:80 A09D536DD1752D542E1FBB3C9CE4449D51298239
-Bridge obfs3 169.229.59.74:31493 AF9F66B7B04F8FF6F32D455F05135250A16543C9
-Bridge obfs3 169.229.59.75:46328 AF9F66B7B04F8FF6F32D455F05135250A16543C9
-Bridge obfs3 109.105.109.163:38980 1E05F577A0EC0213F971D81BF4D86A9E4E8229ED
-Bridge obfs3 109.105.109.163:47779 4C331FA9B3D1D6D8FB0D8FBBF0C259C360D97E6A
-ClientTransportPlugin obfs3 exec [% tbbinfos.ptdir %]/obfsproxy.[% bin_ext %] managed
diff --git a/tor-config/tor_obfs3_httpproxy.conf b/tor-config/tor_obfs3_httpproxy.conf
deleted file mode 100644
index 1e4753b..0000000
--- a/tor-config/tor_obfs3_httpproxy.conf
+++ /dev/null
@@ -1,2 +0,0 @@
-[% INCLUDE tor_obfs3.conf %]
-[% INCLUDE http_proxy %]
1
0

[tor-browser-build/master] Bug 31054: Add android-aarch64 nightly builds
by boklm@torproject.org 08 Jul '19
by boklm@torproject.org 08 Jul '19
08 Jul '19
commit 7bee08d921c147712a69140c44b506eaf19d57d6
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Mon Jul 8 19:20:05 2019 +0200
Bug 31054: Add android-aarch64 nightly builds
Update the tor-browser-bundle-testsuite.git commit, to add
android-aarch64 nightly builds.
At the same time, we update the tor-browser-bundle-testsuite.git URL to
use the repository that created with #30516.
---
tools/ansible/roles/tbb-nightly-build/defaults/main.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/ansible/roles/tbb-nightly-build/defaults/main.yml b/tools/ansible/roles/tbb-nightly-build/defaults/main.yml
index 2a4cc6e..acc88f9 100644
--- a/tools/ansible/roles/tbb-nightly-build/defaults/main.yml
+++ b/tools/ansible/roles/tbb-nightly-build/defaults/main.yml
@@ -4,8 +4,8 @@ nightly_build_cron_hour: 2
nightly_build_cron_minute: 20
nightly_build_keep_builds: 2
testsuite_dir: "/home/{{ nightly_build_user }}/tbb-testsuite"
-testsuite_git_url: https://git.torproject.org/user/boklm/tor-browser-bundle-testsuite.git
-testsuite_git_commit: 9283635ace22c3a7f629b5bc60e8fec0af4dc13c
+testsuite_git_url: https://git.torproject.org/tor-browser-bundle-testsuite.git
+testsuite_git_commit: 6a2c39273bfd729446ef787e4f7d1bf3138cfc4a
nightly_build_wwwdir: "/home/{{ nightly_build_user }}/www"
nightly_build_nginx_enable: true
nightly_build_nginx_listen: 127.0.0.1:80
1
0

[tor-browser-bundle-testsuite/master] .gitkeyring: Add new sub-keys
by boklm@torproject.org 08 Jul '19
by boklm@torproject.org 08 Jul '19
08 Jul '19
commit 6a2c39273bfd729446ef787e4f7d1bf3138cfc4a
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Mon Jul 8 19:13:18 2019 +0200
.gitkeyring: Add new sub-keys
Update .gitkeyring to add a new sub-key, fixing pulling of this git
repository using the tools/pull script.
---
.gitkeyring | Bin 11674 -> 5610 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
diff --git a/.gitkeyring b/.gitkeyring
index b1622f1..cceaf37 100644
Binary files a/.gitkeyring and b/.gitkeyring differ
1
0

[tor-browser-bundle-testsuite/master] Bug 31054: Add android-aarch64 to nightly builds
by boklm@torproject.org 08 Jul '19
by boklm@torproject.org 08 Jul '19
08 Jul '19
commit c705352fa1e043b5659548633dccaa468903e0f9
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Mon Jul 8 18:44:25 2019 +0200
Bug 31054: Add android-aarch64 to nightly builds
---
TBBTestSuite/TestSuite/TorBrowserBuild.pm | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/TBBTestSuite/TestSuite/TorBrowserBuild.pm b/TBBTestSuite/TestSuite/TorBrowserBuild.pm
index f1f88e1..a6def45 100644
--- a/TBBTestSuite/TestSuite/TorBrowserBuild.pm
+++ b/TBBTestSuite/TestSuite/TorBrowserBuild.pm
@@ -103,6 +103,18 @@ sub set_tests {
],
publish_dir => 'nightly-android-x86',
},
+ {
+ name => 'nightly-android-aarch64',
+ descr => 'build tor-browser nightly android-aarch64',
+ type => 'rbm_build',
+ project => 'release',
+ targets => [
+ 'noversiondir',
+ 'nightly',
+ 'torbrowser-android-aarch64',
+ ],
+ publish_dir => 'nightly-android-aarch64',
+ },
];
}
1
0

[tor-browser-build/master] FIXUP: recreated 27503.patch against widl sources without dev debug logging
by gk@torproject.org 08 Jul '19
by gk@torproject.org 08 Jul '19
08 Jul '19
commit 054c4d0f2502698f0803db7574bc0e229a66dfec
Author: Richard Pospesel <richard(a)torproject.org>
Date: Fri Jul 5 13:45:51 2019 -0700
FIXUP: recreated 27503.patch against widl sources without dev debug logging
---
projects/mingw-w64/27503.patch | 258 ++++++++++++++---------------------------
1 file changed, 90 insertions(+), 168 deletions(-)
diff --git a/projects/mingw-w64/27503.patch b/projects/mingw-w64/27503.patch
index f6bd197..ca542d0 100644
--- a/projects/mingw-w64/27503.patch
+++ b/projects/mingw-w64/27503.patch
@@ -1161,7 +1161,7 @@ index 0d44b403..0e62f77c 100644
return 1;
return 0;
diff --git a/mingw-w64-tools/widl/src/parser.tab.c b/mingw-w64-tools/widl/src/parser.tab.c
-index 6266e054..d7053e79 100644
+index 6266e054..8cd1605a 100644
--- a/mingw-w64-tools/widl/src/parser.tab.c
+++ b/mingw-w64-tools/widl/src/parser.tab.c
@@ -1,8 +1,8 @@
@@ -4829,7 +4829,7 @@ index 6266e054..d7053e79 100644
int top)
{
var_t *v = decl->var;
-@@ -5638,58 +5685,80 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+@@ -5638,58 +5685,74 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
expr_t *dim;
type_t **ptype;
type_t *func_type = decl ? decl->func_type : NULL;
@@ -4912,12 +4912,6 @@ index 6266e054..d7053e79 100644
- if (!ptr_attr && top && (*pt)->details.pointer.def_fc != FC_RP)
+ if (!ptr_attr && top && type_pointer_get_default_fc(*pt) != FC_RP)
{
-+ printf("dup_pointer_type!\n");
-+ printf("type : %p name : %s\n", *pt, (*pt)->name);
-+ /* ptr_attr is ref,unique or full (FC_RP, FC_UP, FC_FP) */
-+ /* *pt could be the var's declspec's type OR a type on a typedef */
-+ /* not an array */
-+
/* FIXME: this is a horrible hack to cope with the issue that we
* store an offset to the typeformat string in the type object, but
* two typeformat strings may be written depending on whether the
@@ -4927,7 +4921,7 @@ index 6266e054..d7053e79 100644
}
}
else if (ptr_attr)
-@@ -5700,16 +5769,16 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+@@ -5700,16 +5763,16 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
{
type_t *t = type;
@@ -4947,7 +4941,7 @@ index 6266e054..d7053e79 100644
else
break;
}
-@@ -5726,15 +5795,15 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+@@ -5726,15 +5789,15 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
if (is_attr(v->attrs, ATTR_V1ENUM))
{
@@ -4966,7 +4960,7 @@ index 6266e054..d7053e79 100644
if (sizes) LIST_FOR_EACH_ENTRY(dim, sizes, expr_t, entry)
{
if (dim->type != EXPR_VOID)
-@@ -5747,7 +5816,7 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+@@ -5747,7 +5810,7 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
else
*ptype = type_new_array((*ptype)->name,
type_array_get_element(*ptype), FALSE,
@@ -4975,7 +4969,7 @@ index 6266e054..d7053e79 100644
}
else if (is_ptr(*ptype))
*ptype = type_new_array((*ptype)->name, type_pointer_get_ref(*ptype), TRUE,
-@@ -5756,15 +5825,16 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+@@ -5756,15 +5819,16 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
error_loc("%s: size_is attribute applied to illegal type\n", v->name);
}
@@ -4995,7 +4989,7 @@ index 6266e054..d7053e79 100644
if (lengs) LIST_FOR_EACH_ENTRY(dim, lengs, expr_t, entry)
{
if (dim->type != EXPR_VOID)
-@@ -5782,10 +5852,11 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+@@ -5782,10 +5846,11 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
error_loc("%s: length_is attribute applied to illegal type\n", v->name);
}
@@ -5009,7 +5003,7 @@ index 6266e054..d7053e79 100644
else
error_loc("%s: too many expressions in length_is attribute\n", v->name);
}
-@@ -5796,29 +5867,31 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+@@ -5796,29 +5861,31 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
if (func_type)
{
type_t *ft, *t;
@@ -5050,7 +5044,7 @@ index 6266e054..d7053e79 100644
return v;
}
-@@ -5866,6 +5939,10 @@ var_list_t *append_var(var_list_t *list, var_t *var)
+@@ -5866,6 +5933,10 @@ var_list_t *append_var(var_list_t *list, var_t *var)
list_init( list );
}
list_add_tail( list, &var->entry );
@@ -5061,7 +5055,7 @@ index 6266e054..d7053e79 100644
return list;
}
-@@ -5885,11 +5962,11 @@ var_t *make_var(char *name)
+@@ -5885,11 +5956,11 @@ var_t *make_var(char *name)
{
var_t *v = xmalloc(sizeof(var_t));
v->name = name;
@@ -5075,7 +5069,7 @@ index 6266e054..d7053e79 100644
return v;
}
-@@ -5897,10 +5974,9 @@ static var_t *copy_var(var_t *src, char *name, map_attrs_filter_t attr_filter)
+@@ -5897,10 +5968,9 @@ static var_t *copy_var(var_t *src, char *name, map_attrs_filter_t attr_filter)
{
var_t *v = xmalloc(sizeof(var_t));
v->name = name;
@@ -5087,7 +5081,7 @@ index 6266e054..d7053e79 100644
v->loc_info = src->loc_info;
return v;
}
-@@ -5920,7 +5996,7 @@ static declarator_t *make_declarator(var_t *var)
+@@ -5920,7 +5990,7 @@ static declarator_t *make_declarator(var_t *var)
{
declarator_t *d = xmalloc(sizeof(*d));
d->var = var ? var : make_var(NULL);
@@ -5096,7 +5090,7 @@ index 6266e054..d7053e79 100644
d->func_type = NULL;
d->bits = NULL;
return d;
-@@ -5928,7 +6004,15 @@ static declarator_t *make_declarator(var_t *var)
+@@ -5928,7 +5998,15 @@ static declarator_t *make_declarator(var_t *var)
static type_t *make_safearray(type_t *type)
{
@@ -5113,16 +5107,7 @@ index 6266e054..d7053e79 100644
NULL, NULL, FC_RP);
}
-@@ -6007,6 +6091,8 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in
- }
- if (!namespace)
- namespace = &global_namespace;
-+ printf("reg_type { name : %s, namespace : %s, type : %s, ptr : %p}\n", name, namespace->name, ts_to_str(t), type);
-+
- hash = hash_ident(name);
- nt = xmalloc(sizeof(struct rtype));
- nt->name = name;
-@@ -6018,15 +6104,16 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in
+@@ -6018,15 +6096,16 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in
nt->t = t;
nt->next = namespace->type_hash[hash];
namespace->type_hash[hash] = nt;
@@ -5142,7 +5127,7 @@ index 6266e054..d7053e79 100644
type_get_type_detect_alias(t) == TYPE_UNION ||
type_get_type_detect_alias(t) == TYPE_ENCAPSULATED_UNION);
}
-@@ -6034,19 +6121,16 @@ static int is_incomplete(const type_t *t)
+@@ -6034,19 +6113,16 @@ static int is_incomplete(const type_t *t)
void add_incomplete(type_t *t)
{
struct typenode *tn = xmalloc(sizeof *tn);
@@ -5166,7 +5151,7 @@ index 6266e054..d7053e79 100644
t->defined = ot->defined;
}
}
-@@ -6070,7 +6154,7 @@ static void fix_incomplete_types(type_t *complete_type)
+@@ -6070,7 +6146,7 @@ static void fix_incomplete_types(type_t *complete_type)
{
if (type_is_equal(complete_type, tn->type))
{
@@ -5175,7 +5160,7 @@ index 6266e054..d7053e79 100644
list_remove(&tn->entry);
free(tn);
}
-@@ -6094,7 +6178,13 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
+@@ -6094,7 +6170,13 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
type_get_type_detect_alias(type) == TYPE_ENCAPSULATED_UNION)
{
if (!type->name)
@@ -5189,13 +5174,7 @@ index 6266e054..d7053e79 100644
/* replace existing attributes when generating a typelib */
if (do_typelib)
-@@ -6120,12 +6210,12 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
- * for cleaner solution.
- */
- if (cur && input_name == cur->loc_info.input_name)
-- error_loc("%s: redefinition error; original definition was at %s:%d\n",
-+ error_loc("FOO %s: redefinition error; original definition was at %s:%d\n",
- cur->name, cur->loc_info.input_name,
+@@ -6125,7 +6207,7 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
cur->loc_info.line_number);
name = declare_var(attrs, decl_spec, decl, 0);
@@ -5204,16 +5183,7 @@ index 6266e054..d7053e79 100644
cur->attrs = attrs;
if (is_incomplete(cur))
-@@ -6140,6 +6230,8 @@ type_t *find_type(const char *name, struct namespace *namespace, int t)
- {
- struct rtype *cur;
-
-+ printf("find_type { name : %s, namespace %s, type : %s }\n", name, namespace ? namespace->name : NULL, ts_to_str(t));
-+
- if(namespace && namespace != &global_namespace) {
- for(cur = namespace->type_hash[hash_ident(name)]; cur; cur = cur->next) {
- if(cur->t == t && !strcmp(cur->name, name))
-@@ -6293,7 +6385,6 @@ struct allowed_attr allowed_attr[] =
+@@ -6293,7 +6375,6 @@ struct allowed_attr allowed_attr[] =
/* ATTR_CASE */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "case" },
/* ATTR_CODE */ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" },
/* ATTR_COMMSTATUS */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" },
@@ -5221,7 +5191,7 @@ index 6266e054..d7053e79 100644
/* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" },
/* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, "control" },
/* ATTR_DECODE */ { 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "decode" },
-@@ -6328,7 +6419,6 @@ struct allowed_attr allowed_attr[] =
+@@ -6328,7 +6409,6 @@ struct allowed_attr allowed_attr[] =
/* ATTR_IMMEDIATEBIND */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "immediatebind" },
/* ATTR_IMPLICIT_HANDLE */ { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "implicit_handle" },
/* ATTR_IN */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "in" },
@@ -5229,7 +5199,7 @@ index 6266e054..d7053e79 100644
/* ATTR_INPUTSYNC */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inputsync" },
/* ATTR_LENGTHIS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, "length_is" },
/* ATTR_LIBLCID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "lcid" },
-@@ -6400,10 +6490,10 @@ static attr_list_t *check_iface_attrs(const char *name, attr_list_t *attrs)
+@@ -6400,10 +6480,10 @@ static attr_list_t *check_iface_attrs(const char *name, attr_list_t *attrs)
if (attr->type == ATTR_IMPLICIT_HANDLE)
{
const var_t *var = attr->u.pval;
@@ -5243,7 +5213,7 @@ index 6266e054..d7053e79 100644
continue;
error_loc("attribute %s requires a handle type in interface %s\n",
allowed_attr[attr->type].display_name, name);
-@@ -6608,7 +6698,7 @@ static int is_ptr_guid_type(const type_t *type)
+@@ -6608,7 +6688,7 @@ static int is_ptr_guid_type(const type_t *type)
/* second, make sure it is a pointer to something of size sizeof(GUID),
* i.e. 16 bytes */
@@ -5252,7 +5222,7 @@ index 6266e054..d7053e79 100644
}
static void check_conformance_expr_list(const char *attr_name, const var_t *arg, const type_t *container_type, expr_list_t *expr_list)
-@@ -6635,7 +6725,7 @@ static void check_remoting_fields(const var_t *var, type_t *type);
+@@ -6635,7 +6715,7 @@ static void check_remoting_fields(const var_t *var, type_t *type);
static void check_field_common(const type_t *container_type,
const char *container_name, const var_t *arg)
{
@@ -5261,7 +5231,7 @@ index 6266e054..d7053e79 100644
int more_to_do;
const char *container_type_name;
const char *var_type;
-@@ -6665,7 +6755,7 @@ static void check_field_common(const type_t *container_type,
+@@ -6665,7 +6745,7 @@ static void check_field_common(const type_t *container_type,
}
if (is_attr(arg->attrs, ATTR_LENGTHIS) &&
@@ -5270,7 +5240,7 @@ index 6266e054..d7053e79 100644
error_loc_info(&arg->loc_info,
"string and length_is specified for argument %s are mutually exclusive attributes\n",
arg->name);
-@@ -6762,23 +6852,28 @@ static void check_field_common(const type_t *container_type,
+@@ -6762,23 +6842,28 @@ static void check_field_common(const type_t *container_type,
{
const type_t *t = type;
while (is_ptr(t))
@@ -5303,7 +5273,7 @@ index 6266e054..d7053e79 100644
case TGT_RANGE:
/* nothing to do */
break;
-@@ -6803,13 +6898,18 @@ static void check_remoting_fields(const var_t *var, type_t *type)
+@@ -6803,13 +6888,18 @@ static void check_remoting_fields(const var_t *var, type_t *type)
if (type_is_complete(type))
fields = type_struct_get_fields(type);
else
@@ -5325,7 +5295,7 @@ index 6266e054..d7053e79 100644
}
/* checks that arguments for a function make sense for marshalling and unmarshalling */
-@@ -6818,9 +6918,10 @@ static void check_remoting_args(const var_t *func)
+@@ -6818,9 +6908,10 @@ static void check_remoting_args(const var_t *func)
const char *funcname = func->name;
const var_t *arg;
@@ -5338,7 +5308,7 @@ index 6266e054..d7053e79 100644
/* check that [out] parameters have enough pointer levels */
if (is_attr(arg->attrs, ATTR_OUT))
-@@ -6860,16 +6961,16 @@ static void check_remoting_args(const var_t *func)
+@@ -6860,16 +6951,16 @@ static void check_remoting_args(const var_t *func)
}
}
@@ -5359,7 +5329,7 @@ index 6266e054..d7053e79 100644
free(var.name);
}
}
-@@ -6886,8 +6987,8 @@ static void add_explicit_handle_if_necessary(const type_t *iface, var_t *func)
+@@ -6886,8 +6977,8 @@ static void add_explicit_handle_if_necessary(const type_t *iface, var_t *func)
* function */
var_t *idl_handle = make_var(xstrdup("IDL_handle"));
idl_handle->attrs = append_attr(NULL, make_attr(ATTR_IN));
@@ -5370,7 +5340,7 @@ index 6266e054..d7053e79 100644
}
}
-@@ -6952,6 +7053,7 @@ static void check_async_uuid(type_t *iface)
+@@ -6952,6 +7043,7 @@ static void check_async_uuid(type_t *iface)
type_t *async_iface;
type_t *inherit;
@@ -5378,7 +5348,7 @@ index 6266e054..d7053e79 100644
if (!is_attr(iface->attrs, ATTR_ASYNCUUID)) return;
inherit = iface->details.iface->inherit;
-@@ -6968,7 +7070,8 @@ static void check_async_uuid(type_t *iface)
+@@ -6968,7 +7060,8 @@ static void check_async_uuid(type_t *iface)
var_t *begin_func, *finish_func, *func = stmt->u.var, *arg;
var_list_t *begin_args = NULL, *finish_args = NULL, *args;
@@ -5388,7 +5358,7 @@ index 6266e054..d7053e79 100644
if (args) LIST_FOR_EACH_ENTRY(arg, args, var_t, entry)
{
if (is_attr(arg->attrs, ATTR_IN) || !is_attr(arg->attrs, ATTR_OUT))
-@@ -6978,15 +7081,15 @@ static void check_async_uuid(type_t *iface)
+@@ -6978,15 +7071,15 @@ static void check_async_uuid(type_t *iface)
}
begin_func = copy_var(func, concat_str("Begin_", func->name), NULL);
@@ -5410,7 +5380,7 @@ index 6266e054..d7053e79 100644
stmts = append_statement(stmts, make_statement_declaration(finish_func));
}
-@@ -7026,6 +7129,7 @@ static void check_statements(const statement_list_t *stmts, int is_inside_librar
+@@ -7026,6 +7119,7 @@ static void check_statements(const statement_list_t *stmts, int is_inside_librar
static void check_all_user_types(const statement_list_t *stmts)
{
const statement_t *stmt;
@@ -5418,7 +5388,7 @@ index 6266e054..d7053e79 100644
if (stmts) LIST_FOR_EACH_ENTRY(stmt, stmts, const statement_t, entry)
{
-@@ -7037,7 +7141,11 @@ static void check_all_user_types(const statement_list_t *stmts)
+@@ -7037,7 +7131,11 @@ static void check_all_user_types(const statement_list_t *stmts)
const statement_t *stmt_func;
STATEMENTS_FOR_EACH_FUNC(stmt_func, type_iface_get_stmts(stmt->u.type)) {
const var_t *func = stmt_func->u.var;
@@ -5431,7 +5401,7 @@ index 6266e054..d7053e79 100644
}
}
}
-@@ -7071,6 +7179,10 @@ static statement_t *make_statement_type_decl(type_t *type)
+@@ -7071,6 +7169,10 @@ static statement_t *make_statement_type_decl(type_t *type)
{
statement_t *stmt = make_statement(STMT_TYPE);
stmt->u.type = type;
@@ -5442,7 +5412,7 @@ index 6266e054..d7053e79 100644
return stmt;
}
-@@ -7085,16 +7197,16 @@ static statement_t *make_statement_declaration(var_t *var)
+@@ -7085,16 +7187,16 @@ static statement_t *make_statement_declaration(var_t *var)
{
statement_t *stmt = make_statement(STMT_DECLARATION);
stmt->u.var = var;
@@ -5462,7 +5432,7 @@ index 6266e054..d7053e79 100644
error_loc("instantiation of data is illegal\n");
return stmt;
}
-@@ -7146,6 +7258,7 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
+@@ -7146,6 +7248,7 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
declarator_t *decl, *next;
statement_t *stmt;
type_list_t **type_list;
@@ -5470,7 +5440,7 @@ index 6266e054..d7053e79 100644
if (!decls) return NULL;
-@@ -7157,6 +7270,18 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
+@@ -7157,6 +7260,18 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
{
var_t *var = decl->var;
type_t *type = find_type_or_error(var->name, 0);
@@ -5489,7 +5459,7 @@ index 6266e054..d7053e79 100644
*type_list = xmalloc(sizeof(type_list_t));
(*type_list)->type = type;
(*type_list)->next = NULL;
-@@ -7166,6 +7291,7 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
+@@ -7166,6 +7281,7 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
free(var);
}
@@ -5497,14 +5467,13 @@ index 6266e054..d7053e79 100644
return stmt;
}
-@@ -7206,7 +7332,7 @@ void init_loc_info(loc_info_t *i)
+@@ -7206,7 +7322,7 @@ void init_loc_info(loc_info_t *i)
static void check_def(const type_t *t)
{
- if (t->defined)
-- error_loc("%s: redefinition error; original definition was at %s:%d\n",
+ if (type_is_defined(t))
-+ error_loc("BAR %s: redefinition error; original definition was at %s:%d\n",
+ error_loc("%s: redefinition error; original definition was at %s:%d\n",
t->name, t->loc_info.input_name, t->loc_info.line_number);
}
diff --git a/mingw-w64-tools/widl/src/parser.tab.h b/mingw-w64-tools/widl/src/parser.tab.h
@@ -5544,7 +5513,7 @@ index 09874726..fc7a8f4d 100644
typedef union YYSTYPE YYSTYPE;
diff --git a/mingw-w64-tools/widl/src/parser.y b/mingw-w64-tools/widl/src/parser.y
-index d9793941..bb14bf76 100644
+index d9793941..64503ac1 100644
--- a/mingw-w64-tools/widl/src/parser.y
+++ b/mingw-w64-tools/widl/src/parser.y
@@ -52,13 +52,6 @@ struct _import_t
@@ -6008,7 +5977,7 @@ index d9793941..bb14bf76 100644
int top)
{
var_t *v = decl->var;
-@@ -1523,58 +1573,80 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+@@ -1523,58 +1573,74 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
expr_t *dim;
type_t **ptype;
type_t *func_type = decl ? decl->func_type : NULL;
@@ -6091,12 +6060,6 @@ index d9793941..bb14bf76 100644
- if (!ptr_attr && top && (*pt)->details.pointer.def_fc != FC_RP)
+ if (!ptr_attr && top && type_pointer_get_default_fc(*pt) != FC_RP)
{
-+ printf("dup_pointer_type!\n");
-+ printf("type : %p name : %s\n", *pt, (*pt)->name);
-+ /* ptr_attr is ref,unique or full (FC_RP, FC_UP, FC_FP) */
-+ /* *pt could be the var's declspec's type OR a type on a typedef */
-+ /* not an array */
-+
/* FIXME: this is a horrible hack to cope with the issue that we
* store an offset to the typeformat string in the type object, but
* two typeformat strings may be written depending on whether the
@@ -6106,7 +6069,7 @@ index d9793941..bb14bf76 100644
}
}
else if (ptr_attr)
-@@ -1585,16 +1657,16 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+@@ -1585,16 +1651,16 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
{
type_t *t = type;
@@ -6126,7 +6089,7 @@ index d9793941..bb14bf76 100644
else
break;
}
-@@ -1611,15 +1683,15 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+@@ -1611,15 +1677,15 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
if (is_attr(v->attrs, ATTR_V1ENUM))
{
@@ -6145,7 +6108,7 @@ index d9793941..bb14bf76 100644
if (sizes) LIST_FOR_EACH_ENTRY(dim, sizes, expr_t, entry)
{
if (dim->type != EXPR_VOID)
-@@ -1632,7 +1704,7 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+@@ -1632,7 +1698,7 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
else
*ptype = type_new_array((*ptype)->name,
type_array_get_element(*ptype), FALSE,
@@ -6154,7 +6117,7 @@ index d9793941..bb14bf76 100644
}
else if (is_ptr(*ptype))
*ptype = type_new_array((*ptype)->name, type_pointer_get_ref(*ptype), TRUE,
-@@ -1641,15 +1713,16 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+@@ -1641,15 +1707,16 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
error_loc("%s: size_is attribute applied to illegal type\n", v->name);
}
@@ -6174,7 +6137,7 @@ index d9793941..bb14bf76 100644
if (lengs) LIST_FOR_EACH_ENTRY(dim, lengs, expr_t, entry)
{
if (dim->type != EXPR_VOID)
-@@ -1667,10 +1740,11 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+@@ -1667,10 +1734,11 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
error_loc("%s: length_is attribute applied to illegal type\n", v->name);
}
@@ -6188,7 +6151,7 @@ index d9793941..bb14bf76 100644
else
error_loc("%s: too many expressions in length_is attribute\n", v->name);
}
-@@ -1681,29 +1755,31 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+@@ -1681,29 +1749,31 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
if (func_type)
{
type_t *ft, *t;
@@ -6229,7 +6192,7 @@ index d9793941..bb14bf76 100644
return v;
}
-@@ -1751,6 +1827,10 @@ var_list_t *append_var(var_list_t *list, var_t *var)
+@@ -1751,6 +1821,10 @@ var_list_t *append_var(var_list_t *list, var_t *var)
list_init( list );
}
list_add_tail( list, &var->entry );
@@ -6240,7 +6203,7 @@ index d9793941..bb14bf76 100644
return list;
}
-@@ -1770,11 +1850,11 @@ var_t *make_var(char *name)
+@@ -1770,11 +1844,11 @@ var_t *make_var(char *name)
{
var_t *v = xmalloc(sizeof(var_t));
v->name = name;
@@ -6254,7 +6217,7 @@ index d9793941..bb14bf76 100644
return v;
}
-@@ -1782,10 +1862,9 @@ static var_t *copy_var(var_t *src, char *name, map_attrs_filter_t attr_filter)
+@@ -1782,10 +1856,9 @@ static var_t *copy_var(var_t *src, char *name, map_attrs_filter_t attr_filter)
{
var_t *v = xmalloc(sizeof(var_t));
v->name = name;
@@ -6266,7 +6229,7 @@ index d9793941..bb14bf76 100644
v->loc_info = src->loc_info;
return v;
}
-@@ -1805,7 +1884,7 @@ static declarator_t *make_declarator(var_t *var)
+@@ -1805,7 +1878,7 @@ static declarator_t *make_declarator(var_t *var)
{
declarator_t *d = xmalloc(sizeof(*d));
d->var = var ? var : make_var(NULL);
@@ -6275,7 +6238,7 @@ index d9793941..bb14bf76 100644
d->func_type = NULL;
d->bits = NULL;
return d;
-@@ -1813,7 +1892,15 @@ static declarator_t *make_declarator(var_t *var)
+@@ -1813,7 +1886,15 @@ static declarator_t *make_declarator(var_t *var)
static type_t *make_safearray(type_t *type)
{
@@ -6292,16 +6255,7 @@ index d9793941..bb14bf76 100644
NULL, NULL, FC_RP);
}
-@@ -1892,6 +1979,8 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in
- }
- if (!namespace)
- namespace = &global_namespace;
-+ printf("reg_type { name : %s, namespace : %s, type : %s, ptr : %p}\n", name, namespace->name, ts_to_str(t), type);
-+
- hash = hash_ident(name);
- nt = xmalloc(sizeof(struct rtype));
- nt->name = name;
-@@ -1903,15 +1992,16 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in
+@@ -1903,15 +1984,16 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in
nt->t = t;
nt->next = namespace->type_hash[hash];
namespace->type_hash[hash] = nt;
@@ -6321,7 +6275,7 @@ index d9793941..bb14bf76 100644
type_get_type_detect_alias(t) == TYPE_UNION ||
type_get_type_detect_alias(t) == TYPE_ENCAPSULATED_UNION);
}
-@@ -1919,19 +2009,16 @@ static int is_incomplete(const type_t *t)
+@@ -1919,19 +2001,16 @@ static int is_incomplete(const type_t *t)
void add_incomplete(type_t *t)
{
struct typenode *tn = xmalloc(sizeof *tn);
@@ -6345,7 +6299,7 @@ index d9793941..bb14bf76 100644
t->defined = ot->defined;
}
}
-@@ -1955,7 +2042,7 @@ static void fix_incomplete_types(type_t *complete_type)
+@@ -1955,7 +2034,7 @@ static void fix_incomplete_types(type_t *complete_type)
{
if (type_is_equal(complete_type, tn->type))
{
@@ -6354,7 +6308,7 @@ index d9793941..bb14bf76 100644
list_remove(&tn->entry);
free(tn);
}
-@@ -1979,7 +2066,13 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
+@@ -1979,7 +2058,13 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
type_get_type_detect_alias(type) == TYPE_ENCAPSULATED_UNION)
{
if (!type->name)
@@ -6368,13 +6322,7 @@ index d9793941..bb14bf76 100644
/* replace existing attributes when generating a typelib */
if (do_typelib)
-@@ -2005,12 +2098,12 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
- * for cleaner solution.
- */
- if (cur && input_name == cur->loc_info.input_name)
-- error_loc("%s: redefinition error; original definition was at %s:%d\n",
-+ error_loc("FOO %s: redefinition error; original definition was at %s:%d\n",
- cur->name, cur->loc_info.input_name,
+@@ -2010,7 +2095,7 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
cur->loc_info.line_number);
name = declare_var(attrs, decl_spec, decl, 0);
@@ -6383,16 +6331,7 @@ index d9793941..bb14bf76 100644
cur->attrs = attrs;
if (is_incomplete(cur))
-@@ -2025,6 +2118,8 @@ type_t *find_type(const char *name, struct namespace *namespace, int t)
- {
- struct rtype *cur;
-
-+ printf("find_type { name : %s, namespace %s, type : %s }\n", name, namespace ? namespace->name : NULL, ts_to_str(t));
-+
- if(namespace && namespace != &global_namespace) {
- for(cur = namespace->type_hash[hash_ident(name)]; cur; cur = cur->next) {
- if(cur->t == t && !strcmp(cur->name, name))
-@@ -2178,7 +2273,6 @@ struct allowed_attr allowed_attr[] =
+@@ -2178,7 +2263,6 @@ struct allowed_attr allowed_attr[] =
/* ATTR_CASE */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "case" },
/* ATTR_CODE */ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" },
/* ATTR_COMMSTATUS */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" },
@@ -6400,7 +6339,7 @@ index d9793941..bb14bf76 100644
/* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" },
/* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, "control" },
/* ATTR_DECODE */ { 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "decode" },
-@@ -2213,7 +2307,6 @@ struct allowed_attr allowed_attr[] =
+@@ -2213,7 +2297,6 @@ struct allowed_attr allowed_attr[] =
/* ATTR_IMMEDIATEBIND */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "immediatebind" },
/* ATTR_IMPLICIT_HANDLE */ { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "implicit_handle" },
/* ATTR_IN */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "in" },
@@ -6408,7 +6347,7 @@ index d9793941..bb14bf76 100644
/* ATTR_INPUTSYNC */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inputsync" },
/* ATTR_LENGTHIS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, "length_is" },
/* ATTR_LIBLCID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "lcid" },
-@@ -2285,10 +2378,10 @@ static attr_list_t *check_iface_attrs(const char *name, attr_list_t *attrs)
+@@ -2285,10 +2368,10 @@ static attr_list_t *check_iface_attrs(const char *name, attr_list_t *attrs)
if (attr->type == ATTR_IMPLICIT_HANDLE)
{
const var_t *var = attr->u.pval;
@@ -6422,7 +6361,7 @@ index d9793941..bb14bf76 100644
continue;
error_loc("attribute %s requires a handle type in interface %s\n",
allowed_attr[attr->type].display_name, name);
-@@ -2493,7 +2586,7 @@ static int is_ptr_guid_type(const type_t *type)
+@@ -2493,7 +2576,7 @@ static int is_ptr_guid_type(const type_t *type)
/* second, make sure it is a pointer to something of size sizeof(GUID),
* i.e. 16 bytes */
@@ -6431,7 +6370,7 @@ index d9793941..bb14bf76 100644
}
static void check_conformance_expr_list(const char *attr_name, const var_t *arg, const type_t *container_type, expr_list_t *expr_list)
-@@ -2520,7 +2613,7 @@ static void check_remoting_fields(const var_t *var, type_t *type);
+@@ -2520,7 +2603,7 @@ static void check_remoting_fields(const var_t *var, type_t *type);
static void check_field_common(const type_t *container_type,
const char *container_name, const var_t *arg)
{
@@ -6440,7 +6379,7 @@ index d9793941..bb14bf76 100644
int more_to_do;
const char *container_type_name;
const char *var_type;
-@@ -2550,7 +2643,7 @@ static void check_field_common(const type_t *container_type,
+@@ -2550,7 +2633,7 @@ static void check_field_common(const type_t *container_type,
}
if (is_attr(arg->attrs, ATTR_LENGTHIS) &&
@@ -6449,7 +6388,7 @@ index d9793941..bb14bf76 100644
error_loc_info(&arg->loc_info,
"string and length_is specified for argument %s are mutually exclusive attributes\n",
arg->name);
-@@ -2647,23 +2740,28 @@ static void check_field_common(const type_t *container_type,
+@@ -2647,23 +2730,28 @@ static void check_field_common(const type_t *container_type,
{
const type_t *t = type;
while (is_ptr(t))
@@ -6482,7 +6421,7 @@ index d9793941..bb14bf76 100644
case TGT_RANGE:
/* nothing to do */
break;
-@@ -2688,13 +2786,18 @@ static void check_remoting_fields(const var_t *var, type_t *type)
+@@ -2688,13 +2776,18 @@ static void check_remoting_fields(const var_t *var, type_t *type)
if (type_is_complete(type))
fields = type_struct_get_fields(type);
else
@@ -6504,7 +6443,7 @@ index d9793941..bb14bf76 100644
}
/* checks that arguments for a function make sense for marshalling and unmarshalling */
-@@ -2703,9 +2806,10 @@ static void check_remoting_args(const var_t *func)
+@@ -2703,9 +2796,10 @@ static void check_remoting_args(const var_t *func)
const char *funcname = func->name;
const var_t *arg;
@@ -6517,7 +6456,7 @@ index d9793941..bb14bf76 100644
/* check that [out] parameters have enough pointer levels */
if (is_attr(arg->attrs, ATTR_OUT))
-@@ -2745,16 +2849,16 @@ static void check_remoting_args(const var_t *func)
+@@ -2745,16 +2839,16 @@ static void check_remoting_args(const var_t *func)
}
}
@@ -6538,7 +6477,7 @@ index d9793941..bb14bf76 100644
free(var.name);
}
}
-@@ -2771,8 +2875,8 @@ static void add_explicit_handle_if_necessary(const type_t *iface, var_t *func)
+@@ -2771,8 +2865,8 @@ static void add_explicit_handle_if_necessary(const type_t *iface, var_t *func)
* function */
var_t *idl_handle = make_var(xstrdup("IDL_handle"));
idl_handle->attrs = append_attr(NULL, make_attr(ATTR_IN));
@@ -6549,7 +6488,7 @@ index d9793941..bb14bf76 100644
}
}
-@@ -2837,6 +2941,7 @@ static void check_async_uuid(type_t *iface)
+@@ -2837,6 +2931,7 @@ static void check_async_uuid(type_t *iface)
type_t *async_iface;
type_t *inherit;
@@ -6557,7 +6496,7 @@ index d9793941..bb14bf76 100644
if (!is_attr(iface->attrs, ATTR_ASYNCUUID)) return;
inherit = iface->details.iface->inherit;
-@@ -2853,7 +2958,8 @@ static void check_async_uuid(type_t *iface)
+@@ -2853,7 +2948,8 @@ static void check_async_uuid(type_t *iface)
var_t *begin_func, *finish_func, *func = stmt->u.var, *arg;
var_list_t *begin_args = NULL, *finish_args = NULL, *args;
@@ -6567,7 +6506,7 @@ index d9793941..bb14bf76 100644
if (args) LIST_FOR_EACH_ENTRY(arg, args, var_t, entry)
{
if (is_attr(arg->attrs, ATTR_IN) || !is_attr(arg->attrs, ATTR_OUT))
-@@ -2863,15 +2969,15 @@ static void check_async_uuid(type_t *iface)
+@@ -2863,15 +2959,15 @@ static void check_async_uuid(type_t *iface)
}
begin_func = copy_var(func, concat_str("Begin_", func->name), NULL);
@@ -6589,7 +6528,7 @@ index d9793941..bb14bf76 100644
stmts = append_statement(stmts, make_statement_declaration(finish_func));
}
-@@ -2911,6 +3017,7 @@ static void check_statements(const statement_list_t *stmts, int is_inside_librar
+@@ -2911,6 +3007,7 @@ static void check_statements(const statement_list_t *stmts, int is_inside_librar
static void check_all_user_types(const statement_list_t *stmts)
{
const statement_t *stmt;
@@ -6597,7 +6536,7 @@ index d9793941..bb14bf76 100644
if (stmts) LIST_FOR_EACH_ENTRY(stmt, stmts, const statement_t, entry)
{
-@@ -2922,7 +3029,11 @@ static void check_all_user_types(const statement_list_t *stmts)
+@@ -2922,7 +3019,11 @@ static void check_all_user_types(const statement_list_t *stmts)
const statement_t *stmt_func;
STATEMENTS_FOR_EACH_FUNC(stmt_func, type_iface_get_stmts(stmt->u.type)) {
const var_t *func = stmt_func->u.var;
@@ -6610,7 +6549,7 @@ index d9793941..bb14bf76 100644
}
}
}
-@@ -2956,6 +3067,10 @@ static statement_t *make_statement_type_decl(type_t *type)
+@@ -2956,6 +3057,10 @@ static statement_t *make_statement_type_decl(type_t *type)
{
statement_t *stmt = make_statement(STMT_TYPE);
stmt->u.type = type;
@@ -6621,7 +6560,7 @@ index d9793941..bb14bf76 100644
return stmt;
}
-@@ -2970,16 +3085,16 @@ static statement_t *make_statement_declaration(var_t *var)
+@@ -2970,16 +3075,16 @@ static statement_t *make_statement_declaration(var_t *var)
{
statement_t *stmt = make_statement(STMT_DECLARATION);
stmt->u.var = var;
@@ -6641,7 +6580,7 @@ index d9793941..bb14bf76 100644
error_loc("instantiation of data is illegal\n");
return stmt;
}
-@@ -3031,6 +3146,7 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
+@@ -3031,6 +3136,7 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
declarator_t *decl, *next;
statement_t *stmt;
type_list_t **type_list;
@@ -6649,7 +6588,7 @@ index d9793941..bb14bf76 100644
if (!decls) return NULL;
-@@ -3042,6 +3158,18 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
+@@ -3042,6 +3148,18 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
{
var_t *var = decl->var;
type_t *type = find_type_or_error(var->name, 0);
@@ -6668,7 +6607,7 @@ index d9793941..bb14bf76 100644
*type_list = xmalloc(sizeof(type_list_t));
(*type_list)->type = type;
(*type_list)->next = NULL;
-@@ -3051,6 +3179,7 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
+@@ -3051,6 +3169,7 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
free(var);
}
@@ -6676,14 +6615,13 @@ index d9793941..bb14bf76 100644
return stmt;
}
-@@ -3091,7 +3220,7 @@ void init_loc_info(loc_info_t *i)
+@@ -3091,7 +3210,7 @@ void init_loc_info(loc_info_t *i)
static void check_def(const type_t *t)
{
- if (t->defined)
-- error_loc("%s: redefinition error; original definition was at %s:%d\n",
+ if (type_is_defined(t))
-+ error_loc("BAR %s: redefinition error; original definition was at %s:%d\n",
+ error_loc("%s: redefinition error; original definition was at %s:%d\n",
t->name, t->loc_info.input_name, t->loc_info.line_number);
}
diff --git a/mingw-w64-tools/widl/src/parser.yy.c b/mingw-w64-tools/widl/src/parser.yy.c
@@ -9337,7 +9275,7 @@ index 9b1de2c8..2c2b1276 100644
return VT_PTR;
}
diff --git a/mingw-w64-tools/widl/src/typetree.c b/mingw-w64-tools/widl/src/typetree.c
-index b93806be..f52b785f 100644
+index b93806be..488f7a49 100644
--- a/mingw-w64-tools/widl/src/typetree.c
+++ b/mingw-w64-tools/widl/src/typetree.c
@@ -30,12 +30,16 @@
@@ -9386,7 +9324,7 @@ index b93806be..f52b785f 100644
error_loc("argument '%s' has void type\n", arg->name);
if (!arg->name)
{
-@@ -178,35 +181,29 @@ type_t *type_new_function(var_list_t *args)
+@@ -178,34 +181,28 @@ type_t *type_new_function(var_list_t *args)
return t;
}
@@ -9423,23 +9361,20 @@ index b93806be..f52b785f 100644
{
type_t *type = get_type(TYPE_MODULE, name, NULL, 0);
- if (type->type_type != TYPE_MODULE || type->defined)
-- error_loc("%s: redefinition error; original definition was at %s:%d\n",
+ if (type->type_type != TYPE_MODULE || type_is_defined(type))
-+ error_loc("BAZ %s: redefinition error; original definition was at %s:%d\n",
+ error_loc("%s: redefinition error; original definition was at %s:%d\n",
type->name, type->loc_info.input_name, type->loc_info.line_number);
type->name = name;
- return type;
-@@ -215,15 +212,15 @@ type_t *type_new_module(char *name)
+@@ -215,7 +212,7 @@ type_t *type_new_module(char *name)
type_t *type_new_coclass(char *name)
{
type_t *type = get_type(TYPE_COCLASS, name, NULL, 0);
- if (type->type_type != TYPE_COCLASS || type->defined)
-- error_loc("%s: redefinition error; original definition was at %s:%d\n",
+ if (type->type_type != TYPE_COCLASS || type_is_defined(type))
-+ error_loc("BING %s: redefinition error; original definition was at %s:%d\n",
+ error_loc("%s: redefinition error; original definition was at %s:%d\n",
type->name, type->loc_info.input_name, type->loc_info.line_number);
type->name = name;
- return type;
+@@ -223,7 +220,7 @@ type_t *type_new_coclass(char *name)
}
@@ -10078,7 +10013,7 @@ index 118e2245..4f4252e3 100644
{
MODE_Os, /* inline stubs */
diff --git a/mingw-w64-tools/widl/src/widltypes.h b/mingw-w64-tools/widl/src/widltypes.h
-index 08584de5..b9c5a07d 100644
+index 08584de5..cd71e9af 100644
--- a/mingw-w64-tools/widl/src/widltypes.h
+++ b/mingw-w64-tools/widl/src/widltypes.h
@@ -40,6 +40,7 @@ typedef struct _attr_t attr_t;
@@ -10279,20 +10214,7 @@ index 08584de5..b9c5a07d 100644
void init_types(void);
type_t *alloc_type(void);
-@@ -568,6 +607,12 @@ void clear_all_offsets(void);
- #define tsSTRUCT 2
- #define tsUNION 3
-
-+static inline const char* ts_to_str(int t)
-+{
-+ static const char* strings[] = {"tsNULL", "tsENUM", "tsSTRUCT", "tsUNION"};
-+ return strings[t];
-+}
-+
- var_t *find_const(const char *name, int f);
- type_t *find_type(const char *name, struct namespace *namespace, int t);
- type_t *make_type(enum type_type type);
-@@ -582,38 +627,18 @@ void init_loc_info(loc_info_t *);
+@@ -582,38 +621,18 @@ void init_loc_info(loc_info_t *);
char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix);
1
0

[tor-browser-build/master] Bug 30549: Avoid using keybox format in drop-expired-sub-keys
by gk@torproject.org 08 Jul '19
by gk@torproject.org 08 Jul '19
08 Jul '19
commit cd6555af118fa06a30d54a491618b50c5d463c5d
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Fri Jul 5 17:53:10 2019 +0200
Bug 30549: Avoid using keybox format in drop-expired-sub-keys
When creating a new keyring with gpg >= 2.1, it will be created in the
keybox format, which is only compatible with gpg >= 2.1. This means that
the drop-expired-sub-keys script will create keyring files which are not
compatible with older versions of gpg.
To avoid this, we use the output of gpg --export as the keyring file,
which is in the old format.
---
tools/keyring/drop-expired-sub-keys | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/tools/keyring/drop-expired-sub-keys b/tools/keyring/drop-expired-sub-keys
index e7bbe50..f041746 100755
--- a/tools/keyring/drop-expired-sub-keys
+++ b/tools/keyring/drop-expired-sub-keys
@@ -16,7 +16,5 @@ set -e
keyring="$1"
test -f "$keyring"
tmpfile=$(mktemp)
-gpg --no-auto-check-trustdb --no-default-keyring --keyring "$keyring" --armor --export-options export-clean --export-filter 'drop-subkey=expired -t || revoked -t' --export > "$tmpfile"
-rm -f "$keyring"
-gpg --no-auto-check-trustdb --trust-model always --no-default-keyring --keyring "$keyring" --import "$tmpfile"
-rm -f "$tmpfile"
+gpg --no-auto-check-trustdb --no-default-keyring --keyring "$keyring" --export-options export-clean --export-filter 'drop-subkey=expired -t || revoked -t' --export > "$tmpfile"
+mv -f "$tmpfile" "$keyring"
1
0

[tor-browser-build/master] Merge remote-tracking branch 'boklm/bug_30549_v6'
by gk@torproject.org 08 Jul '19
by gk@torproject.org 08 Jul '19
08 Jul '19
commit 1ece76a456213a16f23b41a6ce133a44a0302ee0
Merge: fdd4aaf cd6555a
Author: Georg Koppen <gk(a)torproject.org>
Date: Mon Jul 8 06:39:15 2019 +0000
Merge remote-tracking branch 'boklm/bug_30549_v6'
tools/keyring/drop-expired-sub-keys | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
1
0
commit fdd4aaf53b5c772fa71a951231ea50a41d00c583
Author: Georg Koppen <gk(a)torproject.org>
Date: Sat Jul 6 06:47:23 2019 +0000
Using build2 for 9.0a4
---
rbm.conf | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rbm.conf b/rbm.conf
index ff4169c..4f6e943 100644
--- a/rbm.conf
+++ b/rbm.conf
@@ -25,7 +25,7 @@ buildconf:
var:
torbrowser_version: '9.0a4'
- torbrowser_build: 'build1'
+ torbrowser_build: 'build2'
torbrowser_incremental_from:
- 9.0a3
project_name: tor-browser
1
0
commit 15d7d2311bfc238b7f16f486348d84fc52b054af
Author: Georg Koppen <gk(a)torproject.org>
Date: Sat Jul 6 06:52:44 2019 +0000
Pick up arch64 properly
---
projects/release/config | 2 ++
1 file changed, 2 insertions(+)
diff --git a/projects/release/config b/projects/release/config
index 1623083..0133c3f 100644
--- a/projects/release/config
+++ b/projects/release/config
@@ -17,6 +17,7 @@ targets:
- torbrowser-osx-x86_64
- torbrowser-android-armv7
- torbrowser-android-x86
+ - torbrowser-android-aarch64
- torbrowser-src
torbrowser-android-armv7:
var:
@@ -124,6 +125,7 @@ input_files:
project: tor-browser
enable: '[% c("var/torbrowser-android-aarch64") %]'
target:
+ - '[% c("var/containers_target") %]'
- '[% c("var/build_target") %]'
- torbrowser-android-aarch64
1
0

04 Jul '19
commit 864378b92afcfdee80c2a79f6ec2e3d5c2d2fbc7
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Jul 4 20:26:50 2019 +0000
Release preparations for 9.0a4
Versions bump and Changelog update
---
projects/firefox/config | 4 ++--
projects/https-everywhere/config | 2 +-
.../tor-browser/Bundle-Data/Docs/ChangeLog.txt | 27 ++++++++++++++++++++++
projects/tor-launcher/config | 2 +-
projects/tor/config | 2 +-
projects/torbutton/config | 2 +-
rbm.conf | 6 ++---
7 files changed, 36 insertions(+), 9 deletions(-)
diff --git a/projects/firefox/config b/projects/firefox/config
index 20c5b0f..9565b8e 100644
--- a/projects/firefox/config
+++ b/projects/firefox/config
@@ -1,14 +1,14 @@
# vim: filetype=yaml sw=2
version: '[% c("abbrev") %]'
filename: 'firefox-[% c("version") %]-[% c("var/osname") %]-[% c("var/build_id") %]'
-git_hash: 'tor-browser-[% c("var/firefox_version") %]-[% c("var/torbrowser_branch") %]-2-build2'
+git_hash: 'tor-browser-[% c("var/firefox_version") %]-[% c("var/torbrowser_branch") %]-1-build1'
tag_gpg_id: 1
git_url: https://git.torproject.org/tor-browser.git
git_submodule: 1
gpg_keyring: torbutton.gpg
var:
- firefox_platform_version: 60.7.0
+ firefox_platform_version: 60.8.0
firefox_version: '[% c("var/firefox_platform_version") %]esr'
torbrowser_branch: 9.0
torbrowser_update_channel: alpha
diff --git a/projects/https-everywhere/config b/projects/https-everywhere/config
index 2db9177..6232669 100644
--- a/projects/https-everywhere/config
+++ b/projects/https-everywhere/config
@@ -1,5 +1,5 @@
# vim: filetype=yaml sw=2
-version: 2019.5.13
+version: 2019.6.27
git_url: https://git.torproject.org/https-everywhere.git
git_hash: '[% c("version") %]'
git_submodule: 1
diff --git a/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt b/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
index 37e89a2..5a1a67a 100644
--- a/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
+++ b/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
@@ -1,3 +1,30 @@
+Tor Browser 9.0a4 -- July 9 2019
+ * All platforms
+ * Update Firefox to 60.8.0esr
+ * Update Torbutton to 2.2.1
+ * Bug 30577: Add Fundraising Banner
+ * Bug 31041: Stop syncing network.cookie.lifetimePolicy
+ * Bug 30468: Add mk locale
+ * Translations update
+ * Update Tor Launcher to 0.2.19.2
+ * Bug 30468: Add mk locale
+ * Translations update
+ * Update HTTPS Everywhere to 2019.6.27
+ * Bug 31055+31058: Remove four default bridges
+ * Bug 30849: Backport fixes for Mozilla's bug 1552627 and 1549833
+ * Windows + OS X + Linux
+ * Update Tor to 0.4.1.3-alpha
+ * Bug 30468: Add mk locale
+ * Bug 31059: Enable Letterboxing
+ * Windows
+ * Bug 27503: Provide full support for accessibility tools
+ * Bug 30575: Don't allow enterprise policies in Tor Browser
+ * OS X
+ * Bug 30631: Blurry Tor Browser icon on macOS app switcher
+ * Android
+ * Bug 28119: Tor Browser for aarch64
+ * Bug 30573: Sanitize old tabs and wait for tor before opening new tabs
+
Tor Browser 9.0a3 -- June 24 2019
* All platforms
* Pick up fixes for Mozilla's bug 1544386 and 1560192
diff --git a/projects/tor-launcher/config b/projects/tor-launcher/config
index 9bf886a..273c466 100644
--- a/projects/tor-launcher/config
+++ b/projects/tor-launcher/config
@@ -1,5 +1,5 @@
# vim: filetype=yaml sw=2
-version: 0.2.19.1
+version: 0.2.19.2
git_url: https://git.torproject.org/tor-launcher.git
git_hash: '[% c("version") %]'
gpg_keyring: torbutton.gpg
diff --git a/projects/tor/config b/projects/tor/config
index 6f4b5f2..35b37ce 100644
--- a/projects/tor/config
+++ b/projects/tor/config
@@ -1,6 +1,6 @@
# vim: filetype=yaml sw=2
filename: '[% project %]-[% c("version") %]-[% c("var/osname") %]-[% c("var/build_id") %]'
-version: 0.4.1.2-alpha
+version: 0.4.1.3-alpha
git_hash: 'tor-[% c("version") %]'
git_url: https://git.torproject.org/tor.git
git_submodule: 1
diff --git a/projects/torbutton/config b/projects/torbutton/config
index ae3f915..1e37b80 100644
--- a/projects/torbutton/config
+++ b/projects/torbutton/config
@@ -1,5 +1,5 @@
# vim: filetype=yaml sw=2
-version: 2.2
+version: 2.2.1
git_url: https://git.torproject.org/torbutton.git
git_hash: '[% c("version") %]'
gpg_keyring: torbutton.gpg
diff --git a/rbm.conf b/rbm.conf
index 1a1570b..ff4169c 100644
--- a/rbm.conf
+++ b/rbm.conf
@@ -24,10 +24,10 @@ buildconf:
git_signtag_opt: '-s'
var:
- torbrowser_version: '9.0a3'
- torbrowser_build: 'build3'
+ torbrowser_version: '9.0a4'
+ torbrowser_build: 'build1'
torbrowser_incremental_from:
- - 9.0a2
+ - 9.0a3
project_name: tor-browser
multi_lingual: 0
build_mar: 1
1
0

[tor-browser-build/maint-8.5] Bug 31079: Fix keyring/firefox.gpg format
by gk@torproject.org 04 Jul '19
by gk@torproject.org 04 Jul '19
04 Jul '19
commit cbe1fe2419c0f18b25a79e8d9eec0288af60f826
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Thu Jul 4 16:52:23 2019 +0200
Bug 31079: Fix keyring/firefox.gpg format
The previous commit updating keyring/firefox.gpg converted it to the
keybox format, which is only supported by gnupg >= 2.1. This commit
changes it back to the previous format, supported by older versions of
gnupg.
---
keyring/firefox.gpg | Bin 2995 -> 2817 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
diff --git a/keyring/firefox.gpg b/keyring/firefox.gpg
index 53e62b2..d2eada0 100644
Binary files a/keyring/firefox.gpg and b/keyring/firefox.gpg differ
1
0

[tor-browser-build/master] Bug 31079: Fix keyring/firefox.gpg format
by gk@torproject.org 04 Jul '19
by gk@torproject.org 04 Jul '19
04 Jul '19
commit e5ed8e3451c0e2ed8c16400ca0c6d1d64eab5f2e
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Thu Jul 4 16:52:23 2019 +0200
Bug 31079: Fix keyring/firefox.gpg format
The previous commit updating keyring/firefox.gpg converted it to the
keybox format, which is only supported by gnupg >= 2.1. This commit
changes it back to the previous format, supported by older versions of
gnupg.
---
keyring/firefox.gpg | Bin 2995 -> 2817 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
diff --git a/keyring/firefox.gpg b/keyring/firefox.gpg
index 53e62b2..d2eada0 100644
Binary files a/keyring/firefox.gpg and b/keyring/firefox.gpg differ
1
0

[tor-browser-build/master] Bug 30468: Add mk locale for desktop builds
by gk@torproject.org 04 Jul '19
by gk@torproject.org 04 Jul '19
04 Jul '19
commit 7b1c46d3649c20c91d4e33529412301e96ce2a0f
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Thu Jul 4 17:44:31 2019 +0200
Bug 30468: Add mk locale for desktop builds
---
projects/firefox-locale-bundle/build | 2 ++
projects/firefox/build | 6 ++++--
rbm.conf | 1 +
3 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/projects/firefox-locale-bundle/build b/projects/firefox-locale-bundle/build
index 7000300..3a9e323 100644
--- a/projects/firefox-locale-bundle/build
+++ b/projects/firefox-locale-bundle/build
@@ -13,6 +13,8 @@ tmpdir=$(mktemp -d)
[% FOREACH lang = c('var/locales') %]
[% SET lang = tmpl(lang);
+ # mk is unavailable on mobile.
+ NEXT IF lang == 'mk';
SET hgurl = "https://hg.mozilla.org/l10n-central/" _ lang %]
if test -d [% lang %]
then
diff --git a/projects/firefox/build b/projects/firefox/build
index 3aa4a4d..e0870c1 100644
--- a/projects/firefox/build
+++ b/projects/firefox/build
@@ -164,8 +164,10 @@ rm -f js/src/configure
[% IF c("var/android") %]
# Building a multi-locale .apk
- [% FOREACH lang = c('var/locales') %]
- [% SET lang = tmpl(lang) %]
+ [% FOREACH lang = c('var/locales');
+ SET lang = tmpl(lang);
+ # mk is unavailable on mobile.
+ NEXT IF lang == 'mk'; %]
# Copy our torbrowser_strings.dtd at the right place
cp /var/tmp/dist/tba-translation/[% lang %]/torbrowser_strings.dtd /var/tmp/dist/locales/[% lang %]/mobile/android/base/
./mach build chrome-[% lang %];
diff --git a/rbm.conf b/rbm.conf
index 62a19a6..1a1570b 100644
--- a/rbm.conf
+++ b/rbm.conf
@@ -82,6 +82,7 @@ var:
- '[% c("var/locale_ja") %]'
- ka
- ko
+ - mk
- nb-NO
- nl
- pl
1
0

[tor-browser-build/master] Merge remote-tracking branch 'boklm/bug_31079_v2'
by gk@torproject.org 04 Jul '19
by gk@torproject.org 04 Jul '19
04 Jul '19
commit 142841696c055fff8b16e143cfe35609a6f0b223
Merge: f16f873 e5ed8e3
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Jul 4 20:05:10 2019 +0000
Merge remote-tracking branch 'boklm/bug_31079_v2'
keyring/firefox.gpg | Bin 2995 -> 2817 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
1
0

[tor-browser-build/master] Merge remote-tracking branch 'boklm/bug_30468'
by gk@torproject.org 04 Jul '19
by gk@torproject.org 04 Jul '19
04 Jul '19
commit f16f8734b4834eaccd4d2c9dc018084f766b60f9
Merge: b1ce9a7 7b1c46d
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Jul 4 20:01:53 2019 +0000
Merge remote-tracking branch 'boklm/bug_30468'
projects/firefox-locale-bundle/build | 2 ++
projects/firefox/build | 6 ++++--
rbm.conf | 1 +
3 files changed, 7 insertions(+), 2 deletions(-)
1
0

04 Jul '19
commit 86b5513abc35287d635855de7e2f1321358f9faf
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Jul 4 19:59:27 2019 +0000
Pick up Torbutton 2.2.1
---
toolkit/torproject/torbutton | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/toolkit/torproject/torbutton b/toolkit/torproject/torbutton
index fc5f85c225f7..cbf7172b5daa 160000
--- a/toolkit/torproject/torbutton
+++ b/toolkit/torproject/torbutton
@@ -1 +1 @@
-Subproject commit fc5f85c225f7518b078ca20457468e38a78430ad
+Subproject commit cbf7172b5daa49ab53542c7757a64ddbabb29dce
1
0
commit 123e2eb78f9b8922cd50a8fc68f0c15cb8354e0b
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Jul 4 16:49:16 2019 +0000
Translations update
---
src/chrome/locale/da/network-settings.dtd | 6 +++---
src/chrome/locale/da/torlauncher.properties | 8 ++++----
src/chrome/locale/fr/network-settings.dtd | 2 +-
src/chrome/locale/th/torlauncher.properties | 10 +++++-----
4 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/src/chrome/locale/da/network-settings.dtd b/src/chrome/locale/da/network-settings.dtd
index cdc10bd..52f89be 100644
--- a/src/chrome/locale/da/network-settings.dtd
+++ b/src/chrome/locale/da/network-settings.dtd
@@ -29,7 +29,7 @@
<!ENTITY torsettings.useProxy.type "Proxytype:">
<!ENTITY torsettings.useProxy.type.placeholder "vælg en proxytype">
<!ENTITY torsettings.useProxy.address "Adresse:">
-<!ENTITY torsettings.useProxy.address.placeholder "IP adresse eller værtsnavn">
+<!ENTITY torsettings.useProxy.address.placeholder "IP-adresse eller værtsnavn">
<!ENTITY torsettings.useProxy.port "Port:">
<!ENTITY torsettings.useProxy.username "Brugernavn:">
<!ENTITY torsettings.useProxy.password "Adgangskode:">
@@ -37,7 +37,7 @@
<!ENTITY torsettings.useProxy.type.socks5 "SOCKS 5">
<!ENTITY torsettings.useProxy.type.http "HTTP/HTTPS">
<!ENTITY torsettings.firewall.checkbox "Computeren går gennem en firewall som kun tillader forbindelse til bestemte porte">
-<!ENTITY torsettings.firewall.allowedPorts "Tilladte Porte:">
+<!ENTITY torsettings.firewall.allowedPorts "Tilladte porte:">
<!ENTITY torsettings.useBridges.checkbox "Tor er censureret i mit land">
<!ENTITY torsettings.useBridges.default "Vælg en indbygget bro">
<!ENTITY torsettings.useBridges.default.placeholder "vælg en bro">
@@ -54,7 +54,7 @@
<!ENTITY torsettings.proxyHelpTitle "Hjælp til proxy">
<!ENTITY torsettings.proxyHelp1 "Der kan være brug for en lokal proxy når der oprettes forbindelse gennem et netværk i virksomhed, skole eller universitet. Hvis du er i tvivl om der er brug for en proxy, så kig i internetindstillingerne i en anden browser eller tjek dit systems netværksindstillinger.">
-<!ENTITY torsettings.bridgeHelpTitle "Bro-relæ hjælp">
+<!ENTITY torsettings.bridgeHelpTitle "Hjælp til bro-relæ">
<!ENTITY torsettings.bridgeHelp1 "Broer er ulistede relæer som gør det sværrer at blokere forbindelser til Tor-netværket.  Hver type bro bruger en anderledes metode for at undgå censur.  Dem med obfs får din netværkstrafik til at ligne tilfældig støj og dem med meek får din netværkstrafik til at se ud som om den er forbundet til tjenesten i stedet for Tor.">
<!ENTITY torsettings.bridgeHelp2 "Pga. den måde bestemte lande prøver at blokere Tor, vil bestemte broer virke i nogle lande men ikke andre.  Besøg torproject.org/about/contact.html#support hvis du er i tvivl om hvilke broer der virker i dit land.">
diff --git a/src/chrome/locale/da/torlauncher.properties b/src/chrome/locale/da/torlauncher.properties
index 3046997..fd93c6d 100644
--- a/src/chrome/locale/da/torlauncher.properties
+++ b/src/chrome/locale/da/torlauncher.properties
@@ -22,7 +22,7 @@ torlauncher.failed_to_get_settings=Kan ikke hente Tor-indstillingerne..\n\n%S
torlauncher.failed_to_save_settings=Kan ikke gemme Tor-indstillingerne.\n\n%S
torlauncher.ensure_tor_is_running=Kontroller venligst at Tor kører.
-torlauncher.error_proxy_addr_missing=Du skal angive både IP adresse eller værts navn og en port, for at konfigurere Tor til at bruge en proxy som forbindelse til internettet.
+torlauncher.error_proxy_addr_missing=Du skal angive både IP-adresse eller værtsnavn og en port, for at konfigurere Tor til at bruge en proxy som forbindelse til internettet.
torlauncher.error_proxy_type_missing=Du skal vælge proxytypen:
torlauncher.error_bridges_missing=Du skal angive en eller flere broer.
torlauncher.error_default_bridges_type_missing=Du skal vælge en transporttype for de tildelte broer.
@@ -47,10 +47,10 @@ torlauncher.quit=Afslut
torlauncher.quit_win=Afslut
torlauncher.done=Færdig
-torlauncher.forAssistance=For hjælp, kontakt %S
-torlauncher.forAssistance2=For hjælp, besøg %S
+torlauncher.forAssistance=For at få hjælp, kontakt %S
+torlauncher.forAssistance2=For at få hjælp, besøg %S
-torlauncher.copiedNLogMessages=Kopieringen er gennemført. %S logbeskeder fra Tor er klar til at blive sat ind i et tekstdokument eller en e-mail.
+torlauncher.copiedNLogMessages=Kopieringen er gennemført. %S logbeskeder er klar til at blive indsæt i en tekstredigering eller en e-mail.
torlauncher.bootstrapStatus.starting=Starter
torlauncher.bootstrapStatus.conn_pt=Opretter forbindelse til bro
diff --git a/src/chrome/locale/fr/network-settings.dtd b/src/chrome/locale/fr/network-settings.dtd
index abbc13d..fd80e04 100644
--- a/src/chrome/locale/fr/network-settings.dtd
+++ b/src/chrome/locale/fr/network-settings.dtd
@@ -46,7 +46,7 @@
<!ENTITY torsettings.useBridges.reloadCaptcha.tooltip "Obtenir un nouveau test">
<!ENTITY torsettings.useBridges.captchaSubmit "Envoyer">
<!ENTITY torsettings.useBridges.custom "Utiliser un pont que je connais">
-<!ENTITY torsettings.useBridges.label "Saisir des informations de pont provenant d’une source fiable">
+<!ENTITY torsettings.useBridges.label "Saisir des renseignements de pont provenant d’une source fiable">
<!ENTITY torsettings.useBridges.placeholder "type adresse:port (un par ligne)">
<!ENTITY torsettings.copyLog "Copier le journal Tor dans le presse-papiers">
diff --git a/src/chrome/locale/th/torlauncher.properties b/src/chrome/locale/th/torlauncher.properties
index 3d587f1..5c97813 100644
--- a/src/chrome/locale/th/torlauncher.properties
+++ b/src/chrome/locale/th/torlauncher.properties
@@ -67,7 +67,7 @@ torlauncher.bootstrapStatus.loading_status=กำลังดึงข้อม
torlauncher.bootstrapStatus.loading_keys=กำลังดึง ใบรับรองสิทธิ
torlauncher.bootstrapStatus.requesting_descriptors=กำลังร้องขอข้อมูล relay
torlauncher.bootstrapStatus.loading_descriptors=กำลังดึงข้อมูล relay
-torlauncher.bootstrapStatus.enough_dirinfo=การโหลดข้อมูลrelay เสร็จสิ้น
+torlauncher.bootstrapStatus.enough_dirinfo=การโหลดข้อมูลรีเลย์ เสร็จสิ้น
torlauncher.bootstrapStatus.ap_conn_pt=กำลังสร้างวงจร: กำลังเชื่อมต่อกับสะพาน
torlauncher.bootstrapStatus.ap_conn_done_pt=กำลังสร้างวงจร: เชื่อมต่อกับสะพานแล้ว
torlauncher.bootstrapStatus.ap_conn_proxy=กำลังสร้างวงจร: กำลังเชื่อมต่อกับพร็อกซี
@@ -84,11 +84,11 @@ torlauncher.bootstrapWarning.connectrefused=ถูกปฏิเสธการ
torlauncher.bootstrapWarning.misc=เบ็ดเตล็ด
torlauncher.bootstrapWarning.resourcelimit=ทรัพยากรไม่เพียงพอ
torlauncher.bootstrapWarning.identity=ข้อมูลประจำตัวไม่ตรงกัน
-torlauncher.bootstrapWarning.timeout=นานเกินไปในการเชื่อมต่อ
-torlauncher.bootstrapWarning.noroute=หาเส้นทางไปหา host ไม่พบ
+torlauncher.bootstrapWarning.timeout=หมดเวลาสำหรับการเชื่อมต่อ
+torlauncher.bootstrapWarning.noroute=ไม่พบเส้นทางไปยัง host
torlauncher.bootstrapWarning.ioerror=อ่าน/เขียน ผิดพลาด
-torlauncher.bootstrapWarning.pt_missing=ที่เสียบสำหรับการขนส่งหายไป
+torlauncher.bootstrapWarning.pt_missing=ที่เสียบสำหรับการโอนถ่ายข้อมูลหายไป
torlauncher.nsresult.NS_ERROR_NET_RESET=การเชื่อมต่อกับเซิร์ฟเวอร์หายไป
-torlauncher.nsresult.NS_ERROR_CONNECTION_REFUSED=ไม่สามารถเชื่อมต่อกับเซิร์ฟเวอร์ได้.
+torlauncher.nsresult.NS_ERROR_CONNECTION_REFUSED=ไม่สามารถเชื่อมต่อกับเซิร์ฟเวอร์ได้
torlauncher.nsresult.NS_ERROR_PROXY_CONNECTION_REFUSED=ไม่สามารถเชื่อมต่อกับพร็อกซี
1
0
commit a5ea1aced958a6c566c5f643ae015aebdafcb32a
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Jul 4 16:49:57 2019 +0000
Release preparations for 0.2.19.2
Version bump
---
src/install.rdf | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/install.rdf b/src/install.rdf
index d78b9a8..9df9f31 100644
--- a/src/install.rdf
+++ b/src/install.rdf
@@ -7,7 +7,7 @@
<em:creator>The Tor Project, Inc.</em:creator>
<em:contributor>Pearl Crescent, LLC</em:contributor>
<em:id>tor-launcher(a)torproject.org</em:id>
- <em:version>0.2.19.1</em:version>
+ <em:version>0.2.19.2</em:version>
<em:multiprocessCompatible>true</em:multiprocessCompatible>
<em:homepageURL>https://www.torproject.org/projects/torbrowser.html</em:homepageURL>
<em:updateURL>data:text/plain,</em:updateURL>
1
0
commit 397253580d87f74447fe150f7336edcf4d816c79
Author: Georg Koppen <gk(a)torproject.org>
Date: Tue Jul 2 10:38:24 2019 +0000
Bug 30468: Add mk locale
---
src/chrome/content/network-settings.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/chrome/content/network-settings.js b/src/chrome/content/network-settings.js
index 7bcd52e..b39a194 100644
--- a/src/chrome/content/network-settings.js
+++ b/src/chrome/content/network-settings.js
@@ -321,6 +321,7 @@ function populateLocaleList(aLangPackAddons)
"ja" : "\u65e5\u672c\u8a9e",
"ka" : "\u10E5\u10D0\u10E0\u10D7\u10E3\u10DA\u10D8",
"ko" : "\ud55c\uad6d\uc5b4",
+ "mk" : "\u041c\u0430\u043a\u0435\u0434\u043e\u043d\u0441\u043a\u0438",
"nl" : "Nederlands",
"nb" : "Norsk bokmå\u0345l",
"pl" : "Polski",
1
0
commit cbf7172b5daa49ab53542c7757a64ddbabb29dce
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Jul 4 16:11:16 2019 +0000
Release preparations for 2.2.1
CHANGELOG update and version bump
---
src/CHANGELOG | 6 ++++++
src/install.rdf | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/CHANGELOG b/src/CHANGELOG
index e1b56304..ce95f237 100644
--- a/src/CHANGELOG
+++ b/src/CHANGELOG
@@ -1,3 +1,9 @@
+2.2.1
+ * Bug 30577: Add Fundraising Banner
+ * Bug 31041: Stop syncing network.cookie.lifetimePolicy
+ * Bug 30468: Add mk locale
+ * Translations update
+
2.2
* Bug 30469: Add ro translation
* Translations update
diff --git a/src/install.rdf b/src/install.rdf
index 2d855202..79a4a6db 100644
--- a/src/install.rdf
+++ b/src/install.rdf
@@ -6,7 +6,7 @@
<em:name>Torbutton</em:name>
<em:creator>Mike Perry</em:creator>
<em:id>torbutton(a)torproject.org</em:id>
- <em:version>2.2</em:version>
+ <em:version>2.2.1</em:version>
<em:multiprocessCompatible>true</em:multiprocessCompatible>
<em:homepageURL>https://www.torproject.org/projects/torbrowser.html.en</em:homepageURL>
<em:iconURL>chrome://torbutton/skin/tor.png</em:iconURL>
1
0

[tor-browser-build/master] Bug 31058: Pick up correct tor-android-service commit
by gk@torproject.org 04 Jul '19
by gk@torproject.org 04 Jul '19
04 Jul '19
commit b1ce9a7e79a9d75b1a6388a23bcff3afd64c06bf
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Jul 4 16:44:21 2019 +0000
Bug 31058: Pick up correct tor-android-service commit
---
projects/tor-android-service/config | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/projects/tor-android-service/config b/projects/tor-android-service/config
index e98f745..e269704 100644
--- a/projects/tor-android-service/config
+++ b/projects/tor-android-service/config
@@ -1,7 +1,7 @@
# vim: filetype=yaml sw=2
version: '[% c("abbrev") %]'
filename: '[% project %]-[% c("version") %]-[% c("var/build_id") %]'
-git_hash: 074285582eb6415431759738fcccc712d1e4bee3
+git_hash: f81e8f61fd83367aead34ae0ce3b397d2ed6a494
git_url: https://git.torproject.org/tor-android-service.git
git_submodule: 1
1
0
commit 016a6e44a67b5054c9d05b70d604ef4a62e56610
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Jul 4 16:07:52 2019 +0000
Translations update
---
src/chrome/locale/ka/aboutTor.dtd | 4 ++--
src/chrome/locale/mk/aboutTor.dtd | 3 +++
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/chrome/locale/ka/aboutTor.dtd b/src/chrome/locale/ka/aboutTor.dtd
index 3cdf164e..c7b5bbff 100644
--- a/src/chrome/locale/ka/aboutTor.dtd
+++ b/src/chrome/locale/ka/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "შეინარჩუნეთ Tor ძლიერი.">
<!ENTITY aboutTor.donationBanner.buttonA "გაიღეთ თანხა">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "ყოველთვიური შემოწირულობები მეტად აძლიერებს Tor-ს.">
+<!ENTITY aboutTor.donationBanner3.line2 "გახდით პირადულობის გუშაგი დღესვე!">
diff --git a/src/chrome/locale/mk/aboutTor.dtd b/src/chrome/locale/mk/aboutTor.dtd
index 551ad217..bb87e67c 100644
--- a/src/chrome/locale/mk/aboutTor.dtd
+++ b/src/chrome/locale/mk/aboutTor.dtd
@@ -30,3 +30,6 @@
<!ENTITY aboutTor.newsletter.link_text "Пријавете се за Tor Вести.">
<!ENTITY aboutTor.donationBanner.line2e "Чувај го Tor силен.">
<!ENTITY aboutTor.donationBanner.buttonA "Донирај сега">
+
+<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
+<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
1
0
commit 3ec6d04c3eeefb766fa1ad4d7e8de8da212863ce
Author: Georg Koppen <gk(a)torproject.org>
Date: Tue Jul 2 13:17:41 2019 +0000
Update mk localization
---
src/chrome/locale/mk/aboutDialog.dtd | 19 ++++++
src/chrome/locale/mk/aboutTBUpdate.dtd | 8 +++
src/chrome/locale/mk/aboutTor.dtd | 57 ++++++----------
src/chrome/locale/mk/brand.dtd | 11 +++-
src/chrome/locale/mk/brand.properties | 13 ++--
src/chrome/locale/mk/browserOnboarding.properties | 71 ++++++++++++++++++++
src/chrome/locale/mk/securityLevel.properties | 23 ++++++-
src/chrome/locale/mk/torbutton.dtd | 56 +++++++++++-----
src/chrome/locale/mk/torbutton.properties | 79 ++++++++++++++++-------
9 files changed, 252 insertions(+), 85 deletions(-)
diff --git a/src/chrome/locale/mk/aboutDialog.dtd b/src/chrome/locale/mk/aboutDialog.dtd
new file mode 100644
index 00000000..6fb30ffe
--- /dev/null
+++ b/src/chrome/locale/mk/aboutDialog.dtd
@@ -0,0 +1,19 @@
+<!ENTITY project.start "&brandShortName; е создаден од">
+<!-- LOCALIZATION NOTE (project.tpoLink): This is a link title that links to https://www.torproject.org -->
+<!ENTITY project.tpoLink "the &vendorShortName;">
+<!ENTITY project.end ", кој е непрофитен и кој работи за вашата онлајн приватност и слобода.">
+
+<!ENTITY help.start "Сакате да помогнете?">
+<!-- LOCALIZATION NOTE (help.donate): This is a link title that links to https://www.torproject.org/donate/donate.html.en -->
+<!ENTITY help.donateLink "Донирај">
+<!ENTITY help.or "или">
+<!-- LOCALIZATION NOTE (help.getInvolvedLink): This is a link title that links to https://www.torproject.org/getinvolved/volunteer.html.en -->
+<!ENTITY help.getInvolvedLink "приклучи се">
+<!ENTITY help.end "!">
+<!-- LOCALIZATION NOTE (bottom.questions): This is a link title that links to https://www.torproject.org/docs/trademark-faq.html.en -->
+<!ENTITY bottomLinks.questions "Прашања?">
+<!-- LOCALIZATION NOTE (bottom.questions): This is a link title that links to https://www.torproject.org/getinvolved/relays -->
+<!ENTITY bottomLinks.grow "Помогнете Тор мрежата да расте!">
+<!-- LOCALIZATION NOTE (bottom.questions): This is a link title that links to about:license -->
+<!ENTITY bottomLinks.license "Лиценца">
+<!ENTITY tor.TrademarkStatement "'Tor' и 'Onion Logo' се регистрирани трговски марки на Tor Project, Inc.">
diff --git a/src/chrome/locale/mk/aboutTBUpdate.dtd b/src/chrome/locale/mk/aboutTBUpdate.dtd
new file mode 100644
index 00000000..eb627510
--- /dev/null
+++ b/src/chrome/locale/mk/aboutTBUpdate.dtd
@@ -0,0 +1,8 @@
+<!ENTITY aboutTBUpdate.changelogTitle "Tor Browser Листа на промени">
+<!ENTITY aboutTBUpdate.updated "Tor Browser е ажуриран.">
+<!ENTITY aboutTBUpdate.linkPrefix "За најнови информации за оваа верзија,">
+<!ENTITY aboutTBUpdate.linkLabel "посетете ја нашата веб страна">
+<!ENTITY aboutTBUpdate.linkSuffix ".">
+<!ENTITY aboutTBUpdate.version "Верзија">
+<!ENTITY aboutTBUpdate.releaseDate "Датум на издавање">
+<!ENTITY aboutTBUpdate.releaseNotes "Забелешки за изданието">
diff --git a/src/chrome/locale/mk/aboutTor.dtd b/src/chrome/locale/mk/aboutTor.dtd
index 9f14022b..551ad217 100644
--- a/src/chrome/locale/mk/aboutTor.dtd
+++ b/src/chrome/locale/mk/aboutTor.dtd
@@ -1,47 +1,32 @@
<!--
- - Copyright (c) 2014, The Tor Project, Inc.
+ - Copyright (c) 2018, The Tor Project, Inc.
- See LICENSE for licensing information.
- vim: set sw=2 sts=2 ts=8 et syntax=xml:
-->
-<!ENTITY aboutTor.title "About Tor">
+<!ENTITY aboutTor.title "За Tor">
-<!ENTITY aboutTor.outOfDateTorOn.label "HOWEVER, this browser is out of date.">
-<!ENTITY aboutTor.outOfDateTorOff.label "ALSO, this browser is out of date.">
-<!ENTITY aboutTor.outOfDate2.label "Click on the onion and then choose Download Tor Browser Bundle Update.">
+<!ENTITY aboutTor.viewChangelog.label "Види Листа на промени">
-<!ENTITY aboutTor.check.label "Test Tor Network Settings">
+<!ENTITY aboutTor.ready.label "Истражувај. Приватно.">
+<!ENTITY aboutTor.ready2.label "Подготвени сте за најприватното прелистувачко искуство во светот.">
+<!ENTITY aboutTor.failure.label "Настана грешка!">
+<!ENTITY aboutTor.failure2.label "Tor не работи во овој прелистувач.">
-<!ENTITY aboutTor.success.label "Congratulations!">
-<!ENTITY aboutTor.success2.label "This browser is configured to use Tor.">
-<!ENTITY aboutTor.success3.label "You are now free to browse the Internet anonymously.">
-<!ENTITY aboutTor.failure.label "Something Went Wrong!">
-<!ENTITY aboutTor.failure2.label "Tor is not working in this browser.">
-<!ENTITY aboutTor.failure3prefix.label "For assistance, please contact ">
-<!ENTITY aboutTor.failure3Link "help(a)rt.torproject.org">
-<!ENTITY aboutTor.failure3suffix.label ".">
+<!ENTITY aboutTor.search.label "Пребарај со DuckDuckGo">
+<!ENTITY aboutTor.searchDDGPost.link "https://duckduckgo.com">
-<!ENTITY aboutTor.search.label "Search">
-<!ENTITY aboutTor.searchSPPost.link "https://startpage.com/do/search">
-<!ENTITY aboutTor.searchDDGPost.link "https://duckduckgo.com/html/">
+<!ENTITY aboutTor.torbrowser_user_manual_questions.label "Прашања?">
+<!ENTITY aboutTor.torbrowser_user_manual_link.label "Провери го Tor Browser Упатството »">
+<!-- The next two entities are used within the browser's Help menu. -->
+<!ENTITY aboutTor.torbrowser_user_manual.accesskey "М">
+<!ENTITY aboutTor.torbrowser_user_manual.label "Tor Browser Упатство">
-<!ENTITY aboutTor.torInfo1.label "Additional Info:">
-<!ENTITY aboutTor.torInfo2.label "Country & IP Address:">
-<!ENTITY aboutTor.torInfo3.label "Exit Node:">
-<!ENTITY aboutTor.torInfo4.label "This server does not log any information about visitors.">
-<!ENTITY aboutTor.whatnextQuestion.label "What Next?">
-<!ENTITY aboutTor.whatnextAnswer.label "Tor is NOT all you need to browse anonymously! You may need to change some of your browsing habits to ensure your identity stays safe.">
-<!ENTITY aboutTor.whatnext.label "Tips On Staying Anonymous »">
-<!ENTITY aboutTor.whatnext.link "https://www.torproject.org/download/download.html.en#warning">
-<!ENTITY aboutTor.helpInfo1.label "You Can Help!">
-<!ENTITY aboutTor.helpInfo2.label "There are many ways you can help make the Tor Network faster and stronger:">
-<!ENTITY aboutTor.helpInfo3.label "Run a Tor Relay Node »">
-<!ENTITY aboutTor.helpInfo3.link "https://www.torproject.org/docs/tor-doc-relay.html.en">
-<!ENTITY aboutTor.helpInfo4.label "Volunteer Your Services »">
-<!ENTITY aboutTor.helpInfo4.link "https://www.torproject.org/getinvolved/volunteer.html.en">
-<!ENTITY aboutTor.helpInfo5.label "Make a Donation »">
-<!ENTITY aboutTor.helpInfo5.link "https://www.torproject.org/donate/donate.html.en">
+<!ENTITY aboutTor.tor_mission.label "Tor Project е US 501(c)(3) не-профитна организација која ги унапредува човековите права и слободи со креирање и имплементирање на слободни и отворен-код технологии за анонимност и приватност, поддржувајќи ги нивната неограничена достапност и употреба, како и нивното понатамошно научно и популарно разбирање.">
+<!ENTITY aboutTor.getInvolved.label "Приклучете се »">
+<!ENTITY aboutTor.getInvolved.link "https://www.torproject.org/getinvolved/volunteer.html.en">
-<!ENTITY aboutTor.footer.label "The Tor Project is a US 501(c)(3) non-profit dedicated to the research, development, and education of online anonymity and privacy.">
-<!ENTITY aboutTor.learnMore.label "Learn more about The Tor Project »">
-<!ENTITY aboutTor.learnMore.link "https://www.torproject.org/about/overview.html.en">
+<!ENTITY aboutTor.newsletter.tagline "Добијте ги најновите вести од Tor директно во вашето сандаче.">
+<!ENTITY aboutTor.newsletter.link_text "Пријавете се за Tor Вести.">
+<!ENTITY aboutTor.donationBanner.line2e "Чувај го Tor силен.">
+<!ENTITY aboutTor.donationBanner.buttonA "Донирај сега">
diff --git a/src/chrome/locale/mk/brand.dtd b/src/chrome/locale/mk/brand.dtd
index 59f665e8..e5e6dca5 100644
--- a/src/chrome/locale/mk/brand.dtd
+++ b/src/chrome/locale/mk/brand.dtd
@@ -2,7 +2,14 @@
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<!ENTITY brandShorterName "Tor Browser">
<!ENTITY brandShortName "Tor Browser">
<!ENTITY brandFullName "Tor Browser">
-<!ENTITY vendorShortName "Tor Project">
-<!ENTITY trademarkInfo.part1 "Firefox and the Firefox logos are trademarks of the Mozilla Foundation.">
+<!ENTITY vendorShortName "Tor Browser">
+<!ENTITY trademarkInfo.part1 "Firefox и Firefox логоата се трговски марки на Mozilla Фондацијата.">
+
+<!-- The following strings are for bug #10280's UI. We place them here for our translators -->
+<!ENTITY plugins.installed.find "Кликни за вчитување на инсталираните системски приклучоци">
+<!ENTITY plugins.installed.enable "Овозможи приклучоци">
+<!ENTITY plugins.installed.disable "Оневозможи приклучоци">
+<!ENTITY plugins.installed.disable.tip "Кликни за запирање на вчитувањето на системските приклучоци">
diff --git a/src/chrome/locale/mk/brand.properties b/src/chrome/locale/mk/brand.properties
index f63def38..8ffcbdf0 100644
--- a/src/chrome/locale/mk/brand.properties
+++ b/src/chrome/locale/mk/brand.properties
@@ -2,14 +2,15 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+brandShorterName=Tor Browser
brandShortName=Tor Browser
brandFullName=Tor Browser
-vendorShortName=Tor Project
+vendorShortName=Tor Browser
-homePageSingleStartMain=Firefox Start, a fast home page with built-in search
-homePageImport=Import your home page from %S
+homePageSingleStartMain=Firefox Старт, брза домашна страница со вграден пребарувач
+homePageImport=Внесете ваша домаша страница од %S
-homePageMigrationPageTitle=Home Page Selection
-homePageMigrationDescription=Please select the home page you wish to use:
+homePageMigrationPageTitle=Избор на Домашна странција
+homePageMigrationDescription=Одберете домашна страница која сакате да ја користите:
-syncBrandShortName=Sync
+syncBrandShortName=Синхронизирај
diff --git a/src/chrome/locale/mk/browserOnboarding.properties b/src/chrome/locale/mk/browserOnboarding.properties
new file mode 100644
index 00000000..f7e732cc
--- /dev/null
+++ b/src/chrome/locale/mk/browserOnboarding.properties
@@ -0,0 +1,71 @@
+# Copyright (c) 2019, The Tor Project, Inc.
+# See LICENSE for licensing information.
+# vim: set sw=2 sts=2 ts=8 et:
+
+onboarding.tour-tor-welcome=Добредојдовте
+onboarding.tour-tor-welcome.title=Вие сте подготвени.
+onboarding.tour-tor-welcome.description=Tor Browser ви нуди највисок стандард на приватност и безбедност додека прелистувате на Интернет. Сега сте заштитени од следење, надзор и цензура. Ова брзо ќе ви покаже како.
+onboarding.tour-tor-welcome.next-button=Оди во Приватност
+
+onboarding.tour-tor-privacy=Приватност
+onboarding.tour-tor-privacy.title=Прескокнете ги следачите и водачите.
+onboarding.tour-tor-privacy.description=Tor Browser ги изолира колачињата и ја брише историјата на вашиот прелистувач после вашата сесија. Овие промени кои ја осигуруваат вашата приватност и безбедност се заштитени во прелистувачот. Кликнете на 'Tor Мрежа' за да научите како да се заштитите на мрежно ниво.
+onboarding.tour-tor-privacy.button=Одете на Tor Мрежа
+
+onboarding.tour-tor-network=Tor Мрежа
+onboarding.tour-tor-network.title=Патувајте низ децентрализираната мрежа.
+onboarding.tour-tor-network.description=Tor Browser ве поврзува на Tor мрежата одржувана од илјадници волонтери низ целиот свет. За разлика од VPN, овде нема место за неуспех или централизиран ентитет на кого треба да му верувате со цел да уживате приватност на Интернет.
+onboarding.tour-tor-network.button=Одете на Круг екранот
+
+onboarding.tour-tor-circuit-display=Круг екран
+onboarding.tour-tor-circuit-display.title=Видете ја вашата патека.
+onboarding.tour-tor-circuit-display.description=За секој домеин кој го посетувате, вашиот сообраќај е пренесуван и енкриптиран во круг преку три Tor релеа низ светот. Ниту една веб страна не знае од каде сте поврзани. Можете да побарате нов круг со кликање на 'Нов круг за оваа веб страна' на Круг екранот.
+onboarding.tour-tor-circuit-display.button=Види ја мојата патека
+onboarding.tour-tor-circuit-display.next-button=Оди во Безбедност
+
+onboarding.tour-tor-security=Безбедност
+onboarding.tour-tor-security.title=Изберете го вашето искуство.
+onboarding.tour-tor-security.description=Ние исто така ви овозможуваме дополнителни поставки за зголемување на безбедноста на вашиот прелистувач. Нашите безбедносни поставки ви овозможуваат да блокирате елементи кои можат да бидат користени да го нападнат вашиот компјутер. Кликнете подолу за да ги видите намените на различните опции.
+onboarding.tour-tor-security.description-suffix=Забелешка: Стандардно, NoScript и HTTPS Насекаде не се вклучени во лентата со алатки, но можете да ја прилагодувате вашата лента со алатки за истите да ги додадете.
+onboarding.tour-tor-security-level.button=Погледнете го вашето ниво на безбедност
+onboarding.tour-tor-security-level.next-button=Оди во Препораки од искуство
+
+onboarding.tour-tor-expect-differences=Препораки од искуство
+onboarding.tour-tor-expect-differences.title=Очекувајте некои разлики.
+onboarding.tour-tor-expect-differences.description=Со сите карактеристики за безбедност и приватност кои ви ги овозможува Tor, вашето искуство додека прелистувате на Интернет може да биде малку различно. Некои нешта можат да бидат побавни, и во зависност од вашето поставено ниво на безбедност, некои елементи можат да не работат или да не бидат вчитани воопшто. Исто така можете да бидете прашани да докажете дека сте човек, а не машина.
+onboarding.tour-tor-expect-differences.button=Види ЧПП
+onboarding.tour-tor-expect-differences.next-button=Оди во Onion услуги
+
+onboarding.tour-tor-onion-services=Onion Услуги
+onboarding.tour-tor-onion-services.title=Бидете екстра заштитени.
+onboarding.tour-tor-onion-services.description=Onion услугите се веб страни кои завршуваат со домеин .onion кој овозможува екстра заштити на издавачите и посетителите, вклучувајќи и додадени заштити против цензурата. Onion услугите му овозможуваат на секого да овозможи содржина и услуги анонимно. Кликнете подолу за да ја посетите onion веб страната DuckDuckGo.
+onboarding.tour-tor-onion-services.button=Посетете Onion
+onboarding.tour-tor-onion-services.next-button=Завршено
+
+onboarding.overlay-icon-tooltip-updated2=Видете што има ново\nво %S
+onboarding.tour-tor-update.prefix-new=Ново
+onboarding.tour-tor-update.prefix-updated=Ажурирано
+
+onboarding.tour-tor-toolbar=Лента со алатки
+onboarding.tour-tor-toolbar-update-8.5.title=Распоред на лентата со алатки
+onboarding.tour-tor-toolbar-update-8.5.description=Го подобривме распоредот на лентата со алатки на прелистувачот. Ја поместивме иконата Torbutton после URL барот, и додадовме икона за безбеносно ниво до неа.
+onboarding.tour-tor-toolbar-update-8.5.next-button=Оди во Безбедност
+
+onboarding.tour-tor-security-update-8.5.title=Искуство од безбедносно ниво
+onboarding.tour-tor-security-update-8.5.description=Го подобривме начинот на кој го гледате и поставувате вашето ниво на безбедност. Го заменивме лизгачот за безбедност со икона за лента со алатки која го прави моменталното ниво видливо цело време. Кликнете ја за да видете детали за вашето моментално ниво или да ги промените вашите поставки за безбедност.
+
+# Circuit Display onboarding.
+onboarding.tor-circuit-display.next=Следно
+onboarding.tor-circuit-display.done=Завршено
+onboarding.tor-circuit-display.one-of-three=1 од 3
+onboarding.tor-circuit-display.two-of-three=2 од 3
+onboarding.tor-circuit-display.three-of-three=3 од 3
+
+onboarding.tor-circuit-display.intro.title=Како работат заобиколувањата?
+onboarding.tor-circuit-display.intro.msg=Заобиколувањата се направени од релеа задолжени по случаен избор, кои се всушност компјутери низ целиот свет кои се конфигурирани да го препраќаат Tor сообраќајот. Заобиколувањата ви овозможуваат да прелистувате приватно и да се поврзувате на onion услуги.
+
+onboarding.tor-circuit-display.diagram.title=Круг екран
+onboarding.tor-circuit-display.diagram.msg=Овој дијаграм покажува релеа кои прават круг за оваа веб страна. За да превенирате поврзување на активност низ различни веб страни, секоја веб страна добива различен круг.
+
+onboarding.tor-circuit-display.new-circuit.title=Дали ви треба нов круг?
+onboarding.tor-circuit-display.new-circuit.msg=Ако не можете да се поврзете на веб страната која се обидувате да ја посетите или истата не се вчитува правилно, тогаш можете да го користите ова копче да ја вчитате отпочеток преку нов круг.
diff --git a/src/chrome/locale/mk/securityLevel.properties b/src/chrome/locale/mk/securityLevel.properties
index b6ceb35c..ad7824bc 100644
--- a/src/chrome/locale/mk/securityLevel.properties
+++ b/src/chrome/locale/mk/securityLevel.properties
@@ -1 +1,22 @@
-securityLevel.restoreDefaults = Стандардни подесувања
+securityLevel.securityLevel = Безбедносно ниво
+securityLevel.customWarning = Прилагодено
+securityLevel.overview = Оневозможи одредени веб можности кои можат да бидат користени за напад врз вашата безбедност и анонимност.
+securityLevel.standard.level = Стандардно
+securityLevel.standard.tooltip = Безбедносно ниво: Стандардно
+securityLevel.standard.summary = Сите можности на Tor Browser и веб страните се овозможени.
+securityLevel.safer.level = Побезбедно
+securityLevel.safer.tooltip = Безбедносно ниво: Побезбедно
+securityLevel.safer.summary = Оневозможува можности на веб страните кои често се опасни, сепак воедно предизвикувајќи некои веб страни да ја изгубат функционалноста.
+securityLevel.safer.description1 = JavaScript е оневозможен на не-HTTPS веб страните.
+securityLevel.safer.description2 = Некои фонтови и математички симболи се оневозможени.
+securityLevel.safer.description3 = Аудио и видео (HTML5 медиа), и WebGL се кликни-да-пуштиш.
+securityLevel.safest.level = Најбезбедно
+securityLevel.safest.tooltip = Безбедносно ниво: Најбезбедно
+securityLevel.safest.summary = Дозволува само можности на веб страните потребни за статичните страни и основните услужни сервиси. Овие измени влијаат на сликите, разни мултимедијални датотеки, и скрипти.
+securityLevel.safest.description1 = JavaScript е стандардно оневозможен на сите веб страни.
+securityLevel.safest.description2 = Некои фонтови, икони, математички симболи, и слики се оневозможени.
+securityLevel.safest.description3 = Аудиото и видеото (HTML5 мултимедијата) се кликни-да-почне.
+securityLevel.custom.summary = Вашите прилагодени својства на прелистувачот резултираа со невообичаени безбедносни поставки. Од причини поврзани со безбедноста и приватноста, ви препорачуваме да ги изберете почетните безбедносни нивоа.
+securityLevel.learnMore = Научи повеќе
+securityLevel.restoreDefaults = Врати на стандардно
+securityLevel.advancedSecuritySettings = Напредни Безбедносни Поставки
diff --git a/src/chrome/locale/mk/torbutton.dtd b/src/chrome/locale/mk/torbutton.dtd
index cc240827..1d7224aa 100644
--- a/src/chrome/locale/mk/torbutton.dtd
+++ b/src/chrome/locale/mk/torbutton.dtd
@@ -1,19 +1,41 @@
-<!ENTITY torbutton.context_menu.new_identity "New Identity">
+<!ENTITY torbutton.context_menu.new_identity "Нов идентитет">
<!ENTITY torbutton.context_menu.new_identity_key "I">
-<!ENTITY torbutton.context_menu.networksettings "Open Network Settings…">
-<!ENTITY torbutton.context_menu.downloadUpdate "Download Tor Browser Bundle Update...">
-<!ENTITY torbutton.context_menu.downloadUpdate.key "Z">
-<!ENTITY torbutton.context_menu.cookieProtections "Cookie Protections">
+<!ENTITY torbutton.context_menu.new_circuit "Нов Tor круг за оваа страна">
+<!ENTITY torbutton.context_menu.new_circuit_key "C">
+<!ENTITY torbutton.context_menu.networksettings "Тор мрежни поставки...">
+<!ENTITY torbutton.context_menu.networksettings.key "N">
+<!ENTITY torbutton.context_menu.downloadUpdate "Провери за нова верзија на Tor Browser...">
+<!ENTITY torbutton.context_menu.downloadUpdate.key "U">
+<!ENTITY torbutton.context_menu.cookieProtections "Заштита за колаче...">
<!ENTITY torbutton.context_menu.cookieProtections.key "C">
-<!ENTITY torbutton.button.tooltip "Кликнете за иницирање на Torbutton">
-<!ENTITY torbutton.cookiedialog.title "Manage Cookie Protections">
-<!ENTITY torbutton.cookiedialog.lockCol "Protected">
-<!ENTITY torbutton.cookiedialog.domainCol "Host">
-<!ENTITY torbutton.cookiedialog.nameCol "Name">
-<!ENTITY torbutton.cookiedialog.pathCol "Path">
-<!ENTITY torbutton.cookiedialog.protectCookie "Protect Cookie">
-<!ENTITY torbutton.cookiedialog.removeCookie "Remove Cookie">
-<!ENTITY torbutton.cookiedialog.unprotectCookie "Unprotect Cookie">
-<!ENTITY torbutton.cookiedialog.removeAllBut "Remove All But Protected">
-<!ENTITY torbutton.cookiedialog.saveAllCookies "Protect New Cookies">
-<!ENTITY torbutton.cookiedialog.doNotSaveAllCookies "Do Not Protect New Cookies">
+<!ENTITY torbutton.button.tooltip "Кликнете за иницијализирање на Torbutton">
+<!ENTITY torbutton.prefs.security_settings "Tor Browser безбедносни поставки">
+<!ENTITY torbutton.cookiedialog.title "Уреди ги заштитите за колаче">
+<!ENTITY torbutton.cookiedialog.lockCol "Заштитено">
+<!ENTITY torbutton.cookiedialog.domainCol "Хост">
+<!ENTITY torbutton.cookiedialog.nameCol "Име">
+<!ENTITY torbutton.cookiedialog.pathCol "Патека">
+<!ENTITY torbutton.cookiedialog.protectCookie "Заштити колаче">
+<!ENTITY torbutton.cookiedialog.removeCookie "Избриши колаче">
+<!ENTITY torbutton.cookiedialog.unprotectCookie "Отстрани заштита на колаче">
+<!ENTITY torbutton.cookiedialog.removeAllBut "Избриши ги сите освен заштитените">
+<!ENTITY torbutton.cookiedialog.saveAllCookies "Заштити ги новите колачиња">
+<!ENTITY torbutton.cookiedialog.doNotSaveAllCookies "Не ги штити новите колачиња">
+<!ENTITY torbutton.prefs.sec_caption "Безбедносно ниво">
+<!ENTITY torbutton.prefs.sec_caption_tooltip "Безбедносниот лизгач ви овозможува да исклучите дадени прелистувачки можности кои можат да го направат вашиот прелистувач поранлив на хакерски напади.">
+<!ENTITY torbutton.prefs.sec_standard_label "Стандардно">
+<!ENTITY torbutton.prefs.sec_standard_description "Сите можности на Tor Browser и веб страните се овозможени.">
+<!ENTITY torbutton.prefs.sec_safer_label "Побезбедно">
+<!ENTITY torbutton.prefs.sec_safer_description "Оневозможува можности на веб страните кои често се опасни, предизвикувајќи некои страни да ја изгубат функционалноста.">
+<!ENTITY torbutton.prefs.sec_safer_list_label "На побезбедна поставка:">
+<!ENTITY torbutton.prefs.sec_safest_label "Најбезбедно">
+<!ENTITY torbutton.prefs.sec_safest_description "Дозволува само можности на веб страните потребни за статичните страни и основните услужни сервиси. Овие измени влијаат на сликите, разни мултимедијални датотеки, и на скрптите.">
+<!ENTITY torbutton.prefs.sec_safest_list_label "На најбезбедна поставка:">
+<!ENTITY torbutton.prefs.sec_learn_more_label "Научи повеќе">
+<!ENTITY torbutton.prefs.sec_js_on_https_sites_only "JavaScript е оневозможен на не-HTTPS веб страните.">
+<!ENTITY torbutton.prefs.sec_js_disabled "JavaScript е стандардно оневозможен на сите веб страни.">
+<!ENTITY torbutton.prefs.sec_limit_typography "Некои фонтови и математички симболи се оневозможени.">
+<!ENTITY torbutton.prefs.sec_limit_graphics_and_typography "Некои фонтови, икони, математички симболи, и слики се оневозможени.">
+<!ENTITY torbutton.prefs.sec_click_to_play_media "Аудио и видео (HTML5 медиа), и WebGL се кликни-да-пуштиш.">
+<!ENTITY torbutton.circuit_display.title "Tor круг">
+<!ENTITY torbutton.circuit_display.new_circuit "Нов круг за оваа веб страна">
diff --git a/src/chrome/locale/mk/torbutton.properties b/src/chrome/locale/mk/torbutton.properties
index 7936dde4..898662af 100644
--- a/src/chrome/locale/mk/torbutton.properties
+++ b/src/chrome/locale/mk/torbutton.properties
@@ -1,27 +1,60 @@
-torbutton.panel.tooltip.disabled = Кликнете за да го вклучите Тор
-torbutton.panel.tooltip.enabled = Кликнете за да го исклучите Тор
-torbutton.panel.label.disabled = Тор е исклучен
-torbutton.panel.label.enabled = Тор е вклучен
-extensions.torbutton(a)torproject.org.description = Torbutton provides a button to configure Tor settings and quickly and easily clear private browsing data.
-torbutton.popup.external.title = Вчитување на екстерна содржина?
-torbutton.popup.external.app = Потребна е екстерна апликација за справување со:\n\n
-torbutton.popup.external.note = \n\nЗАБЕЛЕШКА: Екстерните апликации обично НЕ се свесни за Тор и можат да ве откријат!\n
-torbutton.popup.external.suggest = \nIf this file is untrusted, you should either save it to view while offline or in a VM,\nor consider using a transparent Tor proxy like Tails LiveCD or torsocks.\n
-torbutton.popup.launch = Лансирај ја апликацијата
-torbutton.popup.cancel = Откажи се
-torbutton.popup.dontask = Отсега натаму, секогаш лансирај ги апликациите
-torbutton.popup.prompted_language = To give you more privacy, Torbutton can request the English language version of web pages. This may cause web pages that you prefer to read in your native language to display in English instead.\n\nWould you like to request English language web pages for better privacy?
-torbutton.popup.no_newnym = Torbutton cannot safely give you a new identity. It does not have access to the Tor Control Port.\n\nAre you running Tor Browser Bundle?
-torbutton.title.prompt_torbrowser = Important Torbutton Information
-torbutton.popup.prompt_torbrowser = Torbutton works differently now: you can't turn it off any more.\n\nWe made this change because it isn't safe to use Torbutton in a browser that's also used for non-Tor browsing. There were too many bugs there that we couldn't fix any other way.\n\nIf you want to keep using Firefox normally, you should uninstall Torbutton and download Tor Browser Bundle. The privacy properties of Tor Browser are also superior to those of normal Firefox, even when Firefox is used with Torbutton.\n\nTo remove Torbutton, go to Tools->Addons->Extensions and then click the Remove button next to Torbutton.
-torbutton.popup.short_torbrowser = Important Torbutton Information!\n\nTorbutton is now always enabled.\n\nClick on the Torbutton for more information.
+torbutton.circuit_display.internet = Интернет
+torbutton.circuit_display.ip_unknown = IP непозната
+torbutton.circuit_display.onion_site = Onion веб страна
+torbutton.circuit_display.this_browser = Овој прелистувач
+torbutton.circuit_display.relay = Реле
+torbutton.circuit_display.tor_bridge = Мост
+torbutton.circuit_display.unknown_country = Непозната држава
+torbutton.circuit_display.guard = Чувар
+torbutton.circuit_display.guard_note = Твојот [Чувар] јазол може да не се промени.
+torbutton.circuit_display.learn_more = Научи повеќе
+torbutton.content_sizer.margin_tooltip = Tor Browser ја додава ова маргина за ширината и висината на вашиот прозорец да биде постандарден, со што се намалува можноста луѓето да ве следат онлајн.
+torbutton.panel.tooltip.disabled = Кликнете за да го овозможите Tor
+torbutton.panel.tooltip.enabled = Кликнете за да го оневозможите Tor
+torbutton.panel.label.disabled = Tor е оневозможен
+torbutton.panel.label.enabled = Tor е овозможен
+extensions.torbutton(a)torproject.org.description = Torbutton пружа копче за конфигурирање на Tor поставките и брзо и олеснето чисто приватно прелистување на податоци.
+torbutton.popup.external.title = Преземање на надворешна датотека?
+torbutton.popup.external.app = Tor прелистувачот не може да ја прикаже оваа датотека. Треба да ја отворите со друга апликација.\n\n
+torbutton.popup.external.note = Некои типови на датотеки можат да направат апликациите / програмите да се поврзат на Интернет без да користат Тор.\n\n
+torbutton.popup.external.suggest = Да би биле безбедни, единствено треба преземените датотеки да ги отворате додека сте исклучени од Интернет, или користејќи Tor бутирачкото ЦД како Tails.\n
+torbutton.popup.launch = Преземи датотека
+torbutton.popup.cancel = Откажи
+torbutton.popup.dontask = Автоматски преземај датотеки отсега па натаму
+torbutton.popup.no_newnym = Torbutton не може безбедно да ви даде нов идентитет. Нема пристап до Тор контролната порта.\n\nДали го користите Тор прелистувач-киот пакет?
+torbutton.security_settings.menu.title = Безбедносни подесувања
+torbutton.title.prompt_torbrowser = Важна Torbutton информација
+torbutton.popup.prompt_torbrowser = Torbutton работи поинаку сега: не може повеќе да биде исклучен.\n\nЈа направивме оваа промена, заота што не е безбедно да се користи Torbutton во прелистувач кој исто така се користи за не-Tor прелистување. Имаше премногу грешки и проблеми кои не можеа да бидат поправени на поинаков начин.\n\nАко сакате да продолжите да го користите Firefox стандардно, треба да го деинсталирате Torbutton и да го преземете Tor Browser пакетот. Приватните поставки на Tor Browser се помоќни од оние на стандардниот Firefox дури и кога Firefox се користи со Torbutton.\n\nЗа да го отрстранит
е Torbutton, одете во Алатки->Додатоци->Проширувања и кликнете на 'Отстрани' копчето до Torbutton.
+torbutton.popup.short_torbrowser = Важна Torbutton информација!\n\nTorbutton сега е секогаш вклучен.\n\nКликни на Torbutton за повеќе информации.
-torbutton.popup.confirm_plugins = Plugins such as Flash can harm your privacy and anonymity.\n\nThey can also bypass Tor to reveal your current location and IP address.\n\nAre you sure you want to enable plugins?\n\n
-torbutton.popup.never_ask_again = Never ask me again
+torbutton.popup.confirm_plugins = Приклучоците како Flash можат да ја повредат вашата приватност и анонимност.\n\nТие можат исто така да го заобиколат Tor и да ја откријат важата локација и IP адресата.\n\nДали сте сигурни дека сакате да ги овозможите приклучоците?\n\n
+torbutton.popup.never_ask_again = Не ме прашувај никогаш повеќе
+torbutton.popup.confirm_newnym = Tor Browser ќе ги затвори сите прозорци и табови. Сите веб сесии ќе бидат изгубени.\n\nРестартирајте го Tor Browser сега да го промените вашиот идентитет.\n\n
+
+torbutton.maximize_warning = Максимизирањето на Tor Browser дозволува на веб страните да ја утврдат големината на вашиот монитор, што пак може да се користи за ваше следење. Ви препорачуваме да ги оставите прозорците на Tor Browser во нивната оригинална големина.
# Canvas permission prompt. Strings are kept here for ease of translation.
-canvas.siteprompt=This website (%S) attempted to access image data on a canvas. Since canvas image data can be used to discover information about your computer, blank image data was returned this time.
-canvas.allow=Allow in the Future
-canvas.allowAccessKey=Z
-canvas.never=Never for This Site
+canvas.siteprompt=Оваа веб страна (%S) пробува да извлече HTML5 податоци, преку кои може уникатно да се идентифукува вашиот компјутер.\n\nТреба ли Tor Browser да и дозволи на оваа веб страна да ги извлече HTML5 податоците?
+canvas.notNow=Не сега
+canvas.notNowAccessKey=N
+canvas.allow=Дозволи во иднина
+canvas.allowAccessKey=A
+canvas.never=Никогаш за оваа веб страна (препорачано)
canvas.neverAccessKey=e
+
+# Profile/startup error messages. Strings are kept here for ease of translation.
+# LOCALIZATION NOTE: %S is the application name.
+profileProblemTitle=%S Профил проблем
+profileReadOnly=Не можете да го стартувате %S од систем без запишувачки привилегии. Копирајте %S на друга локација пред обид за користење.
+profileReadOnlyMac=Не можете да го стартувате %S од систем без запишувачки привилегии. Копирајте го %S на Работната површина или во Апликативната папка / Program Files.
+profileAccessDenied=%S нема дозвола да пристапи на профилот. Прилагодете ги системските привилегии на датотеката и обидете се повторно.
+profileMigrationFailed=Миграцијата на вашиот постоечки %S профил не успеа.\nНови поставки ќе бидат користени.
+
+# "Downloading update" string for the hamburger menu (see #28885).
+# This string is kept here for ease of translation.
+# LOCALIZATION NOTE: %S is the application name.
+updateDownloadingPanelUILabel=Преземање %S ажурирање
+
+# .Onion Page Info prompt. Strings are kept here for ease of translation.
+pageInfo_OnionEncryptionWithBitsAndProtocol=Енкриптирано поврзување (Onion Услуга, %1$S, %2$S битни клучеви, %3$S)
+pageInfo_OnionEncryption=Енкриптирано поврзување (Onion Услуга)
1
0
commit a6e66dfd822ca437c1ffeeb48ae6338f776d7681
Author: Georg Koppen <gk(a)torproject.org>
Date: Tue May 14 08:57:16 2019 +0000
Bug 30468: Add mk translation
---
trans_tools/import-translations.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/trans_tools/import-translations.sh b/trans_tools/import-translations.sh
index e52db02a..66c37ac7 100755
--- a/trans_tools/import-translations.sh
+++ b/trans_tools/import-translations.sh
@@ -2,7 +2,7 @@
# This var comes from the TBB locale list.
# XXX: Find some way to keep this, tor-launcher, and Tor Browser in sync
-BUNDLE_LOCALES="ar ca cs da de el es-AR es-ES fa fr ga-IE he hu id is it ja ka ko nb-NO nl pl pt-BR ro ru sv-SE tr vi zh-CN zh-TW"
+BUNDLE_LOCALES="ar ca cs da de el es-AR es-ES fa fr ga-IE he hu id is it ja ka ko nb-NO mk nl pl pt-BR ro ru sv-SE tr vi zh-CN zh-TW"
# XXX: Basque (eu) by request in #10687.
# This is not used for official builds, but should remain so Basque XPIs can be
1
0
commit 171b482609c7b8dc644150f4e83900bac715f071
Merge: 208b1131 3ec6d04c
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Jul 4 16:06:49 2019 +0000
Merge branch 'bug_30468_v4'
src/chrome/locale/mk/aboutDialog.dtd | 19 ++++++
src/chrome/locale/mk/aboutTBUpdate.dtd | 8 +++
src/chrome/locale/mk/aboutTor.dtd | 57 ++++++----------
src/chrome/locale/mk/brand.dtd | 11 +++-
src/chrome/locale/mk/brand.properties | 13 ++--
src/chrome/locale/mk/browserOnboarding.properties | 71 ++++++++++++++++++++
src/chrome/locale/mk/securityLevel.properties | 23 ++++++-
src/chrome/locale/mk/torbutton.dtd | 56 +++++++++++-----
src/chrome/locale/mk/torbutton.properties | 79 ++++++++++++++++-------
trans_tools/import-translations.sh | 2 +-
10 files changed, 253 insertions(+), 86 deletions(-)
1
0

[tor-browser-build/master] Merge remote-tracking branch 'richard/bug_27503'
by gk@torproject.org 04 Jul '19
by gk@torproject.org 04 Jul '19
04 Jul '19
commit b9696546f5416c79449a2f20044ae3ec9ee36e1b
Merge: 702bb68 25aa6ad
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Jul 4 15:51:11 2019 +0000
Merge remote-tracking branch 'richard/bug_27503'
projects/mingw-w64/27503.patch | 10660 +++++++++++++++++++++++++++++++++++++++
projects/mingw-w64/build | 3 +
projects/mingw-w64/config | 1 +
3 files changed, 10664 insertions(+)
1
0

[tor-browser-build/master] Bug 27503: add patch for fixed widl to mingw and update build/config to apply it
by gk@torproject.org 04 Jul '19
by gk@torproject.org 04 Jul '19
04 Jul '19
commit 25aa6ad4eb02c98d17e9f8f714aab22b5ce3b31e
Author: Richard Pospesel <richard(a)torproject.org>
Date: Thu Jun 6 18:08:48 2019 -0700
Bug 27503: add patch for fixed widl to mingw and update build/config to apply it
---
projects/mingw-w64/27503.patch | 10660 +++++++++++++++++++++++++++++++++++++++
projects/mingw-w64/build | 3 +
projects/mingw-w64/config | 1 +
3 files changed, 10664 insertions(+)
diff --git a/projects/mingw-w64/27503.patch b/projects/mingw-w64/27503.patch
new file mode 100644
index 0000000..f6bd197
--- /dev/null
+++ b/projects/mingw-w64/27503.patch
@@ -0,0 +1,10660 @@
+diff --git a/mingw-w64-tools/widl/src/client.c b/mingw-w64-tools/widl/src/client.c
+index a3b2bbb6..d27c6cad 100644
+--- a/mingw-w64-tools/widl/src/client.c
++++ b/mingw-w64-tools/widl/src/client.c
+@@ -20,7 +20,7 @@
+
+ #include "config.h"
+ #include "wine/port.h"
+-
++
+ #include <stdio.h>
+ #include <stdlib.h>
+ #ifdef HAVE_UNISTD_H
+@@ -34,7 +34,7 @@
+ #include "parser.h"
+ #include "header.h"
+
+-#include "widltypes.h"
++#include "typetree.h"
+ #include "typegen.h"
+ #include "expr.h"
+
+@@ -52,12 +52,13 @@ static void print_client( const char *format, ... )
+
+ static void write_client_func_decl( const type_t *iface, const var_t *func )
+ {
+- const char *callconv = get_attrp(func->type->attrs, ATTR_CALLCONV);
+- const var_list_t *args = type_get_function_args(func->type);
+- type_t *rettype = type_function_get_rettype(func->type);
++ const char *callconv = get_attrp(func->declspec.type->attrs, ATTR_CALLCONV);
++ const var_list_t *args = type_function_get_args(func->declspec.type);
++ const decl_spec_t *retdeclspec = type_function_get_retdeclspec(func->declspec.type);
+
+ if (!callconv) callconv = "__cdecl";
+- write_type_decl_left(client, rettype);
++ write_declspec_decl_left(client, retdeclspec);
++ if (func->declspec.funcspecifier == FUNCTION_SPECIFIER_INLINE) fprintf(client, " inline");
+ fprintf(client, " %s ", callconv);
+ fprintf(client, "%s%s(\n", prefix_client, get_name(func));
+ indent++;
+@@ -74,9 +75,9 @@ static void write_function_stub( const type_t *iface, const var_t *func,
+ {
+ unsigned char explicit_fc, implicit_fc;
+ int has_full_pointer = is_full_pointer_function(func);
+- var_t *retval = type_function_get_retval(func->type);
++ var_t *retval = type_function_get_retval(func->declspec.type);
+ const var_t *handle_var = get_func_handle_var( iface, func, &explicit_fc, &implicit_fc );
+- int has_ret = !is_void(retval->type);
++ int has_ret = !is_void(retval->declspec.type);
+
+ if (is_interpreted_func( iface, func ))
+ {
+@@ -97,7 +98,7 @@ static void write_function_stub( const type_t *iface, const var_t *func,
+ print_client("RPC_BINDING_HANDLE _Handle;\n");
+ }
+
+- if (has_ret && decl_indirect(retval->type))
++ if (has_ret && decl_indirect(retval->declspec.type))
+ {
+ print_client("void *_p_%s;\n", retval->name);
+ }
+@@ -136,7 +137,7 @@ static void write_function_stub( const type_t *iface, const var_t *func,
+ if (has_ret)
+ {
+ print_client("%s", "");
+- write_type_decl(client, retval->type, retval->name);
++ write_declspec_decl(client, &retval->declspec, retval->name);
+ fprintf(client, ";\n");
+ }
+ print_client("RPC_MESSAGE _RpcMessage;\n");
+@@ -147,7 +148,7 @@ static void write_function_stub( const type_t *iface, const var_t *func,
+ if (explicit_fc == FC_BIND_GENERIC)
+ print_client("__frame->%s = %s;\n", handle_var->name, handle_var->name );
+ }
+- if (has_ret && decl_indirect(retval->type))
++ if (has_ret && decl_indirect(retval->declspec.type))
+ {
+ print_client("__frame->_p_%s = &%s;\n", retval->name, retval->name);
+ }
+@@ -194,7 +195,7 @@ static void write_function_stub( const type_t *iface, const var_t *func,
+ /* if the context_handle attribute appears in the chain of types
+ * without pointers being followed, then the context handle must
+ * be direct, otherwise it is a pointer */
+- int is_ch_ptr = !is_aliaschain_attr(handle_var->type, ATTR_CONTEXTHANDLE);
++ int is_ch_ptr = !is_aliaschain_attr(handle_var->declspec.type, ATTR_CONTEXTHANDLE);
+ print_client("if (%s%s != 0)\n", is_ch_ptr ? "*" : "", handle_var->name);
+ indent++;
+ print_client("__frame->_Handle = NDRCContextBinding(%s%s);\n",
+@@ -257,9 +258,9 @@ static void write_function_stub( const type_t *iface, const var_t *func,
+ /* unmarshal return value */
+ if (has_ret)
+ {
+- if (decl_indirect(retval->type))
++ if (decl_indirect(retval->declspec.type))
+ print_client("MIDL_memset(&%s, 0, sizeof(%s));\n", retval->name, retval->name);
+- else if (is_ptr(retval->type) || is_array(retval->type))
++ else if (is_ptr(retval->declspec.type) || is_array(retval->declspec.type))
+ print_client("%s = 0;\n", retval->name);
+ write_remoting_arguments(client, indent, func, "", PASS_RETURN, PHASE_UNMARSHAL);
+ }
+@@ -291,7 +292,7 @@ static void write_serialize_function(FILE *file, const type_t *type, const type_
+ const char *func_name, const char *ret_type)
+ {
+ enum stub_mode mode = get_stub_mode();
+- static int emited_pickling_info;
++ static int emitted_pickling_info;
+
+ if (iface && !type->typestring_offset)
+ {
+@@ -301,7 +302,7 @@ static void write_serialize_function(FILE *file, const type_t *type, const type_
+ return;
+ }
+
+- if (!emited_pickling_info && iface && mode != MODE_Os)
++ if (!emitted_pickling_info && iface && mode != MODE_Os)
+ {
+ fprintf(file, "static const MIDL_TYPE_PICKLING_INFO __MIDL_TypePicklingInfo =\n");
+ fprintf(file, "{\n");
+@@ -312,7 +313,7 @@ static void write_serialize_function(FILE *file, const type_t *type, const type_
+ fprintf(file, " 0\n");
+ fprintf(file, "};\n");
+ fprintf(file, "\n");
+- emited_pickling_info = 1;
++ emitted_pickling_info = 1;
+ }
+
+ /* FIXME: Assuming explicit handle */
+@@ -365,8 +366,8 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
+ case STMT_DECLARATION:
+ {
+ const var_t *func = stmt->u.var;
+- if (stmt->u.var->stgclass != STG_NONE
+- || type_get_type_detect_alias(stmt->u.var->type) != TYPE_FUNCTION)
++ if (stmt->u.var->declspec.stgclass != STG_NONE
++ || type_get_type_detect_alias(stmt->u.var->declspec.type) != TYPE_FUNCTION)
+ continue;
+ write_function_stub( iface, func, method_count++, *proc_offset );
+ *proc_offset += get_size_procformatstring_func( iface, func );
+@@ -425,7 +426,7 @@ static void write_stubdescriptor(type_t *iface, int expr_eval_routines)
+ print_client("1, /* -error bounds_check flag */\n");
+ print_client("0x%x, /* Ndr library version */\n", get_stub_mode() == MODE_Oif ? 0x50002 : 0x10001);
+ print_client("0,\n");
+- print_client("0x50100a4, /* MIDL Version 5.1.164 */\n");
++ print_client("0x50200ca, /* MIDL Version 5.2.202 */\n");
+ print_client("0,\n");
+ print_client("%s,\n", list_empty(&user_type_list) ? "0" : "UserMarshalRoutines");
+ print_client("0, /* notify & notify_flag routine table */\n");
+@@ -488,7 +489,7 @@ static void write_implicithandledecl(type_t *iface)
+
+ if (implicit_handle)
+ {
+- write_type_decl( client, implicit_handle->type, implicit_handle->name );
++ write_declspec_decl( client, &implicit_handle->declspec, implicit_handle->name );
+ fprintf(client, ";\n\n");
+ }
+ }
+@@ -532,8 +533,8 @@ static void write_client_ifaces(const statement_list_t *stmts, int expr_eval_rou
+
+ LIST_FOR_EACH_ENTRY(stmt2, type_iface_get_stmts(iface), const statement_t, entry)
+ {
+- if (stmt2->type == STMT_DECLARATION && stmt2->u.var->stgclass == STG_NONE &&
+- type_get_type_detect_alias(stmt2->u.var->type) == TYPE_FUNCTION)
++ if (stmt2->type == STMT_DECLARATION && stmt2->u.var->declspec.stgclass == STG_NONE &&
++ type_get_type_detect_alias(stmt2->u.var->declspec.type) == TYPE_FUNCTION)
+ {
+ needs_stub = 1;
+ break;
+@@ -627,26 +628,6 @@ void write_client(const statement_list_t *stmts)
+ if (!client)
+ return;
+
+- if (do_win32 && do_win64)
+- {
+- fprintf(client, "#ifndef _WIN64\n\n");
+- pointer_size = 4;
+- write_client_routines( stmts );
+- fprintf(client, "\n#else /* _WIN64 */\n\n");
+- pointer_size = 8;
+- write_client_routines( stmts );
+- fprintf(client, "\n#endif /* _WIN64 */\n");
+- }
+- else if (do_win32)
+- {
+- pointer_size = 4;
+- write_client_routines( stmts );
+- }
+- else if (do_win64)
+- {
+- pointer_size = 8;
+- write_client_routines( stmts );
+- }
+-
++ write_client_routines( stmts );
+ fclose(client);
+ }
+diff --git a/mingw-w64-tools/widl/src/expr.c b/mingw-w64-tools/widl/src/expr.c
+index 2ed4aff6..2f075816 100644
+--- a/mingw-w64-tools/widl/src/expr.c
++++ b/mingw-w64-tools/widl/src/expr.c
+@@ -194,10 +194,10 @@ expr_t *make_exprt(enum expr_type type, var_t *var, expr_t *expr)
+ expr_t *e;
+ type_t *tref;
+
+- if (var->stgclass != STG_NONE && var->stgclass != STG_REGISTER)
++ if (var->declspec.stgclass != STG_NONE && var->declspec.stgclass != STG_REGISTER)
+ error_loc("invalid storage class for type expression\n");
+
+- tref = var->type;
++ tref = var->declspec.type;
+
+ e = xmalloc(sizeof(expr_t));
+ e->type = type;
+@@ -474,7 +474,7 @@ static type_t *find_identifier(const char *identifier, const type_t *cont_type,
+ if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
+ if (field->name && !strcmp(identifier, field->name))
+ {
+- type = field->type;
++ type = field->declspec.type;
+ *found_in_cont_type = 1;
+ break;
+ }
+@@ -482,7 +482,7 @@ static type_t *find_identifier(const char *identifier, const type_t *cont_type,
+ if (!type)
+ {
+ var_t *const_var = find_const(identifier, 0);
+- if (const_var) type = const_var->type;
++ if (const_var) type = const_var->declspec.type;
+ }
+
+ return type;
+@@ -521,11 +521,11 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
+ break;
+ case EXPR_STRLIT:
+ result.is_temporary = TRUE;
+- result.type = type_new_pointer(FC_UP, type_new_int(TYPE_BASIC_CHAR, 0), NULL);
++ result.type = type_new_pointer(FC_UP, type_new_int(TYPE_BASIC_CHAR, 0));
+ break;
+ case EXPR_WSTRLIT:
+ result.is_temporary = TRUE;
+- result.type = type_new_pointer(FC_UP, type_new_int(TYPE_BASIC_WCHAR, 0), NULL);
++ result.type = type_new_pointer(FC_UP, type_new_int(TYPE_BASIC_WCHAR, 0));
+ break;
+ case EXPR_CHARCONST:
+ result.is_temporary = TRUE;
+@@ -575,15 +575,15 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
+ expr_loc->attr ? expr_loc->attr : "");
+ result.is_variable = FALSE;
+ result.is_temporary = TRUE;
+- result.type = type_new_pointer(FC_UP, result.type, NULL);
++ result.type = type_new_pointer(FC_UP, result.type);
+ break;
+ case EXPR_PPTR:
+ result = resolve_expression(expr_loc, cont_type, e->ref);
+ if (result.type && is_ptr(result.type))
+- result.type = type_pointer_get_ref(result.type);
++ result.type = type_pointer_get_ref_type(result.type);
+ else if(result.type && is_array(result.type)
+ && type_array_is_decl_as_ptr(result.type))
+- result.type = type_array_get_element(result.type);
++ result.type = type_array_get_element_type(result.type);
+ else
+ error_loc_info(&expr_loc->v->loc_info, "dereference operator applied to non-pointer type in expression%s%s\n",
+ expr_loc->attr ? " for attribute " : "",
+@@ -665,7 +665,7 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
+ if (result.type && is_array(result.type))
+ {
+ struct expression_type index_result;
+- result.type = type_array_get_element(result.type);
++ result.type = type_array_get_element_type(result.type);
+ index_result = resolve_expression(expr_loc, cont_type /* FIXME */, e->u.ext);
+ if (!index_result.type || !is_integer_type(index_result.type))
+ error_loc_info(&expr_loc->v->loc_info, "array subscript not of integral type in expression%s%s\n",
+diff --git a/mingw-w64-tools/widl/src/header.c b/mingw-w64-tools/widl/src/header.c
+index defc7f85..d0d0dc4b 100644
+--- a/mingw-w64-tools/widl/src/header.c
++++ b/mingw-w64-tools/widl/src/header.c
+@@ -43,7 +43,7 @@ user_type_list_t user_type_list = LIST_INIT(user_type_list);
+ context_handle_list_t context_handle_list = LIST_INIT(context_handle_list);
+ generic_handle_list_t generic_handle_list = LIST_INIT(generic_handle_list);
+
+-static void write_type_def_or_decl(FILE *f, type_t *t, int field, const char *name);
++static void write_type_v(FILE *h, const decl_spec_t *ds, int is_field, int declonly, const char *name);
+
+ static void indent(FILE *h, int delta)
+ {
+@@ -69,15 +69,15 @@ int is_ptrchain_attr(const var_t *var, enum attr_type t)
+ return 1;
+ else
+ {
+- type_t *type = var->type;
++ type_t *type = var->declspec.type;
+ for (;;)
+ {
+ if (is_attr(type->attrs, t))
+ return 1;
+ else if (type_is_alias(type))
+- type = type_alias_get_aliasee(type);
++ type = type_alias_get_aliasee_type(type);
+ else if (is_ptr(type))
+- type = type_pointer_get_ref(type);
++ type = type_pointer_get_ref_type(type);
+ else return 0;
+ }
+ }
+@@ -91,7 +91,7 @@ int is_aliaschain_attr(const type_t *type, enum attr_type attr)
+ if (is_attr(t->attrs, attr))
+ return 1;
+ else if (type_is_alias(t))
+- t = type_alias_get_aliasee(t);
++ t = type_alias_get_aliasee_type(t);
+ else return 0;
+ }
+ }
+@@ -204,9 +204,9 @@ static void write_fields(FILE *h, var_list_t *fields)
+ if (!fields) return;
+
+ LIST_FOR_EACH_ENTRY( v, fields, var_t, entry ) {
+- if (!v || !v->type) continue;
++ if (!v || !v->declspec.type) continue;
+
+- switch(type_get_type_detect_alias(v->type)) {
++ switch(type_get_type_detect_alias(v->declspec.type)) {
+ case TYPE_STRUCT:
+ case TYPE_ENCAPSULATED_UNION:
+ nameless_struct_cnt++;
+@@ -220,12 +220,12 @@ static void write_fields(FILE *h, var_list_t *fields)
+ }
+
+ LIST_FOR_EACH_ENTRY( v, fields, var_t, entry ) {
+- if (!v || !v->type) continue;
++ if (!v || !v->declspec.type) continue;
+
+ indent(h, 0);
+ name = v->name;
+
+- switch(type_get_type_detect_alias(v->type)) {
++ switch(type_get_type_detect_alias(v->declspec.type)) {
+ case TYPE_STRUCT:
+ case TYPE_ENCAPSULATED_UNION:
+ if(!v->name) {
+@@ -252,7 +252,7 @@ static void write_fields(FILE *h, var_list_t *fields)
+ default:
+ ;
+ }
+- write_type_def_or_decl(h, v->type, TRUE, name);
++ write_type_v(h, &v->declspec, TRUE, v->declonly, name);
+ fprintf(h, ";\n");
+ }
+ }
+@@ -295,14 +295,21 @@ static void write_pointer_left(FILE *h, type_t *ref)
+ }
+
+ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
++{
++ decl_spec_t ds;
++ write_declspec_left(h, init_declspec(&ds, t), name_type, declonly);
++}
++
++void write_declspec_left(FILE* h, const decl_spec_t *ds, enum name_type name_type, int declonly)
+ {
+ const char *name;
++ type_t *t = ds->type;
+
+ if (!h) return;
+
+ name = type_get_name(t, name_type);
+
+- if (is_attr(t->attrs, ATTR_CONST) &&
++ if ((ds->typequalifier == TYPE_QUALIFIER_CONST) &&
+ (type_is_alias(t) || !is_ptr(t)))
+ fprintf(h, "const ");
+
+@@ -310,7 +317,7 @@ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
+ else {
+ switch (type_get_type_detect_alias(t)) {
+ case TYPE_ENUM:
+- if (!declonly && t->defined && !t->written) {
++ if (!declonly && type_is_defined(t) && !t->written) {
+ if (name) fprintf(h, "enum %s {\n", name);
+ else fprintf(h, "enum {\n");
+ t->written = TRUE;
+@@ -323,7 +330,7 @@ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
+ break;
+ case TYPE_STRUCT:
+ case TYPE_ENCAPSULATED_UNION:
+- if (!declonly && t->defined && !t->written) {
++ if (!declonly && type_is_defined(t) && !t->written) {
+ if (name) fprintf(h, "struct %s {\n", name);
+ else fprintf(h, "struct {\n");
+ t->written = TRUE;
+@@ -338,7 +345,7 @@ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
+ else fprintf(h, "struct %s", name ? name : "");
+ break;
+ case TYPE_UNION:
+- if (!declonly && t->defined && !t->written) {
++ if (!declonly && type_is_defined(t) && !t->written) {
+ if (t->name) fprintf(h, "union %s {\n", t->name);
+ else fprintf(h, "union {\n");
+ t->written = TRUE;
+@@ -351,9 +358,9 @@ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
+ break;
+ case TYPE_POINTER:
+ {
+- write_type_left(h, type_pointer_get_ref(t), name_type, declonly);
+- write_pointer_left(h, type_pointer_get_ref(t));
+- if (is_attr(t->attrs, ATTR_CONST)) fprintf(h, "const ");
++ write_declspec_left(h, type_pointer_get_ref(t), name_type, declonly);
++ write_pointer_left(h, type_pointer_get_ref_type(t));
++ if (ds->typequalifier == TYPE_QUALIFIER_CONST) fprintf(h, "const ");
+ break;
+ }
+ case TYPE_ARRAY:
+@@ -361,9 +368,9 @@ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
+ fprintf(h, "%s", t->name);
+ else
+ {
+- write_type_left(h, type_array_get_element(t), name_type, declonly);
++ write_declspec_left(h, type_array_get_element(t), name_type, declonly);
+ if (type_array_is_decl_as_ptr(t))
+- write_pointer_left(h, type_array_get_element(t));
++ write_pointer_left(h, type_array_get_element_type(t));
+ }
+ break;
+ case TYPE_BASIC:
+@@ -443,7 +450,7 @@ void write_type_right(FILE *h, type_t *t, int is_field)
+ {
+ case TYPE_ARRAY:
+ {
+- type_t *elem = type_array_get_element(t);
++ type_t *elem = type_array_get_element_type(t);
+ if (type_array_is_decl_as_ptr(t))
+ {
+ if (!type_is_alias(elem) && is_array(elem) && !type_array_is_decl_as_ptr(elem))
+@@ -461,7 +468,7 @@ void write_type_right(FILE *h, type_t *t, int is_field)
+ }
+ case TYPE_POINTER:
+ {
+- type_t *ref = type_pointer_get_ref(t);
++ type_t *ref = type_pointer_get_ref_type(t);
+ if (!type_is_alias(ref) && is_array(ref) && !type_array_is_decl_as_ptr(ref))
+ fprintf(h, ")");
+ write_type_right(h, ref, FALSE);
+@@ -485,30 +492,33 @@ void write_type_right(FILE *h, type_t *t, int is_field)
+ }
+ }
+
+-static void write_type_v(FILE *h, type_t *t, int is_field, int declonly, const char *name)
++static void write_type_v(FILE *h, const decl_spec_t *ds, int is_field, int declonly, const char *name)
+ {
++ type_t *t = ds->type;
+ type_t *pt = NULL;
+ int ptr_level = 0;
+
+ if (!h) return;
+
+ if (t) {
+- for (pt = t; is_ptr(pt); pt = type_pointer_get_ref(pt), ptr_level++)
++ const decl_spec_t *dpt = NULL;
++ for (dpt = ds; is_ptr(dpt->type); dpt = type_pointer_get_ref(dpt->type), ptr_level++)
+ ;
++ pt = dpt->type;
+
+ if (type_get_type_detect_alias(pt) == TYPE_FUNCTION) {
+ int i;
+ const char *callconv = get_attrp(pt->attrs, ATTR_CALLCONV);
+ if (!callconv && is_object_interface) callconv = "STDMETHODCALLTYPE";
+- if (is_attr(pt->attrs, ATTR_INLINE)) fprintf(h, "inline ");
+- write_type_left(h, type_function_get_rettype(pt), NAME_DEFAULT, declonly);
++ if (!is_ptr(ds->type) && dpt->funcspecifier == FUNCTION_SPECIFIER_INLINE) fprintf(h, "inline ");
++ write_declspec_left(h, type_function_get_retdeclspec(pt), NAME_DEFAULT, declonly);
+ fputc(' ', h);
+ if (ptr_level) fputc('(', h);
+ if (callconv) fprintf(h, "%s ", callconv);
+ for (i = 0; i < ptr_level; i++)
+ fputc('*', h);
+ } else
+- write_type_left(h, t, NAME_DEFAULT, declonly);
++ write_declspec_left(h, ds, NAME_DEFAULT, declonly);
+ }
+
+ if (name) fprintf(h, "%s%s", !t || needs_space_after(t) ? " " : "", name );
+@@ -529,12 +539,7 @@ static void write_type_v(FILE *h, type_t *t, int is_field, int declonly, const c
+ }
+ }
+
+-static void write_type_def_or_decl(FILE *f, type_t *t, int field, const char *name)
+-{
+- write_type_v(f, t, field, FALSE, name);
+-}
+-
+-static void write_type_definition(FILE *f, type_t *t)
++static void write_type_definition(FILE *f, type_t *t, int declonly)
+ {
+ int in_namespace = t->namespace && !is_global_namespace(t->namespace);
+ int save_written = t->written;
+@@ -545,14 +550,14 @@ static void write_type_definition(FILE *f, type_t *t)
+ write_namespace_start(f, t->namespace);
+ }
+ indent(f, 0);
+- write_type_left(f, t, NAME_DEFAULT, FALSE);
++ write_type_left(f, t, NAME_DEFAULT, declonly);
+ fprintf(f, ";\n");
+ if(in_namespace) {
+ t->written = save_written;
+ write_namespace_end(f, t->namespace);
+ fprintf(f, "extern \"C\" {\n");
+ fprintf(f, "#else\n");
+- write_type_left(f, t, NAME_C, FALSE);
++ write_type_left(f, t, NAME_C, declonly);
+ fprintf(f, ";\n");
+ fprintf(f, "#endif\n\n");
+ }
+@@ -560,12 +565,18 @@ static void write_type_definition(FILE *f, type_t *t)
+
+ void write_type_decl(FILE *f, type_t *t, const char *name)
+ {
+- write_type_v(f, t, FALSE, TRUE, name);
++ decl_spec_t ds;
++ write_declspec_decl(f, init_declspec(&ds, t), name);
++}
++
++void write_declspec_decl(FILE *f, const decl_spec_t *ds, const char *name)
++{
++ write_type_v(f, ds, FALSE, TRUE, name);
+ }
+
+-void write_type_decl_left(FILE *f, type_t *t)
++void write_declspec_decl_left(FILE *f, const decl_spec_t *ds)
+ {
+- write_type_left(f, t, NAME_DEFAULT, TRUE);
++ write_declspec_left(f, ds, NAME_DEFAULT, TRUE);
+ }
+
+ static int user_type_registered(const char *name)
+@@ -602,8 +613,8 @@ unsigned int get_context_handle_offset( const type_t *type )
+
+ while (!is_attr( type->attrs, ATTR_CONTEXTHANDLE ))
+ {
+- if (type_is_alias( type )) type = type_alias_get_aliasee( type );
+- else if (is_ptr( type )) type = type_pointer_get_ref( type );
++ if (type_is_alias( type )) type = type_alias_get_aliasee_type( type );
++ else if (is_ptr( type )) type = type_pointer_get_ref_type( type );
+ else error( "internal error: %s is not a context handle\n", type->name );
+ }
+ LIST_FOR_EACH_ENTRY( ch, &context_handle_list, context_handle_t, entry )
+@@ -622,8 +633,8 @@ unsigned int get_generic_handle_offset( const type_t *type )
+
+ while (!is_attr( type->attrs, ATTR_HANDLE ))
+ {
+- if (type_is_alias( type )) type = type_alias_get_aliasee( type );
+- else if (is_ptr( type )) type = type_pointer_get_ref( type );
++ if (type_is_alias( type )) type = type_alias_get_aliasee_type( type );
++ else if (is_ptr( type )) type = type_pointer_get_ref_type( type );
+ else error( "internal error: %s is not a generic handle\n", type->name );
+ }
+ LIST_FOR_EACH_ENTRY( gh, &generic_handle_list, generic_handle_t, entry )
+@@ -637,82 +648,77 @@ unsigned int get_generic_handle_offset( const type_t *type )
+
+ /* check for types which require additional prototypes to be generated in the
+ * header */
+-void check_for_additional_prototype_types(const var_list_t *list)
+-{
+- const var_t *v;
+-
+- if (!list) return;
+- LIST_FOR_EACH_ENTRY( v, list, const var_t, entry )
+- {
+- type_t *type = v->type;
+- if (!type) continue;
+- for (;;) {
+- const char *name = type->name;
+- if (type->user_types_registered) break;
+- type->user_types_registered = 1;
+- if (is_attr(type->attrs, ATTR_CONTEXTHANDLE)) {
+- if (!context_handle_registered(name))
+- {
+- context_handle_t *ch = xmalloc(sizeof(*ch));
+- ch->name = xstrdup(name);
+- list_add_tail(&context_handle_list, &ch->entry);
+- }
+- /* don't carry on parsing fields within this type */
+- break;
+- }
+- if ((type_get_type(type) != TYPE_BASIC ||
+- type_basic_get_type(type) != TYPE_BASIC_HANDLE) &&
+- is_attr(type->attrs, ATTR_HANDLE)) {
+- if (!generic_handle_registered(name))
+- {
+- generic_handle_t *gh = xmalloc(sizeof(*gh));
+- gh->name = xstrdup(name);
+- list_add_tail(&generic_handle_list, &gh->entry);
+- }
+- /* don't carry on parsing fields within this type */
+- break;
++void check_for_additional_prototype_types(type_t *type)
++{
++ if (!type) return;
++ for (;;) {
++ const char *name = type->name;
++ if (type->user_types_registered) break;
++ type->user_types_registered = 1;
++ if (is_attr(type->attrs, ATTR_CONTEXTHANDLE)) {
++ if (!context_handle_registered(name))
++ {
++ context_handle_t *ch = xmalloc(sizeof(*ch));
++ ch->name = xstrdup(name);
++ list_add_tail(&context_handle_list, &ch->entry);
+ }
+- if (is_attr(type->attrs, ATTR_WIREMARSHAL)) {
+- if (!user_type_registered(name))
+- {
+- user_type_t *ut = xmalloc(sizeof *ut);
+- ut->name = xstrdup(name);
+- list_add_tail(&user_type_list, &ut->entry);
+- }
+- /* don't carry on parsing fields within this type as we are already
+- * using a wire marshaled type */
+- break;
++ /* don't carry on parsing fields within this type */
++ break;
++ }
++ if ((type_get_type(type) != TYPE_BASIC ||
++ type_basic_get_type(type) != TYPE_BASIC_HANDLE) &&
++ is_attr(type->attrs, ATTR_HANDLE)) {
++ if (!generic_handle_registered(name))
++ {
++ generic_handle_t *gh = xmalloc(sizeof(*gh));
++ gh->name = xstrdup(name);
++ list_add_tail(&generic_handle_list, &gh->entry);
+ }
+- else if (type_is_complete(type))
++ /* don't carry on parsing fields within this type */
++ break;
++ }
++ if (is_attr(type->attrs, ATTR_WIREMARSHAL)) {
++ if (!user_type_registered(name))
+ {
+- var_list_t *vars;
+- switch (type_get_type_detect_alias(type))
+- {
+- case TYPE_ENUM:
+- vars = type_enum_get_values(type);
+- break;
+- case TYPE_STRUCT:
+- vars = type_struct_get_fields(type);
+- break;
+- case TYPE_UNION:
+- vars = type_union_get_cases(type);
+- break;
+- default:
+- vars = NULL;
+- break;
+- }
+- check_for_additional_prototype_types(vars);
++ user_type_t *ut = xmalloc(sizeof *ut);
++ ut->name = xstrdup(name);
++ list_add_tail(&user_type_list, &ut->entry);
+ }
+-
+- if (type_is_alias(type))
+- type = type_alias_get_aliasee(type);
+- else if (is_ptr(type))
+- type = type_pointer_get_ref(type);
+- else if (is_array(type))
+- type = type_array_get_element(type);
+- else
++ /* don't carry on parsing fields within this type as we are already
++ * using a wire marshaled type */
++ break;
++ }
++ else if (type_is_complete(type))
++ {
++ var_list_t *vars;
++ const var_t *v;
++ switch (type_get_type_detect_alias(type))
++ {
++ case TYPE_ENUM:
++ vars = type_enum_get_values(type);
++ break;
++ case TYPE_STRUCT:
++ vars = type_struct_get_fields(type);
+ break;
++ case TYPE_UNION:
++ vars = type_union_get_cases(type);
++ break;
++ default:
++ vars = NULL;
++ break;
++ }
++ if (vars) LIST_FOR_EACH_ENTRY( v, vars, const var_t, entry )
++ check_for_additional_prototype_types(v->declspec.type);
+ }
++
++ if (type_is_alias(type))
++ type = type_alias_get_aliasee_type(type);
++ else if (is_ptr(type))
++ type = type_pointer_get_ref_type(type);
++ else if (is_array(type))
++ type = type_array_get_element_type(type);
++ else
++ break;
+ }
+ }
+
+@@ -791,26 +797,26 @@ static void write_generic_handle_routines(FILE *header)
+ }
+ }
+
+-static void write_typedef(FILE *header, type_t *type)
++static void write_typedef(FILE *header, type_t *type, int declonly)
+ {
+ fprintf(header, "typedef ");
+- write_type_def_or_decl(header, type_alias_get_aliasee(type), FALSE, type->name);
++ write_type_v(header, type_alias_get_aliasee(type), FALSE, declonly, type->name);
+ fprintf(header, ";\n");
+ }
+
+ int is_const_decl(const var_t *var)
+ {
+- const type_t *t;
++ const decl_spec_t *ds;
+ /* strangely, MIDL accepts a const attribute on any pointer in the
+ * declaration to mean that data isn't being instantiated. this appears
+ * to be a bug, but there is no benefit to being incompatible with MIDL,
+ * so we'll do the same thing */
+- for (t = var->type; ; )
++ for (ds = &var->declspec; ;)
+ {
+- if (is_attr(t->attrs, ATTR_CONST))
++ if (ds->typequalifier == TYPE_QUALIFIER_CONST)
+ return TRUE;
+- else if (is_ptr(t))
+- t = type_pointer_get_ref(t);
++ else if (is_ptr(ds->type))
++ ds = type_pointer_get_ref(ds->type);
+ else break;
+ }
+ return FALSE;
+@@ -826,7 +832,7 @@ static void write_declaration(FILE *header, const var_t *v)
+ }
+ else
+ {
+- switch (v->stgclass)
++ switch (v->declspec.stgclass)
+ {
+ case STG_NONE:
+ case STG_REGISTER: /* ignored */
+@@ -838,7 +844,7 @@ static void write_declaration(FILE *header, const var_t *v)
+ fprintf(header, "extern ");
+ break;
+ }
+- write_type_def_or_decl(header, v->type, FALSE, v->name);
++ write_type_v(header, &v->declspec, FALSE, FALSE, v->name);
+ fprintf(header, ";\n\n");
+ }
+ }
+@@ -855,9 +861,9 @@ static void write_library(FILE *header, const typelib_t *typelib)
+ const type_t* get_explicit_generic_handle_type(const var_t* var)
+ {
+ const type_t *t;
+- for (t = var->type;
++ for (t = var->declspec.type;
+ is_ptr(t) || type_is_alias(t);
+- t = type_is_alias(t) ? type_alias_get_aliasee(t) : type_pointer_get_ref(t))
++ t = type_is_alias(t) ? type_alias_get_aliasee_type(t) : type_pointer_get_ref_type(t))
+ if ((type_get_type_detect_alias(t) != TYPE_BASIC || type_basic_get_type(t) != TYPE_BASIC_HANDLE) &&
+ is_attr(t->attrs, ATTR_HANDLE))
+ return t;
+@@ -868,13 +874,13 @@ const var_t *get_func_handle_var( const type_t *iface, const var_t *func,
+ unsigned char *explicit_fc, unsigned char *implicit_fc )
+ {
+ const var_t *var;
+- const var_list_t *args = type_get_function_args( func->type );
++ const var_list_t *args = type_function_get_args( func->declspec.type );
+
+ *explicit_fc = *implicit_fc = 0;
+ if (args) LIST_FOR_EACH_ENTRY( var, args, const var_t, entry )
+ {
+ if (!is_attr( var->attrs, ATTR_IN ) && is_attr( var->attrs, ATTR_OUT )) continue;
+- if (type_get_type( var->type ) == TYPE_BASIC && type_basic_get_type( var->type ) == TYPE_BASIC_HANDLE)
++ if (type_get_type( var->declspec.type ) == TYPE_BASIC && type_basic_get_type( var->declspec.type ) == TYPE_BASIC_HANDLE)
+ {
+ *explicit_fc = FC_BIND_PRIMITIVE;
+ return var;
+@@ -884,7 +890,7 @@ const var_t *get_func_handle_var( const type_t *iface, const var_t *func,
+ *explicit_fc = FC_BIND_GENERIC;
+ return var;
+ }
+- if (is_context_handle( var->type ))
++ if (is_context_handle( var->declspec.type ))
+ {
+ *explicit_fc = FC_BIND_CONTEXT;
+ return var;
+@@ -893,8 +899,8 @@ const var_t *get_func_handle_var( const type_t *iface, const var_t *func,
+
+ if ((var = get_attrp( iface->attrs, ATTR_IMPLICIT_HANDLE )))
+ {
+- if (type_get_type( var->type ) == TYPE_BASIC &&
+- type_basic_get_type( var->type ) == TYPE_BASIC_HANDLE)
++ if (type_get_type( var->declspec.type ) == TYPE_BASIC &&
++ type_basic_get_type( var->declspec.type ) == TYPE_BASIC_HANDLE)
+ *implicit_fc = FC_BIND_PRIMITIVE;
+ else
+ *implicit_fc = FC_BIND_GENERIC;
+@@ -909,13 +915,13 @@ int has_out_arg_or_return(const var_t *func)
+ {
+ const var_t *var;
+
+- if (!is_void(type_function_get_rettype(func->type)))
++ if (!is_void(type_function_get_rettype(func->declspec.type)))
+ return 1;
+
+- if (!type_get_function_args(func->type))
++ if (!type_function_get_args(func->declspec.type))
+ return 0;
+
+- LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
++ LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), const var_t, entry )
+ if (is_attr(var->attrs, ATTR_OUT))
+ return 1;
+
+@@ -995,7 +1001,7 @@ static int is_override_method(const type_t *iface, const type_t *child, const va
+
+ static int is_aggregate_return(const var_t *func)
+ {
+- enum type_type type = type_get_type(type_function_get_rettype(func->type));
++ enum type_type type = type_get_type(type_function_get_rettype(func->declspec.type));
+ return type == TYPE_STRUCT || type == TYPE_UNION ||
+ type == TYPE_COCLASS || type == TYPE_INTERFACE;
+ }
+@@ -1035,8 +1041,8 @@ static void write_method_macro(FILE *header, const type_t *iface, const type_t *
+ const var_t *arg;
+
+ fprintf(header, "#define %s_%s(This", name, get_name(func));
+- if (type_get_function_args(func->type))
+- LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), const var_t, entry )
++ if (type_function_get_args(func->declspec.type))
++ LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), const var_t, entry )
+ fprintf(header, ",%s", arg->name);
+ fprintf(header, ") ");
+
+@@ -1047,8 +1053,8 @@ static void write_method_macro(FILE *header, const type_t *iface, const type_t *
+ }
+
+ fprintf(header, "(This)->lpVtbl->%s(This", get_vtbl_entry_name(iface, func));
+- if (type_get_function_args(func->type))
+- LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), const var_t, entry )
++ if (type_function_get_args(func->declspec.type))
++ LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), const var_t, entry )
+ fprintf(header, ",%s", arg->name);
+ fprintf(header, ")\n");
+ }
+@@ -1078,7 +1084,7 @@ void write_args(FILE *h, const var_list_t *args, const char *name, int method, i
+ }
+ else fprintf(h, ",");
+ }
+- write_type_decl(h, arg->type, arg->name);
++ write_declspec_decl(h, &arg->declspec, arg->name);
+ if (method == 2) {
+ const expr_t *expr = get_attrp(arg->attrs, ATTR_DEFAULTVALUE);
+ if (expr) {
+@@ -1090,7 +1096,7 @@ void write_args(FILE *h, const var_list_t *args, const char *name, int method, i
+ expr_t bstr;
+
+ /* Fixup the expression type for a BSTR like midl does. */
+- if (get_type_vt(arg->type) == VT_BSTR && expr->type == EXPR_STRLIT)
++ if (get_type_vt(arg->declspec.type) == VT_BSTR && expr->type == EXPR_STRLIT)
+ {
+ bstr = *expr;
+ bstr.type = EXPR_WSTRLIT;
+@@ -1119,8 +1125,8 @@ static void write_cpp_method_def(FILE *header, const type_t *iface)
+ {
+ const var_t *func = stmt->u.var;
+ if (!is_callas(func->attrs)) {
+- const char *callconv = get_attrp(func->type->attrs, ATTR_CALLCONV);
+- const var_list_t *args = type_get_function_args(func->type);
++ const char *callconv = get_attrp(func->declspec.type->attrs, ATTR_CALLCONV);
++ const var_list_t *args = type_function_get_args(func->declspec.type);
+ const var_t *arg;
+
+ if (!callconv) callconv = "STDMETHODCALLTYPE";
+@@ -1130,11 +1136,11 @@ static void write_cpp_method_def(FILE *header, const type_t *iface)
+
+ indent(header, 0);
+ fprintf(header, "virtual ");
+- write_type_decl_left(header, type_function_get_rettype(func->type));
++ write_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
+ fprintf(header, "* %s %s(\n", callconv, get_name(func));
+ ++indentation;
+ indent(header, 0);
+- write_type_decl_left(header, type_function_get_rettype(func->type));
++ write_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
+ fprintf(header, " *__ret");
+ --indentation;
+ if (args) {
+@@ -1144,7 +1150,7 @@ static void write_cpp_method_def(FILE *header, const type_t *iface)
+ fprintf(header, ") = 0;\n");
+
+ indent(header, 0);
+- write_type_decl_left(header, type_function_get_rettype(func->type));
++ write_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
+ fprintf(header, " %s %s(\n", callconv, get_name(func));
+ write_args(header, args, iface->name, 2, TRUE);
+ fprintf(header, ")\n");
+@@ -1152,7 +1158,7 @@ static void write_cpp_method_def(FILE *header, const type_t *iface)
+ fprintf(header, "{\n");
+ ++indentation;
+ indent(header, 0);
+- write_type_decl_left(header, type_function_get_rettype(func->type));
++ write_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
+ fprintf(header, " __ret;\n");
+ indent(header, 0);
+ fprintf(header, "return *%s(&__ret", get_name(func));
+@@ -1169,7 +1175,7 @@ static void write_cpp_method_def(FILE *header, const type_t *iface)
+
+ indent(header, 0);
+ fprintf(header, "virtual ");
+- write_type_decl_left(header, type_function_get_rettype(func->type));
++ write_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
+ fprintf(header, " %s %s(\n", callconv, get_name(func));
+ write_args(header, args, iface->name, 2, TRUE);
+ fprintf(header, ") = 0;\n");
+@@ -1206,25 +1212,25 @@ static void write_inline_wrappers(FILE *header, const type_t *iface, const type_
+ const var_t *arg;
+
+ fprintf(header, "static FORCEINLINE ");
+- write_type_decl_left(header, type_function_get_rettype(func->type));
++ write_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
+ fprintf(header, " %s_%s(", name, get_name(func));
+- write_args(header, type_get_function_args(func->type), name, 1, FALSE);
++ write_args(header, type_function_get_args(func->declspec.type), name, 1, FALSE);
+ fprintf(header, ") {\n");
+ ++indentation;
+ if (!is_aggregate_return(func)) {
+ indent(header, 0);
+ fprintf(header, "%sThis->lpVtbl->%s(This",
+- is_void(type_function_get_rettype(func->type)) ? "" : "return ",
++ is_void(type_function_get_rettype(func->declspec.type)) ? "" : "return ",
+ get_vtbl_entry_name(iface, func));
+ } else {
+ indent(header, 0);
+- write_type_decl_left(header, type_function_get_rettype(func->type));
++ write_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
+ fprintf(header, " __ret;\n");
+ indent(header, 0);
+ fprintf(header, "return *This->lpVtbl->%s(This,&__ret", get_vtbl_entry_name(iface, func));
+ }
+- if (type_get_function_args(func->type))
+- LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), const var_t, entry )
++ if (type_function_get_args(func->declspec.type))
++ LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), const var_t, entry )
+ fprintf(header, ",%s", arg->name);
+ fprintf(header, ");\n");
+ --indentation;
+@@ -1250,10 +1256,10 @@ static void do_write_c_method_def(FILE *header, const type_t *iface, const char
+ first_iface = 0;
+ }
+ if (!is_callas(func->attrs)) {
+- const char *callconv = get_attrp(func->type->attrs, ATTR_CALLCONV);
++ const char *callconv = get_attrp(func->declspec.type->attrs, ATTR_CALLCONV);
+ if (!callconv) callconv = "STDMETHODCALLTYPE";
+ indent(header, 0);
+- write_type_decl_left(header, type_function_get_rettype(func->type));
++ write_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
+ if (is_aggregate_return(func))
+ fprintf(header, " *");
+ if (is_inherited_method(iface, func))
+@@ -1266,13 +1272,13 @@ static void do_write_c_method_def(FILE *header, const type_t *iface, const char
+ if (is_aggregate_return(func)) {
+ fprintf(header, ",\n");
+ indent(header, 0);
+- write_type_decl_left(header, type_function_get_rettype(func->type));
++ write_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
+ fprintf(header, " *__ret");
+ }
+ --indentation;
+- if (type_get_function_args(func->type)) {
++ if (type_function_get_args(func->declspec.type)) {
+ fprintf(header, ",\n");
+- write_args(header, type_get_function_args(func->type), name, 0, TRUE);
++ write_args(header, type_function_get_args(func->declspec.type), name, 0, TRUE);
+ }
+ fprintf(header, ");\n");
+ fprintf(header, "\n");
+@@ -1299,12 +1305,12 @@ static void write_method_proto(FILE *header, const type_t *iface)
+ const var_t *func = stmt->u.var;
+
+ if (is_callas(func->attrs)) {
+- const char *callconv = get_attrp(func->type->attrs, ATTR_CALLCONV);
++ const char *callconv = get_attrp(func->declspec.type->attrs, ATTR_CALLCONV);
+ if (!callconv) callconv = "STDMETHODCALLTYPE";
+ /* proxy prototype */
+- write_type_decl_left(header, type_function_get_rettype(func->type));
++ write_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
+ fprintf(header, " %s %s_%s_Proxy(\n", callconv, iface->name, get_name(func));
+- write_args(header, type_get_function_args(func->type), iface->name, 1, TRUE);
++ write_args(header, type_function_get_args(func->declspec.type), iface->name, 1, TRUE);
+ fprintf(header, ");\n");
+ /* stub prototype */
+ fprintf(header, "void __RPC_STUB %s_%s_Stub(\n", iface->name, get_name(func));
+@@ -1337,12 +1343,12 @@ static void write_locals(FILE *fp, const type_t *iface, int body)
+ if (&stmt2->entry != type_iface_get_stmts(iface)) {
+ const var_t *m = stmt2->u.var;
+ /* proxy prototype - use local prototype */
+- write_type_decl_left(fp, type_function_get_rettype(m->type));
++ write_declspec_decl_left(fp, type_function_get_retdeclspec(m->declspec.type));
+ fprintf(fp, " CALLBACK %s_%s_Proxy(\n", iface->name, get_name(m));
+- write_args(fp, type_get_function_args(m->type), iface->name, 1, TRUE);
++ write_args(fp, type_function_get_args(m->declspec.type), iface->name, 1, TRUE);
+ fprintf(fp, ")");
+ if (body) {
+- type_t *rt = type_function_get_rettype(m->type);
++ type_t *rt = type_function_get_rettype(m->declspec.type);
+ fprintf(fp, "\n{\n");
+ fprintf(fp, " %s\n", comment);
+ if (rt->name && strcmp(rt->name, "HRESULT") == 0)
+@@ -1359,9 +1365,9 @@ static void write_locals(FILE *fp, const type_t *iface, int body)
+ else
+ fprintf(fp, ";\n");
+ /* stub prototype - use remotable prototype */
+- write_type_decl_left(fp, type_function_get_rettype(func->type));
++ write_declspec_decl_left(fp, type_function_get_retdeclspec(func->declspec.type));
+ fprintf(fp, " __RPC_STUB %s_%s_Stub(\n", iface->name, get_name(m));
+- write_args(fp, type_get_function_args(func->type), iface->name, 1, TRUE);
++ write_args(fp, type_function_get_args(func->declspec.type), iface->name, 1, TRUE);
+ fprintf(fp, ")");
+ if (body)
+ /* Remotable methods must all return HRESULTs. */
+@@ -1407,15 +1413,16 @@ void write_local_stubs(const statement_list_t *stmts)
+
+ static void write_function_proto(FILE *header, const type_t *iface, const var_t *fun, const char *prefix)
+ {
+- const char *callconv = get_attrp(fun->type->attrs, ATTR_CALLCONV);
++ const char *callconv = get_attrp(fun->declspec.type->attrs, ATTR_CALLCONV);
+
+ if (!callconv) callconv = "__cdecl";
+ /* FIXME: do we need to handle call_as? */
+- write_type_decl_left(header, type_function_get_rettype(fun->type));
++ write_declspec_decl_left(header, type_function_get_retdeclspec(fun->declspec.type));
++ if (fun->declspec.funcspecifier == FUNCTION_SPECIFIER_INLINE) fprintf(header, " inline");
+ fprintf(header, " %s ", callconv);
+ fprintf(header, "%s%s(\n", prefix, get_name(fun));
+- if (type_get_function_args(fun->type))
+- write_args(header, type_get_function_args(fun->type), iface->name, 0, TRUE);
++ if (type_function_get_args(fun->declspec.type))
++ write_args(header, type_function_get_args(fun->declspec.type), iface->name, 0, TRUE);
+ else
+ fprintf(header, " void");
+ fprintf(header, ");\n\n");
+@@ -1541,7 +1548,7 @@ static void write_rpc_interface_start(FILE *header, const type_t *iface)
+ if (var)
+ {
+ fprintf(header, "extern ");
+- write_type_decl( header, var->type, var->name );
++ write_declspec_decl( header, &var->declspec, var->name );
+ fprintf(header, ";\n");
+ }
+ if (old_names)
+@@ -1653,6 +1660,7 @@ static void write_forward_decls(FILE *header, const statement_list_t *stmts)
+ if (type_get_type(stmt->u.type) == TYPE_INTERFACE)
+ {
+ type_t *iface = stmt->u.type;
++ assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
+ if (is_object(iface) || is_attr(iface->attrs, ATTR_DISPINTERFACE))
+ {
+ write_forward(header, iface);
+@@ -1694,6 +1702,7 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
+ {
+ type_t *iface = stmt->u.type;
+ type_t *async_iface = iface->details.iface->async_iface;
++ assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
+ if (is_object(iface)) is_object_interface++;
+ if (is_attr(stmt->u.type->attrs, ATTR_DISPINTERFACE) || is_object(stmt->u.type))
+ {
+@@ -1718,7 +1727,7 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
+ write_coclass(header, stmt->u.type);
+ else
+ {
+- write_type_definition(header, stmt->u.type);
++ write_type_definition(header, stmt->u.type, stmt->declonly);
+ }
+ break;
+ case STMT_TYPEREF:
+@@ -1739,7 +1748,7 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
+ {
+ const type_list_t *type_entry = stmt->u.type_list;
+ for (; type_entry; type_entry = type_entry->next)
+- write_typedef(header, type_entry->type);
++ write_typedef(header, type_entry->type, stmt->declonly);
+ break;
+ }
+ case STMT_LIBRARY:
+@@ -1750,7 +1759,7 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
+ fprintf(header, "%s\n", stmt->u.str);
+ break;
+ case STMT_DECLARATION:
+- if (iface && type_get_type(stmt->u.var->type) == TYPE_FUNCTION)
++ if (iface && type_get_type(stmt->u.var->declspec.type) == TYPE_FUNCTION)
+ {
+ if (!ignore_funcs)
+ {
+@@ -1784,15 +1793,15 @@ void write_header(const statement_list_t *stmts)
+ }
+ fprintf(header, "/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n\n", PACKAGE_VERSION, input_name);
+
++ fprintf(header, "#ifdef _WIN32\n");
+ fprintf(header, "#ifndef __REQUIRED_RPCNDR_H_VERSION__\n");
+ fprintf(header, "#define __REQUIRED_RPCNDR_H_VERSION__ 475\n");
+- fprintf(header, "#endif\n\n");
+-
++ fprintf(header, "#endif\n");
+ fprintf(header, "#include <rpc.h>\n" );
+ fprintf(header, "#include <rpcndr.h>\n" );
+ if (!for_each_serializable(stmts, NULL, serializable_exists))
+ fprintf(header, "#include <midles.h>\n" );
+- fprintf(header, "\n" );
++ fprintf(header, "#endif\n\n");
+
+ fprintf(header, "#ifndef COM_NO_WINDOWS_H\n");
+ fprintf(header, "#include <windows.h>\n");
+diff --git a/mingw-w64-tools/widl/src/header.h b/mingw-w64-tools/widl/src/header.h
+index 0d44b403..0e62f77c 100644
+--- a/mingw-w64-tools/widl/src/header.h
++++ b/mingw-w64-tools/widl/src/header.h
+@@ -29,10 +29,12 @@ extern int is_attr(const attr_list_t *list, enum attr_type t);
+ extern void *get_attrp(const attr_list_t *list, enum attr_type t);
+ extern unsigned int get_attrv(const attr_list_t *list, enum attr_type t);
+ extern const char* get_name(const var_t *v);
++extern void write_declspec_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, int declonly);
+ extern void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly);
+ extern void write_type_right(FILE *h, type_t *t, int is_field);
+ extern void write_type_decl(FILE *f, type_t *t, const char *name);
+-extern void write_type_decl_left(FILE *f, type_t *t);
++extern void write_declspec_decl(FILE *f, const decl_spec_t *ds, const char *name);
++extern void write_declspec_decl_left(FILE *f, const decl_spec_t *ds);
+ extern unsigned int get_context_handle_offset( const type_t *type );
+ extern unsigned int get_generic_handle_offset( const type_t *type );
+ extern int needs_space_after(type_t *t);
+@@ -83,12 +85,12 @@ static inline int is_conformant_array(const type_t *t)
+
+ static inline int last_ptr(const type_t *type)
+ {
+- return is_ptr(type) && !is_declptr(type_pointer_get_ref(type));
++ return is_ptr(type) && !is_declptr(type_pointer_get_ref_type(type));
+ }
+
+ static inline int last_array(const type_t *type)
+ {
+- return is_array(type) && !is_array(type_array_get_element(type));
++ return is_array(type) && !is_array(type_array_get_element_type(type));
+ }
+
+ static inline int is_string_type(const attr_list_t *attrs, const type_t *type)
+@@ -102,7 +104,7 @@ static inline int is_context_handle(const type_t *type)
+ const type_t *t;
+ for (t = type;
+ is_ptr(t) || type_is_alias(t);
+- t = type_is_alias(t) ? type_alias_get_aliasee(t) : type_pointer_get_ref(t))
++ t = type_is_alias(t) ? type_alias_get_aliasee_type(t) : type_pointer_get_ref_type(t))
+ if (is_attr(t->attrs, ATTR_CONTEXTHANDLE))
+ return 1;
+ return 0;
+diff --git a/mingw-w64-tools/widl/src/parser.tab.c b/mingw-w64-tools/widl/src/parser.tab.c
+index 6266e054..d7053e79 100644
+--- a/mingw-w64-tools/widl/src/parser.tab.c
++++ b/mingw-w64-tools/widl/src/parser.tab.c
+@@ -1,8 +1,8 @@
+-/* A Bison parser, made by GNU Bison 3.0.5. */
++/* A Bison parser, made by GNU Bison 3.0.4. */
+
+ /* Bison implementation for Yacc-like parsers in C
+
+- Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc.
++ Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+@@ -44,7 +44,7 @@
+ #define YYBISON 1
+
+ /* Bison version. */
+-#define YYBISON_VERSION "3.0.5"
++#define YYBISON_VERSION "3.0.4"
+
+ /* Skeleton name. */
+ #define YYSKELETON_NAME "yacc.c"
+@@ -125,13 +125,6 @@ struct _import_t
+ int import_performed;
+ };
+
+-typedef struct _decl_spec_t
+-{
+- type_t *type;
+- attr_list_t *attrs;
+- enum storage_class stgclass;
+-} decl_spec_t;
+-
+ typelist_t incomplete_types = LIST_INIT(incomplete_types);
+
+ static void fix_incomplete(void);
+@@ -140,7 +133,7 @@ static void fix_incomplete_types(type_t *complete_type);
+ static str_list_t *append_str(str_list_t *list, char *str);
+ static attr_list_t *append_attr(attr_list_t *list, attr_t *attr);
+ static attr_list_t *append_attr_list(attr_list_t *new_list, attr_list_t *old_list);
+-static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, attr_t *attr, enum storage_class stgclass);
++static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, enum storage_class stgclass, enum type_qualifier typequalifier, enum function_specifier funcspecifier);
+ static attr_t *make_attr(enum attr_type type);
+ static attr_t *make_attrv(enum attr_type type, unsigned int val);
+ static attr_t *make_attrp(enum attr_type type, void *val);
+@@ -156,6 +149,7 @@ static declarator_t *make_declarator(var_t *var);
+ static type_t *make_safearray(type_t *type);
+ static typelib_t *make_library(const char *name, const attr_list_t *attrs);
+ static type_t *append_chain_type(type_t *chain, type_t *type);
++static decl_spec_t *append_chain_declspec(decl_spec_t *chain, type_t *type, enum type_qualifier typequalifier);
+ static warning_list_t *append_warning(warning_list_t *, int);
+
+ static type_t *reg_typedefs(decl_spec_t *decl_spec, var_list_t *names, attr_list_t *attrs);
+@@ -212,7 +206,7 @@ static struct namespace *current_namespace = &global_namespace;
+ static typelib_t *current_typelib;
+
+
+-#line 216 "parser.tab.c" /* yacc.c:339 */
++#line 210 "parser.tab.c" /* yacc.c:339 */
+
+ # ifndef YY_NULLPTR
+ # if defined __cplusplus && 201103L <= __cplusplus
+@@ -438,7 +432,7 @@ extern int parser_debug;
+
+ union YYSTYPE
+ {
+-#line 142 "parser.y" /* yacc.c:355 */
++#line 136 "parser.y" /* yacc.c:355 */
+
+ attr_t *attr;
+ attr_list_t *attr_list;
+@@ -465,8 +459,10 @@ union YYSTYPE
+ struct _import_t *import;
+ struct _decl_spec_t *declspec;
+ enum storage_class stgclass;
++ enum type_qualifier typequalifier;
++ enum function_specifier funcspecifier;
+
+-#line 470 "parser.tab.c" /* yacc.c:355 */
++#line 466 "parser.tab.c" /* yacc.c:355 */
+ };
+
+ typedef union YYSTYPE YYSTYPE;
+@@ -483,7 +479,7 @@ int parser_parse (void);
+
+ /* Copy the second part of user declarations. */
+
+-#line 487 "parser.tab.c" /* yacc.c:358 */
++#line 483 "parser.tab.c" /* yacc.c:358 */
+
+ #ifdef short
+ # undef short
+@@ -799,48 +795,48 @@ static const yytype_uint8 yytranslate[] =
+ /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
+ static const yytype_uint16 yyrline[] =
+ {
+- 0, 325, 325, 340, 340, 342, 343, 343, 345, 346,
+- 347, 350, 353, 354, 355, 358, 359, 360, 360, 362,
+- 363, 364, 367, 368, 369, 370, 373, 374, 377, 378,
+- 382, 383, 384, 385, 386, 387, 388, 391, 402, 403,
+- 407, 408, 409, 410, 411, 412, 413, 414, 415, 418,
+- 420, 428, 434, 438, 439, 441, 445, 449, 450, 453,
+- 454, 457, 458, 462, 467, 474, 478, 479, 482, 483,
+- 487, 490, 491, 492, 495, 496, 499, 500, 501, 502,
+- 503, 504, 505, 506, 507, 508, 509, 510, 511, 512,
+- 513, 514, 515, 516, 517, 518, 519, 520, 521, 522,
+- 523, 524, 525, 526, 527, 528, 529, 530, 531, 532,
+- 533, 534, 535, 536, 537, 538, 539, 540, 541, 542,
+- 543, 544, 545, 546, 547, 548, 549, 550, 551, 552,
+- 553, 554, 555, 556, 557, 558, 559, 560, 561, 562,
+- 563, 564, 565, 566, 567, 568, 569, 570, 571, 572,
+- 573, 574, 578, 579, 580, 581, 582, 583, 584, 585,
+- 586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+- 596, 597, 598, 599, 600, 601, 605, 606, 611, 612,
+- 613, 614, 617, 618, 621, 625, 631, 632, 633, 636,
+- 640, 652, 656, 661, 664, 665, 668, 669, 672, 673,
+- 674, 675, 676, 677, 678, 679, 680, 681, 682, 683,
+- 684, 685, 686, 687, 688, 689, 690, 691, 692, 693,
+- 694, 695, 696, 697, 698, 699, 700, 701, 702, 703,
+- 704, 705, 706, 707, 708, 709, 711, 713, 714, 717,
+- 718, 721, 727, 733, 734, 737, 742, 749, 750, 753,
+- 754, 758, 759, 762, 766, 772, 780, 784, 789, 790,
+- 793, 794, 795, 798, 800, 803, 804, 805, 806, 807,
+- 808, 809, 810, 811, 812, 813, 816, 817, 820, 821,
+- 822, 823, 824, 825, 826, 827, 828, 831, 832, 840,
+- 846, 850, 853, 854, 858, 861, 862, 865, 874, 875,
+- 878, 879, 882, 888, 894, 895, 898, 899, 902, 912,
+- 922, 928, 932, 933, 936, 937, 940, 945, 952, 953,
+- 954, 958, 962, 965, 966, 969, 970, 974, 975, 979,
+- 980, 981, 985, 987, 989, 993, 994, 995, 996, 1004,
+- 1006, 1008, 1013, 1015, 1020, 1021, 1026, 1027, 1028, 1029,
+- 1034, 1043, 1045, 1046, 1051, 1053, 1057, 1058, 1065, 1066,
+- 1067, 1068, 1069, 1074, 1082, 1083, 1086, 1087, 1090, 1097,
+- 1098, 1103, 1104, 1108, 1109, 1110, 1111, 1112, 1116, 1117,
+- 1118, 1121, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131,
+- 1132, 1133, 1136, 1143, 1145, 1151, 1152, 1153, 1156, 1158,
+- 1160, 1162, 1165, 1170, 1178, 1179, 1182, 1183, 1186, 1187,
+- 1188
++ 0, 323, 323, 338, 338, 340, 341, 341, 343, 344,
++ 345, 348, 351, 352, 353, 356, 357, 358, 358, 360,
++ 361, 362, 365, 366, 367, 368, 371, 372, 375, 376,
++ 380, 381, 382, 383, 384, 385, 386, 389, 400, 401,
++ 405, 406, 407, 408, 409, 410, 411, 412, 413, 416,
++ 418, 426, 432, 436, 437, 439, 443, 447, 448, 451,
++ 452, 455, 456, 460, 465, 472, 476, 477, 480, 481,
++ 485, 488, 489, 490, 493, 494, 497, 498, 499, 500,
++ 501, 502, 503, 504, 505, 506, 507, 508, 509, 510,
++ 511, 512, 513, 514, 515, 516, 517, 518, 519, 520,
++ 521, 522, 523, 524, 525, 526, 527, 528, 529, 530,
++ 531, 532, 533, 534, 535, 536, 537, 538, 539, 540,
++ 541, 542, 543, 544, 545, 546, 547, 548, 549, 550,
++ 551, 552, 553, 554, 555, 556, 557, 558, 559, 560,
++ 561, 562, 563, 564, 565, 566, 567, 568, 569, 570,
++ 571, 572, 576, 577, 578, 579, 580, 581, 582, 583,
++ 584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
++ 594, 595, 596, 597, 598, 599, 603, 604, 609, 610,
++ 611, 612, 615, 616, 619, 623, 629, 630, 631, 634,
++ 638, 650, 654, 659, 662, 663, 666, 667, 670, 671,
++ 672, 673, 674, 675, 676, 677, 678, 679, 680, 681,
++ 682, 683, 684, 685, 686, 687, 688, 689, 690, 691,
++ 692, 693, 694, 695, 696, 697, 698, 699, 700, 701,
++ 702, 703, 704, 705, 706, 707, 709, 711, 712, 715,
++ 716, 719, 725, 731, 732, 735, 740, 747, 748, 751,
++ 752, 756, 757, 760, 764, 770, 778, 782, 787, 788,
++ 791, 792, 793, 796, 798, 801, 802, 803, 804, 805,
++ 806, 807, 808, 809, 810, 811, 814, 815, 818, 819,
++ 820, 821, 822, 823, 824, 825, 826, 829, 830, 838,
++ 844, 848, 851, 852, 856, 859, 860, 863, 872, 873,
++ 876, 877, 880, 886, 892, 893, 896, 897, 900, 910,
++ 920, 926, 930, 931, 934, 935, 938, 943, 950, 951,
++ 952, 956, 960, 963, 964, 967, 968, 972, 973, 977,
++ 978, 979, 983, 985, 987, 991, 992, 993, 994, 1002,
++ 1004, 1006, 1011, 1013, 1018, 1019, 1024, 1025, 1026, 1027,
++ 1032, 1041, 1043, 1044, 1049, 1051, 1055, 1056, 1063, 1064,
++ 1065, 1066, 1067, 1072, 1080, 1081, 1084, 1085, 1088, 1095,
++ 1096, 1101, 1102, 1106, 1107, 1108, 1109, 1110, 1114, 1115,
++ 1116, 1119, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129,
++ 1130, 1131, 1134, 1141, 1143, 1149, 1150, 1151, 1154, 1156,
++ 1158, 1160, 1163, 1168, 1176, 1177, 1180, 1181, 1184, 1185,
++ 1186
+ };
+ #endif
+
+@@ -903,7 +899,7 @@ static const char *const yytname[] =
+ "dispinterfacedef", "inherit", "interface", "interfacehdr",
+ "interfacedef", "interfacedec", "module", "modulehdr", "moduledef",
+ "storage_cls_spec", "function_specifier", "type_qualifier",
+- "m_type_qual_list", "decl_spec", "m_decl_spec_no_type",
++ "m_type_qual_bits", "decl_spec", "m_decl_spec_no_type",
+ "decl_spec_no_type", "declarator", "direct_declarator",
+ "abstract_declarator", "abstract_declarator_no_direct",
+ "m_abstract_declarator", "abstract_direct_declarator", "any_declarator",
+@@ -2298,7 +2294,6 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+ case N: \
+ yyformat = S; \
+ break
+- default: /* Avoid compiler warnings. */
+ YYCASE_(0, YY_("syntax error"));
+ YYCASE_(1, YY_("syntax error, unexpected %s"));
+ YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+@@ -2615,7 +2610,7 @@ yyreduce:
+ switch (yyn)
+ {
+ case 2:
+-#line 325 "parser.y" /* yacc.c:1648 */
++#line 323 "parser.y" /* yacc.c:1646 */
+ { fix_incomplete();
+ check_statements((yyvsp[-1].stmt_list), FALSE);
+ check_all_user_types((yyvsp[-1].stmt_list));
+@@ -2629,197 +2624,197 @@ yyreduce:
+ write_dlldata((yyvsp[-1].stmt_list));
+ write_local_stubs((yyvsp[-1].stmt_list));
+ }
+-#line 2633 "parser.tab.c" /* yacc.c:1648 */
++#line 2628 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 5:
+-#line 342 "parser.y" /* yacc.c:1648 */
++#line 340 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = NULL; }
+-#line 2639 "parser.tab.c" /* yacc.c:1648 */
++#line 2634 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 6:
+-#line 343 "parser.y" /* yacc.c:1648 */
++#line 341 "parser.y" /* yacc.c:1646 */
+ { push_namespace((yyvsp[-1].str)); }
+-#line 2645 "parser.tab.c" /* yacc.c:1648 */
++#line 2640 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 7:
+-#line 344 "parser.y" /* yacc.c:1648 */
++#line 342 "parser.y" /* yacc.c:1646 */
+ { pop_namespace((yyvsp[-4].str)); (yyval.stmt_list) = append_statements((yyvsp[-5].stmt_list), (yyvsp[-1].stmt_list)); }
+-#line 2651 "parser.tab.c" /* yacc.c:1648 */
++#line 2646 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 8:
+-#line 345 "parser.y" /* yacc.c:1648 */
++#line 343 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_reference((yyvsp[0].type))); }
+-#line 2657 "parser.tab.c" /* yacc.c:1648 */
++#line 2652 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 9:
+-#line 346 "parser.y" /* yacc.c:1648 */
++#line 344 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_type_decl((yyvsp[0].type))); }
+-#line 2663 "parser.tab.c" /* yacc.c:1648 */
++#line 2658 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 10:
+-#line 347 "parser.y" /* yacc.c:1648 */
++#line 345 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = (yyvsp[-2].stmt_list);
+ reg_type((yyvsp[-1].type), (yyvsp[-1].type)->name, current_namespace, 0);
+ }
+-#line 2671 "parser.tab.c" /* yacc.c:1648 */
++#line 2666 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 11:
+-#line 350 "parser.y" /* yacc.c:1648 */
++#line 348 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_type_decl((yyvsp[0].type)));
+ reg_type((yyvsp[0].type), (yyvsp[0].type)->name, current_namespace, 0);
+ }
+-#line 2679 "parser.tab.c" /* yacc.c:1648 */
++#line 2674 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 12:
+-#line 353 "parser.y" /* yacc.c:1648 */
++#line 351 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_module((yyvsp[0].type))); }
+-#line 2685 "parser.tab.c" /* yacc.c:1648 */
++#line 2680 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 13:
+-#line 354 "parser.y" /* yacc.c:1648 */
++#line 352 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_library((yyvsp[0].typelib))); }
+-#line 2691 "parser.tab.c" /* yacc.c:1648 */
++#line 2686 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 14:
+-#line 355 "parser.y" /* yacc.c:1648 */
++#line 353 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), (yyvsp[0].statement)); }
+-#line 2697 "parser.tab.c" /* yacc.c:1648 */
++#line 2692 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 15:
+-#line 358 "parser.y" /* yacc.c:1648 */
++#line 356 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = NULL; }
+-#line 2703 "parser.tab.c" /* yacc.c:1648 */
++#line 2698 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 16:
+-#line 359 "parser.y" /* yacc.c:1648 */
++#line 357 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_reference((yyvsp[0].type))); }
+-#line 2709 "parser.tab.c" /* yacc.c:1648 */
++#line 2704 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 17:
+-#line 360 "parser.y" /* yacc.c:1648 */
++#line 358 "parser.y" /* yacc.c:1646 */
+ { push_namespace((yyvsp[-1].str)); }
+-#line 2715 "parser.tab.c" /* yacc.c:1648 */
++#line 2710 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 18:
+-#line 361 "parser.y" /* yacc.c:1648 */
++#line 359 "parser.y" /* yacc.c:1646 */
+ { pop_namespace((yyvsp[-4].str)); (yyval.stmt_list) = append_statements((yyvsp[-5].stmt_list), (yyvsp[-1].stmt_list)); }
+-#line 2721 "parser.tab.c" /* yacc.c:1648 */
++#line 2716 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 19:
+-#line 362 "parser.y" /* yacc.c:1648 */
++#line 360 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_type_decl((yyvsp[0].type))); }
+-#line 2727 "parser.tab.c" /* yacc.c:1648 */
++#line 2722 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 20:
+-#line 363 "parser.y" /* yacc.c:1648 */
++#line 361 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = (yyvsp[-2].stmt_list); reg_type((yyvsp[-1].type), (yyvsp[-1].type)->name, current_namespace, 0); }
+-#line 2733 "parser.tab.c" /* yacc.c:1648 */
++#line 2728 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 21:
+-#line 364 "parser.y" /* yacc.c:1648 */
++#line 362 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_type_decl((yyvsp[0].type)));
+ reg_type((yyvsp[0].type), (yyvsp[0].type)->name, current_namespace, 0);
+ }
+-#line 2741 "parser.tab.c" /* yacc.c:1648 */
++#line 2736 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 22:
+-#line 367 "parser.y" /* yacc.c:1648 */
++#line 365 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_module((yyvsp[0].type))); }
+-#line 2747 "parser.tab.c" /* yacc.c:1648 */
++#line 2742 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 23:
+-#line 368 "parser.y" /* yacc.c:1648 */
++#line 366 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), (yyvsp[0].statement)); }
+-#line 2753 "parser.tab.c" /* yacc.c:1648 */
++#line 2748 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 24:
+-#line 369 "parser.y" /* yacc.c:1648 */
++#line 367 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_importlib((yyvsp[0].str))); }
+-#line 2759 "parser.tab.c" /* yacc.c:1648 */
++#line 2754 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 25:
+-#line 370 "parser.y" /* yacc.c:1648 */
++#line 368 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_library((yyvsp[0].typelib))); }
+-#line 2765 "parser.tab.c" /* yacc.c:1648 */
++#line 2760 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 26:
+-#line 373 "parser.y" /* yacc.c:1648 */
++#line 371 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = NULL; }
+-#line 2771 "parser.tab.c" /* yacc.c:1648 */
++#line 2766 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 27:
+-#line 374 "parser.y" /* yacc.c:1648 */
++#line 372 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), (yyvsp[0].statement)); }
+-#line 2777 "parser.tab.c" /* yacc.c:1648 */
++#line 2772 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 30:
+-#line 382 "parser.y" /* yacc.c:1648 */
++#line 380 "parser.y" /* yacc.c:1646 */
+ { (yyval.statement) = make_statement_cppquote((yyvsp[0].str)); }
+-#line 2783 "parser.tab.c" /* yacc.c:1648 */
++#line 2778 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 31:
+-#line 383 "parser.y" /* yacc.c:1648 */
++#line 381 "parser.y" /* yacc.c:1646 */
+ { (yyval.statement) = make_statement_type_decl((yyvsp[-1].type)); }
+-#line 2789 "parser.tab.c" /* yacc.c:1648 */
++#line 2784 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 32:
+-#line 384 "parser.y" /* yacc.c:1648 */
++#line 382 "parser.y" /* yacc.c:1646 */
+ { (yyval.statement) = make_statement_declaration((yyvsp[-1].var)); }
+-#line 2795 "parser.tab.c" /* yacc.c:1648 */
++#line 2790 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 33:
+-#line 385 "parser.y" /* yacc.c:1648 */
++#line 383 "parser.y" /* yacc.c:1646 */
+ { (yyval.statement) = make_statement_import((yyvsp[0].str)); }
+-#line 2801 "parser.tab.c" /* yacc.c:1648 */
++#line 2796 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 34:
+-#line 386 "parser.y" /* yacc.c:1648 */
++#line 384 "parser.y" /* yacc.c:1646 */
+ { (yyval.statement) = (yyvsp[-1].statement); }
+-#line 2807 "parser.tab.c" /* yacc.c:1648 */
++#line 2802 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 35:
+-#line 387 "parser.y" /* yacc.c:1648 */
++#line 385 "parser.y" /* yacc.c:1646 */
+ { (yyval.statement) = make_statement_pragma((yyvsp[0].str)); }
+-#line 2813 "parser.tab.c" /* yacc.c:1648 */
++#line 2808 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 36:
+-#line 388 "parser.y" /* yacc.c:1648 */
++#line 386 "parser.y" /* yacc.c:1646 */
+ { (yyval.statement) = NULL; }
+-#line 2819 "parser.tab.c" /* yacc.c:1648 */
++#line 2814 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 37:
+-#line 392 "parser.y" /* yacc.c:1648 */
++#line 390 "parser.y" /* yacc.c:1646 */
+ {
+ int result;
+ (yyval.statement) = NULL;
+@@ -2827,909 +2822,909 @@ yyreduce:
+ if(!result)
+ error_loc("expected \"disable\" or \"enable\"\n");
+ }
+-#line 2831 "parser.tab.c" /* yacc.c:1648 */
++#line 2826 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 38:
+-#line 402 "parser.y" /* yacc.c:1648 */
++#line 400 "parser.y" /* yacc.c:1646 */
+ { (yyval.warning_list) = append_warning(NULL, (yyvsp[0].num)); }
+-#line 2837 "parser.tab.c" /* yacc.c:1648 */
++#line 2832 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 39:
+-#line 403 "parser.y" /* yacc.c:1648 */
++#line 401 "parser.y" /* yacc.c:1646 */
+ { (yyval.warning_list) = append_warning((yyvsp[-1].warning_list), (yyvsp[0].num)); }
+-#line 2843 "parser.tab.c" /* yacc.c:1648 */
++#line 2838 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 41:
+-#line 408 "parser.y" /* yacc.c:1648 */
++#line 406 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_enum((yyvsp[0].str), current_namespace, FALSE, NULL); }
+-#line 2849 "parser.tab.c" /* yacc.c:1648 */
++#line 2844 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 43:
+-#line 410 "parser.y" /* yacc.c:1648 */
++#line 408 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_struct((yyvsp[0].str), current_namespace, FALSE, NULL); }
+-#line 2855 "parser.tab.c" /* yacc.c:1648 */
++#line 2850 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 45:
+-#line 412 "parser.y" /* yacc.c:1648 */
++#line 410 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_nonencapsulated_union((yyvsp[0].str), FALSE, NULL); }
+-#line 2861 "parser.tab.c" /* yacc.c:1648 */
++#line 2856 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 46:
+-#line 413 "parser.y" /* yacc.c:1648 */
++#line 411 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[0].type); (yyval.type)->attrs = check_enum_attrs((yyvsp[-1].attr_list)); }
+-#line 2867 "parser.tab.c" /* yacc.c:1648 */
++#line 2862 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 47:
+-#line 414 "parser.y" /* yacc.c:1648 */
++#line 412 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[0].type); (yyval.type)->attrs = check_struct_attrs((yyvsp[-1].attr_list)); }
+-#line 2873 "parser.tab.c" /* yacc.c:1648 */
++#line 2868 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 48:
+-#line 415 "parser.y" /* yacc.c:1648 */
++#line 413 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[0].type); (yyval.type)->attrs = check_union_attrs((yyvsp[-1].attr_list)); }
+-#line 2879 "parser.tab.c" /* yacc.c:1648 */
++#line 2874 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 49:
+-#line 418 "parser.y" /* yacc.c:1648 */
++#line 416 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = (yyvsp[-1].str); }
+-#line 2885 "parser.tab.c" /* yacc.c:1648 */
++#line 2880 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 50:
+-#line 420 "parser.y" /* yacc.c:1648 */
++#line 418 "parser.y" /* yacc.c:1646 */
+ { assert(yychar == YYEMPTY);
+ (yyval.import) = xmalloc(sizeof(struct _import_t));
+ (yyval.import)->name = (yyvsp[-1].str);
+ (yyval.import)->import_performed = do_import((yyvsp[-1].str));
+ if (!(yyval.import)->import_performed) yychar = aEOF;
+ }
+-#line 2896 "parser.tab.c" /* yacc.c:1648 */
++#line 2891 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 51:
+-#line 428 "parser.y" /* yacc.c:1648 */
++#line 426 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = (yyvsp[-2].import)->name;
+ if ((yyvsp[-2].import)->import_performed) pop_import();
+ free((yyvsp[-2].import));
+ }
+-#line 2905 "parser.tab.c" /* yacc.c:1648 */
++#line 2900 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 52:
+-#line 435 "parser.y" /* yacc.c:1648 */
++#line 433 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = (yyvsp[-2].str); if(!parse_only) add_importlib((yyvsp[-2].str), current_typelib); }
+-#line 2911 "parser.tab.c" /* yacc.c:1648 */
++#line 2906 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 53:
+-#line 438 "parser.y" /* yacc.c:1648 */
++#line 436 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = (yyvsp[0].str); }
+-#line 2917 "parser.tab.c" /* yacc.c:1648 */
++#line 2912 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 54:
+-#line 439 "parser.y" /* yacc.c:1648 */
++#line 437 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = (yyvsp[0].str); }
+-#line 2923 "parser.tab.c" /* yacc.c:1648 */
++#line 2918 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 55:
+-#line 441 "parser.y" /* yacc.c:1648 */
++#line 439 "parser.y" /* yacc.c:1646 */
+ { (yyval.typelib) = make_library((yyvsp[-1].str), check_library_attrs((yyvsp[-1].str), (yyvsp[-2].attr_list)));
+ if (!parse_only && do_typelib) current_typelib = (yyval.typelib);
+ }
+-#line 2931 "parser.tab.c" /* yacc.c:1648 */
++#line 2926 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 56:
+-#line 446 "parser.y" /* yacc.c:1648 */
++#line 444 "parser.y" /* yacc.c:1646 */
+ { (yyval.typelib) = (yyvsp[-3].typelib); (yyval.typelib)->stmts = (yyvsp[-2].stmt_list); }
+-#line 2937 "parser.tab.c" /* yacc.c:1648 */
++#line 2932 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 57:
+-#line 449 "parser.y" /* yacc.c:1648 */
++#line 447 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = NULL; }
+-#line 2943 "parser.tab.c" /* yacc.c:1648 */
++#line 2938 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 59:
+-#line 453 "parser.y" /* yacc.c:1648 */
++#line 451 "parser.y" /* yacc.c:1646 */
+ { check_arg_attrs((yyvsp[0].var)); (yyval.var_list) = append_var( NULL, (yyvsp[0].var) ); }
+-#line 2949 "parser.tab.c" /* yacc.c:1648 */
++#line 2944 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 60:
+-#line 454 "parser.y" /* yacc.c:1648 */
++#line 452 "parser.y" /* yacc.c:1646 */
+ { check_arg_attrs((yyvsp[0].var)); (yyval.var_list) = append_var( (yyvsp[-2].var_list), (yyvsp[0].var) ); }
+-#line 2955 "parser.tab.c" /* yacc.c:1648 */
++#line 2950 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 62:
+-#line 458 "parser.y" /* yacc.c:1648 */
++#line 456 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = append_var( (yyvsp[-2].var_list), make_var(strdup("...")) ); }
+-#line 2961 "parser.tab.c" /* yacc.c:1648 */
++#line 2956 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 63:
+-#line 462 "parser.y" /* yacc.c:1648 */
++#line 460 "parser.y" /* yacc.c:1646 */
+ { if ((yyvsp[-1].declspec)->stgclass != STG_NONE && (yyvsp[-1].declspec)->stgclass != STG_REGISTER)
+ error_loc("invalid storage class for function parameter\n");
+ (yyval.var) = declare_var((yyvsp[-2].attr_list), (yyvsp[-1].declspec), (yyvsp[0].declarator), TRUE);
+ free((yyvsp[-1].declspec)); free((yyvsp[0].declarator));
+ }
+-#line 2971 "parser.tab.c" /* yacc.c:1648 */
++#line 2966 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 64:
+-#line 467 "parser.y" /* yacc.c:1648 */
++#line 465 "parser.y" /* yacc.c:1646 */
+ { if ((yyvsp[-1].declspec)->stgclass != STG_NONE && (yyvsp[-1].declspec)->stgclass != STG_REGISTER)
+ error_loc("invalid storage class for function parameter\n");
+ (yyval.var) = declare_var(NULL, (yyvsp[-1].declspec), (yyvsp[0].declarator), TRUE);
+ free((yyvsp[-1].declspec)); free((yyvsp[0].declarator));
+ }
+-#line 2981 "parser.tab.c" /* yacc.c:1648 */
++#line 2976 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 65:
+-#line 474 "parser.y" /* yacc.c:1648 */
++#line 472 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = (yyvsp[-1].expr);
+ if (!(yyval.expr)->is_const || (yyval.expr)->cval <= 0)
+ error_loc("array dimension is not a positive integer constant\n");
+ }
+-#line 2990 "parser.tab.c" /* yacc.c:1648 */
++#line 2985 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 66:
+-#line 478 "parser.y" /* yacc.c:1648 */
++#line 476 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr(EXPR_VOID); }
+-#line 2996 "parser.tab.c" /* yacc.c:1648 */
++#line 2991 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 67:
+-#line 479 "parser.y" /* yacc.c:1648 */
++#line 477 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr(EXPR_VOID); }
+-#line 3002 "parser.tab.c" /* yacc.c:1648 */
++#line 2997 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 68:
+-#line 482 "parser.y" /* yacc.c:1648 */
++#line 480 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr_list) = NULL; }
+-#line 3008 "parser.tab.c" /* yacc.c:1648 */
++#line 3003 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 70:
+-#line 487 "parser.y" /* yacc.c:1648 */
++#line 485 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr_list) = (yyvsp[-1].attr_list); }
+-#line 3014 "parser.tab.c" /* yacc.c:1648 */
++#line 3009 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 71:
+-#line 490 "parser.y" /* yacc.c:1648 */
++#line 488 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr_list) = append_attr( NULL, (yyvsp[0].attr) ); }
+-#line 3020 "parser.tab.c" /* yacc.c:1648 */
++#line 3015 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 72:
+-#line 491 "parser.y" /* yacc.c:1648 */
++#line 489 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr_list) = append_attr( (yyvsp[-2].attr_list), (yyvsp[0].attr) ); }
+-#line 3026 "parser.tab.c" /* yacc.c:1648 */
++#line 3021 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 73:
+-#line 492 "parser.y" /* yacc.c:1648 */
++#line 490 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr_list) = append_attr( (yyvsp[-3].attr_list), (yyvsp[0].attr) ); }
+-#line 3032 "parser.tab.c" /* yacc.c:1648 */
++#line 3027 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 74:
+-#line 495 "parser.y" /* yacc.c:1648 */
++#line 493 "parser.y" /* yacc.c:1646 */
+ { (yyval.str_list) = append_str( NULL, (yyvsp[0].str) ); }
+-#line 3038 "parser.tab.c" /* yacc.c:1648 */
++#line 3033 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 75:
+-#line 496 "parser.y" /* yacc.c:1648 */
++#line 494 "parser.y" /* yacc.c:1646 */
+ { (yyval.str_list) = append_str( (yyvsp[-2].str_list), (yyvsp[0].str) ); }
+-#line 3044 "parser.tab.c" /* yacc.c:1648 */
++#line 3039 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 76:
+-#line 499 "parser.y" /* yacc.c:1648 */
++#line 497 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = NULL; }
+-#line 3050 "parser.tab.c" /* yacc.c:1648 */
++#line 3045 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 77:
+-#line 500 "parser.y" /* yacc.c:1648 */
++#line 498 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_AGGREGATABLE); }
+-#line 3056 "parser.tab.c" /* yacc.c:1648 */
++#line 3051 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 78:
+-#line 501 "parser.y" /* yacc.c:1648 */
++#line 499 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_ANNOTATION, (yyvsp[-1].str)); }
+-#line 3062 "parser.tab.c" /* yacc.c:1648 */
++#line 3057 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 79:
+-#line 502 "parser.y" /* yacc.c:1648 */
++#line 500 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_APPOBJECT); }
+-#line 3068 "parser.tab.c" /* yacc.c:1648 */
++#line 3063 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 80:
+-#line 503 "parser.y" /* yacc.c:1648 */
++#line 501 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_ASYNC); }
+-#line 3074 "parser.tab.c" /* yacc.c:1648 */
++#line 3069 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 81:
+-#line 504 "parser.y" /* yacc.c:1648 */
++#line 502 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_AUTO_HANDLE); }
+-#line 3080 "parser.tab.c" /* yacc.c:1648 */
++#line 3075 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 82:
+-#line 505 "parser.y" /* yacc.c:1648 */
++#line 503 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_BINDABLE); }
+-#line 3086 "parser.tab.c" /* yacc.c:1648 */
++#line 3081 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 83:
+-#line 506 "parser.y" /* yacc.c:1648 */
++#line 504 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_BROADCAST); }
+-#line 3092 "parser.tab.c" /* yacc.c:1648 */
++#line 3087 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 84:
+-#line 507 "parser.y" /* yacc.c:1648 */
++#line 505 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_CALLAS, (yyvsp[-1].var)); }
+-#line 3098 "parser.tab.c" /* yacc.c:1648 */
++#line 3093 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 85:
+-#line 508 "parser.y" /* yacc.c:1648 */
++#line 506 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_CASE, (yyvsp[-1].expr_list)); }
+-#line 3104 "parser.tab.c" /* yacc.c:1648 */
++#line 3099 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 86:
+-#line 509 "parser.y" /* yacc.c:1648 */
++#line 507 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_CODE); }
+-#line 3110 "parser.tab.c" /* yacc.c:1648 */
++#line 3105 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 87:
+-#line 510 "parser.y" /* yacc.c:1648 */
++#line 508 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_COMMSTATUS); }
+-#line 3116 "parser.tab.c" /* yacc.c:1648 */
++#line 3111 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 88:
+-#line 511 "parser.y" /* yacc.c:1648 */
++#line 509 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); }
+-#line 3122 "parser.tab.c" /* yacc.c:1648 */
++#line 3117 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 89:
+-#line 512 "parser.y" /* yacc.c:1648 */
++#line 510 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_DONT_SERIALIZE */ }
+-#line 3128 "parser.tab.c" /* yacc.c:1648 */
++#line 3123 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 90:
+-#line 513 "parser.y" /* yacc.c:1648 */
++#line 511 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ }
+-#line 3134 "parser.tab.c" /* yacc.c:1648 */
++#line 3129 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 91:
+-#line 514 "parser.y" /* yacc.c:1648 */
++#line 512 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_CONTROL); }
+-#line 3140 "parser.tab.c" /* yacc.c:1648 */
++#line 3135 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 92:
+-#line 515 "parser.y" /* yacc.c:1648 */
++#line 513 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_DECODE); }
+-#line 3146 "parser.tab.c" /* yacc.c:1648 */
++#line 3141 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 93:
+-#line 516 "parser.y" /* yacc.c:1648 */
++#line 514 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_DEFAULT); }
+-#line 3152 "parser.tab.c" /* yacc.c:1648 */
++#line 3147 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 94:
+-#line 517 "parser.y" /* yacc.c:1648 */
++#line 515 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_DEFAULTBIND); }
+-#line 3158 "parser.tab.c" /* yacc.c:1648 */
++#line 3153 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 95:
+-#line 518 "parser.y" /* yacc.c:1648 */
++#line 516 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_DEFAULTCOLLELEM); }
+-#line 3164 "parser.tab.c" /* yacc.c:1648 */
++#line 3159 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 96:
+-#line 519 "parser.y" /* yacc.c:1648 */
++#line 517 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_DEFAULTVALUE, (yyvsp[-1].expr)); }
+-#line 3170 "parser.tab.c" /* yacc.c:1648 */
++#line 3165 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 97:
+-#line 520 "parser.y" /* yacc.c:1648 */
++#line 518 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_DEFAULTVTABLE); }
+-#line 3176 "parser.tab.c" /* yacc.c:1648 */
++#line 3171 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 98:
+-#line 521 "parser.y" /* yacc.c:1648 */
++#line 519 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_DISABLECONSISTENCYCHECK); }
+-#line 3182 "parser.tab.c" /* yacc.c:1648 */
++#line 3177 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 99:
+-#line 522 "parser.y" /* yacc.c:1648 */
++#line 520 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_DISPLAYBIND); }
+-#line 3188 "parser.tab.c" /* yacc.c:1648 */
++#line 3183 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 100:
+-#line 523 "parser.y" /* yacc.c:1648 */
++#line 521 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_DLLNAME, (yyvsp[-1].str)); }
+-#line 3194 "parser.tab.c" /* yacc.c:1648 */
++#line 3189 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 101:
+-#line 524 "parser.y" /* yacc.c:1648 */
++#line 522 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_DUAL); }
+-#line 3200 "parser.tab.c" /* yacc.c:1648 */
++#line 3195 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 102:
+-#line 525 "parser.y" /* yacc.c:1648 */
++#line 523 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_ENABLEALLOCATE); }
+-#line 3206 "parser.tab.c" /* yacc.c:1648 */
++#line 3201 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 103:
+-#line 526 "parser.y" /* yacc.c:1648 */
++#line 524 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_ENCODE); }
+-#line 3212 "parser.tab.c" /* yacc.c:1648 */
++#line 3207 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 104:
+-#line 527 "parser.y" /* yacc.c:1648 */
++#line 525 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_ENDPOINT, (yyvsp[-1].str_list)); }
+-#line 3218 "parser.tab.c" /* yacc.c:1648 */
++#line 3213 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 105:
+-#line 528 "parser.y" /* yacc.c:1648 */
++#line 526 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_ENTRY, (yyvsp[-1].expr)); }
+-#line 3224 "parser.tab.c" /* yacc.c:1648 */
++#line 3219 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 106:
+-#line 529 "parser.y" /* yacc.c:1648 */
++#line 527 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_EXPLICIT_HANDLE); }
+-#line 3230 "parser.tab.c" /* yacc.c:1648 */
++#line 3225 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 107:
+-#line 530 "parser.y" /* yacc.c:1648 */
++#line 528 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_FAULTSTATUS); }
+-#line 3236 "parser.tab.c" /* yacc.c:1648 */
++#line 3231 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 108:
+-#line 531 "parser.y" /* yacc.c:1648 */
++#line 529 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_FORCEALLOCATE); }
+-#line 3242 "parser.tab.c" /* yacc.c:1648 */
++#line 3237 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 109:
+-#line 532 "parser.y" /* yacc.c:1648 */
++#line 530 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_HANDLE); }
+-#line 3248 "parser.tab.c" /* yacc.c:1648 */
++#line 3243 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 110:
+-#line 533 "parser.y" /* yacc.c:1648 */
++#line 531 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_HELPCONTEXT, (yyvsp[-1].expr)); }
+-#line 3254 "parser.tab.c" /* yacc.c:1648 */
++#line 3249 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 111:
+-#line 534 "parser.y" /* yacc.c:1648 */
++#line 532 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_HELPFILE, (yyvsp[-1].str)); }
+-#line 3260 "parser.tab.c" /* yacc.c:1648 */
++#line 3255 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 112:
+-#line 535 "parser.y" /* yacc.c:1648 */
++#line 533 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_HELPSTRING, (yyvsp[-1].str)); }
+-#line 3266 "parser.tab.c" /* yacc.c:1648 */
++#line 3261 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 113:
+-#line 536 "parser.y" /* yacc.c:1648 */
++#line 534 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_HELPSTRINGCONTEXT, (yyvsp[-1].expr)); }
+-#line 3272 "parser.tab.c" /* yacc.c:1648 */
++#line 3267 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 114:
+-#line 537 "parser.y" /* yacc.c:1648 */
++#line 535 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_HELPSTRINGDLL, (yyvsp[-1].str)); }
+-#line 3278 "parser.tab.c" /* yacc.c:1648 */
++#line 3273 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 115:
+-#line 538 "parser.y" /* yacc.c:1648 */
++#line 536 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_HIDDEN); }
+-#line 3284 "parser.tab.c" /* yacc.c:1648 */
++#line 3279 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 116:
+-#line 539 "parser.y" /* yacc.c:1648 */
++#line 537 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_ID, (yyvsp[-1].expr)); }
+-#line 3290 "parser.tab.c" /* yacc.c:1648 */
++#line 3285 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 117:
+-#line 540 "parser.y" /* yacc.c:1648 */
++#line 538 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_IDEMPOTENT); }
+-#line 3296 "parser.tab.c" /* yacc.c:1648 */
++#line 3291 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 118:
+-#line 541 "parser.y" /* yacc.c:1648 */
++#line 539 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_IGNORE); }
+-#line 3302 "parser.tab.c" /* yacc.c:1648 */
++#line 3297 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 119:
+-#line 542 "parser.y" /* yacc.c:1648 */
++#line 540 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_IIDIS, (yyvsp[-1].expr)); }
+-#line 3308 "parser.tab.c" /* yacc.c:1648 */
++#line 3303 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 120:
+-#line 543 "parser.y" /* yacc.c:1648 */
++#line 541 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_IMMEDIATEBIND); }
+-#line 3314 "parser.tab.c" /* yacc.c:1648 */
++#line 3309 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 121:
+-#line 544 "parser.y" /* yacc.c:1648 */
++#line 542 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_IMPLICIT_HANDLE, (yyvsp[-1].var)); }
+-#line 3320 "parser.tab.c" /* yacc.c:1648 */
++#line 3315 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 122:
+-#line 545 "parser.y" /* yacc.c:1648 */
++#line 543 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_IN); }
+-#line 3326 "parser.tab.c" /* yacc.c:1648 */
++#line 3321 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 123:
+-#line 546 "parser.y" /* yacc.c:1648 */
++#line 544 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_INPUTSYNC); }
+-#line 3332 "parser.tab.c" /* yacc.c:1648 */
++#line 3327 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 124:
+-#line 547 "parser.y" /* yacc.c:1648 */
++#line 545 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_LENGTHIS, (yyvsp[-1].expr_list)); }
+-#line 3338 "parser.tab.c" /* yacc.c:1648 */
++#line 3333 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 125:
+-#line 548 "parser.y" /* yacc.c:1648 */
++#line 546 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_LIBLCID, (yyvsp[-1].expr)); }
+-#line 3344 "parser.tab.c" /* yacc.c:1648 */
++#line 3339 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 126:
+-#line 549 "parser.y" /* yacc.c:1648 */
++#line 547 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_PARAMLCID); }
+-#line 3350 "parser.tab.c" /* yacc.c:1648 */
++#line 3345 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 127:
+-#line 550 "parser.y" /* yacc.c:1648 */
++#line 548 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_LICENSED); }
+-#line 3356 "parser.tab.c" /* yacc.c:1648 */
++#line 3351 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 128:
+-#line 551 "parser.y" /* yacc.c:1648 */
++#line 549 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_LOCAL); }
+-#line 3362 "parser.tab.c" /* yacc.c:1648 */
++#line 3357 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 129:
+-#line 552 "parser.y" /* yacc.c:1648 */
++#line 550 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_MAYBE); }
+-#line 3368 "parser.tab.c" /* yacc.c:1648 */
++#line 3363 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 130:
+-#line 553 "parser.y" /* yacc.c:1648 */
++#line 551 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_MESSAGE); }
+-#line 3374 "parser.tab.c" /* yacc.c:1648 */
++#line 3369 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 131:
+-#line 554 "parser.y" /* yacc.c:1648 */
++#line 552 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_NOCODE); }
+-#line 3380 "parser.tab.c" /* yacc.c:1648 */
++#line 3375 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 132:
+-#line 555 "parser.y" /* yacc.c:1648 */
++#line 553 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_NONBROWSABLE); }
+-#line 3386 "parser.tab.c" /* yacc.c:1648 */
++#line 3381 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 133:
+-#line 556 "parser.y" /* yacc.c:1648 */
++#line 554 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_NONCREATABLE); }
+-#line 3392 "parser.tab.c" /* yacc.c:1648 */
++#line 3387 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 134:
+-#line 557 "parser.y" /* yacc.c:1648 */
++#line 555 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_NONEXTENSIBLE); }
+-#line 3398 "parser.tab.c" /* yacc.c:1648 */
++#line 3393 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 135:
+-#line 558 "parser.y" /* yacc.c:1648 */
++#line 556 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_NOTIFY); }
+-#line 3404 "parser.tab.c" /* yacc.c:1648 */
++#line 3399 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 136:
+-#line 559 "parser.y" /* yacc.c:1648 */
++#line 557 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_NOTIFYFLAG); }
+-#line 3410 "parser.tab.c" /* yacc.c:1648 */
++#line 3405 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 137:
+-#line 560 "parser.y" /* yacc.c:1648 */
++#line 558 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_OBJECT); }
+-#line 3416 "parser.tab.c" /* yacc.c:1648 */
++#line 3411 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 138:
+-#line 561 "parser.y" /* yacc.c:1648 */
++#line 559 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_ODL); }
+-#line 3422 "parser.tab.c" /* yacc.c:1648 */
++#line 3417 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 139:
+-#line 562 "parser.y" /* yacc.c:1648 */
++#line 560 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_OLEAUTOMATION); }
+-#line 3428 "parser.tab.c" /* yacc.c:1648 */
++#line 3423 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 140:
+-#line 563 "parser.y" /* yacc.c:1648 */
++#line 561 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_OPTIMIZE, (yyvsp[-1].str)); }
+-#line 3434 "parser.tab.c" /* yacc.c:1648 */
++#line 3429 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 141:
+-#line 564 "parser.y" /* yacc.c:1648 */
++#line 562 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_OPTIONAL); }
+-#line 3440 "parser.tab.c" /* yacc.c:1648 */
++#line 3435 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 142:
+-#line 565 "parser.y" /* yacc.c:1648 */
++#line 563 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_OUT); }
+-#line 3446 "parser.tab.c" /* yacc.c:1648 */
++#line 3441 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 143:
+-#line 566 "parser.y" /* yacc.c:1648 */
++#line 564 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_PARTIALIGNORE); }
+-#line 3452 "parser.tab.c" /* yacc.c:1648 */
++#line 3447 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 144:
+-#line 567 "parser.y" /* yacc.c:1648 */
++#line 565 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrv(ATTR_POINTERDEFAULT, (yyvsp[-1].num)); }
+-#line 3458 "parser.tab.c" /* yacc.c:1648 */
++#line 3453 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 145:
+-#line 568 "parser.y" /* yacc.c:1648 */
++#line 566 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_PROGID, (yyvsp[-1].str)); }
+-#line 3464 "parser.tab.c" /* yacc.c:1648 */
++#line 3459 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 146:
+-#line 569 "parser.y" /* yacc.c:1648 */
++#line 567 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_PROPGET); }
+-#line 3470 "parser.tab.c" /* yacc.c:1648 */
++#line 3465 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 147:
+-#line 570 "parser.y" /* yacc.c:1648 */
++#line 568 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_PROPPUT); }
+-#line 3476 "parser.tab.c" /* yacc.c:1648 */
++#line 3471 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 148:
+-#line 571 "parser.y" /* yacc.c:1648 */
++#line 569 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_PROPPUTREF); }
+-#line 3482 "parser.tab.c" /* yacc.c:1648 */
++#line 3477 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 149:
+-#line 572 "parser.y" /* yacc.c:1648 */
++#line 570 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_PROXY); }
+-#line 3488 "parser.tab.c" /* yacc.c:1648 */
++#line 3483 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 150:
+-#line 573 "parser.y" /* yacc.c:1648 */
++#line 571 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_PUBLIC); }
+-#line 3494 "parser.tab.c" /* yacc.c:1648 */
++#line 3489 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 151:
+-#line 575 "parser.y" /* yacc.c:1648 */
++#line 573 "parser.y" /* yacc.c:1646 */
+ { expr_list_t *list = append_expr( NULL, (yyvsp[-3].expr) );
+ list = append_expr( list, (yyvsp[-1].expr) );
+ (yyval.attr) = make_attrp(ATTR_RANGE, list); }
+-#line 3502 "parser.tab.c" /* yacc.c:1648 */
++#line 3497 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 152:
+-#line 578 "parser.y" /* yacc.c:1648 */
++#line 576 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_READONLY); }
+-#line 3508 "parser.tab.c" /* yacc.c:1648 */
++#line 3503 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 153:
+-#line 579 "parser.y" /* yacc.c:1648 */
++#line 577 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_REPRESENTAS, (yyvsp[-1].type)); }
+-#line 3514 "parser.tab.c" /* yacc.c:1648 */
++#line 3509 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 154:
+-#line 580 "parser.y" /* yacc.c:1648 */
++#line 578 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_REQUESTEDIT); }
+-#line 3520 "parser.tab.c" /* yacc.c:1648 */
++#line 3515 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 155:
+-#line 581 "parser.y" /* yacc.c:1648 */
++#line 579 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_RESTRICTED); }
+-#line 3526 "parser.tab.c" /* yacc.c:1648 */
++#line 3521 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 156:
+-#line 582 "parser.y" /* yacc.c:1648 */
++#line 580 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_RETVAL); }
+-#line 3532 "parser.tab.c" /* yacc.c:1648 */
++#line 3527 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 157:
+-#line 583 "parser.y" /* yacc.c:1648 */
++#line 581 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_SIZEIS, (yyvsp[-1].expr_list)); }
+-#line 3538 "parser.tab.c" /* yacc.c:1648 */
++#line 3533 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 158:
+-#line 584 "parser.y" /* yacc.c:1648 */
++#line 582 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_SOURCE); }
+-#line 3544 "parser.tab.c" /* yacc.c:1648 */
++#line 3539 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 159:
+-#line 585 "parser.y" /* yacc.c:1648 */
++#line 583 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_STRICTCONTEXTHANDLE); }
+-#line 3550 "parser.tab.c" /* yacc.c:1648 */
++#line 3545 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 160:
+-#line 586 "parser.y" /* yacc.c:1648 */
++#line 584 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_STRING); }
+-#line 3556 "parser.tab.c" /* yacc.c:1648 */
++#line 3551 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 161:
+-#line 587 "parser.y" /* yacc.c:1648 */
++#line 585 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_SWITCHIS, (yyvsp[-1].expr)); }
+-#line 3562 "parser.tab.c" /* yacc.c:1648 */
++#line 3557 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 162:
+-#line 588 "parser.y" /* yacc.c:1648 */
++#line 586 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_SWITCHTYPE, (yyvsp[-1].type)); }
+-#line 3568 "parser.tab.c" /* yacc.c:1648 */
++#line 3563 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 163:
+-#line 589 "parser.y" /* yacc.c:1648 */
++#line 587 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_TRANSMITAS, (yyvsp[-1].type)); }
+-#line 3574 "parser.tab.c" /* yacc.c:1648 */
++#line 3569 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 164:
+-#line 590 "parser.y" /* yacc.c:1648 */
++#line 588 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrv(ATTR_THREADING, (yyvsp[-1].num)); }
+-#line 3580 "parser.tab.c" /* yacc.c:1648 */
++#line 3575 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 165:
+-#line 591 "parser.y" /* yacc.c:1648 */
++#line 589 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_UIDEFAULT); }
+-#line 3586 "parser.tab.c" /* yacc.c:1648 */
++#line 3581 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 166:
+-#line 592 "parser.y" /* yacc.c:1648 */
++#line 590 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_USESGETLASTERROR); }
+-#line 3592 "parser.tab.c" /* yacc.c:1648 */
++#line 3587 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 167:
+-#line 593 "parser.y" /* yacc.c:1648 */
++#line 591 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_USERMARSHAL, (yyvsp[-1].type)); }
+-#line 3598 "parser.tab.c" /* yacc.c:1648 */
++#line 3593 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 168:
+-#line 594 "parser.y" /* yacc.c:1648 */
++#line 592 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_UUID, (yyvsp[-1].uuid)); }
+-#line 3604 "parser.tab.c" /* yacc.c:1648 */
++#line 3599 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 169:
+-#line 595 "parser.y" /* yacc.c:1648 */
++#line 593 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_ASYNCUUID, (yyvsp[-1].uuid)); }
+-#line 3610 "parser.tab.c" /* yacc.c:1648 */
++#line 3605 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 170:
+-#line 596 "parser.y" /* yacc.c:1648 */
++#line 594 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_V1ENUM); }
+-#line 3616 "parser.tab.c" /* yacc.c:1648 */
++#line 3611 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 171:
+-#line 597 "parser.y" /* yacc.c:1648 */
++#line 595 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_VARARG); }
+-#line 3622 "parser.tab.c" /* yacc.c:1648 */
++#line 3617 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 172:
+-#line 598 "parser.y" /* yacc.c:1648 */
++#line 596 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrv(ATTR_VERSION, (yyvsp[-1].num)); }
+-#line 3628 "parser.tab.c" /* yacc.c:1648 */
++#line 3623 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 173:
+-#line 599 "parser.y" /* yacc.c:1648 */
++#line 597 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_VIPROGID, (yyvsp[-1].str)); }
+-#line 3634 "parser.tab.c" /* yacc.c:1648 */
++#line 3629 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 174:
+-#line 600 "parser.y" /* yacc.c:1648 */
++#line 598 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_WIREMARSHAL, (yyvsp[-1].type)); }
+-#line 3640 "parser.tab.c" /* yacc.c:1648 */
++#line 3635 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 175:
+-#line 601 "parser.y" /* yacc.c:1648 */
++#line 599 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrv(ATTR_POINTERTYPE, (yyvsp[0].num)); }
+-#line 3646 "parser.tab.c" /* yacc.c:1648 */
++#line 3641 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 177:
+-#line 606 "parser.y" /* yacc.c:1648 */
++#line 604 "parser.y" /* yacc.c:1646 */
+ { if (!is_valid_uuid((yyvsp[0].str)))
+ error_loc("invalid UUID: %s\n", (yyvsp[0].str));
+ (yyval.uuid) = parse_uuid((yyvsp[0].str)); }
+-#line 3654 "parser.tab.c" /* yacc.c:1648 */
++#line 3649 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 178:
+-#line 611 "parser.y" /* yacc.c:1648 */
++#line 609 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = xstrdup("__cdecl"); }
+-#line 3660 "parser.tab.c" /* yacc.c:1648 */
++#line 3655 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 179:
+-#line 612 "parser.y" /* yacc.c:1648 */
++#line 610 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = xstrdup("__fastcall"); }
+-#line 3666 "parser.tab.c" /* yacc.c:1648 */
++#line 3661 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 180:
+-#line 613 "parser.y" /* yacc.c:1648 */
++#line 611 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = xstrdup("__pascal"); }
+-#line 3672 "parser.tab.c" /* yacc.c:1648 */
++#line 3667 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 181:
+-#line 614 "parser.y" /* yacc.c:1648 */
++#line 612 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = xstrdup("__stdcall"); }
+-#line 3678 "parser.tab.c" /* yacc.c:1648 */
++#line 3673 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 182:
+-#line 617 "parser.y" /* yacc.c:1648 */
++#line 615 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = NULL; }
+-#line 3684 "parser.tab.c" /* yacc.c:1648 */
++#line 3679 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 183:
+-#line 618 "parser.y" /* yacc.c:1648 */
++#line 616 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = append_var( (yyvsp[-1].var_list), (yyvsp[0].var) ); }
+-#line 3690 "parser.tab.c" /* yacc.c:1648 */
++#line 3685 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 184:
+-#line 621 "parser.y" /* yacc.c:1648 */
++#line 619 "parser.y" /* yacc.c:1646 */
+ { attr_t *a = make_attrp(ATTR_CASE, append_expr( NULL, (yyvsp[-2].expr) ));
+ (yyval.var) = (yyvsp[0].var); if (!(yyval.var)) (yyval.var) = make_var(NULL);
+ (yyval.var)->attrs = append_attr( (yyval.var)->attrs, a );
+ }
+-#line 3699 "parser.tab.c" /* yacc.c:1648 */
++#line 3694 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 185:
+-#line 625 "parser.y" /* yacc.c:1648 */
++#line 623 "parser.y" /* yacc.c:1646 */
+ { attr_t *a = make_attr(ATTR_DEFAULT);
+ (yyval.var) = (yyvsp[0].var); if (!(yyval.var)) (yyval.var) = make_var(NULL);
+ (yyval.var)->attrs = append_attr( (yyval.var)->attrs, a );
+ }
+-#line 3708 "parser.tab.c" /* yacc.c:1648 */
++#line 3703 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 186:
+-#line 631 "parser.y" /* yacc.c:1648 */
++#line 629 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = NULL; }
+-#line 3714 "parser.tab.c" /* yacc.c:1648 */
++#line 3709 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 187:
+-#line 632 "parser.y" /* yacc.c:1648 */
++#line 630 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = (yyvsp[-1].var_list); }
+-#line 3720 "parser.tab.c" /* yacc.c:1648 */
++#line 3715 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 189:
+-#line 636 "parser.y" /* yacc.c:1648 */
++#line 634 "parser.y" /* yacc.c:1646 */
+ { if (!(yyvsp[0].var)->eval)
+ (yyvsp[0].var)->eval = make_exprl(EXPR_NUM, 0 /* default for first enum entry */);
+ (yyval.var_list) = append_var( NULL, (yyvsp[0].var) );
+ }
+-#line 3729 "parser.tab.c" /* yacc.c:1648 */
++#line 3724 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 190:
+-#line 640 "parser.y" /* yacc.c:1648 */
++#line 638 "parser.y" /* yacc.c:1646 */
+ { if (!(yyvsp[0].var)->eval)
+ {
+ var_t *last = LIST_ENTRY( list_tail((yyval.var_list)), var_t, entry );
+@@ -3740,656 +3735,656 @@ yyreduce:
+ }
+ (yyval.var_list) = append_var( (yyvsp[-2].var_list), (yyvsp[0].var) );
+ }
+-#line 3744 "parser.tab.c" /* yacc.c:1648 */
++#line 3739 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 191:
+-#line 652 "parser.y" /* yacc.c:1648 */
++#line 650 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = reg_const((yyvsp[-2].var));
+ (yyval.var)->eval = (yyvsp[0].expr);
+- (yyval.var)->type = type_new_int(TYPE_BASIC_INT, 0);
++ (yyval.var)->declspec.type = type_new_int(TYPE_BASIC_INT, 0);
+ }
+-#line 3753 "parser.tab.c" /* yacc.c:1648 */
++#line 3748 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 192:
+-#line 656 "parser.y" /* yacc.c:1648 */
++#line 654 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = reg_const((yyvsp[0].var));
+- (yyval.var)->type = type_new_int(TYPE_BASIC_INT, 0);
++ (yyval.var)->declspec.type = type_new_int(TYPE_BASIC_INT, 0);
+ }
+-#line 3761 "parser.tab.c" /* yacc.c:1648 */
++#line 3756 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 193:
+-#line 661 "parser.y" /* yacc.c:1648 */
++#line 659 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_enum((yyvsp[-3].str), current_namespace, TRUE, (yyvsp[-1].var_list)); }
+-#line 3767 "parser.tab.c" /* yacc.c:1648 */
++#line 3762 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 194:
+-#line 664 "parser.y" /* yacc.c:1648 */
++#line 662 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr_list) = append_expr( NULL, (yyvsp[0].expr) ); }
+-#line 3773 "parser.tab.c" /* yacc.c:1648 */
++#line 3768 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 195:
+-#line 665 "parser.y" /* yacc.c:1648 */
++#line 663 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr_list) = append_expr( (yyvsp[-2].expr_list), (yyvsp[0].expr) ); }
+-#line 3779 "parser.tab.c" /* yacc.c:1648 */
++#line 3774 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 196:
+-#line 668 "parser.y" /* yacc.c:1648 */
++#line 666 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr(EXPR_VOID); }
+-#line 3785 "parser.tab.c" /* yacc.c:1648 */
++#line 3780 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 198:
+-#line 672 "parser.y" /* yacc.c:1648 */
++#line 670 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprl(EXPR_NUM, (yyvsp[0].num)); }
+-#line 3791 "parser.tab.c" /* yacc.c:1648 */
++#line 3786 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 199:
+-#line 673 "parser.y" /* yacc.c:1648 */
++#line 671 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprl(EXPR_HEXNUM, (yyvsp[0].num)); }
+-#line 3797 "parser.tab.c" /* yacc.c:1648 */
++#line 3792 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 200:
+-#line 674 "parser.y" /* yacc.c:1648 */
++#line 672 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprd(EXPR_DOUBLE, (yyvsp[0].dbl)); }
+-#line 3803 "parser.tab.c" /* yacc.c:1648 */
++#line 3798 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 201:
+-#line 675 "parser.y" /* yacc.c:1648 */
++#line 673 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprl(EXPR_TRUEFALSE, 0); }
+-#line 3809 "parser.tab.c" /* yacc.c:1648 */
++#line 3804 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 202:
+-#line 676 "parser.y" /* yacc.c:1648 */
++#line 674 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprl(EXPR_NUM, 0); }
+-#line 3815 "parser.tab.c" /* yacc.c:1648 */
++#line 3810 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 203:
+-#line 677 "parser.y" /* yacc.c:1648 */
++#line 675 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprl(EXPR_TRUEFALSE, 1); }
+-#line 3821 "parser.tab.c" /* yacc.c:1648 */
++#line 3816 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 204:
+-#line 678 "parser.y" /* yacc.c:1648 */
++#line 676 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprs(EXPR_STRLIT, (yyvsp[0].str)); }
+-#line 3827 "parser.tab.c" /* yacc.c:1648 */
++#line 3822 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 205:
+-#line 679 "parser.y" /* yacc.c:1648 */
++#line 677 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprs(EXPR_WSTRLIT, (yyvsp[0].str)); }
+-#line 3833 "parser.tab.c" /* yacc.c:1648 */
++#line 3828 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 206:
+-#line 680 "parser.y" /* yacc.c:1648 */
++#line 678 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprs(EXPR_CHARCONST, (yyvsp[0].str)); }
+-#line 3839 "parser.tab.c" /* yacc.c:1648 */
++#line 3834 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 207:
+-#line 681 "parser.y" /* yacc.c:1648 */
++#line 679 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprs(EXPR_IDENTIFIER, (yyvsp[0].str)); }
+-#line 3845 "parser.tab.c" /* yacc.c:1648 */
++#line 3840 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 208:
+-#line 682 "parser.y" /* yacc.c:1648 */
++#line 680 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr3(EXPR_COND, (yyvsp[-4].expr), (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3851 "parser.tab.c" /* yacc.c:1648 */
++#line 3846 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 209:
+-#line 683 "parser.y" /* yacc.c:1648 */
++#line 681 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_LOGOR, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3857 "parser.tab.c" /* yacc.c:1648 */
++#line 3852 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 210:
+-#line 684 "parser.y" /* yacc.c:1648 */
++#line 682 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_LOGAND, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3863 "parser.tab.c" /* yacc.c:1648 */
++#line 3858 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 211:
+-#line 685 "parser.y" /* yacc.c:1648 */
++#line 683 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_OR , (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3869 "parser.tab.c" /* yacc.c:1648 */
++#line 3864 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 212:
+-#line 686 "parser.y" /* yacc.c:1648 */
++#line 684 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_XOR, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3875 "parser.tab.c" /* yacc.c:1648 */
++#line 3870 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 213:
+-#line 687 "parser.y" /* yacc.c:1648 */
++#line 685 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_AND, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3881 "parser.tab.c" /* yacc.c:1648 */
++#line 3876 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 214:
+-#line 688 "parser.y" /* yacc.c:1648 */
++#line 686 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_EQUALITY, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3887 "parser.tab.c" /* yacc.c:1648 */
++#line 3882 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 215:
+-#line 689 "parser.y" /* yacc.c:1648 */
++#line 687 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_INEQUALITY, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3893 "parser.tab.c" /* yacc.c:1648 */
++#line 3888 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 216:
+-#line 690 "parser.y" /* yacc.c:1648 */
++#line 688 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_GTR, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3899 "parser.tab.c" /* yacc.c:1648 */
++#line 3894 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 217:
+-#line 691 "parser.y" /* yacc.c:1648 */
++#line 689 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_LESS, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3905 "parser.tab.c" /* yacc.c:1648 */
++#line 3900 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 218:
+-#line 692 "parser.y" /* yacc.c:1648 */
++#line 690 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_GTREQL, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3911 "parser.tab.c" /* yacc.c:1648 */
++#line 3906 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 219:
+-#line 693 "parser.y" /* yacc.c:1648 */
++#line 691 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_LESSEQL, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3917 "parser.tab.c" /* yacc.c:1648 */
++#line 3912 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 220:
+-#line 694 "parser.y" /* yacc.c:1648 */
++#line 692 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_SHL, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3923 "parser.tab.c" /* yacc.c:1648 */
++#line 3918 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 221:
+-#line 695 "parser.y" /* yacc.c:1648 */
++#line 693 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_SHR, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3929 "parser.tab.c" /* yacc.c:1648 */
++#line 3924 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 222:
+-#line 696 "parser.y" /* yacc.c:1648 */
++#line 694 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_ADD, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3935 "parser.tab.c" /* yacc.c:1648 */
++#line 3930 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 223:
+-#line 697 "parser.y" /* yacc.c:1648 */
++#line 695 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_SUB, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3941 "parser.tab.c" /* yacc.c:1648 */
++#line 3936 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 224:
+-#line 698 "parser.y" /* yacc.c:1648 */
++#line 696 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_MOD, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3947 "parser.tab.c" /* yacc.c:1648 */
++#line 3942 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 225:
+-#line 699 "parser.y" /* yacc.c:1648 */
++#line 697 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_MUL, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3953 "parser.tab.c" /* yacc.c:1648 */
++#line 3948 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 226:
+-#line 700 "parser.y" /* yacc.c:1648 */
++#line 698 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_DIV, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3959 "parser.tab.c" /* yacc.c:1648 */
++#line 3954 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 227:
+-#line 701 "parser.y" /* yacc.c:1648 */
++#line 699 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr1(EXPR_LOGNOT, (yyvsp[0].expr)); }
+-#line 3965 "parser.tab.c" /* yacc.c:1648 */
++#line 3960 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 228:
+-#line 702 "parser.y" /* yacc.c:1648 */
++#line 700 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr1(EXPR_NOT, (yyvsp[0].expr)); }
+-#line 3971 "parser.tab.c" /* yacc.c:1648 */
++#line 3966 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 229:
+-#line 703 "parser.y" /* yacc.c:1648 */
++#line 701 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr1(EXPR_POS, (yyvsp[0].expr)); }
+-#line 3977 "parser.tab.c" /* yacc.c:1648 */
++#line 3972 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 230:
+-#line 704 "parser.y" /* yacc.c:1648 */
++#line 702 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr1(EXPR_NEG, (yyvsp[0].expr)); }
+-#line 3983 "parser.tab.c" /* yacc.c:1648 */
++#line 3978 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 231:
+-#line 705 "parser.y" /* yacc.c:1648 */
++#line 703 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr1(EXPR_ADDRESSOF, (yyvsp[0].expr)); }
+-#line 3989 "parser.tab.c" /* yacc.c:1648 */
++#line 3984 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 232:
+-#line 706 "parser.y" /* yacc.c:1648 */
++#line 704 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr1(EXPR_PPTR, (yyvsp[0].expr)); }
+-#line 3995 "parser.tab.c" /* yacc.c:1648 */
++#line 3990 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 233:
+-#line 707 "parser.y" /* yacc.c:1648 */
++#line 705 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_MEMBER, make_expr1(EXPR_PPTR, (yyvsp[-2].expr)), make_exprs(EXPR_IDENTIFIER, (yyvsp[0].str))); }
+-#line 4001 "parser.tab.c" /* yacc.c:1648 */
++#line 3996 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 234:
+-#line 708 "parser.y" /* yacc.c:1648 */
++#line 706 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_MEMBER, (yyvsp[-2].expr), make_exprs(EXPR_IDENTIFIER, (yyvsp[0].str))); }
+-#line 4007 "parser.tab.c" /* yacc.c:1648 */
++#line 4002 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 235:
+-#line 710 "parser.y" /* yacc.c:1648 */
++#line 708 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprt(EXPR_CAST, declare_var(NULL, (yyvsp[-3].declspec), (yyvsp[-2].declarator), 0), (yyvsp[0].expr)); free((yyvsp[-3].declspec)); free((yyvsp[-2].declarator)); }
+-#line 4013 "parser.tab.c" /* yacc.c:1648 */
++#line 4008 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 236:
+-#line 712 "parser.y" /* yacc.c:1648 */
++#line 710 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprt(EXPR_SIZEOF, declare_var(NULL, (yyvsp[-2].declspec), (yyvsp[-1].declarator), 0), NULL); free((yyvsp[-2].declspec)); free((yyvsp[-1].declarator)); }
+-#line 4019 "parser.tab.c" /* yacc.c:1648 */
++#line 4014 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 237:
+-#line 713 "parser.y" /* yacc.c:1648 */
++#line 711 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_ARRAY, (yyvsp[-3].expr), (yyvsp[-1].expr)); }
+-#line 4025 "parser.tab.c" /* yacc.c:1648 */
++#line 4020 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 238:
+-#line 714 "parser.y" /* yacc.c:1648 */
++#line 712 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = (yyvsp[-1].expr); }
+-#line 4031 "parser.tab.c" /* yacc.c:1648 */
++#line 4026 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 239:
+-#line 717 "parser.y" /* yacc.c:1648 */
++#line 715 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr_list) = append_expr( NULL, (yyvsp[0].expr) ); }
+-#line 4037 "parser.tab.c" /* yacc.c:1648 */
++#line 4032 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 240:
+-#line 718 "parser.y" /* yacc.c:1648 */
++#line 716 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr_list) = append_expr( (yyvsp[-2].expr_list), (yyvsp[0].expr) ); }
+-#line 4043 "parser.tab.c" /* yacc.c:1648 */
++#line 4038 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 241:
+-#line 721 "parser.y" /* yacc.c:1648 */
++#line 719 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = (yyvsp[0].expr);
+ if (!(yyval.expr)->is_const)
+ error_loc("expression is not an integer constant\n");
+ }
+-#line 4052 "parser.tab.c" /* yacc.c:1648 */
++#line 4047 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 242:
+-#line 727 "parser.y" /* yacc.c:1648 */
++#line 725 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = (yyvsp[0].expr);
+ if (!(yyval.expr)->is_const && (yyval.expr)->type != EXPR_STRLIT && (yyval.expr)->type != EXPR_WSTRLIT)
+ error_loc("expression is not constant\n");
+ }
+-#line 4061 "parser.tab.c" /* yacc.c:1648 */
++#line 4056 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 243:
+-#line 733 "parser.y" /* yacc.c:1648 */
++#line 731 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = NULL; }
+-#line 4067 "parser.tab.c" /* yacc.c:1648 */
++#line 4062 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 244:
+-#line 734 "parser.y" /* yacc.c:1648 */
++#line 732 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = append_var_list((yyvsp[-1].var_list), (yyvsp[0].var_list)); }
+-#line 4073 "parser.tab.c" /* yacc.c:1648 */
++#line 4068 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 245:
+-#line 738 "parser.y" /* yacc.c:1648 */
++#line 736 "parser.y" /* yacc.c:1646 */
+ { const char *first = LIST_ENTRY(list_head((yyvsp[-1].declarator_list)), declarator_t, entry)->var->name;
+ check_field_attrs(first, (yyvsp[-3].attr_list));
+ (yyval.var_list) = set_var_types((yyvsp[-3].attr_list), (yyvsp[-2].declspec), (yyvsp[-1].declarator_list));
+ }
+-#line 4082 "parser.tab.c" /* yacc.c:1648 */
++#line 4077 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 246:
+-#line 742 "parser.y" /* yacc.c:1648 */
++#line 740 "parser.y" /* yacc.c:1646 */
+ { var_t *v = make_var(NULL);
+- v->type = (yyvsp[-1].type); v->attrs = (yyvsp[-2].attr_list);
++ v->declspec.type = (yyvsp[-1].type); v->attrs = (yyvsp[-2].attr_list);
+ (yyval.var_list) = append_var(NULL, v);
+ }
+-#line 4091 "parser.tab.c" /* yacc.c:1648 */
++#line 4086 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 247:
+-#line 749 "parser.y" /* yacc.c:1648 */
++#line 747 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = (yyvsp[-1].var); }
+-#line 4097 "parser.tab.c" /* yacc.c:1648 */
++#line 4092 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 248:
+-#line 750 "parser.y" /* yacc.c:1648 */
++#line 748 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = make_var(NULL); (yyval.var)->attrs = (yyvsp[-1].attr_list); }
+-#line 4103 "parser.tab.c" /* yacc.c:1648 */
++#line 4098 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 249:
+-#line 753 "parser.y" /* yacc.c:1648 */
++#line 751 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = NULL; }
+-#line 4109 "parser.tab.c" /* yacc.c:1648 */
++#line 4104 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 250:
+-#line 754 "parser.y" /* yacc.c:1648 */
++#line 752 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = append_var( (yyvsp[-1].var_list), (yyvsp[0].var) ); }
+-#line 4115 "parser.tab.c" /* yacc.c:1648 */
++#line 4110 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 251:
+-#line 758 "parser.y" /* yacc.c:1648 */
++#line 756 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = (yyvsp[-1].var); }
+-#line 4121 "parser.tab.c" /* yacc.c:1648 */
++#line 4116 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 252:
+-#line 759 "parser.y" /* yacc.c:1648 */
++#line 757 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = NULL; }
+-#line 4127 "parser.tab.c" /* yacc.c:1648 */
++#line 4122 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 253:
+-#line 762 "parser.y" /* yacc.c:1648 */
++#line 760 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = declare_var(check_field_attrs((yyvsp[0].declarator)->var->name, (yyvsp[-2].attr_list)),
+ (yyvsp[-1].declspec), (yyvsp[0].declarator), FALSE);
+ free((yyvsp[0].declarator));
+ }
+-#line 4136 "parser.tab.c" /* yacc.c:1648 */
++#line 4131 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 254:
+-#line 766 "parser.y" /* yacc.c:1648 */
++#line 764 "parser.y" /* yacc.c:1646 */
+ { var_t *v = make_var(NULL);
+- v->type = (yyvsp[0].type); v->attrs = (yyvsp[-1].attr_list);
++ v->declspec.type = (yyvsp[0].type); v->attrs = (yyvsp[-1].attr_list);
+ (yyval.var) = v;
+ }
+-#line 4145 "parser.tab.c" /* yacc.c:1648 */
++#line 4140 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 255:
+-#line 772 "parser.y" /* yacc.c:1648 */
++#line 770 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = (yyvsp[0].var);
+- if (type_get_type((yyval.var)->type) != TYPE_FUNCTION)
++ if (type_get_type((yyval.var)->declspec.type) != TYPE_FUNCTION)
+ error_loc("only methods may be declared inside the methods section of a dispinterface\n");
+ check_function_attrs((yyval.var)->name, (yyval.var)->attrs);
+ }
+-#line 4155 "parser.tab.c" /* yacc.c:1648 */
++#line 4150 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 256:
+-#line 781 "parser.y" /* yacc.c:1648 */
++#line 779 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = declare_var((yyvsp[-2].attr_list), (yyvsp[-1].declspec), (yyvsp[0].declarator), FALSE);
+ free((yyvsp[0].declarator));
+ }
+-#line 4163 "parser.tab.c" /* yacc.c:1648 */
++#line 4158 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 257:
+-#line 784 "parser.y" /* yacc.c:1648 */
++#line 782 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = declare_var(NULL, (yyvsp[-1].declspec), (yyvsp[0].declarator), FALSE);
+ free((yyvsp[0].declarator));
+ }
+-#line 4171 "parser.tab.c" /* yacc.c:1648 */
++#line 4166 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 258:
+-#line 789 "parser.y" /* yacc.c:1648 */
++#line 787 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = NULL; }
+-#line 4177 "parser.tab.c" /* yacc.c:1648 */
++#line 4172 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 260:
+-#line 793 "parser.y" /* yacc.c:1648 */
++#line 791 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = NULL; }
+-#line 4183 "parser.tab.c" /* yacc.c:1648 */
++#line 4178 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 261:
+-#line 794 "parser.y" /* yacc.c:1648 */
++#line 792 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = (yyvsp[0].str); }
+-#line 4189 "parser.tab.c" /* yacc.c:1648 */
++#line 4184 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 262:
+-#line 795 "parser.y" /* yacc.c:1648 */
++#line 793 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = (yyvsp[0].str); }
+-#line 4195 "parser.tab.c" /* yacc.c:1648 */
++#line 4190 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 263:
+-#line 798 "parser.y" /* yacc.c:1648 */
++#line 796 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = make_var((yyvsp[0].str)); }
+-#line 4201 "parser.tab.c" /* yacc.c:1648 */
++#line 4196 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 264:
+-#line 800 "parser.y" /* yacc.c:1648 */
++#line 798 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = make_var((yyvsp[0].str)); }
+-#line 4207 "parser.tab.c" /* yacc.c:1648 */
++#line 4202 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 265:
+-#line 803 "parser.y" /* yacc.c:1648 */
++#line 801 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
+-#line 4213 "parser.tab.c" /* yacc.c:1648 */
++#line 4208 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 266:
+-#line 804 "parser.y" /* yacc.c:1648 */
++#line 802 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
+-#line 4219 "parser.tab.c" /* yacc.c:1648 */
++#line 4214 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 268:
+-#line 806 "parser.y" /* yacc.c:1648 */
++#line 804 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(type_basic_get_type((yyvsp[0].type)), -1); }
+-#line 4225 "parser.tab.c" /* yacc.c:1648 */
++#line 4220 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 269:
+-#line 807 "parser.y" /* yacc.c:1648 */
++#line 805 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(type_basic_get_type((yyvsp[0].type)), 1); }
+-#line 4231 "parser.tab.c" /* yacc.c:1648 */
++#line 4226 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 270:
+-#line 808 "parser.y" /* yacc.c:1648 */
++#line 806 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(TYPE_BASIC_INT, 1); }
+-#line 4237 "parser.tab.c" /* yacc.c:1648 */
++#line 4232 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 271:
+-#line 809 "parser.y" /* yacc.c:1648 */
++#line 807 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
+-#line 4243 "parser.tab.c" /* yacc.c:1648 */
++#line 4238 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 272:
+-#line 810 "parser.y" /* yacc.c:1648 */
++#line 808 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
+-#line 4249 "parser.tab.c" /* yacc.c:1648 */
++#line 4244 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 273:
+-#line 811 "parser.y" /* yacc.c:1648 */
++#line 809 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
+-#line 4255 "parser.tab.c" /* yacc.c:1648 */
++#line 4250 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 274:
+-#line 812 "parser.y" /* yacc.c:1648 */
++#line 810 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
+-#line 4261 "parser.tab.c" /* yacc.c:1648 */
++#line 4256 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 275:
+-#line 813 "parser.y" /* yacc.c:1648 */
++#line 811 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
+-#line 4267 "parser.tab.c" /* yacc.c:1648 */
++#line 4262 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 278:
+-#line 820 "parser.y" /* yacc.c:1648 */
++#line 818 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(TYPE_BASIC_INT, 0); }
+-#line 4273 "parser.tab.c" /* yacc.c:1648 */
++#line 4268 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 279:
+-#line 821 "parser.y" /* yacc.c:1648 */
++#line 819 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(TYPE_BASIC_INT16, 0); }
+-#line 4279 "parser.tab.c" /* yacc.c:1648 */
++#line 4274 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 280:
+-#line 822 "parser.y" /* yacc.c:1648 */
++#line 820 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(TYPE_BASIC_INT8, 0); }
+-#line 4285 "parser.tab.c" /* yacc.c:1648 */
++#line 4280 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 281:
+-#line 823 "parser.y" /* yacc.c:1648 */
++#line 821 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(TYPE_BASIC_LONG, 0); }
+-#line 4291 "parser.tab.c" /* yacc.c:1648 */
++#line 4286 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 282:
+-#line 824 "parser.y" /* yacc.c:1648 */
++#line 822 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(TYPE_BASIC_HYPER, 0); }
+-#line 4297 "parser.tab.c" /* yacc.c:1648 */
++#line 4292 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 283:
+-#line 825 "parser.y" /* yacc.c:1648 */
++#line 823 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(TYPE_BASIC_INT64, 0); }
+-#line 4303 "parser.tab.c" /* yacc.c:1648 */
++#line 4298 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 284:
+-#line 826 "parser.y" /* yacc.c:1648 */
++#line 824 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(TYPE_BASIC_CHAR, 0); }
+-#line 4309 "parser.tab.c" /* yacc.c:1648 */
++#line 4304 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 285:
+-#line 827 "parser.y" /* yacc.c:1648 */
++#line 825 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(TYPE_BASIC_INT32, 0); }
+-#line 4315 "parser.tab.c" /* yacc.c:1648 */
++#line 4310 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 286:
+-#line 828 "parser.y" /* yacc.c:1648 */
++#line 826 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(TYPE_BASIC_INT3264, 0); }
+-#line 4321 "parser.tab.c" /* yacc.c:1648 */
++#line 4316 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 287:
+-#line 831 "parser.y" /* yacc.c:1648 */
++#line 829 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_coclass((yyvsp[0].str)); }
+-#line 4327 "parser.tab.c" /* yacc.c:1648 */
++#line 4322 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 288:
+-#line 832 "parser.y" /* yacc.c:1648 */
++#line 830 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = find_type((yyvsp[0].str), NULL, 0);
+ if (type_get_type_detect_alias((yyval.type)) != TYPE_COCLASS)
+ error_loc("%s was not declared a coclass at %s:%d\n",
+ (yyvsp[0].str), (yyval.type)->loc_info.input_name,
+ (yyval.type)->loc_info.line_number);
+ }
+-#line 4338 "parser.tab.c" /* yacc.c:1648 */
++#line 4333 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 289:
+-#line 840 "parser.y" /* yacc.c:1648 */
++#line 838 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[0].type);
+ check_def((yyval.type));
+ (yyval.type)->attrs = check_coclass_attrs((yyvsp[0].type)->name, (yyvsp[-1].attr_list));
+ }
+-#line 4347 "parser.tab.c" /* yacc.c:1648 */
++#line 4342 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 290:
+-#line 847 "parser.y" /* yacc.c:1648 */
++#line 845 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_coclass_define((yyvsp[-4].type), (yyvsp[-2].ifref_list)); }
+-#line 4353 "parser.tab.c" /* yacc.c:1648 */
++#line 4348 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 291:
+-#line 850 "parser.y" /* yacc.c:1648 */
++#line 848 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = (yyvsp[0].str); }
+-#line 4359 "parser.tab.c" /* yacc.c:1648 */
++#line 4354 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 292:
+-#line 853 "parser.y" /* yacc.c:1648 */
++#line 851 "parser.y" /* yacc.c:1646 */
+ { (yyval.ifref_list) = NULL; }
+-#line 4365 "parser.tab.c" /* yacc.c:1648 */
++#line 4360 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 293:
+-#line 854 "parser.y" /* yacc.c:1648 */
++#line 852 "parser.y" /* yacc.c:1646 */
+ { (yyval.ifref_list) = append_ifref( (yyvsp[-1].ifref_list), (yyvsp[0].ifref) ); }
+-#line 4371 "parser.tab.c" /* yacc.c:1648 */
++#line 4366 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 294:
+-#line 858 "parser.y" /* yacc.c:1648 */
++#line 856 "parser.y" /* yacc.c:1646 */
+ { (yyval.ifref) = make_ifref((yyvsp[0].type)); (yyval.ifref)->attrs = (yyvsp[-1].attr_list); }
+-#line 4377 "parser.tab.c" /* yacc.c:1648 */
++#line 4372 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 295:
+-#line 861 "parser.y" /* yacc.c:1648 */
++#line 859 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = get_type(TYPE_INTERFACE, (yyvsp[0].str), current_namespace, 0); }
+-#line 4383 "parser.tab.c" /* yacc.c:1648 */
++#line 4378 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 296:
+-#line 862 "parser.y" /* yacc.c:1648 */
++#line 860 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = get_type(TYPE_INTERFACE, (yyvsp[0].str), current_namespace, 0); }
+-#line 4389 "parser.tab.c" /* yacc.c:1648 */
++#line 4384 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 297:
+-#line 865 "parser.y" /* yacc.c:1648 */
++#line 863 "parser.y" /* yacc.c:1646 */
+ { attr_t *attrs;
+ (yyval.type) = (yyvsp[0].type);
+ check_def((yyval.type));
+@@ -4397,75 +4392,75 @@ yyreduce:
+ (yyval.type)->attrs = append_attr( check_dispiface_attrs((yyvsp[0].type)->name, (yyvsp[-1].attr_list)), attrs );
+ (yyval.type)->defined = TRUE;
+ }
+-#line 4401 "parser.tab.c" /* yacc.c:1648 */
++#line 4396 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 298:
+-#line 874 "parser.y" /* yacc.c:1648 */
++#line 872 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = NULL; }
+-#line 4407 "parser.tab.c" /* yacc.c:1648 */
++#line 4402 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 299:
+-#line 875 "parser.y" /* yacc.c:1648 */
++#line 873 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = append_var( (yyvsp[-2].var_list), (yyvsp[-1].var) ); }
+-#line 4413 "parser.tab.c" /* yacc.c:1648 */
++#line 4408 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 300:
+-#line 878 "parser.y" /* yacc.c:1648 */
++#line 876 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = NULL; }
+-#line 4419 "parser.tab.c" /* yacc.c:1648 */
++#line 4414 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 301:
+-#line 879 "parser.y" /* yacc.c:1648 */
++#line 877 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = append_var( (yyvsp[-2].var_list), (yyvsp[-1].var) ); }
+-#line 4425 "parser.tab.c" /* yacc.c:1648 */
++#line 4420 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 302:
+-#line 885 "parser.y" /* yacc.c:1648 */
++#line 883 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[-4].type);
+ type_dispinterface_define((yyval.type), (yyvsp[-2].var_list), (yyvsp[-1].var_list));
+ }
+-#line 4433 "parser.tab.c" /* yacc.c:1648 */
++#line 4428 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 303:
+-#line 889 "parser.y" /* yacc.c:1648 */
++#line 887 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[-4].type);
+ type_dispinterface_define_from_iface((yyval.type), (yyvsp[-2].type));
+ }
+-#line 4441 "parser.tab.c" /* yacc.c:1648 */
++#line 4436 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 304:
+-#line 894 "parser.y" /* yacc.c:1648 */
++#line 892 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = NULL; }
+-#line 4447 "parser.tab.c" /* yacc.c:1648 */
++#line 4442 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 305:
+-#line 895 "parser.y" /* yacc.c:1648 */
++#line 893 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = find_type_or_error2((yyvsp[0].str), 0); }
+-#line 4453 "parser.tab.c" /* yacc.c:1648 */
++#line 4448 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 306:
+-#line 898 "parser.y" /* yacc.c:1648 */
++#line 896 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = get_type(TYPE_INTERFACE, (yyvsp[0].str), current_namespace, 0); }
+-#line 4459 "parser.tab.c" /* yacc.c:1648 */
++#line 4454 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 307:
+-#line 899 "parser.y" /* yacc.c:1648 */
++#line 897 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = get_type(TYPE_INTERFACE, (yyvsp[0].str), current_namespace, 0); }
+-#line 4465 "parser.tab.c" /* yacc.c:1648 */
++#line 4460 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 308:
+-#line 902 "parser.y" /* yacc.c:1648 */
++#line 900 "parser.y" /* yacc.c:1646 */
+ { (yyval.ifinfo).interface = (yyvsp[0].type);
+ (yyval.ifinfo).old_pointer_default = pointer_default;
+ if (is_attr((yyvsp[-1].attr_list), ATTR_POINTERDEFAULT))
+@@ -4474,11 +4469,11 @@ yyreduce:
+ (yyvsp[0].type)->attrs = check_iface_attrs((yyvsp[0].type)->name, (yyvsp[-1].attr_list));
+ (yyvsp[0].type)->defined = TRUE;
+ }
+-#line 4478 "parser.tab.c" /* yacc.c:1648 */
++#line 4473 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 309:
+-#line 913 "parser.y" /* yacc.c:1648 */
++#line 911 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[-5].ifinfo).interface;
+ if((yyval.type) == (yyvsp[-4].type))
+ error_loc("Interface can't inherit from itself\n");
+@@ -4486,594 +4481,594 @@ yyreduce:
+ check_async_uuid((yyval.type));
+ pointer_default = (yyvsp[-5].ifinfo).old_pointer_default;
+ }
+-#line 4490 "parser.tab.c" /* yacc.c:1648 */
++#line 4485 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 310:
+-#line 924 "parser.y" /* yacc.c:1648 */
++#line 922 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[-7].ifinfo).interface;
+ type_interface_define((yyval.type), find_type_or_error2((yyvsp[-5].str), 0), (yyvsp[-2].stmt_list));
+ pointer_default = (yyvsp[-7].ifinfo).old_pointer_default;
+ }
+-#line 4499 "parser.tab.c" /* yacc.c:1648 */
++#line 4494 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 311:
+-#line 928 "parser.y" /* yacc.c:1648 */
++#line 926 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[-1].type); }
+-#line 4505 "parser.tab.c" /* yacc.c:1648 */
++#line 4500 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 312:
+-#line 932 "parser.y" /* yacc.c:1648 */
++#line 930 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[-1].type); }
+-#line 4511 "parser.tab.c" /* yacc.c:1648 */
++#line 4506 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 313:
+-#line 933 "parser.y" /* yacc.c:1648 */
++#line 931 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[-1].type); }
+-#line 4517 "parser.tab.c" /* yacc.c:1648 */
++#line 4512 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 314:
+-#line 936 "parser.y" /* yacc.c:1648 */
++#line 934 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_module((yyvsp[0].str)); }
+-#line 4523 "parser.tab.c" /* yacc.c:1648 */
++#line 4518 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 315:
+-#line 937 "parser.y" /* yacc.c:1648 */
++#line 935 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_module((yyvsp[0].str)); }
+-#line 4529 "parser.tab.c" /* yacc.c:1648 */
++#line 4524 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 316:
+-#line 940 "parser.y" /* yacc.c:1648 */
++#line 938 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[0].type);
+ (yyval.type)->attrs = check_module_attrs((yyvsp[0].type)->name, (yyvsp[-1].attr_list));
+ }
+-#line 4537 "parser.tab.c" /* yacc.c:1648 */
++#line 4532 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 317:
+-#line 946 "parser.y" /* yacc.c:1648 */
++#line 944 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[-4].type);
+ type_module_define((yyval.type), (yyvsp[-2].stmt_list));
+ }
+-#line 4545 "parser.tab.c" /* yacc.c:1648 */
++#line 4540 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 318:
+-#line 952 "parser.y" /* yacc.c:1648 */
++#line 950 "parser.y" /* yacc.c:1646 */
+ { (yyval.stgclass) = STG_EXTERN; }
+-#line 4551 "parser.tab.c" /* yacc.c:1648 */
++#line 4546 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 319:
+-#line 953 "parser.y" /* yacc.c:1648 */
++#line 951 "parser.y" /* yacc.c:1646 */
+ { (yyval.stgclass) = STG_STATIC; }
+-#line 4557 "parser.tab.c" /* yacc.c:1648 */
++#line 4552 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 320:
+-#line 954 "parser.y" /* yacc.c:1648 */
++#line 952 "parser.y" /* yacc.c:1646 */
+ { (yyval.stgclass) = STG_REGISTER; }
+-#line 4563 "parser.tab.c" /* yacc.c:1648 */
++#line 4558 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 321:
+-#line 958 "parser.y" /* yacc.c:1648 */
+- { (yyval.attr) = make_attr(ATTR_INLINE); }
+-#line 4569 "parser.tab.c" /* yacc.c:1648 */
++#line 956 "parser.y" /* yacc.c:1646 */
++ { (yyval.funcspecifier) = FUNCTION_SPECIFIER_INLINE; }
++#line 4564 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 322:
+-#line 962 "parser.y" /* yacc.c:1648 */
+- { (yyval.attr) = make_attr(ATTR_CONST); }
+-#line 4575 "parser.tab.c" /* yacc.c:1648 */
++#line 960 "parser.y" /* yacc.c:1646 */
++ { (yyval.typequalifier) = TYPE_QUALIFIER_CONST; }
++#line 4570 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 323:
+-#line 965 "parser.y" /* yacc.c:1648 */
+- { (yyval.attr_list) = NULL; }
+-#line 4581 "parser.tab.c" /* yacc.c:1648 */
++#line 963 "parser.y" /* yacc.c:1646 */
++ { (yyval.typequalifier) = TYPE_QUALIFIER_NONE; }
++#line 4576 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 324:
+-#line 966 "parser.y" /* yacc.c:1648 */
+- { (yyval.attr_list) = append_attr((yyvsp[-1].attr_list), (yyvsp[0].attr)); }
+-#line 4587 "parser.tab.c" /* yacc.c:1648 */
++#line 964 "parser.y" /* yacc.c:1646 */
++ { (yyval.typequalifier) = (yyvsp[-1].typequalifier) | (yyvsp[0].typequalifier); }
++#line 4582 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 325:
+-#line 969 "parser.y" /* yacc.c:1648 */
+- { (yyval.declspec) = make_decl_spec((yyvsp[-1].type), (yyvsp[0].declspec), NULL, NULL, STG_NONE); }
+-#line 4593 "parser.tab.c" /* yacc.c:1648 */
++#line 967 "parser.y" /* yacc.c:1646 */
++ { (yyval.declspec) = make_decl_spec((yyvsp[-1].type), (yyvsp[0].declspec), NULL, STG_NONE, TYPE_QUALIFIER_NONE, FUNCTION_SPECIFIER_NONE); }
++#line 4588 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 326:
+-#line 971 "parser.y" /* yacc.c:1648 */
+- { (yyval.declspec) = make_decl_spec((yyvsp[-1].type), (yyvsp[-2].declspec), (yyvsp[0].declspec), NULL, STG_NONE); }
+-#line 4599 "parser.tab.c" /* yacc.c:1648 */
++#line 969 "parser.y" /* yacc.c:1646 */
++ { (yyval.declspec) = make_decl_spec((yyvsp[-1].type), (yyvsp[-2].declspec), (yyvsp[0].declspec), STG_NONE, TYPE_QUALIFIER_NONE, FUNCTION_SPECIFIER_NONE); }
++#line 4594 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 327:
+-#line 974 "parser.y" /* yacc.c:1648 */
++#line 972 "parser.y" /* yacc.c:1646 */
+ { (yyval.declspec) = NULL; }
+-#line 4605 "parser.tab.c" /* yacc.c:1648 */
++#line 4600 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 329:
+-#line 979 "parser.y" /* yacc.c:1648 */
+- { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[0].declspec), NULL, (yyvsp[-1].attr), STG_NONE); }
+-#line 4611 "parser.tab.c" /* yacc.c:1648 */
++#line 977 "parser.y" /* yacc.c:1646 */
++ { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[0].declspec), NULL, STG_NONE, (yyvsp[-1].typequalifier), FUNCTION_SPECIFIER_NONE); }
++#line 4606 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 330:
+-#line 980 "parser.y" /* yacc.c:1648 */
+- { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[0].declspec), NULL, (yyvsp[-1].attr), STG_NONE); }
+-#line 4617 "parser.tab.c" /* yacc.c:1648 */
++#line 978 "parser.y" /* yacc.c:1646 */
++ { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[0].declspec), NULL, STG_NONE, TYPE_QUALIFIER_NONE, (yyvsp[-1].funcspecifier)); }
++#line 4612 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 331:
+-#line 981 "parser.y" /* yacc.c:1648 */
+- { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[0].declspec), NULL, NULL, (yyvsp[-1].stgclass)); }
+-#line 4623 "parser.tab.c" /* yacc.c:1648 */
++#line 979 "parser.y" /* yacc.c:1646 */
++ { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[0].declspec), NULL, (yyvsp[-1].stgclass), TYPE_QUALIFIER_NONE, FUNCTION_SPECIFIER_NONE); }
++#line 4618 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 332:
+-#line 986 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->type = append_chain_type((yyval.declarator)->type, type_new_pointer(pointer_default, NULL, (yyvsp[-1].attr_list))); }
+-#line 4629 "parser.tab.c" /* yacc.c:1648 */
++#line 984 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = (yyvsp[0].declarator); append_chain_declspec(&(yyval.declarator)->declspec, type_new_pointer(pointer_default, NULL), (yyvsp[-1].typequalifier)); }
++#line 4624 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 333:
+-#line 987 "parser.y" /* yacc.c:1648 */
++#line 985 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[0].declarator); if ((yyval.declarator)->func_type) (yyval.declarator)->func_type->attrs = append_attr((yyval.declarator)->func_type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str)));
+- else if ((yyval.declarator)->type) (yyval.declarator)->type->attrs = append_attr((yyval.declarator)->type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
+-#line 4636 "parser.tab.c" /* yacc.c:1648 */
++ else if ((yyval.declarator)->declspec.type) (yyval.declarator)->declspec.type->attrs = append_attr((yyval.declarator)->declspec.type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
++#line 4631 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 335:
+-#line 993 "parser.y" /* yacc.c:1648 */
++#line 991 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = make_declarator((yyvsp[0].var)); }
+-#line 4642 "parser.tab.c" /* yacc.c:1648 */
++#line 4637 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 336:
+-#line 994 "parser.y" /* yacc.c:1648 */
++#line 992 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[-1].declarator); }
+-#line 4648 "parser.tab.c" /* yacc.c:1648 */
++#line 4643 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 337:
+-#line 995 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = (yyvsp[-1].declarator); (yyval.declarator)->type = append_array((yyval.declarator)->type, (yyvsp[0].expr)); }
+-#line 4654 "parser.tab.c" /* yacc.c:1648 */
++#line 993 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = (yyvsp[-1].declarator); (yyval.declarator)->declspec.type = append_array((yyval.declarator)->declspec.type, (yyvsp[0].expr)); }
++#line 4649 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 338:
+-#line 996 "parser.y" /* yacc.c:1648 */
++#line 994 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[-3].declarator);
+- (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->type, type_new_function((yyvsp[-1].var_list)));
+- (yyval.declarator)->type = NULL;
++ (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->declspec.type, type_new_function((yyvsp[-1].var_list)));
++ (yyval.declarator)->declspec.type = NULL;
+ }
+-#line 4663 "parser.tab.c" /* yacc.c:1648 */
++#line 4658 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 339:
+-#line 1005 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->type = append_chain_type((yyval.declarator)->type, type_new_pointer(pointer_default, NULL, (yyvsp[-1].attr_list))); }
+-#line 4669 "parser.tab.c" /* yacc.c:1648 */
++#line 1003 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = (yyvsp[0].declarator); append_chain_declspec(&(yyval.declarator)->declspec, type_new_pointer(pointer_default, NULL), (yyvsp[-1].typequalifier)); }
++#line 4664 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 340:
+-#line 1006 "parser.y" /* yacc.c:1648 */
++#line 1004 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[0].declarator); if ((yyval.declarator)->func_type) (yyval.declarator)->func_type->attrs = append_attr((yyval.declarator)->func_type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str)));
+- else if ((yyval.declarator)->type) (yyval.declarator)->type->attrs = append_attr((yyval.declarator)->type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
+-#line 4676 "parser.tab.c" /* yacc.c:1648 */
++ else if ((yyval.declarator)->declspec.type) (yyval.declarator)->declspec.type->attrs = append_attr((yyval.declarator)->declspec.type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
++#line 4671 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 342:
+-#line 1014 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->type = append_chain_type((yyval.declarator)->type, type_new_pointer(pointer_default, NULL, (yyvsp[-1].attr_list))); }
+-#line 4682 "parser.tab.c" /* yacc.c:1648 */
++#line 1012 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = (yyvsp[0].declarator); append_chain_declspec(&(yyval.declarator)->declspec, type_new_pointer(pointer_default, NULL), (yyvsp[-1].typequalifier)); }
++#line 4677 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 343:
+-#line 1015 "parser.y" /* yacc.c:1648 */
++#line 1013 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[0].declarator); if ((yyval.declarator)->func_type) (yyval.declarator)->func_type->attrs = append_attr((yyval.declarator)->func_type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str)));
+- else if ((yyval.declarator)->type) (yyval.declarator)->type->attrs = append_attr((yyval.declarator)->type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
+-#line 4689 "parser.tab.c" /* yacc.c:1648 */
++ else if ((yyval.declarator)->declspec.type) (yyval.declarator)->declspec.type->attrs = append_attr((yyval.declarator)->declspec.type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
++#line 4684 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 344:
+-#line 1020 "parser.y" /* yacc.c:1648 */
++#line 1018 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = make_declarator(NULL); }
+-#line 4695 "parser.tab.c" /* yacc.c:1648 */
++#line 4690 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 346:
+-#line 1026 "parser.y" /* yacc.c:1648 */
++#line 1024 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[-1].declarator); }
+-#line 4701 "parser.tab.c" /* yacc.c:1648 */
++#line 4696 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 347:
+-#line 1027 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = (yyvsp[-1].declarator); (yyval.declarator)->type = append_array((yyval.declarator)->type, (yyvsp[0].expr)); }
+-#line 4707 "parser.tab.c" /* yacc.c:1648 */
++#line 1025 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = (yyvsp[-1].declarator); (yyval.declarator)->declspec.type = append_array((yyval.declarator)->declspec.type, (yyvsp[0].expr)); }
++#line 4702 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 348:
+-#line 1028 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = make_declarator(NULL); (yyval.declarator)->type = append_array((yyval.declarator)->type, (yyvsp[0].expr)); }
+-#line 4713 "parser.tab.c" /* yacc.c:1648 */
++#line 1026 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = make_declarator(NULL); (yyval.declarator)->declspec.type = append_array((yyval.declarator)->declspec.type, (yyvsp[0].expr)); }
++#line 4708 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 349:
+-#line 1030 "parser.y" /* yacc.c:1648 */
++#line 1028 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = make_declarator(NULL);
+- (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->type, type_new_function((yyvsp[-1].var_list)));
+- (yyval.declarator)->type = NULL;
++ (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->declspec.type, type_new_function((yyvsp[-1].var_list)));
++ (yyval.declarator)->declspec.type = NULL;
+ }
+-#line 4722 "parser.tab.c" /* yacc.c:1648 */
++#line 4717 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 350:
+-#line 1035 "parser.y" /* yacc.c:1648 */
++#line 1033 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[-3].declarator);
+- (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->type, type_new_function((yyvsp[-1].var_list)));
+- (yyval.declarator)->type = NULL;
++ (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->declspec.type, type_new_function((yyvsp[-1].var_list)));
++ (yyval.declarator)->declspec.type = NULL;
+ }
+-#line 4731 "parser.tab.c" /* yacc.c:1648 */
++#line 4726 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 351:
+-#line 1044 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->type = append_chain_type((yyval.declarator)->type, type_new_pointer(pointer_default, NULL, (yyvsp[-1].attr_list))); }
+-#line 4737 "parser.tab.c" /* yacc.c:1648 */
++#line 1042 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = (yyvsp[0].declarator); append_chain_declspec(&(yyval.declarator)->declspec, type_new_pointer(pointer_default, NULL), (yyvsp[-1].typequalifier)); }
++#line 4732 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 352:
+-#line 1045 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->type->attrs = append_attr((yyval.declarator)->type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
+-#line 4743 "parser.tab.c" /* yacc.c:1648 */
++#line 1043 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->declspec.type->attrs = append_attr((yyval.declarator)->declspec.type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
++#line 4738 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 354:
+-#line 1052 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->type = append_chain_type((yyval.declarator)->type, type_new_pointer(pointer_default, NULL, (yyvsp[-1].attr_list))); }
+-#line 4749 "parser.tab.c" /* yacc.c:1648 */
++#line 1050 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = (yyvsp[0].declarator); append_chain_declspec(&(yyval.declarator)->declspec, type_new_pointer(pointer_default, NULL), (yyvsp[-1].typequalifier)); }
++#line 4744 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 355:
+-#line 1053 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->type->attrs = append_attr((yyval.declarator)->type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
+-#line 4755 "parser.tab.c" /* yacc.c:1648 */
++#line 1051 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->declspec.type->attrs = append_attr((yyval.declarator)->declspec.type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
++#line 4750 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 356:
+-#line 1057 "parser.y" /* yacc.c:1648 */
++#line 1055 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = make_declarator(NULL); }
+-#line 4761 "parser.tab.c" /* yacc.c:1648 */
++#line 4756 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 358:
+-#line 1065 "parser.y" /* yacc.c:1648 */
++#line 1063 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = make_declarator((yyvsp[0].var)); }
+-#line 4767 "parser.tab.c" /* yacc.c:1648 */
++#line 4762 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 359:
+-#line 1066 "parser.y" /* yacc.c:1648 */
++#line 1064 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[-1].declarator); }
+-#line 4773 "parser.tab.c" /* yacc.c:1648 */
++#line 4768 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 360:
+-#line 1067 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = (yyvsp[-1].declarator); (yyval.declarator)->type = append_array((yyval.declarator)->type, (yyvsp[0].expr)); }
+-#line 4779 "parser.tab.c" /* yacc.c:1648 */
++#line 1065 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = (yyvsp[-1].declarator); (yyval.declarator)->declspec.type = append_array((yyval.declarator)->declspec.type, (yyvsp[0].expr)); }
++#line 4774 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 361:
+-#line 1068 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = make_declarator(NULL); (yyval.declarator)->type = append_array((yyval.declarator)->type, (yyvsp[0].expr)); }
+-#line 4785 "parser.tab.c" /* yacc.c:1648 */
++#line 1066 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = make_declarator(NULL); (yyval.declarator)->declspec.type = append_array((yyval.declarator)->declspec.type, (yyvsp[0].expr)); }
++#line 4780 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 362:
+-#line 1070 "parser.y" /* yacc.c:1648 */
++#line 1068 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = make_declarator(NULL);
+- (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->type, type_new_function((yyvsp[-1].var_list)));
+- (yyval.declarator)->type = NULL;
++ (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->declspec.type, type_new_function((yyvsp[-1].var_list)));
++ (yyval.declarator)->declspec.type = NULL;
+ }
+-#line 4794 "parser.tab.c" /* yacc.c:1648 */
++#line 4789 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 363:
+-#line 1075 "parser.y" /* yacc.c:1648 */
++#line 1073 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[-3].declarator);
+- (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->type, type_new_function((yyvsp[-1].var_list)));
+- (yyval.declarator)->type = NULL;
++ (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->declspec.type, type_new_function((yyvsp[-1].var_list)));
++ (yyval.declarator)->declspec.type = NULL;
+ }
+-#line 4803 "parser.tab.c" /* yacc.c:1648 */
++#line 4798 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 364:
+-#line 1082 "parser.y" /* yacc.c:1648 */
++#line 1080 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator_list) = append_declarator( NULL, (yyvsp[0].declarator) ); }
+-#line 4809 "parser.tab.c" /* yacc.c:1648 */
++#line 4804 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 365:
+-#line 1083 "parser.y" /* yacc.c:1648 */
++#line 1081 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator_list) = append_declarator( (yyvsp[-2].declarator_list), (yyvsp[0].declarator) ); }
+-#line 4815 "parser.tab.c" /* yacc.c:1648 */
++#line 4810 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 366:
+-#line 1086 "parser.y" /* yacc.c:1648 */
++#line 1084 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = NULL; }
+-#line 4821 "parser.tab.c" /* yacc.c:1648 */
++#line 4816 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 367:
+-#line 1087 "parser.y" /* yacc.c:1648 */
++#line 1085 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = (yyvsp[0].expr); }
+-#line 4827 "parser.tab.c" /* yacc.c:1648 */
++#line 4822 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 368:
+-#line 1090 "parser.y" /* yacc.c:1648 */
++#line 1088 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[-1].declarator); (yyval.declarator)->bits = (yyvsp[0].expr);
+ if (!(yyval.declarator)->bits && !(yyval.declarator)->var->name)
+ error_loc("unnamed fields are not allowed\n");
+ }
+-#line 4836 "parser.tab.c" /* yacc.c:1648 */
++#line 4831 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 369:
+-#line 1097 "parser.y" /* yacc.c:1648 */
++#line 1095 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator_list) = append_declarator( NULL, (yyvsp[0].declarator) ); }
+-#line 4842 "parser.tab.c" /* yacc.c:1648 */
++#line 4837 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 370:
+-#line 1099 "parser.y" /* yacc.c:1648 */
++#line 1097 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator_list) = append_declarator( (yyvsp[-2].declarator_list), (yyvsp[0].declarator) ); }
+-#line 4848 "parser.tab.c" /* yacc.c:1648 */
++#line 4843 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 371:
+-#line 1103 "parser.y" /* yacc.c:1648 */
++#line 1101 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[0].declarator); }
+-#line 4854 "parser.tab.c" /* yacc.c:1648 */
++#line 4849 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 372:
+-#line 1104 "parser.y" /* yacc.c:1648 */
++#line 1102 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[-2].declarator); (yyvsp[-2].declarator)->var->eval = (yyvsp[0].expr); }
+-#line 4860 "parser.tab.c" /* yacc.c:1648 */
++#line 4855 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 373:
+-#line 1108 "parser.y" /* yacc.c:1648 */
++#line 1106 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = THREADING_APARTMENT; }
+-#line 4866 "parser.tab.c" /* yacc.c:1648 */
++#line 4861 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 374:
+-#line 1109 "parser.y" /* yacc.c:1648 */
++#line 1107 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = THREADING_NEUTRAL; }
+-#line 4872 "parser.tab.c" /* yacc.c:1648 */
++#line 4867 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 375:
+-#line 1110 "parser.y" /* yacc.c:1648 */
++#line 1108 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = THREADING_SINGLE; }
+-#line 4878 "parser.tab.c" /* yacc.c:1648 */
++#line 4873 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 376:
+-#line 1111 "parser.y" /* yacc.c:1648 */
++#line 1109 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = THREADING_FREE; }
+-#line 4884 "parser.tab.c" /* yacc.c:1648 */
++#line 4879 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 377:
+-#line 1112 "parser.y" /* yacc.c:1648 */
++#line 1110 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = THREADING_BOTH; }
+-#line 4890 "parser.tab.c" /* yacc.c:1648 */
++#line 4885 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 378:
+-#line 1116 "parser.y" /* yacc.c:1648 */
++#line 1114 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = FC_RP; }
+-#line 4896 "parser.tab.c" /* yacc.c:1648 */
++#line 4891 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 379:
+-#line 1117 "parser.y" /* yacc.c:1648 */
++#line 1115 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = FC_UP; }
+-#line 4902 "parser.tab.c" /* yacc.c:1648 */
++#line 4897 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 380:
+-#line 1118 "parser.y" /* yacc.c:1648 */
++#line 1116 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = FC_FP; }
+-#line 4908 "parser.tab.c" /* yacc.c:1648 */
++#line 4903 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 381:
+-#line 1121 "parser.y" /* yacc.c:1648 */
++#line 1119 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_struct((yyvsp[-3].str), current_namespace, TRUE, (yyvsp[-1].var_list)); }
+-#line 4914 "parser.tab.c" /* yacc.c:1648 */
++#line 4909 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 382:
+-#line 1124 "parser.y" /* yacc.c:1648 */
++#line 1122 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_void(); }
+-#line 4920 "parser.tab.c" /* yacc.c:1648 */
++#line 4915 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 383:
+-#line 1125 "parser.y" /* yacc.c:1648 */
++#line 1123 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
+-#line 4926 "parser.tab.c" /* yacc.c:1648 */
++#line 4921 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 384:
+-#line 1126 "parser.y" /* yacc.c:1648 */
++#line 1124 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[0].type); }
+-#line 4932 "parser.tab.c" /* yacc.c:1648 */
++#line 4927 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 385:
+-#line 1127 "parser.y" /* yacc.c:1648 */
++#line 1125 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[0].type); }
+-#line 4938 "parser.tab.c" /* yacc.c:1648 */
++#line 4933 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 386:
+-#line 1128 "parser.y" /* yacc.c:1648 */
++#line 1126 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_enum((yyvsp[0].str), current_namespace, FALSE, NULL); }
+-#line 4944 "parser.tab.c" /* yacc.c:1648 */
++#line 4939 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 387:
+-#line 1129 "parser.y" /* yacc.c:1648 */
++#line 1127 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[0].type); }
+-#line 4950 "parser.tab.c" /* yacc.c:1648 */
++#line 4945 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 388:
+-#line 1130 "parser.y" /* yacc.c:1648 */
++#line 1128 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_struct((yyvsp[0].str), current_namespace, FALSE, NULL); }
+-#line 4956 "parser.tab.c" /* yacc.c:1648 */
++#line 4951 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 389:
+-#line 1131 "parser.y" /* yacc.c:1648 */
++#line 1129 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[0].type); }
+-#line 4962 "parser.tab.c" /* yacc.c:1648 */
++#line 4957 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 390:
+-#line 1132 "parser.y" /* yacc.c:1648 */
++#line 1130 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_nonencapsulated_union((yyvsp[0].str), FALSE, NULL); }
+-#line 4968 "parser.tab.c" /* yacc.c:1648 */
++#line 4963 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 391:
+-#line 1133 "parser.y" /* yacc.c:1648 */
++#line 1131 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = make_safearray((yyvsp[-1].type)); }
+-#line 4974 "parser.tab.c" /* yacc.c:1648 */
++#line 4969 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 392:
+-#line 1137 "parser.y" /* yacc.c:1648 */
++#line 1135 "parser.y" /* yacc.c:1646 */
+ { (yyvsp[-4].attr_list) = append_attribs((yyvsp[-4].attr_list), (yyvsp[-2].attr_list));
+ reg_typedefs((yyvsp[-1].declspec), (yyvsp[0].declarator_list), check_typedef_attrs((yyvsp[-4].attr_list)));
+ (yyval.statement) = make_statement_typedef((yyvsp[0].declarator_list));
+ }
+-#line 4983 "parser.tab.c" /* yacc.c:1648 */
++#line 4978 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 393:
+-#line 1144 "parser.y" /* yacc.c:1648 */
++#line 1142 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_nonencapsulated_union((yyvsp[-3].str), TRUE, (yyvsp[-1].var_list)); }
+-#line 4989 "parser.tab.c" /* yacc.c:1648 */
++#line 4984 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 394:
+-#line 1147 "parser.y" /* yacc.c:1648 */
++#line 1145 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_encapsulated_union((yyvsp[-8].str), (yyvsp[-5].var), (yyvsp[-3].var), (yyvsp[-1].var_list)); }
+-#line 4995 "parser.tab.c" /* yacc.c:1648 */
++#line 4990 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 395:
+-#line 1151 "parser.y" /* yacc.c:1648 */
++#line 1149 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = MAKEVERSION((yyvsp[0].num), 0); }
+-#line 5001 "parser.tab.c" /* yacc.c:1648 */
++#line 4996 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 396:
+-#line 1152 "parser.y" /* yacc.c:1648 */
++#line 1150 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = MAKEVERSION((yyvsp[-2].num), (yyvsp[0].num)); }
+-#line 5007 "parser.tab.c" /* yacc.c:1648 */
++#line 5002 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 397:
+-#line 1153 "parser.y" /* yacc.c:1648 */
++#line 1151 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = (yyvsp[0].num); }
+-#line 5013 "parser.tab.c" /* yacc.c:1648 */
++#line 5008 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 402:
+-#line 1166 "parser.y" /* yacc.c:1648 */
++#line 1164 "parser.y" /* yacc.c:1646 */
+ { type_t *type = find_type_or_error((yyvsp[-1].str), 0);
+ type->attrs = append_attr_list(type->attrs, (yyvsp[-2].attr_list));
+ }
+-#line 5021 "parser.tab.c" /* yacc.c:1648 */
++#line 5016 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 403:
+-#line 1171 "parser.y" /* yacc.c:1648 */
++#line 1169 "parser.y" /* yacc.c:1646 */
+ { type_t *iface = find_type_or_error2((yyvsp[-3].str), 0);
+ if (type_get_type(iface) != TYPE_INTERFACE)
+ error_loc("%s is not an interface\n", iface->name);
+ iface->attrs = append_attr_list(iface->attrs, (yyvsp[-5].attr_list));
+ }
+-#line 5031 "parser.tab.c" /* yacc.c:1648 */
++#line 5026 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 404:
+-#line 1178 "parser.y" /* yacc.c:1648 */
++#line 1176 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr_list) = NULL; }
+-#line 5037 "parser.tab.c" /* yacc.c:1648 */
++#line 5032 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 405:
+-#line 1179 "parser.y" /* yacc.c:1648 */
++#line 1177 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr_list) = (yyvsp[-1].attr_list); }
+-#line 5043 "parser.tab.c" /* yacc.c:1648 */
++#line 5038 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 406:
+-#line 1182 "parser.y" /* yacc.c:1648 */
++#line 1180 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr_list) = append_attr(NULL, (yyvsp[0].attr)); }
+-#line 5049 "parser.tab.c" /* yacc.c:1648 */
++#line 5044 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 407:
+-#line 1183 "parser.y" /* yacc.c:1648 */
++#line 1181 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr_list) = append_attr((yyvsp[-2].attr_list), (yyvsp[0].attr)); }
+-#line 5055 "parser.tab.c" /* yacc.c:1648 */
++#line 5050 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 408:
+-#line 1186 "parser.y" /* yacc.c:1648 */
++#line 1184 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_ENCODE); }
+-#line 5061 "parser.tab.c" /* yacc.c:1648 */
++#line 5056 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 409:
+-#line 1187 "parser.y" /* yacc.c:1648 */
++#line 1185 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_DECODE); }
+-#line 5067 "parser.tab.c" /* yacc.c:1648 */
++#line 5062 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 410:
+-#line 1188 "parser.y" /* yacc.c:1648 */
++#line 1186 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_EXPLICIT_HANDLE); }
+-#line 5073 "parser.tab.c" /* yacc.c:1648 */
++#line 5068 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+
+-#line 5077 "parser.tab.c" /* yacc.c:1648 */
++#line 5072 "parser.tab.c" /* yacc.c:1646 */
+ default: break;
+ }
+ /* User semantic actions sometimes alter yychar, and that requires
+@@ -5301,7 +5296,7 @@ yyreturn:
+ #endif
+ return yyresult;
+ }
+-#line 1190 "parser.y" /* yacc.c:1907 */
++#line 1188 "parser.y" /* yacc.c:1906 */
+
+
+ static void decl_builtin_basic(const char *name, enum type_basic_type type)
+@@ -5312,7 +5307,8 @@ static void decl_builtin_basic(const char *name, enum type_basic_type type)
+
+ static void decl_builtin_alias(const char *name, type_t *t)
+ {
+- reg_type(type_new_alias(t, name), name, NULL, 0);
++ decl_spec_t ds;
++ reg_type(type_new_alias(init_declspec(&ds, t), name), name, &global_namespace, 0);
+ }
+
+ void init_types(void)
+@@ -5323,7 +5319,7 @@ void init_types(void)
+ decl_builtin_basic("double", TYPE_BASIC_DOUBLE);
+ decl_builtin_basic("error_status_t", TYPE_BASIC_ERROR_STATUS_T);
+ decl_builtin_basic("handle_t", TYPE_BASIC_HANDLE);
+- decl_builtin_alias("boolean", type_new_basic(TYPE_BASIC_BYTE));
++ decl_builtin_alias("boolean", type_new_basic(TYPE_BASIC_CHAR));
+ }
+
+ static str_list_t *append_str(str_list_t *list, char *str)
+@@ -5354,6 +5350,7 @@ static attr_list_t *append_attr(attr_list_t *list, attr_t *attr)
+ LIST_FOR_EACH_ENTRY(attr_existing, list, attr_t, entry)
+ if (attr_existing->type == attr->type)
+ {
++ __builtin_trap();
+ parser_warning("duplicate attribute %s\n", get_attr_display_name(attr->type));
+ /* use the last attribute, like MIDL does */
+ list_remove(&attr_existing->entry);
+@@ -5413,53 +5410,73 @@ static attr_list_t *map_attrs(const attr_list_t *list, map_attrs_filter_t filter
+ return new_list;
+ }
+
+-static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, attr_t *attr, enum storage_class stgclass)
++static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, enum storage_class stgclass, enum type_qualifier typequalifier, enum function_specifier funcspecifier)
+ {
+ decl_spec_t *declspec = left ? left : right;
+ if (!declspec)
+ {
+ declspec = xmalloc(sizeof(*declspec));
+ declspec->type = NULL;
+- declspec->attrs = NULL;
+ declspec->stgclass = STG_NONE;
++ declspec->typequalifier = TYPE_QUALIFIER_NONE;
++ declspec->funcspecifier = FUNCTION_SPECIFIER_NONE;
+ }
+ declspec->type = type;
+ if (left && declspec != left)
+ {
+- declspec->attrs = append_attr_list(declspec->attrs, left->attrs);
+ if (declspec->stgclass == STG_NONE)
+ declspec->stgclass = left->stgclass;
+ else if (left->stgclass != STG_NONE)
+ error_loc("only one storage class can be specified\n");
++
++ if (declspec->typequalifier == TYPE_QUALIFIER_NONE)
++ declspec->typequalifier = left->typequalifier;
++ else if (left->typequalifier != TYPE_QUALIFIER_NONE)
++ error_loc("only one type qualifier can be specified\n");
++
++ if (declspec->funcspecifier == FUNCTION_SPECIFIER_NONE)
++ declspec->funcspecifier = left->funcspecifier;
++ else if (left->funcspecifier != FUNCTION_SPECIFIER_NONE)
++ error_loc("only one function specifier can be specified\n");
++
+ assert(!left->type);
+ free(left);
+ }
+ if (right && declspec != right)
+ {
+- declspec->attrs = append_attr_list(declspec->attrs, right->attrs);
+ if (declspec->stgclass == STG_NONE)
+ declspec->stgclass = right->stgclass;
+ else if (right->stgclass != STG_NONE)
+ error_loc("only one storage class can be specified\n");
++
++ if (declspec->typequalifier == TYPE_QUALIFIER_NONE)
++ declspec->typequalifier = right->typequalifier;
++ else if (right->typequalifier != TYPE_QUALIFIER_NONE)
++ error_loc("only one type qualifier can be specified\n");
++
++ if (declspec->funcspecifier == FUNCTION_SPECIFIER_NONE)
++ declspec->funcspecifier = right->funcspecifier;
++ else if (right->funcspecifier != FUNCTION_SPECIFIER_NONE)
++ error_loc("only one function specifier can be specified\n");
++
+ assert(!right->type);
+ free(right);
+ }
+
+- declspec->attrs = append_attr(declspec->attrs, attr);
+ if (declspec->stgclass == STG_NONE)
+ declspec->stgclass = stgclass;
+ else if (stgclass != STG_NONE)
+ error_loc("only one storage class can be specified\n");
+
+- /* apply attributes to type */
+- if (type && declspec->attrs)
+- {
+- attr_list_t *attrs;
+- declspec->type = duptype(type, 1);
+- attrs = map_attrs(type->attrs, NULL);
+- declspec->type->attrs = append_attr_list(attrs, declspec->attrs);
+- declspec->attrs = NULL;
+- }
++ if (declspec->typequalifier == TYPE_QUALIFIER_NONE)
++ declspec->typequalifier = typequalifier;
++ else if (typequalifier != TYPE_QUALIFIER_NONE)
++ error_loc("only one type qualifier can be specified\n");
++
++ if (declspec->funcspecifier == FUNCTION_SPECIFIER_NONE)
++ declspec->funcspecifier = funcspecifier;
++ else if (funcspecifier != FUNCTION_SPECIFIER_NONE)
++ error_loc("only one function specifier can be specified\n");
+
+ return declspec;
+ }
+@@ -5545,6 +5562,7 @@ void clear_all_offsets(void)
+
+ static void type_function_add_head_arg(type_t *type, var_t *arg)
+ {
++ assert(type_get_type_detect_alias(type) == TYPE_FUNCTION);
+ if (!type->details.function->args)
+ {
+ type->details.function->args = xmalloc( sizeof(*type->details.function->args) );
+@@ -5589,31 +5607,60 @@ static int is_allowed_range_type(const type_t *type)
+ static type_t *get_array_or_ptr_ref(type_t *type)
+ {
+ if (is_ptr(type))
+- return type_pointer_get_ref(type);
++ return type_pointer_get_ref_type(type);
+ else if (is_array(type))
+- return type_array_get_element(type);
++ return type_array_get_element_type(type);
+ return NULL;
+ }
+
+ static type_t *append_chain_type(type_t *chain, type_t *type)
+ {
+- type_t *chain_type;
++ type_t *chain_type = NULL;
+
+ if (!chain)
+ return type;
+ for (chain_type = chain; get_array_or_ptr_ref(chain_type); chain_type = get_array_or_ptr_ref(chain_type))
+ ;
+
++ assert(!type_is_alias(chain_type));
+ if (is_ptr(chain_type))
+- chain_type->details.pointer.ref = type;
++ chain_type->details.pointer.ref.type = type;
+ else if (is_array(chain_type))
+- chain_type->details.array.elem = type;
++ chain_type->details.array.elem.type = type;
+ else
+ assert(0);
+
+ return chain;
+ }
+
++static decl_spec_t *append_chain_declspec(decl_spec_t *chain, type_t *type, enum type_qualifier typequalifier)
++{
++ type_t *chain_type = chain->type;
++ decl_spec_t *chain_declspec = NULL;
++
++ if (!chain_type)
++ {
++ chain->type = type;
++ chain->typequalifier = typequalifier;
++ return chain;
++ }
++
++ for(; get_array_or_ptr_ref(chain_type); chain_type = get_array_or_ptr_ref(chain_type))
++ ;
++
++ if (is_ptr(chain_type))
++ chain_declspec = &chain_type->details.pointer.ref;
++ else if (is_array(chain_type))
++ chain_declspec = &chain_type->details.array.elem;
++ else
++ assert(NULL);
++
++ chain_declspec->type = type;
++ chain_declspec->typequalifier = typequalifier;
++
++ return chain;
++}
++
+ static warning_list_t *append_warning(warning_list_t *list, int num)
+ {
+ warning_t *entry;
+@@ -5629,7 +5676,7 @@ static warning_list_t *append_warning(warning_list_t *list, int num)
+ return list;
+ }
+
+-static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const declarator_t *decl,
++static var_t *declare_var(attr_list_t *attrs, decl_spec_t *declspec, const declarator_t *decl,
+ int top)
+ {
+ var_t *v = decl->var;
+@@ -5638,58 +5685,80 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ expr_t *dim;
+ type_t **ptype;
+ type_t *func_type = decl ? decl->func_type : NULL;
+- type_t *type = decl_spec->type;
++ type_t *type = declspec->type;
+
+- if (is_attr(type->attrs, ATTR_INLINE))
+- {
++
++ if (declspec->funcspecifier == FUNCTION_SPECIFIER_INLINE) {
+ if (!func_type)
+ error_loc("inline attribute applied to non-function type\n");
+ else
+ {
+- type_t *t;
+- /* move inline attribute from return type node to function node */
+- for (t = func_type; is_ptr(t); t = type_pointer_get_ref(t))
+- ;
+- t->attrs = move_attr(t->attrs, type->attrs, ATTR_INLINE);
++ v->declspec.funcspecifier = declspec->funcspecifier;
+ }
+ }
+
+- /* add type onto the end of the pointers in pident->type */
+- v->type = append_chain_type(decl ? decl->type : NULL, type);
+- v->stgclass = decl_spec->stgclass;
++ /* if the var type is a pointerish, we need to move the type qualifier to the pointee's declspec
++ * unless the pointee already has const type qualifier*/
++ if (!decl)
++ {
++ /* simplest case, no pointers to deal with here */
++ v->declspec.typequalifier = declspec->typequalifier;
++ } else if (decl->bits)
++ {
++ /* dealing with a bitfield, generate bitfield and copy over typequalifier*/
++ v->declspec.type = type_new_bitfield(declspec->type, decl->bits);
++ v->declspec.typequalifier = declspec->typequalifier;
++ }
++ else
++ {
++ /* here we're dealing with a pointerish type chain, so we need to pull
++ * the typequalifier off of the declspec and stick them in the type's attr list
++ */
++ v->declspec.type = decl->declspec.type;
++ v->declspec.typequalifier = decl->declspec.typequalifier;
++ append_chain_declspec(&v->declspec, type, declspec->typequalifier);
++ }
++
++ v->declspec.stgclass = declspec->stgclass;
+ v->attrs = attrs;
+
+ /* check for pointer attribute being applied to non-pointer, non-array
+ * type */
+- if (!is_array(v->type))
++ if (!is_array(v->declspec.type))
+ {
+ int ptr_attr = get_attrv(v->attrs, ATTR_POINTERTYPE);
+ const type_t *ptr = NULL;
+ /* pointer attributes on the left side of the type belong to the function
+ * pointer, if one is being declared */
+- type_t **pt = func_type ? &func_type : &v->type;
++ type_t **pt = func_type ? &func_type : &v->declspec.type;
+ for (ptr = *pt; ptr && !ptr_attr; )
+ {
+ ptr_attr = get_attrv(ptr->attrs, ATTR_POINTERTYPE);
+ if (!ptr_attr && type_is_alias(ptr))
+- ptr = type_alias_get_aliasee(ptr);
++ ptr = type_alias_get_aliasee_type(ptr);
+ else
+ break;
+ }
+ if (is_ptr(ptr))
+ {
+ if (ptr_attr && ptr_attr != FC_UP &&
+- type_get_type(type_pointer_get_ref(ptr)) == TYPE_INTERFACE)
++ type_get_type(type_pointer_get_ref_type(ptr)) == TYPE_INTERFACE)
+ warning_loc_info(&v->loc_info,
+ "%s: pointer attribute applied to interface "
+ "pointer type has no effect\n", v->name);
+- if (!ptr_attr && top && (*pt)->details.pointer.def_fc != FC_RP)
++ if (!ptr_attr && top && type_pointer_get_default_fc(*pt) != FC_RP)
+ {
++ printf("dup_pointer_type!\n");
++ printf("type : %p name : %s\n", *pt, (*pt)->name);
++ /* ptr_attr is ref,unique or full (FC_RP, FC_UP, FC_FP) */
++ /* *pt could be the var's declspec's type OR a type on a typedef */
++ /* not an array */
++
+ /* FIXME: this is a horrible hack to cope with the issue that we
+ * store an offset to the typeformat string in the type object, but
+ * two typeformat strings may be written depending on whether the
+ * pointer is a toplevel parameter or not */
+- *pt = duptype(*pt, 1);
++ *pt = dup_pointer_type(*pt);
+ }
+ }
+ else if (ptr_attr)
+@@ -5700,16 +5769,16 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ {
+ type_t *t = type;
+
+- if (!is_ptr(v->type) && !is_array(v->type))
++ if (!is_ptr(v->declspec.type) && !is_array(v->declspec.type))
+ error_loc("'%s': [string] attribute applied to non-pointer, non-array type\n",
+ v->name);
+
+ for (;;)
+ {
+ if (is_ptr(t))
+- t = type_pointer_get_ref(t);
++ t = type_pointer_get_ref_type(t);
+ else if (is_array(t))
+- t = type_array_get_element(t);
++ t = type_array_get_element_type(t);
+ else
+ break;
+ }
+@@ -5726,15 +5795,15 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+
+ if (is_attr(v->attrs, ATTR_V1ENUM))
+ {
+- if (type_get_type_detect_alias(v->type) != TYPE_ENUM)
++ if (type_get_type_detect_alias(v->declspec.type) != TYPE_ENUM)
+ error_loc("'%s': [v1_enum] attribute applied to non-enum type\n", v->name);
+ }
+
+- if (is_attr(v->attrs, ATTR_RANGE) && !is_allowed_range_type(v->type))
++ if (is_attr(v->attrs, ATTR_RANGE) && !is_allowed_range_type(v->declspec.type))
+ error_loc("'%s': [range] attribute applied to non-integer type\n",
+ v->name);
+
+- ptype = &v->type;
++ ptype = &v->declspec.type;
+ if (sizes) LIST_FOR_EACH_ENTRY(dim, sizes, expr_t, entry)
+ {
+ if (dim->type != EXPR_VOID)
+@@ -5747,7 +5816,7 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ else
+ *ptype = type_new_array((*ptype)->name,
+ type_array_get_element(*ptype), FALSE,
+- 0, dim, NULL, 0);
++ 0, dim, NULL, FC_RP);
+ }
+ else if (is_ptr(*ptype))
+ *ptype = type_new_array((*ptype)->name, type_pointer_get_ref(*ptype), TRUE,
+@@ -5756,15 +5825,16 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ error_loc("%s: size_is attribute applied to illegal type\n", v->name);
+ }
+
++ assert(!type_is_alias(*ptype));
+ if (is_ptr(*ptype))
+- ptype = &(*ptype)->details.pointer.ref;
++ ptype = &(*ptype)->details.pointer.ref.type;
+ else if (is_array(*ptype))
+- ptype = &(*ptype)->details.array.elem;
++ ptype = &(*ptype)->details.array.elem.type;
+ else
+ error_loc("%s: too many expressions in size_is attribute\n", v->name);
+ }
+
+- ptype = &v->type;
++ ptype = &v->declspec.type;
+ if (lengs) LIST_FOR_EACH_ENTRY(dim, lengs, expr_t, entry)
+ {
+ if (dim->type != EXPR_VOID)
+@@ -5782,10 +5852,11 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ error_loc("%s: length_is attribute applied to illegal type\n", v->name);
+ }
+
++ assert(!type_is_alias(*ptype));
+ if (is_ptr(*ptype))
+- ptype = &(*ptype)->details.pointer.ref;
++ ptype = &(*ptype)->details.pointer.ref.type;
+ else if (is_array(*ptype))
+- ptype = &(*ptype)->details.array.elem;
++ ptype = &(*ptype)->details.array.elem.type;
+ else
+ error_loc("%s: too many expressions in length_is attribute\n", v->name);
+ }
+@@ -5796,29 +5867,31 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ if (func_type)
+ {
+ type_t *ft, *t;
+- type_t *return_type = v->type;
+- v->type = func_type;
+- for (ft = v->type; is_ptr(ft); ft = type_pointer_get_ref(ft))
++ type_t *return_type = v->declspec.type;
++ enum type_qualifier typequalifier = v->declspec.typequalifier;
++
++ v->declspec.type = func_type;
++ v->declspec.typequalifier = TYPE_QUALIFIER_NONE;
++ for (ft = v->declspec.type; is_ptr(ft); ft = type_pointer_get_ref_type(ft))
+ ;
+ assert(type_get_type_detect_alias(ft) == TYPE_FUNCTION);
+ ft->details.function->retval = make_var(xstrdup("_RetVal"));
+- ft->details.function->retval->type = return_type;
++ ft->details.function->retval->declspec.type = return_type;
++ ft->details.function->retval->declspec.typequalifier = typequalifier;
++
+ /* move calling convention attribute, if present, from pointer nodes to
+ * function node */
+- for (t = v->type; is_ptr(t); t = type_pointer_get_ref(t))
++ for (t = v->declspec.type; is_ptr(t); t = type_pointer_get_ref_type(t))
+ ft->attrs = move_attr(ft->attrs, t->attrs, ATTR_CALLCONV);
+ }
+ else
+ {
+ type_t *t;
+- for (t = v->type; is_ptr(t); t = type_pointer_get_ref(t))
++ for (t = v->declspec.type; is_ptr(t); t = type_pointer_get_ref_type(t))
+ if (is_attr(t->attrs, ATTR_CALLCONV))
+ error_loc("calling convention applied to non-function-pointer type\n");
+ }
+
+- if (decl->bits)
+- v->type = type_new_bitfield(v->type, decl->bits);
+-
+ return v;
+ }
+
+@@ -5866,6 +5939,10 @@ var_list_t *append_var(var_list_t *list, var_t *var)
+ list_init( list );
+ }
+ list_add_tail( list, &var->entry );
++
++ if (var->declspec.type)
++ var->declonly = !type_is_defined(var->declspec.type);
++
+ return list;
+ }
+
+@@ -5885,11 +5962,11 @@ var_t *make_var(char *name)
+ {
+ var_t *v = xmalloc(sizeof(var_t));
+ v->name = name;
+- v->type = NULL;
++ init_declspec(&v->declspec, NULL);
+ v->attrs = NULL;
+ v->eval = NULL;
+- v->stgclass = STG_NONE;
+ init_loc_info(&v->loc_info);
++ v->declonly = TRUE;
+ return v;
+ }
+
+@@ -5897,10 +5974,9 @@ static var_t *copy_var(var_t *src, char *name, map_attrs_filter_t attr_filter)
+ {
+ var_t *v = xmalloc(sizeof(var_t));
+ v->name = name;
+- v->type = src->type;
++ v->declspec = src->declspec;
+ v->attrs = map_attrs(src->attrs, attr_filter);
+ v->eval = src->eval;
+- v->stgclass = src->stgclass;
+ v->loc_info = src->loc_info;
+ return v;
+ }
+@@ -5920,7 +5996,7 @@ static declarator_t *make_declarator(var_t *var)
+ {
+ declarator_t *d = xmalloc(sizeof(*d));
+ d->var = var ? var : make_var(NULL);
+- d->type = NULL;
++ init_declspec(&d->declspec, NULL);
+ d->func_type = NULL;
+ d->bits = NULL;
+ return d;
+@@ -5928,7 +6004,15 @@ static declarator_t *make_declarator(var_t *var)
+
+ static type_t *make_safearray(type_t *type)
+ {
+- return type_new_array(NULL, type_new_alias(type, "SAFEARRAY"), TRUE, 0,
++ decl_spec_t aliasee_ds;
++ decl_spec_t element_ds;
++
++ init_declspec(&element_ds,
++ type_new_alias(
++ init_declspec(&aliasee_ds, type),
++ "SAFEARRAY"));
++
++ return type_new_array(NULL, &element_ds, TRUE, 0,
+ NULL, NULL, FC_RP);
+ }
+
+@@ -6007,6 +6091,8 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in
+ }
+ if (!namespace)
+ namespace = &global_namespace;
++ printf("reg_type { name : %s, namespace : %s, type : %s, ptr : %p}\n", name, namespace->name, ts_to_str(t), type);
++
+ hash = hash_ident(name);
+ nt = xmalloc(sizeof(struct rtype));
+ nt->name = name;
+@@ -6018,15 +6104,16 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in
+ nt->t = t;
+ nt->next = namespace->type_hash[hash];
+ namespace->type_hash[hash] = nt;
+- if ((t == tsSTRUCT || t == tsUNION))
++ if ((t == tsSTRUCT || t == tsUNION || t == tsENUM))
+ fix_incomplete_types(type);
+ return type;
+ }
+
+ static int is_incomplete(const type_t *t)
+ {
+- return !t->defined &&
+- (type_get_type_detect_alias(t) == TYPE_STRUCT ||
++ return !type_is_defined(t) &&
++ (type_get_type_detect_alias(t) == TYPE_ENUM ||
++ type_get_type_detect_alias(t) == TYPE_STRUCT ||
+ type_get_type_detect_alias(t) == TYPE_UNION ||
+ type_get_type_detect_alias(t) == TYPE_ENCAPSULATED_UNION);
+ }
+@@ -6034,19 +6121,16 @@ static int is_incomplete(const type_t *t)
+ void add_incomplete(type_t *t)
+ {
+ struct typenode *tn = xmalloc(sizeof *tn);
++ assert(is_incomplete(t));
+ tn->type = t;
+ list_add_tail(&incomplete_types, &tn->entry);
+ }
+
+ static void fix_type(type_t *t)
+ {
+- if (type_is_alias(t) && is_incomplete(t)) {
+- type_t *ot = type_alias_get_aliasee(t);
+- fix_type(ot);
+- if (type_get_type_detect_alias(ot) == TYPE_STRUCT ||
+- type_get_type_detect_alias(ot) == TYPE_UNION ||
+- type_get_type_detect_alias(ot) == TYPE_ENCAPSULATED_UNION)
+- t->details.structure = ot->details.structure;
++ if (type_is_alias(t) && is_incomplete(t))
++ {
++ type_t *ot = type_alias_get_aliasee_type(t);
+ t->defined = ot->defined;
+ }
+ }
+@@ -6070,7 +6154,7 @@ static void fix_incomplete_types(type_t *complete_type)
+ {
+ if (type_is_equal(complete_type, tn->type))
+ {
+- tn->type->details.structure = complete_type->details.structure;
++ tn->type->details = complete_type->details;
+ list_remove(&tn->entry);
+ free(tn);
+ }
+@@ -6094,7 +6178,13 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
+ type_get_type_detect_alias(type) == TYPE_ENCAPSULATED_UNION)
+ {
+ if (!type->name)
++ {
+ type->name = gen_name();
++ /* the generated name will be used and this typedef excluded from the
++ * built typelib unless the typedef has the 'public' attribute, so add it here */
++ if (do_typelib && !is_attr(attrs, ATTR_PUBLIC))
++ attrs = append_attr(attrs, make_attr(ATTR_PUBLIC));
++ }
+
+ /* replace existing attributes when generating a typelib */
+ if (do_typelib)
+@@ -6120,12 +6210,12 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
+ * for cleaner solution.
+ */
+ if (cur && input_name == cur->loc_info.input_name)
+- error_loc("%s: redefinition error; original definition was at %s:%d\n",
++ error_loc("FOO %s: redefinition error; original definition was at %s:%d\n",
+ cur->name, cur->loc_info.input_name,
+ cur->loc_info.line_number);
+
+ name = declare_var(attrs, decl_spec, decl, 0);
+- cur = type_new_alias(name->type, name->name);
++ cur = type_new_alias(&name->declspec, name->name);
+ cur->attrs = attrs;
+
+ if (is_incomplete(cur))
+@@ -6140,6 +6230,8 @@ type_t *find_type(const char *name, struct namespace *namespace, int t)
+ {
+ struct rtype *cur;
+
++ printf("find_type { name : %s, namespace %s, type : %s }\n", name, namespace ? namespace->name : NULL, ts_to_str(t));
++
+ if(namespace && namespace != &global_namespace) {
+ for(cur = namespace->type_hash[hash_ident(name)]; cur; cur = cur->next) {
+ if(cur->t == t && !strcmp(cur->name, name))
+@@ -6293,7 +6385,6 @@ struct allowed_attr allowed_attr[] =
+ /* ATTR_CASE */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "case" },
+ /* ATTR_CODE */ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" },
+ /* ATTR_COMMSTATUS */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" },
+- /* ATTR_CONST */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "const" },
+ /* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" },
+ /* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, "control" },
+ /* ATTR_DECODE */ { 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "decode" },
+@@ -6328,7 +6419,6 @@ struct allowed_attr allowed_attr[] =
+ /* ATTR_IMMEDIATEBIND */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "immediatebind" },
+ /* ATTR_IMPLICIT_HANDLE */ { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "implicit_handle" },
+ /* ATTR_IN */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "in" },
+- /* ATTR_INLINE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inline" },
+ /* ATTR_INPUTSYNC */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inputsync" },
+ /* ATTR_LENGTHIS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, "length_is" },
+ /* ATTR_LIBLCID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "lcid" },
+@@ -6400,10 +6490,10 @@ static attr_list_t *check_iface_attrs(const char *name, attr_list_t *attrs)
+ if (attr->type == ATTR_IMPLICIT_HANDLE)
+ {
+ const var_t *var = attr->u.pval;
+- if (type_get_type( var->type) == TYPE_BASIC &&
+- type_basic_get_type( var->type ) == TYPE_BASIC_HANDLE)
++ if (type_get_type( var->declspec.type) == TYPE_BASIC &&
++ type_basic_get_type( var->declspec.type ) == TYPE_BASIC_HANDLE)
+ continue;
+- if (is_aliaschain_attr( var->type, ATTR_HANDLE ))
++ if (is_aliaschain_attr( var->declspec.type, ATTR_HANDLE ))
+ continue;
+ error_loc("attribute %s requires a handle type in interface %s\n",
+ allowed_attr[attr->type].display_name, name);
+@@ -6608,7 +6698,7 @@ static int is_ptr_guid_type(const type_t *type)
+
+ /* second, make sure it is a pointer to something of size sizeof(GUID),
+ * i.e. 16 bytes */
+- return (type_memsize(type_pointer_get_ref(type)) == 16);
++ return (type_memsize(type_pointer_get_ref_type(type)) == 16);
+ }
+
+ static void check_conformance_expr_list(const char *attr_name, const var_t *arg, const type_t *container_type, expr_list_t *expr_list)
+@@ -6635,7 +6725,7 @@ static void check_remoting_fields(const var_t *var, type_t *type);
+ static void check_field_common(const type_t *container_type,
+ const char *container_name, const var_t *arg)
+ {
+- type_t *type = arg->type;
++ type_t *type = arg->declspec.type;
+ int more_to_do;
+ const char *container_type_name;
+ const char *var_type;
+@@ -6665,7 +6755,7 @@ static void check_field_common(const type_t *container_type,
+ }
+
+ if (is_attr(arg->attrs, ATTR_LENGTHIS) &&
+- (is_attr(arg->attrs, ATTR_STRING) || is_aliaschain_attr(arg->type, ATTR_STRING)))
++ (is_attr(arg->attrs, ATTR_STRING) || is_aliaschain_attr(arg->declspec.type, ATTR_STRING)))
+ error_loc_info(&arg->loc_info,
+ "string and length_is specified for argument %s are mutually exclusive attributes\n",
+ arg->name);
+@@ -6762,23 +6852,28 @@ static void check_field_common(const type_t *container_type,
+ {
+ const type_t *t = type;
+ while (is_ptr(t))
+- t = type_pointer_get_ref(t);
++ t = type_pointer_get_ref_type(t);
+ if (is_aliaschain_attr(t, ATTR_RANGE))
+ warning_loc_info(&arg->loc_info, "%s: range not verified for a string of ranged types\n", arg->name);
+ break;
+ }
+ case TGT_POINTER:
+- type = type_pointer_get_ref(type);
++ type = type_pointer_get_ref_type(type);
+ more_to_do = TRUE;
+ break;
+ case TGT_ARRAY:
+- type = type_array_get_element(type);
++ type = type_array_get_element_type(type);
+ more_to_do = TRUE;
+ break;
++ case TGT_ENUM:
++ type = type_get_real_type(type);
++ if(!type_is_complete(type))
++ {
++ error_loc_info(&arg->loc_info, "undefined type declaration enum %s\n", type->name);
++ }
+ case TGT_USER_TYPE:
+ case TGT_IFACE_POINTER:
+ case TGT_BASIC:
+- case TGT_ENUM:
+ case TGT_RANGE:
+ /* nothing to do */
+ break;
+@@ -6803,13 +6898,18 @@ static void check_remoting_fields(const var_t *var, type_t *type)
+ if (type_is_complete(type))
+ fields = type_struct_get_fields(type);
+ else
+- error_loc_info(&var->loc_info, "undefined type declaration %s\n", type->name);
++ error_loc_info(&var->loc_info, "undefined type declaration struct %s\n", type->name);
+ }
+ else if (type_get_type(type) == TYPE_UNION || type_get_type(type) == TYPE_ENCAPSULATED_UNION)
+- fields = type_union_get_cases(type);
++ {
++ if (type_is_complete(type))
++ fields = type_union_get_cases(type);
++ else
++ error_loc_info(&var->loc_info, "undefined type declaration union %s\n", type->name);
++ }
+
+ if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
+- if (field->type) check_field_common(type, type->name, field);
++ if (field->declspec.type) check_field_common(type, type->name, field);
+ }
+
+ /* checks that arguments for a function make sense for marshalling and unmarshalling */
+@@ -6818,9 +6918,10 @@ static void check_remoting_args(const var_t *func)
+ const char *funcname = func->name;
+ const var_t *arg;
+
+- if (func->type->details.function->args) LIST_FOR_EACH_ENTRY( arg, func->type->details.function->args, const var_t, entry )
++ assert(type_get_type_detect_alias(func->declspec.type) == TYPE_FUNCTION);
++ if (func->declspec.type->details.function->args) LIST_FOR_EACH_ENTRY( arg, func->declspec.type->details.function->args, const var_t, entry )
+ {
+- const type_t *type = arg->type;
++ const type_t *type = arg->declspec.type;
+
+ /* check that [out] parameters have enough pointer levels */
+ if (is_attr(arg->attrs, ATTR_OUT))
+@@ -6860,16 +6961,16 @@ static void check_remoting_args(const var_t *func)
+ }
+ }
+
+- check_field_common(func->type, funcname, arg);
++ check_field_common(func->declspec.type, funcname, arg);
+ }
+
+- if (type_get_type(type_function_get_rettype(func->type)) != TYPE_VOID)
++ if (type_get_type(type_function_get_rettype(func->declspec.type)) != TYPE_VOID)
+ {
+ var_t var;
+ var = *func;
+- var.type = type_function_get_rettype(func->type);
++ var.declspec.type = type_function_get_rettype(func->declspec.type);
+ var.name = xstrdup("return value");
+- check_field_common(func->type, funcname, &var);
++ check_field_common(func->declspec.type, funcname, &var);
+ free(var.name);
+ }
+ }
+@@ -6886,8 +6987,8 @@ static void add_explicit_handle_if_necessary(const type_t *iface, var_t *func)
+ * function */
+ var_t *idl_handle = make_var(xstrdup("IDL_handle"));
+ idl_handle->attrs = append_attr(NULL, make_attr(ATTR_IN));
+- idl_handle->type = find_type_or_error("handle_t", 0);
+- type_function_add_head_arg(func->type, idl_handle);
++ idl_handle->declspec.type = find_type_or_error("handle_t", 0);
++ type_function_add_head_arg(func->declspec.type, idl_handle);
+ }
+ }
+
+@@ -6952,6 +7053,7 @@ static void check_async_uuid(type_t *iface)
+ type_t *async_iface;
+ type_t *inherit;
+
++ assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
+ if (!is_attr(iface->attrs, ATTR_ASYNCUUID)) return;
+
+ inherit = iface->details.iface->inherit;
+@@ -6968,7 +7070,8 @@ static void check_async_uuid(type_t *iface)
+ var_t *begin_func, *finish_func, *func = stmt->u.var, *arg;
+ var_list_t *begin_args = NULL, *finish_args = NULL, *args;
+
+- args = func->type->details.function->args;
++ assert(type_get_type_detect_alias(func->declspec.type) == TYPE_FUNCTION);
++ args = func->declspec.type->details.function->args;
+ if (args) LIST_FOR_EACH_ENTRY(arg, args, var_t, entry)
+ {
+ if (is_attr(arg->attrs, ATTR_IN) || !is_attr(arg->attrs, ATTR_OUT))
+@@ -6978,15 +7081,15 @@ static void check_async_uuid(type_t *iface)
+ }
+
+ begin_func = copy_var(func, concat_str("Begin_", func->name), NULL);
+- begin_func->type = type_new_function(begin_args);
+- begin_func->type->attrs = func->attrs;
+- begin_func->type->details.function->retval = func->type->details.function->retval;
++ begin_func->declspec.type = type_new_function(begin_args);
++ begin_func->declspec.type->attrs = func->attrs;
++ begin_func->declspec.type->details.function->retval = func->declspec.type->details.function->retval;
+ stmts = append_statement(stmts, make_statement_declaration(begin_func));
+
+ finish_func = copy_var(func, concat_str("Finish_", func->name), NULL);
+- finish_func->type = type_new_function(finish_args);
+- finish_func->type->attrs = func->attrs;
+- finish_func->type->details.function->retval = func->type->details.function->retval;
++ finish_func->declspec.type = type_new_function(finish_args);
++ finish_func->declspec.type->attrs = func->attrs;
++ finish_func->declspec.type->details.function->retval = func->declspec.type->details.function->retval;
+ stmts = append_statement(stmts, make_statement_declaration(finish_func));
+ }
+
+@@ -7026,6 +7129,7 @@ static void check_statements(const statement_list_t *stmts, int is_inside_librar
+ static void check_all_user_types(const statement_list_t *stmts)
+ {
+ const statement_t *stmt;
++ const var_t *v;
+
+ if (stmts) LIST_FOR_EACH_ENTRY(stmt, stmts, const statement_t, entry)
+ {
+@@ -7037,7 +7141,11 @@ static void check_all_user_types(const statement_list_t *stmts)
+ const statement_t *stmt_func;
+ STATEMENTS_FOR_EACH_FUNC(stmt_func, type_iface_get_stmts(stmt->u.type)) {
+ const var_t *func = stmt_func->u.var;
+- check_for_additional_prototype_types(func->type->details.function->args);
++ assert(type_get_type_detect_alias(func->declspec.type) == TYPE_FUNCTION);
++ if (func->declspec.type->details.function->args)
++ LIST_FOR_EACH_ENTRY( v, func->declspec.type->details.function->args, const var_t, entry )
++ check_for_additional_prototype_types(v->declspec.type);
++ check_for_additional_prototype_types(type_function_get_rettype(func->declspec.type));
+ }
+ }
+ }
+@@ -7071,6 +7179,10 @@ static statement_t *make_statement_type_decl(type_t *type)
+ {
+ statement_t *stmt = make_statement(STMT_TYPE);
+ stmt->u.type = type;
++ if (type_is_defined(type))
++ {
++ stmt->declonly = FALSE;
++ }
+ return stmt;
+ }
+
+@@ -7085,16 +7197,16 @@ static statement_t *make_statement_declaration(var_t *var)
+ {
+ statement_t *stmt = make_statement(STMT_DECLARATION);
+ stmt->u.var = var;
+- if (var->stgclass == STG_EXTERN && var->eval)
++ if (var->declspec.stgclass == STG_EXTERN && var->eval)
+ warning("'%s' initialised and declared extern\n", var->name);
+ if (is_const_decl(var))
+ {
+ if (var->eval)
+ reg_const(var);
+ }
+- else if (type_get_type(var->type) == TYPE_FUNCTION)
++ else if (type_get_type(var->declspec.type) == TYPE_FUNCTION)
+ check_function_attrs(var->name, var->attrs);
+- else if (var->stgclass == STG_NONE || var->stgclass == STG_REGISTER)
++ else if (var->declspec.stgclass == STG_NONE || var->declspec.stgclass == STG_REGISTER)
+ error_loc("instantiation of data is illegal\n");
+ return stmt;
+ }
+@@ -7146,6 +7258,7 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
+ declarator_t *decl, *next;
+ statement_t *stmt;
+ type_list_t **type_list;
++ int defined = TRUE;
+
+ if (!decls) return NULL;
+
+@@ -7157,6 +7270,18 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
+ {
+ var_t *var = decl->var;
+ type_t *type = find_type_or_error(var->name, 0);
++
++ /* ensure that all of the types in this typedef statement have been defined
++ * before setting its declonly flag */
++ if (type_is_pointerish(type))
++ {
++ defined = defined & type_is_defined(type_get_pointer_chain_tail(type));
++ }
++ else
++ {
++ defined = defined & type_is_defined(type_get_real_type(type));
++ }
++
+ *type_list = xmalloc(sizeof(type_list_t));
+ (*type_list)->type = type;
+ (*type_list)->next = NULL;
+@@ -7166,6 +7291,7 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
+ free(var);
+ }
+
++ stmt->declonly = !defined;
+ return stmt;
+ }
+
+@@ -7206,7 +7332,7 @@ void init_loc_info(loc_info_t *i)
+
+ static void check_def(const type_t *t)
+ {
+- if (t->defined)
+- error_loc("%s: redefinition error; original definition was at %s:%d\n",
++ if (type_is_defined(t))
++ error_loc("BAR %s: redefinition error; original definition was at %s:%d\n",
+ t->name, t->loc_info.input_name, t->loc_info.line_number);
+ }
+diff --git a/mingw-w64-tools/widl/src/parser.tab.h b/mingw-w64-tools/widl/src/parser.tab.h
+index 09874726..fc7a8f4d 100644
+--- a/mingw-w64-tools/widl/src/parser.tab.h
++++ b/mingw-w64-tools/widl/src/parser.tab.h
+@@ -1,8 +1,8 @@
+-/* A Bison parser, made by GNU Bison 3.0.5. */
++/* A Bison parser, made by GNU Bison 3.0.4. */
+
+ /* Bison interface for Yacc-like parsers in C
+
+- Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc.
++ Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+@@ -239,7 +239,7 @@ extern int parser_debug;
+
+ union YYSTYPE
+ {
+-#line 142 "parser.y" /* yacc.c:1910 */
++#line 136 "parser.y" /* yacc.c:1909 */
+
+ attr_t *attr;
+ attr_list_t *attr_list;
+@@ -266,8 +266,10 @@ union YYSTYPE
+ struct _import_t *import;
+ struct _decl_spec_t *declspec;
+ enum storage_class stgclass;
++ enum type_qualifier typequalifier;
++ enum function_specifier funcspecifier;
+
+-#line 271 "parser.tab.h" /* yacc.c:1910 */
++#line 273 "parser.tab.h" /* yacc.c:1909 */
+ };
+
+ typedef union YYSTYPE YYSTYPE;
+diff --git a/mingw-w64-tools/widl/src/parser.y b/mingw-w64-tools/widl/src/parser.y
+index d9793941..bb14bf76 100644
+--- a/mingw-w64-tools/widl/src/parser.y
++++ b/mingw-w64-tools/widl/src/parser.y
+@@ -52,13 +52,6 @@ struct _import_t
+ int import_performed;
+ };
+
+-typedef struct _decl_spec_t
+-{
+- type_t *type;
+- attr_list_t *attrs;
+- enum storage_class stgclass;
+-} decl_spec_t;
+-
+ typelist_t incomplete_types = LIST_INIT(incomplete_types);
+
+ static void fix_incomplete(void);
+@@ -67,7 +60,7 @@ static void fix_incomplete_types(type_t *complete_type);
+ static str_list_t *append_str(str_list_t *list, char *str);
+ static attr_list_t *append_attr(attr_list_t *list, attr_t *attr);
+ static attr_list_t *append_attr_list(attr_list_t *new_list, attr_list_t *old_list);
+-static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, attr_t *attr, enum storage_class stgclass);
++static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, enum storage_class stgclass, enum type_qualifier typequalifier, enum function_specifier funcspecifier);
+ static attr_t *make_attr(enum attr_type type);
+ static attr_t *make_attrv(enum attr_type type, unsigned int val);
+ static attr_t *make_attrp(enum attr_type type, void *val);
+@@ -83,6 +76,7 @@ static declarator_t *make_declarator(var_t *var);
+ static type_t *make_safearray(type_t *type);
+ static typelib_t *make_library(const char *name, const attr_list_t *attrs);
+ static type_t *append_chain_type(type_t *chain, type_t *type);
++static decl_spec_t *append_chain_declspec(decl_spec_t *chain, type_t *type, enum type_qualifier typequalifier);
+ static warning_list_t *append_warning(warning_list_t *, int);
+
+ static type_t *reg_typedefs(decl_spec_t *decl_spec, var_list_t *names, attr_list_t *attrs);
+@@ -165,6 +159,8 @@ static typelib_t *current_typelib;
+ struct _import_t *import;
+ struct _decl_spec_t *declspec;
+ enum storage_class stgclass;
++ enum type_qualifier typequalifier;
++ enum function_specifier funcspecifier;
+ }
+
+ %token <str> aIDENTIFIER aPRAGMA
+@@ -266,14 +262,16 @@ static typelib_t *current_typelib;
+ %token tWCHAR tWIREMARSHAL
+ %token tAPARTMENT tNEUTRAL tSINGLE tFREE tBOTH
+
+-%type <attr> attribute type_qualifier function_specifier acf_attribute
+-%type <attr_list> m_attributes attributes attrib_list m_type_qual_list
++%type <attr> attribute acf_attribute
++%type <attr_list> m_attributes attributes attrib_list
+ %type <attr_list> acf_attributes acf_attribute_list
+ %type <str_list> str_list
+ %type <expr> m_expr expr expr_const expr_int_const array m_bitfield
+ %type <expr_list> m_exprs /* exprs expr_list */ expr_list_int_const
+ %type <ifinfo> interfacehdr
+ %type <stgclass> storage_cls_spec
++%type <typequalifier> type_qualifier m_type_qual_bits
++%type <funcspecifier> function_specifier
+ %type <declspec> decl_spec decl_spec_no_type m_decl_spec_no_type
+ %type <type> inherit interface interfacedef interfacedec
+ %type <type> dispinterface dispinterfacehdr dispinterfacedef
+@@ -318,7 +316,7 @@ static typelib_t *current_typelib;
+ %right '!' '~' CAST PPTR POS NEG ADDRESSOF tSIZEOF
+ %left '.' MEMBERPTR '[' ']'
+
+-%error-verbose
++%define parse.error verbose
+
+ %%
+
+@@ -651,10 +649,10 @@ enum_list: enum { if (!$1->eval)
+
+ enum: ident '=' expr_int_const { $$ = reg_const($1);
+ $$->eval = $3;
+- $$->type = type_new_int(TYPE_BASIC_INT, 0);
++ $$->declspec.type = type_new_int(TYPE_BASIC_INT, 0);
+ }
+ | ident { $$ = reg_const($1);
+- $$->type = type_new_int(TYPE_BASIC_INT, 0);
++ $$->declspec.type = type_new_int(TYPE_BASIC_INT, 0);
+ }
+ ;
+
+@@ -740,7 +738,7 @@ field: m_attributes decl_spec struct_declarator_list ';'
+ $$ = set_var_types($1, $2, $3);
+ }
+ | m_attributes uniondef ';' { var_t *v = make_var(NULL);
+- v->type = $2; v->attrs = $1;
++ v->declspec.type = $2; v->attrs = $1;
+ $$ = append_var(NULL, v);
+ }
+ ;
+@@ -764,13 +762,13 @@ s_field: m_attributes decl_spec declarator { $$ = declare_var(check_field_attrs
+ free($3);
+ }
+ | m_attributes structdef { var_t *v = make_var(NULL);
+- v->type = $2; v->attrs = $1;
++ v->declspec.type = $2; v->attrs = $1;
+ $$ = v;
+ }
+ ;
+
+ funcdef: declaration { $$ = $1;
+- if (type_get_type($$->type) != TYPE_FUNCTION)
++ if (type_get_type($$->declspec.type) != TYPE_FUNCTION)
+ error_loc("only methods may be declared inside the methods section of a dispinterface\n");
+ check_function_attrs($$->name, $$->attrs);
+ }
+@@ -955,20 +953,20 @@ storage_cls_spec:
+ ;
+
+ function_specifier:
+- tINLINE { $$ = make_attr(ATTR_INLINE); }
++ tINLINE { $$ = FUNCTION_SPECIFIER_INLINE; }
+ ;
+
+ type_qualifier:
+- tCONST { $$ = make_attr(ATTR_CONST); }
++ tCONST { $$ = TYPE_QUALIFIER_CONST; }
+ ;
+
+-m_type_qual_list: { $$ = NULL; }
+- | m_type_qual_list type_qualifier { $$ = append_attr($1, $2); }
++m_type_qual_bits: { $$ = TYPE_QUALIFIER_NONE; }
++ | m_type_qual_bits type_qualifier { $$ = $1 | $2; }
+ ;
+
+-decl_spec: type m_decl_spec_no_type { $$ = make_decl_spec($1, $2, NULL, NULL, STG_NONE); }
++decl_spec: type m_decl_spec_no_type { $$ = make_decl_spec($1, $2, NULL, STG_NONE, TYPE_QUALIFIER_NONE, FUNCTION_SPECIFIER_NONE); }
+ | decl_spec_no_type type m_decl_spec_no_type
+- { $$ = make_decl_spec($2, $1, $3, NULL, STG_NONE); }
++ { $$ = make_decl_spec($2, $1, $3, STG_NONE, TYPE_QUALIFIER_NONE, FUNCTION_SPECIFIER_NONE); }
+ ;
+
+ m_decl_spec_no_type: { $$ = NULL; }
+@@ -976,44 +974,44 @@ m_decl_spec_no_type: { $$ = NULL; }
+ ;
+
+ decl_spec_no_type:
+- type_qualifier m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, $1, STG_NONE); }
+- | function_specifier m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, $1, STG_NONE); }
+- | storage_cls_spec m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, NULL, $1); }
++ type_qualifier m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, STG_NONE, $1, FUNCTION_SPECIFIER_NONE); }
++ | function_specifier m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, STG_NONE, TYPE_QUALIFIER_NONE, $1); }
++ | storage_cls_spec m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, $1, TYPE_QUALIFIER_NONE, FUNCTION_SPECIFIER_NONE); }
+ ;
+
+ declarator:
+- '*' m_type_qual_list declarator %prec PPTR
+- { $$ = $3; $$->type = append_chain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
++ '*' m_type_qual_bits declarator %prec PPTR
++ { $$ = $3; append_chain_declspec(&$$->declspec, type_new_pointer(pointer_default, NULL), $2); }
+ | callconv declarator { $$ = $2; if ($$->func_type) $$->func_type->attrs = append_attr($$->func_type->attrs, make_attrp(ATTR_CALLCONV, $1));
+- else if ($$->type) $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
++ else if ($$->declspec.type) $$->declspec.type->attrs = append_attr($$->declspec.type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
+ | direct_declarator
+ ;
+
+ direct_declarator:
+ ident { $$ = make_declarator($1); }
+ | '(' declarator ')' { $$ = $2; }
+- | direct_declarator array { $$ = $1; $$->type = append_array($$->type, $2); }
++ | direct_declarator array { $$ = $1; $$->declspec.type = append_array($$->declspec.type, $2); }
+ | direct_declarator '(' m_args ')' { $$ = $1;
+- $$->func_type = append_chain_type($$->type, type_new_function($3));
+- $$->type = NULL;
++ $$->func_type = append_chain_type($$->declspec.type, type_new_function($3));
++ $$->declspec.type = NULL;
+ }
+ ;
+
+ /* abstract declarator */
+ abstract_declarator:
+- '*' m_type_qual_list m_abstract_declarator %prec PPTR
+- { $$ = $3; $$->type = append_chain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
++ '*' m_type_qual_bits m_abstract_declarator %prec PPTR
++ { $$ = $3; append_chain_declspec(&$$->declspec, type_new_pointer(pointer_default, NULL), $2); }
+ | callconv m_abstract_declarator { $$ = $2; if ($$->func_type) $$->func_type->attrs = append_attr($$->func_type->attrs, make_attrp(ATTR_CALLCONV, $1));
+- else if ($$->type) $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
++ else if ($$->declspec.type) $$->declspec.type->attrs = append_attr($$->declspec.type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
+ | abstract_direct_declarator
+ ;
+
+ /* abstract declarator without accepting direct declarator */
+ abstract_declarator_no_direct:
+- '*' m_type_qual_list m_any_declarator %prec PPTR
+- { $$ = $3; $$->type = append_chain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
++ '*' m_type_qual_bits m_any_declarator %prec PPTR
++ { $$ = $3; append_chain_declspec(&$$->declspec, type_new_pointer(pointer_default, NULL), $2); }
+ | callconv m_any_declarator { $$ = $2; if ($$->func_type) $$->func_type->attrs = append_attr($$->func_type->attrs, make_attrp(ATTR_CALLCONV, $1));
+- else if ($$->type) $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
++ else if ($$->declspec.type) $$->declspec.type->attrs = append_attr($$->declspec.type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
+ ;
+
+ /* abstract declarator or empty */
+@@ -1024,33 +1022,33 @@ m_abstract_declarator: { $$ = make_declarator(NULL); }
+ /* abstract direct declarator */
+ abstract_direct_declarator:
+ '(' abstract_declarator_no_direct ')' { $$ = $2; }
+- | abstract_direct_declarator array { $$ = $1; $$->type = append_array($$->type, $2); }
+- | array { $$ = make_declarator(NULL); $$->type = append_array($$->type, $1); }
++ | abstract_direct_declarator array { $$ = $1; $$->declspec.type = append_array($$->declspec.type, $2); }
++ | array { $$ = make_declarator(NULL); $$->declspec.type = append_array($$->declspec.type, $1); }
+ | '(' m_args ')'
+ { $$ = make_declarator(NULL);
+- $$->func_type = append_chain_type($$->type, type_new_function($2));
+- $$->type = NULL;
++ $$->func_type = append_chain_type($$->declspec.type, type_new_function($2));
++ $$->declspec.type = NULL;
+ }
+ | abstract_direct_declarator '(' m_args ')'
+ { $$ = $1;
+- $$->func_type = append_chain_type($$->type, type_new_function($3));
+- $$->type = NULL;
++ $$->func_type = append_chain_type($$->declspec.type, type_new_function($3));
++ $$->declspec.type = NULL;
+ }
+ ;
+
+ /* abstract or non-abstract declarator */
+ any_declarator:
+- '*' m_type_qual_list m_any_declarator %prec PPTR
+- { $$ = $3; $$->type = append_chain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
+- | callconv m_any_declarator { $$ = $2; $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
++ '*' m_type_qual_bits m_any_declarator %prec PPTR
++ { $$ = $3; append_chain_declspec(&$$->declspec, type_new_pointer(pointer_default, NULL), $2); }
++ | callconv m_any_declarator { $$ = $2; $$->declspec.type->attrs = append_attr($$->declspec.type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
+ | any_direct_declarator
+ ;
+
+ /* abstract or non-abstract declarator without accepting direct declarator */
+ any_declarator_no_direct:
+- '*' m_type_qual_list m_any_declarator %prec PPTR
+- { $$ = $3; $$->type = append_chain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
+- | callconv m_any_declarator { $$ = $2; $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
++ '*' m_type_qual_bits m_any_declarator %prec PPTR
++ { $$ = $3; append_chain_declspec(&$$->declspec, type_new_pointer(pointer_default, NULL), $2); }
++ | callconv m_any_declarator { $$ = $2; $$->declspec.type->attrs = append_attr($$->declspec.type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
+ ;
+
+ /* abstract or non-abstract declarator or empty */
+@@ -1064,17 +1062,17 @@ m_any_declarator: { $$ = make_declarator(NULL); }
+ any_direct_declarator:
+ ident { $$ = make_declarator($1); }
+ | '(' any_declarator_no_direct ')' { $$ = $2; }
+- | any_direct_declarator array { $$ = $1; $$->type = append_array($$->type, $2); }
+- | array { $$ = make_declarator(NULL); $$->type = append_array($$->type, $1); }
++ | any_direct_declarator array { $$ = $1; $$->declspec.type = append_array($$->declspec.type, $2); }
++ | array { $$ = make_declarator(NULL); $$->declspec.type = append_array($$->declspec.type, $1); }
+ | '(' m_args ')'
+ { $$ = make_declarator(NULL);
+- $$->func_type = append_chain_type($$->type, type_new_function($2));
+- $$->type = NULL;
++ $$->func_type = append_chain_type($$->declspec.type, type_new_function($2));
++ $$->declspec.type = NULL;
+ }
+ | any_direct_declarator '(' m_args ')'
+ { $$ = $1;
+- $$->func_type = append_chain_type($$->type, type_new_function($3));
+- $$->type = NULL;
++ $$->func_type = append_chain_type($$->declspec.type, type_new_function($3));
++ $$->declspec.type = NULL;
+ }
+ ;
+
+@@ -1197,7 +1195,8 @@ static void decl_builtin_basic(const char *name, enum type_basic_type type)
+
+ static void decl_builtin_alias(const char *name, type_t *t)
+ {
+- reg_type(type_new_alias(t, name), name, NULL, 0);
++ decl_spec_t ds;
++ reg_type(type_new_alias(init_declspec(&ds, t), name), name, &global_namespace, 0);
+ }
+
+ void init_types(void)
+@@ -1208,7 +1207,7 @@ void init_types(void)
+ decl_builtin_basic("double", TYPE_BASIC_DOUBLE);
+ decl_builtin_basic("error_status_t", TYPE_BASIC_ERROR_STATUS_T);
+ decl_builtin_basic("handle_t", TYPE_BASIC_HANDLE);
+- decl_builtin_alias("boolean", type_new_basic(TYPE_BASIC_BYTE));
++ decl_builtin_alias("boolean", type_new_basic(TYPE_BASIC_CHAR));
+ }
+
+ static str_list_t *append_str(str_list_t *list, char *str)
+@@ -1239,6 +1238,7 @@ static attr_list_t *append_attr(attr_list_t *list, attr_t *attr)
+ LIST_FOR_EACH_ENTRY(attr_existing, list, attr_t, entry)
+ if (attr_existing->type == attr->type)
+ {
++ __builtin_trap();
+ parser_warning("duplicate attribute %s\n", get_attr_display_name(attr->type));
+ /* use the last attribute, like MIDL does */
+ list_remove(&attr_existing->entry);
+@@ -1298,53 +1298,73 @@ static attr_list_t *map_attrs(const attr_list_t *list, map_attrs_filter_t filter
+ return new_list;
+ }
+
+-static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, attr_t *attr, enum storage_class stgclass)
++static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, enum storage_class stgclass, enum type_qualifier typequalifier, enum function_specifier funcspecifier)
+ {
+ decl_spec_t *declspec = left ? left : right;
+ if (!declspec)
+ {
+ declspec = xmalloc(sizeof(*declspec));
+ declspec->type = NULL;
+- declspec->attrs = NULL;
+ declspec->stgclass = STG_NONE;
++ declspec->typequalifier = TYPE_QUALIFIER_NONE;
++ declspec->funcspecifier = FUNCTION_SPECIFIER_NONE;
+ }
+ declspec->type = type;
+ if (left && declspec != left)
+ {
+- declspec->attrs = append_attr_list(declspec->attrs, left->attrs);
+ if (declspec->stgclass == STG_NONE)
+ declspec->stgclass = left->stgclass;
+ else if (left->stgclass != STG_NONE)
+ error_loc("only one storage class can be specified\n");
++
++ if (declspec->typequalifier == TYPE_QUALIFIER_NONE)
++ declspec->typequalifier = left->typequalifier;
++ else if (left->typequalifier != TYPE_QUALIFIER_NONE)
++ error_loc("only one type qualifier can be specified\n");
++
++ if (declspec->funcspecifier == FUNCTION_SPECIFIER_NONE)
++ declspec->funcspecifier = left->funcspecifier;
++ else if (left->funcspecifier != FUNCTION_SPECIFIER_NONE)
++ error_loc("only one function specifier can be specified\n");
++
+ assert(!left->type);
+ free(left);
+ }
+ if (right && declspec != right)
+ {
+- declspec->attrs = append_attr_list(declspec->attrs, right->attrs);
+ if (declspec->stgclass == STG_NONE)
+ declspec->stgclass = right->stgclass;
+ else if (right->stgclass != STG_NONE)
+ error_loc("only one storage class can be specified\n");
++
++ if (declspec->typequalifier == TYPE_QUALIFIER_NONE)
++ declspec->typequalifier = right->typequalifier;
++ else if (right->typequalifier != TYPE_QUALIFIER_NONE)
++ error_loc("only one type qualifier can be specified\n");
++
++ if (declspec->funcspecifier == FUNCTION_SPECIFIER_NONE)
++ declspec->funcspecifier = right->funcspecifier;
++ else if (right->funcspecifier != FUNCTION_SPECIFIER_NONE)
++ error_loc("only one function specifier can be specified\n");
++
+ assert(!right->type);
+ free(right);
+ }
+
+- declspec->attrs = append_attr(declspec->attrs, attr);
+ if (declspec->stgclass == STG_NONE)
+ declspec->stgclass = stgclass;
+ else if (stgclass != STG_NONE)
+ error_loc("only one storage class can be specified\n");
+
+- /* apply attributes to type */
+- if (type && declspec->attrs)
+- {
+- attr_list_t *attrs;
+- declspec->type = duptype(type, 1);
+- attrs = map_attrs(type->attrs, NULL);
+- declspec->type->attrs = append_attr_list(attrs, declspec->attrs);
+- declspec->attrs = NULL;
+- }
++ if (declspec->typequalifier == TYPE_QUALIFIER_NONE)
++ declspec->typequalifier = typequalifier;
++ else if (typequalifier != TYPE_QUALIFIER_NONE)
++ error_loc("only one type qualifier can be specified\n");
++
++ if (declspec->funcspecifier == FUNCTION_SPECIFIER_NONE)
++ declspec->funcspecifier = funcspecifier;
++ else if (funcspecifier != FUNCTION_SPECIFIER_NONE)
++ error_loc("only one function specifier can be specified\n");
+
+ return declspec;
+ }
+@@ -1430,6 +1450,7 @@ void clear_all_offsets(void)
+
+ static void type_function_add_head_arg(type_t *type, var_t *arg)
+ {
++ assert(type_get_type_detect_alias(type) == TYPE_FUNCTION);
+ if (!type->details.function->args)
+ {
+ type->details.function->args = xmalloc( sizeof(*type->details.function->args) );
+@@ -1474,31 +1495,60 @@ static int is_allowed_range_type(const type_t *type)
+ static type_t *get_array_or_ptr_ref(type_t *type)
+ {
+ if (is_ptr(type))
+- return type_pointer_get_ref(type);
++ return type_pointer_get_ref_type(type);
+ else if (is_array(type))
+- return type_array_get_element(type);
++ return type_array_get_element_type(type);
+ return NULL;
+ }
+
+ static type_t *append_chain_type(type_t *chain, type_t *type)
+ {
+- type_t *chain_type;
++ type_t *chain_type = NULL;
+
+ if (!chain)
+ return type;
+ for (chain_type = chain; get_array_or_ptr_ref(chain_type); chain_type = get_array_or_ptr_ref(chain_type))
+ ;
+
++ assert(!type_is_alias(chain_type));
+ if (is_ptr(chain_type))
+- chain_type->details.pointer.ref = type;
++ chain_type->details.pointer.ref.type = type;
+ else if (is_array(chain_type))
+- chain_type->details.array.elem = type;
++ chain_type->details.array.elem.type = type;
+ else
+ assert(0);
+
+ return chain;
+ }
+
++static decl_spec_t *append_chain_declspec(decl_spec_t *chain, type_t *type, enum type_qualifier typequalifier)
++{
++ type_t *chain_type = chain->type;
++ decl_spec_t *chain_declspec = NULL;
++
++ if (!chain_type)
++ {
++ chain->type = type;
++ chain->typequalifier = typequalifier;
++ return chain;
++ }
++
++ for(; get_array_or_ptr_ref(chain_type); chain_type = get_array_or_ptr_ref(chain_type))
++ ;
++
++ if (is_ptr(chain_type))
++ chain_declspec = &chain_type->details.pointer.ref;
++ else if (is_array(chain_type))
++ chain_declspec = &chain_type->details.array.elem;
++ else
++ assert(NULL);
++
++ chain_declspec->type = type;
++ chain_declspec->typequalifier = typequalifier;
++
++ return chain;
++}
++
+ static warning_list_t *append_warning(warning_list_t *list, int num)
+ {
+ warning_t *entry;
+@@ -1514,7 +1564,7 @@ static warning_list_t *append_warning(warning_list_t *list, int num)
+ return list;
+ }
+
+-static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const declarator_t *decl,
++static var_t *declare_var(attr_list_t *attrs, decl_spec_t *declspec, const declarator_t *decl,
+ int top)
+ {
+ var_t *v = decl->var;
+@@ -1523,58 +1573,80 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ expr_t *dim;
+ type_t **ptype;
+ type_t *func_type = decl ? decl->func_type : NULL;
+- type_t *type = decl_spec->type;
++ type_t *type = declspec->type;
+
+- if (is_attr(type->attrs, ATTR_INLINE))
+- {
++
++ if (declspec->funcspecifier == FUNCTION_SPECIFIER_INLINE) {
+ if (!func_type)
+ error_loc("inline attribute applied to non-function type\n");
+ else
+ {
+- type_t *t;
+- /* move inline attribute from return type node to function node */
+- for (t = func_type; is_ptr(t); t = type_pointer_get_ref(t))
+- ;
+- t->attrs = move_attr(t->attrs, type->attrs, ATTR_INLINE);
++ v->declspec.funcspecifier = declspec->funcspecifier;
+ }
+ }
+
+- /* add type onto the end of the pointers in pident->type */
+- v->type = append_chain_type(decl ? decl->type : NULL, type);
+- v->stgclass = decl_spec->stgclass;
++ /* if the var type is a pointerish, we need to move the type qualifier to the pointee's declspec
++ * unless the pointee already has const type qualifier*/
++ if (!decl)
++ {
++ /* simplest case, no pointers to deal with here */
++ v->declspec.typequalifier = declspec->typequalifier;
++ } else if (decl->bits)
++ {
++ /* dealing with a bitfield, generate bitfield and copy over typequalifier*/
++ v->declspec.type = type_new_bitfield(declspec->type, decl->bits);
++ v->declspec.typequalifier = declspec->typequalifier;
++ }
++ else
++ {
++ /* here we're dealing with a pointerish type chain, so we need to pull
++ * the typequalifier off of the declspec and stick them in the type's attr list
++ */
++ v->declspec.type = decl->declspec.type;
++ v->declspec.typequalifier = decl->declspec.typequalifier;
++ append_chain_declspec(&v->declspec, type, declspec->typequalifier);
++ }
++
++ v->declspec.stgclass = declspec->stgclass;
+ v->attrs = attrs;
+
+ /* check for pointer attribute being applied to non-pointer, non-array
+ * type */
+- if (!is_array(v->type))
++ if (!is_array(v->declspec.type))
+ {
+ int ptr_attr = get_attrv(v->attrs, ATTR_POINTERTYPE);
+ const type_t *ptr = NULL;
+ /* pointer attributes on the left side of the type belong to the function
+ * pointer, if one is being declared */
+- type_t **pt = func_type ? &func_type : &v->type;
++ type_t **pt = func_type ? &func_type : &v->declspec.type;
+ for (ptr = *pt; ptr && !ptr_attr; )
+ {
+ ptr_attr = get_attrv(ptr->attrs, ATTR_POINTERTYPE);
+ if (!ptr_attr && type_is_alias(ptr))
+- ptr = type_alias_get_aliasee(ptr);
++ ptr = type_alias_get_aliasee_type(ptr);
+ else
+ break;
+ }
+ if (is_ptr(ptr))
+ {
+ if (ptr_attr && ptr_attr != FC_UP &&
+- type_get_type(type_pointer_get_ref(ptr)) == TYPE_INTERFACE)
++ type_get_type(type_pointer_get_ref_type(ptr)) == TYPE_INTERFACE)
+ warning_loc_info(&v->loc_info,
+ "%s: pointer attribute applied to interface "
+ "pointer type has no effect\n", v->name);
+- if (!ptr_attr && top && (*pt)->details.pointer.def_fc != FC_RP)
++ if (!ptr_attr && top && type_pointer_get_default_fc(*pt) != FC_RP)
+ {
++ printf("dup_pointer_type!\n");
++ printf("type : %p name : %s\n", *pt, (*pt)->name);
++ /* ptr_attr is ref,unique or full (FC_RP, FC_UP, FC_FP) */
++ /* *pt could be the var's declspec's type OR a type on a typedef */
++ /* not an array */
++
+ /* FIXME: this is a horrible hack to cope with the issue that we
+ * store an offset to the typeformat string in the type object, but
+ * two typeformat strings may be written depending on whether the
+ * pointer is a toplevel parameter or not */
+- *pt = duptype(*pt, 1);
++ *pt = dup_pointer_type(*pt);
+ }
+ }
+ else if (ptr_attr)
+@@ -1585,16 +1657,16 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ {
+ type_t *t = type;
+
+- if (!is_ptr(v->type) && !is_array(v->type))
++ if (!is_ptr(v->declspec.type) && !is_array(v->declspec.type))
+ error_loc("'%s': [string] attribute applied to non-pointer, non-array type\n",
+ v->name);
+
+ for (;;)
+ {
+ if (is_ptr(t))
+- t = type_pointer_get_ref(t);
++ t = type_pointer_get_ref_type(t);
+ else if (is_array(t))
+- t = type_array_get_element(t);
++ t = type_array_get_element_type(t);
+ else
+ break;
+ }
+@@ -1611,15 +1683,15 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+
+ if (is_attr(v->attrs, ATTR_V1ENUM))
+ {
+- if (type_get_type_detect_alias(v->type) != TYPE_ENUM)
++ if (type_get_type_detect_alias(v->declspec.type) != TYPE_ENUM)
+ error_loc("'%s': [v1_enum] attribute applied to non-enum type\n", v->name);
+ }
+
+- if (is_attr(v->attrs, ATTR_RANGE) && !is_allowed_range_type(v->type))
++ if (is_attr(v->attrs, ATTR_RANGE) && !is_allowed_range_type(v->declspec.type))
+ error_loc("'%s': [range] attribute applied to non-integer type\n",
+ v->name);
+
+- ptype = &v->type;
++ ptype = &v->declspec.type;
+ if (sizes) LIST_FOR_EACH_ENTRY(dim, sizes, expr_t, entry)
+ {
+ if (dim->type != EXPR_VOID)
+@@ -1632,7 +1704,7 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ else
+ *ptype = type_new_array((*ptype)->name,
+ type_array_get_element(*ptype), FALSE,
+- 0, dim, NULL, 0);
++ 0, dim, NULL, FC_RP);
+ }
+ else if (is_ptr(*ptype))
+ *ptype = type_new_array((*ptype)->name, type_pointer_get_ref(*ptype), TRUE,
+@@ -1641,15 +1713,16 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ error_loc("%s: size_is attribute applied to illegal type\n", v->name);
+ }
+
++ assert(!type_is_alias(*ptype));
+ if (is_ptr(*ptype))
+- ptype = &(*ptype)->details.pointer.ref;
++ ptype = &(*ptype)->details.pointer.ref.type;
+ else if (is_array(*ptype))
+- ptype = &(*ptype)->details.array.elem;
++ ptype = &(*ptype)->details.array.elem.type;
+ else
+ error_loc("%s: too many expressions in size_is attribute\n", v->name);
+ }
+
+- ptype = &v->type;
++ ptype = &v->declspec.type;
+ if (lengs) LIST_FOR_EACH_ENTRY(dim, lengs, expr_t, entry)
+ {
+ if (dim->type != EXPR_VOID)
+@@ -1667,10 +1740,11 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ error_loc("%s: length_is attribute applied to illegal type\n", v->name);
+ }
+
++ assert(!type_is_alias(*ptype));
+ if (is_ptr(*ptype))
+- ptype = &(*ptype)->details.pointer.ref;
++ ptype = &(*ptype)->details.pointer.ref.type;
+ else if (is_array(*ptype))
+- ptype = &(*ptype)->details.array.elem;
++ ptype = &(*ptype)->details.array.elem.type;
+ else
+ error_loc("%s: too many expressions in length_is attribute\n", v->name);
+ }
+@@ -1681,29 +1755,31 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ if (func_type)
+ {
+ type_t *ft, *t;
+- type_t *return_type = v->type;
+- v->type = func_type;
+- for (ft = v->type; is_ptr(ft); ft = type_pointer_get_ref(ft))
++ type_t *return_type = v->declspec.type;
++ enum type_qualifier typequalifier = v->declspec.typequalifier;
++
++ v->declspec.type = func_type;
++ v->declspec.typequalifier = TYPE_QUALIFIER_NONE;
++ for (ft = v->declspec.type; is_ptr(ft); ft = type_pointer_get_ref_type(ft))
+ ;
+ assert(type_get_type_detect_alias(ft) == TYPE_FUNCTION);
+ ft->details.function->retval = make_var(xstrdup("_RetVal"));
+- ft->details.function->retval->type = return_type;
++ ft->details.function->retval->declspec.type = return_type;
++ ft->details.function->retval->declspec.typequalifier = typequalifier;
++
+ /* move calling convention attribute, if present, from pointer nodes to
+ * function node */
+- for (t = v->type; is_ptr(t); t = type_pointer_get_ref(t))
++ for (t = v->declspec.type; is_ptr(t); t = type_pointer_get_ref_type(t))
+ ft->attrs = move_attr(ft->attrs, t->attrs, ATTR_CALLCONV);
+ }
+ else
+ {
+ type_t *t;
+- for (t = v->type; is_ptr(t); t = type_pointer_get_ref(t))
++ for (t = v->declspec.type; is_ptr(t); t = type_pointer_get_ref_type(t))
+ if (is_attr(t->attrs, ATTR_CALLCONV))
+ error_loc("calling convention applied to non-function-pointer type\n");
+ }
+
+- if (decl->bits)
+- v->type = type_new_bitfield(v->type, decl->bits);
+-
+ return v;
+ }
+
+@@ -1751,6 +1827,10 @@ var_list_t *append_var(var_list_t *list, var_t *var)
+ list_init( list );
+ }
+ list_add_tail( list, &var->entry );
++
++ if (var->declspec.type)
++ var->declonly = !type_is_defined(var->declspec.type);
++
+ return list;
+ }
+
+@@ -1770,11 +1850,11 @@ var_t *make_var(char *name)
+ {
+ var_t *v = xmalloc(sizeof(var_t));
+ v->name = name;
+- v->type = NULL;
++ init_declspec(&v->declspec, NULL);
+ v->attrs = NULL;
+ v->eval = NULL;
+- v->stgclass = STG_NONE;
+ init_loc_info(&v->loc_info);
++ v->declonly = TRUE;
+ return v;
+ }
+
+@@ -1782,10 +1862,9 @@ static var_t *copy_var(var_t *src, char *name, map_attrs_filter_t attr_filter)
+ {
+ var_t *v = xmalloc(sizeof(var_t));
+ v->name = name;
+- v->type = src->type;
++ v->declspec = src->declspec;
+ v->attrs = map_attrs(src->attrs, attr_filter);
+ v->eval = src->eval;
+- v->stgclass = src->stgclass;
+ v->loc_info = src->loc_info;
+ return v;
+ }
+@@ -1805,7 +1884,7 @@ static declarator_t *make_declarator(var_t *var)
+ {
+ declarator_t *d = xmalloc(sizeof(*d));
+ d->var = var ? var : make_var(NULL);
+- d->type = NULL;
++ init_declspec(&d->declspec, NULL);
+ d->func_type = NULL;
+ d->bits = NULL;
+ return d;
+@@ -1813,7 +1892,15 @@ static declarator_t *make_declarator(var_t *var)
+
+ static type_t *make_safearray(type_t *type)
+ {
+- return type_new_array(NULL, type_new_alias(type, "SAFEARRAY"), TRUE, 0,
++ decl_spec_t aliasee_ds;
++ decl_spec_t element_ds;
++
++ init_declspec(&element_ds,
++ type_new_alias(
++ init_declspec(&aliasee_ds, type),
++ "SAFEARRAY"));
++
++ return type_new_array(NULL, &element_ds, TRUE, 0,
+ NULL, NULL, FC_RP);
+ }
+
+@@ -1892,6 +1979,8 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in
+ }
+ if (!namespace)
+ namespace = &global_namespace;
++ printf("reg_type { name : %s, namespace : %s, type : %s, ptr : %p}\n", name, namespace->name, ts_to_str(t), type);
++
+ hash = hash_ident(name);
+ nt = xmalloc(sizeof(struct rtype));
+ nt->name = name;
+@@ -1903,15 +1992,16 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in
+ nt->t = t;
+ nt->next = namespace->type_hash[hash];
+ namespace->type_hash[hash] = nt;
+- if ((t == tsSTRUCT || t == tsUNION))
++ if ((t == tsSTRUCT || t == tsUNION || t == tsENUM))
+ fix_incomplete_types(type);
+ return type;
+ }
+
+ static int is_incomplete(const type_t *t)
+ {
+- return !t->defined &&
+- (type_get_type_detect_alias(t) == TYPE_STRUCT ||
++ return !type_is_defined(t) &&
++ (type_get_type_detect_alias(t) == TYPE_ENUM ||
++ type_get_type_detect_alias(t) == TYPE_STRUCT ||
+ type_get_type_detect_alias(t) == TYPE_UNION ||
+ type_get_type_detect_alias(t) == TYPE_ENCAPSULATED_UNION);
+ }
+@@ -1919,19 +2009,16 @@ static int is_incomplete(const type_t *t)
+ void add_incomplete(type_t *t)
+ {
+ struct typenode *tn = xmalloc(sizeof *tn);
++ assert(is_incomplete(t));
+ tn->type = t;
+ list_add_tail(&incomplete_types, &tn->entry);
+ }
+
+ static void fix_type(type_t *t)
+ {
+- if (type_is_alias(t) && is_incomplete(t)) {
+- type_t *ot = type_alias_get_aliasee(t);
+- fix_type(ot);
+- if (type_get_type_detect_alias(ot) == TYPE_STRUCT ||
+- type_get_type_detect_alias(ot) == TYPE_UNION ||
+- type_get_type_detect_alias(ot) == TYPE_ENCAPSULATED_UNION)
+- t->details.structure = ot->details.structure;
++ if (type_is_alias(t) && is_incomplete(t))
++ {
++ type_t *ot = type_alias_get_aliasee_type(t);
+ t->defined = ot->defined;
+ }
+ }
+@@ -1955,7 +2042,7 @@ static void fix_incomplete_types(type_t *complete_type)
+ {
+ if (type_is_equal(complete_type, tn->type))
+ {
+- tn->type->details.structure = complete_type->details.structure;
++ tn->type->details = complete_type->details;
+ list_remove(&tn->entry);
+ free(tn);
+ }
+@@ -1979,7 +2066,13 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
+ type_get_type_detect_alias(type) == TYPE_ENCAPSULATED_UNION)
+ {
+ if (!type->name)
++ {
+ type->name = gen_name();
++ /* the generated name will be used and this typedef excluded from the
++ * built typelib unless the typedef has the 'public' attribute, so add it here */
++ if (do_typelib && !is_attr(attrs, ATTR_PUBLIC))
++ attrs = append_attr(attrs, make_attr(ATTR_PUBLIC));
++ }
+
+ /* replace existing attributes when generating a typelib */
+ if (do_typelib)
+@@ -2005,12 +2098,12 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
+ * for cleaner solution.
+ */
+ if (cur && input_name == cur->loc_info.input_name)
+- error_loc("%s: redefinition error; original definition was at %s:%d\n",
++ error_loc("FOO %s: redefinition error; original definition was at %s:%d\n",
+ cur->name, cur->loc_info.input_name,
+ cur->loc_info.line_number);
+
+ name = declare_var(attrs, decl_spec, decl, 0);
+- cur = type_new_alias(name->type, name->name);
++ cur = type_new_alias(&name->declspec, name->name);
+ cur->attrs = attrs;
+
+ if (is_incomplete(cur))
+@@ -2025,6 +2118,8 @@ type_t *find_type(const char *name, struct namespace *namespace, int t)
+ {
+ struct rtype *cur;
+
++ printf("find_type { name : %s, namespace %s, type : %s }\n", name, namespace ? namespace->name : NULL, ts_to_str(t));
++
+ if(namespace && namespace != &global_namespace) {
+ for(cur = namespace->type_hash[hash_ident(name)]; cur; cur = cur->next) {
+ if(cur->t == t && !strcmp(cur->name, name))
+@@ -2178,7 +2273,6 @@ struct allowed_attr allowed_attr[] =
+ /* ATTR_CASE */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "case" },
+ /* ATTR_CODE */ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" },
+ /* ATTR_COMMSTATUS */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" },
+- /* ATTR_CONST */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "const" },
+ /* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" },
+ /* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, "control" },
+ /* ATTR_DECODE */ { 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "decode" },
+@@ -2213,7 +2307,6 @@ struct allowed_attr allowed_attr[] =
+ /* ATTR_IMMEDIATEBIND */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "immediatebind" },
+ /* ATTR_IMPLICIT_HANDLE */ { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "implicit_handle" },
+ /* ATTR_IN */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "in" },
+- /* ATTR_INLINE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inline" },
+ /* ATTR_INPUTSYNC */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inputsync" },
+ /* ATTR_LENGTHIS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, "length_is" },
+ /* ATTR_LIBLCID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "lcid" },
+@@ -2285,10 +2378,10 @@ static attr_list_t *check_iface_attrs(const char *name, attr_list_t *attrs)
+ if (attr->type == ATTR_IMPLICIT_HANDLE)
+ {
+ const var_t *var = attr->u.pval;
+- if (type_get_type( var->type) == TYPE_BASIC &&
+- type_basic_get_type( var->type ) == TYPE_BASIC_HANDLE)
++ if (type_get_type( var->declspec.type) == TYPE_BASIC &&
++ type_basic_get_type( var->declspec.type ) == TYPE_BASIC_HANDLE)
+ continue;
+- if (is_aliaschain_attr( var->type, ATTR_HANDLE ))
++ if (is_aliaschain_attr( var->declspec.type, ATTR_HANDLE ))
+ continue;
+ error_loc("attribute %s requires a handle type in interface %s\n",
+ allowed_attr[attr->type].display_name, name);
+@@ -2493,7 +2586,7 @@ static int is_ptr_guid_type(const type_t *type)
+
+ /* second, make sure it is a pointer to something of size sizeof(GUID),
+ * i.e. 16 bytes */
+- return (type_memsize(type_pointer_get_ref(type)) == 16);
++ return (type_memsize(type_pointer_get_ref_type(type)) == 16);
+ }
+
+ static void check_conformance_expr_list(const char *attr_name, const var_t *arg, const type_t *container_type, expr_list_t *expr_list)
+@@ -2520,7 +2613,7 @@ static void check_remoting_fields(const var_t *var, type_t *type);
+ static void check_field_common(const type_t *container_type,
+ const char *container_name, const var_t *arg)
+ {
+- type_t *type = arg->type;
++ type_t *type = arg->declspec.type;
+ int more_to_do;
+ const char *container_type_name;
+ const char *var_type;
+@@ -2550,7 +2643,7 @@ static void check_field_common(const type_t *container_type,
+ }
+
+ if (is_attr(arg->attrs, ATTR_LENGTHIS) &&
+- (is_attr(arg->attrs, ATTR_STRING) || is_aliaschain_attr(arg->type, ATTR_STRING)))
++ (is_attr(arg->attrs, ATTR_STRING) || is_aliaschain_attr(arg->declspec.type, ATTR_STRING)))
+ error_loc_info(&arg->loc_info,
+ "string and length_is specified for argument %s are mutually exclusive attributes\n",
+ arg->name);
+@@ -2647,23 +2740,28 @@ static void check_field_common(const type_t *container_type,
+ {
+ const type_t *t = type;
+ while (is_ptr(t))
+- t = type_pointer_get_ref(t);
++ t = type_pointer_get_ref_type(t);
+ if (is_aliaschain_attr(t, ATTR_RANGE))
+ warning_loc_info(&arg->loc_info, "%s: range not verified for a string of ranged types\n", arg->name);
+ break;
+ }
+ case TGT_POINTER:
+- type = type_pointer_get_ref(type);
++ type = type_pointer_get_ref_type(type);
+ more_to_do = TRUE;
+ break;
+ case TGT_ARRAY:
+- type = type_array_get_element(type);
++ type = type_array_get_element_type(type);
+ more_to_do = TRUE;
+ break;
++ case TGT_ENUM:
++ type = type_get_real_type(type);
++ if(!type_is_complete(type))
++ {
++ error_loc_info(&arg->loc_info, "undefined type declaration enum %s\n", type->name);
++ }
+ case TGT_USER_TYPE:
+ case TGT_IFACE_POINTER:
+ case TGT_BASIC:
+- case TGT_ENUM:
+ case TGT_RANGE:
+ /* nothing to do */
+ break;
+@@ -2688,13 +2786,18 @@ static void check_remoting_fields(const var_t *var, type_t *type)
+ if (type_is_complete(type))
+ fields = type_struct_get_fields(type);
+ else
+- error_loc_info(&var->loc_info, "undefined type declaration %s\n", type->name);
++ error_loc_info(&var->loc_info, "undefined type declaration struct %s\n", type->name);
+ }
+ else if (type_get_type(type) == TYPE_UNION || type_get_type(type) == TYPE_ENCAPSULATED_UNION)
+- fields = type_union_get_cases(type);
++ {
++ if (type_is_complete(type))
++ fields = type_union_get_cases(type);
++ else
++ error_loc_info(&var->loc_info, "undefined type declaration union %s\n", type->name);
++ }
+
+ if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
+- if (field->type) check_field_common(type, type->name, field);
++ if (field->declspec.type) check_field_common(type, type->name, field);
+ }
+
+ /* checks that arguments for a function make sense for marshalling and unmarshalling */
+@@ -2703,9 +2806,10 @@ static void check_remoting_args(const var_t *func)
+ const char *funcname = func->name;
+ const var_t *arg;
+
+- if (func->type->details.function->args) LIST_FOR_EACH_ENTRY( arg, func->type->details.function->args, const var_t, entry )
++ assert(type_get_type_detect_alias(func->declspec.type) == TYPE_FUNCTION);
++ if (func->declspec.type->details.function->args) LIST_FOR_EACH_ENTRY( arg, func->declspec.type->details.function->args, const var_t, entry )
+ {
+- const type_t *type = arg->type;
++ const type_t *type = arg->declspec.type;
+
+ /* check that [out] parameters have enough pointer levels */
+ if (is_attr(arg->attrs, ATTR_OUT))
+@@ -2745,16 +2849,16 @@ static void check_remoting_args(const var_t *func)
+ }
+ }
+
+- check_field_common(func->type, funcname, arg);
++ check_field_common(func->declspec.type, funcname, arg);
+ }
+
+- if (type_get_type(type_function_get_rettype(func->type)) != TYPE_VOID)
++ if (type_get_type(type_function_get_rettype(func->declspec.type)) != TYPE_VOID)
+ {
+ var_t var;
+ var = *func;
+- var.type = type_function_get_rettype(func->type);
++ var.declspec.type = type_function_get_rettype(func->declspec.type);
+ var.name = xstrdup("return value");
+- check_field_common(func->type, funcname, &var);
++ check_field_common(func->declspec.type, funcname, &var);
+ free(var.name);
+ }
+ }
+@@ -2771,8 +2875,8 @@ static void add_explicit_handle_if_necessary(const type_t *iface, var_t *func)
+ * function */
+ var_t *idl_handle = make_var(xstrdup("IDL_handle"));
+ idl_handle->attrs = append_attr(NULL, make_attr(ATTR_IN));
+- idl_handle->type = find_type_or_error("handle_t", 0);
+- type_function_add_head_arg(func->type, idl_handle);
++ idl_handle->declspec.type = find_type_or_error("handle_t", 0);
++ type_function_add_head_arg(func->declspec.type, idl_handle);
+ }
+ }
+
+@@ -2837,6 +2941,7 @@ static void check_async_uuid(type_t *iface)
+ type_t *async_iface;
+ type_t *inherit;
+
++ assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
+ if (!is_attr(iface->attrs, ATTR_ASYNCUUID)) return;
+
+ inherit = iface->details.iface->inherit;
+@@ -2853,7 +2958,8 @@ static void check_async_uuid(type_t *iface)
+ var_t *begin_func, *finish_func, *func = stmt->u.var, *arg;
+ var_list_t *begin_args = NULL, *finish_args = NULL, *args;
+
+- args = func->type->details.function->args;
++ assert(type_get_type_detect_alias(func->declspec.type) == TYPE_FUNCTION);
++ args = func->declspec.type->details.function->args;
+ if (args) LIST_FOR_EACH_ENTRY(arg, args, var_t, entry)
+ {
+ if (is_attr(arg->attrs, ATTR_IN) || !is_attr(arg->attrs, ATTR_OUT))
+@@ -2863,15 +2969,15 @@ static void check_async_uuid(type_t *iface)
+ }
+
+ begin_func = copy_var(func, concat_str("Begin_", func->name), NULL);
+- begin_func->type = type_new_function(begin_args);
+- begin_func->type->attrs = func->attrs;
+- begin_func->type->details.function->retval = func->type->details.function->retval;
++ begin_func->declspec.type = type_new_function(begin_args);
++ begin_func->declspec.type->attrs = func->attrs;
++ begin_func->declspec.type->details.function->retval = func->declspec.type->details.function->retval;
+ stmts = append_statement(stmts, make_statement_declaration(begin_func));
+
+ finish_func = copy_var(func, concat_str("Finish_", func->name), NULL);
+- finish_func->type = type_new_function(finish_args);
+- finish_func->type->attrs = func->attrs;
+- finish_func->type->details.function->retval = func->type->details.function->retval;
++ finish_func->declspec.type = type_new_function(finish_args);
++ finish_func->declspec.type->attrs = func->attrs;
++ finish_func->declspec.type->details.function->retval = func->declspec.type->details.function->retval;
+ stmts = append_statement(stmts, make_statement_declaration(finish_func));
+ }
+
+@@ -2911,6 +3017,7 @@ static void check_statements(const statement_list_t *stmts, int is_inside_librar
+ static void check_all_user_types(const statement_list_t *stmts)
+ {
+ const statement_t *stmt;
++ const var_t *v;
+
+ if (stmts) LIST_FOR_EACH_ENTRY(stmt, stmts, const statement_t, entry)
+ {
+@@ -2922,7 +3029,11 @@ static void check_all_user_types(const statement_list_t *stmts)
+ const statement_t *stmt_func;
+ STATEMENTS_FOR_EACH_FUNC(stmt_func, type_iface_get_stmts(stmt->u.type)) {
+ const var_t *func = stmt_func->u.var;
+- check_for_additional_prototype_types(func->type->details.function->args);
++ assert(type_get_type_detect_alias(func->declspec.type) == TYPE_FUNCTION);
++ if (func->declspec.type->details.function->args)
++ LIST_FOR_EACH_ENTRY( v, func->declspec.type->details.function->args, const var_t, entry )
++ check_for_additional_prototype_types(v->declspec.type);
++ check_for_additional_prototype_types(type_function_get_rettype(func->declspec.type));
+ }
+ }
+ }
+@@ -2956,6 +3067,10 @@ static statement_t *make_statement_type_decl(type_t *type)
+ {
+ statement_t *stmt = make_statement(STMT_TYPE);
+ stmt->u.type = type;
++ if (type_is_defined(type))
++ {
++ stmt->declonly = FALSE;
++ }
+ return stmt;
+ }
+
+@@ -2970,16 +3085,16 @@ static statement_t *make_statement_declaration(var_t *var)
+ {
+ statement_t *stmt = make_statement(STMT_DECLARATION);
+ stmt->u.var = var;
+- if (var->stgclass == STG_EXTERN && var->eval)
++ if (var->declspec.stgclass == STG_EXTERN && var->eval)
+ warning("'%s' initialised and declared extern\n", var->name);
+ if (is_const_decl(var))
+ {
+ if (var->eval)
+ reg_const(var);
+ }
+- else if (type_get_type(var->type) == TYPE_FUNCTION)
++ else if (type_get_type(var->declspec.type) == TYPE_FUNCTION)
+ check_function_attrs(var->name, var->attrs);
+- else if (var->stgclass == STG_NONE || var->stgclass == STG_REGISTER)
++ else if (var->declspec.stgclass == STG_NONE || var->declspec.stgclass == STG_REGISTER)
+ error_loc("instantiation of data is illegal\n");
+ return stmt;
+ }
+@@ -3031,6 +3146,7 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
+ declarator_t *decl, *next;
+ statement_t *stmt;
+ type_list_t **type_list;
++ int defined = TRUE;
+
+ if (!decls) return NULL;
+
+@@ -3042,6 +3158,18 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
+ {
+ var_t *var = decl->var;
+ type_t *type = find_type_or_error(var->name, 0);
++
++ /* ensure that all of the types in this typedef statement have been defined
++ * before setting its declonly flag */
++ if (type_is_pointerish(type))
++ {
++ defined = defined & type_is_defined(type_get_pointer_chain_tail(type));
++ }
++ else
++ {
++ defined = defined & type_is_defined(type_get_real_type(type));
++ }
++
+ *type_list = xmalloc(sizeof(type_list_t));
+ (*type_list)->type = type;
+ (*type_list)->next = NULL;
+@@ -3051,6 +3179,7 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
+ free(var);
+ }
+
++ stmt->declonly = !defined;
+ return stmt;
+ }
+
+@@ -3091,7 +3220,7 @@ void init_loc_info(loc_info_t *i)
+
+ static void check_def(const type_t *t)
+ {
+- if (t->defined)
+- error_loc("%s: redefinition error; original definition was at %s:%d\n",
++ if (type_is_defined(t))
++ error_loc("BAR %s: redefinition error; original definition was at %s:%d\n",
+ t->name, t->loc_info.input_name, t->loc_info.line_number);
+ }
+diff --git a/mingw-w64-tools/widl/src/parser.yy.c b/mingw-w64-tools/widl/src/parser.yy.c
+index 2aaf3c27..0482aa7e 100644
+--- a/mingw-w64-tools/widl/src/parser.yy.c
++++ b/mingw-w64-tools/widl/src/parser.yy.c
+@@ -1,6 +1,6 @@
+-#line 1 "parser.yy.c"
++#line 2 "parser.yy.c"
+
+-#line 3 "parser.yy.c"
++#line 4 "parser.yy.c"
+
+ #define YY_INT_ALIGNED short int
+
+@@ -1041,13 +1041,13 @@ UUID *parse_uuid(const char *u)
+ return uuid;
+ }
+
+-#line 1044 "parser.yy.c"
++#line 1045 "parser.yy.c"
+ /*
+ **************************************************************************
+ * The flexer starts here
+ **************************************************************************
+ */
+-#line 1050 "parser.yy.c"
++#line 1051 "parser.yy.c"
+
+ #define INITIAL 0
+ #define QUOTE 1
+@@ -1281,7 +1281,7 @@ YY_DECL
+ {
+ #line 132 "parser.l"
+
+-#line 1284 "parser.yy.c"
++#line 1285 "parser.yy.c"
+
+ while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
+ {
+@@ -1616,7 +1616,7 @@ YY_RULE_SETUP
+ #line 239 "parser.l"
+ ECHO;
+ YY_BREAK
+-#line 1619 "parser.yy.c"
++#line 1620 "parser.yy.c"
+
+ case YY_END_OF_BUFFER:
+ {
+diff --git a/mingw-w64-tools/widl/src/proxy.c b/mingw-w64-tools/widl/src/proxy.c
+index 87c27be9..36b552be 100644
+--- a/mingw-w64-tools/widl/src/proxy.c
++++ b/mingw-w64-tools/widl/src/proxy.c
+@@ -67,7 +67,7 @@ static void write_stubdesc(int expr_eval_routines)
+ print_proxy( "1, /* -error bounds_check flag */\n");
+ print_proxy( "0x%x, /* Ndr library version */\n", get_stub_mode() == MODE_Oif ? 0x50002 : 0x10001);
+ print_proxy( "0,\n");
+- print_proxy( "0x50100a4, /* MIDL Version 5.1.164 */\n");
++ print_proxy( "0x50200ca, /* MIDL Version 5.2.202 */\n");
+ print_proxy( "0,\n");
+ print_proxy("%s,\n", list_empty(&user_type_list) ? "0" : "UserMarshalRoutines");
+ print_proxy( "0, /* notify & notify_flag routine table */\n");
+@@ -105,15 +105,15 @@ static void clear_output_vars( const var_list_t *args )
+ {
+ if (is_attr(arg->attrs, ATTR_IN)) continue;
+ if (!is_attr(arg->attrs, ATTR_OUT)) continue;
+- if (is_ptr(arg->type))
++ if (is_ptr(arg->declspec.type))
+ {
+- if (type_get_type(type_pointer_get_ref(arg->type)) == TYPE_BASIC) continue;
+- if (type_get_type(type_pointer_get_ref(arg->type)) == TYPE_ENUM) continue;
++ if (type_get_type(type_pointer_get_ref_type(arg->declspec.type)) == TYPE_BASIC) continue;
++ if (type_get_type(type_pointer_get_ref_type(arg->declspec.type)) == TYPE_ENUM) continue;
+ }
+ print_proxy( "if (%s) MIDL_memset( %s, 0, ", arg->name, arg->name );
+- if (is_array(arg->type) && type_array_has_conformance(arg->type))
++ if (is_array(arg->declspec.type) && type_array_has_conformance(arg->declspec.type))
+ {
+- write_expr( proxy, type_array_get_conformance(arg->type), 1, 1, NULL, NULL, "" );
++ write_expr( proxy, type_array_get_conformance(arg->declspec.type), 1, 1, NULL, NULL, "" );
+ fprintf( proxy, " * " );
+ }
+ fprintf( proxy, "sizeof( *%s ));\n", arg->name );
+@@ -147,7 +147,7 @@ static int need_delegation_indirect(const type_t *iface)
+ static void free_variable( const var_t *arg, const char *local_var_prefix )
+ {
+ unsigned int type_offset = arg->typestring_offset;
+- type_t *type = arg->type;
++ type_t *type = arg->declspec.type;
+
+ write_parameter_conf_or_var_exprs(proxy, indent, local_var_prefix, PHASE_FREE, arg, FALSE);
+
+@@ -191,18 +191,18 @@ static void proxy_free_variables( var_list_t *args, const char *local_var_prefix
+ static void gen_proxy(type_t *iface, const var_t *func, int idx,
+ unsigned int proc_offset)
+ {
+- var_t *retval = type_function_get_retval(func->type);
+- int has_ret = !is_void(retval->type);
++ var_t *retval = type_function_get_retval(func->declspec.type);
++ int has_ret = !is_void(retval->declspec.type);
+ int has_full_pointer = is_full_pointer_function(func);
+- const char *callconv = get_attrp(func->type->attrs, ATTR_CALLCONV);
+- const var_list_t *args = type_get_function_args(func->type);
++ const char *callconv = get_attrp(func->declspec.type->attrs, ATTR_CALLCONV);
++ const var_list_t *args = type_function_get_args(func->declspec.type);
+ if (!callconv) callconv = "STDMETHODCALLTYPE";
+
+ indent = 0;
+ if (is_interpreted_func( iface, func ))
+ {
+ if (get_stub_mode() == MODE_Oif && !is_callas( func->attrs )) return;
+- write_type_decl_left(proxy, retval->type);
++ write_declspec_decl_left(proxy, &retval->declspec);
+ print_proxy( " %s %s_%s_Proxy(\n", callconv, iface->name, get_name(func));
+ write_args(proxy, args, iface->name, 1, TRUE);
+ print_proxy( ")\n");
+@@ -219,7 +219,7 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx,
+ print_proxy( "}\n");
+ print_proxy( "\n");
+
+- write_type_decl_left(proxy, retval->type);
++ write_declspec_decl_left(proxy, &retval->declspec);
+ print_proxy( " %s %s_%s_Proxy(\n", callconv, iface->name, get_name(func));
+ write_args(proxy, args, iface->name, 1, TRUE);
+ print_proxy( ")\n");
+@@ -229,12 +229,12 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx,
+ /* local variables */
+ if (has_ret) {
+ print_proxy( "%s", "" );
+- write_type_decl(proxy, retval->type, retval->name);
++ write_declspec_decl(proxy, &retval->declspec, retval->name);
+ fprintf( proxy, ";\n" );
+ }
+ print_proxy( "RPC_MESSAGE _RpcMessage;\n" );
+ if (has_ret) {
+- if (decl_indirect(retval->type))
++ if (decl_indirect(retval->declspec.type))
+ print_proxy("void *_p_%s = &%s;\n", retval->name, retval->name);
+ }
+ print_proxy( "\n");
+@@ -246,7 +246,7 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx,
+ write_full_pointer_init(proxy, indent, func, FALSE);
+
+ /* FIXME: trace */
+- clear_output_vars( type_get_function_args(func->type) );
++ clear_output_vars( type_function_get_args(func->declspec.type) );
+
+ print_proxy( "RpcTryExcept\n" );
+ print_proxy( "{\n" );
+@@ -279,9 +279,9 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx,
+
+ if (has_ret)
+ {
+- if (decl_indirect(retval->type))
++ if (decl_indirect(retval->declspec.type))
+ print_proxy("MIDL_memset(&%s, 0, sizeof(%s));\n", retval->name, retval->name);
+- else if (is_ptr(retval->type) || is_array(retval->type))
++ else if (is_ptr(retval->declspec.type) || is_array(retval->declspec.type))
+ print_proxy("%s = 0;\n", retval->name);
+ write_remoting_arguments(proxy, indent, func, "", PASS_RETURN, PHASE_UNMARSHAL);
+ }
+@@ -301,7 +301,7 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx,
+ print_proxy( "{\n" );
+ if (has_ret) {
+ indent++;
+- proxy_free_variables( type_get_function_args(func->type), "" );
++ proxy_free_variables( type_function_get_args(func->declspec.type), "" );
+ print_proxy( "_RetVal = NdrProxyErrorHandler(RpcExceptionCode());\n" );
+ indent--;
+ }
+@@ -320,7 +320,7 @@ static void gen_stub(type_t *iface, const var_t *func, const char *cas,
+ unsigned int proc_offset)
+ {
+ const var_t *arg;
+- int has_ret = !is_void(type_function_get_rettype(func->type));
++ int has_ret = !is_void(type_function_get_rettype(func->declspec.type));
+ int has_full_pointer = is_full_pointer_function(func);
+
+ if (is_interpreted_func( iface, func )) return;
+@@ -389,10 +389,10 @@ static void gen_stub(type_t *iface, const var_t *func, const char *cas,
+ else fprintf(proxy, "__frame->_This->lpVtbl->%s", get_name(func));
+ fprintf(proxy, "(__frame->_This");
+
+- if (type_get_function_args(func->type))
++ if (type_function_get_args(func->declspec.type))
+ {
+- LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), const var_t, entry )
+- fprintf(proxy, ", %s__frame->%s", is_array(arg->type) && !type_array_is_decl_as_ptr(arg->type) ? "*" :"" , arg->name);
++ LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), const var_t, entry )
++ fprintf(proxy, ", %s__frame->%s", is_array(arg->declspec.type) && !type_array_is_decl_as_ptr(arg->declspec.type) ? "*" :"" , arg->name);
+ }
+ fprintf(proxy, ");\n");
+ fprintf(proxy, "\n");
+@@ -401,7 +401,7 @@ static void gen_stub(type_t *iface, const var_t *func, const char *cas,
+
+ write_remoting_arguments(proxy, indent, func, "__frame->", PASS_OUT, PHASE_BUFFERSIZE);
+
+- if (!is_void(type_function_get_rettype(func->type)))
++ if (!is_void(type_function_get_rettype(func->declspec.type)))
+ write_remoting_arguments(proxy, indent, func, "__frame->", PASS_RETURN, PHASE_BUFFERSIZE);
+
+ print_proxy("NdrStubGetBuffer(This, _pRpcChannelBuffer, &__frame->_StubMsg);\n");
+@@ -410,7 +410,7 @@ static void gen_stub(type_t *iface, const var_t *func, const char *cas,
+ fprintf(proxy, "\n");
+
+ /* marshall the return value */
+- if (!is_void(type_function_get_rettype(func->type)))
++ if (!is_void(type_function_get_rettype(func->declspec.type)))
+ write_remoting_arguments(proxy, indent, func, "__frame->", PASS_RETURN, PHASE_MARSHAL);
+
+ indent--;
+@@ -432,16 +432,16 @@ static void gen_stub(type_t *iface, const var_t *func, const char *cas,
+
+ static void gen_stub_thunk( type_t *iface, const var_t *func, unsigned int proc_offset )
+ {
+- int has_ret = !is_void( type_function_get_rettype( func->type ));
++ int has_ret = !is_void( type_function_get_rettype( func->declspec.type ));
+ const var_t *arg, *callas = is_callas( func->attrs );
+- const var_list_t *args = type_get_function_args( func->type );
++ const var_list_t *args = type_function_get_args( func->declspec.type );
+
+ indent = 0;
+ print_proxy( "void __RPC_API %s_%s_Thunk( PMIDL_STUB_MESSAGE pStubMsg )\n",
+ iface->name, get_name(func) );
+ print_proxy( "{\n");
+ indent++;
+- write_func_param_struct( proxy, iface, func->type,
++ write_func_param_struct( proxy, iface, func->declspec.type,
+ "*pParamStruct = (struct _PARAM_STRUCT *)pStubMsg->StackTop", has_ret );
+ print_proxy( "%s%s_%s_Stub( pParamStruct->This",
+ has_ret ? "pParamStruct->_RetVal = " : "", iface->name, callas->name );
+@@ -526,6 +526,7 @@ static int write_proxy_methods(type_t *iface, int skip)
+ if (skip || (is_local(func->attrs) && !get_callas_source(iface, func)))
+ print_proxy( "0, /* %s::%s */\n", iface->name, get_name(func));
+ else if (is_interpreted_func( iface, func ) &&
++ get_stub_mode() == MODE_Oif &&
+ !is_local( func->attrs ) &&
+ type_iface_get_inherit(iface))
+ print_proxy( "(void *)-1, /* %s::%s */\n", iface->name, get_name(func));
+@@ -613,14 +614,14 @@ static void write_proxy(type_t *iface, unsigned int *proc_offset)
+ if (!is_local(func->attrs)) {
+ const var_t *cas = is_callas(func->attrs);
+ const char *cname = cas ? cas->name : NULL;
+- int idx = func->type->details.function->idx;
++ int idx = type_get_details(func->declspec.type)->function->idx;
+ if (cname) {
+ const statement_t *stmt2;
+ STATEMENTS_FOR_EACH_FUNC(stmt2, type_iface_get_stmts(iface)) {
+ const var_t *m = stmt2->u.var;
+ if (!strcmp(m->name, cname))
+ {
+- idx = m->type->details.function->idx;
++ idx = type_get_details(m->declspec.type)->function->idx;
+ break;
+ }
+ }
+@@ -738,7 +739,7 @@ static void write_proxy(type_t *iface, unsigned int *proc_offset)
+ print_proxy( "{\n");
+ indent++;
+ print_proxy( "%s_%s\n",
+- iface->details.iface->async_iface == iface ? "CStdAsyncStubBuffer" : "CStdStubBuffer",
++ type_get_details(iface)->iface->async_iface == iface ? "CStdAsyncStubBuffer" : "CStdStubBuffer",
+ need_delegation_indirect(iface) ? "DELEGATING_METHODS" : "METHODS");
+ indent--;
+ print_proxy( "}\n");
+@@ -839,8 +840,8 @@ static void write_proxy_stmts(const statement_list_t *stmts, unsigned int *proc_
+ if (need_proxy(iface))
+ {
+ write_proxy(iface, proc_offset);
+- if (iface->details.iface->async_iface)
+- write_proxy(iface->details.iface->async_iface, proc_offset);
++ if (type_get_details(iface)->iface->async_iface)
++ write_proxy(type_get_details(iface)->iface->async_iface, proc_offset);
+ }
+ }
+ }
+@@ -869,9 +870,9 @@ static void build_iface_list( const statement_list_t *stmts, type_t **ifaces[],
+ {
+ *ifaces = xrealloc( *ifaces, (*count + 1) * sizeof(**ifaces) );
+ (*ifaces)[(*count)++] = iface;
+- if (iface->details.iface->async_iface)
++ if (type_get_details(iface)->iface->async_iface)
+ {
+- iface = iface->details.iface->async_iface;
++ iface = type_get_details(iface)->iface->async_iface;
+ *ifaces = xrealloc( *ifaces, (*count + 1) * sizeof(**ifaces) );
+ (*ifaces)[(*count)++] = iface;
+ }
+@@ -942,7 +943,7 @@ static void write_proxy_routines(const statement_list_t *stmts)
+ write_stubdesc(expr_eval_routines);
+
+ print_proxy( "#if !defined(__RPC_WIN%u__)\n", pointer_size == 8 ? 64 : 32);
+- print_proxy( "#error Currently only Wine and WIN32 are supported.\n");
++ print_proxy( "#error Invalid build platform for this proxy.\n");
+ print_proxy( "#endif\n");
+ print_proxy( "\n");
+ write_procformatstring(proxy, stmts, need_proxy);
+@@ -1011,7 +1012,7 @@ static void write_proxy_routines(const statement_list_t *stmts)
+ table_version = get_stub_mode() == MODE_Oif ? 2 : 1;
+ for (i = 0; i < count; i++)
+ {
+- if (interfaces[i]->details.iface->async_iface != interfaces[i]) continue;
++ if (type_get_details(interfaces[i])->iface->async_iface != interfaces[i]) continue;
+ if (table_version != 6)
+ {
+ fprintf(proxy, "static const IID *_AsyncInterfaceTable[] =\n");
+@@ -1053,26 +1054,6 @@ void write_proxies(const statement_list_t *stmts)
+ init_proxy(stmts);
+ if(!proxy) return;
+
+- if (do_win32 && do_win64)
+- {
+- fprintf(proxy, "\n#ifndef _WIN64\n\n");
+- pointer_size = 4;
+- write_proxy_routines( stmts );
+- fprintf(proxy, "\n#else /* _WIN64 */\n\n");
+- pointer_size = 8;
+- write_proxy_routines( stmts );
+- fprintf(proxy, "\n#endif /* _WIN64 */\n");
+- }
+- else if (do_win32)
+- {
+- pointer_size = 4;
+- write_proxy_routines( stmts );
+- }
+- else if (do_win64)
+- {
+- pointer_size = 8;
+- write_proxy_routines( stmts );
+- }
+-
++ write_proxy_routines( stmts );
+ fclose(proxy);
+ }
+diff --git a/mingw-w64-tools/widl/src/register.c b/mingw-w64-tools/widl/src/register.c
+index 210fb747..1c369e7c 100644
+--- a/mingw-w64-tools/widl/src/register.c
++++ b/mingw-w64-tools/widl/src/register.c
+@@ -325,7 +325,7 @@ void output_typelib_regscript( const typelib_t *typelib )
+ sprintf(resname, "%s\\%d", typelib_name, expr->cval);
+ }
+ put_str( indent, "'%x' { %s = s '%%MODULE%%%s' }\n",
+- lcid_expr ? lcid_expr->cval : 0, typelib_kind == SYS_WIN64 ? "win64" : "win32", id_part );
++ lcid_expr ? lcid_expr->cval : 0, pointer_size == 8 ? "win64" : "win32", id_part );
+ put_str( indent, "FLAGS = s '%u'\n", flags );
+ put_str( --indent, "}\n" );
+ put_str( --indent, "}\n" );
+diff --git a/mingw-w64-tools/widl/src/server.c b/mingw-w64-tools/widl/src/server.c
+index 783ff900..dbed870a 100644
+--- a/mingw-w64-tools/widl/src/server.c
++++ b/mingw-w64-tools/widl/src/server.c
+@@ -55,6 +55,8 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
+ unsigned char explicit_fc, implicit_fc;
+ int has_full_pointer = is_full_pointer_function(func);
+ const var_t *handle_var = get_func_handle_var( iface, func, &explicit_fc, &implicit_fc );
++ const decl_spec_t *ret_declspec = type_function_get_retdeclspec(func->declspec.type);
++ type_t *ret_type = ret_declspec->type;
+
+ if (is_interpreted_func( iface, func )) return;
+
+@@ -75,7 +77,7 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
+ indent++;
+ write_remoting_arguments(server, indent, func, "__frame->", PASS_OUT, PHASE_FREE);
+
+- if (!is_void(type_function_get_rettype(func->type)))
++ if (!is_void(ret_type))
+ write_remoting_arguments(server, indent, func, "__frame->", PASS_RETURN, PHASE_FREE);
+
+ if (has_full_pointer)
+@@ -120,7 +122,7 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
+ if (has_full_pointer)
+ write_full_pointer_init(server, indent, func, TRUE);
+
+- if (type_get_function_args(func->type))
++ if (type_function_get_args(func->declspec.type))
+ {
+ print_server("if ((_pRpcMessage->DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)\n");
+ indent++;
+@@ -154,35 +156,42 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
+ assign_stub_out_args(server, indent, func, "__frame->");
+
+ /* Call the real server function */
+- print_server("%s%s%s",
+- is_void(type_function_get_rettype(func->type)) ? "" : "__frame->_RetVal = ",
+- prefix_server, get_name(func));
++ if (is_context_handle(ret_type))
++ {
++ print_server("__frame->_RetVal = NDRSContextUnmarshall((char*)0, _pRpcMessage->DataRepresentation);\n");
++ print_server("*((");
++ write_declspec_decl(server, ret_declspec, NULL);
++ fprintf(server, "*)NDRSContextValue(__frame->_RetVal)) = ");
++ }
++ else
++ print_server("%s", is_void(ret_type) ? "" : "__frame->_RetVal = ");
++ fprintf(server, "%s%s", prefix_server, get_name(func));
+
+- if (type_get_function_args(func->type))
++ if (type_function_get_args(func->declspec.type))
+ {
+ int first_arg = 1;
+
+ fprintf(server, "(\n");
+ indent++;
+- LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
++ LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), const var_t, entry )
+ {
+ if (first_arg)
+ first_arg = 0;
+ else
+ fprintf(server, ",\n");
+- if (is_context_handle(var->type))
++ if (is_context_handle(var->declspec.type))
+ {
+ /* if the context_handle attribute appears in the chain of types
+ * without pointers being followed, then the context handle must
+ * be direct, otherwise it is a pointer */
+- const char *ch_ptr = is_aliaschain_attr(var->type, ATTR_CONTEXTHANDLE) ? "*" : "";
++ const char *ch_ptr = is_aliaschain_attr(var->declspec.type, ATTR_CONTEXTHANDLE) ? "*" : "";
+ print_server("(");
+- write_type_decl_left(server, var->type);
++ write_declspec_decl_left(server, &var->declspec);
+ fprintf(server, ")%sNDRSContextValue(__frame->%s)", ch_ptr, var->name);
+ }
+ else
+ {
+- print_server("%s__frame->%s", is_array(var->type) && !type_array_is_decl_as_ptr(var->type) ? "*" : "", var->name);
++ print_server("%s__frame->%s", is_array(var->declspec.type) && !type_array_is_decl_as_ptr(var->declspec.type) ? "*" : "", var->name);
+ }
+ }
+ fprintf(server, ");\n");
+@@ -197,7 +206,7 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
+ {
+ write_remoting_arguments(server, indent, func, "__frame->", PASS_OUT, PHASE_BUFFERSIZE);
+
+- if (!is_void(type_function_get_rettype(func->type)))
++ if (!is_void(ret_type))
+ write_remoting_arguments(server, indent, func, "__frame->", PASS_RETURN, PHASE_BUFFERSIZE);
+
+ print_server("_pRpcMessage->BufferLength = __frame->_StubMsg.BufferLength;\n");
+@@ -216,7 +225,7 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
+ write_remoting_arguments(server, indent, func, "__frame->", PASS_OUT, PHASE_MARSHAL);
+
+ /* marshall the return value */
+- if (!is_void(type_function_get_rettype(func->type)))
++ if (!is_void(ret_type))
+ write_remoting_arguments(server, indent, func, "__frame->", PASS_RETURN, PHASE_MARSHAL);
+
+ indent--;
+@@ -378,7 +387,7 @@ static void write_stubdescriptor(type_t *iface, int expr_eval_routines)
+ print_server("1, /* -error bounds_check flag */\n");
+ print_server("0x%x, /* Ndr library version */\n", get_stub_mode() == MODE_Oif ? 0x50002 : 0x10001);
+ print_server("0,\n");
+- print_server("0x50100a4, /* MIDL Version 5.1.164 */\n");
++ print_server("0x50200ca, /* MIDL Version 5.2.202 */\n");
+ print_server("0,\n");
+ print_server("%s,\n", list_empty(&user_type_list) ? "0" : "UserMarshalRoutines");
+ print_server("0, /* notify & notify_flag routine table */\n");
+@@ -544,26 +553,6 @@ void write_server(const statement_list_t *stmts)
+ if (!server)
+ return;
+
+- if (do_win32 && do_win64)
+- {
+- fprintf(server, "#ifndef _WIN64\n\n");
+- pointer_size = 4;
+- write_server_routines( stmts );
+- fprintf(server, "\n#else /* _WIN64 */\n\n");
+- pointer_size = 8;
+- write_server_routines( stmts );
+- fprintf(server, "\n#endif /* _WIN64 */\n");
+- }
+- else if (do_win32)
+- {
+- pointer_size = 4;
+- write_server_routines( stmts );
+- }
+- else if (do_win64)
+- {
+- pointer_size = 8;
+- write_server_routines( stmts );
+- }
+-
++ write_server_routines( stmts );
+ fclose(server);
+ }
+diff --git a/mingw-w64-tools/widl/src/typegen.c b/mingw-w64-tools/widl/src/typegen.c
+index 27ba60fc..eebb99f0 100644
+--- a/mingw-w64-tools/widl/src/typegen.c
++++ b/mingw-w64-tools/widl/src/typegen.c
+@@ -67,6 +67,7 @@ enum type_context
+ TYPE_CONTEXT_PARAM,
+ TYPE_CONTEXT_CONTAINER,
+ TYPE_CONTEXT_CONTAINER_NO_POINTERS,
++ TYPE_CONTEXT_RETVAL,
+ };
+
+ /* parameter flags in Oif mode */
+@@ -84,14 +85,14 @@ static const unsigned short IsSimpleRef = 0x0100;
+
+ static unsigned int field_memsize(const type_t *type, unsigned int *offset);
+ static unsigned int fields_memsize(const var_list_t *fields, unsigned int *align);
+-static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type,
++static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
+ const char *name, unsigned int *typestring_offset);
+-static unsigned int write_struct_tfs(FILE *file, type_t *type, const char *name, unsigned int *tfsoff);
+-static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *type,
++static unsigned int write_struct_tfs(FILE *file, const decl_spec_t *declspec, const char *name, unsigned int *tfsoff);
++static int write_embedded_types(FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
+ const char *name, int write_ptr, unsigned int *tfsoff);
+ static const var_t *find_array_or_string_in_struct(const type_t *type);
+ static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs,
+- type_t *type, enum type_context context,
++ const decl_spec_t *declspec, enum type_context context,
+ const char *name, unsigned int *typestring_offset);
+ static unsigned int get_required_buffer_size_type( const type_t *type, const char *name,
+ const attr_list_t *attrs, int toplevel_param,
+@@ -196,7 +197,7 @@ static void *get_aliaschain_attrp(const type_t *type, enum attr_type attr)
+ if (is_attr(t->attrs, attr))
+ return get_attrp(t->attrs, attr);
+ else if (type_is_alias(t))
+- t = type_alias_get_aliasee(t);
++ t = type_alias_get_aliasee_type(t);
+ else return NULL;
+ }
+ }
+@@ -266,7 +267,7 @@ unsigned char get_pointer_fc(const type_t *type, const attr_list_t *attrs, int t
+ if (pointer_type)
+ return pointer_type;
+
+- for (t = type; type_is_alias(t); t = type_alias_get_aliasee(t))
++ for (t = type; type_is_alias(t); t = type_alias_get_aliasee_type(t))
+ {
+ pointer_type = get_attrv(t->attrs, ATTR_POINTERTYPE);
+ if (pointer_type)
+@@ -287,7 +288,7 @@ static unsigned char get_pointer_fc_context( const type_t *type, const attr_list
+ int pointer_fc = get_pointer_fc(type, attrs, context == TYPE_CONTEXT_TOPLEVELPARAM);
+
+ if (pointer_fc == FC_UP && is_attr( attrs, ATTR_OUT ) &&
+- context == TYPE_CONTEXT_PARAM && is_object( current_iface ))
++ (context == TYPE_CONTEXT_PARAM || context == TYPE_CONTEXT_RETVAL) && is_object( current_iface ))
+ pointer_fc = FC_OP;
+
+ return pointer_fc;
+@@ -315,7 +316,7 @@ static type_t *get_user_type(const type_t *t, const char **pname)
+ }
+
+ if (type_is_alias(t))
+- t = type_alias_get_aliasee(t);
++ t = type_alias_get_aliasee_type(t);
+ else
+ return NULL;
+ }
+@@ -350,10 +351,10 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att
+ return TGT_RANGE;
+ return TGT_ENUM;
+ case TYPE_POINTER:
+- if (type_get_type(type_pointer_get_ref(type)) == TYPE_INTERFACE ||
+- (type_get_type(type_pointer_get_ref(type)) == TYPE_VOID && is_attr(attrs, ATTR_IIDIS)))
++ if (type_get_type(type_pointer_get_ref_type(type)) == TYPE_INTERFACE ||
++ (type_get_type(type_pointer_get_ref_type(type)) == TYPE_VOID && is_attr(attrs, ATTR_IIDIS)))
+ return TGT_IFACE_POINTER;
+- else if (is_aliaschain_attr(type_pointer_get_ref(type), ATTR_CONTEXTHANDLE))
++ else if (is_aliaschain_attr(type_pointer_get_ref_type(type), ATTR_CONTEXTHANDLE))
+ return TGT_CTXT_HANDLE_POINTER;
+ else
+ return TGT_POINTER;
+@@ -378,13 +379,13 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att
+
+ static int cant_be_null(const var_t *v)
+ {
+- switch (typegen_detect_type(v->type, v->attrs, TDT_IGNORE_STRINGS))
++ switch (typegen_detect_type(v->declspec.type, v->attrs, TDT_IGNORE_STRINGS))
+ {
+ case TGT_ARRAY:
+- if (!type_array_is_decl_as_ptr( v->type )) return 0;
++ if (!type_array_is_decl_as_ptr( v->declspec.type )) return 0;
+ /* fall through */
+ case TGT_POINTER:
+- return (get_pointer_fc(v->type, v->attrs, TRUE) == FC_RP);
++ return (get_pointer_fc(v->declspec.type, v->attrs, TRUE) == FC_RP);
+ case TGT_CTXT_HANDLE_POINTER:
+ return TRUE;
+ default:
+@@ -404,7 +405,7 @@ static int get_padding(const var_list_t *fields)
+
+ LIST_FOR_EACH_ENTRY(f, fields, const var_t, entry)
+ {
+- type_t *ft = f->type;
++ type_t *ft = f->declspec.type;
+ unsigned int align = 0;
+ unsigned int size = type_memsize_and_alignment(ft, &align);
+ align = clamp_align(align);
+@@ -421,7 +422,7 @@ static unsigned int get_stack_size( const var_t *var, int *by_value )
+ unsigned int stack_size;
+ int by_val;
+
+- switch (typegen_detect_type( var->type, var->attrs, TDT_ALL_TYPES ))
++ switch (typegen_detect_type( var->declspec.type, var->attrs, TDT_ALL_TYPES ))
+ {
+ case TGT_BASIC:
+ case TGT_ENUM:
+@@ -429,7 +430,7 @@ static unsigned int get_stack_size( const var_t *var, int *by_value )
+ case TGT_STRUCT:
+ case TGT_UNION:
+ case TGT_USER_TYPE:
+- stack_size = type_memsize( var->type );
++ stack_size = type_memsize( var->declspec.type );
+ by_val = (pointer_size < 8 || stack_size <= pointer_size); /* FIXME: should be platform-specific */
+ break;
+ default:
+@@ -442,23 +443,27 @@ static unsigned int get_stack_size( const var_t *var, int *by_value )
+ }
+
+ static unsigned char get_contexthandle_flags( const type_t *iface, const attr_list_t *attrs,
+- const type_t *type )
++ const type_t *type, int is_return )
+ {
+ unsigned char flags = 0;
++ int is_out;
+
+ if (is_attr(iface->attrs, ATTR_STRICTCONTEXTHANDLE)) flags |= NDR_STRICT_CONTEXT_HANDLE;
+
+ if (is_ptr(type) &&
+ !is_attr( type->attrs, ATTR_CONTEXTHANDLE ) &&
+ !is_attr( attrs, ATTR_CONTEXTHANDLE ))
+- flags |= 0x80;
++ flags |= HANDLE_PARAM_IS_VIA_PTR;
+
+- if (is_attr(attrs, ATTR_IN))
++ if (is_return) return flags | HANDLE_PARAM_IS_OUT | HANDLE_PARAM_IS_RETURN;
++
++ is_out = is_attr(attrs, ATTR_OUT);
++ if (is_attr(attrs, ATTR_IN) || !is_out)
+ {
+- flags |= 0x40;
+- if (!is_attr(attrs, ATTR_OUT)) flags |= NDR_CONTEXT_HANDLE_CANNOT_BE_NULL;
++ flags |= HANDLE_PARAM_IS_IN;
++ if (!is_out) flags |= NDR_CONTEXT_HANDLE_CANNOT_BE_NULL;
+ }
+- if (is_attr(attrs, ATTR_OUT)) flags |= 0x20;
++ if (is_out) flags |= HANDLE_PARAM_IS_OUT;
+
+ return flags;
+ }
+@@ -490,14 +495,14 @@ unsigned char get_struct_fc(const type_t *type)
+
+ if (fields) LIST_FOR_EACH_ENTRY( field, fields, var_t, entry )
+ {
+- type_t *t = field->type;
++ type_t *t = field->declspec.type;
+ enum typegen_type typegen_type;
+
+ typegen_type = typegen_detect_type(t, field->attrs, TDT_IGNORE_STRINGS);
+
+ if (typegen_type == TGT_ARRAY && !type_array_is_decl_as_ptr(t))
+ {
+- if (is_string_type(field->attrs, field->type))
++ if (is_string_type(field->attrs, field->declspec.type))
+ {
+ if (is_conformant_array(t))
+ has_conformance = 1;
+@@ -505,10 +510,10 @@ unsigned char get_struct_fc(const type_t *type)
+ continue;
+ }
+
+- if (is_array(type_array_get_element(field->type)))
++ if (is_array(type_array_get_element_type(field->declspec.type)))
+ return FC_BOGUS_STRUCT;
+
+- if (type_array_has_conformance(field->type))
++ if (type_array_has_conformance(field->declspec.type))
+ {
+ has_conformance = 1;
+ if (list_next(fields, &field->entry))
+@@ -518,7 +523,7 @@ unsigned char get_struct_fc(const type_t *type)
+ if (type_array_has_variance(t))
+ has_variance = 1;
+
+- t = type_array_get_element(t);
++ t = type_array_get_element_type(t);
+ typegen_type = typegen_detect_type(t, field->attrs, TDT_IGNORE_STRINGS);
+ }
+
+@@ -620,7 +625,7 @@ static unsigned char get_array_fc(const type_t *type)
+ const expr_t *size_is;
+ const type_t *elem_type;
+
+- elem_type = type_array_get_element(type);
++ elem_type = type_array_get_element_type(type);
+ size_is = type_array_get_conformance(type);
+
+ if (!size_is)
+@@ -709,14 +714,14 @@ static int type_has_pointers(const type_t *type)
+ case TGT_POINTER:
+ return TRUE;
+ case TGT_ARRAY:
+- return type_array_is_decl_as_ptr(type) || type_has_pointers(type_array_get_element(type));
++ return type_array_is_decl_as_ptr(type) || type_has_pointers(type_array_get_element_type(type));
+ case TGT_STRUCT:
+ {
+ var_list_t *fields = type_struct_get_fields(type);
+ const var_t *field;
+ if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
+ {
+- if (type_has_pointers(field->type))
++ if (type_has_pointers(field->declspec.type))
+ return TRUE;
+ }
+ break;
+@@ -728,7 +733,7 @@ static int type_has_pointers(const type_t *type)
+ fields = type_union_get_cases(type);
+ if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
+ {
+- if (field->type && type_has_pointers(field->type))
++ if (field->declspec.type && type_has_pointers(field->declspec.type))
+ return TRUE;
+ }
+ break;
+@@ -763,14 +768,14 @@ static int type_has_full_pointer(const type_t *type, const attr_list_t *attrs,
+ if (get_pointer_fc(type, attrs, toplevel_param) == FC_FP)
+ return TRUE;
+ else
+- return type_has_full_pointer(type_array_get_element(type), NULL, FALSE);
++ return type_has_full_pointer(type_array_get_element_type(type), NULL, FALSE);
+ case TGT_STRUCT:
+ {
+ var_list_t *fields = type_struct_get_fields(type);
+ const var_t *field;
+ if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
+ {
+- if (type_has_full_pointer(field->type, field->attrs, FALSE))
++ if (type_has_full_pointer(field->declspec.type, field->attrs, FALSE))
+ return TRUE;
+ }
+ break;
+@@ -782,7 +787,7 @@ static int type_has_full_pointer(const type_t *type, const attr_list_t *attrs,
+ fields = type_union_get_cases(type);
+ if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
+ {
+- if (field->type && type_has_full_pointer(field->type, field->attrs, FALSE))
++ if (field->declspec.type && type_has_full_pointer(field->declspec.type, field->attrs, FALSE))
+ return TRUE;
+ }
+ break;
+@@ -852,7 +857,7 @@ static const char *get_context_handle_type_name(const type_t *type)
+ const type_t *t;
+ for (t = type;
+ is_ptr(t) || type_is_alias(t);
+- t = type_is_alias(t) ? type_alias_get_aliasee(t) : type_pointer_get_ref(t))
++ t = type_is_alias(t) ? type_alias_get_aliasee_type(t) : type_pointer_get_ref_type(t))
+ if (is_attr(t->attrs, ATTR_CONTEXTHANDLE))
+ return t->name;
+ assert(0);
+@@ -902,16 +907,16 @@ static void write_var_init(FILE *file, int indent, const type_t *t, const char *
+
+ void write_parameters_init(FILE *file, int indent, const var_t *func, const char *local_var_prefix)
+ {
+- const var_t *var = type_function_get_retval(func->type);
++ const var_t *var = type_function_get_retval(func->declspec.type);
+
+- if (!is_void(var->type))
+- write_var_init(file, indent, var->type, var->name, local_var_prefix);
++ if (!is_void(var->declspec.type))
++ write_var_init(file, indent, var->declspec.type, var->name, local_var_prefix);
+
+- if (!type_get_function_args(func->type))
++ if (!type_function_get_args(func->declspec.type))
+ return;
+
+- LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
+- write_var_init(file, indent, var->type, var->name, local_var_prefix);
++ LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), const var_t, entry )
++ write_var_init(file, indent, var->declspec.type, var->name, local_var_prefix);
+
+ fprintf(file, "\n");
+ }
+@@ -975,14 +980,14 @@ static unsigned char get_parameter_fc( const var_t *var, int is_return, unsigned
+ if (is_out) *flags |= IsOut;
+ if (is_return) *flags |= IsReturn;
+
+- if (!is_string_type( var->attrs, var->type ))
+- buffer_size = get_required_buffer_size_type( var->type, NULL, var->attrs, TRUE, &alignment );
++ if (!is_string_type( var->attrs, var->declspec.type ))
++ buffer_size = get_required_buffer_size_type( var->declspec.type, NULL, var->attrs, TRUE, &alignment );
+
+- switch (typegen_detect_type( var->type, var->attrs, TDT_ALL_TYPES ))
++ switch (typegen_detect_type( var->declspec.type, var->attrs, TDT_ALL_TYPES ))
+ {
+ case TGT_BASIC:
+ *flags |= IsBasetype;
+- fc = get_basic_fc_signed( var->type );
++ fc = get_basic_fc_signed( var->declspec.type );
+ if (fc == FC_BIND_PRIMITIVE)
+ {
+ buffer_size = 4; /* actually 0 but avoids setting MustSize */
+@@ -991,7 +996,7 @@ static unsigned char get_parameter_fc( const var_t *var, int is_return, unsigned
+ break;
+ case TGT_ENUM:
+ *flags |= IsBasetype;
+- fc = get_enum_fc( var->type );
++ fc = get_enum_fc( var->declspec.type );
+ break;
+ case TGT_RANGE:
+ *flags |= IsByValue;
+@@ -1006,19 +1011,19 @@ static unsigned char get_parameter_fc( const var_t *var, int is_return, unsigned
+ break;
+ case TGT_ARRAY:
+ *flags |= MustFree;
+- if (type_array_is_decl_as_ptr(var->type) && var->type->details.array.ptr_tfsoff &&
+- get_pointer_fc( var->type, var->attrs, !is_return ) == FC_RP)
++ if (type_array_is_decl_as_ptr(var->declspec.type) && type_get_details(var->declspec.type)->array.ptr_tfsoff &&
++ get_pointer_fc( var->declspec.type, var->attrs, !is_return ) == FC_RP)
+ {
+- *typestring_offset = var->type->typestring_offset;
++ *typestring_offset = var->declspec.type->typestring_offset;
+ *flags |= IsSimpleRef;
+ }
+ break;
+ case TGT_STRING:
+ *flags |= MustFree;
+- if (is_declptr( var->type ) && get_pointer_fc( var->type, var->attrs, !is_return ) == FC_RP)
++ if (is_declptr( var->declspec.type ) && get_pointer_fc( var->declspec.type, var->attrs, !is_return ) == FC_RP)
+ {
+ /* skip over pointer description straight to string description */
+- if (is_conformant_array( var->type )) *typestring_offset += 4;
++ if (is_conformant_array( var->declspec.type )) *typestring_offset += 4;
+ else *typestring_offset += 2;
+ *flags |= IsSimpleRef;
+ }
+@@ -1031,9 +1036,9 @@ static unsigned char get_parameter_fc( const var_t *var, int is_return, unsigned
+ buffer_size = 20;
+ break;
+ case TGT_POINTER:
+- if (get_pointer_fc( var->type, var->attrs, !is_return ) == FC_RP)
++ if (get_pointer_fc( var->declspec.type, var->attrs, !is_return ) == FC_RP)
+ {
+- const type_t *ref = type_pointer_get_ref( var->type );
++ const type_t *ref = type_pointer_get_ref_type( var->declspec.type );
+
+ if (!is_string_type( var->attrs, ref ))
+ buffer_size = get_required_buffer_size_type( ref, NULL, NULL, TRUE, &alignment );
+@@ -1059,11 +1064,19 @@ static unsigned char get_parameter_fc( const var_t *var, int is_return, unsigned
+ case TGT_UNION:
+ case TGT_USER_TYPE:
+ case TGT_RANGE:
+- case TGT_ARRAY:
+- *flags |= IsSimpleRef | MustFree;
++ *flags |= MustFree | IsSimpleRef;
+ *typestring_offset = ref->typestring_offset;
+ if (!is_in && is_out) server_size = type_memsize( ref );
+ break;
++ case TGT_ARRAY:
++ *flags |= MustFree;
++ if (!type_array_is_decl_as_ptr(ref))
++ {
++ *flags |= IsSimpleRef;
++ *typestring_offset = ref->typestring_offset;
++ }
++ if (!is_in && is_out) server_size = type_memsize( ref );
++ break;
+ case TGT_STRING:
+ case TGT_POINTER:
+ case TGT_CTXT_HANDLE:
+@@ -1115,8 +1128,8 @@ static unsigned char get_parameter_fc( const var_t *var, int is_return, unsigned
+ static unsigned char get_func_oi2_flags( const var_t *func )
+ {
+ const var_t *var;
+- var_list_t *args = type_get_function_args( func->type );
+- var_t *retval = type_function_get_retval( func->type );
++ var_list_t *args = type_function_get_args( func->declspec.type );
++ var_t *retval = type_function_get_retval( func->declspec.type );
+ unsigned char oi2_flags = 0x40; /* HasExtensions */
+ unsigned short flags;
+ unsigned int stack_size, typestring_offset;
+@@ -1131,7 +1144,7 @@ static unsigned char get_func_oi2_flags( const var_t *func )
+ }
+ }
+
+- if (!is_void( retval->type ))
++ if (!is_void( retval->declspec.type ))
+ {
+ oi2_flags |= 0x04; /* HasRet */
+ get_parameter_fc( retval, 1, &flags, &stack_size, &typestring_offset );
+@@ -1185,8 +1198,8 @@ static unsigned int write_old_procformatstring_type(FILE *file, int indent, cons
+
+ if (!is_in && !is_out) is_in = TRUE;
+
+- if (type_get_type(var->type) == TYPE_BASIC ||
+- type_get_type(var->type) == TYPE_ENUM)
++ if (type_get_type(var->declspec.type) == TYPE_BASIC ||
++ type_get_type(var->declspec.type) == TYPE_ENUM)
+ {
+ unsigned char fc;
+
+@@ -1195,13 +1208,13 @@ static unsigned int write_old_procformatstring_type(FILE *file, int indent, cons
+ else
+ print_file(file, indent, "0x4e, /* FC_IN_PARAM_BASETYPE */\n");
+
+- if (type_get_type(var->type) == TYPE_ENUM)
++ if (type_get_type(var->declspec.type) == TYPE_ENUM)
+ {
+- fc = get_enum_fc(var->type);
++ fc = get_enum_fc(var->declspec.type);
+ }
+ else
+ {
+- fc = get_basic_fc_signed(var->type);
++ fc = get_basic_fc_signed(var->declspec.type);
+
+ if (fc == FC_BIND_PRIMITIVE)
+ fc = FC_IGNORE;
+@@ -1215,10 +1228,12 @@ static unsigned int write_old_procformatstring_type(FILE *file, int indent, cons
+ {
+ unsigned short offset = var->typestring_offset;
+
+- if (!is_interpreted && is_array(var->type) &&
+- type_array_is_decl_as_ptr(var->type) &&
+- var->type->details.array.ptr_tfsoff)
+- offset = var->type->typestring_offset;
++ if (!is_interpreted && is_array(var->declspec.type) &&
++ type_array_is_decl_as_ptr(var->declspec.type) &&
++ type_get_details(var->declspec.type)->array.ptr_tfsoff)
++ {
++ offset = var->declspec.type->typestring_offset;
++ }
+
+ if (is_return)
+ print_file(file, indent, "0x52, /* FC_RETURN_PARAM */\n");
+@@ -1241,8 +1256,8 @@ int is_interpreted_func( const type_t *iface, const var_t *func )
+ {
+ const char *str;
+ const var_t *var;
+- const var_list_t *args = type_get_function_args( func->type );
+- const type_t *ret_type = type_function_get_rettype( func->type );
++ const var_list_t *args = type_function_get_args( func->declspec.type );
++ const type_t *ret_type = type_function_get_rettype( func->declspec.type );
+
+ if (type_get_type( ret_type ) == TYPE_BASIC)
+ {
+@@ -1264,10 +1279,10 @@ int is_interpreted_func( const type_t *iface, const var_t *func )
+ if (get_stub_mode() != MODE_Oif && args)
+ {
+ LIST_FOR_EACH_ENTRY( var, args, const var_t, entry )
+- switch (type_get_type( var->type ))
++ switch (type_get_type( var->declspec.type ))
+ {
+ case TYPE_BASIC:
+- switch (type_basic_get_type( var->type ))
++ switch (type_basic_get_type( var->declspec.type ))
+ {
+ /* floating point arguments are not supported in Oi mode */
+ case TYPE_BASIC_FLOAT: return 0;
+@@ -1292,7 +1307,7 @@ static void write_proc_func_header( FILE *file, int indent, const type_t *iface,
+ unsigned short num_proc )
+ {
+ var_t *var;
+- var_list_t *args = type_get_function_args( func->type );
++ var_list_t *args = type_function_get_args( func->declspec.type );
+ unsigned char explicit_fc, implicit_fc;
+ unsigned char handle_flags;
+ const var_t *handle_var = get_func_handle_var( iface, func, &explicit_fc, &implicit_fc );
+@@ -1323,7 +1338,7 @@ static void write_proc_func_header( FILE *file, int indent, const type_t *iface,
+ param_num++;
+ nb_args++;
+ }
+- if (!is_void( type_function_get_rettype( func->type )))
++ if (!is_void( type_function_get_rettype( func->declspec.type )))
+ {
+ stack_size += pointer_size;
+ nb_args++;
+@@ -1351,22 +1366,22 @@ static void write_proc_func_header( FILE *file, int indent, const type_t *iface,
+ *offset += 4;
+ break;
+ case FC_BIND_GENERIC:
+- handle_flags = type_memsize( handle_var->type );
++ handle_flags = type_memsize( handle_var->declspec.type );
+ print_file( file, indent, "0x%02x,\t/* %s */\n", explicit_fc, string_of_type(explicit_fc) );
+ print_file( file, indent, "0x%02x,\n", handle_flags );
+ print_file( file, indent, "NdrFcShort(0x%hx),\t/* stack offset = %hu */\n",
+ handle_stack_offset, handle_stack_offset );
+- print_file( file, indent, "0x%02x,\n", get_generic_handle_offset( handle_var->type ) );
++ print_file( file, indent, "0x%02x,\n", get_generic_handle_offset( handle_var->declspec.type ) );
+ print_file( file, indent, "0x%x,\t/* FC_PAD */\n", FC_PAD);
+ *offset += 6;
+ break;
+ case FC_BIND_CONTEXT:
+- handle_flags = get_contexthandle_flags( iface, handle_var->attrs, handle_var->type );
++ handle_flags = get_contexthandle_flags( iface, handle_var->attrs, handle_var->declspec.type, 0 );
+ print_file( file, indent, "0x%02x,\t/* %s */\n", explicit_fc, string_of_type(explicit_fc) );
+ print_file( file, indent, "0x%02x,\n", handle_flags );
+ print_file( file, indent, "NdrFcShort(0x%hx),\t/* stack offset = %hu */\n",
+ handle_stack_offset, handle_stack_offset );
+- print_file( file, indent, "0x%02x,\n", get_context_handle_offset( handle_var->type ) );
++ print_file( file, indent, "0x%02x,\n", get_context_handle_offset( handle_var->declspec.type ) );
+ print_file( file, indent, "0x%02x,\t/* param %hu */\n", handle_param_num, handle_param_num );
+ *offset += 6;
+ break;
+@@ -1381,7 +1396,7 @@ static void write_proc_func_header( FILE *file, int indent, const type_t *iface,
+
+ if (is_attr( func->attrs, ATTR_NOTIFY )) ext_flags |= 0x08; /* HasNotify */
+ if (is_attr( func->attrs, ATTR_NOTIFYFLAG )) ext_flags |= 0x10; /* HasNotify2 */
+- if (iface == iface->details.iface->async_iface) oi2_flags |= 0x20;
++ if (iface == type_get_const_details(iface)->iface->async_iface) oi2_flags |= 0x20;
+
+ size = get_function_buffer_size( func, PASS_IN );
+ print_file( file, indent, "NdrFcShort(0x%x),\t/* client buffer = %u */\n", size, size );
+@@ -1402,9 +1417,9 @@ static void write_proc_func_header( FILE *file, int indent, const type_t *iface,
+ if (is_object( iface )) pos += 2;
+ if (args) LIST_FOR_EACH_ENTRY( var, args, var_t, entry )
+ {
+- if (type_get_type( var->type ) == TYPE_BASIC)
++ if (type_get_type( var->declspec.type ) == TYPE_BASIC)
+ {
+- switch (type_basic_get_type( var->type ))
++ switch (type_basic_get_type( var->declspec.type ))
+ {
+ case TYPE_BASIC_FLOAT: fpu_mask |= 1 << pos; break;
+ case TYPE_BASIC_DOUBLE: fpu_mask |= 2 << pos; break;
+@@ -1427,15 +1442,15 @@ static void write_procformatstring_func( FILE *file, int indent, const type_t *i
+ unsigned int stack_offset = is_object( iface ) ? pointer_size : 0;
+ int is_interpreted = is_interpreted_func( iface, func );
+ int is_new_style = is_interpreted && (get_stub_mode() == MODE_Oif);
+- var_t *retval = type_function_get_retval( func->type );
++ var_t *retval = type_function_get_retval( func->declspec.type );
+
+ if (is_interpreted) write_proc_func_header( file, indent, iface, func, offset, num_proc );
+
+ /* emit argument data */
+- if (type_get_function_args(func->type))
++ if (type_function_get_args(func->declspec.type))
+ {
+ const var_t *var;
+- LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
++ LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), const var_t, entry )
+ {
+ print_file( file, 0, "/* %u (parameter %s) */\n", *offset, var->name );
+ if (is_new_style)
+@@ -1446,7 +1461,7 @@ static void write_procformatstring_func( FILE *file, int indent, const type_t *i
+ }
+
+ /* emit return value data */
+- if (is_void(retval->type))
++ if (is_void(retval->declspec.type))
+ {
+ if (!is_new_style)
+ {
+@@ -1475,13 +1490,13 @@ static void for_each_iface(const statement_list_t *stmts,
+
+ if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
+ {
+- if (stmt->type != STMT_TYPE || type_get_type(stmt->u.type) != TYPE_INTERFACE)
++ if (stmt->type != STMT_TYPE || type_get_type_detect_alias(stmt->u.type) != TYPE_INTERFACE)
+ continue;
+ iface = stmt->u.type;
+ if (!pred(iface)) continue;
+ proc(iface, file, indent, offset);
+- if (iface->details.iface->async_iface)
+- proc(iface->details.iface->async_iface, file, indent, offset);
++ if (type_get_const_details(iface)->iface->async_iface)
++ proc(type_get_const_details(iface)->iface->async_iface, file, indent, offset);
+ }
+ }
+
+@@ -1593,7 +1608,7 @@ static unsigned int write_conf_or_var_desc(FILE *file, const type_t *cont_type,
+ {
+ conftype = FC_TOP_LEVEL_CONFORMANCE;
+ conftype_string = "parameter";
+- cont_type = current_func->type;
++ cont_type = current_func->declspec.type;
+ name = current_func->name;
+ iface = current_iface;
+ }
+@@ -1656,7 +1671,7 @@ static unsigned int write_conf_or_var_desc(FILE *file, const type_t *cont_type,
+
+ if (type_get_type(cont_type) == TYPE_FUNCTION)
+ {
+- var_list_t *args = type_get_function_args( cont_type );
++ var_list_t *args = type_function_get_args( cont_type );
+
+ if (is_object( iface )) offset += pointer_size;
+ if (args) LIST_FOR_EACH_ENTRY( var, args, const var_t, entry )
+@@ -1664,7 +1679,7 @@ static unsigned int write_conf_or_var_desc(FILE *file, const type_t *cont_type,
+ if (var->name && !strcmp(var->name, subexpr->u.sval))
+ {
+ expr_loc.v = var;
+- correlation_variable = var->type;
++ correlation_variable = var->declspec.type;
+ break;
+ }
+ offset += get_stack_size( var, NULL );
+@@ -1676,11 +1691,11 @@ static unsigned int write_conf_or_var_desc(FILE *file, const type_t *cont_type,
+
+ if (fields) LIST_FOR_EACH_ENTRY( var, fields, const var_t, entry )
+ {
+- unsigned int size = field_memsize( var->type, &offset );
++ unsigned int size = field_memsize( var->declspec.type, &offset );
+ if (var->name && !strcmp(var->name, subexpr->u.sval))
+ {
+ expr_loc.v = var;
+- correlation_variable = var->type;
++ correlation_variable = var->declspec.type;
+ break;
+ }
+ offset += size;
+@@ -1819,7 +1834,7 @@ static unsigned int fields_memsize(const var_list_t *fields, unsigned int *align
+ LIST_FOR_EACH_ENTRY( v, fields, const var_t, entry )
+ {
+ unsigned int falign = 0;
+- unsigned int fsize = type_memsize_and_alignment(v->type, &falign);
++ unsigned int fsize = type_memsize_and_alignment(v->declspec.type, &falign);
+ if (*align < falign) *align = falign;
+ falign = clamp_align(falign);
+ size = ROUND_SIZE(size, falign);
+@@ -1841,9 +1856,9 @@ static unsigned int union_memsize(const var_list_t *fields, unsigned int *pmaxa)
+ if (fields) LIST_FOR_EACH_ENTRY( v, fields, const var_t, entry )
+ {
+ /* we could have an empty default field with NULL type */
+- if (v->type)
++ if (v->declspec.type)
+ {
+- size = type_memsize_and_alignment(v->type, &align);
++ size = type_memsize_and_alignment(v->declspec.type, &align);
+ if (maxs < size) maxs = size;
+ if (*pmaxa < align) *pmaxa = align;
+ }
+@@ -1931,12 +1946,12 @@ unsigned int type_memsize_and_alignment(const type_t *t, unsigned int *align)
+ {
+ if (is_conformant_array(t))
+ {
+- type_memsize_and_alignment(type_array_get_element(t), align);
++ type_memsize_and_alignment(type_array_get_element_type(t), align);
+ size = 0;
+ }
+ else
+ size = type_array_get_dim(t) *
+- type_memsize_and_alignment(type_array_get_element(t), align);
++ type_memsize_and_alignment(type_array_get_element_type(t), align);
+ }
+ else /* declared as a pointer */
+ {
+@@ -2016,8 +2031,8 @@ static unsigned int type_buffer_alignment(const type_t *t)
+ if (!(fields = type_struct_get_fields(t))) break;
+ LIST_FOR_EACH_ENTRY( var, fields, const var_t, entry )
+ {
+- if (!var->type) continue;
+- align = type_buffer_alignment( var->type );
++ if (!var->declspec.type) continue;
++ align = type_buffer_alignment( var->declspec.type );
+ if (max < align) max = align;
+ }
+ break;
+@@ -2025,8 +2040,8 @@ static unsigned int type_buffer_alignment(const type_t *t)
+ if (!(fields = type_encapsulated_union_get_fields(t))) break;
+ LIST_FOR_EACH_ENTRY( var, fields, const var_t, entry )
+ {
+- if (!var->type) continue;
+- align = type_buffer_alignment( var->type );
++ if (!var->declspec.type) continue;
++ align = type_buffer_alignment( var->declspec.type );
+ if (max < align) max = align;
+ }
+ break;
+@@ -2034,14 +2049,14 @@ static unsigned int type_buffer_alignment(const type_t *t)
+ if (!(fields = type_union_get_cases(t))) break;
+ LIST_FOR_EACH_ENTRY( var, fields, const var_t, entry )
+ {
+- if (!var->type) continue;
+- align = type_buffer_alignment( var->type );
++ if (!var->declspec.type) continue;
++ align = type_buffer_alignment( var->declspec.type );
+ if (max < align) max = align;
+ }
+ break;
+ case TYPE_ARRAY:
+ if (!type_array_is_decl_as_ptr(t))
+- return type_buffer_alignment( type_array_get_element(t) );
++ return type_buffer_alignment( type_array_get_element_type(t) );
+ /* else fall through */
+ case TYPE_POINTER:
+ return 4;
+@@ -2064,12 +2079,12 @@ static unsigned int type_buffer_alignment(const type_t *t)
+ int is_full_pointer_function(const var_t *func)
+ {
+ const var_t *var;
+- if (type_has_full_pointer(type_function_get_rettype(func->type), func->attrs, TRUE))
++ if (type_has_full_pointer(type_function_get_rettype(func->declspec.type), func->attrs, TRUE))
+ return TRUE;
+- if (!type_get_function_args(func->type))
++ if (!type_function_get_args(func->declspec.type))
+ return FALSE;
+- LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
+- if (type_has_full_pointer( var->type, var->attrs, TRUE ))
++ LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), const var_t, entry )
++ if (type_has_full_pointer( var->declspec.type, var->attrs, TRUE ))
+ return TRUE;
+ return FALSE;
+ }
+@@ -2114,12 +2129,13 @@ static unsigned int write_nonsimple_pointer(FILE *file, const attr_list_t *attrs
+ {
+ if (context == TYPE_CONTEXT_TOPLEVELPARAM && is_ptr(type) && pointer_type == FC_RP)
+ {
+- switch (typegen_detect_type(type_pointer_get_ref(type), NULL, TDT_ALL_TYPES))
++ switch (typegen_detect_type(type_pointer_get_ref_type(type), NULL, TDT_ALL_TYPES))
+ {
+ case TGT_STRING:
+ case TGT_POINTER:
+ case TGT_CTXT_HANDLE:
+ case TGT_CTXT_HANDLE_POINTER:
++ case TGT_ARRAY:
+ flags |= FC_ALLOCED_ON_STACK;
+ break;
+ case TGT_IFACE_POINTER:
+@@ -2134,7 +2150,7 @@ static unsigned int write_nonsimple_pointer(FILE *file, const attr_list_t *attrs
+
+ if (is_ptr(type))
+ {
+- type_t *ref = type_pointer_get_ref(type);
++ type_t *ref = type_pointer_get_ref_type(type);
+ if(is_declptr(ref) && !is_user_type(ref))
+ flags |= FC_POINTER_DEREF;
+ }
+@@ -2175,7 +2191,7 @@ static unsigned int write_simple_pointer(FILE *file, const attr_list_t *attrs,
+
+ pointer_fc = get_pointer_fc_context(type, attrs, context);
+
+- ref = type_pointer_get_ref(type);
++ ref = type_pointer_get_ref_type(type);
+ if (type_get_type(ref) == TYPE_ENUM)
+ fc = get_enum_fc(ref);
+ else
+@@ -2200,22 +2216,23 @@ static unsigned int write_simple_pointer(FILE *file, const attr_list_t *attrs,
+ return 4;
+ }
+
+-static void print_start_tfs_comment(FILE *file, type_t *t, unsigned int tfsoff)
++static void print_start_tfs_comment(FILE *file, const decl_spec_t *ds, unsigned int tfsoff)
+ {
+ print_file(file, 0, "/* %u (", tfsoff);
+- write_type_decl(file, t, NULL);
++ write_declspec_decl(file, ds, NULL);
+ print_file(file, 0, ") */\n");
+ }
+
+ static unsigned int write_pointer_tfs(FILE *file, const attr_list_t *attrs,
+- type_t *type, unsigned int ref_offset,
++ const decl_spec_t *declspec, unsigned int ref_offset,
+ enum type_context context,
+ unsigned int *typestring_offset)
+ {
+ unsigned int offset = *typestring_offset;
+- type_t *ref = type_pointer_get_ref(type);
++ type_t *type = declspec->type;
++ type_t *ref = type_pointer_get_ref_type(type);
+
+- print_start_tfs_comment(file, type, offset);
++ print_start_tfs_comment(file, declspec, offset);
+ update_tfsoff(type, offset, file);
+
+ switch (typegen_detect_type(ref, attrs, TDT_ALL_TYPES))
+@@ -2258,10 +2275,11 @@ static int user_type_has_variable_size(const type_t *t)
+ return FALSE;
+ }
+
+-static unsigned int write_user_tfs(FILE *file, type_t *type, unsigned int *tfsoff)
++static unsigned int write_user_tfs(FILE *file, const decl_spec_t *declspec, unsigned int *tfsoff)
+ {
+ unsigned int start, absoff, flags;
+ const char *name = NULL;
++ type_t *type = declspec->type;
+ type_t *utype = get_user_type(type, &name);
+ unsigned int usize = type_memsize(utype);
+ unsigned int ualign = type_buffer_alignment(utype);
+@@ -2279,6 +2297,7 @@ static unsigned int write_user_tfs(FILE *file, type_t *type, unsigned int *tfsof
+ type_get_type(utype) == TYPE_ENUM)
+ {
+ unsigned char fc;
++ decl_spec_t ds;
+
+ if (type_get_type(utype) == TYPE_ENUM)
+ fc = get_enum_fc(utype);
+@@ -2286,7 +2305,7 @@ static unsigned int write_user_tfs(FILE *file, type_t *type, unsigned int *tfsof
+ fc = get_basic_fc(utype);
+
+ absoff = *tfsoff;
+- print_start_tfs_comment(file, utype, absoff);
++ print_start_tfs_comment(file, init_declspec(&ds, utype), absoff);
+ print_file(file, 2, "0x%x,\t/* %s */\n", fc, string_of_type(fc));
+ print_file(file, 2, "0x5c,\t/* FC_PAD */\n");
+ *tfsoff += 2;
+@@ -2294,7 +2313,10 @@ static unsigned int write_user_tfs(FILE *file, type_t *type, unsigned int *tfsof
+ else
+ {
+ if (!processed(utype))
+- write_embedded_types(file, NULL, utype, utype->name, TRUE, tfsoff);
++ {
++ decl_spec_t ds;
++ write_embedded_types(file, NULL, init_declspec(&ds, utype), utype->name, TRUE, tfsoff);
++ }
+ absoff = utype->typestring_offset;
+ }
+
+@@ -2307,7 +2329,7 @@ static unsigned int write_user_tfs(FILE *file, type_t *type, unsigned int *tfsof
+
+ start = *tfsoff;
+ update_tfsoff(type, start, file);
+- print_start_tfs_comment(file, type, start);
++ print_start_tfs_comment(file, declspec, start);
+ print_file(file, 2, "0x%x,\t/* FC_USER_MARSHAL */\n", FC_USER_MARSHAL);
+ print_file(file, 2, "0x%x,\t/* Alignment= %d, Flags= %02x */\n",
+ flags | (ualign - 1), ualign - 1, flags);
+@@ -2364,11 +2386,12 @@ static void write_member_type(FILE *file, const type_t *cont,
+ static void write_array_element_type(FILE *file, const attr_list_t *attrs, const type_t *type,
+ int cont_is_complex, unsigned int *tfsoff)
+ {
+- type_t *elem = type_array_get_element(type);
++ const decl_spec_t *element = type_array_get_element(type);
++ type_t *elem = element->type;
+
+ if (!is_embedded_complex(elem) && is_ptr(elem))
+ {
+- type_t *ref = type_pointer_get_ref(elem);
++ type_t *ref = type_pointer_get_ref_type(elem);
+
+ if (processed(ref))
+ {
+@@ -2378,7 +2401,7 @@ static void write_array_element_type(FILE *file, const attr_list_t *attrs, const
+ }
+ if (cont_is_complex && is_string_type(attrs, elem))
+ {
+- write_string_tfs(file, NULL, elem, TYPE_CONTEXT_CONTAINER, NULL, tfsoff);
++ write_string_tfs(file, NULL, element, TYPE_CONTEXT_CONTAINER, NULL, tfsoff);
+ return;
+ }
+ if (!is_string_type(NULL, elem) &&
+@@ -2410,7 +2433,7 @@ static void write_descriptors(FILE *file, type_t *type, unsigned int *tfsoff)
+
+ if (fs) LIST_FOR_EACH_ENTRY(f, fs, var_t, entry)
+ {
+- type_t *ft = f->type;
++ type_t *ft = f->declspec.type;
+ unsigned int size = field_memsize( ft, &offset );
+ if (type_get_type(ft) == TYPE_UNION && is_attr(f->attrs, ATTR_SWITCHIS))
+ {
+@@ -2433,13 +2456,14 @@ static void write_descriptors(FILE *file, type_t *type, unsigned int *tfsoff)
+ }
+
+ static int write_pointer_description_offsets(
+- FILE *file, const attr_list_t *attrs, type_t *type,
++ FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
+ unsigned int *offset_in_memory, unsigned int *offset_in_buffer,
+ unsigned int *typestring_offset)
+ {
++ type_t *type = declspec->type;
+ int written = 0;
+
+- if ((is_ptr(type) && type_get_type(type_pointer_get_ref(type)) != TYPE_INTERFACE) ||
++ if ((is_ptr(type) && type_get_type(type_pointer_get_ref_type(type)) != TYPE_INTERFACE) ||
+ (is_array(type) && type_array_is_decl_as_ptr(type)))
+ {
+ if (offset_in_memory && offset_in_buffer)
+@@ -2464,10 +2488,10 @@ static int write_pointer_description_offsets(
+
+ if (is_ptr(type))
+ {
+- type_t *ref = type_pointer_get_ref(type);
++ type_t *ref = type_pointer_get_ref_type(type);
+
+ if (is_string_type(attrs, type))
+- write_string_tfs(file, attrs, type, TYPE_CONTEXT_CONTAINER, NULL, typestring_offset);
++ write_string_tfs(file, attrs, declspec, TYPE_CONTEXT_CONTAINER, NULL, typestring_offset);
+ else if (processed(ref))
+ write_nonsimple_pointer(file, attrs, type, TYPE_CONTEXT_CONTAINER,
+ ref->typestring_offset, typestring_offset);
+@@ -2505,13 +2529,13 @@ static int write_pointer_description_offsets(
+ {
+ unsigned int padding;
+ unsigned int align = 0;
+- type_memsize_and_alignment(v->type, &align);
++ type_memsize_and_alignment(v->declspec.type, &align);
+ padding = ROUNDING(*offset_in_memory, align);
+ *offset_in_memory += padding;
+ *offset_in_buffer += padding;
+ }
+ written += write_pointer_description_offsets(
+- file, v->attrs, v->type, offset_in_memory, offset_in_buffer,
++ file, v->attrs, &v->declspec, offset_in_memory, offset_in_buffer,
+ typestring_offset);
+ }
+ }
+@@ -2531,10 +2555,11 @@ static int write_pointer_description_offsets(
+ }
+
+ static int write_no_repeat_pointer_descriptions(
+- FILE *file, const attr_list_t *attrs, type_t *type,
++ FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
+ unsigned int *offset_in_memory, unsigned int *offset_in_buffer,
+ unsigned int *typestring_offset)
+ {
++ type_t *type = declspec->type;
+ int written = 0;
+
+ if (is_ptr(type) ||
+@@ -2544,7 +2569,7 @@ static int write_no_repeat_pointer_descriptions(
+ print_file(file, 2, "0x%02x, /* FC_PAD */\n", FC_PAD);
+ *typestring_offset += 2;
+
+- return write_pointer_description_offsets(file, attrs, type,
++ return write_pointer_description_offsets(file, attrs, declspec,
+ offset_in_memory, offset_in_buffer, typestring_offset);
+ }
+
+@@ -2557,13 +2582,13 @@ static int write_no_repeat_pointer_descriptions(
+ {
+ unsigned int padding;
+ unsigned int align = 0;
+- type_memsize_and_alignment(v->type, &align);
++ type_memsize_and_alignment(v->declspec.type, &align);
+ padding = ROUNDING(*offset_in_memory, align);
+ *offset_in_memory += padding;
+ *offset_in_buffer += padding;
+ }
+ written += write_no_repeat_pointer_descriptions(
+- file, v->attrs, v->type,
++ file, v->attrs, &v->declspec,
+ offset_in_memory, offset_in_buffer, typestring_offset);
+ }
+ }
+@@ -2582,10 +2607,11 @@ static int write_no_repeat_pointer_descriptions(
+ /* Note: if file is NULL return value is number of pointers to write, else
+ * it is the number of type format characters written */
+ static int write_fixed_array_pointer_descriptions(
+- FILE *file, const attr_list_t *attrs, type_t *type,
++ FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
+ unsigned int *offset_in_memory, unsigned int *offset_in_buffer,
+ unsigned int *typestring_offset)
+ {
++ type_t *type = declspec->type;
+ int pointer_count = 0;
+
+ if (type_get_type(type) == TYPE_ARRAY &&
+@@ -2602,7 +2628,7 @@ static int write_fixed_array_pointer_descriptions(
+ unsigned int offset_of_array_pointer_mem = 0;
+ unsigned int offset_of_array_pointer_buf = 0;
+
+- increment_size = type_memsize(type_array_get_element(type));
++ increment_size = type_memsize(type_array_get_element_type(type));
+
+ print_file(file, 2, "0x%02x, /* FC_FIXED_REPEAT */\n", FC_FIXED_REPEAT);
+ print_file(file, 2, "0x%02x, /* FC_PAD */\n", FC_PAD);
+@@ -2613,7 +2639,7 @@ static int write_fixed_array_pointer_descriptions(
+ *typestring_offset += 10;
+
+ pointer_count = write_pointer_description_offsets(
+- file, attrs, type, &offset_of_array_pointer_mem,
++ file, attrs, declspec, &offset_of_array_pointer_mem,
+ &offset_of_array_pointer_buf, typestring_offset);
+ }
+ }
+@@ -2626,13 +2652,13 @@ static int write_fixed_array_pointer_descriptions(
+ {
+ unsigned int padding;
+ unsigned int align = 0;
+- type_memsize_and_alignment(v->type, &align);
++ type_memsize_and_alignment(v->declspec.type, &align);
+ padding = ROUNDING(*offset_in_memory, align);
+ *offset_in_memory += padding;
+ *offset_in_buffer += padding;
+ }
+ pointer_count += write_fixed_array_pointer_descriptions(
+- file, v->attrs, v->type, offset_in_memory, offset_in_buffer,
++ file, v->attrs, &v->declspec, offset_in_memory, offset_in_buffer,
+ typestring_offset);
+ }
+ }
+@@ -2673,7 +2699,7 @@ static int write_conformant_array_pointer_descriptions(
+ unsigned int offset_of_array_pointer_mem = offset_in_memory;
+ unsigned int offset_of_array_pointer_buf = offset_in_memory;
+
+- increment_size = type_memsize(type_array_get_element(type));
++ increment_size = type_memsize(type_array_get_element_type(type));
+
+ if (increment_size > USHRT_MAX)
+ error("array size of %u bytes is too large\n", increment_size);
+@@ -2715,7 +2741,7 @@ static int write_varying_array_pointer_descriptions(
+ {
+ unsigned int increment_size;
+
+- increment_size = type_memsize(type_array_get_element(type));
++ increment_size = type_memsize(type_array_get_element_type(type));
+
+ if (increment_size > USHRT_MAX)
+ error("array size of %u bytes is too large\n", increment_size);
+@@ -2741,20 +2767,20 @@ static int write_varying_array_pointer_descriptions(
+ {
+ unsigned int align = 0, padding;
+
+- if (is_array(v->type) && type_array_has_variance(v->type))
++ if (is_array(v->declspec.type) && type_array_has_variance(v->declspec.type))
+ {
+ *offset_in_buffer = ROUND_SIZE(*offset_in_buffer, 4);
+ /* skip over variance and offset in buffer */
+ *offset_in_buffer += 8;
+ }
+
+- type_memsize_and_alignment(v->type, &align);
++ type_memsize_and_alignment(v->declspec.type, &align);
+ padding = ROUNDING(*offset_in_memory, align);
+ *offset_in_memory += padding;
+ *offset_in_buffer += padding;
+ }
+ pointer_count += write_varying_array_pointer_descriptions(
+- file, v->attrs, v->type, offset_in_memory, offset_in_buffer,
++ file, v->attrs, v->declspec.type, offset_in_memory, offset_in_buffer,
+ typestring_offset);
+ }
+ }
+@@ -2773,9 +2799,10 @@ static int write_varying_array_pointer_descriptions(
+ return pointer_count;
+ }
+
+-static void write_pointer_description(FILE *file, const attr_list_t *attrs, type_t *type,
++static void write_pointer_description(FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
+ unsigned int *typestring_offset)
+ {
++ type_t *type = declspec->type;
+ unsigned int offset_in_buffer;
+ unsigned int offset_in_memory;
+
+@@ -2786,7 +2813,7 @@ static void write_pointer_description(FILE *file, const attr_list_t *attrs, type
+ offset_in_memory = 0;
+ offset_in_buffer = 0;
+ write_no_repeat_pointer_descriptions(
+- file, NULL, type,
++ file, NULL, declspec,
+ &offset_in_memory, &offset_in_buffer, typestring_offset);
+ }
+
+@@ -2794,7 +2821,7 @@ static void write_pointer_description(FILE *file, const attr_list_t *attrs, type
+ offset_in_memory = 0;
+ offset_in_buffer = 0;
+ write_fixed_array_pointer_descriptions(
+- file, NULL, type,
++ file, NULL, declspec,
+ &offset_in_memory, &offset_in_buffer, typestring_offset);
+
+ /* pass 3: search for pointers in conformant only arrays (but don't descend
+@@ -2806,7 +2833,7 @@ static void write_pointer_description(FILE *file, const attr_list_t *attrs, type
+ else if (type_get_type(type) == TYPE_STRUCT &&
+ get_struct_fc(type) == FC_CPSTRUCT)
+ {
+- type_t *carray = find_array_or_string_in_struct(type)->type;
++ type_t *carray = find_array_or_string_in_struct(type)->declspec.type;
+ write_conformant_array_pointer_descriptions( file, NULL, carray,
+ type_memsize(type), typestring_offset);
+ }
+@@ -2820,9 +2847,10 @@ static void write_pointer_description(FILE *file, const attr_list_t *attrs, type
+ }
+
+ static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs,
+- type_t *type, enum type_context context,
++ const decl_spec_t *declspec, enum type_context context,
+ const char *name, unsigned int *typestring_offset)
+ {
++ type_t *type = declspec->type;
+ unsigned int start_offset;
+ unsigned char rtype;
+ type_t *elem_type;
+@@ -2836,7 +2864,7 @@ static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs,
+ int pointer_type = get_pointer_fc_context(type, attrs, context);
+ if (!pointer_type)
+ pointer_type = FC_RP;
+- print_start_tfs_comment(file, type, *typestring_offset);
++ print_start_tfs_comment(file, declspec, *typestring_offset);
+ print_file(file, 2,"0x%x, 0x%x,\t/* %s%s */\n",
+ pointer_type, flag, string_of_type(pointer_type),
+ flag ? " [simple_pointer]" : "");
+@@ -2850,12 +2878,12 @@ static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs,
+ }
+
+ if (is_array(type))
+- elem_type = type_array_get_element(type);
++ elem_type = type_array_get_element_type(type);
+ else
+- elem_type = type_pointer_get_ref(type);
++ elem_type = type_pointer_get_ref_type(type);
+
+ if (type_get_type(elem_type) == TYPE_POINTER && is_array(type))
+- return write_array_tfs(file, attrs, type, name, typestring_offset);
++ return write_array_tfs(file, attrs, declspec, name, typestring_offset);
+
+ if (type_get_type(elem_type) != TYPE_BASIC)
+ {
+@@ -2929,34 +2957,31 @@ static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs,
+ }
+ }
+
+-static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type,
++static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
+ const char *name, unsigned int *typestring_offset)
+ {
++ type_t *type = declspec->type;
+ const expr_t *length_is = type_array_get_variance(type);
+ const expr_t *size_is = type_array_get_conformance(type);
+ unsigned int align;
+ unsigned int size;
+ unsigned int start_offset;
+ unsigned char fc;
+- int pointer_type = get_attrv(attrs, ATTR_POINTERTYPE);
+ unsigned int baseoff
+ = !type_array_is_decl_as_ptr(type) && current_structure
+ ? type_memsize(current_structure)
+ : 0;
+
+- if (!pointer_type)
+- pointer_type = FC_RP;
+-
+- if (!is_string_type(attrs, type_array_get_element(type)))
++ if (!is_string_type(attrs, type_array_get_element_type(type)))
+ write_embedded_types(file, attrs, type_array_get_element(type), name, FALSE, typestring_offset);
+
+- size = type_memsize(is_conformant_array(type) ? type_array_get_element(type) : type);
+- align = type_buffer_alignment(is_conformant_array(type) ? type_array_get_element(type) : type);
++ size = type_memsize(is_conformant_array(type) ? type_array_get_element_type(type) : type);
++ align = type_buffer_alignment(is_conformant_array(type) ? type_array_get_element_type(type) : type);
+ fc = get_array_fc(type);
+
+ start_offset = *typestring_offset;
+ update_tfsoff(type, start_offset, file);
+- print_start_tfs_comment(file, type, start_offset);
++ print_start_tfs_comment(file, declspec, start_offset);
+ print_file(file, 2, "0x%02x,\t/* %s */\n", fc, string_of_type(fc));
+ print_file(file, 2, "0x%x,\t/* %d */\n", align - 1, align - 1);
+ *typestring_offset += 2;
+@@ -2982,7 +3007,7 @@ static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, type_t
+
+ if (fc == FC_SMVARRAY || fc == FC_LGVARRAY)
+ {
+- unsigned int elsize = type_memsize(type_array_get_element(type));
++ unsigned int elsize = type_memsize(type_array_get_element_type(type));
+ unsigned int dim = type_array_get_dim(type);
+
+ if (fc == FC_LGVARRAY)
+@@ -3005,13 +3030,13 @@ static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, type_t
+ += write_conf_or_var_desc(file, current_structure, baseoff,
+ type, length_is);
+
+- if (type_has_pointers(type_array_get_element(type)) &&
++ if (type_has_pointers(type_array_get_element_type(type)) &&
+ (type_array_is_decl_as_ptr(type) || !current_structure))
+ {
+ print_file(file, 2, "0x%x,\t/* FC_PP */\n", FC_PP);
+ print_file(file, 2, "0x%x,\t/* FC_PAD */\n", FC_PAD);
+ *typestring_offset += 2;
+- write_pointer_description(file, is_string_type(attrs, type) ? attrs : NULL, type, typestring_offset);
++ write_pointer_description(file, is_string_type(attrs, type) ? attrs : NULL, declspec, typestring_offset);
+ print_file(file, 2, "0x%x,\t/* FC_END */\n", FC_END);
+ *typestring_offset += 1;
+ }
+@@ -3048,7 +3073,7 @@ static const var_t *find_array_or_string_in_struct(const type_t *type)
+ return NULL;
+
+ last_field = LIST_ENTRY( list_tail(fields), const var_t, entry );
+- ft = last_field->type;
++ ft = last_field->declspec.type;
+
+ if (is_conformant_array(ft) && !type_array_is_decl_as_ptr(ft))
+ return last_field;
+@@ -3071,7 +3096,7 @@ static void write_struct_members(FILE *file, const type_t *type,
+
+ if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
+ {
+- type_t *ft = field->type;
++ type_t *ft = field->declspec.type;
+ unsigned int align = 0;
+ unsigned int size = type_memsize_and_alignment(ft, &align);
+ align = clamp_align(align);
+@@ -3100,7 +3125,7 @@ static void write_struct_members(FILE *file, const type_t *type,
+ offset = ROUND_SIZE(offset, align);
+ *typestring_offset += 1;
+ }
+- write_member_type(file, type, is_complex, field->attrs, field->type, corroff,
++ write_member_type(file, type, is_complex, field->attrs, field->declspec.type, corroff,
+ typestring_offset);
+ offset += size;
+ }
+@@ -3118,9 +3143,10 @@ static void write_struct_members(FILE *file, const type_t *type,
+ write_end(file, typestring_offset);
+ }
+
+-static unsigned int write_struct_tfs(FILE *file, type_t *type,
++static unsigned int write_struct_tfs(FILE *file, const decl_spec_t *declspec,
+ const char *name, unsigned int *tfsoff)
+ {
++ type_t *type = declspec->type;
+ const type_t *save_current_structure = current_structure;
+ unsigned int total_size;
+ const var_t *array;
+@@ -3143,15 +3169,15 @@ static unsigned int write_struct_tfs(FILE *file, type_t *type,
+ name, USHRT_MAX, total_size - USHRT_MAX);
+
+ if (fields) LIST_FOR_EACH_ENTRY(f, fields, var_t, entry)
+- write_embedded_types(file, f->attrs, f->type, f->name, FALSE, tfsoff);
++ write_embedded_types(file, f->attrs, &f->declspec, f->name, FALSE, tfsoff);
+
+ array = find_array_or_string_in_struct(type);
+- if (array && !processed(array->type))
++ if (array && !processed(array->declspec.type))
+ {
+- if(is_string_type(array->attrs, array->type))
+- write_string_tfs(file, array->attrs, array->type, TYPE_CONTEXT_CONTAINER, array->name, tfsoff);
++ if(is_string_type(array->attrs, array->declspec.type))
++ write_string_tfs(file, array->attrs, &array->declspec, TYPE_CONTEXT_CONTAINER, array->name, tfsoff);
+ else
+- write_array_tfs(file, array->attrs, array->type, array->name, tfsoff);
++ write_array_tfs(file, array->attrs, &array->declspec, array->name, tfsoff);
+ }
+
+ corroff = *tfsoff;
+@@ -3159,7 +3185,7 @@ static unsigned int write_struct_tfs(FILE *file, type_t *type,
+
+ start_offset = *tfsoff;
+ update_tfsoff(type, start_offset, file);
+- print_start_tfs_comment(file, type, start_offset);
++ print_start_tfs_comment(file, declspec, start_offset);
+ print_file(file, 2, "0x%x,\t/* %s */\n", fc, string_of_type(fc));
+ print_file(file, 2, "0x%x,\t/* %d */\n", align - 1, align - 1);
+ print_file(file, 2, "NdrFcShort(0x%hx),\t/* %d */\n", (unsigned short)total_size, total_size);
+@@ -3167,7 +3193,7 @@ static unsigned int write_struct_tfs(FILE *file, type_t *type,
+
+ if (array)
+ {
+- unsigned int absoff = array->type->typestring_offset;
++ unsigned int absoff = array->declspec.type->typestring_offset;
+ short reloff = absoff - *tfsoff;
+ print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%u) */\n",
+ reloff, reloff, absoff);
+@@ -3198,7 +3224,7 @@ static unsigned int write_struct_tfs(FILE *file, type_t *type,
+ print_file(file, 2, "0x%x,\t/* FC_PP */\n", FC_PP);
+ print_file(file, 2, "0x%x,\t/* FC_PAD */\n", FC_PAD);
+ *tfsoff += 2;
+- write_pointer_description(file, NULL, type, tfsoff);
++ write_pointer_description(file, NULL, declspec, tfsoff);
+ print_file(file, 2, "0x%x,\t/* FC_END */\n", FC_END);
+ *tfsoff += 1;
+ }
+@@ -3213,15 +3239,16 @@ static unsigned int write_struct_tfs(FILE *file, type_t *type,
+ type->ptrdesc = *tfsoff;
+ if (fields) LIST_FOR_EACH_ENTRY(f, fields, const var_t, entry)
+ {
+- type_t *ft = f->type;
++ const decl_spec_t *fds = &f->declspec;
++ type_t *ft = fds->type;
+ switch (typegen_detect_type(ft, f->attrs, TDT_IGNORE_STRINGS))
+ {
+ case TGT_POINTER:
+ if (is_string_type(f->attrs, ft))
+- write_string_tfs(file, f->attrs, ft, TYPE_CONTEXT_CONTAINER, f->name, tfsoff);
++ write_string_tfs(file, f->attrs, fds, TYPE_CONTEXT_CONTAINER, f->name, tfsoff);
+ else
+- write_pointer_tfs(file, f->attrs, ft,
+- type_pointer_get_ref(ft)->typestring_offset,
++ write_pointer_tfs(file, f->attrs, fds,
++ type_pointer_get_ref_type(ft)->typestring_offset,
+ TYPE_CONTEXT_CONTAINER, tfsoff);
+ break;
+ case TGT_ARRAY:
+@@ -3283,8 +3310,9 @@ static void write_branch_type(FILE *file, const type_t *t, unsigned int *tfsoff)
+ }
+
+ static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs,
+- type_t *type, unsigned int *tfsoff)
++ const decl_spec_t *declspec, unsigned int *tfsoff)
+ {
++ type_t* type = declspec->type;
+ unsigned int start_offset;
+ unsigned int size;
+ var_list_t *fields;
+@@ -3309,17 +3337,17 @@ static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs,
+ expr_list_t *cases = get_attrp(f->attrs, ATTR_CASE);
+ if (cases)
+ nbranch += list_count(cases);
+- if (f->type)
+- write_embedded_types(file, f->attrs, f->type, f->name, TRUE, tfsoff);
++ if (f->declspec.type)
++ write_embedded_types(file, f->attrs, &f->declspec, f->name, TRUE, tfsoff);
+ }
+
+ start_offset = *tfsoff;
+ update_tfsoff(type, start_offset, file);
+- print_start_tfs_comment(file, type, start_offset);
++ print_start_tfs_comment(file, declspec, start_offset);
+ if (type_get_type(type) == TYPE_ENCAPSULATED_UNION)
+ {
+ const var_t *sv = type_union_get_switch_value(type);
+- const type_t *st = sv->type;
++ const type_t *st = sv->declspec.type;
+ unsigned int align = 0;
+ unsigned char fc;
+
+@@ -3351,8 +3379,8 @@ static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs,
+ type_memsize_and_alignment(st, &align);
+ if (fields) LIST_FOR_EACH_ENTRY(f, fields, var_t, entry)
+ {
+- if (f->type)
+- type_memsize_and_alignment(f->type, &align);
++ if (f->declspec.type)
++ type_memsize_and_alignment(f->declspec.type, &align);
+ }
+
+ print_file(file, 2, "0x%x,\t/* FC_ENCAPSULATED_UNION */\n", FC_ENCAPSULATED_UNION);
+@@ -3407,7 +3435,7 @@ static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs,
+
+ if (fields) LIST_FOR_EACH_ENTRY(f, fields, var_t, entry)
+ {
+- type_t *ft = f->type;
++ type_t *ft = f->declspec.type;
+ expr_list_t *cases = get_attrp(f->attrs, ATTR_CASE);
+ int deflt = is_attr(f->attrs, ATTR_DEFAULT);
+ expr_t *c;
+@@ -3448,16 +3476,17 @@ static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs,
+ return start_offset;
+ }
+
+-static unsigned int write_ip_tfs(FILE *file, const attr_list_t *attrs, type_t *type,
++static unsigned int write_ip_tfs(FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
+ unsigned int *typeformat_offset)
+ {
+ unsigned int i;
++ type_t *type = declspec->type;
+ unsigned int start_offset = *typeformat_offset;
+ expr_t *iid = get_attrp(attrs, ATTR_IIDIS);
+
+ if (!iid && processed(type)) return type->typestring_offset;
+
+- print_start_tfs_comment(file, type, start_offset);
++ print_start_tfs_comment(file, declspec, start_offset);
+ update_tfsoff(type, start_offset, file);
+
+ if (iid)
+@@ -3469,7 +3498,7 @@ static unsigned int write_ip_tfs(FILE *file, const attr_list_t *attrs, type_t *t
+ }
+ else
+ {
+- const type_t *base = is_ptr(type) ? type_pointer_get_ref(type) : type;
++ const type_t *base = is_ptr(type) ? type_pointer_get_ref_type(type) : type;
+ const UUID *uuid = get_attrp(base->attrs, ATTR_UUID);
+
+ if (! uuid)
+@@ -3493,18 +3522,19 @@ static unsigned int write_ip_tfs(FILE *file, const attr_list_t *attrs, type_t *t
+
+ static unsigned int write_contexthandle_tfs(FILE *file,
+ const attr_list_t *attrs,
+- type_t *type,
+- int toplevel_param,
++ const decl_spec_t *declspec,
++ enum type_context context,
+ unsigned int *typeformat_offset)
+ {
++ type_t *type = declspec->type;
+ unsigned int start_offset = *typeformat_offset;
+- unsigned char flags = get_contexthandle_flags( current_iface, attrs, type );
++ unsigned char flags = get_contexthandle_flags( current_iface, attrs, type, context == TYPE_CONTEXT_RETVAL );
+
+- print_start_tfs_comment(file, type, start_offset);
++ print_start_tfs_comment(file, declspec, start_offset);
+
+ if (flags & 0x80) /* via ptr */
+ {
+- int pointer_type = get_pointer_fc( type, attrs, toplevel_param );
++ int pointer_type = get_pointer_fc( type, attrs, context == TYPE_CONTEXT_TOPLEVELPARAM );
+ if (!pointer_type) pointer_type = FC_RP;
+ *typeformat_offset += 4;
+ print_file(file, 2,"0x%x, 0x0,\t/* %s */\n", pointer_type, string_of_type(pointer_type) );
+@@ -3514,8 +3544,7 @@ static unsigned int write_contexthandle_tfs(FILE *file,
+
+ print_file(file, 2, "0x%02x,\t/* FC_BIND_CONTEXT */\n", FC_BIND_CONTEXT);
+ print_file(file, 2, "0x%x,\t/* Context flags: ", flags);
+- /* return and can't be null values overlap */
+- if (((flags & 0x21) != 0x21) && (flags & NDR_CONTEXT_HANDLE_CANNOT_BE_NULL))
++ if (flags & NDR_CONTEXT_HANDLE_CANNOT_BE_NULL)
+ print_file(file, 0, "can't be null, ");
+ if (flags & NDR_CONTEXT_HANDLE_SERIALIZE)
+ print_file(file, 0, "serialize, ");
+@@ -3523,13 +3552,13 @@ static unsigned int write_contexthandle_tfs(FILE *file,
+ print_file(file, 0, "no serialize, ");
+ if (flags & NDR_STRICT_CONTEXT_HANDLE)
+ print_file(file, 0, "strict, ");
+- if ((flags & 0x21) == 0x20)
+- print_file(file, 0, "out, ");
+- if ((flags & 0x21) == 0x21)
++ if (flags & HANDLE_PARAM_IS_RETURN)
+ print_file(file, 0, "return, ");
+- if (flags & 0x40)
++ if (flags & HANDLE_PARAM_IS_OUT)
++ print_file(file, 0, "out, ");
++ if (flags & HANDLE_PARAM_IS_IN)
+ print_file(file, 0, "in, ");
+- if (flags & 0x80)
++ if (flags & HANDLE_PARAM_IS_VIA_PTR)
+ print_file(file, 0, "via ptr, ");
+ print_file(file, 0, "*/\n");
+ print_file(file, 2, "0x%x,\t/* rundown routine */\n", get_context_handle_offset( type ));
+@@ -3568,24 +3597,23 @@ static unsigned int write_range_tfs(FILE *file, const attr_list_t *attrs,
+ return start_offset;
+ }
+
+-static unsigned int write_type_tfs(FILE *file, int indent,
+- const attr_list_t *attrs, type_t *type,
+- const char *name,
++static unsigned int write_type_tfs(FILE *file, const attr_list_t *attrs,
++ const decl_spec_t *declspec, const char *name,
+ enum type_context context,
+ unsigned int *typeformat_offset)
+ {
+ unsigned int offset;
++ type_t *type = declspec->type;
+
+ switch (typegen_detect_type(type, attrs, TDT_ALL_TYPES))
+ {
+ case TGT_CTXT_HANDLE:
+ case TGT_CTXT_HANDLE_POINTER:
+- return write_contexthandle_tfs(file, attrs, type,
+- context == TYPE_CONTEXT_TOPLEVELPARAM, typeformat_offset);
++ return write_contexthandle_tfs(file, attrs, declspec, context, typeformat_offset);
+ case TGT_USER_TYPE:
+- return write_user_tfs(file, type, typeformat_offset);
++ return write_user_tfs(file, declspec, typeformat_offset);
+ case TGT_STRING:
+- return write_string_tfs(file, attrs, type, context, name, typeformat_offset);
++ return write_string_tfs(file, attrs, declspec, context, name, typeformat_offset);
+ case TGT_ARRAY:
+ {
+ unsigned int off;
+@@ -3593,15 +3621,14 @@ static unsigned int write_type_tfs(FILE *file, int indent,
+ if ((context != TYPE_CONTEXT_CONTAINER &&
+ context != TYPE_CONTEXT_CONTAINER_NO_POINTERS) ||
+ !is_conformant_array(type) || type_array_is_decl_as_ptr(type))
+- off = write_array_tfs(file, attrs, type, name, typeformat_offset);
++ off = write_array_tfs(file, attrs, declspec, name, typeformat_offset);
+ else
+ off = 0;
+ if (context != TYPE_CONTEXT_CONTAINER &&
+ context != TYPE_CONTEXT_CONTAINER_NO_POINTERS)
+ {
+ int ptr_type;
+- ptr_type = get_pointer_fc(type, attrs,
+- context == TYPE_CONTEXT_TOPLEVELPARAM);
++ ptr_type = get_pointer_fc_context(type, attrs, context);
+ if (ptr_type != FC_RP || type_array_is_decl_as_ptr(type))
+ {
+ unsigned int absoff = type->typestring_offset;
+@@ -3615,14 +3642,14 @@ static unsigned int write_type_tfs(FILE *file, int indent,
+ if (ptr_type != FC_RP) update_tfsoff( type, off, file );
+ *typeformat_offset += 4;
+ }
+- type->details.array.ptr_tfsoff = off;
++ type_get_details(type)->array.ptr_tfsoff = off;
+ }
+ return off;
+ }
+ case TGT_STRUCT:
+- return write_struct_tfs(file, type, name, typeformat_offset);
++ return write_struct_tfs(file, declspec, name, typeformat_offset);
+ case TGT_UNION:
+- return write_union_tfs(file, attrs, type, typeformat_offset);
++ return write_union_tfs(file, attrs, declspec, typeformat_offset);
+ case TGT_ENUM:
+ case TGT_BASIC:
+ /* nothing to do */
+@@ -3635,11 +3662,11 @@ static unsigned int write_type_tfs(FILE *file, int indent,
+ return write_range_tfs(file, attrs, type, range_list, typeformat_offset);
+ }
+ case TGT_IFACE_POINTER:
+- return write_ip_tfs(file, attrs, type, typeformat_offset);
++ return write_ip_tfs(file, attrs, declspec, typeformat_offset);
+ case TGT_POINTER:
+ {
+ enum type_context ref_context;
+- type_t *ref = type_pointer_get_ref(type);
++ const decl_spec_t *ref = type_pointer_get_ref(type);
+
+ if (context == TYPE_CONTEXT_TOPLEVELPARAM)
+ ref_context = TYPE_CONTEXT_PARAM;
+@@ -3648,22 +3675,22 @@ static unsigned int write_type_tfs(FILE *file, int indent,
+ else
+ ref_context = context;
+
+- if (is_string_type(attrs, ref))
++ if (is_string_type(attrs, ref->type))
+ {
+ if (context != TYPE_CONTEXT_CONTAINER_NO_POINTERS)
+- write_pointer_tfs(file, attrs, type, *typeformat_offset + 4, context, typeformat_offset);
++ write_pointer_tfs(file, attrs, declspec, *typeformat_offset + 4, context, typeformat_offset);
+
+- offset = write_type_tfs(file, indent, attrs, ref, name, ref_context, typeformat_offset);
++ offset = write_type_tfs(file, attrs, ref, name, ref_context, typeformat_offset);
+ if (context == TYPE_CONTEXT_CONTAINER_NO_POINTERS)
+ return 0;
+ return offset;
+ }
+
+- offset = write_type_tfs( file, indent, attrs, type_pointer_get_ref(type), name,
++ offset = write_type_tfs( file, attrs, type_pointer_get_ref(type), name,
+ ref_context, typeformat_offset);
+ if (context == TYPE_CONTEXT_CONTAINER_NO_POINTERS)
+ return 0;
+- return write_pointer_tfs(file, attrs, type, offset, context, typeformat_offset);
++ return write_pointer_tfs(file, attrs, declspec, offset, context, typeformat_offset);
+ }
+ case TGT_INVALID:
+ break;
+@@ -3672,10 +3699,10 @@ static unsigned int write_type_tfs(FILE *file, int indent,
+ return 0;
+ }
+
+-static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *type,
++static int write_embedded_types(FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
+ const char *name, int write_ptr, unsigned int *tfsoff)
+ {
+- return write_type_tfs(file, 2, attrs, type, name, write_ptr ? TYPE_CONTEXT_CONTAINER : TYPE_CONTEXT_CONTAINER_NO_POINTERS, tfsoff);
++ return write_type_tfs(file, attrs, declspec, name, write_ptr ? TYPE_CONTEXT_CONTAINER : TYPE_CONTEXT_CONTAINER_NO_POINTERS, tfsoff);
+ }
+
+ static void process_tfs_iface(type_t *iface, FILE *file, int indent, unsigned int *offset)
+@@ -3693,21 +3720,21 @@ static void process_tfs_iface(type_t *iface, FILE *file, int indent, unsigned in
+ {
+ const var_t *func = stmt->u.var;
+
+- if(stmt->u.var->stgclass != STG_NONE
+- || type_get_type_detect_alias(stmt->u.var->type) != TYPE_FUNCTION)
++ if(stmt->u.var->declspec.stgclass != STG_NONE
++ || type_get_type_detect_alias(stmt->u.var->declspec.type) != TYPE_FUNCTION)
+ continue;
+
+ current_func = func;
+ if (is_local(func->attrs)) continue;
+
+- var = type_function_get_retval(func->type);
+- if (!is_void(var->type))
+- var->typestring_offset = write_type_tfs( file, 2, func->attrs, var->type, func->name,
+- TYPE_CONTEXT_PARAM, offset);
++ var = type_function_get_retval(func->declspec.type);
++ if (!is_void(var->declspec.type))
++ var->typestring_offset = write_type_tfs( file, var->attrs, &var->declspec, func->name,
++ TYPE_CONTEXT_RETVAL, offset);
+
+- if (type_get_function_args(func->type))
+- LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), var_t, entry )
+- var->typestring_offset = write_type_tfs( file, 2, var->attrs, var->type, var->name,
++ if (type_function_get_args(func->declspec.type))
++ LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), var_t, entry )
++ var->typestring_offset = write_type_tfs( file, var->attrs, &var->declspec, var->name,
+ TYPE_CONTEXT_TOPLEVELPARAM, offset );
+ break;
+
+@@ -3719,9 +3746,12 @@ static void process_tfs_iface(type_t *iface, FILE *file, int indent, unsigned in
+ {
+ if (is_attr(type_entry->type->attrs, ATTR_ENCODE)
+ || is_attr(type_entry->type->attrs, ATTR_DECODE))
+- type_entry->type->typestring_offset = write_type_tfs( file, 2,
+- type_entry->type->attrs, type_entry->type, type_entry->type->name,
++ {
++ decl_spec_t ds;
++ type_entry->type->typestring_offset = write_type_tfs( file,
++ type_entry->type->attrs, init_declspec(&ds, type_entry->type), type_entry->type->name,
+ TYPE_CONTEXT_CONTAINER, offset);
++ }
+ }
+ break;
+ }
+@@ -3842,7 +3872,7 @@ static unsigned int get_required_buffer_size_type(
+ case TGT_POINTER:
+ {
+ unsigned int size, align;
+- const type_t *ref = type_pointer_get_ref(type);
++ const type_t *ref = type_pointer_get_ref_type(type);
+ if (is_string_type( attrs, ref )) break;
+ if (!(size = get_required_buffer_size_type( ref, name, NULL, FALSE, &align ))) break;
+ if (get_pointer_fc(type, attrs, toplevel_param) != FC_RP)
+@@ -3862,7 +3892,7 @@ static unsigned int get_required_buffer_size_type(
+ case FC_SMFARRAY:
+ case FC_LGFARRAY:
+ return type_array_get_dim(type) *
+- get_required_buffer_size_type(type_array_get_element(type), name,
++ get_required_buffer_size_type(type_array_get_element_type(type), name,
+ NULL, FALSE, alignment);
+ }
+ }
+@@ -3893,8 +3923,8 @@ static unsigned int get_required_buffer_size(const var_t *var, unsigned int *ali
+ return 20;
+ }
+
+- if (!is_string_type(var->attrs, var->type))
+- return get_required_buffer_size_type(var->type, var->name,
++ if (!is_string_type(var->attrs, var->declspec.type))
++ return get_required_buffer_size_type(var->declspec.type, var->name,
+ var->attrs, TRUE, alignment);
+ }
+ return 0;
+@@ -3905,19 +3935,19 @@ static unsigned int get_function_buffer_size( const var_t *func, enum pass pass
+ const var_t *var;
+ unsigned int total_size = 0, alignment;
+
+- if (type_get_function_args(func->type))
++ if (type_function_get_args(func->declspec.type))
+ {
+- LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
++ LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), const var_t, entry )
+ {
+ total_size += get_required_buffer_size(var, &alignment, pass);
+ total_size += alignment;
+ }
+ }
+
+- if (pass == PASS_OUT && !is_void(type_function_get_rettype(func->type)))
++ if (pass == PASS_OUT && !is_void(type_function_get_rettype(func->declspec.type)))
+ {
+ var_t v = *func;
+- v.type = type_function_get_rettype(func->type);
++ v.declspec.type = type_function_get_rettype(func->declspec.type);
+ total_size += get_required_buffer_size(&v, &alignment, PASS_RETURN);
+ total_size += alignment;
+ }
+@@ -3953,9 +3983,9 @@ static void print_phase_function(FILE *file, int indent, const char *type,
+ print_file(file, indent, "&__frame->_StubMsg,\n");
+ print_file(file, indent, "%s%s%s%s%s,\n",
+ (phase == PHASE_UNMARSHAL) ? "(unsigned char **)" : "(unsigned char *)",
+- (phase == PHASE_UNMARSHAL || decl_indirect(var->type)) ? "&" : "",
++ (phase == PHASE_UNMARSHAL || decl_indirect(var->declspec.type)) ? "&" : "",
+ local_var_prefix,
+- (phase == PHASE_UNMARSHAL && decl_indirect(var->type)) ? "_p_" : "",
++ (phase == PHASE_UNMARSHAL && decl_indirect(var->declspec.type)) ? "_p_" : "",
+ var->name);
+ print_file(file, indent, "(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%d]%s\n",
+ type_offset, (phase == PHASE_UNMARSHAL) ? "," : ");");
+@@ -3968,7 +3998,8 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
+ enum remoting_phase phase, enum pass pass, const var_t *var,
+ const char *varname)
+ {
+- type_t *type = var->type;
++ const decl_spec_t *declspec = &var->declspec;
++ type_t *type = declspec->type;
+ unsigned int alignment = 0;
+
+ /* no work to do for other phases, buffer sizing is done elsewhere */
+@@ -3999,8 +4030,8 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
+ }
+ else
+ {
+- const type_t *ref = is_ptr(type) ? type_pointer_get_ref(type) : type;
+- switch (get_basic_fc(ref))
++ const decl_spec_t *ref = is_ptr(type) ? type_pointer_get_ref(type) : declspec;
++ switch (get_basic_fc(ref->type))
+ {
+ case FC_BYTE:
+ case FC_CHAR:
+@@ -4037,7 +4068,7 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
+
+ default:
+ error("print_phase_basetype: Unsupported type: %s (0x%02x, ptr_level: 0)\n",
+- var->name, get_basic_fc(ref));
++ var->name, get_basic_fc(ref->type));
+ }
+
+ if (phase == PHASE_MARSHAL && alignment > 1)
+@@ -4048,7 +4079,7 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
+ if (phase == PHASE_MARSHAL)
+ {
+ print_file(file, indent, "*(");
+- write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL);
++ write_declspec_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : declspec, NULL);
+ if (is_ptr(type))
+ fprintf(file, " *)__frame->_StubMsg.Buffer = *");
+ else
+@@ -4059,7 +4090,7 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
+ else if (phase == PHASE_UNMARSHAL)
+ {
+ print_file(file, indent, "if (__frame->_StubMsg.Buffer + sizeof(");
+- write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL);
++ write_declspec_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : declspec, NULL);
+ fprintf(file, ") > __frame->_StubMsg.BufferEnd)\n");
+ print_file(file, indent, "{\n");
+ print_file(file, indent + 1, "RpcRaiseException(RPC_X_BAD_STUB_DATA);\n");
+@@ -4071,12 +4102,12 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
+ fprintf(file, " = (");
+ else
+ fprintf(file, " = *(");
+- write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL);
++ write_declspec_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : declspec, NULL);
+ fprintf(file, " *)__frame->_StubMsg.Buffer;\n");
+ }
+
+ print_file(file, indent, "__frame->_StubMsg.Buffer += sizeof(");
+- write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL);
++ write_declspec_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : declspec, NULL);
+ fprintf(file, ");\n");
+ }
+ }
+@@ -4092,7 +4123,7 @@ expr_t *get_size_is_expr(const type_t *t, const char *name)
+ {
+ expr_t *x = NULL;
+
+- for ( ; is_array(t); t = type_array_get_element(t))
++ for ( ; is_array(t); t = type_array_get_element_type(t))
+ if (type_array_has_conformance(t) &&
+ type_array_get_conformance(t)->type != EXPR_VOID)
+ {
+@@ -4110,7 +4141,7 @@ expr_t *get_size_is_expr(const type_t *t, const char *name)
+ void write_parameter_conf_or_var_exprs(FILE *file, int indent, const char *local_var_prefix,
+ enum remoting_phase phase, const var_t *var, int valid_variance)
+ {
+- const type_t *type = var->type;
++ const type_t *type = var->declspec.type;
+ /* get fundamental type for the argument */
+ for (;;)
+ {
+@@ -4162,7 +4193,7 @@ void write_parameter_conf_or_var_exprs(FILE *file, int indent, const char *local
+ break;
+ }
+ case TGT_POINTER:
+- type = type_pointer_get_ref(type);
++ type = type_pointer_get_ref_type(type);
+ continue;
+ case TGT_INVALID:
+ case TGT_USER_TYPE:
+@@ -4184,7 +4215,7 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
+ {
+ int in_attr, out_attr, pointer_type;
+ const char *type_str = NULL;
+- const type_t *type = var->type;
++ const type_t *type = var->declspec.type;
+ unsigned int alignment, start_offset = type->typestring_offset;
+
+ if (is_ptr(type) || is_array(type))
+@@ -4237,19 +4268,20 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
+ print_file(file, indent, "NdrServerContextNewMarshall(\n");
+ print_file(file, indent + 1, "&__frame->_StubMsg,\n");
+ print_file(file, indent + 1, "(NDR_SCONTEXT)%s%s,\n", local_var_prefix, var->name);
+- print_file(file, indent + 1, "(NDR_RUNDOWN)%s_rundown,\n", get_context_handle_type_name(var->type));
++ print_file(file, indent + 1, "(NDR_RUNDOWN)%s_rundown,\n", get_context_handle_type_name(var->declspec.type));
+ print_file(file, indent + 1, "(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%d]);\n", start_offset);
+ }
+ }
+ else if (phase == PHASE_UNMARSHAL)
+ {
+- if (pass == PASS_OUT)
++ if (pass == PASS_OUT || pass == PASS_RETURN)
+ {
+ if (!in_attr)
+ print_file(file, indent, "*%s%s = 0;\n", local_var_prefix, var->name);
+ print_file(file, indent, "NdrClientContextUnmarshall(\n");
+ print_file(file, indent + 1, "&__frame->_StubMsg,\n");
+- print_file(file, indent + 1, "(NDR_CCONTEXT *)%s%s,\n", local_var_prefix, var->name);
++ print_file(file, indent + 1, "(NDR_CCONTEXT *)%s%s%s,\n",
++ pass == PASS_RETURN ? "&" : "", local_var_prefix, var->name);
+ print_file(file, indent + 1, "__frame->_Handle);\n");
+ }
+ else
+@@ -4343,10 +4375,10 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
+ ((tc == FC_SMVARRAY || tc == FC_LGVARRAY) && in_attr) ||
+ (tc == FC_CARRAY && !in_attr))
+ {
+- if (type_array_is_decl_as_ptr(type) && type->details.array.ptr_tfsoff)
++ if (type_array_is_decl_as_ptr(type) && type_get_const_details(type)->array.ptr_tfsoff)
+ {
+ print_phase_function(file, indent, "Pointer", local_var_prefix, phase, var,
+- type->details.array.ptr_tfsoff);
++ type_get_const_details(type)->array.ptr_tfsoff);
+ break;
+ }
+ print_phase_function(file, indent, array_type, local_var_prefix, phase, var, start_offset);
+@@ -4380,9 +4412,9 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
+ range_max = LIST_ENTRY(list_next(range_list, list_head(range_list)), const expr_t, entry);
+
+ print_file(file, indent, "if ((%s%s < (", local_var_prefix, var->name);
+- write_type_decl(file, var->type, NULL);
++ write_declspec_decl(file, &var->declspec, NULL);
+ fprintf(file, ")0x%x) || (%s%s > (", range_min->cval, local_var_prefix, var->name);
+- write_type_decl(file, var->type, NULL);
++ write_declspec_decl(file, &var->declspec, NULL);
+ fprintf(file, ")0x%x))\n", range_max->cval);
+ print_file(file, indent, "{\n");
+ print_file(file, indent+1, "RpcRaiseException(RPC_S_INVALID_BOUND);\n");
+@@ -4428,7 +4460,7 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
+ }
+ case TGT_POINTER:
+ {
+- const type_t *ref = type_pointer_get_ref(type);
++ const type_t *ref = type_pointer_get_ref_type(type);
+ if (pointer_type == FC_RP) switch (typegen_detect_type(ref, NULL, TDT_ALL_TYPES))
+ {
+ case TGT_BASIC:
+@@ -4549,14 +4581,14 @@ void write_remoting_arguments(FILE *file, int indent, const var_t *func, const c
+ if (pass == PASS_RETURN)
+ {
+ write_remoting_arg( file, indent, func, local_var_prefix, pass, phase,
+- type_function_get_retval(func->type) );
++ type_function_get_retval(func->declspec.type) );
+ }
+ else
+ {
+ const var_t *var;
+- if (!type_get_function_args(func->type))
++ if (!type_function_get_args(func->declspec.type))
+ return;
+- LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
++ LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), const var_t, entry )
+ write_remoting_arg( file, indent, func, local_var_prefix, pass, phase, var );
+ }
+ }
+@@ -4597,57 +4629,62 @@ void declare_stub_args( FILE *file, int indent, const var_t *func )
+ {
+ int in_attr, out_attr;
+ int i = 0;
+- const var_t *var = type_function_get_retval(func->type);
++ const var_t *var = type_function_get_retval(func->declspec.type);
+
+ /* declare return value */
+- if (!is_void(var->type))
++ if (!is_void(var->declspec.type))
+ {
+- print_file(file, indent, "%s", "");
+- write_type_decl(file, var->type, var->name);
+- fprintf(file, ";\n");
++ if (is_context_handle(var->declspec.type))
++ print_file(file, indent, "NDR_SCONTEXT %s;\n", var->name);
++ else
++ {
++ print_file(file, indent, "%s", "");
++ write_declspec_decl(file, &var->declspec, var->name);
++ fprintf(file, ";\n");
++ }
+ }
+
+- if (!type_get_function_args(func->type))
++ if (!type_function_get_args(func->declspec.type))
+ return;
+
+- LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
++ LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), const var_t, entry )
+ {
+ in_attr = is_attr(var->attrs, ATTR_IN);
+ out_attr = is_attr(var->attrs, ATTR_OUT);
+ if (!out_attr && !in_attr)
+ in_attr = 1;
+
+- if (is_context_handle(var->type))
++ if (is_context_handle(var->declspec.type))
+ print_file(file, indent, "NDR_SCONTEXT %s;\n", var->name);
+ else
+ {
+- if (!in_attr && !is_conformant_array(var->type))
++ if (!in_attr && !is_conformant_array(var->declspec.type))
+ {
+- type_t *type_to_print;
++ const decl_spec_t *declspec_to_print;
+ char name[16];
+ print_file(file, indent, "%s", "");
+- if (type_get_type(var->type) == TYPE_ARRAY &&
+- !type_array_is_decl_as_ptr(var->type))
+- type_to_print = var->type;
++ if (type_get_type(var->declspec.type) == TYPE_ARRAY &&
++ !type_array_is_decl_as_ptr(var->declspec.type))
++ declspec_to_print = &var->declspec;
+ else
+- type_to_print = type_pointer_get_ref(var->type);
++ declspec_to_print = type_pointer_get_ref(var->declspec.type);
+ sprintf(name, "_W%u", i++);
+- write_type_decl(file, type_to_print, name);
++ write_declspec_decl(file, declspec_to_print, name);
+ fprintf(file, ";\n");
+ }
+
+ print_file(file, indent, "%s", "");
+- write_type_decl_left(file, var->type);
++ write_declspec_decl_left(file, &var->declspec);
+ fprintf(file, " ");
+- if (type_get_type(var->type) == TYPE_ARRAY &&
+- !type_array_is_decl_as_ptr(var->type)) {
++ if (type_get_type(var->declspec.type) == TYPE_ARRAY &&
++ !type_array_is_decl_as_ptr(var->declspec.type)) {
+ fprintf(file, "(*%s)", var->name);
+ } else
+ fprintf(file, "%s", var->name);
+- write_type_right(file, var->type, FALSE);
++ write_type_right(file, var->declspec.type, FALSE);
+ fprintf(file, ";\n");
+
+- if (decl_indirect(var->type))
++ if (decl_indirect(var->declspec.type))
+ print_file(file, indent, "void *_p_%s;\n", var->name);
+ }
+ }
+@@ -4661,10 +4698,10 @@ void assign_stub_out_args( FILE *file, int indent, const var_t *func, const char
+ const var_t *var;
+ type_t *ref;
+
+- if (!type_get_function_args(func->type))
++ if (!type_function_get_args(func->declspec.type))
+ return;
+
+- LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
++ LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), const var_t, entry )
+ {
+ in_attr = is_attr(var->attrs, ATTR_IN);
+ out_attr = is_attr(var->attrs, ATTR_OUT);
+@@ -4675,7 +4712,7 @@ void assign_stub_out_args( FILE *file, int indent, const var_t *func, const char
+ {
+ print_file(file, indent, "%s%s", local_var_prefix, var->name);
+
+- switch (typegen_detect_type(var->type, var->attrs, TDT_IGNORE_STRINGS))
++ switch (typegen_detect_type(var->declspec.type, var->attrs, TDT_IGNORE_STRINGS))
+ {
+ case TGT_CTXT_HANDLE_POINTER:
+ fprintf(file, " = NdrContextHandleInitialize(\n");
+@@ -4684,15 +4721,15 @@ void assign_stub_out_args( FILE *file, int indent, const var_t *func, const char
+ var->typestring_offset);
+ break;
+ case TGT_ARRAY:
+- if (type_array_has_conformance(var->type))
++ if (type_array_has_conformance(var->declspec.type))
+ {
+ unsigned int size;
+ type_t *type;
+
+ fprintf(file, " = NdrAllocate(&__frame->_StubMsg, ");
+- for (type = var->type;
++ for (type = var->declspec.type;
+ is_array(type) && type_array_has_conformance(type);
+- type = type_array_get_element(type))
++ type = type_array_get_element_type(type))
+ {
+ write_expr(file, type_array_get_conformance(type), TRUE,
+ TRUE, NULL, NULL, local_var_prefix);
+@@ -4702,9 +4739,9 @@ void assign_stub_out_args( FILE *file, int indent, const var_t *func, const char
+ fprintf(file, "%u);\n", size);
+
+ print_file(file, indent, "memset(%s%s, 0, ", local_var_prefix, var->name);
+- for (type = var->type;
++ for (type = var->declspec.type;
+ is_array(type) && type_array_has_conformance(type);
+- type = type_array_get_element(type))
++ type = type_array_get_element_type(type))
+ {
+ write_expr(file, type_array_get_conformance(type), TRUE,
+ TRUE, NULL, NULL, local_var_prefix);
+@@ -4718,7 +4755,7 @@ void assign_stub_out_args( FILE *file, int indent, const var_t *func, const char
+ break;
+ case TGT_POINTER:
+ fprintf(file, " = &%s_W%u;\n", local_var_prefix, i);
+- ref = type_pointer_get_ref(var->type);
++ ref = type_pointer_get_ref_type(var->declspec.type);
+ switch (typegen_detect_type(ref, var->attrs, TDT_IGNORE_STRINGS))
+ {
+ case TGT_BASIC:
+@@ -4738,7 +4775,7 @@ void assign_stub_out_args( FILE *file, int indent, const var_t *func, const char
+ print_file(file, indent, "%s_W%u = 0;\n", local_var_prefix, i);
+ break;
+ }
+- ref = type_array_get_element(ref);
++ ref = type_array_get_element_type(ref);
+ /* fall through */
+ case TGT_STRUCT:
+ case TGT_UNION:
+@@ -4771,14 +4808,14 @@ void write_func_param_struct( FILE *file, const type_t *iface, const type_t *fun
+ const char *var_decl, int add_retval )
+ {
+ var_t *retval = type_function_get_retval( func );
+- const var_list_t *args = type_get_function_args( func );
++ const var_list_t *args = type_function_get_args( func );
+ const var_t *arg;
+ int needs_packing;
+ unsigned int align = 0;
+
+ if (args)
+ LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry )
+- if (!is_array( arg->type )) type_memsize_and_alignment( arg->type, &align );
++ if (!is_array( arg->declspec.type )) type_memsize_and_alignment( arg->declspec.type, &align );
+
+ needs_packing = (align > pointer_size);
+
+@@ -4790,26 +4827,26 @@ void write_func_param_struct( FILE *file, const type_t *iface, const type_t *fun
+ if (args) LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry )
+ {
+ print_file(file, 2, "%s", "");
+- write_type_left( file, (type_t *)arg->type, NAME_DEFAULT, TRUE );
+- if (needs_space_after( arg->type )) fputc( ' ', file );
+- if (is_array( arg->type ) && !type_array_is_decl_as_ptr( arg->type )) fputc( '*', file );
++ write_declspec_left( file, &arg->declspec, NAME_DEFAULT, TRUE );
++ if (needs_space_after( arg->declspec.type )) fputc( ' ', file );
++ if (is_array( arg->declspec.type ) && !type_array_is_decl_as_ptr( arg->declspec.type )) fputc( '*', file );
+
+ /* FIXME: should check for large args being passed by pointer */
+ align = 0;
+- if (is_array( arg->type ) || is_ptr( arg->type )) align = pointer_size;
+- else type_memsize_and_alignment( arg->type, &align );
++ if (is_array( arg->declspec.type ) || is_ptr( arg->declspec.type )) align = pointer_size;
++ else type_memsize_and_alignment( arg->declspec.type, &align );
+
+ if (align >= pointer_size)
+ fprintf( file, "%s;\n", arg->name );
+ else
+ fprintf( file, "%s DECLSPEC_ALIGN(%u);\n", arg->name, pointer_size );
+ }
+- if (add_retval && !is_void( retval->type ))
++ if (add_retval && !is_void( retval->declspec.type ))
+ {
+ print_file(file, 2, "%s", "");
+- write_type_decl( file, retval->type, retval->name );
+- if (is_array( retval->type ) || is_ptr( retval->type ) ||
+- type_memsize( retval->type ) == pointer_size)
++ write_declspec_decl( file, &retval->declspec, retval->name );
++ if (is_array( retval->declspec.type ) || is_ptr( retval->declspec.type ) ||
++ type_memsize( retval->declspec.type ) == pointer_size)
+ fprintf( file, ";\n" );
+ else
+ fprintf( file, " DECLSPEC_ALIGN(%u);\n", pointer_size );
+@@ -4821,7 +4858,7 @@ void write_func_param_struct( FILE *file, const type_t *iface, const type_t *fun
+
+ void write_pointer_checks( FILE *file, int indent, const var_t *func )
+ {
+- const var_list_t *args = type_get_function_args( func->type );
++ const var_list_t *args = type_function_get_args( func->declspec.type );
+ const var_t *var;
+
+ if (!args) return;
+@@ -4854,10 +4891,11 @@ int write_expr_eval_routines(FILE *file, const char *iface)
+ }
+ else
+ {
++ decl_spec_t declspec;
+ print_file(file, 1, "%s", "");
+- write_type_left(file, (type_t *)eval->cont_type, NAME_DEFAULT, TRUE);
++ write_declspec_left(file, init_declspec(&declspec, (type_t*)eval->cont_type), NAME_DEFAULT, TRUE);
+ fprintf(file, " *%s = (", var_name);
+- write_type_left(file, (type_t *)eval->cont_type, NAME_DEFAULT, TRUE);
++ write_declspec_left(file, init_declspec(&declspec, (type_t*)eval->cont_type), NAME_DEFAULT, TRUE);
+ fprintf(file, " *)(pStubMsg->StackTop - %u);\n", eval->baseoff);
+ }
+ print_file(file, 1, "pStubMsg->Offset = 0;\n"); /* FIXME */
+@@ -4951,9 +4989,10 @@ error:
+ void write_client_call_routine( FILE *file, const type_t *iface, const var_t *func,
+ const char *prefix, unsigned int proc_offset )
+ {
+- type_t *rettype = type_function_get_rettype( func->type );
++ const decl_spec_t *retdeclspec = type_function_get_retdeclspec(func->declspec.type);
++ type_t *rettype = retdeclspec->type;
+ int has_ret = !is_void( rettype );
+- const var_list_t *args = type_get_function_args( func->type );
++ const var_list_t *args = type_function_get_args( func->declspec.type );
+ const var_t *arg;
+ int len, needs_params = 0;
+
+@@ -4964,7 +5003,7 @@ void write_client_call_routine( FILE *file, const type_t *iface, const var_t *fu
+ if (needs_params)
+ {
+ if (has_ret) print_file( file, 1, "%s", "CLIENT_CALL_RETURN _RetVal;\n" );
+- write_func_param_struct( file, iface, func->type, "__params", FALSE );
++ write_func_param_struct( file, iface, func->declspec.type, "__params", FALSE );
+ if (is_object( iface )) print_file( file, 1, "__params.This = This;\n" );
+ if (args)
+ LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry )
+@@ -5001,7 +5040,7 @@ void write_client_call_routine( FILE *file, const type_t *iface, const var_t *fu
+ if (has_ret)
+ {
+ print_file( file, 1, "return (" );
+- write_type_decl_left(file, rettype);
++ write_declspec_decl_left(file, retdeclspec);
+ fprintf( file, ")%s;\n", pointer_size == 8 ? "_RetVal.Simple" : "*(LONG_PTR *)&_RetVal" );
+ }
+ print_file( file, 0, "}\n\n");
+@@ -5029,7 +5068,7 @@ void write_exceptions( FILE *file )
+ fprintf( file, " EXCEPTION_REGISTRATION_RECORD frame; \\\n");
+ fprintf( file, " __filter_func filter; \\\n");
+ fprintf( file, " __finally_func finally; \\\n");
+- fprintf( file, " sigjmp_buf jmp; \\\n");
++ fprintf( file, " __wine_jmp_buf jmp; \\\n");
+ fprintf( file, " DWORD code; \\\n");
+ fprintf( file, " unsigned char abnormal_termination; \\\n");
+ fprintf( file, " unsigned char filter_level; \\\n");
+@@ -5049,13 +5088,13 @@ void write_exceptions( FILE *file )
+ fprintf( file, " __wine_pop_frame( &exc_frame->frame );\n");
+ fprintf( file, " }\n");
+ fprintf( file, " exc_frame->filter_level = 0;\n");
+- fprintf( file, " siglongjmp( exc_frame->jmp, 1 );\n");
++ fprintf( file, " __wine_longjmp( &exc_frame->jmp, 1 );\n");
+ fprintf( file, "}\n");
+ fprintf( file, "\n");
+- fprintf( file, "static DWORD __widl_exception_handler( EXCEPTION_RECORD *record,\n");
+- fprintf( file, " EXCEPTION_REGISTRATION_RECORD *frame,\n");
+- fprintf( file, " CONTEXT *context,\n");
+- fprintf( file, " EXCEPTION_REGISTRATION_RECORD **pdispatcher )\n");
++ fprintf( file, "static DWORD __cdecl __widl_exception_handler( EXCEPTION_RECORD *record,\n");
++ fprintf( file, " EXCEPTION_REGISTRATION_RECORD *frame,\n");
++ fprintf( file, " CONTEXT *context,\n");
++ fprintf( file, " EXCEPTION_REGISTRATION_RECORD **pdispatcher )\n");
+ fprintf( file, "{\n");
+ fprintf( file, " struct __exception_frame *exc_frame = (struct __exception_frame *)frame;\n");
+ fprintf( file, "\n");
+@@ -5075,7 +5114,7 @@ void write_exceptions( FILE *file )
+ fprintf( file, "}\n");
+ fprintf( file, "\n");
+ fprintf( file, "#define RpcTryExcept \\\n");
+- fprintf( file, " if (!sigsetjmp( __frame->jmp, 0 )) \\\n");
++ fprintf( file, " if (!__wine_setjmpex( &__frame->jmp, &__frame->frame )) \\\n");
+ fprintf( file, " { \\\n");
+ fprintf( file, " if (!__frame->finally_level) \\\n" );
+ fprintf( file, " __wine_push_frame( &__frame->frame ); \\\n");
+diff --git a/mingw-w64-tools/widl/src/typelib.c b/mingw-w64-tools/widl/src/typelib.c
+index 9b1de2c8..2c2b1276 100644
+--- a/mingw-w64-tools/widl/src/typelib.c
++++ b/mingw-w64-tools/widl/src/typelib.c
+@@ -97,9 +97,9 @@ static unsigned short builtin_vt(const type_t *t)
+ {
+ const type_t *elem_type;
+ if (is_array(t))
+- elem_type = type_array_get_element(t);
++ elem_type = type_array_get_element_type(t);
+ else
+- elem_type = type_pointer_get_ref(t);
++ elem_type = type_pointer_get_ref_type(t);
+ if (type_get_type(elem_type) == TYPE_BASIC)
+ {
+ switch (type_basic_get_type(elem_type))
+@@ -129,7 +129,8 @@ unsigned short get_type_vt(type_t *t)
+ if (vt) return vt;
+ }
+
+- if (type_is_alias(t) && is_attr(t->attrs, ATTR_PUBLIC))
++ if (type_is_alias(t) &&
++ (is_attr(t->attrs, ATTR_PUBLIC) || is_attr(t->attrs, ATTR_WIREMARSHAL)))
+ return VT_USERDEFINED;
+
+ switch (type_get_type(t)) {
+@@ -169,7 +170,7 @@ unsigned short get_type_vt(type_t *t)
+ else
+ return VT_I8;
+ case TYPE_BASIC_INT3264:
+- if (typelib_kind == SYS_WIN64)
++ if (pointer_size == 8)
+ {
+ if (type_basic_get_sign(t) > 0)
+ return VT_UI8;
+@@ -198,7 +199,7 @@ unsigned short get_type_vt(type_t *t)
+ case TYPE_ARRAY:
+ if (type_array_is_decl_as_ptr(t))
+ {
+- if (match(type_array_get_element(t)->name, "SAFEARRAY"))
++ if (match(type_array_get_element_type(t)->name, "SAFEARRAY"))
+ return VT_SAFEARRAY;
+ return VT_PTR;
+ }
+diff --git a/mingw-w64-tools/widl/src/typetree.c b/mingw-w64-tools/widl/src/typetree.c
+index b93806be..f52b785f 100644
+--- a/mingw-w64-tools/widl/src/typetree.c
++++ b/mingw-w64-tools/widl/src/typetree.c
+@@ -30,12 +30,16 @@
+ #include "typetree.h"
+ #include "header.h"
+
+-type_t *duptype(type_t *t, int dupname)
++/* this function is only used in declare_var in parser.y, see FIXME note */
++type_t *dup_pointer_type(type_t *t)
+ {
+- type_t *d = alloc_type();
++ type_t *d;
+
++ assert(is_ptr(t) && t->details.pointer.def_fc != FC_RP);
++
++ d = alloc_type();
+ *d = *t;
+- if (dupname && t->name)
++ if (t->name)
+ d->name = xstrdup(t->name);
+
+ return d;
+@@ -49,7 +53,6 @@ type_t *make_type(enum type_type type)
+ t->type_type = type;
+ t->attrs = NULL;
+ t->c_name = NULL;
+- t->orig = NULL;
+ memset(&t->details, 0, sizeof(t->details));
+ t->typestring_offset = 0;
+ t->ptrdesc = 0;
+@@ -137,7 +140,7 @@ type_t *type_new_function(var_list_t *args)
+ if (args)
+ {
+ arg = LIST_ENTRY(list_head(args), var_t, entry);
+- if (list_count(args) == 1 && !arg->name && arg->type && type_get_type(arg->type) == TYPE_VOID)
++ if (list_count(args) == 1 && !arg->name && arg->declspec.type && type_get_type(arg->declspec.type) == TYPE_VOID)
+ {
+ list_remove(&arg->entry);
+ free(arg);
+@@ -147,7 +150,7 @@ type_t *type_new_function(var_list_t *args)
+ }
+ if (args) LIST_FOR_EACH_ENTRY(arg, args, var_t, entry)
+ {
+- if (arg->type && type_get_type(arg->type) == TYPE_VOID)
++ if (arg->declspec.type && type_get_type(arg->declspec.type) == TYPE_VOID)
+ error_loc("argument '%s' has void type\n", arg->name);
+ if (!arg->name)
+ {
+@@ -178,35 +181,29 @@ type_t *type_new_function(var_list_t *args)
+ return t;
+ }
+
+-type_t *type_new_pointer(unsigned char pointer_default, type_t *ref, attr_list_t *attrs)
++type_t *type_new_pointer(unsigned char pointer_default, type_t *ref)
+ {
+ type_t *t = make_type(TYPE_POINTER);
+ t->details.pointer.def_fc = pointer_default;
+- t->details.pointer.ref = ref;
+- t->attrs = attrs;
++ t->details.pointer.ref.type = ref;
+ return t;
+ }
+
+-type_t *type_new_alias(type_t *t, const char *name)
++type_t *type_new_alias(const decl_spec_t *ds, const char *name)
+ {
+- type_t *a = duptype(t, 0);
+-
++ type_t *a = make_type(ds->type->type_type);
+ a->name = xstrdup(name);
+ a->attrs = NULL;
+- a->orig = t;
++ a->details.alias.aliasee = *ds;
+ a->is_alias = TRUE;
+- /* for pointer types */
+- a->details = t->details;
+- init_loc_info(&a->loc_info);
+-
+ return a;
+ }
+
+ type_t *type_new_module(char *name)
+ {
+ type_t *type = get_type(TYPE_MODULE, name, NULL, 0);
+- if (type->type_type != TYPE_MODULE || type->defined)
+- error_loc("%s: redefinition error; original definition was at %s:%d\n",
++ if (type->type_type != TYPE_MODULE || type_is_defined(type))
++ error_loc("BAZ %s: redefinition error; original definition was at %s:%d\n",
+ type->name, type->loc_info.input_name, type->loc_info.line_number);
+ type->name = name;
+ return type;
+@@ -215,15 +212,15 @@ type_t *type_new_module(char *name)
+ type_t *type_new_coclass(char *name)
+ {
+ type_t *type = get_type(TYPE_COCLASS, name, NULL, 0);
+- if (type->type_type != TYPE_COCLASS || type->defined)
+- error_loc("%s: redefinition error; original definition was at %s:%d\n",
++ if (type->type_type != TYPE_COCLASS || type_is_defined(type))
++ error_loc("BING %s: redefinition error; original definition was at %s:%d\n",
+ type->name, type->loc_info.input_name, type->loc_info.line_number);
+ type->name = name;
+ return type;
+ }
+
+
+-type_t *type_new_array(const char *name, type_t *element, int declptr,
++type_t *type_new_array(const char *name, const decl_spec_t *element, int declptr,
+ unsigned int dim, expr_t *size_is, expr_t *length_is,
+ unsigned char ptr_default_fc)
+ {
+@@ -235,7 +232,9 @@ type_t *type_new_array(const char *name, type_t *element, int declptr,
+ t->details.array.size_is = size_is;
+ else
+ t->details.array.dim = dim;
+- t->details.array.elem = element;
++ if (element) {
++ t->details.array.elem = *element;
++ }
+ t->details.array.ptr_def_fc = ptr_default_fc;
+ return t;
+ }
+@@ -273,80 +272,99 @@ type_t *type_new_void(void)
+
+ type_t *type_new_enum(const char *name, struct namespace *namespace, int defined, var_list_t *enums)
+ {
+- type_t *tag_type = name ? find_type(name, namespace, tsENUM) : NULL;
+- type_t *t = make_type(TYPE_ENUM);
+- t->name = name;
+- t->namespace = namespace;
+-
+- if (tag_type && tag_type->details.enumeration)
+- t->details.enumeration = tag_type->details.enumeration;
+- else if (defined)
++ type_t *t = NULL;
++
++ if (name)
++ t = find_type(name, namespace, tsENUM);
++
++ if (!t)
+ {
+- t->details.enumeration = xmalloc(sizeof(*t->details.enumeration));
+- t->details.enumeration->enums = enums;
+- t->defined = TRUE;
++ t = make_type(TYPE_ENUM);
++ t->name = name;
++ t->namespace = namespace;
++ if (name)
++ reg_type(t, name, namespace, tsENUM);
+ }
+
+- if (name)
++ if (!type_is_defined(t))
+ {
+ if (defined)
+- reg_type(t, name, namespace, tsENUM);
++ {
++ t->details.enumeration = xmalloc(sizeof(*t->details.enumeration));
++ t->details.enumeration->enums = enums;
++ t->defined = TRUE;
++ }
+ else
++ {
+ add_incomplete(t);
++ }
+ }
++
+ return t;
+ }
+
+ type_t *type_new_struct(char *name, struct namespace *namespace, int defined, var_list_t *fields)
+ {
+- type_t *tag_type = name ? find_type(name, namespace, tsSTRUCT) : NULL;
+- type_t *t;
+-
+- /* avoid creating duplicate typelib type entries */
+- if (tag_type && do_typelib) return tag_type;
++ type_t *t = NULL;
+
+- t = make_type(TYPE_STRUCT);
+- t->name = name;
+- t->namespace = namespace;
++ if (name)
++ t = find_type(name, namespace, tsSTRUCT);
+
+- if (tag_type && tag_type->details.structure)
+- t->details.structure = tag_type->details.structure;
+- else if (defined)
++ if (!t)
+ {
+- t->details.structure = xmalloc(sizeof(*t->details.structure));
+- t->details.structure->fields = fields;
+- t->defined = TRUE;
++ t = make_type(TYPE_STRUCT);
++ t->name = name;
++ t->namespace = namespace;
++ if (name)
++ reg_type(t, name, namespace, tsSTRUCT);
+ }
+- if (name)
++
++ if (!type_is_defined(t))
+ {
+ if (defined)
+- reg_type(t, name, namespace, tsSTRUCT);
++ {
++ t->details.structure = xmalloc(sizeof(*t->details.structure));
++ t->details.structure->fields = fields;
++ t->defined = TRUE;
++ }
+ else
++ {
+ add_incomplete(t);
++ }
+ }
++
+ return t;
+ }
+
+ type_t *type_new_nonencapsulated_union(const char *name, int defined, var_list_t *fields)
+ {
+- type_t *tag_type = name ? find_type(name, NULL, tsUNION) : NULL;
+- type_t *t = make_type(TYPE_UNION);
+- t->name = name;
+- if (tag_type && tag_type->details.structure)
+- t->details.structure = tag_type->details.structure;
+- else if (defined)
++ type_t *t = NULL;
++
++ if (name)
++ t = find_type(name, NULL, tsUNION);
++
++ if (!t)
+ {
+- t->details.structure = xmalloc(sizeof(*t->details.structure));
+- t->details.structure->fields = fields;
+- t->defined = TRUE;
++ t = make_type(TYPE_UNION);
++ t->name = name;
++ if (name)
++ reg_type(t, name, NULL, tsUNION);
+ }
+- if (name)
++
++ if (!type_is_defined(t))
+ {
+ if (defined)
+- reg_type(t, name, NULL, tsUNION);
++ {
++ t->details.structure = xmalloc(sizeof(*t->details.structure));
++ t->details.structure->fields = fields;
++ t->defined = TRUE;
++ }
+ else
++ {
+ add_incomplete(t);
++ }
+ }
++
+ return t;
+ }
+
+@@ -354,7 +372,7 @@ type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *unio
+ {
+ type_t *t = get_type(TYPE_ENCAPSULATED_UNION, name, NULL, tsUNION);
+ if (!union_field) union_field = make_var( xstrdup("tagged_union") );
+- union_field->type = type_new_nonencapsulated_union(NULL, TRUE, cases);
++ union_field->declspec.type = type_new_nonencapsulated_union(NULL, TRUE, cases);
+ t->details.structure = xmalloc(sizeof(*t->details.structure));
+ t->details.structure->fields = append_var( NULL, switch_field );
+ t->details.structure->fields = append_var( t->details.structure->fields, union_field );
+@@ -430,7 +448,7 @@ static int compute_method_indexes(type_t *iface)
+ {
+ var_t *func = stmt->u.var;
+ if (!is_callas(func->attrs))
+- func->type->details.function->idx = idx++;
++ func->declspec.type->details.function->idx = idx++;
+ }
+
+ return idx;
+@@ -438,6 +456,7 @@ static int compute_method_indexes(type_t *iface)
+
+ void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts)
+ {
++ assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
+ iface->details.iface = xmalloc(sizeof(*iface->details.iface));
+ iface->details.iface->disp_props = NULL;
+ iface->details.iface->disp_methods = NULL;
+@@ -451,6 +470,7 @@ void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stm
+
+ void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *methods)
+ {
++ assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
+ iface->details.iface = xmalloc(sizeof(*iface->details.iface));
+ iface->details.iface->disp_props = props;
+ iface->details.iface->disp_methods = methods;
+@@ -465,6 +485,7 @@ void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *met
+
+ void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface)
+ {
++ assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
+ dispiface->details.iface = xmalloc(sizeof(*dispiface->details.iface));
+ dispiface->details.iface->disp_props = NULL;
+ dispiface->details.iface->disp_methods = NULL;
+@@ -479,6 +500,7 @@ void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface)
+
+ void type_module_define(type_t *module, statement_list_t *stmts)
+ {
++ assert(type_get_type_detect_alias(module) == TYPE_MODULE);
+ if (module->details.module) error_loc("multiple definition error\n");
+ module->details.module = xmalloc(sizeof(*module->details.module));
+ module->details.module->stmts = stmts;
+@@ -487,6 +509,7 @@ void type_module_define(type_t *module, statement_list_t *stmts)
+
+ type_t *type_coclass_define(type_t *coclass, ifref_list_t *ifaces)
+ {
++ assert(type_get_type_detect_alias(coclass) == TYPE_COCLASS);
+ coclass->details.coclass.ifaces = ifaces;
+ coclass->defined = TRUE;
+ return coclass;
+diff --git a/mingw-w64-tools/widl/src/typetree.h b/mingw-w64-tools/widl/src/typetree.h
+index fc134cd5..96fcae8d 100644
+--- a/mingw-w64-tools/widl/src/typetree.h
++++ b/mingw-w64-tools/widl/src/typetree.h
+@@ -30,10 +30,10 @@ enum name_type {
+ };
+
+ type_t *type_new_function(var_list_t *args);
+-type_t *type_new_pointer(unsigned char pointer_default, type_t *ref, attr_list_t *attrs);
+-type_t *type_new_alias(type_t *t, const char *name);
++type_t *type_new_pointer(unsigned char pointer_default, type_t *ref);
++type_t *type_new_alias(const decl_spec_t *aliasee, const char *name);
+ type_t *type_new_module(char *name);
+-type_t *type_new_array(const char *name, type_t *element, int declptr,
++type_t *type_new_array(const char* name, const decl_spec_t *element, int declptr,
+ unsigned int dim, expr_t *size_is, expr_t *length_is,
+ unsigned char ptr_default_fc);
+ type_t *type_new_basic(enum type_basic_type basic_type);
+@@ -53,14 +53,38 @@ type_t *type_coclass_define(type_t *coclass, ifref_list_t *ifaces);
+ int type_is_equal(const type_t *type1, const type_t *type2);
+ const char *type_get_name(const type_t *type, enum name_type name_type);
+
+-/* FIXME: shouldn't need to export this */
+-type_t *duptype(type_t *t, int dupname);
++/* copy pointer type to deal with need for duplicate typeformat strings */
++type_t *dup_pointer_type(type_t *t);
++
++#define STATEMENTS_FOR_EACH_FUNC(stmt, stmts) \
++ if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, statement_t, entry ) \
++ if (stmt->type == STMT_DECLARATION && stmt->u.var->declspec.stgclass == STG_NONE && \
++ type_get_type_detect_alias(stmt->u.var->declspec.type) == TYPE_FUNCTION)
++
++static inline enum type_type type_get_type_detect_alias(const type_t *type)
++{
++ if (type->is_alias)
++ return TYPE_ALIAS;
++ return type->type_type;
++}
++
++static inline int statements_has_func(const statement_list_t *stmts)
++{
++ const statement_t *stmt;
++ int has_func = 0;
++ STATEMENTS_FOR_EACH_FUNC(stmt, stmts)
++ {
++ has_func = 1;
++ break;
++ }
++ return has_func;
++}
+
+ /* un-alias the type until finding the non-alias type */
+ static inline type_t *type_get_real_type(const type_t *type)
+ {
+ if (type->is_alias)
+- return type_get_real_type(type->orig);
++ return type_get_real_type(type->details.alias.aliasee.type);
+ else
+ return (type_t *)type;
+ }
+@@ -105,9 +129,14 @@ static inline var_t *type_function_get_retval(const type_t *type)
+ return type->details.function->retval;
+ }
+
++static inline const decl_spec_t *type_function_get_retdeclspec(const type_t *type)
++{
++ return &type_function_get_retval(type)->declspec;
++}
++
+ static inline type_t *type_function_get_rettype(const type_t *type)
+ {
+- return type_function_get_retval(type)->type;
++ return type_function_get_retdeclspec(type)->type;
+ }
+
+ static inline var_list_t *type_enum_get_values(const type_t *type)
+@@ -142,7 +171,7 @@ static inline var_list_t *type_union_get_cases(const type_t *type)
+ if (type_type == TYPE_ENCAPSULATED_UNION)
+ {
+ const var_t *uv = LIST_ENTRY(list_tail(type->details.structure->fields), const var_t, entry);
+- return uv->type->details.structure->fields;
++ return uv->declspec.type->details.structure->fields;
+ }
+ else
+ return type->details.structure->fields;
+@@ -250,11 +279,16 @@ static inline expr_t *type_array_get_variance(const type_t *type)
+ return type->details.array.length_is;
+ }
+
+-static inline type_t *type_array_get_element(const type_t *type)
++static inline const decl_spec_t *type_array_get_element(const type_t *type)
+ {
+ type = type_get_real_type(type);
+ assert(type_get_type(type) == TYPE_ARRAY);
+- return type->details.array.elem;
++ return &type->details.array.elem;
++}
++
++static inline type_t *type_array_get_element_type(const type_t *type)
++{
++ return type_array_get_element(type)->type;
+ }
+
+ static inline int type_array_is_decl_as_ptr(const type_t *type)
+@@ -276,10 +310,15 @@ static inline int type_is_alias(const type_t *type)
+ return type->is_alias;
+ }
+
+-static inline type_t *type_alias_get_aliasee(const type_t *type)
++static inline const decl_spec_t *type_alias_get_aliasee(const type_t *type)
+ {
+ assert(type_is_alias(type));
+- return type->orig;
++ return &type->details.alias.aliasee;
++}
++
++static inline type_t *type_alias_get_aliasee_type(const type_t *type)
++{
++ return type_alias_get_aliasee(type)->type;
+ }
+
+ static inline ifref_list_t *type_coclass_get_ifaces(const type_t *type)
+@@ -289,11 +328,16 @@ static inline ifref_list_t *type_coclass_get_ifaces(const type_t *type)
+ return type->details.coclass.ifaces;
+ }
+
+-static inline type_t *type_pointer_get_ref(const type_t *type)
++static inline const decl_spec_t *type_pointer_get_ref(const type_t *type)
+ {
+ type = type_get_real_type(type);
+ assert(type_get_type(type) == TYPE_POINTER);
+- return type->details.pointer.ref;
++ return &type->details.pointer.ref;
++}
++
++static inline type_t *type_pointer_get_ref_type(const type_t *type)
++{
++ return type_pointer_get_ref(type)->type;
+ }
+
+ static inline unsigned char type_pointer_get_default_fc(const type_t *type)
+@@ -317,4 +361,54 @@ static inline const expr_t *type_bitfield_get_bits(const type_t *type)
+ return type->details.bitfield.bits;
+ }
+
++/* gets pointer to details_t union with the assumption the caller wants to write to it
++ * so assert if we're actually dealing with an alias and writing to the details would
++ * overwrite the alias_details
++ */
++static inline details_t *type_get_details(type_t* type)
++{
++ assert(!type_is_alias(type));
++ return &type->details;
++}
++
++/* const overload of type_get_details */
++
++static inline const details_t *type_get_const_details(const type_t* type)
++{
++ assert(!type_is_alias(type));
++ return &type->details;
++}
++
++static inline int type_is_pointerish(const type_t *type)
++{
++ type = type_get_real_type(type);
++ return type_get_type(type) == TYPE_ARRAY || type_get_type(type) == TYPE_POINTER;
++}
++
++static inline type_t * type_get_pointer_chain_tail(const type_t *type)
++{
++ type_t *pointee = NULL;
++ type_t *pointer = type_get_real_type(type);
++
++ if (type_get_type(pointer) == TYPE_ARRAY)
++ {
++ pointee = type_array_get_element_type(pointer);
++ }
++ else if (type_get_type(pointer) == TYPE_POINTER)
++ {
++ pointee = type_pointer_get_ref_type(pointer);
++ }
++ else
++ {
++ assert(FALSE);
++ }
++
++ if (type_is_pointerish(pointee))
++ {
++ return type_get_pointer_chain_tail(pointee);
++ }
++
++ return pointee;
++}
++
+ #endif /* WIDL_TYPE_TREE_H */
+diff --git a/mingw-w64-tools/widl/src/widl.c b/mingw-w64-tools/widl/src/widl.c
+index 1af42509..8542e518 100644
+--- a/mingw-w64-tools/widl/src/widl.c
++++ b/mingw-w64-tools/widl/src/widl.c
+@@ -44,11 +44,6 @@
+ #include "header.h"
+ #include "pathtools.h"
+
+-/* future options to reserve characters for: */
+-/* A = ACF input filename */
+-/* J = do not search standard include path */
+-/* w = select win16/win32 output (?) */
+-
+ static const char usage[] =
+ "Usage: widl [options...] infile.idl\n"
+ " or: widl [options...] --dlldata-only name1 [name2...]\n"
+@@ -64,7 +59,7 @@ static const char usage[] =
+ " -H file Name of header file (default is infile.h)\n"
+ " -I path Set include search dir to path (multiple -I allowed)\n"
+ " --local-stubs=file Write empty stubs for call_as/local methods to file\n"
+-" -m32, -m64 Set the kind of typelib to build (Win32 or Win64)\n"
++" -m32, -m64 Set the target architecture (Win32 or Win64)\n"
+ " -N Do not preprocess input\n"
+ " --oldnames Use old naming conventions\n"
+ " -o, --output=NAME Set the output file name\n"
+@@ -82,8 +77,7 @@ static const char usage[] =
+ " -u Generate interface identifiers file\n"
+ " -V Print version and exit\n"
+ " -W Enable pedantic warnings\n"
+-" --win32 Only generate 32-bit code\n"
+-" --win64 Only generate 64-bit code\n"
++" --win32, --win64 Set the target architecture (Win32 or Win64)\n"
+ " --win32-align n Set win32 structure alignment to 'n'\n"
+ " --win64-align n Set win64 structure alignment to 'n'\n"
+ "Debug level 'n' is a bitmask with following meaning:\n"
+@@ -98,6 +92,20 @@ static const char usage[] =
+ static const char version_string[] = "Wine IDL Compiler version " PACKAGE_VERSION "\n"
+ "Copyright 2002 Ove Kaaven\n";
+
++#ifdef __i386__
++enum target_cpu target_cpu = CPU_x86;
++#elif defined(__x86_64__)
++enum target_cpu target_cpu = CPU_x86_64;
++#elif defined(__powerpc__)
++enum target_cpu target_cpu = CPU_POWERPC;
++#elif defined(__arm__)
++enum target_cpu target_cpu = CPU_ARM;
++#elif defined(__aarch64__)
++enum target_cpu target_cpu = CPU_ARM64;
++#else
++#error Unsupported CPU
++#endif
++
+ int debuglevel = DEBUGLEVEL_NONE;
+ int parser_debug, yy_flex_debug;
+
+@@ -114,8 +122,6 @@ int do_idfile = 0;
+ int do_dlldata = 0;
+ static int no_preprocess = 0;
+ int old_names = 0;
+-int do_win32 = 1;
+-int do_win64 = 1;
+ int win32_packing = 8;
+ int win64_packing = 8;
+ int winrt_mode = 0;
+@@ -148,7 +154,6 @@ int line_number = 1;
+ static FILE *idfile;
+
+ unsigned int pointer_size = 0;
+-syskind_t typelib_kind = sizeof(void*) == 8 ? SYS_WIN64 : SYS_WIN32;
+
+ time_t now;
+
+@@ -188,6 +193,7 @@ static const struct option long_options[] = {
+ { "prefix-client", 1, NULL, PREFIX_CLIENT_OPTION },
+ { "prefix-server", 1, NULL, PREFIX_SERVER_OPTION },
+ { "robust", 0, NULL, ROBUST_OPTION },
++ { "target", 0, NULL, 'b' },
+ { "winrt", 0, NULL, RT_OPTION },
+ { "win32", 0, NULL, WIN32_OPTION },
+ { "win64", 0, NULL, WIN64_OPTION },
+@@ -269,20 +275,25 @@ static void set_target( const char *target )
+ {
+ static const struct
+ {
+- const char *name;
+- syskind_t kind;
++ const char *name;
++ enum target_cpu cpu;
+ } cpu_names[] =
+ {
+- { "i386", SYS_WIN32 },
+- { "i486", SYS_WIN32 },
+- { "i586", SYS_WIN32 },
+- { "i686", SYS_WIN32 },
+- { "i786", SYS_WIN32 },
+- { "amd64", SYS_WIN64 },
+- { "x86_64", SYS_WIN64 },
+- { "powerpc", SYS_WIN32 },
+- { "arm", SYS_WIN32 },
+- { "aarch64", SYS_WIN64 }
++ { "i386", CPU_x86 },
++ { "i486", CPU_x86 },
++ { "i586", CPU_x86 },
++ { "i686", CPU_x86 },
++ { "i786", CPU_x86 },
++ { "amd64", CPU_x86_64 },
++ { "x86_64", CPU_x86_64 },
++ { "powerpc", CPU_POWERPC },
++ { "arm", CPU_ARM },
++ { "armv5", CPU_ARM },
++ { "armv6", CPU_ARM },
++ { "armv7", CPU_ARM },
++ { "armv7a", CPU_ARM },
++ { "arm64", CPU_ARM64 },
++ { "aarch64", CPU_ARM64 },
+ };
+
+ unsigned int i;
+@@ -296,7 +307,7 @@ static void set_target( const char *target )
+ {
+ if (!strcmp( cpu_names[i].name, spec ))
+ {
+- typelib_kind = cpu_names[i].kind;
++ target_cpu = cpu_names[i].cpu;
+ free( spec );
+ return;
+ }
+@@ -484,6 +495,7 @@ static void write_id_data_stmts(const statement_list_t *stmts)
+ uuid = get_attrp(type->attrs, ATTR_UUID);
+ write_id_guid(idfile, "IID", is_attr(type->attrs, ATTR_DISPINTERFACE) ? "DIID" : "IID",
+ type->name, uuid);
++ assert(type_get_type_detect_alias(type) == TYPE_INTERFACE);
+ if (type->details.iface->async_iface)
+ {
+ uuid = get_attrp(type->details.iface->async_iface->attrs, ATTR_UUID);
+@@ -606,12 +618,10 @@ int main(int argc,char *argv[])
+ use_abi_namespace = 1;
+ break;
+ case WIN32_OPTION:
+- do_win32 = 1;
+- do_win64 = 0;
++ pointer_size = 4;
+ break;
+ case WIN64_OPTION:
+- do_win32 = 0;
+- do_win64 = 1;
++ pointer_size = 8;
+ break;
+ case WIN32_ALIGN_OPTION:
+ win32_packing = strtol(optarg, NULL, 0);
+@@ -664,8 +674,8 @@ int main(int argc,char *argv[])
+ wpp_add_include_path(optarg);
+ break;
+ case 'm':
+- if (!strcmp( optarg, "32" )) typelib_kind = SYS_WIN32;
+- else if (!strcmp( optarg, "64" )) typelib_kind = SYS_WIN64;
++ if (!strcmp( optarg, "32" )) pointer_size = 4;
++ else if (!strcmp( optarg, "64" )) pointer_size = 8;
+ break;
+ case 'N':
+ no_preprocess = 1;
+@@ -726,6 +736,7 @@ int main(int argc,char *argv[])
+ }
+
+ #ifdef DEFAULT_INCLUDE_DIR
++ wpp_add_include_path(DEFAULT_INCLUDE_DIR);
+ char exe_path[PATH_MAX];
+ get_executable_path (argv[0], &exe_path[0], sizeof (exe_path) / sizeof (exe_path[0]));
+ char * rel_to_includedir = get_relative_path (DEFAULT_BINDIR, DEFAULT_INCLUDE_DIR);
+@@ -739,6 +750,26 @@ int main(int argc,char *argv[])
+ wpp_add_include_path(relocated_default_include_dir);
+ #endif
+
++ switch (target_cpu)
++ {
++ case CPU_x86:
++ if (pointer_size == 8) target_cpu = CPU_x86_64;
++ else pointer_size = 4;
++ break;
++ case CPU_x86_64:
++ if (pointer_size == 4) target_cpu = CPU_x86;
++ else pointer_size = 8;
++ break;
++ case CPU_ARM64:
++ if (pointer_size == 4) error( "Cannot build 32-bit code for this CPU\n" );
++ pointer_size = 8;
++ break;
++ default:
++ if (pointer_size == 8) error( "Cannot build 64-bit code for this CPU\n" );
++ pointer_size = 4;
++ break;
++ }
++
+ /* if nothing specified, try to guess output type from the output file name */
+ if (output_name && do_everything && !do_header && !do_typelib && !do_proxies &&
+ !do_client && !do_server && !do_regscript && !do_idfile && !do_dlldata)
+diff --git a/mingw-w64-tools/widl/src/widl.h b/mingw-w64-tools/widl/src/widl.h
+index 118e2245..4f4252e3 100644
+--- a/mingw-w64-tools/widl/src/widl.h
++++ b/mingw-w64-tools/widl/src/widl.h
+@@ -45,8 +45,6 @@ extern int do_regscript;
+ extern int do_idfile;
+ extern int do_dlldata;
+ extern int old_names;
+-extern int do_win32;
+-extern int do_win64;
+ extern int win32_packing;
+ extern int win64_packing;
+ extern int winrt_mode;
+@@ -76,6 +74,13 @@ extern time_t now;
+ extern int line_number;
+ extern int char_number;
+
++enum target_cpu
++{
++ CPU_x86, CPU_x86_64, CPU_POWERPC, CPU_ARM, CPU_ARM64, CPU_LAST = CPU_ARM64
++};
++
++extern enum target_cpu target_cpu;
++
+ enum stub_mode
+ {
+ MODE_Os, /* inline stubs */
+diff --git a/mingw-w64-tools/widl/src/widltypes.h b/mingw-w64-tools/widl/src/widltypes.h
+index 08584de5..b9c5a07d 100644
+--- a/mingw-w64-tools/widl/src/widltypes.h
++++ b/mingw-w64-tools/widl/src/widltypes.h
+@@ -40,6 +40,7 @@ typedef struct _attr_t attr_t;
+ typedef struct _expr_t expr_t;
+ typedef struct _type_t type_t;
+ typedef struct _var_t var_t;
++typedef struct _decl_spec_t decl_spec_t;
+ typedef struct _declarator_t declarator_t;
+ typedef struct _ifref_t ifref_t;
+ typedef struct _typelib_entry_t typelib_entry_t;
+@@ -80,7 +81,6 @@ enum attr_type
+ ATTR_CASE,
+ ATTR_CODE,
+ ATTR_COMMSTATUS,
+- ATTR_CONST, /* const pseudo-attribute */
+ ATTR_CONTEXTHANDLE,
+ ATTR_CONTROL,
+ ATTR_DECODE,
+@@ -115,7 +115,6 @@ enum attr_type
+ ATTR_IMMEDIATEBIND,
+ ATTR_IMPLICIT_HANDLE,
+ ATTR_IN,
+- ATTR_INLINE,
+ ATTR_INPUTSYNC,
+ ATTR_LENGTHIS,
+ ATTR_LIBLCID,
+@@ -234,6 +233,18 @@ enum storage_class
+ STG_REGISTER,
+ };
+
++enum type_qualifier
++{
++ TYPE_QUALIFIER_NONE = 0,
++ TYPE_QUALIFIER_CONST = 1,
++};
++
++enum function_specifier
++{
++ FUNCTION_SPECIFIER_NONE,
++ FUNCTION_SPECIFIER_INLINE,
++};
++
+ enum statement_type
+ {
+ STMT_LIBRARY,
+@@ -293,6 +304,14 @@ struct str_list_entry_t
+ struct list entry;
+ };
+
++struct _decl_spec_t
++{
++ type_t *type;
++ enum storage_class stgclass;
++ enum type_qualifier typequalifier;
++ enum function_specifier funcspecifier;
++};
++
+ struct _attr_t {
+ enum attr_type type;
+ union {
+@@ -356,7 +375,7 @@ struct array_details
+ {
+ expr_t *size_is;
+ expr_t *length_is;
+- struct _type_t *elem;
++ struct _decl_spec_t elem;
+ unsigned int dim;
+ unsigned char ptr_def_fc;
+ unsigned char declptr; /* if declared as a pointer */
+@@ -376,7 +395,7 @@ struct basic_details
+
+ struct pointer_details
+ {
+- struct _type_t *ref;
++ struct _decl_spec_t ref;
+ unsigned char def_fc;
+ };
+
+@@ -386,6 +405,11 @@ struct bitfield_details
+ const expr_t *bits;
+ };
+
++struct alias_details
++{
++ struct _decl_spec_t aliasee;
++};
++
+ #define HASHMAX 64
+
+ struct namespace {
+@@ -414,26 +438,28 @@ enum type_type
+ TYPE_BITFIELD,
+ };
+
++typedef union _details_t
++{
++ struct struct_details *structure;
++ struct enumeration_details *enumeration;
++ struct func_details *function;
++ struct iface_details *iface;
++ struct module_details *module;
++ struct array_details array;
++ struct coclass_details coclass;
++ struct basic_details basic;
++ struct pointer_details pointer;
++ struct bitfield_details bitfield;
++ struct alias_details alias;
++} details_t;
++
+ struct _type_t {
+ const char *name;
+ struct namespace *namespace;
+ enum type_type type_type;
+ attr_list_t *attrs;
+- union
+- {
+- struct struct_details *structure;
+- struct enumeration_details *enumeration;
+- struct func_details *function;
+- struct iface_details *iface;
+- struct module_details *module;
+- struct array_details array;
+- struct coclass_details coclass;
+- struct basic_details basic;
+- struct pointer_details pointer;
+- struct bitfield_details bitfield;
+- } details;
++ details_t details;
+ const char *c_name;
+- type_t *orig; /* dup'd types */
+ unsigned int typestring_offset;
+ unsigned int ptrdesc; /* used for complex structs */
+ int typelib_idx;
+@@ -449,14 +475,20 @@ struct _type_t {
+
+ struct _var_t {
+ char *name;
+- type_t *type;
++ decl_spec_t declspec;
+ attr_list_t *attrs;
+ expr_t *eval;
+- enum storage_class stgclass;
+ unsigned int procstring_offset;
+ unsigned int typestring_offset;
+
+ struct _loc_info_t loc_info;
++ /* this flag indicates that this var's type (or pointed to type in the case of
++ * array or pointer) was not fully defined at the time of declaration.
++ * If this flag is set to TRUE then the type definition will not be written for this var
++ * If this flag is set to FALSE then the type definition will only be written if it has not
++ * been written yet (determined by the type_t's 'written' flag)
++ */
++ int declonly : 1;
+
+ /* parser-internal */
+ struct list entry;
+@@ -464,7 +496,7 @@ struct _var_t {
+
+ struct _declarator_t {
+ var_t *var;
+- type_t *type;
++ decl_spec_t declspec;
+ type_t *func_type;
+ expr_t *bits;
+
+@@ -497,6 +529,7 @@ struct _importinfo_t {
+ };
+
+ struct _importlib_t {
++ int offset;
+ char *name;
+
+ int version;
+@@ -539,6 +572,13 @@ struct _statement_t {
+ typelib_t *lib;
+ type_list_t *type_list;
+ } u;
++ /* this flag indicates that this statement's type (or pointed to type in the case of
++ * array or pointer) was not fully defined at the time of declaration.
++ * If this flag is set to TRUE then the type definition will not be written for this statement
++ * If this flag is set to FALSE then the type definition will only be written if it has not
++ * been written yet (determined by the type_t's 'written' flag)
++ */
++ int declonly : 1;
+ };
+
+ struct _warning_t {
+@@ -553,11 +593,10 @@ typedef enum {
+ SYS_WIN64
+ } syskind_t;
+
+-extern syskind_t typelib_kind;
+ extern user_type_list_t user_type_list;
+ extern context_handle_list_t context_handle_list;
+ extern generic_handle_list_t generic_handle_list;
+-void check_for_additional_prototype_types(const var_list_t *list);
++void check_for_additional_prototype_types(type_t *type);
+
+ void init_types(void);
+ type_t *alloc_type(void);
+@@ -568,6 +607,12 @@ void clear_all_offsets(void);
+ #define tsSTRUCT 2
+ #define tsUNION 3
+
++static inline const char* ts_to_str(int t)
++{
++ static const char* strings[] = {"tsNULL", "tsENUM", "tsSTRUCT", "tsUNION"};
++ return strings[t];
++}
++
+ var_t *find_const(const char *name, int f);
+ type_t *find_type(const char *name, struct namespace *namespace, int t);
+ type_t *make_type(enum type_type type);
+@@ -582,38 +627,18 @@ void init_loc_info(loc_info_t *);
+
+ char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix);
+
+-static inline var_list_t *type_get_function_args(const type_t *func_type)
+-{
+- return func_type->details.function->args;
+-}
+-
+-static inline enum type_type type_get_type_detect_alias(const type_t *type)
+-{
+- if (type->is_alias)
+- return TYPE_ALIAS;
+- return type->type_type;
+-}
+-
+-#define STATEMENTS_FOR_EACH_FUNC(stmt, stmts) \
+- if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, statement_t, entry ) \
+- if (stmt->type == STMT_DECLARATION && stmt->u.var->stgclass == STG_NONE && \
+- type_get_type_detect_alias(stmt->u.var->type) == TYPE_FUNCTION)
+-
+-static inline int statements_has_func(const statement_list_t *stmts)
++static inline int is_global_namespace(const struct namespace *namespace)
+ {
+- const statement_t *stmt;
+- int has_func = 0;
+- STATEMENTS_FOR_EACH_FUNC(stmt, stmts)
+- {
+- has_func = 1;
+- break;
+- }
+- return has_func;
++ return !namespace->name;
+ }
+
+-static inline int is_global_namespace(const struct namespace *namespace)
++static inline decl_spec_t *init_declspec(decl_spec_t *declspec, type_t *type)
+ {
+- return !namespace->name;
++ declspec->type = type;
++ declspec->stgclass = STG_NONE;
++ declspec->typequalifier=TYPE_QUALIFIER_NONE;
++ declspec->funcspecifier=FUNCTION_SPECIFIER_NONE;
++ return declspec;
+ }
+
+ #endif
+diff --git a/mingw-w64-tools/widl/src/write_msft.c b/mingw-w64-tools/widl/src/write_msft.c
+index 88a80d12..da7ce89d 100644
+--- a/mingw-w64-tools/widl/src/write_msft.c
++++ b/mingw-w64-tools/widl/src/write_msft.c
+@@ -702,15 +702,15 @@ static void alloc_importinfo(msft_typelib_t *typelib, importinfo_t *importinfo)
+
+ guid_idx = ctl2_alloc_guid(typelib, &guid);
+
+- alloc_importfile(typelib, guid_idx, importlib->version&0xffff,
+- importlib->version>>16, importlib->name);
++ importlib->offset = alloc_importfile(typelib, guid_idx, importlib->version & 0xffff,
++ importlib->version >> 16, importlib->name);
+ }
+
+ if(importinfo->offset == -1 || !(importinfo->flags & MSFT_IMPINFO_OFFSET_IS_GUID)) {
+ MSFT_ImpInfo impinfo;
+
+ impinfo.flags = importinfo->flags;
+- impinfo.oImpFile = 0;
++ impinfo.oImpFile = importlib->offset;
+
+ if(importinfo->flags & MSFT_IMPINFO_OFFSET_IS_GUID) {
+ MSFT_GuidEntry guid;
+@@ -763,7 +763,7 @@ static void add_enum_typeinfo(msft_typelib_t *typelib, type_t *enumeration);
+ static void add_union_typeinfo(msft_typelib_t *typelib, type_t *tunion);
+ static void add_coclass_typeinfo(msft_typelib_t *typelib, type_t *cls);
+ static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinterface);
+-
++static void add_typedef_typeinfo(msft_typelib_t *typelib, type_t *tdef);
+
+ /****************************************************************************
+ * encode_type
+@@ -862,8 +862,8 @@ static int encode_type(
+ case VT_PTR:
+ {
+ int next_vt;
+- for(next_vt = 0; is_ptr(type); type = type_pointer_get_ref(type)) {
+- next_vt = get_type_vt(type_pointer_get_ref(type));
++ for(next_vt = 0; is_ptr(type); type = type_pointer_get_ref_type(type)) {
++ next_vt = get_type_vt(type_pointer_get_ref_type(type));
+ if (next_vt != 0)
+ break;
+ }
+@@ -871,7 +871,7 @@ static int encode_type(
+ if (next_vt == 0)
+ next_vt = VT_VOID;
+
+- encode_type(typelib, next_vt, type_pointer_get_ref(type),
++ encode_type(typelib, next_vt, type_pointer_get_ref_type(type),
+ &target_type, &child_size);
+ /* these types already have an implicit pointer, so we don't need to
+ * add another */
+@@ -912,10 +912,10 @@ static int encode_type(
+
+ case VT_SAFEARRAY:
+ {
+- type_t *element_type = type_alias_get_aliasee(type_array_get_element(type));
++ type_t *element_type = type_alias_get_aliasee_type(type_array_get_element_type(type));
+ int next_vt = get_type_vt(element_type);
+
+- encode_type(typelib, next_vt, type_alias_get_aliasee(type_array_get_element(type)),
++ encode_type(typelib, next_vt, type_alias_get_aliasee_type(type_array_get_element_type(type)),
+ &target_type, &child_size);
+
+ for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
+@@ -966,33 +966,61 @@ static int encode_type(
+ }
+ else
+ {
+- /* typedef'd types without public attribute aren't included in the typelib */
+- while (type_is_alias(type) && !is_attr(type->attrs, ATTR_PUBLIC))
+- type = type_alias_get_aliasee(type);
++ /* typedef'd types without public attribute aren't included in the typelib
++ * typedef'd types with a wire_marshal attribute must be included
++ */
++ while (type_is_alias(type))
++ {
++ if (is_attr(type->attrs, ATTR_WIREMARSHAL))
++ {
++ type = get_attrp(type->attrs, ATTR_WIREMARSHAL);
++ break;
++ }
++ else if(!is_attr(type->attrs, ATTR_PUBLIC))
++ {
++ type = type_alias_get_aliasee_type(type);
++ }
++ else
++ {
++ break;
++ }
++ }
+
+ chat("encode_type: VT_USERDEFINED - adding new type %s, real type %d\n",
+ type->name, type_get_type(type));
+
+- switch (type_get_type(type))
++ /* we've either fully resolved the typedef down to an actual type or
++ * we must include the typedef because it's a wiremarshal (or public) type
++ */
++ if (type_is_alias(type))
+ {
+- case TYPE_STRUCT:
+- add_structure_typeinfo(typelib, type);
+- break;
+- case TYPE_INTERFACE:
+- add_interface_typeinfo(typelib, type);
+- break;
+- case TYPE_ENUM:
+- add_enum_typeinfo(typelib, type);
+- break;
+- case TYPE_UNION:
+- add_union_typeinfo(typelib, type);
+- break;
+- case TYPE_COCLASS:
+- add_coclass_typeinfo(typelib, type);
+- break;
+- default:
+- error("encode_type: VT_USERDEFINED - unhandled type %d\n",
+- type_get_type(type));
++ add_typedef_typeinfo(typelib, type);
++ }
++ else
++ {
++ switch (type_get_type(type))
++ {
++ case TYPE_STRUCT:
++ add_structure_typeinfo(typelib, type);
++ break;
++ case TYPE_INTERFACE:
++ add_interface_typeinfo(typelib, type);
++ break;
++ case TYPE_ENUM:
++ add_enum_typeinfo(typelib, type);
++ break;
++ /* fallthrough */
++ case TYPE_UNION:
++ case TYPE_ENCAPSULATED_UNION:
++ add_union_typeinfo(typelib, type);
++ break;
++ case TYPE_COCLASS:
++ add_coclass_typeinfo(typelib, type);
++ break;
++ default:
++ error("encode_type: VT_USERDEFINED - unhandled type %d\n",
++ type_get_type(type));
++ }
+ }
+
+ typeinfo_offset = typelib->typelib_typeinfo_offsets[type->typelib_idx];
+@@ -1056,7 +1084,7 @@ static int encode_var(
+ num_dims = 0;
+ for (atype = type;
+ is_array(atype) && !type_array_is_decl_as_ptr(atype);
+- atype = type_array_get_element(atype))
++ atype = type_array_get_element_type(atype))
+ ++num_dims;
+
+ chat("array with %d dimensions\n", num_dims);
+@@ -1071,7 +1099,7 @@ static int encode_var(
+ arraydata += 2;
+ for (atype = type;
+ is_array(atype) && !type_array_is_decl_as_ptr(atype);
+- atype = type_array_get_element(atype))
++ atype = type_array_get_element_type(atype))
+ {
+ arraydata[0] = type_array_get_dim(atype);
+ arraydata[1] = 0;
+@@ -1093,7 +1121,7 @@ static int encode_var(
+ vt = get_type_vt(type);
+ if (vt == VT_PTR) {
+ type_t *ref = is_ptr(type) ?
+- type_pointer_get_ref(type) : type_array_get_element(type);
++ type_pointer_get_ref_type(type) : type_array_get_element_type(type);
+ int skip_ptr = encode_var(typelib, ref, var, &target_type, &child_size);
+
+ if(skip_ptr == 2) {
+@@ -1114,7 +1142,7 @@ static int encode_var(
+ if (target_type & 0x80000000) {
+ mix_field = ((target_type >> 16) & 0x3fff) | VT_BYREF;
+ } else if (get_type_vt(ref) == VT_SAFEARRAY) {
+- type_t *element_type = type_alias_get_aliasee(type_array_get_element(ref));
++ type_t *element_type = type_alias_get_aliasee_type(type_array_get_element_type(ref));
+ mix_field = get_type_vt(element_type) | VT_ARRAY | VT_BYREF;
+ } else {
+ typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type];
+@@ -1204,7 +1232,7 @@ static void write_default_value(msft_typelib_t *typelib, type_t *type, expr_t *e
+ if (type_get_type(type) == TYPE_ENUM) {
+ vt = VT_I4;
+ } else if (is_ptr(type)) {
+- vt = get_type_vt(type_pointer_get_ref(type));
++ vt = get_type_vt(type_pointer_get_ref_type(type));
+ if (vt == VT_USERDEFINED)
+ vt = VT_I4;
+ if (expr->cval)
+@@ -1301,8 +1329,8 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index)
+ return S_FALSE;
+ }
+
+- if (type_get_function_args(func->type))
+- LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), var_t, entry )
++ if (type_function_get_args(func->declspec.type))
++ LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), var_t, entry )
+ {
+ num_params++;
+ if (arg->attrs) LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry ) {
+@@ -1444,7 +1472,7 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index)
+
+ /* fill out the basic type information */
+ typedata[0] = typedata_size | (index << 16);
+- encode_var(typeinfo->typelib, type_function_get_rettype(func->type), func,
++ encode_var(typeinfo->typelib, type_function_get_rettype(func->declspec.type), func,
+ &typedata[1], &decoded_size);
+ typedata[2] = funcflags;
+ typedata[3] = ((52 /*sizeof(FUNCDESC)*/ + decoded_size) << 16) | typeinfo->typeinfo->cbSizeVft;
+@@ -1471,10 +1499,10 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index)
+ warning("unknown number of optional attrs\n");
+ }
+
+- if (type_get_function_args(func->type))
++ if (type_function_get_args(func->declspec.type))
+ {
+ i = 0;
+- LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), var_t, entry )
++ LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), var_t, entry )
+ {
+ int paramflags = 0;
+ int *paramdata = typedata + 6 + extra_attr + (num_defaults ? num_params : 0) + i * 3;
+@@ -1482,13 +1510,13 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index)
+
+ if(defaultdata) *defaultdata = -1;
+
+- encode_var(typeinfo->typelib, arg->type, arg, paramdata, &decoded_size);
++ encode_var(typeinfo->typelib, arg->declspec.type, arg, paramdata, &decoded_size);
+ if (arg->attrs) LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry ) {
+ switch(attr->type) {
+ case ATTR_DEFAULTVALUE:
+ {
+ paramflags |= 0x30; /* PARAMFLAG_FHASDEFAULT | PARAMFLAG_FOPT */
+- write_default_value(typeinfo->typelib, arg->type, (expr_t *)attr->u.pval, defaultdata);
++ write_default_value(typeinfo->typelib, arg->declspec.type, (expr_t *)attr->u.pval, defaultdata);
+ break;
+ }
+ case ATTR_IN:
+@@ -1572,10 +1600,10 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index)
+ if(typeinfo->typekind == TKIND_MODULE)
+ namedata[9] |= 0x20;
+
+- if (type_get_function_args(func->type))
++ if (type_function_get_args(func->declspec.type))
+ {
+ i = 0;
+- LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), var_t, entry )
++ LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), var_t, entry )
+ {
+ /* don't give the last arg of a [propput*] func a name */
+ if(i != num_params - 1 || (invokekind != 0x4 /* INVOKE_PROPERTYPUT */ && invokekind != 0x8 /* INVOKE_PROPERTYPUTREF */))
+@@ -1697,8 +1725,8 @@ static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var)
+ typeinfo->var_offsets[var_num] = offset;
+
+ /* figure out type widths and whatnot */
+- var_datawidth = type_memsize_and_alignment(var->type, &var_alignment);
+- encode_var(typeinfo->typelib, var->type, var, &typedata[1], &var_type_size);
++ var_datawidth = type_memsize_and_alignment(var->declspec.type, &var_alignment);
++ encode_var(typeinfo->typelib, var->declspec.type, var, &typedata[1], &var_type_size);
+
+ /* pad out starting position to data width */
+ typeinfo->datawidth += var_alignment - 1;
+@@ -1977,6 +2005,7 @@ static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinte
+ var_t *var;
+ msft_typeinfo_t *msft_typeinfo;
+
++ assert(type_get_type_detect_alias(dispinterface) == TYPE_INTERFACE);
+ if (-1 < dispinterface->typelib_idx)
+ return;
+
+@@ -2181,7 +2210,7 @@ static void add_typedef_typeinfo(msft_typelib_t *typelib, type_t *tdef)
+ if (-1 < tdef->typelib_idx)
+ return;
+
+- type = type_alias_get_aliasee(tdef);
++ type = type_alias_get_aliasee_type(tdef);
+
+ if (!type->name || strcmp(tdef->name, type->name) != 0)
+ {
+@@ -2297,6 +2326,7 @@ static void add_module_typeinfo(msft_typelib_t *typelib, type_t *module)
+ const statement_t *stmt;
+ msft_typeinfo_t *msft_typeinfo;
+
++ assert(type_get_type_detect_alias(module) == TYPE_MODULE);
+ if (-1 < module->typelib_idx)
+ return;
+
+@@ -2364,7 +2394,7 @@ static void add_entry(msft_typelib_t *typelib, const statement_t *stmt)
+ if (is_attr(type_entry->type->attrs, ATTR_PUBLIC))
+ add_typedef_typeinfo(typelib, type_entry->type);
+ else
+- add_type_typeinfo(typelib, type_alias_get_aliasee(type_entry->type));
++ add_type_typeinfo(typelib, type_alias_get_aliasee_type(type_entry->type));
+ }
+ break;
+ }
+@@ -2653,8 +2683,6 @@ int create_msft_typelib(typelib_t *typelib)
+ GUID midl_info_guid = {0xde77ba65,0x517c,0x11d1,{0xa2,0xda,0x00,0x00,0xf8,0x77,0x3c,0xe9}};
+ char info_string[128];
+
+- pointer_size = (typelib_kind == SYS_WIN64) ? 8 : 4;
+-
+ msft = xmalloc(sizeof(*msft));
+ memset(msft, 0, sizeof(*msft));
+ msft->typelib = typelib;
+@@ -2662,7 +2690,7 @@ int create_msft_typelib(typelib_t *typelib)
+ ctl2_init_header(msft);
+ ctl2_init_segdir(msft);
+
+- msft->typelib_header.varflags |= typelib_kind;
++ msft->typelib_header.varflags |= (pointer_size == 8) ? SYS_WIN64 : SYS_WIN32;
+
+ /*
+ * The following two calls return an offset or -1 if out of memory. We
diff --git a/projects/mingw-w64/build b/projects/mingw-w64/build
index 4be660d..faa5997 100644
--- a/projects/mingw-w64/build
+++ b/projects/mingw-w64/build
@@ -52,6 +52,9 @@ cd /var/tmp/build/builddir/mingw-w64/mingw-w64-pthread
make -j[% c("buildconf/num_procs") %]
make install
+# patch mingw with widl fixes for #27503 ( https://trac.torproject.org/projects/tor/ticket/27503 )
+patch -p1 -d /var/tmp/build/[% project %]-[% c("version") %] < $rootdir/27503.patch
+
mkdir -p /var/tmp/build/builddir/mingw-w64/widl32
cd /var/tmp/build/builddir/mingw-w64/widl32
/var/tmp/build/[% project %]-[% c("version") %]/mingw-w64-tools/widl/configure \
diff --git a/projects/mingw-w64/config b/projects/mingw-w64/config
index d0268cb..a2f0701 100644
--- a/projects/mingw-w64/config
+++ b/projects/mingw-w64/config
@@ -35,3 +35,4 @@ input_files:
- name: binutils
project: binutils
- filename: libtool-sort.patch
+ - filename: 27503.patch
1
0
commit 1d1731f54208a82b21b28ae517664637a3b34c34
Author: Georg Koppen <gk(a)torproject.org>
Date: Wed Jul 3 18:19:37 2019 +0000
Update translations
---
src/chrome/locale/de/aboutTor.dtd | 4 ++--
src/chrome/locale/es-ES/aboutTor.dtd | 2 +-
src/chrome/locale/fa/aboutTor.dtd | 4 ++--
src/chrome/locale/fr/aboutTor.dtd | 4 ++--
src/chrome/locale/he/aboutTor.dtd | 4 ++--
src/chrome/locale/it/aboutTor.dtd | 4 ++--
src/chrome/locale/nl/aboutTor.dtd | 4 ++--
src/chrome/locale/tr/aboutTor.dtd | 4 ++--
src/chrome/locale/zh-CN/aboutTor.dtd | 4 ++--
9 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/src/chrome/locale/de/aboutTor.dtd b/src/chrome/locale/de/aboutTor.dtd
index ef055f13..33e9be15 100644
--- a/src/chrome/locale/de/aboutTor.dtd
+++ b/src/chrome/locale/de/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "Mache Tor stark.">
<!ENTITY aboutTor.donationBanner.buttonA "Spende jetzt">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "Automatische monatliche Spenden halten Tor stark.">
+<!ENTITY aboutTor.donationBanner3.line2 "Werde noch heute ein Verteidiger der Privatsphäre.">
diff --git a/src/chrome/locale/es-ES/aboutTor.dtd b/src/chrome/locale/es-ES/aboutTor.dtd
index 325e10a9..f2fbb4c5 100644
--- a/src/chrome/locale/es-ES/aboutTor.dtd
+++ b/src/chrome/locale/es-ES/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "Mantén fuerte a Tor.">
<!ENTITY aboutTor.donationBanner.buttonA "Dona ahora.">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
+<!ENTITY aboutTor.donationBanner3.line1 "Las donación mensual automática fortalece a Tor.">
<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
diff --git a/src/chrome/locale/fa/aboutTor.dtd b/src/chrome/locale/fa/aboutTor.dtd
index f6ad0773..77999b0c 100644
--- a/src/chrome/locale/fa/aboutTor.dtd
+++ b/src/chrome/locale/fa/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "تور را محکم نگه دارید.">
<!ENTITY aboutTor.donationBanner.buttonA "اکنون اهداء کنید">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "کمک های مالی ماهانه خودکار تور را قوی نگه میدارند.">
+<!ENTITY aboutTor.donationBanner3.line2 "امروز تبدیل به یک مدافع حریم خصوصی شوید.">
diff --git a/src/chrome/locale/fr/aboutTor.dtd b/src/chrome/locale/fr/aboutTor.dtd
index c44b3ddd..e83f750c 100644
--- a/src/chrome/locale/fr/aboutTor.dtd
+++ b/src/chrome/locale/fr/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "Assurez la robustesse de Tor.">
<!ENTITY aboutTor.donationBanner.buttonA "Faites un don maintenant">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "Les dons mensuels automatiques assurent la robustesse de Tor.">
+<!ENTITY aboutTor.donationBanner3.line2 "Devenez dès aujourd'hui un défenseur de la vie privée et de sa protection.">
diff --git a/src/chrome/locale/he/aboutTor.dtd b/src/chrome/locale/he/aboutTor.dtd
index b42fdfc4..dfa2fbae 100644
--- a/src/chrome/locale/he/aboutTor.dtd
+++ b/src/chrome/locale/he/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "שמור על Tor חזק.">
<!ENTITY aboutTor.donationBanner.buttonA "תרום עכשיו">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "תרומות חודשיות אוטומטיות שומרות על Tor חזק.">
+<!ENTITY aboutTor.donationBanner3.line2 "הפוך אל מגן של פרטיות היום.">
diff --git a/src/chrome/locale/it/aboutTor.dtd b/src/chrome/locale/it/aboutTor.dtd
index 7cd090e7..a1477463 100644
--- a/src/chrome/locale/it/aboutTor.dtd
+++ b/src/chrome/locale/it/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "Mantieni Tor forte.">
<!ENTITY aboutTor.donationBanner.buttonA "Dona Ora">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "Le donazioni mensili automatiche mantengono forte Tor.">
+<!ENTITY aboutTor.donationBanner3.line2 "Diventa un Difensore della Privacy oggi.">
diff --git a/src/chrome/locale/nl/aboutTor.dtd b/src/chrome/locale/nl/aboutTor.dtd
index d72342e2..3e78eb8b 100644
--- a/src/chrome/locale/nl/aboutTor.dtd
+++ b/src/chrome/locale/nl/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "Houd Tor sterk.">
<!ENTITY aboutTor.donationBanner.buttonA "Nu doneren">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "Automatische maandelijkse donaties houden Tor sterk.">
+<!ENTITY aboutTor.donationBanner3.line2 "Word vandaag nog voorvechter van privacy.">
diff --git a/src/chrome/locale/tr/aboutTor.dtd b/src/chrome/locale/tr/aboutTor.dtd
index 7bf9012c..8ddbea88 100644
--- a/src/chrome/locale/tr/aboutTor.dtd
+++ b/src/chrome/locale/tr/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "Tor uygulamasının gücünü koruyun.">
<!ENTITY aboutTor.donationBanner.buttonA "Bağış Yapın">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "Aylık otomatik bağışlar Tor projesinin gücünü korumasına yardımcı olur.">
+<!ENTITY aboutTor.donationBanner3.line2 "Bugün kişisel gizliliği savunmak için destek olmaya başlayın.">
diff --git a/src/chrome/locale/zh-CN/aboutTor.dtd b/src/chrome/locale/zh-CN/aboutTor.dtd
index 01e438b4..c0a8bb61 100644
--- a/src/chrome/locale/zh-CN/aboutTor.dtd
+++ b/src/chrome/locale/zh-CN/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "让 Tor 网络保持健壮。">
<!ENTITY aboutTor.donationBanner.buttonA "立即捐助">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "每个月自动捐款来使Tor保持强大">
+<!ENTITY aboutTor.donationBanner3.line2 "今天就成为隐私的捍卫者">
1
0
commit 208b1131bf0a5d91a66a4df98a93c08253c87b26
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Jul 4 06:25:27 2019 +0000
Update translations
---
src/chrome/locale/es-ES/aboutTor.dtd | 4 ++--
src/chrome/locale/pl/aboutTor.dtd | 4 ++--
src/chrome/locale/pt-BR/aboutTor.dtd | 8 ++++----
src/chrome/locale/sv-SE/aboutTor.dtd | 4 ++--
src/chrome/locale/sv-SE/browserOnboarding.properties | 2 +-
5 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/src/chrome/locale/es-ES/aboutTor.dtd b/src/chrome/locale/es-ES/aboutTor.dtd
index f2fbb4c5..26c792d2 100644
--- a/src/chrome/locale/es-ES/aboutTor.dtd
+++ b/src/chrome/locale/es-ES/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "Mantén fuerte a Tor.">
<!ENTITY aboutTor.donationBanner.buttonA "Dona ahora.">
-<!ENTITY aboutTor.donationBanner3.line1 "Las donación mensual automática fortalece a Tor.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "Las donaciones mensuales automáticas mantienen a Tor.">
+<!ENTITY aboutTor.donationBanner3.line2 "Conviértete en un Defensor de la Privacidad, hoy.">
diff --git a/src/chrome/locale/pl/aboutTor.dtd b/src/chrome/locale/pl/aboutTor.dtd
index 2b93c099..138c73e1 100644
--- a/src/chrome/locale/pl/aboutTor.dtd
+++ b/src/chrome/locale/pl/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "Utrzymuj Tor silnym.">
<!ENTITY aboutTor.donationBanner.buttonA "Wesprzyj teraz">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "Automatyczne comiesięczne darowizny trzymają Tora silnym.">
+<!ENTITY aboutTor.donationBanner3.line2 "Zostań dzisiaj Obrońcą Prywatności.">
diff --git a/src/chrome/locale/pt-BR/aboutTor.dtd b/src/chrome/locale/pt-BR/aboutTor.dtd
index fb64963a..e5a512fc 100644
--- a/src/chrome/locale/pt-BR/aboutTor.dtd
+++ b/src/chrome/locale/pt-BR/aboutTor.dtd
@@ -22,15 +22,15 @@
<!ENTITY aboutTor.torbrowser_user_manual.accesskey "M">
<!ENTITY aboutTor.torbrowser_user_manual.label "Manual do Navegador Tor">
-<!ENTITY aboutTor.tor_mission.label "O Projeto Tor é uma organização sem fins lucrativos dos EUA 501 (c) (3) que promove direitos humanos e liberdades, criando e implantando tecnologias de privacidade e anonimato, de fonte aberta e livre, apoiando sua disponibilidade e uso irrestritos e promovendo seu entendimento científico e popular">
+<!ENTITY aboutTor.tor_mission.label "O Projeto Tor é uma organização sem fins lucrativos dos EUA 501 (c) (3) que promove direitos humanos e liberdades, criando e implementando tecnologias de privacidade e anonimato, de código aberto e livre, apoiando a sua disponibilidade e uso irrestrito e promovendo o seu entendimento científico e popular">
<!ENTITY aboutTor.getInvolved.label "Envolva-se »
">
<!ENTITY aboutTor.getInvolved.link "https://www.torproject.org/getinvolved/volunteer.html.en">
<!ENTITY aboutTor.newsletter.tagline "Receba as últimas notícias do Tor diretamente na sua caixa de e-mail.">
<!ENTITY aboutTor.newsletter.link_text "Inscreva-se para receber Notícias do Tor.">
-<!ENTITY aboutTor.donationBanner.line2e "Manter a força do Tor.">
+<!ENTITY aboutTor.donationBanner.line2e "Fortaleça o Tor.">
<!ENTITY aboutTor.donationBanner.buttonA "Doar Agora">
-<!ENTITY aboutTor.donationBanner3.line1 "Doações mensais automáticas mantem Tor forte.">
-<!ENTITY aboutTor.donationBanner3.line2 "Se torne hoje um Defensor da Privacidade.">
+<!ENTITY aboutTor.donationBanner3.line1 "Doações mensais automáticas fortalecem o Tor.">
+<!ENTITY aboutTor.donationBanner3.line2 "Torne-se hoje um Defensor da Privacidade.">
diff --git a/src/chrome/locale/sv-SE/aboutTor.dtd b/src/chrome/locale/sv-SE/aboutTor.dtd
index 6b8094fa..ee567e6d 100644
--- a/src/chrome/locale/sv-SE/aboutTor.dtd
+++ b/src/chrome/locale/sv-SE/aboutTor.dtd
@@ -31,5 +31,5 @@
<!ENTITY aboutTor.donationBanner.line2e "Håll Tor stark.">
<!ENTITY aboutTor.donationBanner.buttonA "Donera nu">
-<!ENTITY aboutTor.donationBanner3.line1 "Automatic monthly donations keep Tor strong.">
-<!ENTITY aboutTor.donationBanner3.line2 "Become a Defender of Privacy today.">
+<!ENTITY aboutTor.donationBanner3.line1 "Automatiska månatliga donationer håller Tor stark.">
+<!ENTITY aboutTor.donationBanner3.line2 "Bli en försvarare av privatlivet idag.">
diff --git a/src/chrome/locale/sv-SE/browserOnboarding.properties b/src/chrome/locale/sv-SE/browserOnboarding.properties
index 61779ce7..5da6b093 100644
--- a/src/chrome/locale/sv-SE/browserOnboarding.properties
+++ b/src/chrome/locale/sv-SE/browserOnboarding.properties
@@ -25,7 +25,7 @@ onboarding.tour-tor-circuit-display.next-button=Gå till Säkerhet
onboarding.tour-tor-security=Säkerhet
onboarding.tour-tor-security.title=Välj din upplevelse.
-onboarding.tour-tor-security.description=Vi ger dig också ytterligare inställningar för att stöta upp din webbläsares säkerhet. Våra säkerhetsinställningar kan du blockera element som kan användas för att attackera din dator. Klicka nedan för att se vad de olika alternativen gör.
+onboarding.tour-tor-security.description=Vi ger dig också ytterligare inställningar för att höja din webbläsares säkerhet. Våra säkerhetsinställningar kan du blockera element som kan användas för att attackera din dator. Klicka nedan för att se vad de olika alternativen gör.
onboarding.tour-tor-security.description-suffix=Observera: Som standard ingår inte NoScript och HTTPS Everywhere i verktygsfältet, men du kan anpassa verktygsfältet för att lägga till dem.
onboarding.tour-tor-security-level.button=Se din säkerhetsnivå
onboarding.tour-tor-security-level.next-button=Gå till Erfarenhets tips
1
0