Merge m-c to autoland. a=merge UPGRADE_NSS_RELEASE
--HG-- rename : dom/security/test/sri/iframe_style_crossdomain.html => dom/security/test/sri/iframe_style_crossdomain_legacy.html rename : mobile/android/themes/core/content.css => mobile/android/themes/geckoview/content.css rename : mobile/android/themes/core/images/accessiblecaret-normal-hdpi.png => mobile/android/themes/geckoview/images/accessiblecaret-normal-hdpi.png rename : mobile/android/themes/core/images/accessiblecaret-normal-xhdpi.png => mobile/android/themes/geckoview/images/accessiblecaret-normal-xhdpi.png rename : mobile/android/themes/core/images/accessiblecaret-normal-xxhdpi.png => mobile/android/themes/geckoview/images/accessiblecaret-normal-xxhdpi.png rename : mobile/android/themes/core/images/accessiblecaret-tilt-left-hdpi.png => mobile/android/themes/geckoview/images/accessiblecaret-tilt-left-hdpi.png rename : mobile/android/themes/core/images/accessiblecaret-tilt-left-xhdpi.png => mobile/android/themes/geckoview/images/accessiblecaret-tilt-left-xhdpi.png rename : mobile/android/themes/core/images/accessiblecaret-tilt-left-xxhdpi.png => mobile/android/themes/geckoview/images/accessiblecaret-tilt-left-xxhdpi.png rename : mobile/android/themes/core/images/accessiblecaret-tilt-right-hdpi.png => mobile/android/themes/geckoview/images/accessiblecaret-tilt-right-hdpi.png rename : mobile/android/themes/core/images/accessiblecaret-tilt-right-xhdpi.png => mobile/android/themes/geckoview/images/accessiblecaret-tilt-right-xhdpi.png rename : mobile/android/themes/core/images/accessiblecaret-tilt-right-xxhdpi.png => mobile/android/themes/geckoview/images/accessiblecaret-tilt-right-xxhdpi.png rename : mobile/android/themes/core/images/dropmarker-right.svg => mobile/android/themes/geckoview/images/dropmarker-right.svg rename : mobile/android/themes/core/images/dropmarker.svg => mobile/android/themes/geckoview/images/dropmarker.svg rename : mobile/android/themes/core/images/cast-active.svg => mobile/android/themes/geckoview/images/videocontrols-cast-active.svg rename : mobile/android/themes/core/images/cast-ready.svg => mobile/android/themes/geckoview/images/videocontrols-cast-ready.svg rename : mobile/android/themes/core/images/exitfullscreen.svg => mobile/android/themes/geckoview/images/videocontrols-exitfullscreen.svg rename : mobile/android/themes/core/images/fullscreen.svg => mobile/android/themes/geckoview/images/videocontrols-fullscreen.svg rename : mobile/android/themes/core/images/mute.svg => mobile/android/themes/geckoview/images/videocontrols-mute.svg rename : mobile/android/themes/core/images/pause.svg => mobile/android/themes/geckoview/images/videocontrols-pause.svg rename : mobile/android/themes/core/images/play.svg => mobile/android/themes/geckoview/images/videocontrols-play.svg rename : mobile/android/themes/core/images/scrubber.svg => mobile/android/themes/geckoview/images/videocontrols-scrubber.svg rename : mobile/android/themes/core/images/unmute.svg => mobile/android/themes/geckoview/images/videocontrols-unmute.svg rename : mobile/android/themes/core/scrollbar-apz.css => mobile/android/themes/geckoview/scrollbar-apz.css rename : mobile/android/themes/core/touchcontrols.css => mobile/android/themes/geckoview/videocontrols.css extra : rebase_source : a5b4c2c75991990af25c4686ff96c199834ff317
3
CLOBBER
|
@ -22,4 +22,5 @@
|
|||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||
# don't change CLOBBER for WebIDL changes any more.
|
||||
|
||||
Bug 1340627 - clobber for Skia update
|
||||
Bug 1361661 - Update Telemetry build and headers.
|
||||
|
||||
|
|
|
@ -730,7 +730,9 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
|
|||
}
|
||||
mContentInsertions.Clear();
|
||||
|
||||
// Bind hanging child documents.
|
||||
// Bind hanging child documents unless we are using IPC and the
|
||||
// document has no IPC actor. If we fail to bind the child doc then
|
||||
// shut it down.
|
||||
uint32_t hangingDocCnt = mHangingChildDocuments.Length();
|
||||
nsTArray<RefPtr<DocAccessible>> newChildDocs;
|
||||
for (uint32_t idx = 0; idx < hangingDocCnt; idx++) {
|
||||
|
@ -738,6 +740,11 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
|
|||
if (childDoc->IsDefunct())
|
||||
continue;
|
||||
|
||||
if (IPCAccessibilityActive() && !mDocument->IPCDoc()) {
|
||||
childDoc->Shutdown();
|
||||
continue;
|
||||
}
|
||||
|
||||
nsIContent* ownerContent = mDocument->DocumentNode()->
|
||||
FindContentForSubDocument(childDoc->DocumentNode());
|
||||
if (ownerContent) {
|
||||
|
@ -755,6 +762,8 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
|
|||
childDoc->Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
// Clear the hanging documents list, even if we didn't bind them.
|
||||
mHangingChildDocuments.Clear();
|
||||
MOZ_ASSERT(mDocument, "Illicit document shutdown");
|
||||
if (!mDocument) {
|
||||
|
|
|
@ -149,7 +149,6 @@ public:
|
|||
DebugOnly<bool> result = mChildDocs.RemoveElement(aChildDoc->mActorID);
|
||||
aChildDoc->mParentDoc = kNoParentDoc;
|
||||
MOZ_ASSERT(result);
|
||||
MOZ_ASSERT(aChildDoc->mChildDocs.Length() == 0);
|
||||
}
|
||||
|
||||
void RemoveAccessible(ProxyAccessible* aAccessible)
|
||||
|
|
Двоичные данные
browser/branding/aurora/appname.bmp
До Ширина: | Высота: | Размер: 193 KiB |
Двоичные данные
browser/branding/aurora/bgintro.bmp
До Ширина: | Высота: | Размер: 666 KiB |
После Ширина: | Высота: | Размер: 809 KiB |
Двоичные данные
browser/branding/aurora/clock.bmp
До Ширина: | Высота: | Размер: 121 KiB |
После Ширина: | Высота: | Размер: 31 KiB |
Двоичные данные
browser/branding/aurora/particles.bmp
До Ширина: | Высота: | Размер: 121 KiB |
Двоичные данные
browser/branding/aurora/pencil-rtl.bmp
До Ширина: | Высота: | Размер: 121 KiB |
Двоичные данные
browser/branding/aurora/pencil.bmp
До Ширина: | Высота: | Размер: 121 KiB |
|
@ -19,18 +19,14 @@ def FirefoxBranding():
|
|||
'VisualElements_70.png',
|
||||
]
|
||||
BRANDING_FILES += [
|
||||
'appname.bmp',
|
||||
'bgintro.bmp',
|
||||
'bgstub.bmp',
|
||||
'branding.nsi',
|
||||
'clock.bmp',
|
||||
'document.ico',
|
||||
'firefox.ico',
|
||||
'firefox64.ico',
|
||||
'newtab.ico',
|
||||
'newwindow.ico',
|
||||
'particles.bmp',
|
||||
'pbmode.ico',
|
||||
'pencil-rtl.bmp',
|
||||
'pencil.bmp',
|
||||
'wizHeader.bmp',
|
||||
'wizHeaderRTL.bmp',
|
||||
'wizWatermark.bmp',
|
||||
|
|
Двоичные данные
browser/branding/nightly/appname.bmp
До Ширина: | Высота: | Размер: 173 KiB |
Двоичные данные
browser/branding/nightly/bgintro.bmp
До Ширина: | Высота: | Размер: 666 KiB |
После Ширина: | Высота: | Размер: 809 KiB |
Двоичные данные
browser/branding/nightly/clock.bmp
До Ширина: | Высота: | Размер: 121 KiB |
После Ширина: | Высота: | Размер: 31 KiB |
Двоичные данные
browser/branding/nightly/particles.bmp
До Ширина: | Высота: | Размер: 121 KiB |
Двоичные данные
browser/branding/nightly/pencil-rtl.bmp
До Ширина: | Высота: | Размер: 121 KiB |
Двоичные данные
browser/branding/nightly/pencil.bmp
До Ширина: | Высота: | Размер: 121 KiB |
Двоичные данные
browser/branding/official/appname.bmp
До Ширина: | Высота: | Размер: 12 KiB |
Двоичные данные
browser/branding/official/bgintro.bmp
До Ширина: | Высота: | Размер: 666 KiB |
После Ширина: | Высота: | Размер: 809 KiB |
Двоичные данные
browser/branding/official/clock.bmp
До Ширина: | Высота: | Размер: 8.8 KiB |
После Ширина: | Высота: | Размер: 21 KiB |
Двоичные данные
browser/branding/official/particles.bmp
До Ширина: | Высота: | Размер: 8.8 KiB |
Двоичные данные
browser/branding/official/pencil-rtl.bmp
До Ширина: | Высота: | Размер: 8.8 KiB |
Двоичные данные
browser/branding/official/pencil.bmp
До Ширина: | Высота: | Размер: 8.8 KiB |
Двоичные данные
browser/branding/unofficial/appname.bmp
До Ширина: | Высота: | Размер: 87 KiB |
Двоичные данные
browser/branding/unofficial/bgintro.bmp
До Ширина: | Высота: | Размер: 666 KiB |
После Ширина: | Высота: | Размер: 809 KiB |
Двоичные данные
browser/branding/unofficial/clock.bmp
До Ширина: | Высота: | Размер: 121 KiB |
После Ширина: | Высота: | Размер: 31 KiB |
Двоичные данные
browser/branding/unofficial/particles.bmp
До Ширина: | Высота: | Размер: 121 KiB |
Двоичные данные
browser/branding/unofficial/pencil-rtl.bmp
До Ширина: | Высота: | Размер: 121 KiB |
Двоичные данные
browser/branding/unofficial/pencil.bmp
До Ширина: | Высота: | Размер: 121 KiB |
|
@ -49,21 +49,25 @@ function promiseMigration(migrator, resourceType, aProfile = null) {
|
|||
* Replaces a directory service entry with a given nsIFile.
|
||||
*/
|
||||
function registerFakePath(key, file) {
|
||||
// Register our own provider for the Library directory.
|
||||
let provider = {
|
||||
getFile(prop, persistent) {
|
||||
persistent.value = true;
|
||||
if (prop == key) {
|
||||
return file;
|
||||
}
|
||||
throw Cr.NS_ERROR_FAILURE;
|
||||
},
|
||||
QueryInterface: XPCOMUtils.generateQI([ Ci.nsIDirectoryServiceProvider ])
|
||||
};
|
||||
Services.dirsvc.QueryInterface(Ci.nsIDirectoryService)
|
||||
.registerProvider(provider);
|
||||
let dirsvc = Services.dirsvc.QueryInterface(Ci.nsIProperties);
|
||||
let originalFile;
|
||||
try {
|
||||
// If a file is already provided save it and undefine, otherwise set will
|
||||
// throw for persistent entries (ones that are cached).
|
||||
originalFile = dirsvc.get(key, Ci.nsIFile);
|
||||
dirsvc.undefine(key);
|
||||
} catch (e) {
|
||||
// dirsvc.get will throw if nothing provides for the key and dirsvc.undefine
|
||||
// will throw if it's not a persistent entry, in either case we don't want
|
||||
// to set the original file in cleanup.
|
||||
originalFile = undefined;
|
||||
}
|
||||
|
||||
dirsvc.set(key, file);
|
||||
do_register_cleanup(() => {
|
||||
Services.dirsvc.QueryInterface(Ci.nsIDirectoryService)
|
||||
.unregisterProvider(provider);
|
||||
dirsvc.undefine(key);
|
||||
if (originalFile) {
|
||||
dirsvc.set(key, originalFile);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -23,13 +23,9 @@ INSTALLER_FILES += \
|
|||
endif
|
||||
|
||||
BRANDING_FILES = \
|
||||
bgstub.bmp \
|
||||
branding.nsi \
|
||||
appname.bmp \
|
||||
bgintro.bmp \
|
||||
clock.bmp \
|
||||
particles.bmp \
|
||||
pencil.bmp \
|
||||
pencil-rtl.bmp \
|
||||
firefox64.ico \
|
||||
wizHeader.bmp \
|
||||
wizHeaderRTL.bmp \
|
||||
wizWatermark.bmp \
|
||||
|
@ -90,9 +86,6 @@ $(CONFIG_DIR)/setup.exe::
|
|||
--preprocess-single-file $(topsrcdir) \
|
||||
$(PPL_LOCALE_ARGS) $(CONFIG_DIR) \
|
||||
nsisstrings.properties nsisstrings.nlf
|
||||
$(PYTHON) $(topsrcdir)/toolkit/mozapps/installer/windows/nsis/preprocess-locale.py \
|
||||
--convert-utf8-utf16le \
|
||||
$(srcdir)/nsis/oneoff_en-US.nsh $(CONFIG_DIR)/oneoff_en-US.nsh
|
||||
|
||||
GARBARGE_DIRS += instgen
|
||||
|
||||
|
|
|
@ -125,6 +125,9 @@ VIAddVersionKey "ProductVersion" "${AppVersion}"
|
|||
!define OPTIONS_ITEM_WIDTH_DU 356u
|
||||
!define OPTIONS_SUBITEM_EDGE_DU 119u
|
||||
!define OPTIONS_SUBITEM_WIDTH_DU 327u
|
||||
!define INSTALL_BLURB_TOP_DU 78u
|
||||
!define NOW_INSTALLING_TOP_DU 70u
|
||||
!define INSTALL_BLURB_TOP_DU 137u
|
||||
!define INSTALL_FOOTER_TOP_DU -48u
|
||||
!define PROGRESS_BAR_TOP_DU 112u
|
||||
!define APPNAME_BMP_EDGE_DU 19u
|
||||
!define APPNAME_BMP_TOP_DU 12u
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
# 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/.
|
||||
|
||||
; Custom strings for en-US. This is not in the locale directory so these strings
|
||||
; aren't translated.
|
||||
!define INDENT " "
|
||||
!define INTRO_BLURB "Thanks for choosing $BrandFullName. We’re not just designed to be different, we’re different by design."
|
||||
!define INSTALL_BLURB1 "You're about to enjoy the very latest in speed, flexibility and security so you're always in control."
|
||||
!define INSTALL_BLURB2 "And you're joining a global community of users, contributors and developers working to make the best browser in the world."
|
||||
!define INSTALL_BLURB3 "You even get a haiku:$\n${INDENT}Proudly non-profit$\n${INDENT}Free to innovate for you$\n${INDENT}And a better Web"
|
||||
!undef INDENT
|
|
@ -18,50 +18,22 @@
|
|||
# You can use \n to create a newline in the string but only when the string
|
||||
# from en-US contains a \n.
|
||||
|
||||
WIN_CAPTION=$BrandShortName Setup
|
||||
INSTALLER_WIN_CAPTION=$BrandShortName Installer
|
||||
|
||||
INTRO_BLURB1=Thanks for choosing $BrandFullName, the browser that chooses you above everything else.
|
||||
INSTALL_BLURB1=You're about to enjoy the very latest in speed, flexibility and security so you're always in control.
|
||||
INSTALL_BLURB2=That's because $BrandShortName is made by a non-profit to make browsing and the Web better for you.
|
||||
INSTALL_BLURB3=You're also joining a global community of users, contributors and developers working to make the best browser in the world.
|
||||
STUB_INSTALLING_LABEL=Now installing
|
||||
STUB_BLURB1=Fast, responsive online experiences
|
||||
STUB_BLURB2=Compatibility with more of your favorite sites
|
||||
STUB_BLURB3=Built-in privacy tools for safer browsing
|
||||
STUB_BLURB_FOOTER=The only browser built for people, not profit
|
||||
|
||||
WARN_MIN_SUPPORTED_OSVER_MSG=Sorry, $BrandShortName can't be installed. This version of $BrandShortName requires ${MinSupportedVer} or newer. Please click the OK button for additional information.
|
||||
WARN_MIN_SUPPORTED_CPU_MSG=Sorry, $BrandShortName can't be installed. This version of $BrandShortName requires a processor with ${MinSupportedCPU} support. Please click the OK button for additional information.
|
||||
WARN_MIN_SUPPORTED_OSVER_CPU_MSG=Sorry, $BrandShortName can't be installed. This version of $BrandShortName requires ${MinSupportedVer} or newer and a processor with ${MinSupportedCPU} support. Please click the OK button for additional information.
|
||||
WARN_WRITE_ACCESS=You don't have access to write to the installation directory.\n\nClick OK to select a different directory.
|
||||
WARN_DISK_SPACE=You don't have sufficient disk space to install to this location.\n\nClick OK to select a different location.
|
||||
WARN_ROOT_INSTALL=Unable to install to the root of your disk.\n\nClick OK to select a different location.
|
||||
WARN_WRITE_ACCESS_QUIT=You don't have access to write to the installation directory
|
||||
WARN_DISK_SPACE_QUIT=You don't have sufficient disk space to install.
|
||||
WARN_MANUALLY_CLOSE_APP_LAUNCH=$BrandShortName is already running.\n\nPlease close $BrandShortName prior to launching the version you have just installed.
|
||||
|
||||
ERROR_DOWNLOAD=Your download was interrupted.\n\nPlease click the OK button to continue.
|
||||
ERROR_DOWNLOAD_CONT=Hmm. For some reason, we could not install $BrandShortName.\nChoose OK to start over.
|
||||
|
||||
INSTALL_BUTTON=&Install
|
||||
UPGRADE_BUTTON=&Upgrade
|
||||
CANCEL_BUTTON=Cancel
|
||||
OPTIONS_BUTTON=&Options
|
||||
|
||||
MAKE_DEFAULT=&Make $BrandShortName my default browser
|
||||
ADD_SC_DESKTOP_TASKBAR=&Create desktop and taskbar shortcuts for $BrandShortName
|
||||
ADD_SC_DESKTOP_QUICKLAUNCHBAR=&Create desktop and quick launch shortcuts for $BrandShortName
|
||||
VERSION_32BIT=32-bit $BrandShortName
|
||||
VERSION_64BIT=64-bit $BrandShortName
|
||||
ARCH_DROPLIST_LABEL=&Version to install
|
||||
SPACE_REQUIRED=Space Required:
|
||||
SPACE_AVAILABLE=Space Available:
|
||||
ONE_MOMENT_INSTALL=One moment, $BrandShortName will launch as soon as the install is complete…
|
||||
ONE_MOMENT_UPGRADE=One moment, $BrandShortName will launch as soon as the upgrade is complete…
|
||||
INSTALL_MAINT_SERVICE=&Install the $BrandShortName background update service
|
||||
SEND_PING=S&end information about this installation to Mozilla
|
||||
BROWSE_BUTTON=B&rowse…
|
||||
DEST_FOLDER=Destination Folder
|
||||
|
||||
DOWNLOADING_LABEL=Downloading $BrandShortName…
|
||||
INSTALLING_LABEL=Installing $BrandShortName…
|
||||
UPGRADING_LABEL=Upgrading $BrandShortName…
|
||||
|
||||
SELECT_FOLDER_TEXT=Select the folder to install $BrandShortName in.
|
||||
|
||||
BYTE=B
|
||||
KILO=K
|
||||
MEGA=M
|
||||
GIGA=G
|
||||
|
|
|
@ -81,7 +81,7 @@ add_task(async function test_context_menu() {
|
|||
|
||||
// Also check events.
|
||||
let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
|
||||
events = (events.default || []).filter(e => e[1] == "navigation" && e[2] == "search");
|
||||
events = (events.parent || []).filter(e => e[1] == "navigation" && e[2] == "search");
|
||||
checkEvents(events, [["navigation", "search", "contextmenu", null, {engine: "other-MozSearch"}]]);
|
||||
|
||||
contextMenu.hidePopup();
|
||||
|
@ -117,7 +117,7 @@ add_task(async function test_about_newtab() {
|
|||
|
||||
// Also check events.
|
||||
let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
|
||||
events = (events.default || []).filter(e => e[1] == "navigation" && e[2] == "search");
|
||||
events = (events.parent || []).filter(e => e[1] == "navigation" && e[2] == "search");
|
||||
checkEvents(events, [["navigation", "search", "about_newtab", "enter", {engine: "other-MozSearch"}]]);
|
||||
|
||||
await BrowserTestUtils.removeTab(tab);
|
||||
|
|
|
@ -81,7 +81,7 @@ add_task(async function test_abouthome_simpleQuery() {
|
|||
|
||||
// Also check events.
|
||||
let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
|
||||
events = (events.default || []).filter(e => e[1] == "navigation" && e[2] == "search");
|
||||
events = (events.parent || []).filter(e => e[1] == "navigation" && e[2] == "search");
|
||||
checkEvents(events, [["navigation", "search", "about_home", "enter", {engine: "other-MozSearch"}]]);
|
||||
|
||||
await BrowserTestUtils.removeTab(tab);
|
||||
|
|
|
@ -129,7 +129,7 @@ add_task(async function test_plainQuery() {
|
|||
|
||||
// Also check events.
|
||||
let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
|
||||
events = (events.default || []).filter(e => e[1] == "navigation" && e[2] == "search");
|
||||
events = (events.parent || []).filter(e => e[1] == "navigation" && e[2] == "search");
|
||||
checkEvents(events, [["navigation", "search", "searchbar", "enter", {engine: "other-MozSearch"}]]);
|
||||
|
||||
// Check the histograms as well.
|
||||
|
@ -173,7 +173,7 @@ add_task(async function test_oneOff_enter() {
|
|||
|
||||
// Also check events.
|
||||
let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
|
||||
events = (events.default || []).filter(e => e[1] == "navigation" && e[2] == "search");
|
||||
events = (events.parent || []).filter(e => e[1] == "navigation" && e[2] == "search");
|
||||
checkEvents(events, [["navigation", "search", "searchbar", "oneoff", {engine: "other-MozSearch2"}]]);
|
||||
|
||||
// Check the histograms as well.
|
||||
|
@ -298,7 +298,7 @@ add_task(async function test_suggestion_click() {
|
|||
|
||||
// Also check events.
|
||||
let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
|
||||
events = (events.default || []).filter(e => e[1] == "navigation" && e[2] == "search");
|
||||
events = (events.parent || []).filter(e => e[1] == "navigation" && e[2] == "search");
|
||||
checkEvents(events, [["navigation", "search", "searchbar", "suggestion", {engine: searchEngineId}]]);
|
||||
|
||||
// Check the histograms as well.
|
||||
|
|
|
@ -138,7 +138,7 @@ add_task(async function test_simpleQuery() {
|
|||
|
||||
// Also check events.
|
||||
let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
|
||||
events = (events.default || []).filter(e => e[1] == "navigation" && e[2] == "search");
|
||||
events = (events.parent || []).filter(e => e[1] == "navigation" && e[2] == "search");
|
||||
checkEvents(events, [["navigation", "search", "urlbar", "enter", {engine: "other-MozSearch"}]]);
|
||||
|
||||
// Check the histograms as well.
|
||||
|
@ -197,7 +197,7 @@ add_task(async function test_searchAlias() {
|
|||
|
||||
// Also check events.
|
||||
let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
|
||||
events = (events.default || []).filter(e => e[1] == "navigation" && e[2] == "search");
|
||||
events = (events.parent || []).filter(e => e[1] == "navigation" && e[2] == "search");
|
||||
checkEvents(events, [["navigation", "search", "urlbar", "alias", {engine: "other-MozSearch"}]]);
|
||||
|
||||
// Check the histograms as well.
|
||||
|
@ -261,7 +261,7 @@ add_task(async function test_oneOff_enter() {
|
|||
|
||||
// Also check events.
|
||||
let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
|
||||
events = (events.default || []).filter(e => e[1] == "navigation" && e[2] == "search");
|
||||
events = (events.parent || []).filter(e => e[1] == "navigation" && e[2] == "search");
|
||||
checkEvents(events, [["navigation", "search", "urlbar", "oneoff", {engine: "other-MozSearch"}]]);
|
||||
|
||||
// Check the histograms as well.
|
||||
|
@ -408,7 +408,7 @@ add_task(async function test_suggestion_click() {
|
|||
|
||||
// Also check events.
|
||||
let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
|
||||
events = (events.default || []).filter(e => e[1] == "navigation" && e[2] == "search");
|
||||
events = (events.parent || []).filter(e => e[1] == "navigation" && e[2] == "search");
|
||||
checkEvents(events, [["navigation", "search", "urlbar", "suggestion", {engine: searchEngineId}]]);
|
||||
|
||||
// Check the histograms as well.
|
||||
|
|
|
@ -100,8 +100,8 @@ function checkKeyedHistogram(h, key, expectedValue) {
|
|||
*/
|
||||
function getParentProcessScalars(aChannel, aKeyed = false, aClear = false) {
|
||||
const scalars = aKeyed ?
|
||||
Services.telemetry.snapshotKeyedScalars(aChannel, aClear)["default"] :
|
||||
Services.telemetry.snapshotScalars(aChannel, aClear)["default"];
|
||||
Services.telemetry.snapshotKeyedScalars(aChannel, aClear)["parent"] :
|
||||
Services.telemetry.snapshotScalars(aChannel, aClear)["parent"];
|
||||
return scalars || {};
|
||||
}
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
Library('freetype')
|
||||
|
||||
if CONFIG['MOZ_TREE_FREETYPE']:
|
||||
USE_LIBS += [
|
||||
'static:/modules/freetype2/.libs/freetype',
|
||||
DIRS += [
|
||||
'/modules/freetype2',
|
||||
]
|
||||
else:
|
||||
OS_LIBS += CONFIG['FT2_LIBS']
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "mozilla/dom/ImageData.h"
|
||||
#include "mozilla/dom/ImageDataBinding.h"
|
||||
#include "mozilla/dom/ipc/BlobChild.h"
|
||||
#include "mozilla/dom/ipc/nsIRemoteBlob.h"
|
||||
#include "mozilla/dom/StructuredClone.h"
|
||||
#include "mozilla/dom/MessagePort.h"
|
||||
#include "mozilla/dom/MessagePortBinding.h"
|
||||
|
@ -501,95 +500,6 @@ StructuredCloneHolder::WriteFullySerializableObjects(JSContext* aCx,
|
|||
|
||||
namespace {
|
||||
|
||||
// Recursive!
|
||||
already_AddRefed<BlobImpl>
|
||||
EnsureBlobForBackgroundManager(BlobImpl* aBlobImpl,
|
||||
PBackgroundChild* aManager,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aBlobImpl);
|
||||
RefPtr<BlobImpl> blobImpl = aBlobImpl;
|
||||
|
||||
if (!aManager) {
|
||||
aManager = BackgroundChild::GetForCurrentThread();
|
||||
if (!aManager) {
|
||||
return blobImpl.forget();
|
||||
}
|
||||
}
|
||||
|
||||
const nsTArray<RefPtr<BlobImpl>>* subBlobImpls =
|
||||
aBlobImpl->GetSubBlobImpls();
|
||||
|
||||
if (!subBlobImpls || !subBlobImpls->Length()) {
|
||||
if (nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryObject(blobImpl)) {
|
||||
// Always make sure we have a blob from an actor we can use on this
|
||||
// thread.
|
||||
BlobChild* blobChild = BlobChild::GetOrCreate(aManager, blobImpl);
|
||||
MOZ_ASSERT(blobChild);
|
||||
|
||||
blobImpl = blobChild->GetBlobImpl();
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
DebugOnly<bool> isMutable;
|
||||
MOZ_ASSERT(NS_SUCCEEDED(blobImpl->GetMutable(&isMutable)));
|
||||
MOZ_ASSERT(!isMutable);
|
||||
} else {
|
||||
MOZ_ALWAYS_SUCCEEDS(blobImpl->SetMutable(false));
|
||||
}
|
||||
|
||||
return blobImpl.forget();
|
||||
}
|
||||
|
||||
const uint32_t subBlobCount = subBlobImpls->Length();
|
||||
MOZ_ASSERT(subBlobCount);
|
||||
|
||||
nsTArray<RefPtr<BlobImpl>> newSubBlobImpls;
|
||||
newSubBlobImpls.SetLength(subBlobCount);
|
||||
|
||||
bool newBlobImplNeeded = false;
|
||||
|
||||
for (uint32_t index = 0; index < subBlobCount; index++) {
|
||||
const RefPtr<BlobImpl>& subBlobImpl = subBlobImpls->ElementAt(index);
|
||||
MOZ_ASSERT(subBlobImpl);
|
||||
|
||||
RefPtr<BlobImpl>& newSubBlobImpl = newSubBlobImpls[index];
|
||||
|
||||
newSubBlobImpl = EnsureBlobForBackgroundManager(subBlobImpl, aManager, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(newSubBlobImpl);
|
||||
|
||||
if (subBlobImpl != newSubBlobImpl) {
|
||||
newBlobImplNeeded = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (newBlobImplNeeded) {
|
||||
nsString contentType;
|
||||
blobImpl->GetType(contentType);
|
||||
|
||||
if (blobImpl->IsFile()) {
|
||||
nsString name;
|
||||
blobImpl->GetName(name);
|
||||
|
||||
blobImpl = MultipartBlobImpl::Create(Move(newSubBlobImpls), name,
|
||||
contentType, aRv);
|
||||
} else {
|
||||
blobImpl = MultipartBlobImpl::Create(Move(newSubBlobImpls), contentType, aRv);
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_SUCCEEDS(blobImpl->SetMutable(false));
|
||||
}
|
||||
|
||||
return blobImpl.forget();
|
||||
}
|
||||
|
||||
JSObject*
|
||||
ReadBlob(JSContext* aCx,
|
||||
uint32_t aIndex,
|
||||
|
@ -599,14 +509,7 @@ ReadBlob(JSContext* aCx,
|
|||
MOZ_ASSERT(aIndex < aHolder->BlobImpls().Length());
|
||||
RefPtr<BlobImpl> blobImpl = aHolder->BlobImpls()[aIndex];
|
||||
|
||||
ErrorResult rv;
|
||||
blobImpl = EnsureBlobForBackgroundManager(blobImpl, nullptr, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
rv.SuppressException();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(blobImpl);
|
||||
MOZ_ALWAYS_SUCCEEDS(blobImpl->SetMutable(false));
|
||||
|
||||
// RefPtr<File> needs to go out of scope before toObject() is
|
||||
// called because the static analysis thinks dereferencing XPCOM objects
|
||||
|
@ -638,16 +541,7 @@ WriteBlob(JSStructuredCloneWriter* aWriter,
|
|||
return false;
|
||||
}
|
||||
|
||||
ErrorResult rv;
|
||||
RefPtr<BlobImpl> blobImpl =
|
||||
EnsureBlobForBackgroundManager(aBlob->Impl(), nullptr, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
rv.SuppressException();
|
||||
return false;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
RefPtr<BlobImpl> blobImpl = aBlob->Impl();
|
||||
MOZ_ALWAYS_SUCCEEDS(blobImpl->SetMutable(false));
|
||||
|
||||
// We store the position of the blobImpl in the array as index.
|
||||
|
@ -766,14 +660,7 @@ ReadFileList(JSContext* aCx,
|
|||
RefPtr<BlobImpl> blobImpl = aHolder->BlobImpls()[pos];
|
||||
MOZ_ASSERT(blobImpl->IsFile());
|
||||
|
||||
ErrorResult rv;
|
||||
blobImpl = EnsureBlobForBackgroundManager(blobImpl, nullptr, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
rv.SuppressException();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(blobImpl);
|
||||
MOZ_ALWAYS_SUCCEEDS(blobImpl->SetMutable(false));
|
||||
|
||||
RefPtr<File> file = File::Create(aHolder->ParentDuringRead(), blobImpl);
|
||||
if (!fileList->Append(file)) {
|
||||
|
@ -811,18 +698,11 @@ WriteFileList(JSStructuredCloneWriter* aWriter,
|
|||
return false;
|
||||
}
|
||||
|
||||
ErrorResult rv;
|
||||
nsTArray<RefPtr<BlobImpl>> blobImpls;
|
||||
|
||||
for (uint32_t i = 0; i < aFileList->Length(); ++i) {
|
||||
RefPtr<BlobImpl> blobImpl =
|
||||
EnsureBlobForBackgroundManager(aFileList->Item(i)->Impl(), nullptr, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
rv.SuppressException();
|
||||
return false;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(blobImpl);
|
||||
RefPtr<BlobImpl> blobImpl = aFileList->Item(i)->Impl();
|
||||
MOZ_ALWAYS_SUCCEEDS(blobImpl->SetMutable(false));
|
||||
blobImpls.AppendElement(blobImpl);
|
||||
}
|
||||
|
||||
|
@ -864,20 +744,13 @@ ReadFormData(JSContext* aCx,
|
|||
|
||||
RefPtr<BlobImpl> blobImpl =
|
||||
aHolder->BlobImpls()[indexOrLengthOfString];
|
||||
|
||||
ErrorResult rv;
|
||||
blobImpl = EnsureBlobForBackgroundManager(blobImpl, nullptr, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
rv.SuppressException();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(blobImpl);
|
||||
MOZ_ALWAYS_SUCCEEDS(blobImpl->SetMutable(false));
|
||||
|
||||
RefPtr<Blob> blob =
|
||||
Blob::Create(aHolder->ParentDuringRead(), blobImpl);
|
||||
MOZ_ASSERT(blob);
|
||||
|
||||
ErrorResult rv;
|
||||
formData->Append(name, *blob, thirdArg, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
rv.SuppressException();
|
||||
|
@ -970,20 +843,14 @@ WriteFormData(JSStructuredCloneWriter* aWriter,
|
|||
}
|
||||
|
||||
if (aValue.IsBlob()) {
|
||||
ErrorResult rv;
|
||||
RefPtr<BlobImpl> blobImpl =
|
||||
EnsureBlobForBackgroundManager(aValue.GetAsBlob()->Impl(), nullptr,
|
||||
rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
rv.SuppressException();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!JS_WriteUint32Pair(closure->mWriter, SCTAG_DOM_BLOB,
|
||||
closure->mHolder->BlobImpls().Length())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<BlobImpl> blobImpl = aValue.GetAsBlob()->Impl();
|
||||
MOZ_ALWAYS_SUCCEEDS(blobImpl->SetMutable(false));
|
||||
|
||||
closure->mHolder->BlobImpls().AppendElement(blobImpl);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1493,6 +1493,7 @@ GK_ATOM(font_style, "font-style")
|
|||
GK_ATOM(font_variant, "font-variant")
|
||||
GK_ATOM(foreignObject, "foreignObject")
|
||||
GK_ATOM(fractalNoise, "fractalNoise")
|
||||
GK_ATOM(fr, "fr")
|
||||
GK_ATOM(fx, "fx")
|
||||
GK_ATOM(fy, "fy")
|
||||
GK_ATOM(G, "G")
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<script>function f() { history.length; } window.onload = function() { var f = window.f; document.open(); document.close(); parent.continueTest(f); }</script>
|
|
@ -0,0 +1 @@
|
|||
<script>window.onload = function runTest1() { document.open(); setTimeout('parent.test1Done();'); document.close(); }</script>
|
|
@ -128,6 +128,7 @@ support-files =
|
|||
file_bug1274806.html
|
||||
file_domwindowutils_animation.html
|
||||
file_general_document.html
|
||||
file_history_document_open.html
|
||||
file_htmlserializer_1.html
|
||||
file_htmlserializer_1_bodyonly.html
|
||||
file_htmlserializer_1_format.html
|
||||
|
@ -152,6 +153,7 @@ support-files =
|
|||
file_mozfiledataurl_img.jpg
|
||||
file_record_orientation.html
|
||||
file_restrictedEventSource.sjs
|
||||
file_settimeout_inner.html
|
||||
file_simplecontentpolicy.js
|
||||
file_timer_flood.html
|
||||
file_websocket_basic_wsh.py
|
||||
|
|
|
@ -29,7 +29,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=943418
|
|||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=943418">Mozilla Bug 943418</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<iframe src="data:text/html,<script>function f() { history.length; } window.onload = function() { var f = window.f; document.open(); document.close(); parent.continueTest(f); }</script>" </script>
|
||||
<iframe src="file_history_document_open.html"></script>
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
|
|
@ -24,9 +24,15 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=936129
|
|||
window.runTest2();
|
||||
setTimeout(allDone);
|
||||
}
|
||||
iframe.src = "about:blank";
|
||||
|
||||
// Per whatwg spec, "If the src attribute and the srcdoc attribute are
|
||||
// both specified together, the srcdoc attribute takes priority."
|
||||
//
|
||||
// So if we were to use src attribute here, it will be considered as a
|
||||
// no-op, so simply use a simple srcdoc here.
|
||||
iframe.srcdoc = "<html></html>";
|
||||
}
|
||||
iframe.src = "data:text/html,<script>function runTest2() { setTimeout('parent.test2Done()'); };<" + "/script>";
|
||||
iframe.srcdoc = "<script>function runTest2() { setTimeout('parent.test2Done()'); };<" + "/script>";
|
||||
}
|
||||
window.test2DoneCalled = false;
|
||||
function test2Done()
|
||||
|
@ -45,7 +51,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=936129
|
|||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=936129">Mozilla Bug 936129</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<iframe id="testFrame" src="data:text/html,<script>window.onload = function runTest1() { document.open(); setTimeout('parent.test1Done();'); document.close(); }</script>"></iframe>
|
||||
<iframe id="testFrame" src="file_settimeout_inner.html"></iframe>
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PBackground;
|
||||
include protocol PBlob;
|
||||
include protocol PChildToParentStream;
|
||||
include protocol PFileDescriptorSet;
|
||||
include protocol PIPCBlobInputStream;
|
||||
include protocol PParentToChildStream;
|
||||
include protocol PChildToParentStream; // FIXME: bug 792908
|
||||
include protocol PFileDescriptorSet; // FIXME: bug 792908
|
||||
include protocol PIPCBlobInputStream; // FIXME: bug 792908
|
||||
include protocol PParentToChildStream; // FIXME: bug 792908
|
||||
|
||||
include DOMTypes;
|
||||
|
||||
using struct mozilla::SerializedStructuredCloneBuffer from "ipc/IPCMessageUtils.h";
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PBackground;
|
||||
include protocol PBlob; // FIXME: bug 792908
|
||||
include protocol PCacheOp;
|
||||
include protocol PCacheStreamControl;
|
||||
include protocol PFileDescriptorSet;
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PBackground;
|
||||
include protocol PBlob; // FIXME: bug 792908
|
||||
include protocol PCache;
|
||||
include protocol PCacheOp;
|
||||
include protocol PCacheStreamControl;
|
||||
|
|
|
@ -26,6 +26,7 @@ FileBlobImpl::FileBlobImpl(nsIFile* aFile)
|
|||
: BaseBlobImpl(EmptyString(), EmptyString(), UINT64_MAX, INT64_MAX)
|
||||
, mFile(aFile)
|
||||
, mWholeFile(true)
|
||||
, mFileId(-1)
|
||||
{
|
||||
MOZ_ASSERT(mFile, "must have file");
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
@ -40,6 +41,7 @@ FileBlobImpl::FileBlobImpl(const nsAString& aName,
|
|||
: BaseBlobImpl(aName, aContentType, aLength, UINT64_MAX)
|
||||
, mFile(aFile)
|
||||
, mWholeFile(true)
|
||||
, mFileId(-1)
|
||||
{
|
||||
MOZ_ASSERT(mFile, "must have file");
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
@ -52,6 +54,7 @@ FileBlobImpl::FileBlobImpl(const nsAString& aName,
|
|||
: BaseBlobImpl(aName, aContentType, aLength, aLastModificationDate)
|
||||
, mFile(aFile)
|
||||
, mWholeFile(true)
|
||||
, mFileId(-1)
|
||||
{
|
||||
MOZ_ASSERT(mFile, "must have file");
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
@ -62,6 +65,7 @@ FileBlobImpl::FileBlobImpl(nsIFile* aFile, const nsAString& aName,
|
|||
: BaseBlobImpl(aName, aContentType, UINT64_MAX, INT64_MAX)
|
||||
, mFile(aFile)
|
||||
, mWholeFile(true)
|
||||
, mFileId(-1)
|
||||
{
|
||||
MOZ_ASSERT(mFile, "must have file");
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
@ -76,6 +80,7 @@ FileBlobImpl::FileBlobImpl(const FileBlobImpl* aOther, uint64_t aStart,
|
|||
: BaseBlobImpl(aContentType, aOther->mStart + aStart, aLength)
|
||||
, mFile(aOther->mFile)
|
||||
, mWholeFile(false)
|
||||
, mFileId(-1)
|
||||
{
|
||||
MOZ_ASSERT(mFile, "must have file");
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
|
|
@ -60,6 +60,16 @@ public:
|
|||
mContentType = aType;
|
||||
}
|
||||
|
||||
int64_t GetFileId() override
|
||||
{
|
||||
return mFileId;
|
||||
}
|
||||
|
||||
void SetFileId(int64_t aFileId)
|
||||
{
|
||||
mFileId = aFileId;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~FileBlobImpl() = default;
|
||||
|
||||
|
@ -74,6 +84,7 @@ private:
|
|||
|
||||
nsCOMPtr<nsIFile> mFile;
|
||||
bool mWholeFile;
|
||||
int64_t mFileId;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -43,6 +43,7 @@ StreamBlobImpl::StreamBlobImpl(nsIInputStream* aInputStream,
|
|||
: BaseBlobImpl(aContentType, aLength)
|
||||
, mInputStream(aInputStream)
|
||||
, mIsDirectory(false)
|
||||
, mFileId(-1)
|
||||
{
|
||||
mImmutable = true;
|
||||
}
|
||||
|
@ -53,6 +54,7 @@ StreamBlobImpl::StreamBlobImpl(StreamBlobImpl* aOther,
|
|||
: BaseBlobImpl(aContentType, aOther->mStart + aStart, aLength)
|
||||
, mInputStream(new SlicedInputStream(aOther->mInputStream, aStart, aLength))
|
||||
, mIsDirectory(false)
|
||||
, mFileId(-1)
|
||||
{
|
||||
mImmutable = true;
|
||||
}
|
||||
|
@ -65,6 +67,7 @@ StreamBlobImpl::StreamBlobImpl(nsIInputStream* aInputStream,
|
|||
: BaseBlobImpl(aName, aContentType, aLength, aLastModifiedDate)
|
||||
, mInputStream(aInputStream)
|
||||
, mIsDirectory(false)
|
||||
, mFileId(-1)
|
||||
{
|
||||
mImmutable = true;
|
||||
}
|
||||
|
|
|
@ -46,6 +46,16 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
int64_t GetFileId() override
|
||||
{
|
||||
return mFileId;
|
||||
}
|
||||
|
||||
void SetFileId(int64_t aFileId)
|
||||
{
|
||||
mFileId = aFileId;
|
||||
}
|
||||
|
||||
void SetFullPath(const nsAString& aFullPath)
|
||||
{
|
||||
mFullPath = aFullPath;
|
||||
|
@ -91,6 +101,7 @@ private:
|
|||
|
||||
nsString mFullPath;
|
||||
bool mIsDirectory;
|
||||
int64_t mFileId;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -58,6 +58,9 @@ struct IPCBlob
|
|||
IPCBlobStream inputStream;
|
||||
|
||||
IPCFileUnion file;
|
||||
|
||||
// This ID is used only by indexedDB tests.
|
||||
int64_t fileId;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -28,7 +28,7 @@ public:
|
|||
|
||||
nsCOMPtr<nsIEventTarget> target = aEventTarget;
|
||||
if (!target) {
|
||||
target = SystemGroup::EventTargetFor(TaskCategory::Other);
|
||||
target = NS_GetCurrentThread();
|
||||
}
|
||||
|
||||
target->Dispatch(runnable, NS_DISPATCH_NORMAL);
|
||||
|
@ -69,6 +69,7 @@ NS_INTERFACE_MAP_BEGIN(IPCBlobInputStream)
|
|||
NS_INTERFACE_MAP_ENTRY(nsICloneableInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIIPCSerializableInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsISeekableStream, IsSeekableStream())
|
||||
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIFileMetadata, IsFileMetadata())
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIInputStream)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
|
@ -369,6 +370,50 @@ IPCBlobInputStream::ExpectedSerializedLength()
|
|||
return mozilla::Nothing();
|
||||
}
|
||||
|
||||
// nsIFileMetadata
|
||||
|
||||
bool
|
||||
IPCBlobInputStream::IsFileMetadata() const
|
||||
{
|
||||
// We are nsIFileMetadata only if we have the remote stream and that is a
|
||||
// nsIFileMetadata.
|
||||
nsCOMPtr<nsIFileMetadata> fileMetadata = do_QueryInterface(mRemoteStream);
|
||||
return !!fileMetadata;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IPCBlobInputStream::GetSize(int64_t* aRetval)
|
||||
{
|
||||
nsCOMPtr<nsIFileMetadata> fileMetadata = do_QueryInterface(mRemoteStream);
|
||||
if (!fileMetadata) {
|
||||
return mState == eClosed ? NS_BASE_STREAM_CLOSED : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return fileMetadata->GetSize(aRetval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IPCBlobInputStream::GetLastModified(int64_t* aRetval)
|
||||
{
|
||||
nsCOMPtr<nsIFileMetadata> fileMetadata = do_QueryInterface(mRemoteStream);
|
||||
if (!fileMetadata) {
|
||||
return mState == eClosed ? NS_BASE_STREAM_CLOSED : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return fileMetadata->GetLastModified(aRetval);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IPCBlobInputStream::GetFileDescriptor(PRFileDesc** aRetval)
|
||||
{
|
||||
nsCOMPtr<nsIFileMetadata> fileMetadata = do_QueryInterface(mRemoteStream);
|
||||
if (!fileMetadata) {
|
||||
return mState == eClosed ? NS_BASE_STREAM_CLOSED : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return fileMetadata->GetFileDescriptor(aRetval);
|
||||
}
|
||||
|
||||
// nsISeekableStream
|
||||
|
||||
bool
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "nsIAsyncInputStream.h"
|
||||
#include "nsICloneableInputStream.h"
|
||||
#include "nsIFileStreams.h"
|
||||
#include "nsIIPCSerializableInputStream.h"
|
||||
#include "nsISeekableStream.h"
|
||||
|
||||
|
@ -22,6 +23,7 @@ class IPCBlobInputStream final : public nsIAsyncInputStream
|
|||
, public nsICloneableInputStream
|
||||
, public nsIIPCSerializableInputStream
|
||||
, public nsISeekableStream
|
||||
, public nsIFileMetadata
|
||||
{
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
@ -31,6 +33,7 @@ public:
|
|||
NS_DECL_NSICLONEABLEINPUTSTREAM
|
||||
NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM
|
||||
NS_DECL_NSISEEKABLESTREAM
|
||||
NS_DECL_NSIFILEMETADATA
|
||||
|
||||
explicit IPCBlobInputStream(IPCBlobInputStreamChild* aActor);
|
||||
|
||||
|
@ -47,6 +50,9 @@ private:
|
|||
bool
|
||||
IsSeekableStream() const;
|
||||
|
||||
bool
|
||||
IsFileMetadata() const;
|
||||
|
||||
RefPtr<IPCBlobInputStreamChild> mActor;
|
||||
|
||||
// This is the list of possible states.
|
||||
|
|
|
@ -57,6 +57,23 @@ IPCBlobInputStreamParent::ActorDestroy(IProtocol::ActorDestroyReason aReason)
|
|||
mPBackgroundManager = nullptr;
|
||||
|
||||
IPCBlobInputStreamStorage::Get()->ForgetStream(mID);
|
||||
|
||||
RefPtr<IPCBlobInputStreamParentCallback> callback;
|
||||
mCallback.swap(callback);
|
||||
|
||||
if (callback) {
|
||||
callback->ActorDestroyed(mID);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IPCBlobInputStreamParent::SetCallback(
|
||||
IPCBlobInputStreamParentCallback* aCallback)
|
||||
{
|
||||
MOZ_ASSERT(aCallback);
|
||||
MOZ_ASSERT(!mCallback);
|
||||
|
||||
mCallback = aCallback;
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
|
|
|
@ -14,6 +14,19 @@ class nsIInputStream;
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class NS_NO_VTABLE IPCBlobInputStreamParentCallback
|
||||
{
|
||||
public:
|
||||
virtual void
|
||||
ActorDestroyed(const nsID& aID) = 0;
|
||||
|
||||
NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
|
||||
|
||||
protected:
|
||||
virtual ~IPCBlobInputStreamParentCallback()
|
||||
{ }
|
||||
};
|
||||
|
||||
class IPCBlobInputStreamParent final
|
||||
: public mozilla::ipc::PIPCBlobInputStreamParent
|
||||
{
|
||||
|
@ -41,6 +54,9 @@ public:
|
|||
return mSize;
|
||||
}
|
||||
|
||||
void
|
||||
SetCallback(IPCBlobInputStreamParentCallback* aCallback);
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
RecvStreamNeeded() override;
|
||||
|
||||
|
@ -61,6 +77,8 @@ private:
|
|||
// the parent actor alive. The pointers will be nullified in ActorDestroyed.
|
||||
nsIContentParent* mContentManager;
|
||||
mozilla::ipc::PBackgroundParent* mPBackgroundManager;
|
||||
|
||||
RefPtr<IPCBlobInputStreamParentCallback> mCallback;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -65,6 +65,8 @@ Deserialize(const IPCBlob& aIPCBlob)
|
|||
blobImpl->SetIsDirectory(file.isDirectory());
|
||||
}
|
||||
|
||||
blobImpl->SetFileId(aIPCBlob.fileId());
|
||||
|
||||
return blobImpl.forget();
|
||||
}
|
||||
|
||||
|
@ -178,6 +180,8 @@ SerializeInternal(BlobImpl* aBlobImpl, M* aManager, IPCBlob& aIPCBlob)
|
|||
aIPCBlob.file() = file;
|
||||
}
|
||||
|
||||
aIPCBlob.fileId() = aBlobImpl->GetFileId();
|
||||
|
||||
nsCOMPtr<nsIInputStream> inputStream;
|
||||
aBlobImpl->GetInternalStream(getter_AddRefs(inputStream), rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
|
|
|
@ -27,10 +27,12 @@
|
|||
#include "mozilla/dom/TabChild.h"
|
||||
#include "mozilla/dom/indexedDB/PBackgroundIDBDatabaseFileChild.h"
|
||||
#include "mozilla/dom/indexedDB/PIndexedDBPermissionRequestChild.h"
|
||||
#include "mozilla/dom/ipc/BlobChild.h"
|
||||
#include "mozilla/dom/IPCBlobUtils.h"
|
||||
#include "mozilla/ipc/BackgroundUtils.h"
|
||||
#include "mozilla/TaskQueue.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIAsyncInputStream.h"
|
||||
#include "nsIBFCacheEntry.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
|
@ -615,18 +617,15 @@ DeserializeStructuredCloneFiles(
|
|||
|
||||
switch (serializedFile.type()) {
|
||||
case StructuredCloneFile::eBlob: {
|
||||
MOZ_ASSERT(blobOrMutableFile.type() == BlobOrMutableFile::TPBlobChild);
|
||||
MOZ_ASSERT(blobOrMutableFile.type() == BlobOrMutableFile::TIPCBlob);
|
||||
|
||||
auto* actor =
|
||||
static_cast<BlobChild*>(blobOrMutableFile.get_PBlobChild());
|
||||
const IPCBlob& ipcBlob = blobOrMutableFile.get_IPCBlob();
|
||||
|
||||
RefPtr<BlobImpl> blobImpl = actor->GetBlobImpl();
|
||||
RefPtr<BlobImpl> blobImpl = IPCBlobUtils::Deserialize(ipcBlob);
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
RefPtr<Blob> blob = Blob::Create(aDatabase->GetOwner(), blobImpl);
|
||||
|
||||
aDatabase->NoteReceivedBlob(blob);
|
||||
|
||||
StructuredCloneFile* file = aFiles.AppendElement();
|
||||
MOZ_ASSERT(file);
|
||||
|
||||
|
@ -710,19 +709,15 @@ DeserializeStructuredCloneFiles(
|
|||
break;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(blobOrMutableFile.type() ==
|
||||
BlobOrMutableFile::TPBlobChild);
|
||||
MOZ_ASSERT(blobOrMutableFile.type() == BlobOrMutableFile::TIPCBlob);
|
||||
|
||||
auto* actor =
|
||||
static_cast<BlobChild*>(blobOrMutableFile.get_PBlobChild());
|
||||
const IPCBlob& ipcBlob = blobOrMutableFile.get_IPCBlob();
|
||||
|
||||
RefPtr<BlobImpl> blobImpl = actor->GetBlobImpl();
|
||||
RefPtr<BlobImpl> blobImpl = IPCBlobUtils::Deserialize(ipcBlob);
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
RefPtr<Blob> blob = Blob::Create(aDatabase->GetOwner(), blobImpl);
|
||||
|
||||
aDatabase->NoteReceivedBlob(blob);
|
||||
|
||||
StructuredCloneFile* file = aFiles.AppendElement();
|
||||
MOZ_ASSERT(file);
|
||||
|
||||
|
@ -1155,6 +1150,7 @@ WorkerPermissionRequestChildProcessActor::Recv__delete__(
|
|||
// CancelableRunnable is used to make workers happy.
|
||||
class BackgroundRequestChild::PreprocessHelper final
|
||||
: public CancelableRunnable
|
||||
, public nsIInputStreamCallback
|
||||
{
|
||||
typedef std::pair<nsCOMPtr<nsIInputStream>,
|
||||
nsCOMPtr<nsIInputStream>> StreamPair;
|
||||
|
@ -1163,6 +1159,14 @@ class BackgroundRequestChild::PreprocessHelper final
|
|||
nsTArray<StreamPair> mStreamPairs;
|
||||
nsTArray<RefPtr<JS::WasmModule>> mModuleSet;
|
||||
BackgroundRequestChild* mActor;
|
||||
|
||||
// These 2 are populated when the processing of the stream pairs runs.
|
||||
PRFileDesc* mCurrentBytecodeFileDesc;
|
||||
PRFileDesc* mCurrentCompiledFileDesc;
|
||||
|
||||
RefPtr<TaskQueue> mTaskQueue;
|
||||
nsCOMPtr<nsIEventTarget> mTaskQueueEventTarget;
|
||||
|
||||
uint32_t mModuleSetIndex;
|
||||
nsresult mResultCode;
|
||||
|
||||
|
@ -1171,6 +1175,8 @@ public:
|
|||
: CancelableRunnable("indexedDB::BackgroundRequestChild::PreprocessHelper")
|
||||
, mOwningThread(aActor->GetActorEventTarget())
|
||||
, mActor(aActor)
|
||||
, mCurrentBytecodeFileDesc(nullptr)
|
||||
, mCurrentCompiledFileDesc(nullptr)
|
||||
, mModuleSetIndex(aModuleSetIndex)
|
||||
, mResultCode(NS_OK)
|
||||
{
|
||||
|
@ -1210,15 +1216,27 @@ public:
|
|||
|
||||
private:
|
||||
~PreprocessHelper()
|
||||
{ }
|
||||
{
|
||||
if (mTaskQueue) {
|
||||
mTaskQueue->BeginShutdown();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RunOnOwningThread();
|
||||
|
||||
nsresult
|
||||
RunOnStreamTransportThread();
|
||||
void
|
||||
ProcessCurrentStreamPair();
|
||||
|
||||
nsresult
|
||||
WaitForStreamReady(nsIInputStream* aInputStream);
|
||||
|
||||
void
|
||||
ContinueWithStatus(nsresult aStatus);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIRUNNABLE
|
||||
NS_DECL_NSIINPUTSTREAMCALLBACK
|
||||
|
||||
virtual nsresult
|
||||
Cancel() override;
|
||||
|
@ -1796,7 +1814,7 @@ BackgroundDatabaseChild::ActorDestroy(ActorDestroyReason aWhy)
|
|||
|
||||
PBackgroundIDBDatabaseFileChild*
|
||||
BackgroundDatabaseChild::AllocPBackgroundIDBDatabaseFileChild(
|
||||
PBlobChild* aBlobChild)
|
||||
const IPCBlob& aIPCBlob)
|
||||
{
|
||||
MOZ_CRASH("PBackgroundIDBFileChild actors should be manually constructed!");
|
||||
}
|
||||
|
@ -3019,14 +3037,22 @@ PreprocessHelper::Dispatch()
|
|||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
// The stream transport service is used for asynchronous processing. It has
|
||||
// a threadpool with a high cap of 25 threads. Fortunately, the service can
|
||||
// be used on workers too.
|
||||
nsCOMPtr<nsIEventTarget> target =
|
||||
do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(target);
|
||||
if (!mTaskQueue) {
|
||||
// The stream transport service is used for asynchronous processing. It has
|
||||
// a threadpool with a high cap of 25 threads. Fortunately, the service can
|
||||
// be used on workers too.
|
||||
nsCOMPtr<nsIEventTarget> target =
|
||||
do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(target);
|
||||
|
||||
nsresult rv = target->Dispatch(this, NS_DISPATCH_NORMAL);
|
||||
// We use a TaskQueue here in order to be sure that the events are
|
||||
// dispatched in the correct order. This is not guaranteed in case we use
|
||||
// the I/O thread directly.
|
||||
mTaskQueue = new TaskQueue(target.forget());
|
||||
mTaskQueueEventTarget = mTaskQueue->WrapAsEventTarget();
|
||||
}
|
||||
|
||||
nsresult rv = mTaskQueueEventTarget->Dispatch(this, NS_DISPATCH_NORMAL);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -3051,61 +3077,128 @@ PreprocessHelper::RunOnOwningThread()
|
|||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
void
|
||||
BackgroundRequestChild::
|
||||
PreprocessHelper::RunOnStreamTransportThread()
|
||||
PreprocessHelper::ProcessCurrentStreamPair()
|
||||
{
|
||||
MOZ_ASSERT(!IsOnOwningThread());
|
||||
MOZ_ASSERT(!mStreamPairs.IsEmpty());
|
||||
MOZ_ASSERT(mModuleSet.IsEmpty());
|
||||
|
||||
const uint32_t count = mStreamPairs.Length();
|
||||
nsresult rv;
|
||||
|
||||
for (uint32_t index = 0; index < count; index++) {
|
||||
const StreamPair& streamPair = mStreamPairs[index];
|
||||
const StreamPair& streamPair = mStreamPairs[0];
|
||||
|
||||
// We still don't have the current bytecode FileDesc.
|
||||
if (!mCurrentBytecodeFileDesc) {
|
||||
const nsCOMPtr<nsIInputStream>& bytecodeStream = streamPair.first;
|
||||
|
||||
MOZ_ASSERT(bytecodeStream);
|
||||
|
||||
PRFileDesc* bytecodeFileDesc = GetFileDescriptorFromStream(bytecodeStream);
|
||||
if (NS_WARN_IF(!bytecodeFileDesc)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
mCurrentBytecodeFileDesc = GetFileDescriptorFromStream(bytecodeStream);
|
||||
if (!mCurrentBytecodeFileDesc) {
|
||||
rv = WaitForStreamReady(bytecodeStream);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
ContinueWithStatus(rv);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const nsCOMPtr<nsIInputStream>& compiledStream = streamPair.second;
|
||||
|
||||
MOZ_ASSERT(compiledStream);
|
||||
|
||||
PRFileDesc* compiledFileDesc = GetFileDescriptorFromStream(compiledStream);
|
||||
if (NS_WARN_IF(!compiledFileDesc)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
JS::BuildIdCharVector buildId;
|
||||
bool ok = GetBuildId(&buildId);
|
||||
if (NS_WARN_IF(!ok)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
RefPtr<JS::WasmModule> module = JS::DeserializeWasmModule(bytecodeFileDesc,
|
||||
compiledFileDesc,
|
||||
Move(buildId),
|
||||
nullptr,
|
||||
0,
|
||||
0);
|
||||
if (NS_WARN_IF(!module)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mModuleSet.AppendElement(module);
|
||||
}
|
||||
|
||||
mStreamPairs.Clear();
|
||||
if (!mCurrentCompiledFileDesc) {
|
||||
const nsCOMPtr<nsIInputStream>& compiledStream = streamPair.second;
|
||||
MOZ_ASSERT(compiledStream);
|
||||
|
||||
mCurrentCompiledFileDesc = GetFileDescriptorFromStream(compiledStream);
|
||||
if (!mCurrentCompiledFileDesc) {
|
||||
rv = WaitForStreamReady(compiledStream);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
ContinueWithStatus(rv);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mCurrentBytecodeFileDesc && mCurrentCompiledFileDesc);
|
||||
|
||||
JS::BuildIdCharVector buildId;
|
||||
bool ok = GetBuildId(&buildId);
|
||||
if (NS_WARN_IF(!ok)) {
|
||||
ContinueWithStatus(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<JS::WasmModule> module =
|
||||
JS::DeserializeWasmModule(mCurrentBytecodeFileDesc,
|
||||
mCurrentCompiledFileDesc,
|
||||
Move(buildId),
|
||||
nullptr,
|
||||
0,
|
||||
0);
|
||||
if (NS_WARN_IF(!module)) {
|
||||
ContinueWithStatus(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
mModuleSet.AppendElement(module);
|
||||
mStreamPairs.RemoveElementAt(0);
|
||||
|
||||
ContinueWithStatus(NS_OK);
|
||||
}
|
||||
|
||||
nsresult
|
||||
BackgroundRequestChild::
|
||||
PreprocessHelper::WaitForStreamReady(nsIInputStream* aInputStream)
|
||||
{
|
||||
MOZ_ASSERT(!IsOnOwningThread());
|
||||
MOZ_ASSERT(aInputStream);
|
||||
|
||||
nsCOMPtr<nsIAsyncInputStream> asyncStream = do_QueryInterface(aInputStream);
|
||||
if (!asyncStream) {
|
||||
return NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
|
||||
nsresult rv = asyncStream->AsyncWait(this, 0, 0, mTaskQueueEventTarget);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
BackgroundRequestChild::
|
||||
PreprocessHelper::ContinueWithStatus(nsresult aStatus)
|
||||
{
|
||||
MOZ_ASSERT(!IsOnOwningThread());
|
||||
|
||||
// Let's reset the value for the next operation.
|
||||
mCurrentBytecodeFileDesc = nullptr;
|
||||
mCurrentCompiledFileDesc = nullptr;
|
||||
|
||||
nsCOMPtr<nsIEventTarget> eventTarget;
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(aStatus))) {
|
||||
// If the previous operation failed, we don't continue the processing of the
|
||||
// other stream pairs.
|
||||
MOZ_ASSERT(mResultCode == NS_OK);
|
||||
mResultCode = aStatus;
|
||||
|
||||
eventTarget = mOwningThread;
|
||||
} else if (mStreamPairs.IsEmpty()) {
|
||||
// If all the streams have been processed, we can go back to the owning
|
||||
// thread.
|
||||
eventTarget = mOwningThread;
|
||||
} else {
|
||||
// Continue the processing.
|
||||
eventTarget = mTaskQueueEventTarget;
|
||||
}
|
||||
|
||||
nsresult rv = eventTarget->Dispatch(this, NS_DISPATCH_NORMAL);
|
||||
Unused << NS_WARN_IF(NS_FAILED(rv));
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED(BackgroundRequestChild::PreprocessHelper,
|
||||
CancelableRunnable, nsIInputStreamCallback)
|
||||
|
||||
NS_IMETHODIMP
|
||||
BackgroundRequestChild::
|
||||
PreprocessHelper::Run()
|
||||
|
@ -3113,18 +3206,48 @@ PreprocessHelper::Run()
|
|||
if (IsOnOwningThread()) {
|
||||
RunOnOwningThread();
|
||||
} else {
|
||||
nsresult rv = RunOnStreamTransportThread();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
MOZ_ASSERT(mResultCode == NS_OK);
|
||||
mResultCode = rv;
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_SUCCEEDS(mOwningThread->Dispatch(this, NS_DISPATCH_NORMAL));
|
||||
ProcessCurrentStreamPair();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
BackgroundRequestChild::
|
||||
PreprocessHelper::OnInputStreamReady(nsIAsyncInputStream* aStream)
|
||||
{
|
||||
MOZ_ASSERT(!IsOnOwningThread());
|
||||
MOZ_ASSERT(aStream);
|
||||
MOZ_ASSERT(!mStreamPairs.IsEmpty());
|
||||
|
||||
// We still don't have the current bytecode FileDesc.
|
||||
if (!mCurrentBytecodeFileDesc) {
|
||||
mCurrentBytecodeFileDesc = GetFileDescriptorFromStream(aStream);
|
||||
if (!mCurrentBytecodeFileDesc) {
|
||||
ContinueWithStatus(NS_ERROR_FAILURE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Let's continue with the processing of the current pair.
|
||||
ProcessCurrentStreamPair();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!mCurrentCompiledFileDesc) {
|
||||
mCurrentCompiledFileDesc = GetFileDescriptorFromStream(aStream);
|
||||
if (!mCurrentCompiledFileDesc) {
|
||||
ContinueWithStatus(NS_ERROR_FAILURE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Let's continue with the processing of the current pair.
|
||||
ProcessCurrentStreamPair();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MOZ_CRASH("If we have both fileDescs why are we here?");
|
||||
}
|
||||
|
||||
nsresult
|
||||
BackgroundRequestChild::
|
||||
PreprocessHelper::Cancel()
|
||||
|
|
|
@ -365,8 +365,7 @@ private:
|
|||
ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
virtual PBackgroundIDBDatabaseFileChild*
|
||||
AllocPBackgroundIDBDatabaseFileChild(PBlobChild* aBlobChild)
|
||||
override;
|
||||
AllocPBackgroundIDBDatabaseFileChild(const IPCBlob& aIPCBlob) override;
|
||||
|
||||
virtual bool
|
||||
DeallocPBackgroundIDBDatabaseFileChild(
|
||||
|
|
|
@ -52,7 +52,8 @@
|
|||
#include "mozilla/dom/indexedDB/PBackgroundIDBVersionChangeTransactionParent.h"
|
||||
#include "mozilla/dom/indexedDB/PBackgroundIndexedDBUtilsParent.h"
|
||||
#include "mozilla/dom/indexedDB/PIndexedDBPermissionRequestParent.h"
|
||||
#include "mozilla/dom/ipc/BlobParent.h"
|
||||
#include "mozilla/dom/IPCBlobUtils.h"
|
||||
#include "mozilla/dom/ipc/IPCBlobInputStreamParent.h"
|
||||
#include "mozilla/dom/quota/Client.h"
|
||||
#include "mozilla/dom/quota/FileStreams.h"
|
||||
#include "mozilla/dom/quota/OriginScope.h"
|
||||
|
@ -127,9 +128,6 @@
|
|||
#define IDB_MOBILE
|
||||
#endif
|
||||
|
||||
#define BLOB_IMPL_STORED_FILE_IID \
|
||||
{0x6b505c84, 0x2c60, 0x4ffb, {0x8b, 0x91, 0xfe, 0x22, 0xb1, 0xec, 0x75, 0xe2}}
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPRFileDesc,
|
||||
|
@ -6397,6 +6395,7 @@ class Database final
|
|||
friend class VersionChangeTransaction;
|
||||
|
||||
class StartTransactionOp;
|
||||
class UnmapBlobCallback;
|
||||
|
||||
private:
|
||||
RefPtr<Factory> mFactory;
|
||||
|
@ -6405,6 +6404,7 @@ private:
|
|||
RefPtr<DirectoryLock> mDirectoryLock;
|
||||
nsTHashtable<nsPtrHashKey<TransactionBase>> mTransactions;
|
||||
nsTHashtable<nsPtrHashKey<MutableFile>> mMutableFiles;
|
||||
nsRefPtrHashtable<nsIDHashKey, FileInfo> mMappedBlobs;
|
||||
RefPtr<DatabaseConnection> mConnection;
|
||||
const PrincipalInfo mPrincipalInfo;
|
||||
const Maybe<ContentParentId> mOptionalContentParentId;
|
||||
|
@ -6422,6 +6422,9 @@ private:
|
|||
bool mActorWasAlive;
|
||||
bool mActorDestroyed;
|
||||
bool mMetadataCleanedUp;
|
||||
#ifdef DEBUG
|
||||
bool mAllBlobsUnmapped;
|
||||
#endif
|
||||
|
||||
public:
|
||||
// Created by OpenDatabaseOp.
|
||||
|
@ -6571,6 +6574,9 @@ public:
|
|||
void
|
||||
SetActorAlive();
|
||||
|
||||
void
|
||||
MapBlob(const IPCBlob& aIPCBlob, FileInfo* aFileInfo);
|
||||
|
||||
bool
|
||||
IsActorAlive() const
|
||||
{
|
||||
|
@ -6626,6 +6632,15 @@ private:
|
|||
MOZ_ASSERT_IF(mActorWasAlive, mActorDestroyed);
|
||||
}
|
||||
|
||||
already_AddRefed<FileInfo>
|
||||
GetBlob(const IPCBlob& aID);
|
||||
|
||||
void
|
||||
UnmapBlob(const nsID& aID);
|
||||
|
||||
void
|
||||
UnmapAllBlobs();
|
||||
|
||||
bool
|
||||
CloseInternal();
|
||||
|
||||
|
@ -6646,8 +6661,7 @@ private:
|
|||
ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
PBackgroundIDBDatabaseFileParent*
|
||||
AllocPBackgroundIDBDatabaseFileParent(PBlobParent* aBlobParent)
|
||||
override;
|
||||
AllocPBackgroundIDBDatabaseFileParent(const IPCBlob& aIPCBlob) override;
|
||||
|
||||
bool
|
||||
DeallocPBackgroundIDBDatabaseFileParent(
|
||||
|
@ -6748,6 +6762,36 @@ private:
|
|||
Cleanup() override;
|
||||
};
|
||||
|
||||
class Database::UnmapBlobCallback final
|
||||
: public IPCBlobInputStreamParentCallback
|
||||
{
|
||||
RefPtr<Database> mDatabase;
|
||||
|
||||
public:
|
||||
explicit UnmapBlobCallback(Database* aDatabase)
|
||||
: mDatabase(aDatabase)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
}
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Database::UnmapBlobCallback, override)
|
||||
|
||||
void
|
||||
ActorDestroyed(const nsID& aID) override
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(mDatabase);
|
||||
|
||||
RefPtr<Database> database;
|
||||
mDatabase.swap(database);
|
||||
|
||||
database->UnmapBlob(aID);
|
||||
}
|
||||
|
||||
private:
|
||||
~UnmapBlobCallback() = default;
|
||||
};
|
||||
|
||||
/**
|
||||
* In coordination with IDBDatabase's mFileActors weak-map on the child side, a
|
||||
* long-lived mapping from a child process's live Blobs to their corresponding
|
||||
|
@ -6756,19 +6800,18 @@ private:
|
|||
* - Blobs retrieved from this database and sent to the child that do not need
|
||||
* to be written to disk because they already exist on disk in this database's
|
||||
* files directory.
|
||||
* - Blobs retrieved from other databases (that are therefore !IsShareable())
|
||||
* or from anywhere else that will need to be written to this database's files
|
||||
* directory. In this case we will hold a reference to its BlobImpl in
|
||||
* mBlobImpl until we have successfully written the Blob to disk.
|
||||
* - Blobs retrieved from other databases or from anywhere else that will need
|
||||
* to be written to this database's files directory. In this case we will
|
||||
* hold a reference to its BlobImpl in mBlobImpl until we have successfully
|
||||
* written the Blob to disk.
|
||||
*
|
||||
* Relevant Blob context: Blobs sent from the parent process to child processes
|
||||
* are automatically linked back to their source BlobImpl when the child process
|
||||
* references the Blob via IPC. (This is true even when a new "KnownBlob" actor
|
||||
* must be created because the reference is occurring on a different thread than
|
||||
* the PBlob actor created when the blob was sent to the child.) However, when
|
||||
* getting an actor in the child process for sending an in-child-created Blob to
|
||||
* the parent process, there is (currently) no Blob machinery to automatically
|
||||
* establish and reuse a long-lived Actor. As a result, without IDB's weak-map
|
||||
* references the Blob via IPC. This is done using the internal IPCBlob
|
||||
* inputStream actor ID to FileInfo mapping. However, when getting an actor
|
||||
* in the child process for sending an in-child-created Blob to the parent
|
||||
* process, there is (currently) no Blob machinery to automatically establish
|
||||
* and reuse a long-lived Actor. As a result, without IDB's weak-map
|
||||
* cleverness, a memory-backed Blob repeatedly sent from the child to the parent
|
||||
* would appear as a different Blob each time, requiring the Blob data to be
|
||||
* sent over IPC each time as well as potentially needing to be written to disk
|
||||
|
@ -9111,70 +9154,6 @@ private:
|
|||
~DatabaseLoggingInfo();
|
||||
};
|
||||
|
||||
class BlobImplStoredFile final
|
||||
: public FileBlobImpl
|
||||
{
|
||||
RefPtr<FileInfo> mFileInfo;
|
||||
const bool mSnapshot;
|
||||
|
||||
public:
|
||||
BlobImplStoredFile(nsIFile* aFile, FileInfo* aFileInfo, bool aSnapshot)
|
||||
: FileBlobImpl(aFile)
|
||||
, mFileInfo(aFileInfo)
|
||||
, mSnapshot(aSnapshot)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
// Getting the content type is not currently supported off the main thread.
|
||||
// This isn't a problem here because:
|
||||
//
|
||||
// 1. The real content type is stored in the structured clone data and
|
||||
// that's all that the DOM will see. This blob's data will be updated
|
||||
// during RecvSetMysteryBlobInfo().
|
||||
// 2. The nsExternalHelperAppService guesses the content type based only
|
||||
// on the file extension. Our stored files have no extension so the
|
||||
// current code path fails and sets the content type to the empty
|
||||
// string.
|
||||
//
|
||||
// So, this is a hack to keep the nsExternalHelperAppService out of the
|
||||
// picture entirely. Eventually we should probably fix this some other way.
|
||||
mContentType.Truncate();
|
||||
mIsFile = false;
|
||||
}
|
||||
|
||||
bool
|
||||
IsShareable(FileManager* aFileManager) const
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
return mFileInfo->Manager() == aFileManager && !mSnapshot;
|
||||
}
|
||||
|
||||
FileInfo*
|
||||
GetFileInfo() const
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
return mFileInfo;
|
||||
}
|
||||
|
||||
private:
|
||||
~BlobImplStoredFile() override = default;
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(BLOB_IMPL_STORED_FILE_IID)
|
||||
|
||||
int64_t
|
||||
GetFileId() override
|
||||
{
|
||||
MOZ_ASSERT(mFileInfo);
|
||||
|
||||
return mFileInfo->Id();
|
||||
}
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(BlobImplStoredFile, BLOB_IMPL_STORED_FILE_IID)
|
||||
|
||||
class QuotaClient final
|
||||
: public mozilla::dom::quota::Client
|
||||
{
|
||||
|
@ -10159,24 +10138,25 @@ SerializeStructuredCloneFiles(
|
|||
|
||||
switch (file.mType) {
|
||||
case StructuredCloneFile::eBlob: {
|
||||
RefPtr<BlobImpl> impl = new BlobImplStoredFile(nativeFile,
|
||||
file.mFileInfo,
|
||||
/* aSnapshot */ false);
|
||||
RefPtr<FileBlobImpl> impl = new FileBlobImpl(nativeFile);
|
||||
impl->SetFileId(file.mFileInfo->Id());
|
||||
|
||||
PBlobParent* actor =
|
||||
BackgroundParent::GetOrCreateActorForBlobImpl(aBackgroundActor, impl);
|
||||
if (!actor) {
|
||||
IPCBlob ipcBlob;
|
||||
nsresult rv = IPCBlobUtils::Serialize(impl, aBackgroundActor, ipcBlob);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
// This can only fail if the child has crashed.
|
||||
IDB_REPORT_INTERNAL_ERR();
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
SerializedStructuredCloneFile* file = aResult.AppendElement(fallible);
|
||||
MOZ_ASSERT(file);
|
||||
SerializedStructuredCloneFile* serializedFile =
|
||||
aResult.AppendElement(fallible);
|
||||
MOZ_ASSERT(serializedFile);
|
||||
|
||||
file->file() = actor;
|
||||
file->type() = StructuredCloneFile::eBlob;
|
||||
serializedFile->file() = ipcBlob;
|
||||
serializedFile->type() = StructuredCloneFile::eBlob;
|
||||
|
||||
aDatabase->MapBlob(ipcBlob, file.mFileInfo);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -10236,14 +10216,13 @@ SerializeStructuredCloneFiles(
|
|||
serializedFile->file() = null_t();
|
||||
serializedFile->type() = file.mType;
|
||||
} else {
|
||||
RefPtr<BlobImpl> impl = new BlobImplStoredFile(nativeFile,
|
||||
file.mFileInfo,
|
||||
/* aSnapshot */ false);
|
||||
RefPtr<FileBlobImpl> impl = new FileBlobImpl(nativeFile);
|
||||
impl->SetFileId(file.mFileInfo->Id());
|
||||
|
||||
PBlobParent* actor =
|
||||
BackgroundParent::GetOrCreateActorForBlobImpl(aBackgroundActor,
|
||||
impl);
|
||||
if (!actor) {
|
||||
IPCBlob ipcBlob;
|
||||
nsresult rv =
|
||||
IPCBlobUtils::Serialize(impl, aBackgroundActor, ipcBlob);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
// This can only fail if the child has crashed.
|
||||
IDB_REPORT_INTERNAL_ERR();
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
|
@ -10253,8 +10232,10 @@ SerializeStructuredCloneFiles(
|
|||
aResult.AppendElement(fallible);
|
||||
MOZ_ASSERT(serializedFile);
|
||||
|
||||
serializedFile->file() = actor;
|
||||
serializedFile->file() = ipcBlob;
|
||||
serializedFile->type() = file.mType;
|
||||
|
||||
aDatabase->MapBlob(ipcBlob, file.mFileInfo);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -14173,6 +14154,9 @@ Database::Database(Factory* aFactory,
|
|||
, mActorWasAlive(false)
|
||||
, mActorDestroyed(false)
|
||||
, mMetadataCleanedUp(false)
|
||||
#ifdef DEBUG
|
||||
, mAllBlobsUnmapped(false)
|
||||
#endif
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aFactory);
|
||||
|
@ -14398,6 +14382,76 @@ Database::SetActorAlive()
|
|||
AddRef();
|
||||
}
|
||||
|
||||
void
|
||||
Database::MapBlob(const IPCBlob& aIPCBlob, FileInfo* aFileInfo)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
const IPCBlobStream& stream = aIPCBlob.inputStream();
|
||||
MOZ_ASSERT(stream.type() == IPCBlobStream::TPIPCBlobInputStreamParent);
|
||||
|
||||
IPCBlobInputStreamParent* actor =
|
||||
static_cast<IPCBlobInputStreamParent*>(stream.get_PIPCBlobInputStreamParent());
|
||||
|
||||
MOZ_ASSERT(!mMappedBlobs.GetWeak(actor->ID()));
|
||||
mMappedBlobs.Put(actor->ID(), aFileInfo);
|
||||
|
||||
RefPtr<UnmapBlobCallback> callback = new UnmapBlobCallback(this);
|
||||
actor->SetCallback(callback);
|
||||
}
|
||||
|
||||
already_AddRefed<FileInfo>
|
||||
Database::GetBlob(const IPCBlob& aIPCBlob)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
const IPCBlobStream& stream = aIPCBlob.inputStream();
|
||||
MOZ_ASSERT(stream.type() == IPCBlobStream::TIPCStream);
|
||||
|
||||
const IPCStream& ipcStream = stream.get_IPCStream();
|
||||
|
||||
if (ipcStream.type() != IPCStream::TInputStreamParamsWithFds) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const InputStreamParams& inputStreamParams =
|
||||
ipcStream.get_InputStreamParamsWithFds().stream();
|
||||
if (inputStreamParams.type() !=
|
||||
InputStreamParams::TIPCBlobInputStreamParams) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const nsID& id = inputStreamParams.get_IPCBlobInputStreamParams().id();
|
||||
|
||||
RefPtr<FileInfo> fileInfo;
|
||||
if (!mMappedBlobs.Get(id, getter_AddRefs(fileInfo))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return fileInfo.forget();
|
||||
}
|
||||
|
||||
void
|
||||
Database::UnmapBlob(const nsID& aID)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
MOZ_ASSERT_IF(!mAllBlobsUnmapped, mMappedBlobs.GetWeak(aID));
|
||||
mMappedBlobs.Remove(aID);
|
||||
}
|
||||
|
||||
void
|
||||
Database::UnmapAllBlobs()
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
#ifdef DEBUG
|
||||
mAllBlobsUnmapped = true;
|
||||
#endif
|
||||
|
||||
mMappedBlobs.Clear();
|
||||
}
|
||||
|
||||
bool
|
||||
Database::CloseInternal()
|
||||
{
|
||||
|
@ -14463,6 +14517,8 @@ Database::ConnectionClosedCallback()
|
|||
|
||||
CleanupMetadata();
|
||||
|
||||
UnmapAllBlobs();
|
||||
|
||||
if (IsInvalidated() && IsActorAlive()) {
|
||||
// Step 3 and 4 of "5.2 Closing a Database":
|
||||
// 1. Wait for all transactions to complete.
|
||||
|
@ -14539,24 +14595,17 @@ Database::ActorDestroy(ActorDestroyReason aWhy)
|
|||
}
|
||||
|
||||
PBackgroundIDBDatabaseFileParent*
|
||||
Database::AllocPBackgroundIDBDatabaseFileParent(PBlobParent* aBlobParent)
|
||||
Database::AllocPBackgroundIDBDatabaseFileParent(const IPCBlob& aIPCBlob)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aBlobParent);
|
||||
|
||||
RefPtr<BlobImpl> blobImpl =
|
||||
static_cast<BlobParent*>(aBlobParent)->GetBlobImpl();
|
||||
RefPtr<BlobImpl> blobImpl = IPCBlobUtils::Deserialize(aIPCBlob);
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
RefPtr<FileInfo> fileInfo;
|
||||
RefPtr<FileInfo> fileInfo = GetBlob(aIPCBlob);
|
||||
RefPtr<DatabaseFile> actor;
|
||||
|
||||
RefPtr<BlobImplStoredFile> storedFileImpl = do_QueryObject(blobImpl);
|
||||
if (storedFileImpl && storedFileImpl->IsShareable(mFileManager)) {
|
||||
// This blob was previously shared with the child.
|
||||
fileInfo = storedFileImpl->GetFileInfo();
|
||||
MOZ_ASSERT(fileInfo);
|
||||
|
||||
if (fileInfo) {
|
||||
actor = new DatabaseFile(fileInfo);
|
||||
} else {
|
||||
// This is a blob we haven't seen before.
|
||||
|
@ -17677,14 +17726,6 @@ FileManager::GetUsage(nsIFile* aDirectory, uint64_t* aUsage)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* FileImplStoredFile
|
||||
******************************************************************************/
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED(BlobImplStoredFile,
|
||||
FileBlobImpl,
|
||||
BlobImplStoredFile)
|
||||
|
||||
/*******************************************************************************
|
||||
* QuotaClient
|
||||
******************************************************************************/
|
||||
|
@ -20849,8 +20890,9 @@ MutableFile::CreateBlobImpl()
|
|||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
RefPtr<BlobImpl> blobImpl =
|
||||
new BlobImplStoredFile(mFile, mFileInfo, /* aSnapshot */ true);
|
||||
RefPtr<FileBlobImpl> blobImpl = new FileBlobImpl(mFile);
|
||||
blobImpl->SetFileId(mFileInfo->Id());
|
||||
|
||||
return blobImpl.forget();
|
||||
}
|
||||
|
||||
|
|
|
@ -30,11 +30,10 @@
|
|||
#include "mozilla/dom/IDBObjectStoreBinding.h"
|
||||
#include "mozilla/dom/indexedDB/PBackgroundIDBDatabaseFileChild.h"
|
||||
#include "mozilla/dom/indexedDB/PBackgroundIDBSharedTypes.h"
|
||||
#include "mozilla/dom/IPCBlobUtils.h"
|
||||
#include "mozilla/dom/quota/QuotaManager.h"
|
||||
#include "mozilla/ipc/BackgroundChild.h"
|
||||
#include "mozilla/ipc/BackgroundUtils.h"
|
||||
#include "mozilla/dom/ipc/BlobChild.h"
|
||||
#include "mozilla/dom/ipc/nsIRemoteBlob.h"
|
||||
#include "mozilla/dom/quota/QuotaManager.h"
|
||||
#include "mozilla/ipc/FileDescriptor.h"
|
||||
#include "mozilla/ipc/InputStreamParams.h"
|
||||
#include "mozilla/ipc/InputStreamUtils.h"
|
||||
|
@ -927,63 +926,27 @@ IDBDatabase::GetOrCreateFileActorForBlob(Blob* aBlob)
|
|||
BlobImpl* blobImpl = aBlob->Impl();
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
if (mReceivedBlobs.GetEntry(weakRef)) {
|
||||
// This blob was previously retrieved from the database.
|
||||
nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryObject(blobImpl);
|
||||
MOZ_ASSERT(remoteBlob);
|
||||
PBackgroundChild* backgroundManager =
|
||||
mBackgroundActor->Manager()->Manager();
|
||||
MOZ_ASSERT(backgroundManager);
|
||||
|
||||
BlobChild* blobChild = remoteBlob->GetBlobChild();
|
||||
MOZ_ASSERT(blobChild);
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
PBackgroundChild* backgroundManager = blobChild->GetBackgroundManager();
|
||||
MOZ_ASSERT(backgroundManager);
|
||||
|
||||
PBackgroundChild* thisManager = mBackgroundActor->Manager()->Manager();
|
||||
MOZ_ASSERT(thisManager);
|
||||
|
||||
MOZ_ASSERT(thisManager == backgroundManager);
|
||||
}
|
||||
#endif
|
||||
auto* dbFile = new DatabaseFile(this);
|
||||
|
||||
actor =
|
||||
mBackgroundActor->SendPBackgroundIDBDatabaseFileConstructor(dbFile,
|
||||
blobChild);
|
||||
if (NS_WARN_IF(!actor)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(actor->GetActorEventTarget(),
|
||||
"The event target shall be inherited from its manager actor.");
|
||||
} else {
|
||||
// Make sure that the input stream we get here is one that can actually be
|
||||
// serialized to PBackground.
|
||||
PBackgroundChild* backgroundManager =
|
||||
mBackgroundActor->Manager()->Manager();
|
||||
MOZ_ASSERT(backgroundManager);
|
||||
|
||||
auto* blobChild =
|
||||
static_cast<BlobChild*>(
|
||||
BackgroundChild::GetOrCreateActorForBlob(backgroundManager, aBlob));
|
||||
MOZ_ASSERT(blobChild);
|
||||
|
||||
auto* dbFile = new DatabaseFile(this);
|
||||
|
||||
actor =
|
||||
mBackgroundActor->SendPBackgroundIDBDatabaseFileConstructor(dbFile,
|
||||
blobChild);
|
||||
if (NS_WARN_IF(!actor)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(actor->GetActorEventTarget(),
|
||||
"The event target shall be inherited from its manager actor.");
|
||||
IPCBlob ipcBlob;
|
||||
nsresult rv = IPCBlobUtils::Serialize(blobImpl, backgroundManager, ipcBlob);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(actor);
|
||||
auto* dbFile = new DatabaseFile(this);
|
||||
|
||||
actor =
|
||||
mBackgroundActor->SendPBackgroundIDBDatabaseFileConstructor(dbFile,
|
||||
ipcBlob);
|
||||
if (NS_WARN_IF(!actor)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(actor->GetActorEventTarget(),
|
||||
"The event target shall be inherited from its manager actor.");
|
||||
mFileActors.Put(weakRef, actor);
|
||||
}
|
||||
|
||||
|
@ -1009,42 +972,6 @@ IDBDatabase::NoteFinishedFileActor(PBackgroundIDBDatabaseFileChild* aFileActor)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
IDBDatabase::NoteReceivedBlob(Blob* aBlob)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aBlob);
|
||||
MOZ_ASSERT(mBackgroundActor);
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
RefPtr<BlobImpl> blobImpl = aBlob->Impl();
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryObject(blobImpl);
|
||||
MOZ_ASSERT(remoteBlob);
|
||||
|
||||
BlobChild* blobChild = remoteBlob->GetBlobChild();
|
||||
MOZ_ASSERT(blobChild);
|
||||
|
||||
PBackgroundChild* backgroundManager = blobChild->GetBackgroundManager();
|
||||
MOZ_ASSERT(backgroundManager);
|
||||
|
||||
PBackgroundChild* thisManager = mBackgroundActor->Manager()->Manager();
|
||||
MOZ_ASSERT(thisManager);
|
||||
|
||||
MOZ_ASSERT(thisManager == backgroundManager);
|
||||
}
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIDOMBlob> blob = aBlob;
|
||||
nsCOMPtr<nsIWeakReference> weakRef = do_GetWeakReference(blob);
|
||||
MOZ_ASSERT(weakRef);
|
||||
|
||||
// It's ok if this entry already exists in the table.
|
||||
mReceivedBlobs.PutEntry(weakRef);
|
||||
}
|
||||
|
||||
void
|
||||
IDBDatabase::DelayedMaybeExpireFileActors()
|
||||
{
|
||||
|
@ -1156,25 +1083,6 @@ IDBDatabase::ExpireFileActors(bool aExpireAll)
|
|||
} else {
|
||||
MOZ_ASSERT(!mFileActors.Count());
|
||||
}
|
||||
|
||||
if (mReceivedBlobs.Count()) {
|
||||
if (aExpireAll) {
|
||||
mReceivedBlobs.Clear();
|
||||
} else {
|
||||
for (auto iter = mReceivedBlobs.Iter(); !iter.Done(); iter.Next()) {
|
||||
nsISupports* key = iter.Get()->GetKey();
|
||||
MOZ_ASSERT(key);
|
||||
|
||||
nsCOMPtr<nsIWeakReference> weakRef = do_QueryInterface(key);
|
||||
MOZ_ASSERT(weakRef);
|
||||
|
||||
nsCOMPtr<nsISupports> referent = do_QueryReferent(weakRef);
|
||||
if (!referent) {
|
||||
iter.Remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -77,8 +77,6 @@ class IDBDatabase final
|
|||
nsDataHashtable<nsISupportsHashKey, indexedDB::PBackgroundIDBDatabaseFileChild*>
|
||||
mFileActors;
|
||||
|
||||
nsTHashtable<nsISupportsHashKey> mReceivedBlobs;
|
||||
|
||||
RefPtr<Observer> mObserver;
|
||||
|
||||
// Weak refs, IDBMutableFile strongly owns this IDBDatabase object.
|
||||
|
@ -197,9 +195,6 @@ public:
|
|||
void
|
||||
NoteFinishedFileActor(indexedDB::PBackgroundIDBDatabaseFileChild* aFileActor);
|
||||
|
||||
void
|
||||
NoteReceivedBlob(Blob* aBlob);
|
||||
|
||||
void
|
||||
DelayedMaybeExpireFileActors();
|
||||
|
||||
|
|
|
@ -39,8 +39,6 @@
|
|||
#include "mozilla/dom/StructuredCloneTags.h"
|
||||
#include "mozilla/dom/indexedDB/PBackgroundIDBSharedTypes.h"
|
||||
#include "mozilla/dom/ipc/BlobChild.h"
|
||||
#include "mozilla/dom/ipc/BlobParent.h"
|
||||
#include "mozilla/dom/ipc/nsIRemoteBlob.h"
|
||||
#include "mozilla/ipc/BackgroundChild.h"
|
||||
#include "mozilla/ipc/PBackgroundSharedTypes.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
@ -429,32 +427,6 @@ GetAddInfoCallback(JSContext* aCx, void* aClosure)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
BlobChild*
|
||||
ActorFromRemoteBlobImpl(BlobImpl* aImpl)
|
||||
{
|
||||
MOZ_ASSERT(aImpl);
|
||||
|
||||
nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryInterface(aImpl);
|
||||
if (remoteBlob) {
|
||||
BlobChild* actor = remoteBlob->GetBlobChild();
|
||||
MOZ_ASSERT(actor);
|
||||
|
||||
if (actor->GetContentManager()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(actor->GetBackgroundManager());
|
||||
MOZ_ASSERT(BackgroundChild::GetForCurrentThread());
|
||||
MOZ_ASSERT(actor->GetBackgroundManager() ==
|
||||
BackgroundChild::GetForCurrentThread(),
|
||||
"Blob actor is not bound to this thread!");
|
||||
|
||||
return actor;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
ResolveMysteryMutableFile(IDBMutableFile* aMutableFile,
|
||||
const nsString& aName,
|
||||
|
@ -465,33 +437,6 @@ ResolveMysteryMutableFile(IDBMutableFile* aMutableFile,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ResolveMysteryFile(BlobImpl* aImpl,
|
||||
const nsString& aName,
|
||||
const nsString& aContentType,
|
||||
uint64_t aSize,
|
||||
uint64_t aLastModifiedDate)
|
||||
{
|
||||
BlobChild* actor = ActorFromRemoteBlobImpl(aImpl);
|
||||
if (actor) {
|
||||
return actor->SetMysteryBlobInfo(aName, aContentType,
|
||||
aSize, aLastModifiedDate);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ResolveMysteryBlob(BlobImpl* aImpl,
|
||||
const nsString& aContentType,
|
||||
uint64_t aSize)
|
||||
{
|
||||
BlobChild* actor = ActorFromRemoteBlobImpl(aImpl);
|
||||
if (actor) {
|
||||
return actor->SetMysteryBlobInfo(aContentType, aSize);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
StructuredCloneReadString(JSStructuredCloneReader* aReader,
|
||||
nsCString& aString)
|
||||
|
@ -690,16 +635,22 @@ public:
|
|||
MOZ_ASSERT(parent);
|
||||
|
||||
if (aData.tag == SCTAG_DOM_BLOB) {
|
||||
if (NS_WARN_IF(!ResolveMysteryBlob(aFile.mBlob->Impl(),
|
||||
aData.type,
|
||||
aData.size))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aFile.mBlob->Impl()->SetLazyData(
|
||||
NullString(), aData.type, aData.size, INT64_MAX);
|
||||
MOZ_ASSERT(!aFile.mBlob->IsFile());
|
||||
|
||||
// ActorsParent sends here a kind of half blob and half file wrapped into
|
||||
// a DOM File object. DOM File and DOM Blob are a WebIDL wrapper around a
|
||||
// BlobImpl object. SetLazyData() has just changed the BlobImpl to be a
|
||||
// Blob (see the previous assert), but 'aFile.mBlob' still has the WebIDL
|
||||
// DOM File wrapping.
|
||||
// Before exposing it to content, we must recreate a DOM Blob object.
|
||||
|
||||
RefPtr<Blob> blob =
|
||||
Blob::Create(aFile.mBlob->GetParentObject(), aFile.mBlob->Impl());
|
||||
MOZ_ASSERT(blob);
|
||||
JS::Rooted<JS::Value> wrappedBlob(aCx);
|
||||
if (!ToJSValue(aCx, aFile.mBlob, &wrappedBlob)) {
|
||||
if (!ToJSValue(aCx, blob, &wrappedBlob)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -707,13 +658,9 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!ResolveMysteryFile(aFile.mBlob->Impl(),
|
||||
aData.name,
|
||||
aData.type,
|
||||
aData.size,
|
||||
aData.lastModifiedDate))) {
|
||||
return false;
|
||||
}
|
||||
aFile.mBlob->Impl()->SetLazyData(
|
||||
aData.name, aData.type, aData.size,
|
||||
aData.lastModifiedDate * PR_USEC_PER_MSEC);
|
||||
|
||||
MOZ_ASSERT(aFile.mBlob->IsFile());
|
||||
RefPtr<File> file = aFile.mBlob->ToFile();
|
||||
|
|
|
@ -5,7 +5,10 @@
|
|||
include protocol PBackgroundIDBTransaction;
|
||||
include protocol PBackgroundIDBVersionChangeTransaction;
|
||||
include protocol PBackgroundMutableFile;
|
||||
include protocol PBlob;
|
||||
include protocol PChildToParentStream; // FIXME: bug 792908
|
||||
include protocol PFileDescriptorSet; // FIXME: bug 792908
|
||||
include protocol PIPCBlobInputStream; // FIXME: bug 792908
|
||||
include protocol PParentToChildStream; // FIXME: bug 792908
|
||||
|
||||
include PBackgroundIDBSharedTypes;
|
||||
|
||||
|
|
|
@ -8,8 +8,12 @@ include protocol PBackgroundIDBFactory;
|
|||
include protocol PBackgroundIDBTransaction;
|
||||
include protocol PBackgroundIDBVersionChangeTransaction;
|
||||
include protocol PBackgroundMutableFile;
|
||||
include protocol PBlob;
|
||||
include protocol PChildToParentStream; // FIXME: bug 792908
|
||||
include protocol PFileDescriptorSet; // FIXME: bug 792908
|
||||
include protocol PIPCBlobInputStream; // FIXME: bug 792908
|
||||
include protocol PParentToChildStream; // FIXME: bug 792908
|
||||
|
||||
include IPCBlob;
|
||||
include InputStreamParams;
|
||||
include PBackgroundIDBSharedTypes;
|
||||
|
||||
|
@ -59,7 +63,7 @@ parent:
|
|||
|
||||
async Close();
|
||||
|
||||
async PBackgroundIDBDatabaseFile(PBlob blob);
|
||||
async PBackgroundIDBDatabaseFile(IPCBlob blob);
|
||||
|
||||
async PBackgroundIDBDatabaseRequest(DatabaseRequestParams params);
|
||||
|
||||
|
|
|
@ -5,7 +5,10 @@
|
|||
include protocol PBackgroundIDBTransaction;
|
||||
include protocol PBackgroundIDBVersionChangeTransaction;
|
||||
include protocol PBackgroundMutableFile;
|
||||
include protocol PBlob;
|
||||
include protocol PChildToParentStream; // FIXME: bug 792908
|
||||
include protocol PFileDescriptorSet; // FIXME: bug 792908
|
||||
include protocol PIPCBlobInputStream; // FIXME: bug 792908
|
||||
include protocol PParentToChildStream; // FIXME: bug 792908
|
||||
|
||||
include PBackgroundIDBSharedTypes;
|
||||
|
||||
|
|
|
@ -4,9 +4,13 @@
|
|||
|
||||
include protocol PBackgroundIDBDatabaseFile;
|
||||
include protocol PBackgroundMutableFile;
|
||||
include protocol PBlob;
|
||||
include protocol PChildToParentStream; // FIXME: bug 792908
|
||||
include protocol PFileDescriptorSet; // FIXME: bug 792908
|
||||
include protocol PIPCBlobInputStream; // FIXME: bug 792908
|
||||
include protocol PParentToChildStream; // FIXME: bug 792908
|
||||
|
||||
include DOMTypes;
|
||||
include IPCBlob;
|
||||
include ProtocolTypes;
|
||||
|
||||
include "mozilla/dom/indexedDB/SerializationHelpers.h";
|
||||
|
@ -52,7 +56,7 @@ struct SerializedKeyRange
|
|||
union BlobOrMutableFile
|
||||
{
|
||||
null_t;
|
||||
PBlob;
|
||||
IPCBlob;
|
||||
PBackgroundMutableFile;
|
||||
};
|
||||
|
||||
|
|
|
@ -7,7 +7,10 @@ include protocol PBackgroundIDBDatabase;
|
|||
include protocol PBackgroundIDBDatabaseFile;
|
||||
include protocol PBackgroundIDBRequest;
|
||||
include protocol PBackgroundMutableFile;
|
||||
include protocol PBlob;
|
||||
include protocol PChildToParentStream; // FIXME: bug 792908
|
||||
include protocol PFileDescriptorSet; // FIXME: bug 792908
|
||||
include protocol PIPCBlobInputStream; // FIXME: bug 792908
|
||||
include protocol PParentToChildStream; // FIXME: bug 792908
|
||||
|
||||
include PBackgroundIDBSharedTypes;
|
||||
|
||||
|
|
|
@ -286,6 +286,7 @@ using namespace mozilla::jsipc;
|
|||
using namespace mozilla::psm;
|
||||
using namespace mozilla::widget;
|
||||
using mozilla::loader::PScriptCacheParent;
|
||||
using mozilla::Telemetry::ProcessID;
|
||||
|
||||
// XXX Workaround for bug 986973 to maintain the existing broken semantics
|
||||
template<>
|
||||
|
@ -533,6 +534,16 @@ ScriptableCPInfo::GetMessageManager(nsIMessageSender** aMessenger)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
ProcessID
|
||||
GetTelemetryProcessID(const nsAString& remoteType)
|
||||
{
|
||||
// OOP WebExtensions run in a content process.
|
||||
// For Telemetry though we want to break out collected data from the WebExtensions process into
|
||||
// a separate bucket, to make sure we can analyze it separately and avoid skewing normal content
|
||||
// process metrics.
|
||||
return remoteType.EqualsLiteral(EXTENSION_REMOTE_TYPE) ? ProcessID::Extension : ProcessID::Content;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
nsTArray<ContentParent*>* ContentParent::sPrivateContent;
|
||||
|
@ -5126,7 +5137,7 @@ mozilla::ipc::IPCResult
|
|||
ContentParent::RecvAccumulateChildHistograms(
|
||||
InfallibleTArray<Accumulation>&& aAccumulations)
|
||||
{
|
||||
TelemetryIPC::AccumulateChildHistograms(GeckoProcessType_Content, aAccumulations);
|
||||
TelemetryIPC::AccumulateChildHistograms(GetTelemetryProcessID(mRemoteType), aAccumulations);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
@ -5134,7 +5145,7 @@ mozilla::ipc::IPCResult
|
|||
ContentParent::RecvAccumulateChildKeyedHistograms(
|
||||
InfallibleTArray<KeyedAccumulation>&& aAccumulations)
|
||||
{
|
||||
TelemetryIPC::AccumulateChildKeyedHistograms(GeckoProcessType_Content, aAccumulations);
|
||||
TelemetryIPC::AccumulateChildKeyedHistograms(GetTelemetryProcessID(mRemoteType), aAccumulations);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
@ -5142,7 +5153,7 @@ mozilla::ipc::IPCResult
|
|||
ContentParent::RecvUpdateChildScalars(
|
||||
InfallibleTArray<ScalarAction>&& aScalarActions)
|
||||
{
|
||||
TelemetryIPC::UpdateChildScalars(GeckoProcessType_Content, aScalarActions);
|
||||
TelemetryIPC::UpdateChildScalars(GetTelemetryProcessID(mRemoteType), aScalarActions);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
@ -5150,14 +5161,14 @@ mozilla::ipc::IPCResult
|
|||
ContentParent::RecvUpdateChildKeyedScalars(
|
||||
InfallibleTArray<KeyedScalarAction>&& aScalarActions)
|
||||
{
|
||||
TelemetryIPC::UpdateChildKeyedScalars(GeckoProcessType_Content, aScalarActions);
|
||||
TelemetryIPC::UpdateChildKeyedScalars(GetTelemetryProcessID(mRemoteType), aScalarActions);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
ContentParent::RecvRecordChildEvents(nsTArray<mozilla::Telemetry::ChildEventData>&& aEvents)
|
||||
{
|
||||
TelemetryIPC::RecordChildEvents(GeckoProcessType_Content, aEvents);
|
||||
TelemetryIPC::RecordChildEvents(GetTelemetryProcessID(mRemoteType), aEvents);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
|
|
@ -206,7 +206,7 @@ const char* mozilla::dom::ContentPrefs::gInitPrefs[] = {
|
|||
"privacy.firstparty.isolate",
|
||||
"privacy.firstparty.isolate.restrict_opener_access",
|
||||
"privacy.resistFingerprinting",
|
||||
"security.data_uri.inherit_security_context",
|
||||
"security.data_uri.unique_opaque_origin",
|
||||
"security.fileuri.strict_origin_policy",
|
||||
"security.sandbox.content.level",
|
||||
"security.sandbox.content.tempDirSuffix",
|
||||
|
|
|
@ -3,11 +3,10 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PBackground;
|
||||
include protocol PChildToParentStream;
|
||||
include protocol PFileDescriptorSet;
|
||||
include protocol PIPCBlobInputStream;
|
||||
include protocol PParentToChildStream;
|
||||
include protocol PBlob;
|
||||
include protocol PChildToParentStream; // FIXME: bug 792908
|
||||
include protocol PFileDescriptorSet; // FIXME: bug 792908
|
||||
include protocol PIPCBlobInputStream; // FIXME: bug 792908
|
||||
include protocol PParentToChildStream; // FIXME: bug 792908
|
||||
|
||||
include DOMTypes;
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
include protocol PNecko;
|
||||
include protocol PBackground;
|
||||
include protocol PBlob; //FIXME: bug #792908
|
||||
include protocol PFileDescriptorSet; // FIXME: bug #792908
|
||||
include protocol PChildToParentStream; //FIXME: bug #792908
|
||||
include protocol PParentToChildStream; //FIXME: bug #792908
|
||||
|
|
|
@ -14,10 +14,6 @@
|
|||
#include "mozilla/Telemetry.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#endif
|
||||
|
||||
using std::vector;
|
||||
using std::string;
|
||||
|
||||
|
@ -56,82 +52,12 @@ PluginProcessParent::~PluginProcessParent()
|
|||
#endif
|
||||
}
|
||||
|
||||
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
|
||||
static void
|
||||
AddSandboxAllowedFile(vector<std::wstring>& aAllowedFiles, nsIProperties* aDirSvc,
|
||||
const char* aDir, const nsAString& aSuffix = EmptyString())
|
||||
{
|
||||
nsCOMPtr<nsIFile> userDir;
|
||||
nsresult rv = aDirSvc->Get(aDir, NS_GET_IID(nsIFile), getter_AddRefs(userDir));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoString userDirPath;
|
||||
rv = userDir->GetPath(userDirPath);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!aSuffix.IsEmpty()) {
|
||||
userDirPath.Append(aSuffix);
|
||||
}
|
||||
aAllowedFiles.push_back(std::wstring(userDirPath.get()));
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
AddSandboxAllowedFiles(int32_t aSandboxLevel,
|
||||
vector<std::wstring>& aAllowedFilesRead,
|
||||
vector<std::wstring>& aAllowedFilesReadWrite,
|
||||
vector<std::wstring>& aAllowedDirectories)
|
||||
{
|
||||
if (aSandboxLevel < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIProperties> dirSvc =
|
||||
do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Level 2 and above is now using low integrity, so we need to give write
|
||||
// access to the Flash directories.
|
||||
// This should be made Flash specific (Bug 1171396).
|
||||
AddSandboxAllowedFile(aAllowedFilesReadWrite, dirSvc, NS_WIN_APPDATA_DIR,
|
||||
NS_LITERAL_STRING("\\Macromedia\\Flash Player\\*"));
|
||||
AddSandboxAllowedFile(aAllowedFilesReadWrite, dirSvc, NS_WIN_LOCAL_APPDATA_DIR,
|
||||
NS_LITERAL_STRING("\\Macromedia\\Flash Player\\*"));
|
||||
AddSandboxAllowedFile(aAllowedFilesReadWrite, dirSvc, NS_WIN_APPDATA_DIR,
|
||||
NS_LITERAL_STRING("\\Adobe\\Flash Player\\*"));
|
||||
|
||||
// Access also has to be given to create the parent directories as they may
|
||||
// not exist.
|
||||
AddSandboxAllowedFile(aAllowedDirectories, dirSvc, NS_WIN_APPDATA_DIR,
|
||||
NS_LITERAL_STRING("\\Macromedia"));
|
||||
AddSandboxAllowedFile(aAllowedDirectories, dirSvc, NS_WIN_APPDATA_DIR,
|
||||
NS_LITERAL_STRING("\\Macromedia\\Flash Player"));
|
||||
AddSandboxAllowedFile(aAllowedDirectories, dirSvc, NS_WIN_LOCAL_APPDATA_DIR,
|
||||
NS_LITERAL_STRING("\\Macromedia"));
|
||||
AddSandboxAllowedFile(aAllowedDirectories, dirSvc, NS_WIN_LOCAL_APPDATA_DIR,
|
||||
NS_LITERAL_STRING("\\Macromedia\\Flash Player"));
|
||||
AddSandboxAllowedFile(aAllowedDirectories, dirSvc, NS_WIN_APPDATA_DIR,
|
||||
NS_LITERAL_STRING("\\Adobe"));
|
||||
AddSandboxAllowedFile(aAllowedDirectories, dirSvc, NS_WIN_APPDATA_DIR,
|
||||
NS_LITERAL_STRING("\\Adobe\\Flash Player"));
|
||||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
PluginProcessParent::Launch(mozilla::UniquePtr<LaunchCompleteTask> aLaunchCompleteTask,
|
||||
int32_t aSandboxLevel)
|
||||
{
|
||||
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
|
||||
mSandboxLevel = aSandboxLevel;
|
||||
AddSandboxAllowedFiles(mSandboxLevel, mAllowedFilesRead,
|
||||
mAllowedFilesReadWrite, mAllowedDirectories);
|
||||
#else
|
||||
if (aSandboxLevel != 0) {
|
||||
MOZ_ASSERT(false,
|
||||
|
|
|
@ -45,11 +45,11 @@
|
|||
ok(false, "We should load non-CORS cross-domain stylesheets with incorrect hashes!");
|
||||
}
|
||||
|
||||
function bad_correctDataBlocked() {
|
||||
ok(false, "We should not block non-CORS cross-domain stylesheets in data: URI!");
|
||||
function good_correctDataBlocked() {
|
||||
ok(true, "We should block CORS cross-domain stylesheets in data: URI!");
|
||||
}
|
||||
function good_correctDataLoaded() {
|
||||
ok(true, "A non-CORS cross-domain stylesheet with data: URI was correctly loaded.");
|
||||
function bad_correctDataLoaded() {
|
||||
ok(false, "A CORS cross-domain stylesheet with data: URI was correctly loaded.");
|
||||
}
|
||||
function bad_correctDataCORSBlocked() {
|
||||
ok(false, "We should not block CORS stylesheets in data: URI!");
|
||||
|
@ -85,11 +85,18 @@
|
|||
onerror="good_incorrectHashBlocked()"
|
||||
onload="bad_incorrectHashLoaded()">
|
||||
|
||||
<!-- valid non-CORS sha256 hash in a data: URL -->
|
||||
<!-- valid CORS sha256 hash in a data: URL, but didn't specify crossorigin -->
|
||||
<link rel="stylesheet" href="data:text/css,.green-text{color:rgb(0, 255, 0)}"
|
||||
integrity="sha256-EhVtGGyovvffvYdhyqJxUJ/ekam7zlxxo46iM13cwP0="
|
||||
onerror="bad_correctDataBlocked()"
|
||||
onload="good_correctDataLoaded()">
|
||||
onerror="good_correctDataBlocked()"
|
||||
onload="bad_correctDataLoaded()">
|
||||
|
||||
<!-- valid CORS sha256 hash in a data: URL -->
|
||||
<link rel="stylesheet" href="data:text/css,.green-text{color:rgb(0, 255, 0)}"
|
||||
integrity="sha256-EhVtGGyovvffvYdhyqJxUJ/ekam7zlxxo46iM13cwP0="
|
||||
crossorigin="anonymous"
|
||||
onerror="bad_correctDataCORSBlocked()"
|
||||
onload="good_correctDataCORSLoaded()">
|
||||
|
||||
<!-- valid CORS sha256 hash in a data: URL -->
|
||||
<link rel="stylesheet" href="data:text/css,.blue-text{color:rgb(0, 0, 255)}"
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
<!DOCTYPE HTML>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<html>
|
||||
<head>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript">
|
||||
function check_styles() {
|
||||
var redText = document.getElementById('red-text');
|
||||
var greenText = document.getElementById('green-text');
|
||||
var blueText = document.getElementById('blue-text');
|
||||
var redTextColor = window.getComputedStyle(redText).getPropertyValue('color');
|
||||
var greenTextColor = window.getComputedStyle(greenText).getPropertyValue('color');
|
||||
var blueTextColor = window.getComputedStyle(blueText).getPropertyValue('color');
|
||||
ok(redTextColor == 'rgb(255, 0, 0)', "The first part should be red.");
|
||||
ok(greenTextColor == 'rgb(0, 255, 0)', "The second part should be green.");
|
||||
ok(blueTextColor == 'rgb(0, 0, 255)', "The third part should be blue.");
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
window.onload = function() {
|
||||
check_styles();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
function good_correctHashCORSLoaded() {
|
||||
ok(true, "A CORS cross-domain stylesheet with correct hash was correctly loaded.");
|
||||
}
|
||||
function bad_correctHashCORSBlocked() {
|
||||
ok(false, "We should load CORS cross-domain stylesheets with hashes that match!");
|
||||
}
|
||||
function good_correctHashBlocked() {
|
||||
ok(true, "A non-CORS cross-domain stylesheet with correct hash was correctly blocked.");
|
||||
}
|
||||
function bad_correctHashLoaded() {
|
||||
ok(false, "We should block non-CORS cross-domain stylesheets with hashes that match!");
|
||||
}
|
||||
|
||||
function good_incorrectHashBlocked() {
|
||||
ok(true, "A non-CORS cross-domain stylesheet with incorrect hash was correctly blocked.");
|
||||
}
|
||||
function bad_incorrectHashLoaded() {
|
||||
ok(false, "We should load non-CORS cross-domain stylesheets with incorrect hashes!");
|
||||
}
|
||||
|
||||
function bad_correctDataBlocked() {
|
||||
ok(false, "We should not block non-CORS cross-domain stylesheets in data: URI!");
|
||||
}
|
||||
function good_correctDataLoaded() {
|
||||
ok(true, "A non-CORS cross-domain stylesheet with data: URI was correctly loaded.");
|
||||
}
|
||||
function bad_correctDataCORSBlocked() {
|
||||
ok(false, "We should not block CORS stylesheets in data: URI!");
|
||||
}
|
||||
function good_correctDataCORSLoaded() {
|
||||
ok(true, "A CORS stylesheet with data: URI was correctly loaded.");
|
||||
}
|
||||
|
||||
function good_correctHashOpaqueBlocked() {
|
||||
ok(true, "A non-CORS(Opaque) cross-domain stylesheet with correct hash was correctly blocked.");
|
||||
}
|
||||
function bad_correctHashOpaqueLoaded() {
|
||||
ok(false, "We should not load non-CORS(Opaque) cross-domain stylesheets with correct hashes!");
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- valid CORS sha256 hash -->
|
||||
<link rel="stylesheet" href="http://example.com/tests/dom/security/test/sri/style1.css"
|
||||
crossorigin="anonymous"
|
||||
integrity="sha256-qs8lnkunWoVldk5d5E+652yth4VTSHohlBKQvvgGwa8="
|
||||
onerror="bad_correctHashCORSBlocked()"
|
||||
onload="good_correctHashCORSLoaded()">
|
||||
|
||||
<!-- valid non-CORS sha256 hash -->
|
||||
<link rel="stylesheet" href="style_301.css"
|
||||
integrity="sha256-qs8lnkunWoVldk5d5E+652yth4VTSHohlBKQvvgGwa8="
|
||||
onerror="good_correctHashBlocked()"
|
||||
onload="bad_correctHashLoaded()">
|
||||
|
||||
<!-- invalid non-CORS sha256 hash -->
|
||||
<link rel="stylesheet" href="style_301.css?again"
|
||||
integrity="sha256-bogus"
|
||||
onerror="good_incorrectHashBlocked()"
|
||||
onload="bad_incorrectHashLoaded()">
|
||||
|
||||
<!-- valid non-CORS sha256 hash in a data: URL -->
|
||||
<link rel="stylesheet" href="data:text/css,.green-text{color:rgb(0, 255, 0)}"
|
||||
integrity="sha256-EhVtGGyovvffvYdhyqJxUJ/ekam7zlxxo46iM13cwP0="
|
||||
onerror="bad_correctDataBlocked()"
|
||||
onload="good_correctDataLoaded()">
|
||||
|
||||
<!-- valid CORS sha256 hash in a data: URL -->
|
||||
<link rel="stylesheet" href="data:text/css,.blue-text{color:rgb(0, 0, 255)}"
|
||||
crossorigin="anonymous"
|
||||
integrity="sha256-m0Fs2hNSyPOn1030Dp+c8pJFHNmwpeTbB+8J/DcqLss="
|
||||
onerror="bad_correctDataCORSBlocked()"
|
||||
onload="good_correctDataCORSLoaded()">
|
||||
|
||||
<!-- valid non-CORS sha256 hash -->
|
||||
<link rel="stylesheet" href="http://example.com/tests/dom/security/test/sri/style1.css"
|
||||
integrity="sha256-qs8lnkunWoVldk5d5E+652yth4VTSHohlBKQvvgGwa8="
|
||||
onerror="good_correctHashOpaqueBlocked()"
|
||||
onload="bad_correctHashOpaqueLoaded()">
|
||||
</head>
|
||||
<body>
|
||||
<p><span id="red-text">This should be red</span> but
|
||||
<span id="green-text" class="green-text">this should be green</span> and
|
||||
<span id="blue-text" class="blue-text">this should be blue</span></p>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -10,6 +10,7 @@ support-files =
|
|||
iframe_script_sameorigin.html
|
||||
iframe_sri_disabled.html
|
||||
iframe_style_crossdomain.html
|
||||
iframe_style_crossdomain_legacy.html
|
||||
iframe_style_sameorigin.html
|
||||
rsf_csp_worker.js
|
||||
rsf_csp_worker.js^headers^
|
||||
|
@ -50,6 +51,7 @@ support-files =
|
|||
[test_script_crossdomain.html]
|
||||
[test_sri_disabled.html]
|
||||
[test_style_crossdomain.html]
|
||||
[test_style_crossdomain_legacy.html]
|
||||
[test_style_sameorigin.html]
|
||||
[test_require-sri-for_csp_directive.html]
|
||||
[test_require-sri-for_csp_directive_disabled.html]
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
<title>Cross-domain stylesheet tests for Bug 1196740</title>
|
||||
<script>
|
||||
SpecialPowers.setBoolPref("security.sri.enable", true);
|
||||
// TODO: Bug 1324406: Treat 'data:' documents as unique, opaque origins
|
||||
SpecialPowers.setBoolPref("security.data_uri.unique_opaque_origin", true);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE HTML>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Cross-domain stylesheet tests for Bug 1196740</title>
|
||||
<script>
|
||||
SpecialPowers.setBoolPref("security.sri.enable", true);
|
||||
// TODO: Bug 1324406: Treat 'data:' documents as unique, opaque origins
|
||||
SpecialPowers.setBoolPref("security.data_uri.unique_opaque_origin", false);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1196740">Mozilla Bug 1196740</a>
|
||||
<div>
|
||||
<iframe src="iframe_style_crossdomain_legacy.html" height="100%" width="90%" frameborder="0"></iframe>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -198,13 +198,14 @@ SVGRadialGradientElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenP
|
|||
return SVGRadialGradientElementBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
nsSVGElement::LengthInfo SVGRadialGradientElement::sLengthInfo[5] =
|
||||
nsSVGElement::LengthInfo SVGRadialGradientElement::sLengthInfo[6] =
|
||||
{
|
||||
{ &nsGkAtoms::cx, 50, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::X },
|
||||
{ &nsGkAtoms::cy, 50, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::Y },
|
||||
{ &nsGkAtoms::r, 50, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::XY },
|
||||
{ &nsGkAtoms::fx, 50, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::X },
|
||||
{ &nsGkAtoms::fy, 50, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::Y },
|
||||
{ &nsGkAtoms::fr, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::XY },
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -252,6 +253,12 @@ SVGRadialGradientElement::Fy()
|
|||
return mLengthAttributes[ATTR_FY].ToDOMAnimatedLength(this);
|
||||
}
|
||||
|
||||
already_AddRefed<SVGAnimatedLength>
|
||||
SVGRadialGradientElement::Fr()
|
||||
{
|
||||
return mLengthAttributes[ATTR_FR].ToDOMAnimatedLength(this);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsSVGElement methods
|
||||
|
||||
|
|
|
@ -142,13 +142,14 @@ public:
|
|||
already_AddRefed<SVGAnimatedLength> R();
|
||||
already_AddRefed<SVGAnimatedLength> Fx();
|
||||
already_AddRefed<SVGAnimatedLength> Fy();
|
||||
already_AddRefed<SVGAnimatedLength> Fr();
|
||||
protected:
|
||||
|
||||
virtual LengthAttributesInfo GetLengthInfo() override;
|
||||
|
||||
enum { ATTR_CX, ATTR_CY, ATTR_R, ATTR_FX, ATTR_FY };
|
||||
nsSVGLength2 mLengthAttributes[5];
|
||||
static LengthInfo sLengthInfo[5];
|
||||
enum { ATTR_CX, ATTR_CY, ATTR_R, ATTR_FX, ATTR_FY, ATTR_FR };
|
||||
nsSVGLength2 mLengthAttributes[6];
|
||||
static LengthInfo sLengthInfo[6];
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<script>var maintest = opener.opener; opener.location = 'data:text/html,test'; maintest.end(); window.close();</script>
|
|
@ -3,7 +3,7 @@
|
|||
<script>
|
||||
<!--
|
||||
function listener1() {
|
||||
window.showModalDialog("data:text/html,<script>var maintest = opener.opener; opener.location = 'data:text/html,test'; maintest.end(); window.close();</script>");
|
||||
window.showModalDialog("file2_bug291653.html");
|
||||
}
|
||||
|
||||
function listener2() {
|
||||
|
|
|
@ -11,6 +11,7 @@ support-files =
|
|||
devicemotion_inner.html
|
||||
devicemotion_outer.html
|
||||
file_bug291653.html
|
||||
file2_bug291653.html
|
||||
file_bug406375.html
|
||||
file_bug504862.html
|
||||
file2_bug504862.html
|
||||
|
|
|
@ -35,7 +35,7 @@ function start() {
|
|||
}
|
||||
|
||||
function closeTest() {
|
||||
w.setTimeout("close()", 0);
|
||||
w.close();
|
||||
setTimeout("finish()", 500);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
<html><style>
|
||||
* { outline: none; -moz-appearance: none; min-width:10px; min-height:10px; }
|
||||
#elem:focus { outline: 2px solid red; }
|
||||
#elem:-moz-focusring { outline: 1px solid blue; }
|
||||
</style><div id='container'></html>
|
|
@ -58,6 +58,7 @@ support-files =
|
|||
!/image/test/mochitest/over.png
|
||||
!/image/test/mochitest/red.png
|
||||
!/dom/base/test/file_empty.html
|
||||
file_focusrings.html
|
||||
|
||||
[test_497898.html]
|
||||
skip-if = toolkit == 'android'
|
||||
|
|
|
@ -168,7 +168,7 @@ SimpleTest.waitForFocus(runTest);
|
|||
<button id="b2" label="Button"/>
|
||||
<button id="b3" label="Button"/>
|
||||
|
||||
<iframe id="child" src="data:text/html,<html><style>* { outline: none; -moz-appearance: none; min-width:10px; min-height:10px; } %23elem:focus { outline: 2px solid red; } %23elem:-moz-focusring { outline: 1px solid blue; }</style><div id='container'></html>"/>
|
||||
<iframe id="child" src="file_focusrings.html"/>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml" style="height: 300px; overflow: auto;"/>
|
||||
|
||||
|
|
|
@ -21,5 +21,7 @@ interface SVGRadialGradientElement : SVGGradientElement {
|
|||
readonly attribute SVGAnimatedLength fx;
|
||||
[Constant]
|
||||
readonly attribute SVGAnimatedLength fy;
|
||||
// readonly attribute SVGAnimatedLength fr;
|
||||
// XXX: Bug 1242048
|
||||
// [SameObject]
|
||||
readonly attribute SVGAnimatedLength fr;
|
||||
};
|
||||
|
|
|
@ -222,9 +222,13 @@ FileReaderSync::ReadAsText(Blob& aBlob,
|
|||
return;
|
||||
}
|
||||
|
||||
aRv = multiplexStream->AppendStream(syncStream);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
// ConvertAsyncToSyncStream returns a null syncStream if the stream has been
|
||||
// already closed or there is nothing to read.
|
||||
if (syncStream) {
|
||||
aRv = multiplexStream->AppendStream(syncStream);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
aRv = ConvertStream(multiplexStream, encoding.get(), aResult);
|
||||
|
@ -262,6 +266,8 @@ FileReaderSync::ReadAsDataURL(Blob& aBlob, nsAString& aResult,
|
|||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(syncStream);
|
||||
|
||||
uint64_t size;
|
||||
aRv = syncStream->Available(&size);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
|
@ -476,6 +482,12 @@ FileReaderSync::ConvertAsyncToSyncStream(nsIInputStream* aAsyncStream,
|
|||
|
||||
uint64_t length;
|
||||
nsresult rv = aAsyncStream->Available(&length);
|
||||
if (rv == NS_BASE_STREAM_CLOSED) {
|
||||
// The stream has already been closed. Nothing to do.
|
||||
*aSyncStream = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
|