diff options
author | Jan Beich <jbeich@FreeBSD.org> | 2018-03-29 08:53:36 +0800 |
---|---|---|
committer | Jan Beich <jbeich@FreeBSD.org> | 2018-03-29 08:53:36 +0800 |
commit | ab288320cfef5547ac63733122d94eeb03bb8e18 (patch) | |
tree | dee52af7cf08261adc7cf42970506b8491ec037e | |
parent | 7195d6be3264c9e4a5a093bf11565729d333a986 (diff) | |
download | freebsd-ports-ab288320cfef5547ac63733122d94eeb03bb8e18.tar.gz freebsd-ports-ab288320cfef5547ac63733122d94eeb03bb8e18.tar.zst freebsd-ports-ab288320cfef5547ac63733122d94eeb03bb8e18.zip |
www/waterfox: apply some FF60 fixes
Notes
Notes:
svn path=/head/; revision=465858
-rw-r--r-- | www/waterfox/Makefile | 1 | ||||
-rw-r--r-- | www/waterfox/files/patch-bug1340039 | 232 | ||||
-rw-r--r-- | www/waterfox/files/patch-bug1402380 | 257 | ||||
-rw-r--r-- | www/waterfox/files/patch-bug1409440 | 89 | ||||
-rw-r--r-- | www/waterfox/files/patch-bug1416045 | 338 | ||||
-rw-r--r-- | www/waterfox/files/patch-bug1433609 | 103 | ||||
-rw-r--r-- | www/waterfox/files/patch-bug1441941 | 252 | ||||
-rw-r--r-- | www/waterfox/files/patch-bug1443092 | 64 | ||||
-rw-r--r-- | www/waterfox/files/patch-bug1444231 | 45 | ||||
-rw-r--r-- | www/waterfox/files/patch-bug1448136 | 71 | ||||
-rw-r--r-- | www/waterfox/files/patch-servo19654 | 44 |
11 files changed, 1496 insertions, 0 deletions
diff --git a/www/waterfox/Makefile b/www/waterfox/Makefile index 8e77d317ae80..7a9af6942af8 100644 --- a/www/waterfox/Makefile +++ b/www/waterfox/Makefile @@ -2,6 +2,7 @@ PORTNAME= waterfox DISTVERSION= 56.1.0 +PORTREVISION= 1 CATEGORIES= www ipv6 MAINTAINER= jbeich@FreeBSD.org diff --git a/www/waterfox/files/patch-bug1340039 b/www/waterfox/files/patch-bug1340039 new file mode 100644 index 000000000000..2f601b7db234 --- /dev/null +++ b/www/waterfox/files/patch-bug1340039 @@ -0,0 +1,232 @@ +commit 753d522440f6 +Author: Hector Zhao <bzhao@mozilla.com> +Date: Wed Mar 14 16:44:36 2018 +0800 + + Bug 1340039 - Set contentPolicyType when copying image, and pass it between processes. r=smaug, a=jcristau + + MozReview-Commit-ID: CJj1a1Lj699 + + --HG-- + extra : source : 445ec9da938f984a6fe2fe163c7f3d7be4710a77 +--- + dom/base/nsContentUtils.cpp | 2 ++ + dom/base/nsContentUtils.h | 1 + + dom/base/nsCopySupport.cpp | 1 + + dom/events/EventStateManager.cpp | 5 ++++- + dom/ipc/ContentParent.cpp | 2 ++ + dom/ipc/ContentParent.h | 1 + + dom/ipc/PBrowser.ipdl | 3 ++- + dom/ipc/PContent.ipdl | 1 + + dom/ipc/TabChild.cpp | 4 +++- + dom/ipc/TabChild.h | 3 ++- + dom/ipc/TabParent.cpp | 6 ++++-- + dom/ipc/TabParent.h | 3 ++- + widget/nsClipboardProxy.cpp | 5 ++++- + 13 files changed, 29 insertions(+), 8 deletions(-) + +diff --git dom/base/nsContentUtils.cpp dom/base/nsContentUtils.cpp +index fe773465faba..63e1ac06bf2d 100644 +--- dom/base/nsContentUtils.cpp ++++ dom/base/nsContentUtils.cpp +@@ -7986,6 +7986,7 @@ nsresult + nsContentUtils::IPCTransferableToTransferable(const IPCDataTransfer& aDataTransfer, + const bool& aIsPrivateData, + nsIPrincipal* aRequestingPrincipal, ++ const nsContentPolicyType& aContentPolicyType, + nsITransferable* aTransferable, + mozilla::dom::nsIContentParent* aContentParent, + mozilla::dom::TabChild* aTabChild) +@@ -8051,6 +8052,7 @@ nsContentUtils::IPCTransferableToTransferable(const IPCDataTransfer& aDataTransf + + aTransferable->SetIsPrivateData(aIsPrivateData); + aTransferable->SetRequestingPrincipal(aRequestingPrincipal); ++ aTransferable->SetContentPolicyType(aContentPolicyType); + return NS_OK; + } + +diff --git dom/base/nsContentUtils.h dom/base/nsContentUtils.h +index 356d3841b9e9..9ef79a569ea3 100644 +--- dom/base/nsContentUtils.h ++++ dom/base/nsContentUtils.h +@@ -2845,6 +2845,7 @@ public: + static nsresult IPCTransferableToTransferable(const mozilla::dom::IPCDataTransfer& aDataTransfer, + const bool& aIsPrivateData, + nsIPrincipal* aRequestingPrincipal, ++ const nsContentPolicyType& aContentPolicyType, + nsITransferable* aTransferable, + mozilla::dom::nsIContentParent* aContentParent, + mozilla::dom::TabChild* aTabChild); +diff --git dom/base/nsCopySupport.cpp dom/base/nsCopySupport.cpp +index 0f680c21c126..5e2d4065b3b7 100644 +--- dom/base/nsCopySupport.cpp ++++ dom/base/nsCopySupport.cpp +@@ -680,6 +680,7 @@ static nsresult AppendImagePromise(nsITransferable* aTransferable, + NS_ENSURE_SUCCESS(rv, rv); + + aTransferable->SetRequestingPrincipal(node->NodePrincipal()); ++ aTransferable->SetContentPolicyType(nsIContentPolicy::TYPE_INTERNAL_IMAGE); + + // add the dataless file promise flavor + return aTransferable->AddDataFlavor(kFilePromiseMime); +diff --git dom/events/EventStateManager.cpp dom/events/EventStateManager.cpp +index 4423e3aecc5e..bdc1bb6e50c9 100644 +--- dom/events/EventStateManager.cpp ++++ dom/events/EventStateManager.cpp +@@ -5469,8 +5469,11 @@ EventStateManager::DoContentCommandEvent(WidgetContentCommandEvent* aEvent) + transferable->GetIsPrivateData(&isPrivateData); + nsCOMPtr<nsIPrincipal> requestingPrincipal; + transferable->GetRequestingPrincipal(getter_AddRefs(requestingPrincipal)); ++ nsContentPolicyType contentPolicyType = nsIContentPolicy::TYPE_OTHER; ++ transferable->GetContentPolicyType(&contentPolicyType); + remote->SendPasteTransferable(ipcDataTransfer, isPrivateData, +- IPC::Principal(requestingPrincipal)); ++ IPC::Principal(requestingPrincipal), ++ contentPolicyType); + rv = NS_OK; + } else { + nsCOMPtr<nsICommandController> commandController = do_QueryInterface(controller); +diff --git dom/ipc/ContentParent.cpp dom/ipc/ContentParent.cpp +index e27f3eedc1b1..3c3d2fbc3735 100644 +--- dom/ipc/ContentParent.cpp ++++ dom/ipc/ContentParent.cpp +@@ -2605,6 +2605,7 @@ mozilla::ipc::IPCResult + ContentParent::RecvSetClipboard(const IPCDataTransfer& aDataTransfer, + const bool& aIsPrivateData, + const IPC::Principal& aRequestingPrincipal, ++ const uint32_t& aContentPolicyType, + const int32_t& aWhichClipboard) + { + nsresult rv; +@@ -2619,6 +2620,7 @@ ContentParent::RecvSetClipboard(const IPCDataTransfer& aDataTransfer, + rv = nsContentUtils::IPCTransferableToTransferable(aDataTransfer, + aIsPrivateData, + aRequestingPrincipal, ++ aContentPolicyType, + trans, this, nullptr); + NS_ENSURE_SUCCESS(rv, IPC_OK()); + +diff --git dom/ipc/ContentParent.h dom/ipc/ContentParent.h +index 1977cfbfd651..a1311bd39403 100644 +--- dom/ipc/ContentParent.h ++++ dom/ipc/ContentParent.h +@@ -976,6 +976,7 @@ private: + virtual mozilla::ipc::IPCResult RecvSetClipboard(const IPCDataTransfer& aDataTransfer, + const bool& aIsPrivateData, + const IPC::Principal& aRequestingPrincipal, ++ const uint32_t& aContentPolicyType, + const int32_t& aWhichClipboard) override; + + virtual mozilla::ipc::IPCResult RecvGetClipboard(nsTArray<nsCString>&& aTypes, +diff --git dom/ipc/PBrowser.ipdl dom/ipc/PBrowser.ipdl +index 3a7b21271fec..b1cf9efbe964 100644 +--- dom/ipc/PBrowser.ipdl ++++ dom/ipc/PBrowser.ipdl +@@ -720,7 +720,8 @@ child: + */ + async PasteTransferable(IPCDataTransfer aDataTransfer, + bool aIsPrivateData, +- Principal aRequestingPrincipal); ++ Principal aRequestingPrincipal, ++ uint32_t aContentPolicyType); + + /** + * Activate event forwarding from client to parent. +diff --git dom/ipc/PContent.ipdl dom/ipc/PContent.ipdl +index 7e33b2920cbe..4ab9da3cc105 100644 +--- dom/ipc/PContent.ipdl ++++ dom/ipc/PContent.ipdl +@@ -837,6 +837,7 @@ parent: + async SetClipboard(IPCDataTransfer aDataTransfer, + bool aIsPrivateData, + Principal aRequestingPrincipal, ++ uint32_t aContentPolicyType, + int32_t aWhichClipboard); + + // Given a list of supported types, returns the clipboard data for the +diff --git dom/ipc/TabChild.cpp dom/ipc/TabChild.cpp +index 50725636d280..72df59ea98c0 100644 +--- dom/ipc/TabChild.cpp ++++ dom/ipc/TabChild.cpp +@@ -2164,7 +2164,8 @@ TabChild::RecvNormalPrioritySelectionEvent(const WidgetSelectionEvent& aEvent) + mozilla::ipc::IPCResult + TabChild::RecvPasteTransferable(const IPCDataTransfer& aDataTransfer, + const bool& aIsPrivateData, +- const IPC::Principal& aRequestingPrincipal) ++ const IPC::Principal& aRequestingPrincipal, ++ const uint32_t& aContentPolicyType) + { + nsresult rv; + nsCOMPtr<nsITransferable> trans = +@@ -2175,6 +2176,7 @@ TabChild::RecvPasteTransferable(const IPCDataTransfer& aDataTransfer, + rv = nsContentUtils::IPCTransferableToTransferable(aDataTransfer, + aIsPrivateData, + aRequestingPrincipal, ++ aContentPolicyType, + trans, nullptr, this); + NS_ENSURE_SUCCESS(rv, IPC_OK()); + +diff --git dom/ipc/TabChild.h dom/ipc/TabChild.h +index f18906568c1c..48bd8e9eb86e 100644 +--- dom/ipc/TabChild.h ++++ dom/ipc/TabChild.h +@@ -454,7 +454,8 @@ public: + virtual mozilla::ipc::IPCResult + RecvPasteTransferable(const IPCDataTransfer& aDataTransfer, + const bool& aIsPrivateData, +- const IPC::Principal& aRequestingPrincipal) override; ++ const IPC::Principal& aRequestingPrincipal, ++ const uint32_t& aContentPolicyType) override; + + virtual mozilla::ipc::IPCResult + RecvActivateFrameEvent(const nsString& aType, const bool& aCapture) override; +diff --git dom/ipc/TabParent.cpp dom/ipc/TabParent.cpp +index d4e3d11ea2e9..ae43c24e8891 100644 +--- dom/ipc/TabParent.cpp ++++ dom/ipc/TabParent.cpp +@@ -2312,11 +2312,13 @@ TabParent::SendSelectionEvent(WidgetSelectionEvent& aEvent) + bool + TabParent::SendPasteTransferable(const IPCDataTransfer& aDataTransfer, + const bool& aIsPrivateData, +- const IPC::Principal& aRequestingPrincipal) ++ const IPC::Principal& aRequestingPrincipal, ++ const uint32_t& aContentPolicyType) + { + return PBrowserParent::SendPasteTransferable(aDataTransfer, + aIsPrivateData, +- aRequestingPrincipal); ++ aRequestingPrincipal, ++ aContentPolicyType); + } + + /*static*/ TabParent* +diff --git dom/ipc/TabParent.h dom/ipc/TabParent.h +index c31827499403..e3c2601ce0b4 100644 +--- dom/ipc/TabParent.h ++++ dom/ipc/TabParent.h +@@ -497,7 +497,8 @@ public: + + bool SendPasteTransferable(const IPCDataTransfer& aDataTransfer, + const bool& aIsPrivateData, +- const IPC::Principal& aRequestingPrincipal); ++ const IPC::Principal& aRequestingPrincipal, ++ const uint32_t& aContentPolicyType); + + static TabParent* GetFrom(nsFrameLoader* aFrameLoader); + +diff --git widget/nsClipboardProxy.cpp widget/nsClipboardProxy.cpp +index f7d863475b13..4fb90721c0b6 100644 +--- widget/nsClipboardProxy.cpp ++++ widget/nsClipboardProxy.cpp +@@ -37,8 +37,11 @@ nsClipboardProxy::SetData(nsITransferable *aTransferable, + aTransferable->GetIsPrivateData(&isPrivateData); + nsCOMPtr<nsIPrincipal> requestingPrincipal; + aTransferable->GetRequestingPrincipal(getter_AddRefs(requestingPrincipal)); ++ nsContentPolicyType contentPolicyType = nsIContentPolicy::TYPE_OTHER; ++ aTransferable->GetContentPolicyType(&contentPolicyType); + child->SendSetClipboard(ipcDataTransfer, isPrivateData, +- IPC::Principal(requestingPrincipal), aWhichClipboard); ++ IPC::Principal(requestingPrincipal), ++ contentPolicyType, aWhichClipboard); + + return NS_OK; + } diff --git a/www/waterfox/files/patch-bug1402380 b/www/waterfox/files/patch-bug1402380 new file mode 100644 index 000000000000..cb0f76b6caa2 --- /dev/null +++ b/www/waterfox/files/patch-bug1402380 @@ -0,0 +1,257 @@ +commit fb06fdcf7d66 +Author: Tooru Fujisawa <arai_a@mac.com> +Date: Sun Mar 25 17:23:48 2018 +0900 + + Bug 1402380 - Set text/x-moz-url flavor of data transfer for places container with URLs inside it. r=enndeakin, a=jcristau + + --HG-- + extra : source : e4cc022b417a1268fa063fe054aa79f3c141c2e2 +--- + .../components/places/tests/browser/browser.ini | 1 + + .../tests/browser/browser_drag_folder_on_newTab.js | 94 ++++++++++++++++++++++ + testing/mochitest/tests/SimpleTest/EventUtils.js | 86 ++++++++++++++++++++ + toolkit/components/places/PlacesUtils.jsm | 11 ++- + 4 files changed, 191 insertions(+), 1 deletion(-) + +diff --git browser/components/places/tests/browser/browser.ini browser/components/places/tests/browser/browser.ini +index 64b7782c5f83..33c4cf5cc416 100644 +--- browser/components/places/tests/browser/browser.ini ++++ browser/components/places/tests/browser/browser.ini +@@ -63,3 +63,4 @@ support-files = + support-files = + bookmark_dummy_1.html + bookmark_dummy_2.html ++[browser_drag_folder_on_newTab.js] +diff --git browser/components/places/tests/browser/browser_drag_folder_on_newTab.js browser/components/places/tests/browser/browser_drag_folder_on_newTab.js +new file mode 100644 +index 000000000000..00646fff18b4 +--- /dev/null ++++ browser/components/places/tests/browser/browser_drag_folder_on_newTab.js +@@ -0,0 +1,94 @@ ++/* Any copyright is dedicated to the Public Domain. ++ * http://creativecommons.org/publicdomain/zero/1.0/ */ ++ ++"use strict"; ++ ++add_task(async function setup() { ++ let toolbar = document.getElementById("PersonalToolbar"); ++ let wasCollapsed = toolbar.collapsed; ++ ++ // Uncollapse the personal toolbar if needed. ++ if (wasCollapsed) { ++ await promiseSetToolbarVisibility(toolbar, true); ++ } ++ ++ // Clean before and after so we don't have anything in the folders. ++ await PlacesUtils.bookmarks.eraseEverything(); ++ ++ registerCleanupFunction(async function() { ++ // Collapse the personal toolbar if needed. ++ if (wasCollapsed) { ++ await promiseSetToolbarVisibility(toolbar, false); ++ } ++ ++ await PlacesUtils.bookmarks.eraseEverything(); ++ }); ++}); ++ ++const TEST_FOLDER_NAME = "Test folder"; ++ ++add_task(async function test_change_location_from_Toolbar() { ++ let newTabButton = document.getElementById("new-tab-button"); ++ ++ let children = [ ++ { ++ title: "first", ++ url: "http://www.mochi.test/first" ++ }, ++ { ++ title: "second", ++ url: "http://www.mochi.test/second" ++ }, ++ { ++ type: PlacesUtils.bookmarks.TYPE_SEPARATOR, ++ }, ++ { ++ title: "third", ++ url: "http://www.mochi.test/third" ++ }, ++ ]; ++ let guid = PlacesUtils.history.makeGuid(); ++ await PlacesUtils.bookmarks.insertTree({ ++ guid: PlacesUtils.bookmarks.toolbarGuid, ++ children: [ ++ { ++ guid, ++ type: PlacesUtils.bookmarks.TYPE_FOLDER, ++ title: TEST_FOLDER_NAME, ++ children, ++ }, ++ ], ++ }); ++ ++ let folder = getToolbarNodeForItemGuid(guid); ++ ++ let loadedPromises = children.filter(item => "url" in item).map( ++ item => BrowserTestUtils.waitForNewTab(gBrowser, item.url, false, true)); ++ ++ let srcX = 10, srcY = 10; ++ // We should drag upwards, since dragging downwards opens menu instead. ++ let stepX = 0, stepY = -5; ++ ++ // We need to dispatch mousemove before dragging, to populate ++ // PlacesToolbar._cachedMouseMoveEvent, with the cursor position after the ++ // first step, so that the places code detects it as dragging upward. ++ EventUtils.synthesizeMouse(folder, srcX + stepX, srcY + stepY, ++ { type: "mousemove" }); ++ ++ await EventUtils.synthesizePlainDragAndDrop({ ++ srcElement: folder, ++ destElement: newTabButton, ++ srcX, ++ srcY, ++ stepX, ++ stepY, ++ }); ++ ++ let tabs = await Promise.all(loadedPromises); ++ ++ for (let tab of tabs) { ++ BrowserTestUtils.removeTab(tab); ++ } ++ ++ ok(true); ++}); +diff --git testing/mochitest/tests/SimpleTest/EventUtils.js testing/mochitest/tests/SimpleTest/EventUtils.js +index cad43966d91d..907cf60dc254 100644 +--- testing/mochitest/tests/SimpleTest/EventUtils.js ++++ testing/mochitest/tests/SimpleTest/EventUtils.js +@@ -17,6 +17,7 @@ + * synthesizeMouseExpectEvent + * synthesizeKeyExpectEvent + * synthesizeNativeOSXClick ++ * synthesizePlainDragAndDrop + * + * When adding methods to this file, please add a performance test for it. + */ +@@ -2161,6 +2162,91 @@ function synthesizeDrop(aSrcElement, aDestElement, aDragData, aDropEffect, aWind + } + } + ++/** ++ * Emulate a drag and drop by emulating a dragstart by mousedown and mousemove, ++ * and firing events dragenter, dragover, drop, and mouseup. ++ * This does not modify dataTransfer and tries to emulate the plain drag and ++ * drop as much as possible, compared to synthesizeDrop. ++ * ++ * @param aParams ++ * { ++ * srcElement: The element to start dragging ++ * destElement: The element to drop on ++ * srcX: The initial x coordinate inside srcElement ++ * srcY: The initial y coordinate inside srcElement ++ * stepX: The x-axis step for mousemove inside srcElement ++ * stepY: The y-axis step for mousemove inside srcElement ++ * destX: The x coordinate inside destElement ++ * destY: The x coordinate inside destElement ++ * srcWindow: The window for dispatching event on srcElement, ++ * defaults to the current window object ++ * destWindow: The window for dispatching event on destElement, ++ * defaults to the current window object ++ * } ++ */ ++async function synthesizePlainDragAndDrop(aParams) ++{ ++ let { ++ srcElement, ++ destElement, ++ srcX = 2, ++ srcY = 2, ++ stepX = 9, ++ stepY = 9, ++ destX = 2, ++ destY = 2, ++ srcWindow = window, ++ destWindow = window, ++ } = aParams; ++ ++ const ds = _EU_Cc["@mozilla.org/widget/dragservice;1"] ++ .getService(_EU_Ci.nsIDragService); ++ ds.startDragSession(); ++ ++ try { ++ let dataTransfer = null; ++ function trapDrag(aEvent) { ++ dataTransfer = aEvent.dataTransfer; ++ } ++ srcElement.addEventListener("dragstart", trapDrag, true); ++ synthesizeMouse(srcElement, srcX, srcY, { type: "mousedown" }, srcWindow); ++ ++ // Wait for the next event tick after each event dispatch, so that UI elements ++ // (e.g. menu) work like the real user input. ++ await new Promise(r => setTimeout(r, 0)); ++ ++ srcX += stepX; srcY += stepY; ++ synthesizeMouse(srcElement, srcX, srcY, { type: "mousemove" }, srcWindow); ++ ++ await new Promise(r => setTimeout(r, 0)); ++ ++ srcX += stepX; srcY += stepY; ++ synthesizeMouse(srcElement, srcX, srcY, { type: "mousemove" }, srcWindow); ++ ++ await new Promise(r => setTimeout(r, 0)); ++ ++ srcElement.removeEventListener("dragstart", trapDrag, true); ++ ++ await new Promise(r => setTimeout(r, 0)); ++ ++ let event = createDragEventObject("dragover", destElement, destWindow, ++ dataTransfer, {}); ++ sendDragEvent(event, destElement, destWindow); ++ ++ await new Promise(r => setTimeout(r, 0)); ++ ++ event = createDragEventObject("drop", destElement, destWindow, ++ dataTransfer, {}); ++ sendDragEvent(event, destElement, destWindow); ++ ++ await new Promise(r => setTimeout(r, 0)); ++ ++ synthesizeMouseAtCenter(destElement, { type: "mouseup" }, destWindow); ++ } finally { ++ ds.endDragSession(true, 0); ++ } ++} ++ + var PluginUtils = + { + withTestPlugin : function(callback) +diff --git toolkit/components/places/PlacesUtils.jsm toolkit/components/places/PlacesUtils.jsm +index f6315f68eb4c..5aebe0496ee8 100644 +--- toolkit/components/places/PlacesUtils.jsm ++++ toolkit/components/places/PlacesUtils.jsm +@@ -896,6 +896,11 @@ this.PlacesUtils = { + case this.TYPE_X_MOZ_URL: { + if (aFeedURI || PlacesUtils.nodeIsURI(aNode)) + return (aFeedURI || aNode.uri) + NEWLINE + aNode.title; ++ if (PlacesUtils.nodeIsContainer(aNode)) { ++ return PlacesUtils.getURLsForContainerNode(aNode) ++ .map(item => item.uri + "\n" + item.title) ++ .join("\n"); ++ } + return ""; + } + case this.TYPE_HTML: { +@@ -1491,7 +1496,11 @@ this.PlacesUtils = { + for (let i = 0; i < root.childCount; ++i) { + let child = root.getChild(i); + if (this.nodeIsURI(child)) +- urls.push({uri: child.uri, isBookmark: this.nodeIsBookmark(child)}); ++ urls.push({ ++ uri: child.uri, ++ isBookmark: this.nodeIsBookmark(child), ++ title: child.title, ++ }); + } + + if (!wasOpen) { diff --git a/www/waterfox/files/patch-bug1409440 b/www/waterfox/files/patch-bug1409440 new file mode 100644 index 000000000000..48c39a66876e --- /dev/null +++ b/www/waterfox/files/patch-bug1409440 @@ -0,0 +1,89 @@ +commit 362d0bb251e6 +Author: Andrew Osmond <aosmond@mozilla.com> +Date: Tue Mar 27 09:01:14 2018 -0400 + + Bug 1409440. r=tnikkel, a=RyanVM + + --HG-- + extra : source : 52c14d32d9812951c12d92b2594056fc15c5de80 +--- + image/Downscaler.cpp | 14 ++++++++++---- + image/DownscalingFilter.h | 14 ++++++++++---- + 2 files changed, 20 insertions(+), 8 deletions(-) + +diff --git image/Downscaler.cpp image/Downscaler.cpp +index 475d18319a19..f97d067720b6 100644 +--- image/Downscaler.cpp ++++ image/Downscaler.cpp +@@ -195,13 +195,14 @@ Downscaler::CommitRow() + int32_t inLineToRead = filterOffset + mLinesInBuffer; + MOZ_ASSERT(mCurrentInLine <= inLineToRead, "Reading past end of input"); + if (mCurrentInLine == inLineToRead) { ++ MOZ_RELEASE_ASSERT(mLinesInBuffer < mWindowCapacity, "Need more rows than capacity!"); + mXFilter.ConvolveHorizontally(mRowBuffer.get(), mWindow[mLinesInBuffer++], mHasAlpha); + } + + MOZ_ASSERT(mCurrentOutLine < mTargetSize.height, + "Writing past end of output"); + +- while (mLinesInBuffer == filterLength) { ++ while (mLinesInBuffer >= filterLength) { + DownscaleInputLine(); + + if (mCurrentOutLine == mTargetSize.height) { +@@ -297,9 +298,14 @@ Downscaler::DownscaleInputLine() + + // Shift the buffer. We're just moving pointers here, so this is cheap. + mLinesInBuffer -= diff; +- mLinesInBuffer = max(mLinesInBuffer, 0); +- for (int32_t i = 0; i < mLinesInBuffer; ++i) { +- swap(mWindow[i], mWindow[filterLength - mLinesInBuffer + i]); ++ mLinesInBuffer = min(max(mLinesInBuffer, 0), mWindowCapacity); ++ ++ // If we already have enough rows to satisfy the filter, there is no need ++ // to swap as we won't be writing more before the next convolution. ++ if (filterLength > mLinesInBuffer) { ++ for (int32_t i = 0; i < mLinesInBuffer; ++i) { ++ swap(mWindow[i], mWindow[filterLength - mLinesInBuffer + i]); ++ } + } + } + +diff --git image/DownscalingFilter.h image/DownscalingFilter.h +index 6f516d0e0d90..764aade2e63b 100644 +--- image/DownscalingFilter.h ++++ image/DownscalingFilter.h +@@ -232,13 +232,14 @@ protected: + int32_t inputRowToRead = filterOffset + mRowsInWindow; + MOZ_ASSERT(mInputRow <= inputRowToRead, "Reading past end of input"); + if (mInputRow == inputRowToRead) { ++ MOZ_RELEASE_ASSERT(mRowsInWindow < mWindowCapacity, "Need more rows than capacity!"); + mXFilter.ConvolveHorizontally(mRowBuffer.get(), mWindow[mRowsInWindow++], mHasAlpha); + } + + MOZ_ASSERT(mOutputRow < mNext.InputSize().height, + "Writing past end of output"); + +- while (mRowsInWindow == filterLength) { ++ while (mRowsInWindow >= filterLength) { + DownscaleInputRow(); + + if (mOutputRow == mNext.InputSize().height) { +@@ -297,9 +298,14 @@ private: + + // Shift the buffer. We're just moving pointers here, so this is cheap. + mRowsInWindow -= diff; +- mRowsInWindow = std::max(mRowsInWindow, 0); +- for (int32_t i = 0; i < mRowsInWindow; ++i) { +- std::swap(mWindow[i], mWindow[filterLength - mRowsInWindow + i]); ++ mRowsInWindow = std::min(std::max(mRowsInWindow, 0), mWindowCapacity); ++ ++ // If we already have enough rows to satisfy the filter, there is no need ++ // to swap as we won't be writing more before the next convolution. ++ if (filterLength > mRowsInWindow) { ++ for (int32_t i = 0; i < mRowsInWindow; ++i) { ++ std::swap(mWindow[i], mWindow[filterLength - mRowsInWindow + i]); ++ } + } + } + diff --git a/www/waterfox/files/patch-bug1416045 b/www/waterfox/files/patch-bug1416045 new file mode 100644 index 000000000000..0d41443faa5c --- /dev/null +++ b/www/waterfox/files/patch-bug1416045 @@ -0,0 +1,338 @@ +commit 5d7b84950d03 +Author: vinoth <cegvinoth@gmail.com> +Date: Thu Mar 22 21:02:16 2018 +0200 + + Bug 1416045. r=mayhemer, a=RyanVM + + Reviewers: mayhemer + + Reviewed By: mayhemer + + Subscribers: freddyb, dveditz, mayhemer, ckerschb, vinoth + + Tags: PHID-PROJ-wkydohdk6pajyfn2llkb + + Bug #: 1416045 + + Differential Revision: https://phabricator.services.mozilla.com/D675 + + --HG-- + extra : source : a0a2092724797e534549cc2d80dc9c423bfaf43d + extra : amend_source : f1ddea498e322b79b6d1b9af45c7e04832f43ed1 +--- + .../test/csp/file_multipart_testserver.sjs | 110 ++++++++++++++++++++- + dom/security/test/csp/test_multipartchannel.html | 42 +++++++- + netwerk/streamconv/converters/nsMultiMixedConv.cpp | 36 +++++++ + netwerk/streamconv/converters/nsMultiMixedConv.h | 3 + + 4 files changed, 182 insertions(+), 9 deletions(-) + +diff --git dom/security/test/csp/file_multipart_testserver.sjs dom/security/test/csp/file_multipart_testserver.sjs +index d2eb58c82b52..3934df0a9572 100644 +--- dom/security/test/csp/file_multipart_testserver.sjs ++++ dom/security/test/csp/file_multipart_testserver.sjs +@@ -1,8 +1,11 @@ + // SJS file specifically for the needs of bug +-// Bug 1223743 - CSP: Check baseChannel for CSP when loading multipart channel ++// Bug 1416045/Bug 1223743 - CSP: Check baseChannel for CSP when loading multipart channel + + var CSP = "script-src 'unsafe-inline', img-src 'none'"; +-var BOUNDARY = "fooboundary" ++var rootCSP = "script-src 'unsafe-inline'"; ++var part1CSP = "img-src *"; ++var part2CSP = "img-src 'none'"; ++var BOUNDARY = "fooboundary"; + + // small red image + const IMG_BYTES = atob( +@@ -14,16 +17,72 @@ var RESPONSE = ` + var myImg = new Image; + myImg.src = "file_multipart_testserver.sjs?img"; + myImg.onerror = function(e) { +- window.parent.postMessage("img-blocked", "*"); ++ window.parent.postMessage({"test": "rootCSP_test", ++ "msg": "img-blocked"}, "*"); + }; + myImg.onload = function() { +- window.parent.postMessage("img-loaded", "*"); ++ window.parent.postMessage({"test": "rootCSP_test", ++ "msg": "img-loaded"}, "*"); + }; + document.body.appendChild(myImg); + </script> + `; + +-var myTimer; ++var RESPONSE1 = ` ++ <body> ++ <script> ++ var triggerNextPartFrame = document.createElement('iframe'); ++ var myImg = new Image; ++ myImg.src = "file_multipart_testserver.sjs?img"; ++ myImg.onerror = function(e) { ++ window.parent.postMessage({"test": "part1CSP_test", ++ "msg": "part1-img-blocked"}, "*"); ++ triggerNextPartFrame.src = 'file_multipart_testserver.sjs?sendnextpart'; ++ }; ++ myImg.onload = function() { ++ window.parent.postMessage({"test": "part1CSP_test", ++ "msg": "part1-img-loaded"}, "*"); ++ triggerNextPartFrame.src = 'file_multipart_testserver.sjs?sendnextpart'; ++ }; ++ document.body.appendChild(myImg); ++ document.body.appendChild(triggerNextPartFrame); ++ </script> ++ </body> ++`; ++ ++var RESPONSE2 = ` ++ <body> ++ <script> ++ var myImg = new Image; ++ myImg.src = "file_multipart_testserver.sjs?img"; ++ myImg.onerror = function(e) { ++ window.parent.postMessage({"test": "part2CSP_test", ++ "msg": "part2-img-blocked"}, "*"); ++ }; ++ myImg.onload = function() { ++ window.parent.postMessage({"test": "part2CSP_test", ++ "msg": "part2-img-loaded"}, "*"); ++ }; ++ document.body.appendChild(myImg); ++ </script> ++ </body> ++`; ++ ++function setGlobalState(data, key) ++{ ++ x = { data: data, QueryInterface: function(iid) { return this } }; ++ x.wrappedJSObject = x; ++ setObjectState(key, x); ++} ++ ++function getGlobalState(key) ++{ ++ var data; ++ getObjectState(key, function(x) { ++ data = x && x.wrappedJSObject.data; ++ }); ++ return data; ++} + + function handleRequest(request, response) + { +@@ -39,6 +98,29 @@ function handleRequest(request, response) + return; + } + ++ if (request.queryString == "partcspdoc") { ++ response.setHeader("Content-Security-Policy", rootCSP, false); ++ response.setHeader("Content-Type", ++ "multipart/x-mixed-replace; boundary=" + BOUNDARY, false); ++ response.setStatusLine(request.httpVersion, 200, "OK"); ++ response.processAsync(); ++ response.write("--"+BOUNDARY+"\r\n"); ++ sendNextPart(response, 1); ++ return; ++ } ++ ++ if (request.queryString == "sendnextpart") { ++ response.setStatusLine(request.httpVersion, 204, "No content"); ++ var blockedResponse = getGlobalState("root-document-response"); ++ if (typeof blockedResponse == "object") { ++ sendNextPart(blockedResponse, 2); ++ sendClose(blockedResponse); ++ } else { ++ dump("Couldn't find the stored response object."); ++ } ++ return; ++ } ++ + if (request.queryString == "img") { + response.setHeader("Content-Type", "image/png"); + response.write(IMG_BYTES); +@@ -48,3 +130,21 @@ function handleRequest(request, response) + // we should never get here - return something unexpected + response.write("d'oh"); + } ++ ++function sendClose(response) { ++ response.write("--"+BOUNDARY+"--\r\n"); ++ response.finish(); ++} ++ ++function sendNextPart(response, partNumber) { ++ response.write("Content-type: text/html" + "\r\n"); ++ if (partNumber == 1) { ++ response.write("Content-Security-Policy:" + part1CSP + "\r\n"); ++ response.write(RESPONSE1); ++ setGlobalState(response, "root-document-response"); ++ } else { ++ response.write("Content-Security-Policy:" + part2CSP + "\r\n"); ++ response.write(RESPONSE2); ++ } ++ response.write("--"+BOUNDARY+"\r\n"); ++} +diff --git dom/security/test/csp/test_multipartchannel.html dom/security/test/csp/test_multipartchannel.html +index 120f9712d0e0..1c03157cc0b4 100644 +--- dom/security/test/csp/test_multipartchannel.html ++++ dom/security/test/csp/test_multipartchannel.html +@@ -2,32 +2,66 @@ + <html> + <head> + <meta charset="utf-8"> +- <title>Bug 1223743 - CSP: Check baseChannel for CSP when loading multipart channel</title> ++ <title>Bug 1416045/Bug 1223743 - CSP: Check baseChannel for CSP when loading multipart channel</title> + <!-- Including SimpleTest.js so we can use waitForExplicitFinish !--> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + </head> + <body> + <iframe style="width:100%;" id="testframe"></iframe> ++<iframe style="width:100%;" id="testPartCSPframe"></iframe> + + <script class="testbody" type="text/javascript"> + ++var testsToRunMultipartCSP = { ++ rootCSP_test: false, ++ part1CSP_test: false, ++ part2CSP_test: false, ++}; ++ + SimpleTest.waitForExplicitFinish(); + ++function checkTestsCompleted() { ++ for (var prop in testsToRunMultipartCSP) { ++ // some test hasn't run yet so we're not done ++ if (!testsToRunMultipartCSP[prop]) { ++ return; ++ } ++ } ++ window.removeEventListener("message", receiveMessage); ++ SimpleTest.finish(); ++} + /* Description of the test: + * We apply a CSP to a multipart channel and then try to load an image + * within a segment making sure the image is blocked correctly by CSP. ++ * We also provide CSP for each part and try to load an image in each ++ * part and make sure the image is loaded in first part and blocked in ++ * second part correctly based on its CSP accordingly. + */ + + window.addEventListener("message", receiveMessage); + function receiveMessage(event) { +- is(event.data, "img-blocked", "image should be blocked"); +- window.removeEventListener("message", receiveMessage); +- SimpleTest.finish(); ++ switch (event.data.test) { ++ case "rootCSP_test": ++ is(event.data.msg, "img-blocked", "image should be blocked"); ++ testsToRunMultipartCSP["rootCSP_test"] = true; ++ break; ++ case "part1CSP_test": ++ is(event.data.msg, "part1-img-loaded", "Part1 image should be loaded"); ++ testsToRunMultipartCSP["part1CSP_test"] = true; ++ break; ++ case "part2CSP_test": ++ is(event.data.msg, "part2-img-blocked", "Part2 image should be blocked"); ++ testsToRunMultipartCSP["part2CSP_test"] = true; ++ break; ++ } ++ checkTestsCompleted(); + } + + // start the test + document.getElementById("testframe").src = "file_multipart_testserver.sjs?doc"; ++document.getElementById("testPartCSPframe").src = ++ "file_multipart_testserver.sjs?partcspdoc"; + + </script> + </body> +diff --git netwerk/streamconv/converters/nsMultiMixedConv.cpp netwerk/streamconv/converters/nsMultiMixedConv.cpp +index 1af800eb8d90..80cb030a6fab 100644 +--- netwerk/streamconv/converters/nsMultiMixedConv.cpp ++++ netwerk/streamconv/converters/nsMultiMixedConv.cpp +@@ -488,6 +488,12 @@ nsMultiMixedConv::OnStartRequest(nsIRequest *request, nsISupports *ctxt) + if (NS_FAILED(rv)) { + return rv; + } ++ nsCString csp; ++ rv = httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("content-security-policy"), ++ csp); ++ if (NS_SUCCEEDED(rv)) { ++ mRootContentSecurityPolicy = csp; ++ } + } else { + // try asking the channel directly + rv = mChannel->GetContentType(contentType); +@@ -528,6 +534,10 @@ nsMultiMixedConv::OnStartRequest(nsIRequest *request, nsISupports *ctxt) + mTokenizer.AddCustomToken("content-range", mTokenizer.CASE_INSENSITIVE, false); + mHeaderTokens[HEADER_RANGE] = + mTokenizer.AddCustomToken("range", mTokenizer.CASE_INSENSITIVE, false); ++ mHeaderTokens[HEADER_CONTENT_SECURITY_POLICY] = ++ mTokenizer.AddCustomToken("content-security-policy", ++ mTokenizer.CASE_INSENSITIVE, ++ false); + + mLFToken = mTokenizer.AddCustomToken("\n", mTokenizer.CASE_SENSITIVE, false); + mCRLFToken = mTokenizer.AddCustomToken("\r\n", mTokenizer.CASE_SENSITIVE, false); +@@ -1001,6 +1011,7 @@ nsMultiMixedConv::HeadersToDefault() + mContentLength = UINT64_MAX; + mContentType.Truncate(); + mContentDisposition.Truncate(); ++ mContentSecurityPolicy.Truncate(); + mIsByteRangeRequest = false; + } + +@@ -1053,6 +1064,31 @@ nsMultiMixedConv::ProcessHeader() + } + break; + } ++ case HEADER_CONTENT_SECURITY_POLICY: { ++ mContentSecurityPolicy = mResponseHeaderValue; ++ mContentSecurityPolicy.CompressWhitespace(); ++ nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(mChannel); ++ if (httpChannel) { ++ nsCString resultCSP = mRootContentSecurityPolicy; ++ if (!mContentSecurityPolicy.IsEmpty()) { ++ // We are updating the root channel CSP header respectively for ++ // each part as: CSP-root + CSP-partN, where N is the part number. ++ // Here we append current part's CSP to root CSP and reset CSP ++ // header for each part. ++ if (!resultCSP.IsEmpty()) { ++ resultCSP.Append(";"); ++ } ++ resultCSP.Append(mContentSecurityPolicy); ++ } ++ nsresult rv = httpChannel->SetResponseHeader( ++ NS_LITERAL_CSTRING("Content-Security-Policy"), ++ resultCSP, false); ++ if (NS_FAILED(rv)) { ++ return NS_ERROR_CORRUPTED_CONTENT; ++ } ++ } ++ break; ++ } + case HEADER_UNKNOWN: + // We ignore anything else... + break; +diff --git netwerk/streamconv/converters/nsMultiMixedConv.h netwerk/streamconv/converters/nsMultiMixedConv.h +index b46a094608a5..fdd7e73c7fd1 100644 +--- netwerk/streamconv/converters/nsMultiMixedConv.h ++++ netwerk/streamconv/converters/nsMultiMixedConv.h +@@ -151,6 +151,8 @@ protected: + nsCOMPtr<nsISupports> mContext; + nsCString mContentType; + nsCString mContentDisposition; ++ nsCString mContentSecurityPolicy; ++ nsCString mRootContentSecurityPolicy; + uint64_t mContentLength; + uint64_t mTotalSent; + +@@ -198,6 +200,7 @@ protected: + HEADER_SET_COOKIE, + HEADER_CONTENT_RANGE, + HEADER_RANGE, ++ HEADER_CONTENT_SECURITY_POLICY, + HEADER_UNKNOWN + } mResponseHeader; + // Cumulated value of a response header. diff --git a/www/waterfox/files/patch-bug1433609 b/www/waterfox/files/patch-bug1433609 new file mode 100644 index 000000000000..0b6ecc63e18b --- /dev/null +++ b/www/waterfox/files/patch-bug1433609 @@ -0,0 +1,103 @@ +commit 9d65f87e8479 +Author: Valentin Gosu <valentin.gosu@gmail.com> +Date: Wed Feb 14 14:40:05 2018 +0100 + + Bug 1433609 - Ensure that deserialized URL is correct. r=mayhemer, a=RyanVM + + MozReview-Commit-ID: BMQfPzPhDhc + + --HG-- + extra : source : d0da2be2c9508f48b8e4804bd4a4ca3b37b56d4f +--- + netwerk/base/nsStandardURL.cpp | 64 ++++++++++++++++++++++++++++++++---------- + 1 file changed, 49 insertions(+), 15 deletions(-) + +diff --git netwerk/base/nsStandardURL.cpp netwerk/base/nsStandardURL.cpp +index 85ab13fed7ae..67dc701e7272 100644 +--- netwerk/base/nsStandardURL.cpp ++++ netwerk/base/nsStandardURL.cpp +@@ -3726,10 +3726,29 @@ ToIPCSegment(const nsStandardURL::URLSegment& aSegment) + } + + inline +-nsStandardURL::URLSegment +-FromIPCSegment(const ipc::StandardURLSegment& aSegment) ++MOZ_MUST_USE bool ++FromIPCSegment(const nsACString& aSpec, const ipc::StandardURLSegment& aSegment, nsStandardURL::URLSegment& aTarget) + { +- return nsStandardURL::URLSegment(aSegment.position(), aSegment.length()); ++ // This seems to be just an empty segment. ++ if (aSegment.length() == -1) { ++ aTarget = nsStandardURL::URLSegment(); ++ return true; ++ } ++ ++ // A value of -1 means an empty segment, but < -1 is undefined. ++ if (NS_WARN_IF(aSegment.length() < -1)) { ++ return false; ++ } ++ ++ // Make sure the segment does not extend beyond the spec. ++ if (NS_WARN_IF(aSegment.position() + aSegment.length() > aSpec.Length())) { ++ return false; ++ } ++ ++ aTarget.mPos = aSegment.position(); ++ aTarget.mLen = aSegment.length(); ++ ++ return true; + } + + void +@@ -3797,24 +3816,39 @@ nsStandardURL::Deserialize(const URIParams& aParams) + mPort = params.port(); + mDefaultPort = params.defaultPort(); + mSpec = params.spec(); +- mScheme = FromIPCSegment(params.scheme()); +- mAuthority = FromIPCSegment(params.authority()); +- mUsername = FromIPCSegment(params.username()); +- mPassword = FromIPCSegment(params.password()); +- mHost = FromIPCSegment(params.host()); +- mPath = FromIPCSegment(params.path()); +- mFilepath = FromIPCSegment(params.filePath()); +- mDirectory = FromIPCSegment(params.directory()); +- mBasename = FromIPCSegment(params.baseName()); +- mExtension = FromIPCSegment(params.extension()); +- mQuery = FromIPCSegment(params.query()); +- mRef = FromIPCSegment(params.ref()); ++ ++ NS_ENSURE_TRUE(mSpec.Length() <= (uint32_t) net_GetURLMaxLength(), false); ++ NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.scheme(), mScheme), false); ++ NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.authority(), mAuthority), false); ++ NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.username(), mUsername), false); ++ NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.password(), mPassword), false); ++ NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.host(), mHost), false); ++ NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.path(), mPath), false); ++ NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.filePath(), mFilepath), false); ++ NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.directory(), mDirectory), false); ++ NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.baseName(), mBasename), false); ++ NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.extension(), mExtension), false); ++ NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.query(), mQuery), false); ++ NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.ref(), mRef), false); ++ + mOriginCharset = params.originCharset(); + mMutable = params.isMutable(); + mSupportsFileURL = params.supportsFileURL(); + + CALL_RUST_SYNC; + ++ // Some sanity checks ++ NS_ENSURE_TRUE(mScheme.mPos == 0, false); ++ NS_ENSURE_TRUE(mScheme.mLen > 0, false); ++ // Make sure scheme is followed by :// (3 characters) ++ NS_ENSURE_TRUE(mScheme.mLen < INT32_MAX - 3, false); // avoid overflow ++ NS_ENSURE_TRUE(mSpec.Length() >= (uint32_t) mScheme.mLen + 3, false); ++ NS_ENSURE_TRUE(nsDependentCSubstring(mSpec, mScheme.mLen, 3).EqualsLiteral("://"), false); ++ NS_ENSURE_TRUE(mPath.mLen != -1 && mSpec.CharAt(mPath.mPos) == '/', false); ++ NS_ENSURE_TRUE(mPath.mPos == mFilepath.mPos, false); ++ NS_ENSURE_TRUE(mQuery.mLen == -1 || mSpec.CharAt(mQuery.mPos - 1) == '?', false); ++ NS_ENSURE_TRUE(mRef.mLen == -1 || mSpec.CharAt(mRef.mPos - 1) == '#', false); ++ + // mSpecEncoding and mDisplayHost are just caches that can be recovered as needed. + return true; + } diff --git a/www/waterfox/files/patch-bug1441941 b/www/waterfox/files/patch-bug1441941 new file mode 100644 index 000000000000..14b1f9ec8e83 --- /dev/null +++ b/www/waterfox/files/patch-bug1441941 @@ -0,0 +1,252 @@ +commit e75ef89e7d0f +Author: Lee Salzman <lsalzman@mozilla.com> +Date: Wed Mar 28 00:34:13 2018 -0400 + + Bug 1441941 - Limit allocations in SkTDArray. r=jrmuizel, a=RyanVM +--- + gfx/skia/skia/include/core/SkTypes.h | 6 ++ + gfx/skia/skia/include/private/SkTDArray.h | 8 ++- + gfx/skia/skia/src/core/SkMallocPixelRef.cpp | 13 ++++ + gfx/skia/skia/src/core/SkMath.cpp | 15 ++++ + gfx/skia/skia/src/core/SkSafeMath.h | 106 ++++++++++++++++++++++++++++ + 5 files changed, 145 insertions(+), 3 deletions(-) + +diff --git gfx/skia/skia/include/core/SkTypes.h gfx/skia/skia/include/core/SkTypes.h +index beb2be51432b..ed138f930fd3 100644 +--- gfx/skia/skia/include/core/SkTypes.h ++++ gfx/skia/skia/include/core/SkTypes.h +@@ -235,6 +235,7 @@ template <typename D, typename S> D SkTo(S s) { + #define SK_MaxU32 0xFFFFFFFF + #define SK_MinU32 0 + #define SK_NaN32 ((int) (1U << 31)) ++#define SK_MaxSizeT SIZE_MAX + + /** Returns true if the value can be represented with signed 16bits + */ +diff --git gfx/skia/skia/include/private/SkMalloc.h gfx/skia/skia/include/private/SkMalloc.h +index ee5590063bc8..19d29634bd70 100644 +--- gfx/skia/skia/include/private/SkMalloc.h ++++ gfx/skia/skia/include/private/SkMalloc.h +@@ -46,6 +46,11 @@ SK_API extern void* sk_calloc(size_t size); + */ + SK_API extern void* sk_calloc_throw(size_t size); + ++// Performs a safe multiply count * elemSize, checking for overflow ++SK_API extern void* sk_calloc_throw(size_t count, size_t elemSize); ++SK_API extern void* sk_malloc_throw(size_t count, size_t elemSize); ++SK_API extern void* sk_realloc_throw(void* buffer, size_t count, size_t elemSize); ++ + /** Called internally if we run out of memory. The platform implementation must + not return, but should either throw an exception or otherwise exit. + */ +diff --git gfx/skia/skia/include/private/SkTDArray.h gfx/skia/skia/include/private/SkTDArray.h +index 4c58d478fe63..36986d81e9fe 100644 +--- gfx/skia/skia/include/private/SkTDArray.h ++++ gfx/skia/skia/include/private/SkTDArray.h +@@ -22,7 +22,7 @@ public: + fReserve = fCount = 0; + fArray = NULL; + if (count) { +- fArray = (T*)sk_malloc_throw(count * sizeof(T)); ++ fArray = (T*)sk_malloc_throw(count, sizeof(T)); + memcpy(fArray, src, sizeof(T) * count); + fReserve = fCount = count; + } +@@ -353,7 +353,7 @@ public: + + void shrinkToFit() { + fReserve = fCount; +- fArray = (T*)sk_realloc_throw(fArray, fReserve * sizeof(T)); ++ fArray = (T*)sk_realloc_throw(fArray, fReserve, sizeof(T)); + } + + private: +@@ -366,6 +366,7 @@ private: + * This is the same as calling setCount(count() + delta). + */ + void adjustCount(int delta) { ++ SkASSERT_RELEASE(fCount <= std::numeric_limits<int>::max() - delta); + this->setCount(fCount + delta); + } + +@@ -379,9 +380,10 @@ private: + */ + void resizeStorageToAtLeast(int count) { + SkASSERT(count > fReserve); ++ SkASSERT_RELEASE(count <= std::numeric_limits<int>::max() - std::numeric_limits<int>::max() / 5 - 4); + fReserve = count + 4; + fReserve += fReserve / 4; +- fArray = (T*)sk_realloc_throw(fArray, fReserve * sizeof(T)); ++ fArray = (T*)sk_realloc_throw(fArray, fReserve, sizeof(T)); + } + }; + +diff --git gfx/skia/skia/src/core/SkMallocPixelRef.cpp gfx/skia/skia/src/core/SkMallocPixelRef.cpp +index ed3a97b7e0f5..c2da0ecec8bb 100644 +--- gfx/skia/skia/src/core/SkMallocPixelRef.cpp ++++ gfx/skia/skia/src/core/SkMallocPixelRef.cpp +@@ -8,8 +8,21 @@ + #include "SkMallocPixelRef.h" + #include "SkBitmap.h" + #include "SkReadBuffer.h" ++#include "SkSafeMath.h" + #include "SkWriteBuffer.h" + ++void* sk_calloc_throw(size_t count, size_t elemSize) { ++ return sk_calloc_throw(SkSafeMath::Mul(count, elemSize)); ++} ++ ++void* sk_malloc_throw(size_t count, size_t elemSize) { ++ return sk_malloc_throw(SkSafeMath::Mul(count, elemSize)); ++} ++ ++void* sk_realloc_throw(void* buffer, size_t count, size_t elemSize) { ++ return sk_realloc_throw(buffer, SkSafeMath::Mul(count, elemSize)); ++} ++ + // assumes ptr was allocated via sk_malloc + static void sk_free_releaseproc(void* ptr, void*) { + sk_free(ptr); +diff --git gfx/skia/skia/src/core/SkMath.cpp gfx/skia/skia/src/core/SkMath.cpp +index 6eff790c85c5..2196d6913c9c 100644 +--- gfx/skia/skia/src/core/SkMath.cpp ++++ gfx/skia/skia/src/core/SkMath.cpp +@@ -9,6 +9,7 @@ + #include "SkFixed.h" + #include "SkFloatBits.h" + #include "SkFloatingPoint.h" ++#include "SkSafeMath.h" + #include "SkScalar.h" + + #define sub_shift(zeros, x, n) \ +@@ -84,3 +85,18 @@ float SkScalarSinCos(float radians, float* cosValue) { + } + return sinValue; + } ++ ++/////////////////////////////////////////////////////////////////////////////////////////////////// ++ ++size_t SkSafeMath::Add(size_t x, size_t y) { ++ SkSafeMath tmp; ++ size_t sum = tmp.add(x, y); ++ return tmp.ok() ? sum : SK_MaxSizeT; ++} ++ ++size_t SkSafeMath::Mul(size_t x, size_t y) { ++ SkSafeMath tmp; ++ size_t prod = tmp.mul(x, y); ++ return tmp.ok() ? prod : SK_MaxSizeT; ++} ++ +diff --git gfx/skia/skia/src/core/SkSafeMath.h gfx/skia/skia/src/core/SkSafeMath.h +new file mode 100644 +index 000000000000..0bc0fbfac473 +--- /dev/null ++++ gfx/skia/skia/src/core/SkSafeMath.h +@@ -0,0 +1,106 @@ ++/* ++ * Copyright 2017 Google Inc. ++ * ++ * Use of this source code is governed by a BSD-style license that can be ++ * found in the LICENSE file. ++ */ ++ ++#ifndef SkSafeMath_DEFINED ++#define SkSafeMath_DEFINED ++ ++#include "SkTypes.h" ++ ++// SkSafeMath always check that a series of operations do not overflow. ++// This must be correct for all platforms, because this is a check for safety at runtime. ++ ++class SkSafeMath { ++public: ++ SkSafeMath() = default; ++ ++ bool ok() const { return fOK; } ++ explicit operator bool() const { return fOK; } ++ ++ size_t mul(size_t x, size_t y) { ++ return sizeof(size_t) == sizeof(uint64_t) ? mul64(x, y) : mul32(x, y); ++ } ++ ++ size_t add(size_t x, size_t y) { ++ size_t result = x + y; ++ fOK &= result >= x; ++ return result; ++ } ++ ++ /** ++ * Return a + b, unless this result is an overflow/underflow. In those cases, fOK will ++ * be set to false, and it is undefined what this returns. ++ */ ++ int addInt(int a, int b) { ++ if (b < 0 && a < std::numeric_limits<int>::min() - b) { ++ fOK = false; ++ return a; ++ } else if (b > 0 && a > std::numeric_limits<int>::max() - b) { ++ fOK = false; ++ return a; ++ } ++ return a + b; ++ } ++ ++ size_t alignUp(size_t x, size_t alignment) { ++ SkASSERT(alignment && !(alignment & (alignment - 1))); ++ return add(x, alignment - 1) & ~(alignment - 1); ++ } ++ ++ template <typename T> T castTo(size_t value) { ++ if (!SkTFitsIn<T>(value)) { ++ fOK = false; ++ } ++ return static_cast<T>(value); ++ } ++ ++ // These saturate to their results ++ static size_t Add(size_t x, size_t y); ++ static size_t Mul(size_t x, size_t y); ++ static size_t Align4(size_t x) { ++ SkSafeMath safe; ++ return safe.alignUp(x, 4); ++ } ++ ++private: ++ uint32_t mul32(uint32_t x, uint32_t y) { ++ uint64_t bx = x; ++ uint64_t by = y; ++ uint64_t result = bx * by; ++ fOK &= result >> 32 == 0; ++ return result; ++ } ++ ++ uint64_t mul64(uint64_t x, uint64_t y) { ++ if (x <= std::numeric_limits<uint64_t>::max() >> 32 ++ && y <= std::numeric_limits<uint64_t>::max() >> 32) { ++ return x * y; ++ } else { ++ auto hi = [](uint64_t x) { return x >> 32; }; ++ auto lo = [](uint64_t x) { return x & 0xFFFFFFFF; }; ++ ++ uint64_t lx_ly = lo(x) * lo(y); ++ uint64_t hx_ly = hi(x) * lo(y); ++ uint64_t lx_hy = lo(x) * hi(y); ++ uint64_t hx_hy = hi(x) * hi(y); ++ uint64_t result = 0; ++ result = this->add(lx_ly, (hx_ly << 32)); ++ result = this->add(result, (lx_hy << 32)); ++ fOK &= (hx_hy + (hx_ly >> 32) + (lx_hy >> 32)) == 0; ++ ++ #if defined(SK_DEBUG) && defined(__clang__) && defined(__x86_64__) ++ auto double_check = (unsigned __int128)x * y; ++ SkASSERT(result == (double_check & 0xFFFFFFFFFFFFFFFF)); ++ SkASSERT(!fOK || (double_check >> 64 == 0)); ++ #endif ++ ++ return result; ++ } ++ } ++ bool fOK = true; ++}; ++ ++#endif//SkSafeMath_DEFINED diff --git a/www/waterfox/files/patch-bug1443092 b/www/waterfox/files/patch-bug1443092 new file mode 100644 index 000000000000..9df39136173c --- /dev/null +++ b/www/waterfox/files/patch-bug1443092 @@ -0,0 +1,64 @@ +commit a70f63a1ef81 +Author: Botond Ballo <botond@mozilla.com> +Date: Fri Mar 9 17:26:24 2018 -0500 + + Bug 1443092 - Avoid calling SVGAnimatedEnumeration::AnimVal() from nsSVGUtils::GetBBox(). r=jwatt, a=RyanVM + + AnimVal() is a DOM getter, and it flushes animations, which we don't want + in GetBBox() which is called from display list building cide and + FrameLayerBuilder. + + MozReview-Commit-ID: 80DyTcGs5io +--- + dom/svg/SVGClipPathElement.cpp | 7 +++++++ + dom/svg/SVGClipPathElement.h | 4 ++++ + layout/svg/nsSVGUtils.cpp | 3 +-- + 3 files changed, 12 insertions(+), 2 deletions(-) + +diff --git dom/svg/SVGClipPathElement.cpp dom/svg/SVGClipPathElement.cpp +index 4220c206a3f1..86b361012fa4 100644 +--- dom/svg/SVGClipPathElement.cpp ++++ dom/svg/SVGClipPathElement.cpp +@@ -53,6 +53,13 @@ SVGClipPathElement::GetEnumInfo() + ArrayLength(sEnumInfo)); + } + ++bool ++SVGClipPathElement::IsUnitsObjectBoundingBox() const ++{ ++ return mEnumAttributes[CLIPPATHUNITS].GetAnimValue() == SVG_UNIT_TYPE_OBJECTBOUNDINGBOX; ++} ++ ++ + //---------------------------------------------------------------------- + // nsIDOMNode methods + +diff --git dom/svg/SVGClipPathElement.h dom/svg/SVGClipPathElement.h +index c5f8eb765246..d8ca24d28a20 100644 +--- dom/svg/SVGClipPathElement.h ++++ dom/svg/SVGClipPathElement.h +@@ -37,6 +37,10 @@ public: + // WebIDL + already_AddRefed<SVGAnimatedEnumeration> ClipPathUnits(); + ++ // This is an internal method that does not flush style, and thus ++ // the answer may be out of date if there's a pending style flush. ++ bool IsUnitsObjectBoundingBox() const; ++ + protected: + + enum { CLIPPATHUNITS }; +diff --git layout/svg/nsSVGUtils.cpp layout/svg/nsSVGUtils.cpp +index 714f35f9f549..cd9fae39dec6 100644 +--- layout/svg/nsSVGUtils.cpp ++++ layout/svg/nsSVGUtils.cpp +@@ -1183,8 +1183,7 @@ nsSVGUtils::GetBBox(nsIFrame* aFrame, uint32_t aFlags, + if (clipPathFrame) { + SVGClipPathElement *clipContent = + static_cast<SVGClipPathElement*>(clipPathFrame->GetContent()); +- RefPtr<SVGAnimatedEnumeration> units = clipContent->ClipPathUnits(); +- if (units->AnimVal() == SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { ++ if (clipContent->IsUnitsObjectBoundingBox()) { + matrix.PreTranslate(gfxPoint(x, y)); + matrix.PreScale(width, height); + } else if (aFrame->IsSVGForeignObjectFrame()) { diff --git a/www/waterfox/files/patch-bug1444231 b/www/waterfox/files/patch-bug1444231 new file mode 100644 index 000000000000..e35a39d78b05 --- /dev/null +++ b/www/waterfox/files/patch-bug1444231 @@ -0,0 +1,45 @@ +commit 62d7770e2c7c +Author: Boris Zbarsky <bzbarsky@mit.edu> +Date: Tue Mar 13 00:59:23 2018 -0400 + + Bug 1444231 - Fix QI implementation for FragmentOrElement. r=mccr8 a=jcristau + + MozReview-Commit-ID: 9mPO2ezk2Y7 + + --HG-- + extra : rebase_source : 1b15f9dac21206fbefeb9a6b72f3c54ff4d74537 + extra : source : 060024fa93121d878d27f329c959757e6f71017a +--- + dom/base/Element.cpp | 6 ++++++ + dom/base/FragmentOrElement.cpp | 1 - + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git dom/base/Element.cpp dom/base/Element.cpp +index 5f694b4b4ccd..26c7fbb6feef 100644 +--- dom/base/Element.cpp ++++ dom/base/Element.cpp +@@ -214,6 +214,12 @@ Element::GetSVGAnimatedClass() const + NS_IMETHODIMP + Element::QueryInterface(REFNSIID aIID, void** aInstancePtr) + { ++ if (aIID.Equals(NS_GET_IID(Element))) { ++ NS_ADDREF_THIS(); ++ *aInstancePtr = this; ++ return NS_OK; ++ } ++ + NS_ASSERTION(aInstancePtr, + "QueryInterface requires a non-NULL destination!"); + nsresult rv = FragmentOrElement::QueryInterface(aIID, aInstancePtr); +diff --git dom/base/FragmentOrElement.cpp dom/base/FragmentOrElement.cpp +index 8c23d2de91f0..4b48fde78058 100644 +--- dom/base/FragmentOrElement.cpp ++++ dom/base/FragmentOrElement.cpp +@@ -2093,7 +2093,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + NS_INTERFACE_MAP_BEGIN(FragmentOrElement) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY + NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(FragmentOrElement) +- NS_INTERFACE_MAP_ENTRY(Element) + NS_INTERFACE_MAP_ENTRY(nsIContent) + NS_INTERFACE_MAP_ENTRY(nsINode) + NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget) diff --git a/www/waterfox/files/patch-bug1448136 b/www/waterfox/files/patch-bug1448136 new file mode 100644 index 000000000000..c653ec375ad6 --- /dev/null +++ b/www/waterfox/files/patch-bug1448136 @@ -0,0 +1,71 @@ +commit 6ad2160158ba (origin/beta) +Author: Matthew Gaudet <mgaudet@mozilla.com> +Date: Fri Mar 23 13:10:08 2018 -0700 + + Bug 1448136 - Ensure Debug OSR transition is respected in InstanceOf Fallback stub. r=jandem, a=RyanVM + + --HG-- + extra : source : af66807a5c4b8366dc98d3aae7d55124003a1039 +--- + js/src/jit-test/tests/cacheir/bug1448136.js | 23 +++++++++++++++++++++++ + js/src/jit/BaselineIC.cpp | 9 ++++++++- + 2 files changed, 31 insertions(+), 1 deletion(-) + +diff --git js/src/jit-test/tests/cacheir/bug1448136.js js/src/jit-test/tests/cacheir/bug1448136.js +new file mode 100644 +index 000000000000..6256cb751e34 +--- /dev/null ++++ js/src/jit-test/tests/cacheir/bug1448136.js +@@ -0,0 +1,23 @@ ++print = function(s) { return s.toString(); } ++assertEq = function(a,b) { ++ try { print(a); print(b); } catch(exc) {} ++} ++g = newGlobal(); ++g.parent = this; ++g.eval("(" + function() { ++ Debugger(parent).onExceptionUnwind = function(frame) { ++ frame.older ++ } ++} + ")()") ++function a() {}; ++function b() {}; ++for (let _ of Array(100)) ++ assertEq(b instanceof a, true); ++function c(){}; ++function d(){}; ++function e(){}; ++Object.defineProperty(a, Symbol.hasInstance, {value: assertEq }); ++let funcs = [a, b, c, d]; ++for (let f of funcs) ++ assertEq(e instanceof f, true); ++ +diff --git js/src/jit/BaselineIC.cpp js/src/jit/BaselineIC.cpp +index 69aabacda0cd..20440b4a980b 100644 +--- js/src/jit/BaselineIC.cpp ++++ js/src/jit/BaselineIC.cpp +@@ -4146,9 +4146,12 @@ TryAttachInstanceOfStub(JSContext* cx, BaselineFrame* frame, ICInstanceOf_Fallba + } + + static bool +-DoInstanceOfFallback(JSContext* cx, BaselineFrame* frame, ICInstanceOf_Fallback* stub, ++DoInstanceOfFallback(JSContext* cx, BaselineFrame* frame, ICInstanceOf_Fallback* stub_, + HandleValue lhs, HandleValue rhs, MutableHandleValue res) + { ++ // This fallback stub may trigger debug mode toggling. ++ DebugModeOSRVolatileStub<ICInstanceOf_Fallback*> stub(ICStubEngine::Baseline, frame, stub_); ++ + FallbackICSpew(cx, stub, "InstanceOf"); + + if (!rhs.isObject()) { +@@ -4163,6 +4166,10 @@ DoInstanceOfFallback(JSContext* cx, BaselineFrame* frame, ICInstanceOf_Fallback* + + res.setBoolean(cond); + ++ // Check if debug mode toggling made the stub invalid. ++ if (stub.invalid()) ++ return true; ++ + if (!obj->is<JSFunction>()) { + stub->noteUnoptimizableAccess(); + return true; diff --git a/www/waterfox/files/patch-servo19654 b/www/waterfox/files/patch-servo19654 new file mode 100644 index 000000000000..a6fc2c441530 --- /dev/null +++ b/www/waterfox/files/patch-servo19654 @@ -0,0 +1,44 @@ +commit 61f3d7e4e83b +Author: Emilio Cobos Álvarez <emilio@crisal.io> +Date: Wed Jan 3 12:01:42 2018 -0600 + + servo: Merge #19654 - style: Allow building stylo with rust nightly (from emilio:geckolib-nightly); r=jdm + + See individual commits for details. + + Source-Repo: https://github.com/servo/servo + Source-Revision: f71fb8bddc28060320c233701898541112322d66 + + --HG-- + extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear + extra : subtree_revision : 8f8b2ccece94cc9df26c8c41afba04032fe9d506 +--- + servo/components/style/gecko/wrapper.rs | 2 +- + servo/components/style/gecko_bindings/sugar/ownership.rs | 1 - + 2 files changed, 1 insertion(+), 2 deletions(-) + +diff --git servo/components/style/gecko/wrapper.rs servo/components/style/gecko/wrapper.rs +index 034dd94590e2..a516d5db7d0d 100644 +--- servo/components/style/gecko/wrapper.rs ++++ servo/components/style/gecko/wrapper.rs +@@ -1398,7 +1398,7 @@ impl<'le> Eq for GeckoElement<'le> {} + + impl<'le> Hash for GeckoElement<'le> { + fn hash<H: Hasher>(&self, state: &mut H) { +- (self.0 as *const _).hash(state); ++ (self.0 as *const RawGeckoElement).hash(state); + } + } + +diff --git servo/components/style/gecko_bindings/sugar/ownership.rs servo/components/style/gecko_bindings/sugar/ownership.rs +index b0ac00368eae..8695efaaa40f 100644 +--- servo/components/style/gecko_bindings/sugar/ownership.rs ++++ servo/components/style/gecko_bindings/sugar/ownership.rs +@@ -109,7 +109,6 @@ pub unsafe trait HasArcFFI : HasFFI { + /// + /// &GeckoType -> &Arc<ServoType> + fn as_arc<'a>(ptr: &'a &Self::FFIType) -> &'a RawOffsetArc<Self> { +- debug_assert!(!(ptr as *const _).is_null()); + unsafe { + transmute::<&&Self::FFIType, &RawOffsetArc<Self>>(ptr) + } |