aboutsummaryrefslogtreecommitdiff
path: root/gnu/packages/patches
diff options
context:
space:
mode:
authorMark H Weaver <mhw@netris.org>2018-09-21 03:28:03 -0400
committerMark H Weaver <mhw@netris.org>2018-09-21 07:16:02 -0400
commite67ad5532f76b53e955149da2f1e237696ff0893 (patch)
tree179f00c315bc610804b310b17e5a3c60a5f0b7bf /gnu/packages/patches
parentc5327efb97208df569b4682ef5bfe4ac825d1c4f (diff)
downloadguix-e67ad5532f76b53e955149da2f1e237696ff0893.tar.gz
guix-e67ad5532f76b53e955149da2f1e237696ff0893.zip
gnu: icecat: Update to 60.2.0-gnu1 (pre-release).
* gnu/packages/gnuzilla.scm (icecat): Update to 60.2.0-gnu1. [source]: Download pre-release from alpha.gnu.org. Remove obsolete patches. Comment out the code to delete the bundled copies of libevent, cairo, harfbuzz, and graphite2. [inputs]: Use the latest ffmpeg. Comment out libevent, cairo, harfbuzz, and graphite2. [native-inputs]: Add rust and cargo. [arguments]: Remove --enable-gio and --disable-gnomeui. Add --disable-stylo. Comment out --with-system-{libevent,harfbuzz,graphite2}, --enable-system-cairo. Import %cargo-build-system-modules. Add 'patch-cargo-checksums' phase. * gnu/packages/patches/icecat-CVE-2018-5157-and-CVE-2018-5158.patch, gnu/packages/patches/icecat-bug-1413868-pt1.patch: Delete files. * gnu/local.mk (dist_patch_DATA): Remove them.
Diffstat (limited to 'gnu/packages/patches')
-rw-r--r--gnu/packages/patches/icecat-CVE-2018-5157-and-CVE-2018-5158.patch441
-rw-r--r--gnu/packages/patches/icecat-bug-1413868-pt1.patch663
2 files changed, 0 insertions, 1104 deletions
diff --git a/gnu/packages/patches/icecat-CVE-2018-5157-and-CVE-2018-5158.patch b/gnu/packages/patches/icecat-CVE-2018-5157-and-CVE-2018-5158.patch
deleted file mode 100644
index b776640133..0000000000
--- a/gnu/packages/patches/icecat-CVE-2018-5157-and-CVE-2018-5158.patch
+++ /dev/null
@@ -1,441 +0,0 @@
-Based on <https://hg.mozilla.org/releases/mozilla-esr52/rev/608e76ec5ba2>
-Adapted to apply cleanly to GNU IceCat.
-
-# HG changeset patch
-# User Ryan VanderMeulen <ryanvm@gmail.com>
-# Date 1523630807 14400
-# Node ID 608e76ec5ba25cec2271d2b400c7bce2d4c5ef79
-# Parent 10b7f43b536f93151201d44d304c991aa9af5d0c
-Bug 1452075 - Backport some upstream pdf.js fixes to ESR52. r=bdahl, r=yury, a=RyanVM
-
-diff --git a/browser/extensions/pdfjs/content/PdfStreamConverter.jsm b/browser/extensions/pdfjs/content/PdfStreamConverter.jsm
---- a/browser/extensions/pdfjs/content/PdfStreamConverter.jsm
-+++ b/browser/extensions/pdfjs/content/PdfStreamConverter.jsm
-@@ -24,17 +24,18 @@ const Cc = Components.classes;
- const Ci = Components.interfaces;
- const Cr = Components.results;
- const Cu = Components.utils;
- // True only if this is the version of pdf.js that is included with icecat.
- const MOZ_CENTRAL = JSON.parse('true');
- const PDFJS_EVENT_ID = 'pdf.js.message';
- const PDF_CONTENT_TYPE = 'application/pdf';
- const PREF_PREFIX = 'pdfjs';
--const PDF_VIEWER_WEB_PAGE = 'resource://pdf.js/web/viewer.html';
-+const PDF_VIEWER_ORIGIN = "resource://pdf.js";
-+const PDF_VIEWER_WEB_PAGE = "resource://pdf.js/web/viewer.html";
- const MAX_NUMBER_OF_PREFS = 50;
- const MAX_STRING_PREF_LENGTH = 128;
-
- Cu.import('resource://gre/modules/XPCOMUtils.jsm');
- Cu.import('resource://gre/modules/Services.jsm');
- Cu.import('resource://gre/modules/NetUtil.jsm');
-
- XPCOMUtils.defineLazyModuleGetter(this, 'NetworkManager',
-@@ -105,21 +106,25 @@ function log(aMsg) {
- if (!getBoolPref(PREF_PREFIX + '.pdfBugEnabled', false)) {
- return;
- }
- var msg = 'PdfStreamConverter.js: ' + (aMsg.join ? aMsg.join('') : aMsg);
- Services.console.logStringMessage(msg);
- dump(msg + '\n');
- }
-
--function getDOMWindow(aChannel) {
-+function getDOMWindow(aChannel, aPrincipal) {
- var requestor = aChannel.notificationCallbacks ?
- aChannel.notificationCallbacks :
- aChannel.loadGroup.notificationCallbacks;
- var win = requestor.getInterface(Components.interfaces.nsIDOMWindow);
-+ // Ensure the window wasn't navigated to something that is not PDF.js.
-+ if (!win.document.nodePrincipal.equals(aPrincipal)) {
-+ return null;
-+ }
- return win;
- }
-
- function getLocalizedStrings(path) {
- var stringBundle = Cc['@mozilla.org/intl/stringbundle;1'].
- getService(Ci.nsIStringBundleService).
- createBundle('chrome://pdf.js/locale/' + path);
-
-@@ -627,31 +632,31 @@ var RangedChromeActions = (function Rang
- data = this.dataListener.readData();
-
- this.dataListener.onprogress = function (loaded, total) {
- self.domWindow.postMessage({
- pdfjsLoadAction: 'progressiveRead',
- loaded: loaded,
- total: total,
- chunk: self.dataListener.readData()
-- }, '*');
-+ }, PDF_VIEWER_ORIGIN);
- };
- this.dataListener.oncomplete = function () {
- self.dataListener = null;
- };
- }
-
- this.domWindow.postMessage({
- pdfjsLoadAction: 'supportsRangedLoading',
- rangeEnabled: this.rangeEnabled,
- streamingEnabled: this.streamingEnabled,
- pdfUrl: this.pdfUrl,
- length: this.contentLength,
- data: data
-- }, '*');
-+ }, PDF_VIEWER_ORIGIN);
-
- return true;
- };
-
- proto.requestDataRange = function RangedChromeActions_requestDataRange(args) {
- if (!this.rangeEnabled) {
- return;
- }
-@@ -663,23 +668,23 @@ var RangedChromeActions = (function Rang
- // errors from chrome code for non-range requests, so this doesn't
- // seem high-pri
- this.networkManager.requestRange(begin, end, {
- onDone: function RangedChromeActions_onDone(args) {
- domWindow.postMessage({
- pdfjsLoadAction: 'range',
- begin: args.begin,
- chunk: args.chunk
-- }, '*');
-+ }, PDF_VIEWER_ORIGIN);
- },
- onProgress: function RangedChromeActions_onProgress(evt) {
- domWindow.postMessage({
- pdfjsLoadAction: 'rangeProgress',
- loaded: evt.loaded,
-- }, '*');
-+ }, PDF_VIEWER_ORIGIN);
- }
- });
- };
-
- proto.abortLoading = function RangedChromeActions_abortLoading() {
- this.networkManager.abortAllRequests();
- if (this.originalRequest) {
- this.originalRequest.cancel(Cr.NS_BINDING_ABORTED);
-@@ -718,26 +723,26 @@ var StandardChromeActions = (function St
- var self = this;
-
- this.dataListener.onprogress = function ChromeActions_dataListenerProgress(
- loaded, total) {
- self.domWindow.postMessage({
- pdfjsLoadAction: 'progress',
- loaded: loaded,
- total: total
-- }, '*');
-+ }, PDF_VIEWER_ORIGIN);
- };
-
- this.dataListener.oncomplete =
- function StandardChromeActions_dataListenerComplete(data, errorCode) {
- self.domWindow.postMessage({
- pdfjsLoadAction: 'complete',
- data: data,
- errorCode: errorCode
-- }, '*');
-+ }, PDF_VIEWER_ORIGIN);
-
- self.dataListener = null;
- self.originalRequest = null;
- };
-
- return true;
- };
-
-@@ -972,31 +977,35 @@ PdfStreamConverter.prototype = {
- var proxy = {
- onStartRequest: function(request, context) {
- listener.onStartRequest(aRequest, aContext);
- },
- onDataAvailable: function(request, context, inputStream, offset, count) {
- listener.onDataAvailable(aRequest, aContext, inputStream,
- offset, count);
- },
-- onStopRequest: function(request, context, statusCode) {
-- // We get the DOM window here instead of before the request since it
-- // may have changed during a redirect.
-- var domWindow = getDOMWindow(channel);
-+ onStopRequest(request, context, statusCode) {
-+ var domWindow = getDOMWindow(channel, resourcePrincipal);
-+ if (!Components.isSuccessCode(statusCode) || !domWindow) {
-+ // The request may have been aborted and the document may have been
-+ // replaced with something that is not PDF.js, abort attaching.
-+ listener.onStopRequest(aRequest, context, statusCode);
-+ return;
-+ }
- var actions;
- if (rangeRequest || streamRequest) {
- actions = new RangedChromeActions(
- domWindow, contentDispositionFilename, aRequest,
- rangeRequest, streamRequest, dataListener);
- } else {
- actions = new StandardChromeActions(
- domWindow, contentDispositionFilename, aRequest, dataListener);
- }
- var requestListener = new RequestListener(actions);
-- domWindow.addEventListener(PDFJS_EVENT_ID, function(event) {
-+ domWindow.document.addEventListener(PDFJS_EVENT_ID, function(event) {
- requestListener.receive(event);
- }, false, true);
- if (actions.supportsIntegratedFind()) {
- var findEventManager = new FindEventManager(domWindow);
- findEventManager.bind();
- }
- listener.onStopRequest(aRequest, aContext, statusCode);
-
-diff --git a/browser/extensions/pdfjs/content/build/pdf.worker.js b/browser/extensions/pdfjs/content/build/pdf.worker.js
---- a/browser/extensions/pdfjs/content/build/pdf.worker.js
-+++ b/browser/extensions/pdfjs/content/build/pdf.worker.js
-@@ -41648,16 +41648,32 @@
- var error = sharedUtil.error;
- var info = sharedUtil.info;
- var isArray = sharedUtil.isArray;
- var isBool = sharedUtil.isBool;
- var isDict = corePrimitives.isDict;
- var isStream = corePrimitives.isStream;
- var PostScriptLexer = corePsParser.PostScriptLexer;
- var PostScriptParser = corePsParser.PostScriptParser;
-+ function toNumberArray(arr) {
-+ if (!Array.isArray(arr)) {
-+ return null;
-+ }
-+ var length = arr.length;
-+ for (var i = 0; i < length; i++) {
-+ if (typeof arr[i] !== 'number') {
-+ var result = new Array(length);
-+ for (var j = 0; j < length; j++) {
-+ result[j] = +arr[j];
-+ }
-+ return result;
-+ }
-+ }
-+ return arr;
-+ }
- var PDFFunction = function PDFFunctionClosure() {
- var CONSTRUCT_SAMPLED = 0;
- var CONSTRUCT_INTERPOLATED = 2;
- var CONSTRUCT_STICHED = 3;
- var CONSTRUCT_POSTSCRIPT = 4;
- return {
- getSampleArray: function PDFFunction_getSampleArray(size, outputSize, bps, str) {
- var i, ii;
-@@ -41747,43 +41763,43 @@
- out[index] = [
- arr[i],
- arr[i + 1]
- ];
- ++index;
- }
- return out;
- }
-- var domain = dict.getArray('Domain');
-- var range = dict.getArray('Range');
-+ var domain = toNumberArray(dict.getArray('Domain'));
-+ var range = toNumberArray(dict.getArray('Range'));
- if (!domain || !range) {
- error('No domain or range');
- }
- var inputSize = domain.length / 2;
- var outputSize = range.length / 2;
- domain = toMultiArray(domain);
- range = toMultiArray(range);
-- var size = dict.get('Size');
-+ var size = toNumberArray(dict.get('Size'));
- var bps = dict.get('BitsPerSample');
- var order = dict.get('Order') || 1;
- if (order !== 1) {
- // No description how cubic spline interpolation works in PDF32000:2008
- // As in poppler, ignoring order, linear interpolation may work as good
- info('No support for cubic spline interpolation: ' + order);
- }
-- var encode = dict.getArray('Encode');
-+ var encode = toNumberArray(dict.getArray('Encode'));
- if (!encode) {
- encode = [];
- for (var i = 0; i < inputSize; ++i) {
-- encode.push(0);
-- encode.push(size[i] - 1);
-- }
-- }
-- encode = toMultiArray(encode);
-- var decode = dict.getArray('Decode');
-+ encode.push([0, size[i] - 1]);
-+ }
-+ } else {
-+ encode = toMultiArray(encode);
-+ }
-+ var decode = toNumberArray(dict.getArray('Decode'));
- if (!decode) {
- decode = range;
- } else {
- decode = toMultiArray(decode);
- }
- var samples = this.getSampleArray(size, outputSize, bps, str);
- return [
- CONSTRUCT_SAMPLED,
-@@ -41868,22 +41884,19 @@
- // Decode_2j, Decode_2j+1)
- rj = interpolate(rj, 0, 1, decode[j][0], decode[j][1]);
- // y_j = min(max(r_j, range_2j), range_2j+1)
- dest[destOffset + j] = Math.min(Math.max(rj, range[j][0]), range[j][1]);
- }
- };
- },
- constructInterpolated: function PDFFunction_constructInterpolated(str, dict) {
-- var c0 = dict.getArray('C0') || [0];
-- var c1 = dict.getArray('C1') || [1];
-+ var c0 = toNumberArray(dict.getArray('C0')) || [0];
-+ var c1 = toNumberArray(dict.getArray('C1')) || [1];
- var n = dict.get('N');
-- if (!isArray(c0) || !isArray(c1)) {
-- error('Illegal dictionary for interpolated function');
-- }
- var length = c0.length;
- var diff = [];
- for (var i = 0; i < length; ++i) {
- diff.push(c1[i] - c0[i]);
- }
- return [
- CONSTRUCT_INTERPOLATED,
- c0,
-@@ -41899,49 +41912,45 @@
- return function constructInterpolatedFromIRResult(src, srcOffset, dest, destOffset) {
- var x = n === 1 ? src[srcOffset] : Math.pow(src[srcOffset], n);
- for (var j = 0; j < length; ++j) {
- dest[destOffset + j] = c0[j] + x * diff[j];
- }
- };
- },
- constructStiched: function PDFFunction_constructStiched(fn, dict, xref) {
-- var domain = dict.getArray('Domain');
-+ var domain = toNumberArray(dict.getArray('Domain'));
- if (!domain) {
- error('No domain');
- }
- var inputSize = domain.length / 2;
- if (inputSize !== 1) {
- error('Bad domain for stiched function');
- }
- var fnRefs = dict.get('Functions');
- var fns = [];
- for (var i = 0, ii = fnRefs.length; i < ii; ++i) {
-- fns.push(PDFFunction.getIR(xref, xref.fetchIfRef(fnRefs[i])));
-- }
-- var bounds = dict.getArray('Bounds');
-- var encode = dict.getArray('Encode');
-+ fns.push(PDFFunction.parse(xref, xref.fetchIfRef(fnRefs[i])));
-+ }
-+ var bounds = toNumberArray(dict.getArray('Bounds'));
-+ var encode = toNumberArray(dict.getArray('Encode'));
- return [
- CONSTRUCT_STICHED,
- domain,
- bounds,
- encode,
- fns
- ];
- },
- constructStichedFromIR: function PDFFunction_constructStichedFromIR(IR) {
- var domain = IR[1];
- var bounds = IR[2];
- var encode = IR[3];
-- var fnsIR = IR[4];
-- var fns = [];
-+ var fns = IR[4];
- var tmpBuf = new Float32Array(1);
-- for (var i = 0, ii = fnsIR.length; i < ii; i++) {
-- fns.push(PDFFunction.fromIR(fnsIR[i]));
-- }
- return function constructStichedFromIRResult(src, srcOffset, dest, destOffset) {
- var clip = function constructStichedFromIRClip(v, min, max) {
- if (v > max) {
- v = max;
- } else if (v < min) {
- v = min;
- }
- return v;
-@@ -41968,18 +41977,18 @@
- // Prevent the value from becoming NaN as a result
- // of division by zero (fixes issue6113.pdf).
- tmpBuf[0] = dmin === dmax ? rmin : rmin + (v - dmin) * (rmax - rmin) / (dmax - dmin);
- // call the appropriate function
- fns[i](tmpBuf, 0, dest, destOffset);
- };
- },
- constructPostScript: function PDFFunction_constructPostScript(fn, dict, xref) {
-- var domain = dict.getArray('Domain');
-- var range = dict.getArray('Range');
-+ var domain = toNumberArray(dict.getArray('Domain'));
-+ var range = toNumberArray(dict.getArray('Range'));
- if (!domain) {
- error('No domain.');
- }
- if (!range) {
- error('No range.');
- }
- var lexer = new PostScriptLexer(fn);
- var parser = new PostScriptParser(lexer);
-@@ -42928,18 +42937,18 @@
- case 'IndexedCS':
- var baseIndexedCS = IR[1];
- var hiVal = IR[2];
- var lookup = IR[3];
- return new IndexedCS(ColorSpace.fromIR(baseIndexedCS), hiVal, lookup);
- case 'AlternateCS':
- var numComps = IR[1];
- var alt = IR[2];
-- var tintFnIR = IR[3];
-- return new AlternateCS(numComps, ColorSpace.fromIR(alt), PDFFunction.fromIR(tintFnIR));
-+ var tintFn = IR[3];
-+ return new AlternateCS(numComps, ColorSpace.fromIR(alt), tintFn);
- case 'LabCS':
- whitePoint = IR[1];
- blackPoint = IR[2];
- var range = IR[3];
- return new LabCS(whitePoint, blackPoint, range);
- default:
- error('Unknown name ' + name);
- }
-@@ -43067,22 +43076,22 @@
- var name = xref.fetchIfRef(cs[1]);
- numComps = 1;
- if (isName(name)) {
- numComps = 1;
- } else if (isArray(name)) {
- numComps = name.length;
- }
- alt = ColorSpace.parseToIR(cs[2], xref, res);
-- var tintFnIR = PDFFunction.getIR(xref, xref.fetchIfRef(cs[3]));
-+ var tintFn = PDFFunction.parse(xref, xref.fetchIfRef(cs[3]));
- return [
- 'AlternateCS',
- numComps,
- alt,
-- tintFnIR
-+ tintFn
- ];
- case 'Lab':
- params = xref.fetchIfRef(cs[1]);
- whitePoint = params.getArray('WhitePoint');
- blackPoint = params.getArray('BlackPoint');
- var range = params.getArray('Range');
- return [
- 'LabCS',
-@@ -52483,9 +52492,9 @@
- initializeWorker();
- }
- exports.setPDFNetworkStreamClass = setPDFNetworkStreamClass;
- exports.WorkerTask = WorkerTask;
- exports.WorkerMessageHandler = WorkerMessageHandler;
- }));
- }.call(pdfjsLibs));
- exports.WorkerMessageHandler = pdfjsLibs.pdfjsCoreWorker.WorkerMessageHandler;
--}));
-\ No newline at end of file
-+}));
-
diff --git a/gnu/packages/patches/icecat-bug-1413868-pt1.patch b/gnu/packages/patches/icecat-bug-1413868-pt1.patch
deleted file mode 100644
index 18382dc33a..0000000000
--- a/gnu/packages/patches/icecat-bug-1413868-pt1.patch
+++ /dev/null
@@ -1,663 +0,0 @@
-Based on <https://hg.mozilla.org/releases/mozilla-esr52/rev/431fa5dd4016>
-Adapted to apply cleanly to GNU IceCat.
-
-# HG changeset patch
-# User Honza Bambas <honzab.moz@firemni.cz>
-# Date 1528830658 14400
-# Node ID 431fa5dd4016bdab7e4bb0d3c4df85468fe337b0
-# Parent e8e9e1ef79f2a18c61ec1b87cfb214c8d4960f8e
-Bug 1413868. r=valentin, a=RyanVM
-
-diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp
---- a/toolkit/xre/nsAppRunner.cpp
-+++ b/toolkit/xre/nsAppRunner.cpp
-@@ -4,16 +4,17 @@
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
- #include "mozilla/dom/ContentParent.h"
- #include "mozilla/dom/ContentChild.h"
- #include "mozilla/ipc/GeckoChildProcessHost.h"
-
- #include "mozilla/ArrayUtils.h"
- #include "mozilla/Attributes.h"
-+#include "mozilla/FilePreferences.h"
- #include "mozilla/ChaosMode.h"
- #include "mozilla/IOInterposer.h"
- #include "mozilla/Likely.h"
- #include "mozilla/MemoryChecking.h"
- #include "mozilla/Poison.h"
- #include "mozilla/Preferences.h"
- #include "mozilla/ScopeExit.h"
- #include "mozilla/Services.h"
-@@ -4304,16 +4305,20 @@ XREMain::XRE_mainRun()
- // Need to write out the fact that the profile has been removed and potentially
- // that the selected/default profile changed.
- mProfileSvc->Flush();
- }
- }
-
- mDirProvider.DoStartup();
-
-+ // As FilePreferences need the profile directory, we must initialize right here.
-+ mozilla::FilePreferences::InitDirectoriesWhitelist();
-+ mozilla::FilePreferences::InitPrefs();
-+
- OverrideDefaultLocaleIfNeeded();
-
- #ifdef MOZ_CRASHREPORTER
- nsCString userAgentLocale;
- // Try a localized string first. This pref is always a localized string in
- // IceCatMobile, and might be elsewhere, too.
- if (NS_SUCCEEDED(Preferences::GetLocalizedCString("general.useragent.locale", &userAgentLocale))) {
- CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("useragent_locale"), userAgentLocale);
-diff --git a/toolkit/xre/nsEmbedFunctions.cpp b/toolkit/xre/nsEmbedFunctions.cpp
---- a/toolkit/xre/nsEmbedFunctions.cpp
-+++ b/toolkit/xre/nsEmbedFunctions.cpp
-@@ -46,16 +46,17 @@
- #include "nsX11ErrorHandler.h"
- #include "nsGDKErrorHandler.h"
- #include "base/at_exit.h"
- #include "base/command_line.h"
- #include "base/message_loop.h"
- #include "base/process_util.h"
- #include "chrome/common/child_process.h"
-
-+#include "mozilla/FilePreferences.h"
- #include "mozilla/ipc/BrowserProcessSubThread.h"
- #include "mozilla/ipc/GeckoChildProcessHost.h"
- #include "mozilla/ipc/IOThreadChild.h"
- #include "mozilla/ipc/ProcessChild.h"
- #include "ScopedXREEmbed.h"
-
- #include "mozilla/plugins/PluginProcessChild.h"
- #include "mozilla/dom/ContentProcess.h"
-@@ -680,16 +681,18 @@ XRE_InitChildProcess(int aArgc,
- ::SetProcessShutdownParameters(0x280 - 1, SHUTDOWN_NORETRY);
- #endif
-
- #if defined(MOZ_SANDBOX) && defined(XP_WIN)
- // We need to do this after the process has been initialised, as
- // InitLoggingIfRequired may need access to prefs.
- mozilla::sandboxing::InitLoggingIfRequired(aChildData->ProvideLogFunction);
- #endif
-+ mozilla::FilePreferences::InitDirectoriesWhitelist();
-+ mozilla::FilePreferences::InitPrefs();
-
- OverrideDefaultLocaleIfNeeded();
-
- #if defined(MOZ_CRASHREPORTER)
- #if defined(MOZ_CONTENT_SANDBOX) && !defined(MOZ_WIDGET_GONK)
- AddContentSandboxLevelAnnotation();
- #endif
- #endif
-diff --git a/xpcom/io/FilePreferences.cpp b/xpcom/io/FilePreferences.cpp
-new file mode 100644
---- /dev/null
-+++ b/xpcom/io/FilePreferences.cpp
-@@ -0,0 +1,271 @@
-+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-+/* 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/. */
-+
-+#include "FilePreferences.h"
-+
-+#include "mozilla/Preferences.h"
-+#include "nsAppDirectoryServiceDefs.h"
-+#include "nsDirectoryServiceDefs.h"
-+#include "nsDirectoryServiceUtils.h"
-+
-+namespace mozilla {
-+namespace FilePreferences {
-+
-+static bool sBlockUNCPaths = false;
-+typedef nsTArray<nsString> Paths;
-+
-+static Paths& PathArray()
-+{
-+ static Paths sPaths;
-+ return sPaths;
-+}
-+
-+static void AllowDirectory(char const* directory)
-+{
-+ nsCOMPtr<nsIFile> file;
-+ NS_GetSpecialDirectory(directory, getter_AddRefs(file));
-+ if (!file) {
-+ return;
-+ }
-+
-+ nsString path;
-+ if (NS_FAILED(file->GetTarget(path))) {
-+ return;
-+ }
-+
-+ // The whitelist makes sense only for UNC paths, because this code is used
-+ // to block only UNC paths, hence, no need to add non-UNC directories here
-+ // as those would never pass the check.
-+ if (!StringBeginsWith(path, NS_LITERAL_STRING("\\\\"))) {
-+ return;
-+ }
-+
-+ if (!PathArray().Contains(path)) {
-+ PathArray().AppendElement(path);
-+ }
-+}
-+
-+void InitPrefs()
-+{
-+ sBlockUNCPaths = Preferences::GetBool("network.file.disable_unc_paths", false);
-+}
-+
-+void InitDirectoriesWhitelist()
-+{
-+ // NS_GRE_DIR is the installation path where the binary resides.
-+ AllowDirectory(NS_GRE_DIR);
-+ // NS_APP_USER_PROFILE_50_DIR and NS_APP_USER_PROFILE_LOCAL_50_DIR are the two
-+ // parts of the profile we store permanent and local-specific data.
-+ AllowDirectory(NS_APP_USER_PROFILE_50_DIR);
-+ AllowDirectory(NS_APP_USER_PROFILE_LOCAL_50_DIR);
-+}
-+
-+namespace { // anon
-+
-+class Normalizer
-+{
-+public:
-+ Normalizer(const nsAString& aFilePath, const char16_t aSeparator);
-+ bool Get(nsAString& aNormalizedFilePath);
-+
-+private:
-+ bool ConsumeItem();
-+ bool ConsumeSeparator();
-+ bool IsEOF() { return mFilePathCursor == mFilePathEnd; }
-+
-+ bool ConsumeName();
-+ bool CheckParentDir();
-+ bool CheckCurrentDir();
-+
-+ nsString::const_char_iterator mFilePathCursor;
-+ nsString::const_char_iterator mFilePathEnd;
-+
-+ nsDependentSubstring mItem;
-+ char16_t const mSeparator;
-+ nsTArray<nsDependentSubstring> mStack;
-+};
-+
-+Normalizer::Normalizer(const nsAString& aFilePath, const char16_t aSeparator)
-+ : mFilePathCursor(aFilePath.BeginReading())
-+ , mFilePathEnd(aFilePath.EndReading())
-+ , mSeparator(aSeparator)
-+{
-+}
-+
-+bool Normalizer::ConsumeItem()
-+{
-+ if (IsEOF()) {
-+ return false;
-+ }
-+
-+ nsString::const_char_iterator nameBegin = mFilePathCursor;
-+ while (mFilePathCursor != mFilePathEnd) {
-+ if (*mFilePathCursor == mSeparator) {
-+ break; // don't include the separator
-+ }
-+ ++mFilePathCursor;
-+ }
-+
-+ mItem.Rebind(nameBegin, mFilePathCursor);
-+ return true;
-+}
-+
-+bool Normalizer::ConsumeSeparator()
-+{
-+ if (IsEOF()) {
-+ return false;
-+ }
-+
-+ if (*mFilePathCursor != mSeparator) {
-+ return false;
-+ }
-+
-+ ++mFilePathCursor;
-+ return true;
-+}
-+
-+bool Normalizer::Get(nsAString& aNormalizedFilePath)
-+{
-+ aNormalizedFilePath.Truncate();
-+
-+ if (IsEOF()) {
-+ return true;
-+ }
-+ if (ConsumeSeparator()) {
-+ aNormalizedFilePath.Append(mSeparator);
-+ }
-+
-+ if (IsEOF()) {
-+ return true;
-+ }
-+ if (ConsumeSeparator()) {
-+ aNormalizedFilePath.Append(mSeparator);
-+ }
-+
-+ while (!IsEOF()) {
-+ if (!ConsumeName()) {
-+ return false;
-+ }
-+ }
-+
-+ for (auto const& name : mStack) {
-+ aNormalizedFilePath.Append(name);
-+ }
-+
-+ return true;
-+}
-+
-+bool Normalizer::ConsumeName()
-+{
-+ if (!ConsumeItem()) {
-+ return true;
-+ }
-+
-+ if (CheckCurrentDir()) {
-+ return true;
-+ }
-+
-+ if (CheckParentDir()) {
-+ if (!mStack.Length()) {
-+ // This means there are more \.. than valid names
-+ return false;
-+ }
-+
-+ mStack.RemoveElementAt(mStack.Length() - 1);
-+ return true;
-+ }
-+
-+ if (mItem.IsEmpty()) {
-+ // this means an empty name (a lone slash), which is illegal
-+ return false;
-+ }
-+
-+ if (ConsumeSeparator()) {
-+ mItem.Rebind(mItem.BeginReading(), mFilePathCursor);
-+ }
-+ mStack.AppendElement(mItem);
-+
-+ return true;
-+}
-+
-+bool Normalizer::CheckCurrentDir()
-+{
-+ if (mItem == NS_LITERAL_STRING(".")) {
-+ ConsumeSeparator();
-+ // EOF is acceptable
-+ return true;
-+ }
-+
-+ return false;
-+}
-+
-+bool Normalizer::CheckParentDir()
-+{
-+ if (mItem == NS_LITERAL_STRING("..")) {
-+ ConsumeSeparator();
-+ // EOF is acceptable
-+ return true;
-+ }
-+
-+ return false;
-+}
-+
-+} // anon
-+
-+bool IsBlockedUNCPath(const nsAString& aFilePath)
-+{
-+ if (!sBlockUNCPaths) {
-+ return false;
-+ }
-+
-+ if (!StringBeginsWith(aFilePath, NS_LITERAL_STRING("\\\\"))) {
-+ return false;
-+ }
-+
-+ nsAutoString normalized;
-+ if (!Normalizer(aFilePath, L'\\').Get(normalized)) {
-+ // Broken paths are considered invalid and thus inaccessible
-+ return true;
-+ }
-+
-+ for (const auto& allowedPrefix : PathArray()) {
-+ if (StringBeginsWith(normalized, allowedPrefix)) {
-+ if (normalized.Length() == allowedPrefix.Length()) {
-+ return false;
-+ }
-+ if (normalized[allowedPrefix.Length()] == L'\\') {
-+ return false;
-+ }
-+
-+ // When we are here, the path has a form "\\path\prefixevil"
-+ // while we have an allowed prefix of "\\path\prefix".
-+ // Note that we don't want to add a slash to the end of a prefix
-+ // so that opening the directory (no slash at the end) still works.
-+ break;
-+ }
-+ }
-+
-+ return true;
-+}
-+
-+void testing::SetBlockUNCPaths(bool aBlock)
-+{
-+ sBlockUNCPaths = aBlock;
-+}
-+
-+void testing::AddDirectoryToWhitelist(nsAString const & aPath)
-+{
-+ PathArray().AppendElement(aPath);
-+}
-+
-+bool testing::NormalizePath(nsAString const & aPath, nsAString & aNormalized)
-+{
-+ Normalizer normalizer(aPath, L'\\');
-+ return normalizer.Get(aNormalized);
-+}
-+
-+} // ::FilePreferences
-+} // ::mozilla
-diff --git a/xpcom/io/FilePreferences.h b/xpcom/io/FilePreferences.h
-new file mode 100644
---- /dev/null
-+++ b/xpcom/io/FilePreferences.h
-@@ -0,0 +1,25 @@
-+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-+/* 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/. */
-+
-+#include "nsIObserver.h"
-+
-+namespace mozilla {
-+namespace FilePreferences {
-+
-+void InitPrefs();
-+void InitDirectoriesWhitelist();
-+bool IsBlockedUNCPath(const nsAString& aFilePath);
-+
-+namespace testing {
-+
-+void SetBlockUNCPaths(bool aBlock);
-+void AddDirectoryToWhitelist(nsAString const& aPath);
-+bool NormalizePath(nsAString const & aPath, nsAString & aNormalized);
-+
-+}
-+
-+} // FilePreferences
-+} // mozilla
-diff --git a/xpcom/io/moz.build b/xpcom/io/moz.build
---- a/xpcom/io/moz.build
-+++ b/xpcom/io/moz.build
-@@ -79,24 +79,26 @@ EXPORTS += [
- 'nsUnicharInputStream.h',
- 'nsWildCard.h',
- 'SlicedInputStream.h',
- 'SpecialSystemDirectory.h',
- ]
-
- EXPORTS.mozilla += [
- 'Base64.h',
-+ 'FilePreferences.h',
- 'SnappyCompressOutputStream.h',
- 'SnappyFrameUtils.h',
- 'SnappyUncompressInputStream.h',
- ]
-
- UNIFIED_SOURCES += [
- 'Base64.cpp',
- 'crc32c.c',
-+ 'FilePreferences.cpp',
- 'nsAnonymousTemporaryFile.cpp',
- 'nsAppFileLocationProvider.cpp',
- 'nsBinaryStream.cpp',
- 'nsDirectoryService.cpp',
- 'nsEscape.cpp',
- 'nsInputStreamTee.cpp',
- 'nsIOUtil.cpp',
- 'nsLinebreakConverter.cpp',
-diff --git a/xpcom/io/nsLocalFileWin.cpp b/xpcom/io/nsLocalFileWin.cpp
---- a/xpcom/io/nsLocalFileWin.cpp
-+++ b/xpcom/io/nsLocalFileWin.cpp
-@@ -41,16 +41,17 @@
- #include <stdio.h>
- #include <stdlib.h>
- #include <mbstring.h>
-
- #include "nsXPIDLString.h"
- #include "prproces.h"
- #include "prlink.h"
-
-+#include "mozilla/FilePreferences.h"
- #include "mozilla/Mutex.h"
- #include "SpecialSystemDirectory.h"
-
- #include "nsTraceRefcnt.h"
- #include "nsXPCOMCIDInternal.h"
- #include "nsThreadUtils.h"
- #include "nsXULAppAPI.h"
-
-@@ -1162,16 +1163,20 @@ nsLocalFile::InitWithPath(const nsAStrin
- char16_t secondChar = *(++begin);
-
- // just do a sanity check. if it has any forward slashes, it is not a Native path
- // on windows. Also, it must have a colon at after the first char.
- if (FindCharInReadable(L'/', begin, end)) {
- return NS_ERROR_FILE_UNRECOGNIZED_PATH;
- }
-
-+ if (FilePreferences::IsBlockedUNCPath(aFilePath)) {
-+ return NS_ERROR_FILE_ACCESS_DENIED;
-+ }
-+
- if (secondChar != L':' && (secondChar != L'\\' || firstChar != L'\\')) {
- return NS_ERROR_FILE_UNRECOGNIZED_PATH;
- }
-
- if (secondChar == L':') {
- // Make sure we have a valid drive, later code assumes the drive letter
- // is a single char a-z or A-Z.
- if (PathGetDriveNumberW(aFilePath.Data()) == -1) {
-@@ -1974,16 +1979,20 @@ nsLocalFile::CopySingleFile(nsIFile* aSo
- bool path1Remote, path2Remote;
- if (!IsRemoteFilePath(filePath.get(), path1Remote) ||
- !IsRemoteFilePath(destPath.get(), path2Remote) ||
- path1Remote || path2Remote) {
- dwCopyFlags |= COPY_FILE_NO_BUFFERING;
- }
- }
-
-+ if (FilePreferences::IsBlockedUNCPath(destPath)) {
-+ return NS_ERROR_FILE_ACCESS_DENIED;
-+ }
-+
- if (!move) {
- copyOK = ::CopyFileExW(filePath.get(), destPath.get(), nullptr,
- nullptr, nullptr, dwCopyFlags);
- } else {
- copyOK = ::MoveFileExW(filePath.get(), destPath.get(),
- MOVEFILE_REPLACE_EXISTING);
-
- // Check if copying the source file to a different volume,
-diff --git a/xpcom/tests/gtest/TestFilePreferencesWin.cpp b/xpcom/tests/gtest/TestFilePreferencesWin.cpp
-new file mode 100644
---- /dev/null
-+++ b/xpcom/tests/gtest/TestFilePreferencesWin.cpp
-@@ -0,0 +1,141 @@
-+#include "gtest/gtest.h"
-+
-+#include "mozilla/FilePreferences.h"
-+#include "nsIFile.h"
-+#include "nsXPCOMCID.h"
-+
-+TEST(FilePreferencesWin, Normalization)
-+{
-+ nsAutoString normalized;
-+
-+ mozilla::FilePreferences::testing::NormalizePath(
-+ NS_LITERAL_STRING("foo"), normalized);
-+ ASSERT_TRUE(normalized == NS_LITERAL_STRING("foo"));
-+
-+ mozilla::FilePreferences::testing::NormalizePath(
-+ NS_LITERAL_STRING("\\foo"), normalized);
-+ ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\foo"));
-+
-+ mozilla::FilePreferences::testing::NormalizePath(
-+ NS_LITERAL_STRING("\\\\foo"), normalized);
-+ ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\foo"));
-+
-+ mozilla::FilePreferences::testing::NormalizePath(
-+ NS_LITERAL_STRING("foo\\some"), normalized);
-+ ASSERT_TRUE(normalized == NS_LITERAL_STRING("foo\\some"));
-+
-+ mozilla::FilePreferences::testing::NormalizePath(
-+ NS_LITERAL_STRING("\\\\.\\foo"), normalized);
-+ ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\foo"));
-+
-+ mozilla::FilePreferences::testing::NormalizePath(
-+ NS_LITERAL_STRING("\\\\."), normalized);
-+ ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\"));
-+
-+ mozilla::FilePreferences::testing::NormalizePath(
-+ NS_LITERAL_STRING("\\\\.\\"), normalized);
-+ ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\"));
-+
-+ mozilla::FilePreferences::testing::NormalizePath(
-+ NS_LITERAL_STRING("\\\\.\\."), normalized);
-+ ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\"));
-+
-+ mozilla::FilePreferences::testing::NormalizePath(
-+ NS_LITERAL_STRING("\\\\foo\\bar"), normalized);
-+ ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\foo\\bar"));
-+
-+ mozilla::FilePreferences::testing::NormalizePath(
-+ NS_LITERAL_STRING("\\\\foo\\bar\\"), normalized);
-+ ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\foo\\bar\\"));
-+
-+ mozilla::FilePreferences::testing::NormalizePath(
-+ NS_LITERAL_STRING("\\\\foo\\bar\\."), normalized);
-+ ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\foo\\bar\\"));
-+
-+ mozilla::FilePreferences::testing::NormalizePath(
-+ NS_LITERAL_STRING("\\\\foo\\bar\\.\\"), normalized);
-+ ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\foo\\bar\\"));
-+
-+ mozilla::FilePreferences::testing::NormalizePath(
-+ NS_LITERAL_STRING("\\\\foo\\bar\\..\\"), normalized);
-+ ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\foo\\"));
-+
-+ mozilla::FilePreferences::testing::NormalizePath(
-+ NS_LITERAL_STRING("\\\\foo\\bar\\.."), normalized);
-+ ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\foo\\"));
-+
-+ mozilla::FilePreferences::testing::NormalizePath(
-+ NS_LITERAL_STRING("\\\\foo\\..\\bar\\..\\"), normalized);
-+ ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\"));
-+
-+ mozilla::FilePreferences::testing::NormalizePath(
-+ NS_LITERAL_STRING("\\\\foo\\..\\bar"), normalized);
-+ ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\bar"));
-+
-+ mozilla::FilePreferences::testing::NormalizePath(
-+ NS_LITERAL_STRING("\\\\foo\\bar\\..\\..\\"), normalized);
-+ ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\"));
-+
-+ mozilla::FilePreferences::testing::NormalizePath(
-+ NS_LITERAL_STRING("\\\\foo\\bar\\.\\..\\.\\..\\"), normalized);
-+ ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\"));
-+
-+ bool result;
-+
-+ result = mozilla::FilePreferences::testing::NormalizePath(
-+ NS_LITERAL_STRING("\\\\.."), normalized);
-+ ASSERT_FALSE(result);
-+
-+ result = mozilla::FilePreferences::testing::NormalizePath(
-+ NS_LITERAL_STRING("\\\\..\\"), normalized);
-+ ASSERT_FALSE(result);
-+
-+ result = mozilla::FilePreferences::testing::NormalizePath(
-+ NS_LITERAL_STRING("\\\\.\\..\\"), normalized);
-+ ASSERT_FALSE(result);
-+
-+ result = mozilla::FilePreferences::testing::NormalizePath(
-+ NS_LITERAL_STRING("\\\\foo\\\\bar"), normalized);
-+ ASSERT_FALSE(result);
-+
-+ result = mozilla::FilePreferences::testing::NormalizePath(
-+ NS_LITERAL_STRING("\\\\foo\\bar\\..\\..\\..\\..\\"), normalized);
-+ ASSERT_FALSE(result);
-+
-+ result = mozilla::FilePreferences::testing::NormalizePath(
-+ NS_LITERAL_STRING("\\\\\\"), normalized);
-+ ASSERT_FALSE(result);
-+
-+ result = mozilla::FilePreferences::testing::NormalizePath(
-+ NS_LITERAL_STRING("\\\\.\\\\"), normalized);
-+ ASSERT_FALSE(result);
-+
-+ result = mozilla::FilePreferences::testing::NormalizePath(
-+ NS_LITERAL_STRING("\\\\..\\\\"), normalized);
-+ ASSERT_FALSE(result);
-+}
-+
-+TEST(FilePreferencesWin, AccessUNC)
-+{
-+ nsCOMPtr<nsIFile> lf = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
-+
-+ nsresult rv;
-+
-+ mozilla::FilePreferences::testing::SetBlockUNCPaths(false);
-+
-+ rv = lf->InitWithPath(NS_LITERAL_STRING("\\\\nice\\..\\evil\\share"));
-+ ASSERT_EQ(rv, NS_OK);
-+
-+ mozilla::FilePreferences::testing::SetBlockUNCPaths(true);
-+
-+ rv = lf->InitWithPath(NS_LITERAL_STRING("\\\\nice\\..\\evil\\share"));
-+ ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED);
-+
-+ mozilla::FilePreferences::testing::AddDirectoryToWhitelist(NS_LITERAL_STRING("\\\\nice"));
-+
-+ rv = lf->InitWithPath(NS_LITERAL_STRING("\\\\nice\\share"));
-+ ASSERT_EQ(rv, NS_OK);
-+
-+ rv = lf->InitWithPath(NS_LITERAL_STRING("\\\\nice\\..\\evil\\share"));
-+ ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED);
-+}
-diff --git a/xpcom/tests/gtest/moz.build b/xpcom/tests/gtest/moz.build
---- a/xpcom/tests/gtest/moz.build
-+++ b/xpcom/tests/gtest/moz.build
-@@ -51,16 +51,21 @@ UNIFIED_SOURCES += [
- if CONFIG['MOZ_DEBUG'] and CONFIG['OS_ARCH'] not in ('WINNT') and CONFIG['OS_TARGET'] != 'Android':
- # FIXME bug 523392: TestDeadlockDetector doesn't like Windows
- # Bug 1054249: Doesn't work on Android
- UNIFIED_SOURCES += [
- 'TestDeadlockDetector.cpp',
- 'TestDeadlockDetectorScalability.cpp',
- ]
-
-+if CONFIG['OS_TARGET'] == 'WINNT':
-+ UNIFIED_SOURCES += [
-+ 'TestFilePreferencesWin.cpp',
-+ ]
-+
- if CONFIG['WRAP_STL_INCLUDES'] and not CONFIG['CLANG_CL']:
- UNIFIED_SOURCES += [
- 'TestSTLWrappers.cpp',
- ]
-
- # Compile TestAllocReplacement separately so Windows headers don't pollute
- # the global namespace for other files.
- SOURCES += [
-