author | Gijs Kruitbosch <gijskruitbosch@gmail.com> |
Wed, 06 May 2020 20:34:51 +0000 | |
changeset 528516 | ae1a72a9dce69a7fd11cf79f270002659a6d9838 |
parent 528515 | 979a77b1cbf396e2442e8ff9e345fa2d459e94eb |
child 528517 | c1ee5647da8fb482d817bb0fe6532e3737d7e48c |
push id | 37388 |
push user | csabou@mozilla.com |
push date | Thu, 07 May 2020 04:06:39 +0000 |
treeherder | mozilla-central@98040184b6c0 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mattwoodrow, jaws |
bugs | 1633790 |
milestone | 78.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/browser/extensions/pdfjs/content/PdfStreamConverter.jsm +++ b/browser/extensions/pdfjs/content/PdfStreamConverter.jsm @@ -1102,25 +1102,31 @@ PdfStreamConverter.prototype = { Cu.reportError("Found unusable PDF preferences. Fixing back to PDF.js"); mime.preferredAction = Ci.nsIHandlerInfo.handleInternally; mime.alwaysAskBeforeHandling = false; Svc.handlers.store(mime); return true; }, - getConvertedType(aFromType) { - if (!this._validateAndMaybeUpdatePDFPrefs()) { - throw new Components.Exception( - "Can't use PDF.js", - Cr.NS_ERROR_NOT_AVAILABLE - ); + getConvertedType(aFromType, aChannel) { + const HTML = "text/html"; + if (this._validateAndMaybeUpdatePDFPrefs()) { + return HTML; + } + // Hm, so normally, no pdfjs. However... if this is a file: channel loaded + // with system principal, load it anyway: + if (aChannel && aChannel.URI.schemeIs("file")) { + let triggeringPrincipal = aChannel?.loadInfo?.triggeringPrincipal; + if (triggeringPrincipal?.isSystemPrincipal) { + return HTML; + } } - return "text/html"; + throw new Components.Exception("Can't use PDF.js", Cr.NS_ERROR_FAILURE); }, // nsIStreamListener::onDataAvailable onDataAvailable(aRequest, aInputStream, aOffset, aCount) { if (!this.dataListener) { return; }
--- a/browser/extensions/pdfjs/test/browser.ini +++ b/browser/extensions/pdfjs/test/browser.ini @@ -1,12 +1,13 @@ [DEFAULT] support-files = file_pdfjs_test.pdf head.js +[browser_pdfjs_force_opening_files.js] [browser_pdfjs_main.js] [browser_pdfjs_navigation.js] [browser_pdfjs_savedialog.js] skip-if = verify [browser_pdfjs_views.js] [browser_pdfjs_zoom.js] skip-if = (verify && debug && (os == 'win'))
copy from browser/extensions/pdfjs/test/browser_pdfjs_savedialog.js copy to browser/extensions/pdfjs/test/browser_pdfjs_force_opening_files.js --- a/browser/extensions/pdfjs/test/browser_pdfjs_savedialog.js +++ b/browser/extensions/pdfjs/test/browser_pdfjs_force_opening_files.js @@ -1,30 +1,51 @@ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ -const RELATIVE_DIR = "browser/extensions/pdfjs/test/"; -const TESTROOT = "http://example.com/browser/" + RELATIVE_DIR; +add_task(async function test_file_opening() { + // Get a ref to the pdf we want to open. + let dirFileObj = getChromeDir(getResolvedURI(gTestPath)); + dirFileObj.append("file_pdfjs_test.pdf"); -function test() { + // Change the defaults. var oldAction = changeMimeHandler(Ci.nsIHandlerInfo.useSystemDefault, true); - var tab = BrowserTestUtils.addTab(gBrowser, TESTROOT + "file_pdfjs_test.pdf"); - // Test: "Open with" dialog comes up when pdf.js is not selected as the default - // handler. - addWindowListener( - "chrome://mozapps/content/downloads/unknownContentType.xhtml", - finish - ); + + // Test: "Open with" dialog should not come up, despite pdf.js not being + // the default - because files from disk should always use pdfjs, unless + // it is forcibly disabled. + let openedWindow = false; + let windowOpenedPromise = new Promise((resolve, reject) => { + addWindowListener( + "chrome://mozapps/content/downloads/unknownContentType.xhtml", + () => { + openedWindow = true; + resolve(); + } + ); + }); - waitForExplicitFinish(); + // Open the tab with a system principal: + var tab = BrowserTestUtils.addTab(gBrowser, dirFileObj.path); + + let pdfjsLoadedPromise = TestUtils.waitForCondition(() => { + let { contentPrincipal } = tab.linkedBrowser; + return (contentPrincipal?.URI?.spec || "").endsWith("viewer.html"); + }); + await Promise.race([pdfjsLoadedPromise, windowOpenedPromise]); + ok(!openedWindow, "Shouldn't open an unknownContentType window!"); + registerCleanupFunction(function() { + if (listenerCleanup) { + listenerCleanup(); + } changeMimeHandler(oldAction[0], oldAction[1]); gBrowser.removeTab(tab); }); -} +}); function changeMimeHandler(preferredAction, alwaysAskBeforeHandling) { let handlerService = Cc[ "@mozilla.org/uriloader/handler-service;1" ].getService(Ci.nsIHandlerService); let mimeService = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService); let handlerInfo = mimeService.getFromTypeAndExtension( "application/pdf", @@ -53,28 +74,32 @@ function changeMimeHandler(preferredActi handlerInfo.preferredAction, preferredAction, "mime handler change successful" ); return oldAction; } +let listenerCleanup; function addWindowListener(aURL, aCallback) { - Services.wm.addListener({ + let listener = { onOpenWindow(aXULWindow) { info("window opened, waiting for focus"); - Services.wm.removeListener(this); + listenerCleanup(); + listenerCleanup = null; var domwindow = aXULWindow.docShell.domWindow; waitForFocus(function() { is( domwindow.document.location.href, aURL, "should have seen the right window open" ); domwindow.close(); aCallback(); }, domwindow); }, onCloseWindow(aXULWindow) {}, - }); + }; + Services.wm.addListener(listener); + listenerCleanup = () => Services.wm.removeListener(listener); }
--- a/devtools/client/jsonview/converter-child.js +++ b/devtools/client/jsonview/converter-child.js @@ -70,17 +70,17 @@ Converter.prototype = { */ convert: function(fromStream, fromType, toType, ctx) { return fromStream; }, asyncConvertData: function(fromType, toType, listener, ctx) { this.listener = listener; }, - getConvertedType: function(fromType) { + getConvertedType: function(fromType, channel) { return "text/html"; }, onDataAvailable: function(request, inputStream, offset, count) { // Decode and insert data. const buffer = new ArrayBuffer(count); new BinaryInput(inputStream).readArrayBuffer(count, buffer); this.decodeAndInsertBuffer(buffer);
--- a/modules/libjar/zipwriter/nsDeflateConverter.cpp +++ b/modules/libjar/zipwriter/nsDeflateConverter.cpp @@ -88,16 +88,17 @@ NS_IMETHODIMP nsDeflateConverter::AsyncC mListener = aListener; mContext = aCtxt; return rv; } NS_IMETHODIMP nsDeflateConverter::GetConvertedType(const nsACString& aFromType, + nsIChannel* aChannel, nsACString& aToType) { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP nsDeflateConverter::OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aInputStream, uint64_t aOffset, uint32_t aCount) {
--- a/netwerk/ipc/DocumentLoadListener.cpp +++ b/netwerk/ipc/DocumentLoadListener.cpp @@ -112,17 +112,17 @@ class ParentProcessDocumentOpenInfo fina if (mContentType.LowerCaseEqualsASCII(UNKNOWN_CONTENT_TYPE)) { return nsDocumentOpenInfo::TryStreamConversion(aChannel); } nsresult rv; nsCOMPtr<nsIStreamConverterService> streamConvService = do_GetService(NS_STREAMCONVERTERSERVICE_CONTRACTID, &rv); nsAutoCString str; - rv = streamConvService->ConvertedType(mContentType, str); + rv = streamConvService->ConvertedType(mContentType, aChannel, str); NS_ENSURE_SUCCESS(rv, rv); // We only support passing data to the default content listener // (docshell), and we don't supported chaining converters. if (TryDefaultContentListener(aChannel, str)) { mContentType = str; return NS_OK; }
--- a/netwerk/streamconv/converters/mozTXTToHTMLConv.cpp +++ b/netwerk/streamconv/converters/mozTXTToHTMLConv.cpp @@ -1214,17 +1214,17 @@ NS_IMETHODIMP mozTXTToHTMLConv::AsyncConvertData(const char* aFromType, const char* aToType, nsIStreamListener* aListener, nsISupports* aCtxt) { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP mozTXTToHTMLConv::GetConvertedType(const nsACString& aFromType, - nsACString& aToType) { + nsIChannel* aChannel, nsACString& aToType) { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP mozTXTToHTMLConv::OnDataAvailable(nsIRequest* request, nsIInputStream* inStr, uint64_t sourceOffset, uint32_t count) { return NS_ERROR_NOT_IMPLEMENTED; }
--- a/netwerk/streamconv/converters/nsFTPDirListingConv.cpp +++ b/netwerk/streamconv/converters/nsFTPDirListingConv.cpp @@ -67,16 +67,17 @@ nsFTPDirListingConv::AsyncConvertData(co ("nsFTPDirListingConv::AsyncConvertData() converting FROM raw, TO " "application/http-index-format\n")); return NS_OK; } NS_IMETHODIMP nsFTPDirListingConv::GetConvertedType(const nsACString& aFromType, + nsIChannel* aChannel, nsACString& aToType) { return NS_ERROR_NOT_IMPLEMENTED; } // nsIStreamListener implementation NS_IMETHODIMP nsFTPDirListingConv::OnDataAvailable(nsIRequest* request, nsIInputStream* inStr, uint64_t sourceOffset, uint32_t count) {
--- a/netwerk/streamconv/converters/nsHTTPCompressConv.cpp +++ b/netwerk/streamconv/converters/nsHTTPCompressConv.cpp @@ -112,16 +112,17 @@ nsHTTPCompressConv::AsyncConvertData(con // hook ourself up with the receiving listener. mListener = aListener; return NS_OK; } NS_IMETHODIMP nsHTTPCompressConv::GetConvertedType(const nsACString& aFromType, + nsIChannel* aChannel, nsACString& aToType) { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP nsHTTPCompressConv::OnStartRequest(nsIRequest* request) { LOG(("nsHttpCompresssConv %p onstart\n", this)); nsCOMPtr<nsIStreamListener> listener;
--- a/netwerk/streamconv/converters/nsIndexedToHTML.cpp +++ b/netwerk/streamconv/converters/nsIndexedToHTML.cpp @@ -87,17 +87,17 @@ NS_IMETHODIMP nsIndexedToHTML::AsyncConvertData(const char* aFromType, const char* aToType, nsIStreamListener* aListener, nsISupports* aCtxt) { return Init(aListener); } NS_IMETHODIMP nsIndexedToHTML::GetConvertedType(const nsACString& aFromType, - nsACString& aToType) { + nsIChannel* aChannel, nsACString& aToType) { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP nsIndexedToHTML::OnStartRequest(nsIRequest* request) { nsCString buffer; nsresult rv = DoOnStartRequest(request, nullptr, buffer); if (NS_FAILED(rv)) {
--- a/netwerk/streamconv/converters/nsMultiMixedConv.cpp +++ b/netwerk/streamconv/converters/nsMultiMixedConv.cpp @@ -419,17 +419,17 @@ nsMultiMixedConv::AsyncConvertData(const // of these for each sub-part in the raw stream. mFinalListener = aListener; return NS_OK; } NS_IMETHODIMP nsMultiMixedConv::GetConvertedType(const nsACString& aFromType, - nsACString& aToType) { + nsIChannel* aChannel, nsACString& aToType) { return NS_ERROR_NOT_IMPLEMENTED; } // nsIRequestObserver implementation NS_IMETHODIMP nsMultiMixedConv::OnStartRequest(nsIRequest* request) { // we're assuming the content-type is available at this stage NS_ASSERTION(mBoundary.IsEmpty(), "a second on start???");
--- a/netwerk/streamconv/converters/nsUnknownDecoder.cpp +++ b/netwerk/streamconv/converters/nsUnknownDecoder.cpp @@ -140,17 +140,17 @@ nsUnknownDecoder::AsyncConvertData(const MutexAutoLock lock(mMutex); mNextListener = aListener; return (aListener) ? NS_OK : NS_ERROR_FAILURE; } NS_IMETHODIMP nsUnknownDecoder::GetConvertedType(const nsACString& aFromType, - nsACString& aToType) { + nsIChannel* aChannel, nsACString& aToType) { return NS_ERROR_NOT_IMPLEMENTED; } // ---- // // nsIStreamListener methods... // // ----
--- a/netwerk/streamconv/nsIStreamConverter.idl +++ b/netwerk/streamconv/nsIStreamConverter.idl @@ -1,15 +1,16 @@ /* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* 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 "nsIStreamListener.idl" +interface nsIChannel; interface nsIInputStream; /** * nsIStreamConverter provides an interface to implement when you have code * that converts data from one type to another. * * Suppose you had code that converted plain text into HTML. You could implement * this interface to allow everyone else to use your conversion logic using a @@ -93,17 +94,20 @@ interface nsIStreamConverter : nsIStream in string aToType, in nsIStreamListener aListener, in nsISupports aCtxt); /** * Returns the content type that the stream listener passed to asyncConvertData will * see on the channel if the conversion is being done from aFromType to * /*. * + * @param aFromType The type of the content prior to conversion. + * @param aChannel The channel that we'd like to convert. May be null. + * * @throws if the converter does not support conversion to * /* or if it doesn't know * the type in advance. */ - ACString getConvertedType(in ACString aFromType); + ACString getConvertedType(in ACString aFromType, in nsIChannel aChannel); }; %{C++ #define NS_ISTREAMCONVERTER_KEY "@mozilla.org/streamconv;1" %}
--- a/netwerk/streamconv/nsIStreamConverterService.idl +++ b/netwerk/streamconv/nsIStreamConverterService.idl @@ -1,15 +1,16 @@ /* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* 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 "nsISupports.idl" +interface nsIChannel; interface nsIInputStream; interface nsIStreamListener; %{C++ #define NS_ISTREAMCONVERTER_KEY "@mozilla.org/streamconv;1" %} /** @@ -35,17 +36,17 @@ interface nsIStreamConverterService : ns boolean canConvert(in string aFromType, in string aToType); /** * Returns the content type that will be returned from a converter * created with aFromType and * /*. * Can fail if no converters support this conversion, or if the * output type isn't known in advance. */ - ACString convertedType(in ACString aFromType); + ACString convertedType(in ACString aFromType, in nsIChannel aChannel); /** * <b>SYNCHRONOUS VERSION</b> * Converts a stream of one type, to a stream of another type. * * Use this method when you have a stream you want to convert. * * @param aFromStream The stream representing the original/raw data.
--- a/netwerk/streamconv/nsStreamConverterService.cpp +++ b/netwerk/streamconv/nsStreamConverterService.cpp @@ -352,29 +352,30 @@ nsStreamConverterService::CanConvert(con *_retval = NS_SUCCEEDED(rv); delete converterChain; return NS_OK; } NS_IMETHODIMP nsStreamConverterService::ConvertedType(const nsACString& aFromType, + nsIChannel* aChannel, nsACString& aOutToType) { // first determine whether we can even handle this conversion // build a CONTRACTID nsAutoCString contractID; contractID.AssignLiteral(NS_ISTREAMCONVERTER_KEY "?from="); contractID.Append(aFromType); contractID.AppendLiteral("&to=*/*"); const char* cContractID = contractID.get(); nsresult rv; nsCOMPtr<nsIStreamConverter> converter(do_CreateInstance(cContractID, &rv)); if (NS_SUCCEEDED(rv)) { - return converter->GetConvertedType(aFromType, aOutToType); + return converter->GetConvertedType(aFromType, aChannel, aOutToType); } return rv; } NS_IMETHODIMP nsStreamConverterService::Convert(nsIInputStream* aFromStream, const char* aFromType, const char* aToType, nsISupports* aContext,