author | Carsten "Tomcat" Book <cbook@mozilla.com> |
Mon, 16 Feb 2015 15:59:56 +0100 | |
changeset 229281 | 09f4968d5f429e48e8d53a8a21408cb9674e996c |
parent 229108 | dfc80e670462bee5ab2b497e0055bd8fff6d7d3d (current diff) |
parent 229280 | c99e7a982123e33a55cce791f0fd92dd38d6bfb2 (diff) |
child 229282 | 29846628ba2b7072f707fcb6e5fff74ec6628b59 |
child 229295 | 81633bc6771b8b26a943c4ea9179ed8ff8bb8d35 |
child 229322 | 4fea2fc642e5c004c413febe4a087f5828e22a07 |
child 229352 | 12189d1c13af8dea7ebfe91391dee8b1186aeaca |
push id | 28282 |
push user | cbook@mozilla.com |
push date | Mon, 16 Feb 2015 15:06:35 +0000 |
treeherder | mozilla-central@09f4968d5f42 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | merge |
milestone | 38.0a1 |
first release with | nightly linux32
09f4968d5f42
/
38.0a1
/
20150217030213
/
files
nightly linux64
09f4968d5f42
/
38.0a1
/
20150217030213
/
files
nightly mac
09f4968d5f42
/
38.0a1
/
20150217030213
/
files
nightly win32
09f4968d5f42
/
38.0a1
/
20150217030213
/
files
nightly win64
09f4968d5f42
/
38.0a1
/
20150217030213
/
files
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly linux32
38.0a1
/
20150217030213
/
pushlog to previous
nightly linux64
38.0a1
/
20150217030213
/
pushlog to previous
nightly mac
38.0a1
/
20150217030213
/
pushlog to previous
nightly win32
38.0a1
/
20150217030213
/
pushlog to previous
nightly win64
38.0a1
/
20150217030213
/
pushlog to previous
|
--- a/accessible/base/nsAccessibilityService.cpp +++ b/accessible/base/nsAccessibilityService.cpp @@ -965,61 +965,60 @@ nsAccessibilityService::GetOrCreateAcces if (roleMapEntry && roleMapEntry->Is(nsGkAtoms::presentation)) { if (!MustBeAccessible(content, document)) return nullptr; roleMapEntry = nullptr; } if (!newAcc && isHTML) { // HTML accessibles - if (roleMapEntry) { - // Create pure ARIA grid/treegrid related accessibles if they weren't used - // on accessible HTML table elements. + bool isARIATableOrCell = roleMapEntry && + (roleMapEntry->accTypes & (eTableCell | eTable)); + + if (!isARIATableOrCell || + frame->AccessibleType() == eHTMLTableCellType || + frame->AccessibleType() == eHTMLTableType) { + // Prefer to use markup (mostly tag name, perhaps attributes) to decide if + // and what kind of accessible to create, + newAcc = CreateHTMLAccessibleByMarkup(frame, content, aContext); + if (!newAcc) // try by frame accessible type. + newAcc = CreateAccessibleByFrameType(frame, content, aContext); + } + + // In case of ARIA grids use grid-specific classes if it's not native table + // based. + if (isARIATableOrCell && (!newAcc || newAcc->IsGenericHyperText())) { if ((roleMapEntry->accTypes & eTableCell)) { - if (aContext->IsTableRow() && - (frame->AccessibleType() != eHTMLTableCellType || - aContext->GetContent() != content->GetParent())) { + if (aContext->IsTableRow()) newAcc = new ARIAGridCellAccessibleWrap(content, document); - } - } else if ((roleMapEntry->IsOfType(eTable)) && - frame->AccessibleType() != eHTMLTableType) { + } else if (roleMapEntry->IsOfType(eTable)) { newAcc = new ARIAGridAccessibleWrap(content, document); } } - if (!newAcc) { - // Prefer to use markup (mostly tag name, perhaps attributes) to decide if - // and what kind of accessible to create. - newAcc = CreateHTMLAccessibleByMarkup(frame, content, aContext); - - // Try using frame to do it. - if (!newAcc) - newAcc = CreateAccessibleByFrameType(frame, content, aContext); - - // If table has strong ARIA role then all table descendants shouldn't - // expose their native roles. - if (!roleMapEntry && newAcc && aContext->HasStrongARIARole()) { - if (frame->AccessibleType() == eHTMLTableRowType) { - nsRoleMapEntry* contextRoleMap = aContext->ARIARoleMap(); - if (!contextRoleMap->IsOfType(eTable)) - roleMapEntry = &aria::gEmptyRoleMap; - - } else if (frame->AccessibleType() == eHTMLTableCellType && - aContext->ARIARoleMap() == &aria::gEmptyRoleMap) { + // If table has strong ARIA role then all table descendants shouldn't + // expose their native roles. + if (!roleMapEntry && newAcc && aContext->HasStrongARIARole()) { + if (frame->AccessibleType() == eHTMLTableRowType) { + nsRoleMapEntry* contextRoleMap = aContext->ARIARoleMap(); + if (!contextRoleMap->IsOfType(eTable)) roleMapEntry = &aria::gEmptyRoleMap; - } else if (content->Tag() == nsGkAtoms::dt || - content->Tag() == nsGkAtoms::li || - content->Tag() == nsGkAtoms::dd || - frame->AccessibleType() == eHTMLLiType) { - nsRoleMapEntry* contextRoleMap = aContext->ARIARoleMap(); - if (!contextRoleMap->IsOfType(eList)) - roleMapEntry = &aria::gEmptyRoleMap; - } + } else if (frame->AccessibleType() == eHTMLTableCellType && + aContext->ARIARoleMap() == &aria::gEmptyRoleMap) { + roleMapEntry = &aria::gEmptyRoleMap; + + } else if (content->Tag() == nsGkAtoms::dt || + content->Tag() == nsGkAtoms::li || + content->Tag() == nsGkAtoms::dd || + frame->AccessibleType() == eHTMLLiType) { + nsRoleMapEntry* contextRoleMap = aContext->ARIARoleMap(); + if (!contextRoleMap->IsOfType(eList)) + roleMapEntry = &aria::gEmptyRoleMap; } } } // Accessible XBL types and deck stuff are used in XUL only currently. if (!newAcc && content->IsXUL()) { // No accessible for not selected deck panel and its children. if (!aContext->IsXULTabpanels()) {
--- a/accessible/generic/ARIAGridAccessible.cpp +++ b/accessible/generic/ARIAGridAccessible.cpp @@ -599,10 +599,17 @@ ARIAGridCellAccessible::NativeAttributes } int32_t rowIdx = RowIndexFor(thisRow); nsAutoString stringIdx; stringIdx.AppendInt(rowIdx * colCount + colIdx); nsAccUtils::SetAccAttr(attributes, nsGkAtoms::tableCellIndex, stringIdx); +#ifdef DEBUG + nsAutoString unused; + attributes->SetStringProperty(NS_LITERAL_CSTRING("cppclass"), + NS_LITERAL_STRING("ARIAGridCellAccessible"), + unused); +#endif + return attributes.forget(); }
--- a/accessible/generic/Accessible.h +++ b/accessible/generic/Accessible.h @@ -574,16 +574,17 @@ public: bool IsButton() const { return HasGenericType(eButton); } bool IsCombobox() const { return HasGenericType(eCombobox); } bool IsDoc() const { return HasGenericType(eDocument); } DocAccessible* AsDoc(); + bool IsGenericHyperText() const { return mType == eHyperTextType; } bool IsHyperText() const { return HasGenericType(eHyperText); } HyperTextAccessible* AsHyperText(); bool IsHTMLBr() const { return mType == eHTMLBRType; } bool IsHTMLCombobox() const { return mType == eHTMLComboboxType; } bool IsHTMLFileInput() const { return mType == eHTMLFileInputType; } bool IsHTMLListItem() const { return mType == eHTMLLiType; }
--- a/accessible/generic/HyperTextAccessible.cpp +++ b/accessible/generic/HyperTextAccessible.cpp @@ -45,16 +45,17 @@ using namespace mozilla::a11y; //////////////////////////////////////////////////////////////////////////////// // HyperTextAccessible //////////////////////////////////////////////////////////////////////////////// HyperTextAccessible:: HyperTextAccessible(nsIContent* aNode, DocAccessible* aDoc) : AccessibleWrap(aNode, aDoc) { + mType = eHyperTextType; mGenericTypes |= eHyperText; } NS_IMPL_ISUPPORTS_INHERITED0(HyperTextAccessible, Accessible) role HyperTextAccessible::NativeRole() {
--- a/accessible/html/HTMLTableAccessible.cpp +++ b/accessible/html/HTMLTableAccessible.cpp @@ -43,16 +43,17 @@ using namespace mozilla::a11y; //////////////////////////////////////////////////////////////////////////////// // HTMLTableCellAccessible //////////////////////////////////////////////////////////////////////////////// HTMLTableCellAccessible:: HTMLTableCellAccessible(nsIContent* aContent, DocAccessible* aDoc) : HyperTextAccessibleWrap(aContent, aDoc) { + mType = eHTMLTableCellType; mGenericTypes |= eTableCell; } NS_IMPL_ISUPPORTS_INHERITED0(HTMLTableCellAccessible, HyperTextAccessible) //////////////////////////////////////////////////////////////////////////////// // HTMLTableCellAccessible: Accessible implementation @@ -124,16 +125,23 @@ HTMLTableCellAccessible::NativeAttribute nsAccUtils::SetAccAttr(attributes, nsGkAtoms::abbr, abbrText); // axis attribute nsAutoString axisText; mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::axis, axisText); if (!axisText.IsEmpty()) nsAccUtils::SetAccAttr(attributes, nsGkAtoms::axis, axisText); +#ifdef DEBUG + nsAutoString unused; + attributes->SetStringProperty(NS_LITERAL_CSTRING("cppclass"), + NS_LITERAL_STRING("HTMLTableCellAccessible"), + unused); +#endif + return attributes.forget(); } //////////////////////////////////////////////////////////////////////////////// // HTMLTableCellAccessible: TableCellAccessible implementation TableAccessible* HTMLTableCellAccessible::Table() const
--- a/accessible/tests/mochitest/table/test_headers_ariagrid.html +++ b/accessible/tests/mochitest/table/test_headers_ariagrid.html @@ -57,31 +57,52 @@ testHeaderCells(headerInfoMap); ////////////////////////////////////////////////////////////////////////// // column and row headers from markup for crazy grid. headerInfoMap = [ { - // not focusable cell (nsARIAGridCellAccessible is used) + // not focusable cell (ARIAGridCellAccessible is used) cell: "table2_dc_1", rowHeaderCells: [], columnHeaderCells: [ "table2_ch_1" ] }, { - // focusable cell (nsARIAGridCellAccessible is used) + // focusable cell (ARIAGridCellAccessible is used) cell: "table2_dc_2", rowHeaderCells: [], columnHeaderCells: [ "table2_ch_2" ] } ]; testHeaderCells(headerInfoMap); + + ////////////////////////////////////////////////////////////////////////// + // column and row headers from markup for one more crazy grid. + + headerInfoMap = [ + { + // ARIAGridCellAccessible is used + cell: "t3_dc_1", + rowHeaderCells: [ "t3_rh_1" ], + columnHeaderCells: [ ] + }, + { + // ARIAGridCellAccessible is used (inside rowgroup) + cell: "t3_dc_2", + rowHeaderCells: [ "t3_rh_2" ], + columnHeaderCells: [ ] + } + ]; + + testHeaderCells(headerInfoMap); + SimpleTest.finish(); } SimpleTest.waitForExplicitFinish(); addA11yLoadEvent(doTest); </script> </head> @@ -130,10 +151,35 @@ <tr> <td id="table2_dc_1" role="gridcell">cell1</td> <td id="table2_dc_2" role="gridcell" tabindex="-1">cell2</td> </tr> </table> </div> </div> + <div role="grid"> + <table role="presentation"> + <tbody role="presentation"> + <tr role="row"> + <th id="t3_rh_1" role="rowheader">Row 1</th> + <td id="t3_dc_1" role="gridcell" tabindex="-1"> + Apple Inc. + </td> + </tr> + </tbody> + </table> + <div role="rowgroup" tabindex="0"> + <table role="presentation"> + <tbody role="presentation"> + <tr role="row"> + <th id="t3_rh_2" role="rowheader">Row 2</th> + <td id="t3_dc_2" role="gridcell" tabindex="-1"> + Apple-Shmapple Inc. + </td> + </tr> + </tbody> + </table> + </div> + </div> + </body> </html>
--- a/browser/app/jar.mn +++ b/browser/app/jar.mn @@ -1,4 +1,3 @@ browser.jar: - -# The file that holds the default permissions (which is loaded by nsPermissionManager) for the browser. - default_permissions (default_permissions) +% resource app % + defaults/permissions (permissions)
--- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -405,16 +405,19 @@ pref("browser.search.context.loadInBackg pref("browser.search.showOneOffButtons", true); // comma seperated list of of engines to hide in the search panel. pref("browser.search.hiddenOneOffs", ""); pref("browser.sessionhistory.max_entries", 50); +// Built-in default permissions. +pref("permissions.manager.defaultsUrl", "resource://app/defaults/permissions"); + // handle links targeting new windows // 1=current window/tab, 2=new window, 3=new tab in most recent window pref("browser.link.open_newwindow", 3); // handle external links (i.e. links opened from a different application) // default: use browser.link.open_newwindow // 1-3: see browser.link.open_newwindow for interpretation pref("browser.link.open_newwindow.override.external", -1);
--- a/browser/components/migration/FirefoxProfileMigrator.js +++ b/browser/components/migration/FirefoxProfileMigrator.js @@ -8,19 +8,22 @@ /* * Migrates from a Firefox profile in a lossy manner in order to clean up a * user's profile. Data is only migrated where the benefits outweigh the * potential problems caused by importing undesired/invalid configurations * from the source profile. */ -Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); -Components.utils.import("resource:///modules/MigrationUtils.jsm"); -Components.utils.import("resource://gre/modules/Services.jsm"); +const { classes: Cc, interfaces: Ci, utils: Cu } = Components; + +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +Cu.import("resource:///modules/MigrationUtils.jsm"); +Cu.import("resource://gre/modules/Services.jsm"); + XPCOMUtils.defineLazyModuleGetter(this, "PlacesBackups", "resource://gre/modules/PlacesBackups.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "SessionMigration", "resource:///modules/sessionstore/SessionMigration.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "FileUtils", "resource://gre/modules/FileUtils.jsm"); @@ -29,53 +32,75 @@ XPCOMUtils.defineLazyModuleGetter(this, function FirefoxProfileMigrator() { this.wrappedJSObject = this; // for testing... } FirefoxProfileMigrator.prototype = Object.create(MigratorPrototype); +FirefoxProfileMigrator.prototype._getAllProfiles = function () { + let allProfiles = new Map(); + let profiles = + Components.classes["@mozilla.org/toolkit/profile-service;1"] + .getService(Components.interfaces.nsIToolkitProfileService) + .profiles; + while (profiles.hasMoreElements()) { + let profile = profiles.getNext().QueryInterface(Ci.nsIToolkitProfile); + let rootDir = profile.rootDir; + + if (rootDir.exists() && rootDir.isReadable() && + !rootDir.equals(MigrationUtils.profileStartup.directory)) { + allProfiles.set(profile.name, rootDir); + } + } + return allProfiles; +}; + +function sorter(a, b) { + return a.id.toLocaleLowerCase().localeCompare(b.id.toLocaleLowerCase()); +} + +Object.defineProperty(FirefoxProfileMigrator.prototype, "sourceProfiles", { + get: function() { + return [{id: x, name: x} for (x of this._getAllProfiles().keys())].sort(sorter); + } +}); + FirefoxProfileMigrator.prototype._getFileObject = function(dir, fileName) { let file = dir.clone(); file.append(fileName); // File resources are monolithic. We don't make partial copies since // they are not expected to work alone. Return null to avoid trying to // copy non-existing files. return file.exists() ? file : null; -} +}; -FirefoxProfileMigrator.prototype.getResources = function() { - // Only allow migrating from the default (selected) profile since this will - // be the only one returned by the toolkit profile service after bug 214675. - let sourceProfile = +FirefoxProfileMigrator.prototype.getResources = function(aProfile) { + let sourceProfileDir = aProfile ? this._getAllProfiles().get(aProfile.id) : Components.classes["@mozilla.org/toolkit/profile-service;1"] .getService(Components.interfaces.nsIToolkitProfileService) - .selectedProfile; - if (!sourceProfile) - return null; - - let sourceProfileDir = sourceProfile.rootDir; + .selectedProfile.rootDir; if (!sourceProfileDir || !sourceProfileDir.exists() || !sourceProfileDir.isReadable()) return null; // Being a startup-only migrator, we can rely on // MigrationUtils.profileStartup being set. let currentProfileDir = MigrationUtils.profileStartup.directory; // Surely data cannot be imported from the current profile. if (sourceProfileDir.equals(currentProfileDir)) return null; - return this._getResourcesInternal(sourceProfileDir, currentProfileDir); -} + return this._getResourcesInternal(sourceProfileDir, currentProfileDir, aProfile); +}; -FirefoxProfileMigrator.prototype._getResourcesInternal = function(sourceProfileDir, currentProfileDir) { +FirefoxProfileMigrator.prototype._getResourcesInternal = function(sourceProfileDir, currentProfileDir, aProfile) { let getFileResource = function(aMigrationType, aFileNames) { let files = []; for (let fileName of aFileNames) { let file = this._getFileObject(sourceProfileDir, fileName); if (file) files.push(file); } if (!files.length) { @@ -102,17 +127,17 @@ FirefoxProfileMigrator.prototype._getRes let bookmarksBackups = getFileResource(types.OTHERDATA, [PlacesBackups.profileRelativeFolderPath]); let dictionary = getFileResource(types.OTHERDATA, ["persdict.dat"]); let sessionCheckpoints = this._getFileObject(sourceProfileDir, "sessionCheckpoints.json"); let sessionFile = this._getFileObject(sourceProfileDir, "sessionstore.js"); let session; if (sessionFile) { - session = { + session = aProfile ? getFileResource(types.SESSION, ["sessionstore.js"]) : { type: types.SESSION, migrate: function(aCallback) { sessionCheckpoints.copyTo(currentProfileDir, "sessionCheckpoints.json"); let newSessionFile = currentProfileDir.clone(); newSessionFile.append("sessionstore.js"); let migrationPromise = SessionMigration.migrate(sessionFile.path, newSessionFile.path); migrationPromise.then(function() { let buildID = Services.appinfo.platformBuildID; @@ -212,17 +237,17 @@ FirefoxProfileMigrator.prototype._getRes } aCallback(true); } } return [r for each (r in [places, cookies, passwords, formData, dictionary, bookmarksBackups, session, times, healthReporter]) if (r)]; -} +}; Object.defineProperty(FirefoxProfileMigrator.prototype, "startupOnlyMigrator", { get: function() true }); FirefoxProfileMigrator.prototype.classDescription = "Firefox Profile Migrator"; FirefoxProfileMigrator.prototype.contractID = "@mozilla.org/profile/migrator;1?app=browser&type=firefox";
--- a/browser/components/migration/MigrationUtils.jsm +++ b/browser/components/migration/MigrationUtils.jsm @@ -40,23 +40,20 @@ function getMigrationBundle() { /** * Figure out what is the default browser, and if there is a migrator * for it, return that migrator's internal name. * For the time being, the "internal name" of a migraotr is its contract-id * trailer (e.g. ie for @mozilla.org/profile/migrator;1?app=browser&type=ie), * but it will soon be exposed properly. */ function getMigratorKeyForDefaultBrowser() { - // Don't map Firefox to the Firefox migrator, because we don't - // expect it to ever show up as an option in the wizard. - // We may want to revise this if/when we use separate profiles - // for each Firefox-update channel. const APP_DESC_TO_KEY = { "Internet Explorer": "ie", "Safari": "safari", + "Firefox": "firefox", "Google Chrome": "chrome", // Windows, Linux "Chrome": "chrome", // OS X }; let browserDesc = ""; try { let browserDesc = Cc["@mozilla.org/uriloader/external-protocol-service;1"]. @@ -480,21 +477,21 @@ this.MigrationUtils = Object.freeze({ return migrator && migrator.sourceExists ? migrator : null; }, // Iterates the available migrators, in the most suitable // order for the running platform. get migrators() { let migratorKeysOrdered = [ #ifdef XP_WIN - "ie", "chrome", "safari" + "firefox", "ie", "chrome", "safari" #elifdef XP_MACOSX - "safari", "chrome" + "firefox", "safari", "chrome" #elifdef XP_UNIX - "chrome" + "firefox", "chrome" #endif ]; // If a supported default browser is found check it first // so that the wizard defaults to import from that browser. let defaultBrowserKey = getMigratorKeyForDefaultBrowser(); if (defaultBrowserKey) migratorKeysOrdered.sort(function (a, b) b == defaultBrowserKey ? 1 : 0);
--- a/browser/components/migration/content/migration.js +++ b/browser/components/migration/content/migration.js @@ -120,17 +120,20 @@ var MigrationWizard = { this._itemsFlags = kIMig.ALL; this._selectedProfile = null; } this._source = newSource; // check for more than one source profile var sourceProfiles = this._migrator.sourceProfiles; - if (sourceProfiles && sourceProfiles.length > 1) { + if (this._skipImportSourcePage) { + this._wiz.currentPage.next = "homePageImport"; + } + else if (sourceProfiles && sourceProfiles.length > 1) { this._wiz.currentPage.next = "selectProfile"; } else { if (this._autoMigrate) this._wiz.currentPage.next = "homePageImport"; else this._wiz.currentPage.next = "importItems";
--- a/browser/components/migration/content/migration.xul +++ b/browser/components/migration/content/migration.xul @@ -27,27 +27,27 @@ #ifdef XP_WIN <description id="importAll" control="importSourceGroup">&importFrom.label;</description> #else <description id="importAll" control="importSourceGroup">&importFromUnix.label;</description> #endif <description id="importBookmarks" control="importSourceGroup" hidden="true">&importFromBookmarks.label;</description> <radiogroup id="importSourceGroup" align="start"> + <radio id="firefox" label="&importFromFirefox.label;" accesskey="&importFromFirefox.accesskey;"/> #ifdef XP_WIN <radio id="ie" label="&importFromIE.label;" accesskey="&importFromIE.accesskey;"/> <radio id="chrome" label="&importFromChrome.label;" accesskey="&importFromChrome.accesskey;"/> <radio id="safari" label="&importFromSafari.label;" accesskey="&importFromSafari.accesskey;"/> #elifdef XP_MACOSX <radio id="safari" label="&importFromSafari.label;" accesskey="&importFromSafari.accesskey;"/> <radio id="chrome" label="&importFromChrome.label;" accesskey="&importFromChrome.accesskey;"/> #elifdef XP_UNIX <radio id="chrome" label="&importFromChrome.label;" accesskey="&importFromChrome.accesskey;"/> #endif - <radio id="firefox" label="&importFromFirefox.label;" accesskey="&importFromFirefox.accesskey;"/> <radio id="nothing" label="&importFromNothing.label;" accesskey="&importFromNothing.accesskey;" hidden="true"/> </radiogroup> <label id="noSources" hidden="true">&noMigrationSources.label;</label> </wizardpage> <wizardpage id="selectProfile" pageid="selectProfile" label="&selectProfile.title;" next="importItems" onpageshow="return MigrationWizard.onSelectProfilePageShow();"
--- a/configure.in +++ b/configure.in @@ -52,28 +52,31 @@ dnl ==================================== MOZJPEG=62 MOZPNG=10616 NSPR_VERSION=4 NSPR_MINVER=4.10.8 NSS_VERSION=3 dnl Set the minimum version of toolkit libs used by mozilla dnl ======================================================== -GLIB_VERSION=1.2.0 +GLIB_VERSION=2.22 +# 2_26 is the earliest version we can set GLIB_VERSION_MIN_REQUIRED. +# The macro won't be used when compiling with earlier versions anyway. +GLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_26 +GIO_VERSION=2.22 PERL_VERSION=5.006 CAIRO_VERSION=1.10 PANGO_VERSION=1.22.0 GTK2_VERSION=2.18.0 -GTK3_VERSION=3.0.0 +GTK3_VERSION=3.4.0 WINDRES_VERSION=2.14.90 W32API_VERSION=3.14 GNOMEVFS_VERSION=2.0 GNOMEUI_VERSION=2.2.0 GCONF_VERSION=1.2.1 -GIO_VERSION=2.20 STARTUP_NOTIFICATION_VERSION=0.8 DBUS_VERSION=0.60 SQLITE_VERSION=3.8.8.2 MSMANIFEST_TOOL= dnl Set various checks dnl ======================================================== @@ -4402,23 +4405,29 @@ fi if test "$COMPILE_ENVIRONMENT"; then if test "$MOZ_ENABLE_GTK3"; then PKG_CHECK_MODULES(MOZ_GTK3, gtk+-3.0 >= $GTK3_VERSION gtk+-unix-print-3.0 glib-2.0 gobject-2.0 atk-bridge-2.0 $GDK_PACKAGES) MOZ_GTK3_CFLAGS="-I${_topsrcdir}/widget/gtk/compat-gtk3 $MOZ_GTK3_CFLAGS" dnl Contrary to MOZ_GTK2_LIBS, MOZ_GTK3_LIBS needs to be literally added to TK_LIBS instead dnl of a make reference because of how TK_LIBS is mangled in toolkit/library/moz.build dnl for GTK+3 builds. TK_LIBS=$MOZ_GTK3_LIBS + GLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_32 + fi + if test "$MOZ_ENABLE_GTK2"; then + GLIB_VERSION_MAX_ALLOWED=$GLIB_VERSION_MIN_REQUIRED fi if test "$MOZ_ENABLE_GTK"; then if test "$MOZ_X11"; then GDK_PACKAGES=gdk-x11-2.0 fi - - PKG_CHECK_MODULES(MOZ_GTK2, gtk+-2.0 >= $GTK2_VERSION gtk+-unix-print-2.0 glib-2.0 gobject-2.0 $GDK_PACKAGES) + AC_DEFINE_UNQUOTED(GLIB_VERSION_MIN_REQUIRED,$GLIB_VERSION_MIN_REQUIRED) + AC_DEFINE_UNQUOTED(GLIB_VERSION_MAX_ALLOWED,$GLIB_VERSION_MAX_ALLOWED) + + PKG_CHECK_MODULES(MOZ_GTK2, gtk+-2.0 >= $GTK2_VERSION gtk+-unix-print-2.0 glib-2.0 >= $GLIB_VERSION gobject-2.0 $GDK_PACKAGES) MOZ_GTK2_CFLAGS="-I${_topsrcdir}/widget/gtk/compat $MOZ_GTK2_CFLAGS" fi fi # COMPILE_ENVIRONMENT AC_SUBST(MOZ_FS_LAYOUT) dnl ======================================================== @@ -5605,17 +5614,17 @@ fi MOZ_ARG_ENABLE_BOOL(alsa, [ --enable-alsa Enable Alsa support (default on Linux)], MOZ_ALSA=1, MOZ_ALSA=) if test -n "$MOZ_ALSA"; then PKG_CHECK_MODULES(MOZ_ALSA, alsa, , [echo "$MOZ_ALSA_PKG_ERRORS" - AC_MSG_ERROR([Need alsa for Ogg, Wave or WebM decoding on Linux. Disable with --disable-ogg --disable-wave --disable-webm. (On Ubuntu, you might try installing the package libasound2-dev.)])]) + AC_MSG_ERROR([Need alsa for audio output on Linux. (On Ubuntu, you might try installing the package libasound2-dev.)])]) fi AC_SUBST(MOZ_ALSA) dnl ======================================================== dnl = Disable PulseAudio dnl ========================================================
--- a/docshell/base/IHistory.h +++ b/docshell/base/IHistory.h @@ -1,146 +1,145 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=4 sw=4 et tw=80: - * This Source Code Form is subject to the terms of the Mozilla Public +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_IHistory_h_ #define mozilla_IHistory_h_ #include "nsISupports.h" class nsIURI; class nsString; namespace mozilla { - namespace dom { - class Link; - } +namespace dom { +class Link; +} // 0057c9d3-b98e-4933-bdc5-0275d06705e1 #define IHISTORY_IID \ {0x0057c9d3, 0xb98e, 0x4933, {0xbd, 0xc5, 0x02, 0x75, 0xd0, 0x67, 0x05, 0xe1}} class IHistory : public nsISupports { public: - NS_DECLARE_STATIC_IID_ACCESSOR(IHISTORY_IID) + NS_DECLARE_STATIC_IID_ACCESSOR(IHISTORY_IID) - /** - * Registers the Link for notifications about the visited-ness of aURI. - * Consumers should assume that the URI is unvisited after calling this, and - * they will be notified if that state (unvisited) changes by having - * SetLinkState called on themselves. This function is guaranteed to run to - * completion before aLink is notified. After the node is notified, it will - * be unregistered. - * - * @note SetLinkState must not call RegisterVisitedCallback or - * UnregisterVisitedCallback. - * - * @pre aURI must not be null. - * @pre aLink may be null only in the parent (chrome) process. - * - * @param aURI - * The URI to check. - * @param aLink - * The link to update whenever the history status changes. The - * implementation will only hold onto a raw pointer, so if this - * object should be destroyed, be sure to call - * UnregisterVistedCallback first. - */ - NS_IMETHOD RegisterVisitedCallback(nsIURI *aURI, dom::Link *aLink) = 0; + /** + * Registers the Link for notifications about the visited-ness of aURI. + * Consumers should assume that the URI is unvisited after calling this, and + * they will be notified if that state (unvisited) changes by having + * SetLinkState called on themselves. This function is guaranteed to run to + * completion before aLink is notified. After the node is notified, it will + * be unregistered. + * + * @note SetLinkState must not call RegisterVisitedCallback or + * UnregisterVisitedCallback. + * + * @pre aURI must not be null. + * @pre aLink may be null only in the parent (chrome) process. + * + * @param aURI + * The URI to check. + * @param aLink + * The link to update whenever the history status changes. The + * implementation will only hold onto a raw pointer, so if this + * object should be destroyed, be sure to call + * UnregisterVistedCallback first. + */ + NS_IMETHOD RegisterVisitedCallback(nsIURI* aURI, dom::Link* aLink) = 0; - /** - * Unregisters a previously registered Link object. This must be called - * before destroying the registered object. - * - * @pre aURI must not be null. - * @pre aLink must not be null. - * - * @param aURI - * The URI that aLink was registered for. - * @param aLink - * The link object to unregister for aURI. - */ - NS_IMETHOD UnregisterVisitedCallback(nsIURI *aURI, dom::Link *aLink) = 0; + /** + * Unregisters a previously registered Link object. This must be called + * before destroying the registered object. + * + * @pre aURI must not be null. + * @pre aLink must not be null. + * + * @param aURI + * The URI that aLink was registered for. + * @param aLink + * The link object to unregister for aURI. + */ + NS_IMETHOD UnregisterVisitedCallback(nsIURI* aURI, dom::Link* aLink) = 0; - enum VisitFlags { - /** - * Indicates whether the URI was loaded in a top-level window. - */ - TOP_LEVEL = 1 << 0, - /** - * Indicates whether the URI was loaded as part of a permanent redirect. - */ - REDIRECT_PERMANENT = 1 << 1, - /** - * Indicates whether the URI was loaded as part of a temporary redirect. - */ - REDIRECT_TEMPORARY = 1 << 2, - /** - * Indicates the URI is redirecting (Response code 3xx). - */ - REDIRECT_SOURCE = 1 << 3, - /** - * Indicates the URI caused an error that is unlikely fixable by a - * retry, like a not found or unfetchable page. - */ - UNRECOVERABLE_ERROR = 1 << 4 - }; - + enum VisitFlags + { + /** + * Indicates whether the URI was loaded in a top-level window. + */ + TOP_LEVEL = 1 << 0, + /** + * Indicates whether the URI was loaded as part of a permanent redirect. + */ + REDIRECT_PERMANENT = 1 << 1, + /** + * Indicates whether the URI was loaded as part of a temporary redirect. + */ + REDIRECT_TEMPORARY = 1 << 2, + /** + * Indicates the URI is redirecting (Response code 3xx). + */ + REDIRECT_SOURCE = 1 << 3, /** - * Adds a history visit for the URI. - * - * @pre aURI must not be null. - * - * @param aURI - * The URI of the page being visited. - * @param aLastVisitedURI - * The URI of the last visit in the chain. - * @param aFlags - * The VisitFlags describing this visit. + * Indicates the URI caused an error that is unlikely fixable by a + * retry, like a not found or unfetchable page. */ - NS_IMETHOD VisitURI( - nsIURI *aURI, - nsIURI *aLastVisitedURI, - uint32_t aFlags - ) = 0; + UNRECOVERABLE_ERROR = 1 << 4 + }; - /** - * Set the title of the URI. - * - * @pre aURI must not be null. - * - * @param aURI - * The URI to set the title for. - * @param aTitle - * The title string. - */ - NS_IMETHOD SetURITitle(nsIURI* aURI, const nsAString& aTitle) = 0; + /** + * Adds a history visit for the URI. + * + * @pre aURI must not be null. + * + * @param aURI + * The URI of the page being visited. + * @param aLastVisitedURI + * The URI of the last visit in the chain. + * @param aFlags + * The VisitFlags describing this visit. + */ + NS_IMETHOD VisitURI(nsIURI* aURI, + nsIURI* aLastVisitedURI, + uint32_t aFlags) = 0; - /** - * Notifies about the visited status of a given URI. - * - * @param aURI - * The URI to notify about. - */ - NS_IMETHOD NotifyVisited(nsIURI* aURI) = 0; + /** + * Set the title of the URI. + * + * @pre aURI must not be null. + * + * @param aURI + * The URI to set the title for. + * @param aTitle + * The title string. + */ + NS_IMETHOD SetURITitle(nsIURI* aURI, const nsAString& aTitle) = 0; + + /** + * Notifies about the visited status of a given URI. + * + * @param aURI + * The URI to notify about. + */ + NS_IMETHOD NotifyVisited(nsIURI* aURI) = 0; }; NS_DEFINE_STATIC_IID_ACCESSOR(IHistory, IHISTORY_IID) #define NS_DECL_IHISTORY \ - NS_IMETHOD RegisterVisitedCallback(nsIURI *aURI, \ - mozilla::dom::Link *aContent) MOZ_OVERRIDE; \ - NS_IMETHOD UnregisterVisitedCallback(nsIURI *aURI, \ - mozilla::dom::Link *aContent) MOZ_OVERRIDE; \ - NS_IMETHOD VisitURI(nsIURI *aURI, \ - nsIURI *aLastVisitedURI, \ - uint32_t aFlags) MOZ_OVERRIDE; \ - NS_IMETHOD SetURITitle(nsIURI* aURI, const nsAString& aTitle) MOZ_OVERRIDE; \ - NS_IMETHOD NotifyVisited(nsIURI* aURI) MOZ_OVERRIDE; + NS_IMETHOD RegisterVisitedCallback(nsIURI* aURI, \ + mozilla::dom::Link* aContent) MOZ_OVERRIDE; \ + NS_IMETHOD UnregisterVisitedCallback(nsIURI* aURI, \ + mozilla::dom::Link* aContent) MOZ_OVERRIDE; \ + NS_IMETHOD VisitURI(nsIURI* aURI, \ + nsIURI* aLastVisitedURI, \ + uint32_t aFlags) MOZ_OVERRIDE; \ + NS_IMETHOD SetURITitle(nsIURI* aURI, const nsAString& aTitle) MOZ_OVERRIDE; \ + NS_IMETHOD NotifyVisited(nsIURI* aURI) MOZ_OVERRIDE; } // namespace mozilla #endif // mozilla_IHistory_h_
--- a/docshell/base/LoadContext.cpp +++ b/docshell/base/LoadContext.cpp @@ -1,10 +1,10 @@ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set sw=2 ts=8 et tw=80 : */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/Assertions.h" #include "mozilla/LoadContext.h" namespace mozilla { @@ -154,17 +154,17 @@ LoadContext::GetAppId(uint32_t* aAppId) *aAppId = mAppId; return NS_OK; } //----------------------------------------------------------------------------- // LoadContext::nsIInterfaceRequestor //----------------------------------------------------------------------------- NS_IMETHODIMP -LoadContext::GetInterface(const nsIID &aIID, void **aResult) +LoadContext::GetInterface(const nsIID& aIID, void** aResult) { NS_ENSURE_ARG_POINTER(aResult); *aResult = nullptr; if (aIID.Equals(NS_GET_IID(nsILoadContext))) { *aResult = static_cast<nsILoadContext*>(this); NS_ADDREF_THIS(); return NS_OK;
--- a/docshell/base/LoadContext.h +++ b/docshell/base/LoadContext.h @@ -1,10 +1,10 @@ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set sw=2 ts=8 et tw=80 : */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef LoadContext_h #define LoadContext_h #include "SerializedLoadContext.h" @@ -26,18 +26,19 @@ namespace mozilla { * typically provided by nsDocShell. This is only used when the original * docshell is in a different process and we need to copy certain values from * it. * * Note: we also generate a new nsILoadContext using LoadContext(uint32_t aAppId) * to separate the safebrowsing cookie. */ -class LoadContext MOZ_FINAL : public nsILoadContext, - public nsIInterfaceRequestor +class LoadContext MOZ_FINAL + : public nsILoadContext + , public nsIInterfaceRequestor { public: NS_DECL_ISUPPORTS NS_DECL_NSILOADCONTEXT NS_DECL_NSIINTERFACEREQUESTOR // AppId/inBrowser arguments override those in SerializedLoadContext provided // by child process. @@ -107,24 +108,24 @@ public: // Constructor for creating a LoadContext with a given principal's appId and // browser flag. explicit LoadContext(nsIPrincipal* aPrincipal); private: ~LoadContext() {} - nsWeakPtr mTopFrameElement; - uint64_t mNestedFrameId; - uint32_t mAppId; - bool mIsContent; - bool mUsePrivateBrowsing; - bool mUseRemoteTabs; - bool mIsInBrowserElement; + nsWeakPtr mTopFrameElement; + uint64_t mNestedFrameId; + uint32_t mAppId; + bool mIsContent; + bool mUsePrivateBrowsing; + bool mUseRemoteTabs; + bool mIsInBrowserElement; #ifdef DEBUG - bool mIsNotNull; + bool mIsNotNull; #endif }; } // namespace mozilla #endif // LoadContext_h
--- a/docshell/base/LoadInfo.cpp +++ b/docshell/base/LoadInfo.cpp @@ -1,10 +1,10 @@ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set sw=2 ts=8 et tw=80 : */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/LoadInfo.h" #include "mozilla/Assertions.h" #include "nsIDocument.h" @@ -88,58 +88,59 @@ LoadInfo::GetTriggeringPrincipal(nsIPrin nsIPrincipal* LoadInfo::TriggeringPrincipal() { return mTriggeringPrincipal; } NS_IMETHODIMP -LoadInfo::GetLoadingDocument(nsIDOMDocument** outLoadingDocument) +LoadInfo::GetLoadingDocument(nsIDOMDocument** aResult) { nsCOMPtr<nsINode> node = do_QueryReferent(mLoadingContext); if (node) { nsCOMPtr<nsIDOMDocument> context = do_QueryInterface(node->OwnerDoc()); - context.forget(outLoadingDocument); + context.forget(aResult); } return NS_OK; } nsINode* LoadInfo::LoadingNode() { nsCOMPtr<nsINode> node = do_QueryReferent(mLoadingContext); return node; } NS_IMETHODIMP -LoadInfo::GetSecurityFlags(nsSecurityFlags* outSecurityFlags) +LoadInfo::GetSecurityFlags(nsSecurityFlags* aResult) { - *outSecurityFlags = mSecurityFlags; + *aResult = mSecurityFlags; return NS_OK; } NS_IMETHODIMP LoadInfo::GetForceInheritPrincipal(bool* aInheritPrincipal) { - *aInheritPrincipal = (mSecurityFlags & nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL); + *aInheritPrincipal = + (mSecurityFlags & nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL); return NS_OK; } NS_IMETHODIMP LoadInfo::GetLoadingSandboxed(bool* aLoadingSandboxed) { *aLoadingSandboxed = (mSecurityFlags & nsILoadInfo::SEC_SANDBOXED); return NS_OK; } NS_IMETHODIMP -LoadInfo::GetContentPolicyType(nsContentPolicyType* outContentPolicyType) +LoadInfo::GetContentPolicyType(nsContentPolicyType* aResult) { - *outContentPolicyType = mContentPolicyType; + *aResult = mContentPolicyType; return NS_OK; } NS_IMETHODIMP LoadInfo::GetBaseURI(nsIURI** aBaseURI) { *aBaseURI = mBaseURI; NS_IF_ADDREF(*aBaseURI); @@ -148,15 +149,15 @@ LoadInfo::GetBaseURI(nsIURI** aBaseURI) nsIURI* LoadInfo::BaseURI() { return mBaseURI; } NS_IMETHODIMP -LoadInfo::GetInnerWindowID(uint32_t* outInnerWindowID) +LoadInfo::GetInnerWindowID(uint32_t* aResult) { - *outInnerWindowID = mInnerWindowID; + *aResult = mInnerWindowID; return NS_OK; } } // namespace mozilla
--- a/docshell/base/LoadInfo.h +++ b/docshell/base/LoadInfo.h @@ -1,10 +1,10 @@ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set sw=2 ts=8 et tw=80 : */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_LoadInfo_h #define mozilla_LoadInfo_h #include "nsIContentPolicy.h" @@ -51,19 +51,19 @@ private: friend class net::HttpChannelParent; friend class net::FTPChannelParent; ~LoadInfo(); nsCOMPtr<nsIPrincipal> mLoadingPrincipal; nsCOMPtr<nsIPrincipal> mTriggeringPrincipal; - nsWeakPtr mLoadingContext; - nsSecurityFlags mSecurityFlags; - nsContentPolicyType mContentPolicyType; - nsCOMPtr<nsIURI> mBaseURI; - uint32_t mInnerWindowID; + nsWeakPtr mLoadingContext; + nsSecurityFlags mSecurityFlags; + nsContentPolicyType mContentPolicyType; + nsCOMPtr<nsIURI> mBaseURI; + uint32_t mInnerWindowID; }; } // namespace mozilla #endif // mozilla_LoadInfo_h
--- a/docshell/base/SerializedLoadContext.cpp +++ b/docshell/base/SerializedLoadContext.cpp @@ -1,10 +1,10 @@ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set sw=2 ts=8 et tw=80 : */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "SerializedLoadContext.h" #include "nsNetUtil.h" #include "nsIChannel.h" #include "nsIWebSocketChannel.h" @@ -29,17 +29,18 @@ SerializedLoadContext::SerializedLoadCon if (!loadContext) { // Attempt to retrieve the private bit from the channel if it has been // overriden. bool isPrivate = false; bool isOverriden = false; nsCOMPtr<nsIPrivateBrowsingChannel> pbChannel = do_QueryInterface(aChannel); if (pbChannel && - NS_SUCCEEDED(pbChannel->IsPrivateModeOverriden(&isPrivate, &isOverriden)) && + NS_SUCCEEDED(pbChannel->IsPrivateModeOverriden(&isPrivate, + &isOverriden)) && isOverriden) { mUsePrivateBrowsing = isPrivate; mIsPrivateBitValid = true; } } } SerializedLoadContext::SerializedLoadContext(nsIWebSocketChannel* aChannel)
--- a/docshell/base/SerializedLoadContext.h +++ b/docshell/base/SerializedLoadContext.h @@ -1,10 +1,10 @@ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set sw=2 ts=8 et tw=80 : */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef SerializedLoadContext_h #define SerializedLoadContext_h #include "base/basictypes.h" @@ -32,36 +32,29 @@ public: } explicit SerializedLoadContext(nsILoadContext* aLoadContext); explicit SerializedLoadContext(nsIChannel* aChannel); explicit SerializedLoadContext(nsIWebSocketChannel* aChannel); void Init(nsILoadContext* aLoadContext); - bool IsNotNull() const - { - return mIsNotNull; - } - - bool IsPrivateBitValid() const - { - return mIsPrivateBitValid; - } + bool IsNotNull() const { return mIsNotNull; } + bool IsPrivateBitValid() const { return mIsPrivateBitValid; } // used to indicate if child-side LoadContext * was null. - bool mIsNotNull; + bool mIsNotNull; // used to indicate if child-side mUsePrivateBrowsing flag is valid, even if // mIsNotNull is false, i.e., child LoadContext was null. - bool mIsPrivateBitValid; - bool mIsContent; - bool mUsePrivateBrowsing; - bool mUseRemoteTabs; - bool mIsInBrowserElement; - uint32_t mAppId; + bool mIsPrivateBitValid; + bool mIsContent; + bool mUsePrivateBrowsing; + bool mUseRemoteTabs; + bool mIsInBrowserElement; + uint32_t mAppId; }; // Function to serialize over IPDL template<> struct ParamTraits<SerializedLoadContext> { typedef SerializedLoadContext paramType;
--- a/docshell/base/TimelineMarker.cpp +++ b/docshell/base/TimelineMarker.cpp @@ -1,12 +1,11 @@ -/* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=2 sw=2 tw=80 et: - * - * This Source Code Form is subject to the terms of the Mozilla Public +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsDocShell.h" #include "TimelineMarker.h" TimelineMarker::TimelineMarker(nsDocShell* aDocShell, const char* aName, TracingMetadata aMetaData)
--- a/docshell/base/TimelineMarker.h +++ b/docshell/base/TimelineMarker.h @@ -1,12 +1,11 @@ -/* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=2 sw=2 tw=80 et: - * - * This Source Code Form is subject to the terms of the Mozilla Public +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef TimelineMarker_h__ #define TimelineMarker_h__ #include "nsString.h" #include "GeckoProfiler.h" @@ -29,80 +28,62 @@ public: TracingMetadata aMetaData, const nsAString& aCause); virtual ~TimelineMarker(); // Check whether two markers should be considered the same, // for the purpose of pairing start and end markers. Normally // this definition suffices. - virtual bool Equals(const TimelineMarker* other) + virtual bool Equals(const TimelineMarker* aOther) { - return strcmp(mName, other->mName) == 0; + return strcmp(mName, aOther->mName) == 0; } // Add details specific to this marker type to aMarker. The // standard elements have already been set. This method is // called on both the starting and ending markers of a pair. // Ordinarily the ending marker doesn't need to do anything // here. - virtual void AddDetails(mozilla::dom::ProfileTimelineMarker& aMarker) - { - } + virtual void AddDetails(mozilla::dom::ProfileTimelineMarker& aMarker) {} - virtual void AddLayerRectangles(mozilla::dom::Sequence<mozilla::dom::ProfileTimelineLayerRect>&) + virtual void AddLayerRectangles( + mozilla::dom::Sequence<mozilla::dom::ProfileTimelineLayerRect>&) { MOZ_ASSERT_UNREACHABLE("can only be called on layer markers"); } - const char* GetName() const - { - return mName; - } - - TracingMetadata GetMetaData() const - { - return mMetaData; - } - - DOMHighResTimeStamp GetTime() const - { - return mTime; - } - - const nsString& GetCause() const - { - return mCause; - } + const char* GetName() const { return mName; } + TracingMetadata GetMetaData() const { return mMetaData; } + DOMHighResTimeStamp GetTime() const { return mTime; } + const nsString& GetCause() const { return mCause; } JSObject* GetStack() { if (mStackTrace.initialized()) { return mStackTrace; } return nullptr; } protected: - void CaptureStack() { JSContext* ctx = nsContentUtils::GetCurrentJSContext(); if (ctx) { JS::RootedObject stack(ctx); if (JS::CaptureCurrentStack(ctx, &stack)) { mStackTrace.init(ctx, stack.get()); } else { JS_ClearPendingException(ctx); } } } private: - const char* mName; TracingMetadata mMetaData; DOMHighResTimeStamp mTime; nsString mCause; // While normally it is not a good idea to make a persistent root, // in this case changing nsDocShell to participate in cycle // collection was deemed too invasive, and the markers are only held
--- a/docshell/base/nsAboutRedirector.cpp +++ b/docshell/base/nsAboutRedirector.cpp @@ -1,170 +1,195 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim:set ts=4 sw=4 sts=4 et cindent: */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsAboutRedirector.h" #include "nsNetUtil.h" #include "nsAboutProtocolUtils.h" #include "mozilla/ArrayUtils.h" #include "nsDOMString.h" NS_IMPL_ISUPPORTS(nsAboutRedirector, nsIAboutModule) -struct RedirEntry { - const char* id; - const char* url; - uint32_t flags; +struct RedirEntry +{ + const char* id; + const char* url; + uint32_t flags; }; /* Entries which do not have URI_SAFE_FOR_UNTRUSTED_CONTENT will run with chrome privileges. This is potentially dangerous. Please use URI_SAFE_FOR_UNTRUSTED_CONTENT in the third argument to each map item below unless your about: page really needs chrome privileges. Security review is required before adding new map entries without URI_SAFE_FOR_UNTRUSTED_CONTENT. Also note, however, that adding URI_SAFE_FOR_UNTRUSTED_CONTENT will allow random web sites to link to that URI. Perhaps we should separate the two concepts out... */ static RedirEntry kRedirMap[] = { - { "", "chrome://global/content/about.xhtml", - nsIAboutModule::ALLOW_SCRIPT }, - { "about", "chrome://global/content/aboutAbout.xhtml", 0 }, - { "credits", "http://www.mozilla.org/credits/", - nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT }, - { "mozilla", "chrome://global/content/mozilla.xhtml", - nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT }, - { "plugins", "chrome://global/content/plugins.html", 0 }, - { "config", "chrome://global/content/config.xul", 0 }, + { + "", "chrome://global/content/about.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, + { "about", "chrome://global/content/aboutAbout.xhtml", 0 }, + { + "credits", "http://www.mozilla.org/credits/", + nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT + }, + { + "mozilla", "chrome://global/content/mozilla.xhtml", + nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT + }, + { "plugins", "chrome://global/content/plugins.html", 0 }, + { "config", "chrome://global/content/config.xul", 0 }, #ifdef MOZ_CRASHREPORTER - { "crashes", "chrome://global/content/crashes.xhtml", 0 }, + { "crashes", "chrome://global/content/crashes.xhtml", 0 }, #endif - { "logo", "chrome://branding/content/about.png", - nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT}, - { "buildconfig", "chrome://global/content/buildconfig.html", - nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT }, - { "license", "chrome://global/content/license.html", - nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT }, - { "neterror", "chrome://global/content/netError.xhtml", - nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | + { + "logo", "chrome://branding/content/about.png", + nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT + }, + { + "buildconfig", "chrome://global/content/buildconfig.html", + nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT + }, + { + "license", "chrome://global/content/license.html", + nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT + }, + { + "neterror", "chrome://global/content/netError.xhtml", + nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | nsIAboutModule::URI_CAN_LOAD_IN_CHILD | nsIAboutModule::ALLOW_SCRIPT | - nsIAboutModule::HIDE_FROM_ABOUTABOUT }, - { "memory", "chrome://global/content/aboutMemory.xhtml", - nsIAboutModule::ALLOW_SCRIPT }, - { "compartments", "chrome://global/content/aboutCompartments.xhtml", - nsIAboutModule::ALLOW_SCRIPT }, - { "addons", "chrome://mozapps/content/extensions/extensions.xul", - nsIAboutModule::ALLOW_SCRIPT }, - { "newaddon", "chrome://mozapps/content/extensions/newaddon.xul", - nsIAboutModule::ALLOW_SCRIPT | - nsIAboutModule::HIDE_FROM_ABOUTABOUT }, - { "support", "chrome://global/content/aboutSupport.xhtml", - nsIAboutModule::ALLOW_SCRIPT }, - { "telemetry", "chrome://global/content/aboutTelemetry.xhtml", - nsIAboutModule::ALLOW_SCRIPT }, - { "networking", "chrome://global/content/aboutNetworking.xhtml", - nsIAboutModule::ALLOW_SCRIPT }, - { "webrtc", "chrome://global/content/aboutwebrtc/aboutWebrtc.xhtml", - nsIAboutModule::ALLOW_SCRIPT }, - // about:srcdoc is unresolvable by specification. It is included here - // because the security manager would disallow srcdoc iframes otherwise. - { "srcdoc", "about:blank", - nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | - nsIAboutModule::HIDE_FROM_ABOUTABOUT } + nsIAboutModule::HIDE_FROM_ABOUTABOUT + }, + { + "memory", "chrome://global/content/aboutMemory.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "compartments", "chrome://global/content/aboutCompartments.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "addons", "chrome://mozapps/content/extensions/extensions.xul", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "newaddon", "chrome://mozapps/content/extensions/newaddon.xul", + nsIAboutModule::ALLOW_SCRIPT | + nsIAboutModule::HIDE_FROM_ABOUTABOUT + }, + { + "support", "chrome://global/content/aboutSupport.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "telemetry", "chrome://global/content/aboutTelemetry.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "networking", "chrome://global/content/aboutNetworking.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, + { + "webrtc", "chrome://global/content/aboutwebrtc/aboutWebrtc.xhtml", + nsIAboutModule::ALLOW_SCRIPT + }, + // about:srcdoc is unresolvable by specification. It is included here + // because the security manager would disallow srcdoc iframes otherwise. + { + "srcdoc", "about:blank", + nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | + nsIAboutModule::HIDE_FROM_ABOUTABOUT + } }; static const int kRedirTotal = mozilla::ArrayLength(kRedirMap); NS_IMETHODIMP nsAboutRedirector::NewChannel(nsIURI* aURI, nsILoadInfo* aLoadInfo, - nsIChannel** result) + nsIChannel** aResult) { - NS_ENSURE_ARG_POINTER(aURI); - NS_ASSERTION(result, "must not be null"); + NS_ENSURE_ARG_POINTER(aURI); + NS_ASSERTION(aResult, "must not be null"); - nsAutoCString path; - nsresult rv = NS_GetAboutModuleName(aURI, path); - NS_ENSURE_SUCCESS(rv, rv); + nsAutoCString path; + nsresult rv = NS_GetAboutModuleName(aURI, path); + NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv); - NS_ENSURE_SUCCESS(rv, rv); - + nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv); + NS_ENSURE_SUCCESS(rv, rv); - for (int i=0; i<kRedirTotal; i++) - { - if (!strcmp(path.get(), kRedirMap[i].id)) - { - nsCOMPtr<nsIChannel> tempChannel; - nsCOMPtr<nsIURI> tempURI; - rv = NS_NewURI(getter_AddRefs(tempURI), kRedirMap[i].url); - NS_ENSURE_SUCCESS(rv, rv); - // Bug 1087720 (and Bug 1099296): - // Once all callsites have been updated to call NewChannel2() - // instead of NewChannel() we should have a non-null loadInfo - // consistently. Until then we have to branch on the loadInfo. - if (aLoadInfo) { - rv = NS_NewChannelInternal(getter_AddRefs(tempChannel), - tempURI, - aLoadInfo); - } - else { - rv = ioService->NewChannelFromURI(tempURI, - getter_AddRefs(tempChannel)); - } - if (NS_FAILED(rv)) - return rv; + for (int i = 0; i < kRedirTotal; i++) { + if (!strcmp(path.get(), kRedirMap[i].id)) { + nsCOMPtr<nsIChannel> tempChannel; + nsCOMPtr<nsIURI> tempURI; + rv = NS_NewURI(getter_AddRefs(tempURI), kRedirMap[i].url); + NS_ENSURE_SUCCESS(rv, rv); + // Bug 1087720 (and Bug 1099296): + // Once all callsites have been updated to call NewChannel2() + // instead of NewChannel() we should have a non-null loadInfo + // consistently. Until then we have to branch on the loadInfo. + if (aLoadInfo) { + rv = NS_NewChannelInternal(getter_AddRefs(tempChannel), + tempURI, + aLoadInfo); + } else { + rv = ioService->NewChannelFromURI(tempURI, getter_AddRefs(tempChannel)); + } + if (NS_FAILED(rv)) { + return rv; + } - tempChannel->SetOriginalURI(aURI); + tempChannel->SetOriginalURI(aURI); - NS_ADDREF(*result = tempChannel); - return rv; - } + NS_ADDREF(*aResult = tempChannel); + return rv; } + } - NS_ERROR("nsAboutRedirector called for unknown case"); - return NS_ERROR_ILLEGAL_VALUE; + NS_ERROR("nsAboutRedirector called for unknown case"); + return NS_ERROR_ILLEGAL_VALUE; } NS_IMETHODIMP -nsAboutRedirector::GetURIFlags(nsIURI *aURI, uint32_t *result) +nsAboutRedirector::GetURIFlags(nsIURI* aURI, uint32_t* aResult) { - NS_ENSURE_ARG_POINTER(aURI); + NS_ENSURE_ARG_POINTER(aURI); - nsAutoCString name; - nsresult rv = NS_GetAboutModuleName(aURI, name); - NS_ENSURE_SUCCESS(rv, rv); + nsAutoCString name; + nsresult rv = NS_GetAboutModuleName(aURI, name); + NS_ENSURE_SUCCESS(rv, rv); - for (int i=0; i < kRedirTotal; i++) - { - if (name.EqualsASCII(kRedirMap[i].id)) - { - *result = kRedirMap[i].flags; - return NS_OK; - } + for (int i = 0; i < kRedirTotal; i++) { + if (name.EqualsASCII(kRedirMap[i].id)) { + *aResult = kRedirMap[i].flags; + return NS_OK; } + } - NS_ERROR("nsAboutRedirector called for unknown case"); - return NS_ERROR_ILLEGAL_VALUE; + NS_ERROR("nsAboutRedirector called for unknown case"); + return NS_ERROR_ILLEGAL_VALUE; } NS_IMETHODIMP -nsAboutRedirector::GetIndexedDBOriginPostfix(nsIURI *aURI, nsAString &result) +nsAboutRedirector::GetIndexedDBOriginPostfix(nsIURI* aURI, nsAString& aResult) { - SetDOMStringToNull(result); - return NS_ERROR_NOT_IMPLEMENTED; + SetDOMStringToNull(aResult); + return NS_ERROR_NOT_IMPLEMENTED; } nsresult -nsAboutRedirector::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult) +nsAboutRedirector::Create(nsISupports* aOuter, REFNSIID aIID, void** aResult) { - nsAboutRedirector* about = new nsAboutRedirector(); - if (about == nullptr) - return NS_ERROR_OUT_OF_MEMORY; - NS_ADDREF(about); - nsresult rv = about->QueryInterface(aIID, aResult); - NS_RELEASE(about); - return rv; + nsAboutRedirector* about = new nsAboutRedirector(); + NS_ADDREF(about); + nsresult rv = about->QueryInterface(aIID, aResult); + NS_RELEASE(about); + return rv; }
--- a/docshell/base/nsAboutRedirector.h +++ b/docshell/base/nsAboutRedirector.h @@ -1,32 +1,32 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef nsAboutRedirector_h__ #define nsAboutRedirector_h__ #include "nsIAboutModule.h" class nsAboutRedirector : public nsIAboutModule { public: - NS_DECL_ISUPPORTS + NS_DECL_ISUPPORTS - NS_DECL_NSIABOUTMODULE + NS_DECL_NSIABOUTMODULE - nsAboutRedirector() {} + nsAboutRedirector() {} - static nsresult - Create(nsISupports *aOuter, REFNSIID aIID, void **aResult); + static nsresult Create(nsISupports* aOuter, REFNSIID aIID, void** aResult); protected: - virtual ~nsAboutRedirector() {} + virtual ~nsAboutRedirector() {} }; #define NS_ABOUT_REDIRECTOR_MODULE_CID \ { /* f0acde16-1dd1-11b2-9e35-f5786fff5a66*/ \ 0xf0acde16, \ 0x1dd1, \ 0x11b2, \ {0x9e, 0x35, 0xf5, 0x78, 0x6f, 0xff, 0x5a, 0x66} \
--- a/docshell/base/nsDSURIContentListener.cpp +++ b/docshell/base/nsDSURIContentListener.cpp @@ -1,9 +1,10 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsDocShell.h" #include "nsDSURIContentListener.h" #include "nsIChannel.h" #include "nsServiceManagerUtils.h" @@ -24,525 +25,531 @@ using namespace mozilla; //***************************************************************************** //*** nsDSURIContentListener: Object Management //***************************************************************************** nsDSURIContentListener::nsDSURIContentListener(nsDocShell* aDocShell) - : mDocShell(aDocShell) - , mExistingJPEGRequest(nullptr) - , mParentContentListener(nullptr) + : mDocShell(aDocShell) + , mExistingJPEGRequest(nullptr) + , mParentContentListener(nullptr) { } nsDSURIContentListener::~nsDSURIContentListener() { } nsresult -nsDSURIContentListener::Init() +nsDSURIContentListener::Init() { - nsresult rv; - mNavInfo = do_GetService(NS_WEBNAVIGATION_INFO_CONTRACTID, &rv); - NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to get webnav info"); - return rv; + nsresult rv; + mNavInfo = do_GetService(NS_WEBNAVIGATION_INFO_CONTRACTID, &rv); + NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to get webnav info"); + return rv; } - //***************************************************************************** // nsDSURIContentListener::nsISupports -//***************************************************************************** +//***************************************************************************** NS_IMPL_ADDREF(nsDSURIContentListener) NS_IMPL_RELEASE(nsDSURIContentListener) NS_INTERFACE_MAP_BEGIN(nsDSURIContentListener) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIURIContentListener) - NS_INTERFACE_MAP_ENTRY(nsIURIContentListener) - NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIURIContentListener) + NS_INTERFACE_MAP_ENTRY(nsIURIContentListener) + NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) NS_INTERFACE_MAP_END //***************************************************************************** // nsDSURIContentListener::nsIURIContentListener -//***************************************************************************** +//***************************************************************************** NS_IMETHODIMP nsDSURIContentListener::OnStartURIOpen(nsIURI* aURI, bool* aAbortOpen) { - // If mDocShell is null here, that means someone's starting a load - // in our docshell after it's already been destroyed. Don't let - // that happen. - if (!mDocShell) { - *aAbortOpen = true; - return NS_OK; - } - - nsCOMPtr<nsIURIContentListener> parentListener; - GetParentContentListener(getter_AddRefs(parentListener)); - if (parentListener) - return parentListener->OnStartURIOpen(aURI, aAbortOpen); + // If mDocShell is null here, that means someone's starting a load + // in our docshell after it's already been destroyed. Don't let + // that happen. + if (!mDocShell) { + *aAbortOpen = true; + return NS_OK; + } - return NS_OK; + nsCOMPtr<nsIURIContentListener> parentListener; + GetParentContentListener(getter_AddRefs(parentListener)); + if (parentListener) { + return parentListener->OnStartURIOpen(aURI, aAbortOpen); + } + + return NS_OK; } -NS_IMETHODIMP -nsDSURIContentListener::DoContent(const char* aContentType, +NS_IMETHODIMP +nsDSURIContentListener::DoContent(const char* aContentType, bool aIsContentPreferred, - nsIRequest* request, + nsIRequest* aRequest, nsIStreamListener** aContentHandler, bool* aAbortProcess) { - nsresult rv; - NS_ENSURE_ARG_POINTER(aContentHandler); - NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE); + nsresult rv; + NS_ENSURE_ARG_POINTER(aContentHandler); + NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE); - // Check whether X-Frame-Options permits us to load this content in an - // iframe and abort the load (unless we've disabled x-frame-options - // checking). - if (!CheckFrameOptions(request)) { - *aAbortProcess = true; - return NS_OK; - } + // Check whether X-Frame-Options permits us to load this content in an + // iframe and abort the load (unless we've disabled x-frame-options + // checking). + if (!CheckFrameOptions(aRequest)) { + *aAbortProcess = true; + return NS_OK; + } - *aAbortProcess = false; + *aAbortProcess = false; - // determine if the channel has just been retargeted to us... - nsLoadFlags loadFlags = 0; - nsCOMPtr<nsIChannel> aOpenedChannel = do_QueryInterface(request); + // determine if the channel has just been retargeted to us... + nsLoadFlags loadFlags = 0; + nsCOMPtr<nsIChannel> aOpenedChannel = do_QueryInterface(aRequest); - if (aOpenedChannel) - aOpenedChannel->GetLoadFlags(&loadFlags); + if (aOpenedChannel) { + aOpenedChannel->GetLoadFlags(&loadFlags); + } - if(loadFlags & nsIChannel::LOAD_RETARGETED_DOCUMENT_URI) - { - // XXX: Why does this not stop the content too? - mDocShell->Stop(nsIWebNavigation::STOP_NETWORK); + if (loadFlags & nsIChannel::LOAD_RETARGETED_DOCUMENT_URI) { + // XXX: Why does this not stop the content too? + mDocShell->Stop(nsIWebNavigation::STOP_NETWORK); - mDocShell->SetLoadType(aIsContentPreferred ? LOAD_LINK : LOAD_NORMAL); - } - - // In case of multipart jpeg request (mjpeg) we don't really want to - // create new viewer since the one we already have is capable of - // rendering multipart jpeg correctly (see bug 625012) - nsCOMPtr<nsIChannel> baseChannel; - if (nsCOMPtr<nsIMultiPartChannel> mpchan = do_QueryInterface(request)) { - mpchan->GetBaseChannel(getter_AddRefs(baseChannel)); - } + mDocShell->SetLoadType(aIsContentPreferred ? LOAD_LINK : LOAD_NORMAL); + } + + // In case of multipart jpeg request (mjpeg) we don't really want to + // create new viewer since the one we already have is capable of + // rendering multipart jpeg correctly (see bug 625012) + nsCOMPtr<nsIChannel> baseChannel; + if (nsCOMPtr<nsIMultiPartChannel> mpchan = do_QueryInterface(aRequest)) { + mpchan->GetBaseChannel(getter_AddRefs(baseChannel)); + } - bool reuseCV = baseChannel - && baseChannel == mExistingJPEGRequest - && nsDependentCString(aContentType).EqualsLiteral("image/jpeg"); + bool reuseCV = baseChannel && baseChannel == mExistingJPEGRequest && + nsDependentCString(aContentType).EqualsLiteral("image/jpeg"); - if (mExistingJPEGStreamListener && reuseCV) { - nsRefPtr<nsIStreamListener> copy(mExistingJPEGStreamListener); - copy.forget(aContentHandler); - rv = NS_OK; + if (mExistingJPEGStreamListener && reuseCV) { + nsRefPtr<nsIStreamListener> copy(mExistingJPEGStreamListener); + copy.forget(aContentHandler); + rv = NS_OK; + } else { + rv = mDocShell->CreateContentViewer(aContentType, aRequest, aContentHandler); + if (NS_SUCCEEDED(rv) && reuseCV) { + mExistingJPEGStreamListener = *aContentHandler; } else { - rv = mDocShell->CreateContentViewer(aContentType, request, aContentHandler); - if (NS_SUCCEEDED(rv) && reuseCV) { - mExistingJPEGStreamListener = *aContentHandler; - } else { - mExistingJPEGStreamListener = nullptr; - } - mExistingJPEGRequest = baseChannel; + mExistingJPEGStreamListener = nullptr; } - + mExistingJPEGRequest = baseChannel; + } - if (rv == NS_ERROR_REMOTE_XUL) { - request->Cancel(rv); - *aAbortProcess = true; - return NS_OK; - } + if (rv == NS_ERROR_REMOTE_XUL) { + aRequest->Cancel(rv); + *aAbortProcess = true; + return NS_OK; + } - if (NS_FAILED(rv)) { - // we don't know how to handle the content - *aContentHandler = nullptr; - return rv; - } + if (NS_FAILED(rv)) { + // we don't know how to handle the content + *aContentHandler = nullptr; + return rv; + } - if (loadFlags & nsIChannel::LOAD_RETARGETED_DOCUMENT_URI) { - nsCOMPtr<nsIDOMWindow> domWindow = mDocShell ? mDocShell->GetWindow() - : nullptr; - NS_ENSURE_TRUE(domWindow, NS_ERROR_FAILURE); - domWindow->Focus(); - } + if (loadFlags & nsIChannel::LOAD_RETARGETED_DOCUMENT_URI) { + nsCOMPtr<nsIDOMWindow> domWindow = + mDocShell ? mDocShell->GetWindow() : nullptr; + NS_ENSURE_TRUE(domWindow, NS_ERROR_FAILURE); + domWindow->Focus(); + } - return NS_OK; + return NS_OK; } NS_IMETHODIMP nsDSURIContentListener::IsPreferred(const char* aContentType, - char ** aDesiredContentType, + char** aDesiredContentType, bool* aCanHandle) { - NS_ENSURE_ARG_POINTER(aCanHandle); - NS_ENSURE_ARG_POINTER(aDesiredContentType); + NS_ENSURE_ARG_POINTER(aCanHandle); + NS_ENSURE_ARG_POINTER(aDesiredContentType); - // the docshell has no idea if it is the preferred content provider or not. - // It needs to ask its parent if it is the preferred content handler or not... + // the docshell has no idea if it is the preferred content provider or not. + // It needs to ask its parent if it is the preferred content handler or not... - nsCOMPtr<nsIURIContentListener> parentListener; - GetParentContentListener(getter_AddRefs(parentListener)); - if (parentListener) { - return parentListener->IsPreferred(aContentType, - aDesiredContentType, - aCanHandle); - } - // we used to return false here if we didn't have a parent properly - // registered at the top of the docshell hierarchy to dictate what - // content types this docshell should be a preferred handler for. But - // this really makes it hard for developers using iframe or browser tags - // because then they need to make sure they implement - // nsIURIContentListener otherwise all link clicks would get sent to - // another window because we said we weren't the preferred handler type. - // I'm going to change the default now...if we can handle the content, - // and someone didn't EXPLICITLY set a nsIURIContentListener at the top - // of our docshell chain, then we'll now always attempt to process the - // content ourselves... - return CanHandleContent(aContentType, - true, - aDesiredContentType, - aCanHandle); + nsCOMPtr<nsIURIContentListener> parentListener; + GetParentContentListener(getter_AddRefs(parentListener)); + if (parentListener) { + return parentListener->IsPreferred(aContentType, + aDesiredContentType, + aCanHandle); + } + // we used to return false here if we didn't have a parent properly + // registered at the top of the docshell hierarchy to dictate what + // content types this docshell should be a preferred handler for. But + // this really makes it hard for developers using iframe or browser tags + // because then they need to make sure they implement + // nsIURIContentListener otherwise all link clicks would get sent to + // another window because we said we weren't the preferred handler type. + // I'm going to change the default now...if we can handle the content, + // and someone didn't EXPLICITLY set a nsIURIContentListener at the top + // of our docshell chain, then we'll now always attempt to process the + // content ourselves... + return CanHandleContent(aContentType, true, aDesiredContentType, aCanHandle); } NS_IMETHODIMP nsDSURIContentListener::CanHandleContent(const char* aContentType, bool aIsContentPreferred, - char ** aDesiredContentType, + char** aDesiredContentType, bool* aCanHandleContent) { - NS_PRECONDITION(aCanHandleContent, "Null out param?"); - NS_ENSURE_ARG_POINTER(aDesiredContentType); + NS_PRECONDITION(aCanHandleContent, "Null out param?"); + NS_ENSURE_ARG_POINTER(aDesiredContentType); - *aCanHandleContent = false; - *aDesiredContentType = nullptr; + *aCanHandleContent = false; + *aDesiredContentType = nullptr; - nsresult rv = NS_OK; - if (aContentType) { - uint32_t canHandle = nsIWebNavigationInfo::UNSUPPORTED; - rv = mNavInfo->IsTypeSupported(nsDependentCString(aContentType), - mDocShell, - &canHandle); - *aCanHandleContent = (canHandle != nsIWebNavigationInfo::UNSUPPORTED); - } + nsresult rv = NS_OK; + if (aContentType) { + uint32_t canHandle = nsIWebNavigationInfo::UNSUPPORTED; + rv = mNavInfo->IsTypeSupported(nsDependentCString(aContentType), + mDocShell, + &canHandle); + *aCanHandleContent = (canHandle != nsIWebNavigationInfo::UNSUPPORTED); + } - return rv; + return rv; } NS_IMETHODIMP -nsDSURIContentListener::GetLoadCookie(nsISupports ** aLoadCookie) +nsDSURIContentListener::GetLoadCookie(nsISupports** aLoadCookie) { - NS_IF_ADDREF(*aLoadCookie = nsDocShell::GetAsSupports(mDocShell)); - return NS_OK; + NS_IF_ADDREF(*aLoadCookie = nsDocShell::GetAsSupports(mDocShell)); + return NS_OK; } NS_IMETHODIMP -nsDSURIContentListener::SetLoadCookie(nsISupports * aLoadCookie) +nsDSURIContentListener::SetLoadCookie(nsISupports* aLoadCookie) { #ifdef DEBUG - nsRefPtr<nsDocLoader> cookieAsDocLoader = - nsDocLoader::GetAsDocLoader(aLoadCookie); - NS_ASSERTION(cookieAsDocLoader && cookieAsDocLoader == mDocShell, - "Invalid load cookie being set!"); + nsRefPtr<nsDocLoader> cookieAsDocLoader = + nsDocLoader::GetAsDocLoader(aLoadCookie); + NS_ASSERTION(cookieAsDocLoader && cookieAsDocLoader == mDocShell, + "Invalid load cookie being set!"); #endif - return NS_OK; + return NS_OK; } -NS_IMETHODIMP -nsDSURIContentListener::GetParentContentListener(nsIURIContentListener** - aParentListener) +NS_IMETHODIMP +nsDSURIContentListener::GetParentContentListener( + nsIURIContentListener** aParentListener) { - if (mWeakParentContentListener) - { - nsCOMPtr<nsIURIContentListener> tempListener = - do_QueryReferent(mWeakParentContentListener); - *aParentListener = tempListener; - NS_IF_ADDREF(*aParentListener); - } - else { - *aParentListener = mParentContentListener; - NS_IF_ADDREF(*aParentListener); - } - return NS_OK; + if (mWeakParentContentListener) { + nsCOMPtr<nsIURIContentListener> tempListener = + do_QueryReferent(mWeakParentContentListener); + *aParentListener = tempListener; + NS_IF_ADDREF(*aParentListener); + } else { + *aParentListener = mParentContentListener; + NS_IF_ADDREF(*aParentListener); + } + return NS_OK; } NS_IMETHODIMP -nsDSURIContentListener::SetParentContentListener(nsIURIContentListener* - aParentListener) +nsDSURIContentListener::SetParentContentListener( + nsIURIContentListener* aParentListener) { - if (aParentListener) - { - // Store the parent listener as a weak ref. Parents not supporting - // nsISupportsWeakReference assert but may still be used. - mParentContentListener = nullptr; - mWeakParentContentListener = do_GetWeakReference(aParentListener); - if (!mWeakParentContentListener) - { - mParentContentListener = aParentListener; - } + if (aParentListener) { + // Store the parent listener as a weak ref. Parents not supporting + // nsISupportsWeakReference assert but may still be used. + mParentContentListener = nullptr; + mWeakParentContentListener = do_GetWeakReference(aParentListener); + if (!mWeakParentContentListener) { + mParentContentListener = aParentListener; } - else - { - mWeakParentContentListener = nullptr; - mParentContentListener = nullptr; - } - return NS_OK; + } else { + mWeakParentContentListener = nullptr; + mParentContentListener = nullptr; + } + return NS_OK; } -bool nsDSURIContentListener::CheckOneFrameOptionsPolicy(nsIHttpChannel *httpChannel, - const nsAString& policy) { - static const char allowFrom[] = "allow-from"; - const uint32_t allowFromLen = ArrayLength(allowFrom) - 1; - bool isAllowFrom = - StringHead(policy, allowFromLen).LowerCaseEqualsLiteral(allowFrom); +bool +nsDSURIContentListener::CheckOneFrameOptionsPolicy(nsIHttpChannel* aHttpChannel, + const nsAString& aPolicy) +{ + static const char allowFrom[] = "allow-from"; + const uint32_t allowFromLen = ArrayLength(allowFrom) - 1; + bool isAllowFrom = + StringHead(aPolicy, allowFromLen).LowerCaseEqualsLiteral(allowFrom); + + // return early if header does not have one of the values with meaning + if (!aPolicy.LowerCaseEqualsLiteral("deny") && + !aPolicy.LowerCaseEqualsLiteral("sameorigin") && + !isAllowFrom) { + return true; + } + + nsCOMPtr<nsIURI> uri; + aHttpChannel->GetURI(getter_AddRefs(uri)); + + // XXXkhuey when does this happen? Is returning true safe here? + if (!mDocShell) { + return true; + } + + // We need to check the location of this window and the location of the top + // window, if we're not the top. X-F-O: SAMEORIGIN requires that the + // document must be same-origin with top window. X-F-O: DENY requires that + // the document must never be framed. + nsCOMPtr<nsIDOMWindow> thisWindow = mDocShell->GetWindow(); + // If we don't have DOMWindow there is no risk of clickjacking + if (!thisWindow) { + return true; + } - // return early if header does not have one of the values with meaning - if (!policy.LowerCaseEqualsLiteral("deny") && - !policy.LowerCaseEqualsLiteral("sameorigin") && - !isAllowFrom) - return true; + // GetScriptableTop, not GetTop, because we want this to respect + // <iframe mozbrowser> boundaries. + nsCOMPtr<nsIDOMWindow> topWindow; + thisWindow->GetScriptableTop(getter_AddRefs(topWindow)); + + // if the document is in the top window, it's not in a frame. + if (thisWindow == topWindow) { + return true; + } - nsCOMPtr<nsIURI> uri; - httpChannel->GetURI(getter_AddRefs(uri)); + // Find the top docshell in our parent chain that doesn't have the system + // principal and use it for the principal comparison. Finding the top + // content-type docshell doesn't work because some chrome documents are + // loaded in content docshells (see bug 593387). + nsCOMPtr<nsIDocShellTreeItem> thisDocShellItem( + do_QueryInterface(static_cast<nsIDocShell*>(mDocShell))); + nsCOMPtr<nsIDocShellTreeItem> parentDocShellItem; + nsCOMPtr<nsIDocShellTreeItem> curDocShellItem = thisDocShellItem; + nsCOMPtr<nsIDocument> topDoc; + nsresult rv; + nsCOMPtr<nsIScriptSecurityManager> ssm = + do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); + if (!ssm) { + MOZ_CRASH(); + } - // XXXkhuey when does this happen? Is returning true safe here? - if (!mDocShell) { - return true; + // Traverse up the parent chain and stop when we see a docshell whose + // parent has a system principal, or a docshell corresponding to + // <iframe mozbrowser>. + while (NS_SUCCEEDED( + curDocShellItem->GetParent(getter_AddRefs(parentDocShellItem))) && + parentDocShellItem) { + nsCOMPtr<nsIDocShell> curDocShell = do_QueryInterface(curDocShellItem); + if (curDocShell && curDocShell->GetIsBrowserOrApp()) { + break; } - // We need to check the location of this window and the location of the top - // window, if we're not the top. X-F-O: SAMEORIGIN requires that the - // document must be same-origin with top window. X-F-O: DENY requires that - // the document must never be framed. - nsCOMPtr<nsIDOMWindow> thisWindow = mDocShell->GetWindow(); - // If we don't have DOMWindow there is no risk of clickjacking - if (!thisWindow) - return true; + bool system = false; + topDoc = parentDocShellItem->GetDocument(); + if (topDoc) { + if (NS_SUCCEEDED( + ssm->IsSystemPrincipal(topDoc->NodePrincipal(), &system)) && + system) { + // Found a system-principled doc: last docshell was top. + break; + } + } else { + return false; + } + curDocShellItem = parentDocShellItem; + } - // GetScriptableTop, not GetTop, because we want this to respect - // <iframe mozbrowser> boundaries. - nsCOMPtr<nsIDOMWindow> topWindow; - thisWindow->GetScriptableTop(getter_AddRefs(topWindow)); + // If this document has the top non-SystemPrincipal docshell it is not being + // framed or it is being framed by a chrome document, which we allow. + if (curDocShellItem == thisDocShellItem) { + return true; + } - // if the document is in the top window, it's not in a frame. - if (thisWindow == topWindow) - return true; + // If the value of the header is DENY, and the previous condition is + // not met (current docshell is not the top docshell), prohibit the + // load. + if (aPolicy.LowerCaseEqualsLiteral("deny")) { + ReportXFOViolation(curDocShellItem, uri, eDENY); + return false; + } + + topDoc = curDocShellItem->GetDocument(); + nsCOMPtr<nsIURI> topUri; + topDoc->NodePrincipal()->GetURI(getter_AddRefs(topUri)); - // Find the top docshell in our parent chain that doesn't have the system - // principal and use it for the principal comparison. Finding the top - // content-type docshell doesn't work because some chrome documents are - // loaded in content docshells (see bug 593387). - nsCOMPtr<nsIDocShellTreeItem> thisDocShellItem(do_QueryInterface( - static_cast<nsIDocShell*> (mDocShell))); - nsCOMPtr<nsIDocShellTreeItem> parentDocShellItem, - curDocShellItem = thisDocShellItem; - nsCOMPtr<nsIDocument> topDoc; - nsresult rv; - nsCOMPtr<nsIScriptSecurityManager> ssm = - do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); - if (!ssm) { - MOZ_CRASH(); + // If the X-Frame-Options value is SAMEORIGIN, then the top frame in the + // parent chain must be from the same origin as this document. + if (aPolicy.LowerCaseEqualsLiteral("sameorigin")) { + rv = ssm->CheckSameOriginURI(uri, topUri, true); + if (NS_FAILED(rv)) { + ReportXFOViolation(curDocShellItem, uri, eSAMEORIGIN); + return false; /* wasn't same-origin */ + } + } + + // If the X-Frame-Options value is "allow-from [uri]", then the top + // frame in the parent chain must be from that origin + if (isAllowFrom) { + if (aPolicy.Length() == allowFromLen || + (aPolicy[allowFromLen] != ' ' && + aPolicy[allowFromLen] != '\t')) { + ReportXFOViolation(curDocShellItem, uri, eALLOWFROM); + return false; + } + rv = NS_NewURI(getter_AddRefs(uri), Substring(aPolicy, allowFromLen)); + if (NS_FAILED(rv)) { + return false; } - // Traverse up the parent chain and stop when we see a docshell whose - // parent has a system principal, or a docshell corresponding to - // <iframe mozbrowser>. - while (NS_SUCCEEDED(curDocShellItem->GetParent(getter_AddRefs(parentDocShellItem))) && - parentDocShellItem) { - - nsCOMPtr<nsIDocShell> curDocShell = do_QueryInterface(curDocShellItem); - if (curDocShell && curDocShell->GetIsBrowserOrApp()) { - break; - } - - bool system = false; - topDoc = parentDocShellItem->GetDocument(); - if (topDoc) { - if (NS_SUCCEEDED(ssm->IsSystemPrincipal(topDoc->NodePrincipal(), - &system)) && system) { - // Found a system-principled doc: last docshell was top. - break; - } - } - else { - return false; - } - curDocShellItem = parentDocShellItem; - } - - // If this document has the top non-SystemPrincipal docshell it is not being - // framed or it is being framed by a chrome document, which we allow. - if (curDocShellItem == thisDocShellItem) - return true; - - // If the value of the header is DENY, and the previous condition is - // not met (current docshell is not the top docshell), prohibit the - // load. - if (policy.LowerCaseEqualsLiteral("deny")) { - ReportXFOViolation(curDocShellItem, uri, eDENY); - return false; + rv = ssm->CheckSameOriginURI(uri, topUri, true); + if (NS_FAILED(rv)) { + ReportXFOViolation(curDocShellItem, uri, eALLOWFROM); + return false; } - - topDoc = curDocShellItem->GetDocument(); - nsCOMPtr<nsIURI> topUri; - topDoc->NodePrincipal()->GetURI(getter_AddRefs(topUri)); - - // If the X-Frame-Options value is SAMEORIGIN, then the top frame in the - // parent chain must be from the same origin as this document. - if (policy.LowerCaseEqualsLiteral("sameorigin")) { - rv = ssm->CheckSameOriginURI(uri, topUri, true); - if (NS_FAILED(rv)) { - ReportXFOViolation(curDocShellItem, uri, eSAMEORIGIN); - return false; /* wasn't same-origin */ - } - } + } - // If the X-Frame-Options value is "allow-from [uri]", then the top - // frame in the parent chain must be from that origin - if (isAllowFrom) { - if (policy.Length() == allowFromLen || - (policy[allowFromLen] != ' ' && - policy[allowFromLen] != '\t')) { - ReportXFOViolation(curDocShellItem, uri, eALLOWFROM); - return false; - } - rv = NS_NewURI(getter_AddRefs(uri), - Substring(policy, allowFromLen)); - if (NS_FAILED(rv)) - return false; - - rv = ssm->CheckSameOriginURI(uri, topUri, true); - if (NS_FAILED(rv)) { - ReportXFOViolation(curDocShellItem, uri, eALLOWFROM); - return false; - } - } - - return true; + return true; } // Check if X-Frame-Options permits this document to be loaded as a subdocument. // This will iterate through and check any number of X-Frame-Options policies // in the request (comma-separated in a header, multiple headers, etc). -bool nsDSURIContentListener::CheckFrameOptions(nsIRequest *request) +bool +nsDSURIContentListener::CheckFrameOptions(nsIRequest* aRequest) { - nsresult rv; - nsCOMPtr<nsIChannel> chan = do_QueryInterface(request); - if (!chan) { - return true; - } + nsresult rv; + nsCOMPtr<nsIChannel> chan = do_QueryInterface(aRequest); + if (!chan) { + return true; + } - nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(chan); - if (!httpChannel) { - // check if it is hiding in a multipart channel - rv = mDocShell->GetHttpChannel(chan, getter_AddRefs(httpChannel)); - if (NS_FAILED(rv)) - return false; + nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(chan); + if (!httpChannel) { + // check if it is hiding in a multipart channel + rv = mDocShell->GetHttpChannel(chan, getter_AddRefs(httpChannel)); + if (NS_FAILED(rv)) { + return false; } + } - if (!httpChannel) { - return true; - } - - nsAutoCString xfoHeaderCValue; - httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("X-Frame-Options"), - xfoHeaderCValue); - NS_ConvertUTF8toUTF16 xfoHeaderValue(xfoHeaderCValue); + if (!httpChannel) { + return true; + } - // if no header value, there's nothing to do. - if (xfoHeaderValue.IsEmpty()) - return true; + nsAutoCString xfoHeaderCValue; + httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("X-Frame-Options"), + xfoHeaderCValue); + NS_ConvertUTF8toUTF16 xfoHeaderValue(xfoHeaderCValue); + + // if no header value, there's nothing to do. + if (xfoHeaderValue.IsEmpty()) { + return true; + } - // iterate through all the header values (usually there's only one, but can - // be many. If any want to deny the load, deny the load. - nsCharSeparatedTokenizer tokenizer(xfoHeaderValue, ','); - while (tokenizer.hasMoreTokens()) { - const nsSubstring& tok = tokenizer.nextToken(); - if (!CheckOneFrameOptionsPolicy(httpChannel, tok)) { - // cancel the load and display about:blank - httpChannel->Cancel(NS_BINDING_ABORTED); - if (mDocShell) { - nsCOMPtr<nsIWebNavigation> webNav(do_QueryObject(mDocShell)); - if (webNav) { - webNav->LoadURI(MOZ_UTF16("about:blank"), - 0, nullptr, nullptr, nullptr); - } - } - return false; + // iterate through all the header values (usually there's only one, but can + // be many. If any want to deny the load, deny the load. + nsCharSeparatedTokenizer tokenizer(xfoHeaderValue, ','); + while (tokenizer.hasMoreTokens()) { + const nsSubstring& tok = tokenizer.nextToken(); + if (!CheckOneFrameOptionsPolicy(httpChannel, tok)) { + // cancel the load and display about:blank + httpChannel->Cancel(NS_BINDING_ABORTED); + if (mDocShell) { + nsCOMPtr<nsIWebNavigation> webNav(do_QueryObject(mDocShell)); + if (webNav) { + webNav->LoadURI(MOZ_UTF16("about:blank"), + 0, nullptr, nullptr, nullptr); } + } + return false; } + } - return true; + return true; } void nsDSURIContentListener::ReportXFOViolation(nsIDocShellTreeItem* aTopDocShellItem, nsIURI* aThisURI, XFOHeader aHeader) { MOZ_ASSERT(aTopDocShellItem, "Need a top docshell"); - nsCOMPtr<nsPIDOMWindow> topOuterWindow = aTopDocShellItem->GetWindow(); - if (!topOuterWindow) - return; + nsCOMPtr<nsPIDOMWindow> topOuterWindow = aTopDocShellItem->GetWindow(); + if (!topOuterWindow) { + return; + } - NS_ASSERTION(topOuterWindow->IsOuterWindow(), "Huh?"); - nsPIDOMWindow* topInnerWindow = topOuterWindow->GetCurrentInnerWindow(); - if (!topInnerWindow) - return; + NS_ASSERTION(topOuterWindow->IsOuterWindow(), "Huh?"); + nsPIDOMWindow* topInnerWindow = topOuterWindow->GetCurrentInnerWindow(); + if (!topInnerWindow) { + return; + } - nsCOMPtr<nsIURI> topURI; + nsCOMPtr<nsIURI> topURI; - nsCOMPtr<nsIDocument> document = aTopDocShellItem->GetDocument(); - nsresult rv = document->NodePrincipal()->GetURI(getter_AddRefs(topURI)); - if (NS_FAILED(rv)) - return; + nsCOMPtr<nsIDocument> document = aTopDocShellItem->GetDocument(); + nsresult rv = document->NodePrincipal()->GetURI(getter_AddRefs(topURI)); + if (NS_FAILED(rv)) { + return; + } - if (!topURI) - return; + if (!topURI) { + return; + } - nsCString topURIString; - nsCString thisURIString; + nsCString topURIString; + nsCString thisURIString; - rv = topURI->GetSpec(topURIString); - if (NS_FAILED(rv)) - return; + rv = topURI->GetSpec(topURIString); + if (NS_FAILED(rv)) { + return; + } - rv = aThisURI->GetSpec(thisURIString); - if (NS_FAILED(rv)) - return; + rv = aThisURI->GetSpec(thisURIString); + if (NS_FAILED(rv)) { + return; + } - nsCOMPtr<nsIConsoleService> consoleService = - do_GetService(NS_CONSOLESERVICE_CONTRACTID); - nsCOMPtr<nsIScriptError> errorObject = - do_CreateInstance(NS_SCRIPTERROR_CONTRACTID); + nsCOMPtr<nsIConsoleService> consoleService = + do_GetService(NS_CONSOLESERVICE_CONTRACTID); + nsCOMPtr<nsIScriptError> errorObject = + do_CreateInstance(NS_SCRIPTERROR_CONTRACTID); - if (!consoleService || !errorObject) - return; + if (!consoleService || !errorObject) { + return; + } - nsString msg = NS_LITERAL_STRING("Load denied by X-Frame-Options: "); - msg.Append(NS_ConvertUTF8toUTF16(thisURIString)); + nsString msg = NS_LITERAL_STRING("Load denied by X-Frame-Options: "); + msg.Append(NS_ConvertUTF8toUTF16(thisURIString)); - switch (aHeader) { - case eDENY: - msg.AppendLiteral(" does not permit framing."); - break; - case eSAMEORIGIN: - msg.AppendLiteral(" does not permit cross-origin framing."); - break; - case eALLOWFROM: - msg.AppendLiteral(" does not permit framing by "); - msg.Append(NS_ConvertUTF8toUTF16(topURIString)); - msg.Append('.'); - break; - } + switch (aHeader) { + case eDENY: + msg.AppendLiteral(" does not permit framing."); + break; + case eSAMEORIGIN: + msg.AppendLiteral(" does not permit cross-origin framing."); + break; + case eALLOWFROM: + msg.AppendLiteral(" does not permit framing by "); + msg.Append(NS_ConvertUTF8toUTF16(topURIString)); + msg.Append('.'); + break; + } - rv = errorObject->InitWithWindowID(msg, EmptyString(), EmptyString(), 0, 0, - nsIScriptError::errorFlag, - "X-Frame-Options", - topInnerWindow->WindowID()); - if (NS_FAILED(rv)) - return; + rv = errorObject->InitWithWindowID(msg, EmptyString(), EmptyString(), 0, 0, + nsIScriptError::errorFlag, + "X-Frame-Options", + topInnerWindow->WindowID()); + if (NS_FAILED(rv)) { + return; + } - consoleService->LogMessage(errorObject); + consoleService->LogMessage(errorObject); }
--- a/docshell/base/nsDSURIContentListener.h +++ b/docshell/base/nsDSURIContentListener.h @@ -1,71 +1,74 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * This Source Code Form is subject to the terms of the Mozilla Public +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef nsDSURIContentListener_h__ #define nsDSURIContentListener_h__ #include "nsCOMPtr.h" #include "nsIURIContentListener.h" #include "nsWeakReference.h" class nsDocShell; class nsIWebNavigationInfo; class nsIHttpChannel; class nsAString; -class nsDSURIContentListener MOZ_FINAL : - public nsIURIContentListener, - public nsSupportsWeakReference - +class nsDSURIContentListener MOZ_FINAL + : public nsIURIContentListener + , public nsSupportsWeakReference { -friend class nsDocShell; + friend class nsDocShell; + public: - NS_DECL_THREADSAFE_ISUPPORTS - NS_DECL_NSIURICONTENTLISTENER + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIURICONTENTLISTENER - nsresult Init(); + nsresult Init(); protected: - explicit nsDSURIContentListener(nsDocShell* aDocShell); - virtual ~nsDSURIContentListener(); + explicit nsDSURIContentListener(nsDocShell* aDocShell); + virtual ~nsDSURIContentListener(); - void DropDocShellreference() { - mDocShell = nullptr; - mExistingJPEGRequest = nullptr; - mExistingJPEGStreamListener = nullptr; - } + void DropDocShellReference() + { + mDocShell = nullptr; + mExistingJPEGRequest = nullptr; + mExistingJPEGStreamListener = nullptr; + } - // Determine if X-Frame-Options allows content to be framed - // as a subdocument - bool CheckFrameOptions(nsIRequest* request); - bool CheckOneFrameOptionsPolicy(nsIHttpChannel* httpChannel, - const nsAString& policy); + // Determine if X-Frame-Options allows content to be framed + // as a subdocument + bool CheckFrameOptions(nsIRequest* aRequest); + bool CheckOneFrameOptionsPolicy(nsIHttpChannel* aHttpChannel, + const nsAString& aPolicy); - enum XFOHeader { - eDENY, - eSAMEORIGIN, - eALLOWFROM - }; + enum XFOHeader + { + eDENY, + eSAMEORIGIN, + eALLOWFROM + }; - void ReportXFOViolation(nsIDocShellTreeItem* aTopDocShellItem, - nsIURI* aThisURI, - XFOHeader aHeader); + void ReportXFOViolation(nsIDocShellTreeItem* aTopDocShellItem, + nsIURI* aThisURI, + XFOHeader aHeader); + protected: - nsDocShell* mDocShell; - // Hack to handle multipart images without creating a new viewer - nsCOMPtr<nsIStreamListener> mExistingJPEGStreamListener; - nsCOMPtr<nsIChannel> mExistingJPEGRequest; + nsDocShell* mDocShell; + // Hack to handle multipart images without creating a new viewer + nsCOMPtr<nsIStreamListener> mExistingJPEGStreamListener; + nsCOMPtr<nsIChannel> mExistingJPEGRequest; - // Store the parent listener in either of these depending on - // if supports weak references or not. Proper weak refs are - // preferred and encouraged! - nsWeakPtr mWeakParentContentListener; - nsIURIContentListener* mParentContentListener; + // Store the parent listener in either of these depending on + // if supports weak references or not. Proper weak refs are + // preferred and encouraged! + nsWeakPtr mWeakParentContentListener; + nsIURIContentListener* mParentContentListener; - nsCOMPtr<nsIWebNavigationInfo> mNavInfo; + nsCOMPtr<nsIWebNavigationInfo> mNavInfo; }; #endif /* nsDSURIContentListener_h__ */
--- a/docshell/base/nsDefaultURIFixup.cpp +++ b/docshell/base/nsDefaultURIFixup.cpp @@ -1,11 +1,11 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * This Source Code Form is subject to the terms of the Mozilla Public +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsNetUtil.h" #include "nsCRT.h" #include "nsIFile.h" #include <algorithm> @@ -34,1193 +34,1165 @@ NS_IMPL_ISUPPORTS(nsDefaultURIFixup, nsI static bool sInitializedPrefCaches = false; static bool sFixTypos = true; static bool sDNSFirstForSingleWords = false; static bool sFixupKeywords = true; nsDefaultURIFixup::nsDefaultURIFixup() { - /* member initializers and constructor code */ } - nsDefaultURIFixup::~nsDefaultURIFixup() { - /* destructor code */ } /* nsIURI createExposableURI (in nsIURI aURI); */ NS_IMETHODIMP -nsDefaultURIFixup::CreateExposableURI(nsIURI *aURI, nsIURI **aReturn) +nsDefaultURIFixup::CreateExposableURI(nsIURI* aURI, nsIURI** aReturn) { - NS_ENSURE_ARG_POINTER(aURI); - NS_ENSURE_ARG_POINTER(aReturn); + NS_ENSURE_ARG_POINTER(aURI); + NS_ENSURE_ARG_POINTER(aReturn); - bool isWyciwyg = false; - aURI->SchemeIs("wyciwyg", &isWyciwyg); + bool isWyciwyg = false; + aURI->SchemeIs("wyciwyg", &isWyciwyg); + + nsAutoCString userPass; + aURI->GetUserPass(userPass); - nsAutoCString userPass; - aURI->GetUserPass(userPass); + // most of the time we can just AddRef and return + if (!isWyciwyg && userPass.IsEmpty()) { + *aReturn = aURI; + NS_ADDREF(*aReturn); + return NS_OK; + } - // most of the time we can just AddRef and return - if (!isWyciwyg && userPass.IsEmpty()) - { - *aReturn = aURI; - NS_ADDREF(*aReturn); - return NS_OK; + // Rats, we have to massage the URI + nsCOMPtr<nsIURI> uri; + if (isWyciwyg) { + nsAutoCString path; + nsresult rv = aURI->GetPath(path); + NS_ENSURE_SUCCESS(rv, rv); + + uint32_t pathLength = path.Length(); + if (pathLength <= 2) { + return NS_ERROR_FAILURE; } - // Rats, we have to massage the URI - nsCOMPtr<nsIURI> uri; - if (isWyciwyg) - { - nsAutoCString path; - nsresult rv = aURI->GetPath(path); - NS_ENSURE_SUCCESS(rv, rv); - - uint32_t pathLength = path.Length(); - if (pathLength <= 2) - { - return NS_ERROR_FAILURE; - } + // Path is of the form "//123/http://foo/bar", with a variable number of + // digits. To figure out where the "real" URL starts, search path for a '/', + // starting at the third character. + int32_t slashIndex = path.FindChar('/', 2); + if (slashIndex == kNotFound) { + return NS_ERROR_FAILURE; + } - // Path is of the form "//123/http://foo/bar", with a variable number of digits. - // To figure out where the "real" URL starts, search path for a '/', starting at - // the third character. - int32_t slashIndex = path.FindChar('/', 2); - if (slashIndex == kNotFound) - { - return NS_ERROR_FAILURE; - } + // Get the charset of the original URI so we can pass it to our fixed up + // URI. + nsAutoCString charset; + aURI->GetOriginCharset(charset); - // Get the charset of the original URI so we can pass it to our fixed up URI. - nsAutoCString charset; - aURI->GetOriginCharset(charset); - - rv = NS_NewURI(getter_AddRefs(uri), + rv = NS_NewURI(getter_AddRefs(uri), Substring(path, slashIndex + 1, pathLength - slashIndex - 1), charset.get()); - NS_ENSURE_SUCCESS(rv, rv); - } - else - { - // clone the URI so zapping user:pass doesn't change the original - nsresult rv = aURI->Clone(getter_AddRefs(uri)); - NS_ENSURE_SUCCESS(rv, rv); - } + NS_ENSURE_SUCCESS(rv, rv); + } else { + // clone the URI so zapping user:pass doesn't change the original + nsresult rv = aURI->Clone(getter_AddRefs(uri)); + NS_ENSURE_SUCCESS(rv, rv); + } - // hide user:pass unless overridden by pref - if (Preferences::GetBool("browser.fixup.hide_user_pass", true)) - { - uri->SetUserPass(EmptyCString()); - } + // hide user:pass unless overridden by pref + if (Preferences::GetBool("browser.fixup.hide_user_pass", true)) { + uri->SetUserPass(EmptyCString()); + } - // return the fixed-up URI - *aReturn = uri; - NS_ADDREF(*aReturn); - return NS_OK; + // return the fixed-up URI + *aReturn = uri; + NS_ADDREF(*aReturn); + return NS_OK; } /* nsIURI createFixupURI (in nsAUTF8String aURIText, in unsigned long aFixupFlags); */ NS_IMETHODIMP -nsDefaultURIFixup::CreateFixupURI(const nsACString& aStringURI, uint32_t aFixupFlags, - nsIInputStream **aPostData, nsIURI **aURI) +nsDefaultURIFixup::CreateFixupURI(const nsACString& aStringURI, + uint32_t aFixupFlags, + nsIInputStream** aPostData, nsIURI** aURI) { nsCOMPtr<nsIURIFixupInfo> fixupInfo; nsresult rv = GetFixupURIInfo(aStringURI, aFixupFlags, aPostData, getter_AddRefs(fixupInfo)); NS_ENSURE_SUCCESS(rv, rv); fixupInfo->GetPreferredURI(aURI); return rv; } NS_IMETHODIMP -nsDefaultURIFixup::GetFixupURIInfo(const nsACString& aStringURI, uint32_t aFixupFlags, - nsIInputStream **aPostData, nsIURIFixupInfo **aInfo) +nsDefaultURIFixup::GetFixupURIInfo(const nsACString& aStringURI, + uint32_t aFixupFlags, + nsIInputStream** aPostData, + nsIURIFixupInfo** aInfo) { - NS_ENSURE_ARG(!aStringURI.IsEmpty()); - - nsresult rv; - - nsAutoCString uriString(aStringURI); - - // Eliminate embedded newlines, which single-line text fields now allow: - uriString.StripChars("\r\n"); - // Cleanup the empty spaces that might be on each end: - uriString.Trim(" "); + NS_ENSURE_ARG(!aStringURI.IsEmpty()); - NS_ENSURE_TRUE(!uriString.IsEmpty(), NS_ERROR_FAILURE); - - nsRefPtr<nsDefaultURIFixupInfo> info = new nsDefaultURIFixupInfo(uriString); - NS_ADDREF(*aInfo = info); + nsresult rv; - nsCOMPtr<nsIIOService> ioService = do_GetService(NS_IOSERVICE_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - nsAutoCString scheme; - ioService->ExtractScheme(aStringURI, scheme); - - // View-source is a pseudo scheme. We're interested in fixing up the stuff - // after it. The easiest way to do that is to call this method again with the - // "view-source:" lopped off and then prepend it again afterwards. + nsAutoCString uriString(aStringURI); - if (scheme.LowerCaseEqualsLiteral("view-source")) - { - nsCOMPtr<nsIURIFixupInfo> uriInfo; - uint32_t newFixupFlags = aFixupFlags & ~FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP; + // Eliminate embedded newlines, which single-line text fields now allow: + uriString.StripChars("\r\n"); + // Cleanup the empty spaces that might be on each end: + uriString.Trim(" "); + + NS_ENSURE_TRUE(!uriString.IsEmpty(), NS_ERROR_FAILURE); + + nsRefPtr<nsDefaultURIFixupInfo> info = new nsDefaultURIFixupInfo(uriString); + NS_ADDREF(*aInfo = info); - rv = GetFixupURIInfo(Substring(uriString, - sizeof("view-source:") - 1, - uriString.Length() - - (sizeof("view-source:") - 1)), - newFixupFlags, aPostData, getter_AddRefs(uriInfo)); - if (NS_FAILED(rv)) - return NS_ERROR_FAILURE; - nsAutoCString spec; - nsCOMPtr<nsIURI> uri; - uriInfo->GetPreferredURI(getter_AddRefs(uri)); - if (!uri) - return NS_ERROR_FAILURE; - uri->GetSpec(spec); - uriString.AssignLiteral("view-source:"); - uriString.Append(spec); - } - else { - // Check for if it is a file URL - nsCOMPtr<nsIURI> uri; - FileURIFixup(uriString, getter_AddRefs(uri)); - // NB: FileURIFixup only returns a URI if it had to fix the protocol to - // do so, so passing in file:///foo/bar will not hit this path: - if (uri) - { - uri.swap(info->mFixedURI); - info->mPreferredURI = info->mFixedURI; - info->mFixupChangedProtocol = true; - return NS_OK; - } + nsCOMPtr<nsIIOService> ioService = + do_GetService(NS_IOSERVICE_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + nsAutoCString scheme; + ioService->ExtractScheme(aStringURI, scheme); + + // View-source is a pseudo scheme. We're interested in fixing up the stuff + // after it. The easiest way to do that is to call this method again with the + // "view-source:" lopped off and then prepend it again afterwards. -#if defined(XP_WIN) - // Not a file URL, so translate '\' to '/' for convenience in the common protocols - // e.g. catch - // - // http:\\broken.com\address - // http:\\broken.com/blah - // broken.com\blah - // - // Code will also do partial fix up the following urls - // - // http:\\broken.com\address/somewhere\image.jpg (stops at first forward slash) - // http:\\broken.com\blah?arg=somearg\foo.jpg (stops at question mark) - // http:\\broken.com#odd\ref (stops at hash) - // - if (scheme.IsEmpty() || - scheme.LowerCaseEqualsLiteral("http") || - scheme.LowerCaseEqualsLiteral("https") || - scheme.LowerCaseEqualsLiteral("ftp")) - { - // Walk the string replacing backslashes with forward slashes until - // the end is reached, or a question mark, or a hash, or a forward - // slash. The forward slash test is to stop before trampling over - // URIs which legitimately contain a mix of both forward and - // backward slashes. - nsAutoCString::iterator start; - nsAutoCString::iterator end; - uriString.BeginWriting(start); - uriString.EndWriting(end); - while (start != end) { - if (*start == '?' || *start == '#' || *start == '/') - break; - if (*start == '\\') - *start = '/'; - ++start; - } - } -#endif - } - - if (!sInitializedPrefCaches) { - // Check if we want to fix up common scheme typos. - rv = Preferences::AddBoolVarCache(&sFixTypos, - "browser.fixup.typo.scheme", - sFixTypos); - MOZ_ASSERT(NS_SUCCEEDED(rv), - "Failed to observe \"browser.fixup.typo.scheme\""); - - rv = Preferences::AddBoolVarCache(&sDNSFirstForSingleWords, - "browser.fixup.dns_first_for_single_words", - sDNSFirstForSingleWords); - MOZ_ASSERT(NS_SUCCEEDED(rv), "Failed to observe \"browser.fixup.dns_first_for_single_words\""); - - rv = Preferences::AddBoolVarCache(&sFixupKeywords, "keyword.enabled", - sFixupKeywords); - MOZ_ASSERT(NS_SUCCEEDED(rv), "Failed to observe \"keyword.enabled\""); - sInitializedPrefCaches = true; - } + if (scheme.LowerCaseEqualsLiteral("view-source")) { + nsCOMPtr<nsIURIFixupInfo> uriInfo; + uint32_t newFixupFlags = aFixupFlags & ~FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP; - // Fix up common scheme typos. - if (sFixTypos && (aFixupFlags & FIXUP_FLAG_FIX_SCHEME_TYPOS)) { - - // Fast-path for common cases. - if (scheme.IsEmpty() || - scheme.LowerCaseEqualsLiteral("http") || - scheme.LowerCaseEqualsLiteral("https") || - scheme.LowerCaseEqualsLiteral("ftp") || - scheme.LowerCaseEqualsLiteral("file")) { - // Do nothing. - } else if (scheme.LowerCaseEqualsLiteral("ttp")) { - // ttp -> http. - uriString.Replace(0, 3, "http"); - scheme.AssignLiteral("http"); - info->mFixupChangedProtocol = true; - } else if (scheme.LowerCaseEqualsLiteral("ttps")) { - // ttps -> https. - uriString.Replace(0, 4, "https"); - scheme.AssignLiteral("https"); - info->mFixupChangedProtocol = true; - } else if (scheme.LowerCaseEqualsLiteral("tps")) { - // tps -> https. - uriString.Replace(0, 3, "https"); - scheme.AssignLiteral("https"); - info->mFixupChangedProtocol = true; - } else if (scheme.LowerCaseEqualsLiteral("ps")) { - // ps -> https. - uriString.Replace(0, 2, "https"); - scheme.AssignLiteral("https"); - info->mFixupChangedProtocol = true; - } else if (scheme.LowerCaseEqualsLiteral("ile")) { - // ile -> file. - uriString.Replace(0, 3, "file"); - scheme.AssignLiteral("file"); - info->mFixupChangedProtocol = true; - } else if (scheme.LowerCaseEqualsLiteral("le")) { - // le -> file. - uriString.Replace(0, 2, "file"); - scheme.AssignLiteral("file"); - info->mFixupChangedProtocol = true; - } + rv = GetFixupURIInfo(Substring(uriString, + sizeof("view-source:") - 1, + uriString.Length() - + (sizeof("view-source:") - 1)), + newFixupFlags, aPostData, getter_AddRefs(uriInfo)); + if (NS_FAILED(rv)) { + return NS_ERROR_FAILURE; + } + nsAutoCString spec; + nsCOMPtr<nsIURI> uri; + uriInfo->GetPreferredURI(getter_AddRefs(uri)); + if (!uri) { + return NS_ERROR_FAILURE; } - - // Now we need to check whether "scheme" is something we don't - // really know about. - nsCOMPtr<nsIProtocolHandler> ourHandler, extHandler; - - ioService->GetProtocolHandler(scheme.get(), getter_AddRefs(ourHandler)); - extHandler = do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX"default"); - - if (ourHandler != extHandler || !PossiblyHostPortUrl(uriString)) { - // Just try to create an URL out of it - rv = NS_NewURI(getter_AddRefs(info->mFixedURI), uriString, nullptr); - - if (!info->mFixedURI && rv != NS_ERROR_MALFORMED_URI) { - return rv; - } + uri->GetSpec(spec); + uriString.AssignLiteral("view-source:"); + uriString.Append(spec); + } else { + // Check for if it is a file URL + nsCOMPtr<nsIURI> uri; + FileURIFixup(uriString, getter_AddRefs(uri)); + // NB: FileURIFixup only returns a URI if it had to fix the protocol to + // do so, so passing in file:///foo/bar will not hit this path: + if (uri) { + uri.swap(info->mFixedURI); + info->mPreferredURI = info->mFixedURI; + info->mFixupChangedProtocol = true; + return NS_OK; } - if (info->mFixedURI && ourHandler == extHandler && sFixupKeywords && - (aFixupFlags & FIXUP_FLAG_FIX_SCHEME_TYPOS)) { - nsCOMPtr<nsIExternalProtocolService> extProtService = - do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID); - if (extProtService) { - bool handlerExists = false; - rv = extProtService->ExternalProtocolHandlerExists(scheme.get(), &handlerExists); - if (NS_FAILED(rv)) { - return rv; - } - // This basically means we're dealing with a theoretically valid - // URI... but we have no idea how to load it. (e.g. "christmas:humbug") - // It's more likely the user wants to search, and so we - // chuck this over to their preferred search provider instead: - if (!handlerExists) { - TryKeywordFixupForURIInfo(uriString, info, aPostData); - } +#if defined(XP_WIN) + // Not a file URL, so translate '\' to '/' for convenience in the common + // protocols. E.g. catch + // + // http:\\broken.com\address + // http:\\broken.com/blah + // broken.com\blah + // + // Code will also do partial fix up the following urls + // + // http:\\broken.com\address/somewhere\image.jpg (stops at first forward slash) + // http:\\broken.com\blah?arg=somearg\foo.jpg (stops at question mark) + // http:\\broken.com#odd\ref (stops at hash) + // + if (scheme.IsEmpty() || + scheme.LowerCaseEqualsLiteral("http") || + scheme.LowerCaseEqualsLiteral("https") || + scheme.LowerCaseEqualsLiteral("ftp")) { + // Walk the string replacing backslashes with forward slashes until + // the end is reached, or a question mark, or a hash, or a forward + // slash. The forward slash test is to stop before trampling over + // URIs which legitimately contain a mix of both forward and + // backward slashes. + nsAutoCString::iterator start; + nsAutoCString::iterator end; + uriString.BeginWriting(start); + uriString.EndWriting(end); + while (start != end) { + if (*start == '?' || *start == '#' || *start == '/') { + break; } + if (*start == '\\') { + *start = '/'; + } + ++start; + } } - - if (info->mFixedURI) { - if (!info->mPreferredURI) { - if (aFixupFlags & FIXUP_FLAGS_MAKE_ALTERNATE_URI) - info->mFixupCreatedAlternateURI = MakeAlternateURI(info->mFixedURI); - info->mPreferredURI = info->mFixedURI; - } - return NS_OK; - } +#endif + } + + if (!sInitializedPrefCaches) { + // Check if we want to fix up common scheme typos. + rv = Preferences::AddBoolVarCache(&sFixTypos, + "browser.fixup.typo.scheme", + sFixTypos); + MOZ_ASSERT(NS_SUCCEEDED(rv), + "Failed to observe \"browser.fixup.typo.scheme\""); + + rv = Preferences::AddBoolVarCache(&sDNSFirstForSingleWords, + "browser.fixup.dns_first_for_single_words", + sDNSFirstForSingleWords); + MOZ_ASSERT(NS_SUCCEEDED(rv), + "Failed to observe \"browser.fixup.dns_first_for_single_words\""); + + rv = Preferences::AddBoolVarCache(&sFixupKeywords, "keyword.enabled", + sFixupKeywords); + MOZ_ASSERT(NS_SUCCEEDED(rv), "Failed to observe \"keyword.enabled\""); + sInitializedPrefCaches = true; + } - // Fix up protocol string before calling KeywordURIFixup, because - // it cares about the hostname of such URIs: - nsCOMPtr<nsIURI> uriWithProtocol; - bool inputHadDuffProtocol = false; + // Fix up common scheme typos. + if (sFixTypos && (aFixupFlags & FIXUP_FLAG_FIX_SCHEME_TYPOS)) { + // Fast-path for common cases. + if (scheme.IsEmpty() || + scheme.LowerCaseEqualsLiteral("http") || + scheme.LowerCaseEqualsLiteral("https") || + scheme.LowerCaseEqualsLiteral("ftp") || + scheme.LowerCaseEqualsLiteral("file")) { + // Do nothing. + } else if (scheme.LowerCaseEqualsLiteral("ttp")) { + // ttp -> http. + uriString.Replace(0, 3, "http"); + scheme.AssignLiteral("http"); + info->mFixupChangedProtocol = true; + } else if (scheme.LowerCaseEqualsLiteral("ttps")) { + // ttps -> https. + uriString.Replace(0, 4, "https"); + scheme.AssignLiteral("https"); + info->mFixupChangedProtocol = true; + } else if (scheme.LowerCaseEqualsLiteral("tps")) { + // tps -> https. + uriString.Replace(0, 3, "https"); + scheme.AssignLiteral("https"); + info->mFixupChangedProtocol = true; + } else if (scheme.LowerCaseEqualsLiteral("ps")) { + // ps -> https. + uriString.Replace(0, 2, "https"); + scheme.AssignLiteral("https"); + info->mFixupChangedProtocol = true; + } else if (scheme.LowerCaseEqualsLiteral("ile")) { + // ile -> file. + uriString.Replace(0, 3, "file"); + scheme.AssignLiteral("file"); + info->mFixupChangedProtocol = true; + } else if (scheme.LowerCaseEqualsLiteral("le")) { + // le -> file. + uriString.Replace(0, 2, "file"); + scheme.AssignLiteral("file"); + info->mFixupChangedProtocol = true; + } + } - // Prune duff protocol schemes - // - // ://totallybroken.url.com - // //shorthand.url.com - // - if (StringBeginsWith(uriString, NS_LITERAL_CSTRING("://"))) - { - uriString = StringTail(uriString, uriString.Length() - 3); - inputHadDuffProtocol = true; - } else if (StringBeginsWith(uriString, NS_LITERAL_CSTRING("//"))) { - uriString = StringTail(uriString, uriString.Length() - 2); - inputHadDuffProtocol = true; - } + // Now we need to check whether "scheme" is something we don't + // really know about. + nsCOMPtr<nsIProtocolHandler> ourHandler, extHandler; - // NB: this rv gets returned at the end of this method if we never - // do a keyword fixup after this (because the pref or the flags passed - // might not let us). - rv = FixupURIProtocol(uriString, info, getter_AddRefs(uriWithProtocol)); - if (uriWithProtocol) { - info->mFixedURI = uriWithProtocol; + ioService->GetProtocolHandler(scheme.get(), getter_AddRefs(ourHandler)); + extHandler = do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "default"); + + if (ourHandler != extHandler || !PossiblyHostPortUrl(uriString)) { + // Just try to create an URL out of it + rv = NS_NewURI(getter_AddRefs(info->mFixedURI), uriString, nullptr); + + if (!info->mFixedURI && rv != NS_ERROR_MALFORMED_URI) { + return rv; } + } - // See if it is a keyword - // Test whether keywords need to be fixed up - if (sFixupKeywords && (aFixupFlags & FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP) && - !inputHadDuffProtocol) { - if (NS_SUCCEEDED(KeywordURIFixup(uriString, info, aPostData)) && - info->mPreferredURI) { - return NS_OK; - } + if (info->mFixedURI && ourHandler == extHandler && sFixupKeywords && + (aFixupFlags & FIXUP_FLAG_FIX_SCHEME_TYPOS)) { + nsCOMPtr<nsIExternalProtocolService> extProtService = + do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID); + if (extProtService) { + bool handlerExists = false; + rv = extProtService->ExternalProtocolHandlerExists(scheme.get(), + &handlerExists); + if (NS_FAILED(rv)) { + return rv; + } + // This basically means we're dealing with a theoretically valid + // URI... but we have no idea how to load it. (e.g. "christmas:humbug") + // It's more likely the user wants to search, and so we + // chuck this over to their preferred search provider instead: + if (!handlerExists) { + TryKeywordFixupForURIInfo(uriString, info, aPostData); + } } - - // Did the caller want us to try an alternative URI? - // If so, attempt to fixup http://foo into http://www.foo.com + } - if (info->mFixedURI && aFixupFlags & FIXUP_FLAGS_MAKE_ALTERNATE_URI) { + if (info->mFixedURI) { + if (!info->mPreferredURI) { + if (aFixupFlags & FIXUP_FLAGS_MAKE_ALTERNATE_URI) { info->mFixupCreatedAlternateURI = MakeAlternateURI(info->mFixedURI); + } + info->mPreferredURI = info->mFixedURI; } + return NS_OK; + } + + // Fix up protocol string before calling KeywordURIFixup, because + // it cares about the hostname of such URIs: + nsCOMPtr<nsIURI> uriWithProtocol; + bool inputHadDuffProtocol = false; - // If there is no relevent dot in the host, do we require the domain to - // be whitelisted? - if (info->mFixedURI) { - if (aFixupFlags & FIXUP_FLAG_REQUIRE_WHITELISTED_HOST) { + // Prune duff protocol schemes + // + // ://totallybroken.url.com + // //shorthand.url.com + // + if (StringBeginsWith(uriString, NS_LITERAL_CSTRING("://"))) { + uriString = StringTail(uriString, uriString.Length() - 3); + inputHadDuffProtocol = true; + } else if (StringBeginsWith(uriString, NS_LITERAL_CSTRING("//"))) { + uriString = StringTail(uriString, uriString.Length() - 2); + inputHadDuffProtocol = true; + } - nsAutoCString asciiHost; - if (NS_SUCCEEDED(info->mFixedURI->GetAsciiHost(asciiHost)) && - !asciiHost.IsEmpty()) { - - uint32_t dotLoc = uint32_t(asciiHost.FindChar('.')); + // NB: this rv gets returned at the end of this method if we never + // do a keyword fixup after this (because the pref or the flags passed + // might not let us). + rv = FixupURIProtocol(uriString, info, getter_AddRefs(uriWithProtocol)); + if (uriWithProtocol) { + info->mFixedURI = uriWithProtocol; + } - if ((dotLoc == uint32_t(kNotFound) || dotLoc == asciiHost.Length() - 1)) { - if (IsDomainWhitelisted(asciiHost, dotLoc)) { - info->mPreferredURI = info->mFixedURI; - } - } else { - info->mPreferredURI = info->mFixedURI; - } - } + // See if it is a keyword + // Test whether keywords need to be fixed up + if (sFixupKeywords && (aFixupFlags & FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP) && + !inputHadDuffProtocol) { + if (NS_SUCCEEDED(KeywordURIFixup(uriString, info, aPostData)) && + info->mPreferredURI) { + return NS_OK; + } + } + + // Did the caller want us to try an alternative URI? + // If so, attempt to fixup http://foo into http://www.foo.com + + if (info->mFixedURI && aFixupFlags & FIXUP_FLAGS_MAKE_ALTERNATE_URI) { + info->mFixupCreatedAlternateURI = MakeAlternateURI(info->mFixedURI); + } + + // If there is no relevent dot in the host, do we require the domain to + // be whitelisted? + if (info->mFixedURI) { + if (aFixupFlags & FIXUP_FLAG_REQUIRE_WHITELISTED_HOST) { + nsAutoCString asciiHost; + if (NS_SUCCEEDED(info->mFixedURI->GetAsciiHost(asciiHost)) && + !asciiHost.IsEmpty()) { + uint32_t dotLoc = uint32_t(asciiHost.FindChar('.')); + + if ((dotLoc == uint32_t(kNotFound) || + dotLoc == asciiHost.Length() - 1)) { + if (IsDomainWhitelisted(asciiHost, dotLoc)) { + info->mPreferredURI = info->mFixedURI; + } } else { - info->mPreferredURI = info->mFixedURI; + info->mPreferredURI = info->mFixedURI; } - - return NS_OK; + } + } else { + info->mPreferredURI = info->mFixedURI; } - // If we still haven't been able to construct a valid URI, try to force a - // keyword match. This catches search strings with '.' or ':' in them. - if (sFixupKeywords && (aFixupFlags & FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP)) { - rv = TryKeywordFixupForURIInfo(aStringURI, info, aPostData); + return NS_OK; + } + + // If we still haven't been able to construct a valid URI, try to force a + // keyword match. This catches search strings with '.' or ':' in them. + if (sFixupKeywords && (aFixupFlags & FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP)) { + rv = TryKeywordFixupForURIInfo(aStringURI, info, aPostData); + } + + return rv; +} + +NS_IMETHODIMP +nsDefaultURIFixup::KeywordToURI(const nsACString& aKeyword, + nsIInputStream** aPostData, + nsIURIFixupInfo** aInfo) +{ + nsRefPtr<nsDefaultURIFixupInfo> info = new nsDefaultURIFixupInfo(aKeyword); + NS_ADDREF(*aInfo = info); + + if (aPostData) { + *aPostData = nullptr; + } + NS_ENSURE_STATE(Preferences::GetRootBranch()); + + // Strip leading "?" and leading/trailing spaces from aKeyword + nsAutoCString keyword(aKeyword); + if (StringBeginsWith(keyword, NS_LITERAL_CSTRING("?"))) { + keyword.Cut(0, 1); + } + keyword.Trim(" "); + + if (XRE_GetProcessType() == GeckoProcessType_Content) { + dom::ContentChild* contentChild = dom::ContentChild::GetSingleton(); + if (!contentChild) { + return NS_ERROR_NOT_AVAILABLE; } - return rv; -} + ipc::OptionalInputStreamParams postData; + ipc::OptionalURIParams uri; + nsAutoString providerName; + if (!contentChild->SendKeywordToURI(keyword, &providerName, &postData, + &uri)) { + return NS_ERROR_FAILURE; + } -NS_IMETHODIMP nsDefaultURIFixup::KeywordToURI(const nsACString& aKeyword, - nsIInputStream **aPostData, - nsIURIFixupInfo **aInfo) -{ - nsRefPtr<nsDefaultURIFixupInfo> info = new nsDefaultURIFixupInfo(aKeyword); - NS_ADDREF(*aInfo = info); + CopyUTF8toUTF16(keyword, info->mKeywordAsSent); + info->mKeywordProviderName = providerName; if (aPostData) { - *aPostData = nullptr; - } - NS_ENSURE_STATE(Preferences::GetRootBranch()); + nsTArray<ipc::FileDescriptor> fds; + nsCOMPtr<nsIInputStream> temp = DeserializeInputStream(postData, fds); + temp.forget(aPostData); - // Strip leading "?" and leading/trailing spaces from aKeyword - nsAutoCString keyword(aKeyword); - if (StringBeginsWith(keyword, NS_LITERAL_CSTRING("?"))) { - keyword.Cut(0, 1); + MOZ_ASSERT(fds.IsEmpty()); } - keyword.Trim(" "); - if (XRE_GetProcessType() == GeckoProcessType_Content) { - dom::ContentChild* contentChild = dom::ContentChild::GetSingleton(); - if (!contentChild) { - return NS_ERROR_NOT_AVAILABLE; - } + nsCOMPtr<nsIURI> temp = DeserializeURI(uri); + info->mPreferredURI = temp.forget(); + return NS_OK; + } - ipc::OptionalInputStreamParams postData; - ipc::OptionalURIParams uri; - nsAutoString providerName; - if (!contentChild->SendKeywordToURI(keyword, &providerName, &postData, &uri)) { - return NS_ERROR_FAILURE; - } +#ifdef MOZ_TOOLKIT_SEARCH + // Try falling back to the search service's default search engine + nsCOMPtr<nsIBrowserSearchService> searchSvc = + do_GetService("@mozilla.org/browser/search-service;1"); + if (searchSvc) { + nsCOMPtr<nsISearchEngine> defaultEngine; + searchSvc->GetDefaultEngine(getter_AddRefs(defaultEngine)); + if (defaultEngine) { + nsCOMPtr<nsISearchSubmission> submission; + nsAutoString responseType; + // We allow default search plugins to specify alternate + // parameters that are specific to keyword searches. + NS_NAMED_LITERAL_STRING(mozKeywordSearch, + "application/x-moz-keywordsearch"); + bool supportsResponseType = false; + defaultEngine->SupportsResponseType(mozKeywordSearch, + &supportsResponseType); + if (supportsResponseType) { + responseType.Assign(mozKeywordSearch); + } - CopyUTF8toUTF16(keyword, info->mKeywordAsSent); - info->mKeywordProviderName = providerName; + NS_ConvertUTF8toUTF16 keywordW(keyword); + defaultEngine->GetSubmission(keywordW, + responseType, + NS_LITERAL_STRING("keyword"), + getter_AddRefs(submission)); + if (submission) { + nsCOMPtr<nsIInputStream> postData; + submission->GetPostData(getter_AddRefs(postData)); if (aPostData) { - nsTArray<ipc::FileDescriptor> fds; - nsCOMPtr<nsIInputStream> temp = DeserializeInputStream(postData, fds); - temp.forget(aPostData); - - MOZ_ASSERT(fds.IsEmpty()); + postData.forget(aPostData); + } else if (postData) { + // The submission specifies POST data (i.e. the search + // engine's "method" is POST), but our caller didn't allow + // passing post data back. No point passing back a URL that + // won't load properly. + return NS_ERROR_FAILURE; } - nsCOMPtr<nsIURI> temp = DeserializeURI(uri); - info->mPreferredURI = temp.forget(); - return NS_OK; + defaultEngine->GetName(info->mKeywordProviderName); + info->mKeywordAsSent = keywordW; + return submission->GetUri(getter_AddRefs(info->mPreferredURI)); + } } - -#ifdef MOZ_TOOLKIT_SEARCH - // Try falling back to the search service's default search engine - nsCOMPtr<nsIBrowserSearchService> searchSvc = do_GetService("@mozilla.org/browser/search-service;1"); - if (searchSvc) { - nsCOMPtr<nsISearchEngine> defaultEngine; - searchSvc->GetDefaultEngine(getter_AddRefs(defaultEngine)); - if (defaultEngine) { - nsCOMPtr<nsISearchSubmission> submission; - nsAutoString responseType; - // We allow default search plugins to specify alternate - // parameters that are specific to keyword searches. - NS_NAMED_LITERAL_STRING(mozKeywordSearch, "application/x-moz-keywordsearch"); - bool supportsResponseType = false; - defaultEngine->SupportsResponseType(mozKeywordSearch, &supportsResponseType); - if (supportsResponseType) { - responseType.Assign(mozKeywordSearch); - } - - NS_ConvertUTF8toUTF16 keywordW(keyword); - defaultEngine->GetSubmission(keywordW, - responseType, - NS_LITERAL_STRING("keyword"), - getter_AddRefs(submission)); - - if (submission) { - nsCOMPtr<nsIInputStream> postData; - submission->GetPostData(getter_AddRefs(postData)); - if (aPostData) { - postData.forget(aPostData); - } else if (postData) { - // The submission specifies POST data (i.e. the search - // engine's "method" is POST), but our caller didn't allow - // passing post data back. No point passing back a URL that - // won't load properly. - return NS_ERROR_FAILURE; - } - - defaultEngine->GetName(info->mKeywordProviderName); - info->mKeywordAsSent = keywordW; - return submission->GetUri(getter_AddRefs(info->mPreferredURI)); - } - } - } + } #endif - // out of options - return NS_ERROR_NOT_AVAILABLE; + // out of options + return NS_ERROR_NOT_AVAILABLE; } // Helper to deal with passing around uri fixup stuff nsresult -nsDefaultURIFixup::TryKeywordFixupForURIInfo(const nsACString & aURIString, +nsDefaultURIFixup::TryKeywordFixupForURIInfo(const nsACString& aURIString, nsDefaultURIFixupInfo* aFixupInfo, - nsIInputStream **aPostData) + nsIInputStream** aPostData) { - nsCOMPtr<nsIURIFixupInfo> keywordInfo; - nsresult rv = KeywordToURI(aURIString, aPostData, getter_AddRefs(keywordInfo)); - if (NS_SUCCEEDED(rv)) { - keywordInfo->GetKeywordProviderName(aFixupInfo->mKeywordProviderName); - keywordInfo->GetKeywordAsSent(aFixupInfo->mKeywordAsSent); - keywordInfo->GetPreferredURI(getter_AddRefs(aFixupInfo->mPreferredURI)); - } - return rv; + nsCOMPtr<nsIURIFixupInfo> keywordInfo; + nsresult rv = KeywordToURI(aURIString, aPostData, + getter_AddRefs(keywordInfo)); + if (NS_SUCCEEDED(rv)) { + keywordInfo->GetKeywordProviderName(aFixupInfo->mKeywordProviderName); + keywordInfo->GetKeywordAsSent(aFixupInfo->mKeywordAsSent); + keywordInfo->GetPreferredURI(getter_AddRefs(aFixupInfo->mPreferredURI)); + } + return rv; } -bool nsDefaultURIFixup::MakeAlternateURI(nsIURI *aURI) +bool +nsDefaultURIFixup::MakeAlternateURI(nsIURI* aURI) { - if (!Preferences::GetRootBranch()) - { - return false; - } - if (!Preferences::GetBool("browser.fixup.alternate.enabled", true)) - { - return false; - } + if (!Preferences::GetRootBranch()) { + return false; + } + if (!Preferences::GetBool("browser.fixup.alternate.enabled", true)) { + return false; + } - // Code only works for http. Not for any other protocol including https! - bool isHttp = false; - aURI->SchemeIs("http", &isHttp); - if (!isHttp) { - return false; - } + // Code only works for http. Not for any other protocol including https! + bool isHttp = false; + aURI->SchemeIs("http", &isHttp); + if (!isHttp) { + return false; + } - // Security - URLs with user / password info should NOT be fixed up - nsAutoCString userpass; - aURI->GetUserPass(userpass); - if (!userpass.IsEmpty()) { - return false; - } + // Security - URLs with user / password info should NOT be fixed up + nsAutoCString userpass; + aURI->GetUserPass(userpass); + if (!userpass.IsEmpty()) { + return false; + } - nsAutoCString oldHost; - nsAutoCString newHost; - aURI->GetHost(oldHost); + nsAutoCString oldHost; + nsAutoCString newHost; + aURI->GetHost(oldHost); - // Count the dots - int32_t numDots = 0; - nsReadingIterator<char> iter; - nsReadingIterator<char> iterEnd; - oldHost.BeginReading(iter); - oldHost.EndReading(iterEnd); - while (iter != iterEnd) { - if (*iter == '.') - numDots++; - ++iter; + // Count the dots + int32_t numDots = 0; + nsReadingIterator<char> iter; + nsReadingIterator<char> iterEnd; + oldHost.BeginReading(iter); + oldHost.EndReading(iterEnd); + while (iter != iterEnd) { + if (*iter == '.') { + numDots++; } - - - // Get the prefix and suffix to stick onto the new hostname. By default these - // are www. & .com but they could be any other value, e.g. www. & .org + ++iter; + } - nsAutoCString prefix("www."); - nsAdoptingCString prefPrefix = - Preferences::GetCString("browser.fixup.alternate.prefix"); - if (prefPrefix) - { - prefix.Assign(prefPrefix); - } + // Get the prefix and suffix to stick onto the new hostname. By default these + // are www. & .com but they could be any other value, e.g. www. & .org + + nsAutoCString prefix("www."); + nsAdoptingCString prefPrefix = + Preferences::GetCString("browser.fixup.alternate.prefix"); + if (prefPrefix) { + prefix.Assign(prefPrefix); + } - nsAutoCString suffix(".com"); - nsAdoptingCString prefSuffix = - Preferences::GetCString("browser.fixup.alternate.suffix"); - if (prefSuffix) - { - suffix.Assign(prefSuffix); - } - - if (numDots == 0) - { - newHost.Assign(prefix); - newHost.Append(oldHost); - newHost.Append(suffix); + nsAutoCString suffix(".com"); + nsAdoptingCString prefSuffix = + Preferences::GetCString("browser.fixup.alternate.suffix"); + if (prefSuffix) { + suffix.Assign(prefSuffix); + } + + if (numDots == 0) { + newHost.Assign(prefix); + newHost.Append(oldHost); + newHost.Append(suffix); + } else if (numDots == 1) { + if (!prefix.IsEmpty() && + oldHost.EqualsIgnoreCase(prefix.get(), prefix.Length())) { + newHost.Assign(oldHost); + newHost.Append(suffix); + } else if (!suffix.IsEmpty()) { + newHost.Assign(prefix); + newHost.Append(oldHost); + } else { + // Do nothing + return false; } - else if (numDots == 1) - { - if (!prefix.IsEmpty() && - oldHost.EqualsIgnoreCase(prefix.get(), prefix.Length())) { - newHost.Assign(oldHost); - newHost.Append(suffix); - } - else if (!suffix.IsEmpty()) { - newHost.Assign(prefix); - newHost.Append(oldHost); - } - else - { - // Do nothing - return false; - } - } - else - { - // Do nothing - return false; - } + } else { + // Do nothing + return false; + } - if (newHost.IsEmpty()) { - return false; - } + if (newHost.IsEmpty()) { + return false; + } - // Assign the new host string over the old one - aURI->SetHost(newHost); - return true; + // Assign the new host string over the old one + aURI->SetHost(newHost); + return true; } /** * Check if the host name starts with ftp\d*\. and it's not directly followed * by the tld. */ -bool nsDefaultURIFixup::IsLikelyFTP(const nsCString &aHostSpec) +bool +nsDefaultURIFixup::IsLikelyFTP(const nsCString& aHostSpec) { - bool likelyFTP = false; - if (aHostSpec.EqualsIgnoreCase("ftp", 3)) { - nsACString::const_iterator iter; - nsACString::const_iterator end; - aHostSpec.BeginReading(iter); - aHostSpec.EndReading(end); - iter.advance(3); // move past the "ftp" part + bool likelyFTP = false; + if (aHostSpec.EqualsIgnoreCase("ftp", 3)) { + nsACString::const_iterator iter; + nsACString::const_iterator end; + aHostSpec.BeginReading(iter); + aHostSpec.EndReading(end); + iter.advance(3); // move past the "ftp" part - while (iter != end) - { - if (*iter == '.') { - // now make sure the name has at least one more dot in it - ++iter; - while (iter != end) - { - if (*iter == '.') { - likelyFTP = true; - break; - } - ++iter; - } - break; - } - else if (!nsCRT::IsAsciiDigit(*iter)) { - break; - } - ++iter; + while (iter != end) { + if (*iter == '.') { + // now make sure the name has at least one more dot in it + ++iter; + while (iter != end) { + if (*iter == '.') { + likelyFTP = true; + break; + } + ++iter; } + break; + } else if (!nsCRT::IsAsciiDigit(*iter)) { + break; + } + ++iter; } - return likelyFTP; + } + return likelyFTP; } -nsresult nsDefaultURIFixup::FileURIFixup(const nsACString& aStringURI, - nsIURI** aURI) +nsresult +nsDefaultURIFixup::FileURIFixup(const nsACString& aStringURI, nsIURI** aURI) { - nsAutoCString uriSpecOut; + nsAutoCString uriSpecOut; - nsresult rv = ConvertFileToStringURI(aStringURI, uriSpecOut); - if (NS_SUCCEEDED(rv)) - { - // if this is file url, uriSpecOut is already in FS charset - if(NS_SUCCEEDED(NS_NewURI(aURI, uriSpecOut.get(), nullptr))) - return NS_OK; - } - return NS_ERROR_FAILURE; + nsresult rv = ConvertFileToStringURI(aStringURI, uriSpecOut); + if (NS_SUCCEEDED(rv)) { + // if this is file url, uriSpecOut is already in FS charset + if (NS_SUCCEEDED(NS_NewURI(aURI, uriSpecOut.get(), nullptr))) { + return NS_OK; + } + } + return NS_ERROR_FAILURE; } -nsresult nsDefaultURIFixup::ConvertFileToStringURI(const nsACString& aIn, - nsCString& aOut) +nsresult +nsDefaultURIFixup::ConvertFileToStringURI(const nsACString& aIn, + nsCString& aResult) { - bool attemptFixup = false; + bool attemptFixup = false; #if defined(XP_WIN) - // Check for \ in the url-string or just a drive (PC) - if(kNotFound != aIn.FindChar('\\') || - (aIn.Length() == 2 && (aIn.Last() == ':' || aIn.Last() == '|'))) - { - attemptFixup = true; - } + // Check for \ in the url-string or just a drive (PC) + if (kNotFound != aIn.FindChar('\\') || + (aIn.Length() == 2 && (aIn.Last() == ':' || aIn.Last() == '|'))) { + attemptFixup = true; + } #elif defined(XP_UNIX) - // Check if it starts with / (UNIX) - if(aIn.First() == '/') - { - attemptFixup = true; - } + // Check if it starts with / (UNIX) + if (aIn.First() == '/') { + attemptFixup = true; + } #else - // Do nothing (All others for now) + // Do nothing (All others for now) #endif - if (attemptFixup) - { - // Test if this is a valid path by trying to create a local file - // object. The URL of that is returned if successful. + if (attemptFixup) { + // Test if this is a valid path by trying to create a local file + // object. The URL of that is returned if successful. - // NOTE: Please be sure to check that the call to NS_NewLocalFile - // rejects bad file paths when using this code on a new - // platform. + // NOTE: Please be sure to check that the call to NS_NewLocalFile + // rejects bad file paths when using this code on a new + // platform. - nsCOMPtr<nsIFile> filePath; - nsresult rv; + nsCOMPtr<nsIFile> filePath; + nsresult rv; - // this is not the real fix but a temporary fix - // in order to really fix the problem, we need to change the - // nsICmdLineService interface to use wstring to pass paramenters - // instead of string since path name and other argument could be - // in non ascii.(see bug 87127) Since it is too risky to make interface change right - // now, we decide not to do so now. - // Therefore, the aIn we receive here maybe already in damage form - // (e.g. treat every bytes as ISO-8859-1 and cast up to char16_t - // while the real data could be in file system charset ) - // we choice the following logic which will work for most of the case. - // Case will still failed only if it meet ALL the following condiction: - // 1. running on CJK, Russian, or Greek system, and - // 2. user type it from URL bar - // 3. the file name contains character in the range of - // U+00A1-U+00FF but encode as different code point in file - // system charset (e.g. ACP on window)- this is very rare case - // We should remove this logic and convert to File system charset here - // once we change nsICmdLineService to use wstring and ensure - // all the Unicode data come in is correctly converted. - // XXXbz nsICmdLineService doesn't hand back unicode, so in some cases - // what we have is actually a "utf8" version of a "utf16" string that's - // actually byte-expanded native-encoding data. Someone upstream needs - // to stop using AssignWithConversion and do things correctly. See bug - // 58866 for what happens if we remove this - // PossiblyByteExpandedFileName check. - NS_ConvertUTF8toUTF16 in(aIn); - if (PossiblyByteExpandedFileName(in)) { - // removes high byte - rv = NS_NewNativeLocalFile(NS_LossyConvertUTF16toASCII(in), false, getter_AddRefs(filePath)); - } - else { - // input is unicode - rv = NS_NewLocalFile(in, false, getter_AddRefs(filePath)); - } - - if (NS_SUCCEEDED(rv)) - { - NS_GetURLSpecFromFile(filePath, aOut); - return NS_OK; - } + // this is not the real fix but a temporary fix + // in order to really fix the problem, we need to change the + // nsICmdLineService interface to use wstring to pass paramenters + // instead of string since path name and other argument could be + // in non ascii.(see bug 87127) Since it is too risky to make interface + // change right now, we decide not to do so now. + // Therefore, the aIn we receive here maybe already in damage form + // (e.g. treat every bytes as ISO-8859-1 and cast up to char16_t + // while the real data could be in file system charset ) + // we choice the following logic which will work for most of the case. + // Case will still failed only if it meet ALL the following condiction: + // 1. running on CJK, Russian, or Greek system, and + // 2. user type it from URL bar + // 3. the file name contains character in the range of + // U+00A1-U+00FF but encode as different code point in file + // system charset (e.g. ACP on window)- this is very rare case + // We should remove this logic and convert to File system charset here + // once we change nsICmdLineService to use wstring and ensure + // all the Unicode data come in is correctly converted. + // XXXbz nsICmdLineService doesn't hand back unicode, so in some cases + // what we have is actually a "utf8" version of a "utf16" string that's + // actually byte-expanded native-encoding data. Someone upstream needs + // to stop using AssignWithConversion and do things correctly. See bug + // 58866 for what happens if we remove this + // PossiblyByteExpandedFileName check. + NS_ConvertUTF8toUTF16 in(aIn); + if (PossiblyByteExpandedFileName(in)) { + // removes high byte + rv = NS_NewNativeLocalFile(NS_LossyConvertUTF16toASCII(in), false, + getter_AddRefs(filePath)); + } else { + // input is unicode + rv = NS_NewLocalFile(in, false, getter_AddRefs(filePath)); } - return NS_ERROR_FAILURE; + if (NS_SUCCEEDED(rv)) { + NS_GetURLSpecFromFile(filePath, aResult); + return NS_OK; + } + } + + return NS_ERROR_FAILURE; } - nsresult -nsDefaultURIFixup::FixupURIProtocol(const nsACString & aURIString, +nsDefaultURIFixup::FixupURIProtocol(const nsACString& aURIString, nsDefaultURIFixupInfo* aFixupInfo, nsIURI** aURI) { - nsAutoCString uriString(aURIString); - *aURI = nullptr; + nsAutoCString uriString(aURIString); + *aURI = nullptr; - // Add ftp:// or http:// to front of url if it has no spec - // - // Should fix: - // - // no-scheme.com - // ftp.no-scheme.com - // ftp4.no-scheme.com - // no-scheme.com/query?foo=http://www.foo.com - // - int32_t schemeDelim = uriString.Find("://",0); - int32_t firstDelim = uriString.FindCharInSet("/:"); - if (schemeDelim <= 0 || - (firstDelim != -1 && schemeDelim > firstDelim)) { - // find host name - int32_t hostPos = uriString.FindCharInSet("/:?#"); - if (hostPos == -1) - hostPos = uriString.Length(); + // Add ftp:// or http:// to front of url if it has no spec + // + // Should fix: + // + // no-scheme.com + // ftp.no-scheme.com + // ftp4.no-scheme.com + // no-scheme.com/query?foo=http://www.foo.com + // + int32_t schemeDelim = uriString.Find("://", 0); + int32_t firstDelim = uriString.FindCharInSet("/:"); + if (schemeDelim <= 0 || + (firstDelim != -1 && schemeDelim > firstDelim)) { + // find host name + int32_t hostPos = uriString.FindCharInSet("/:?#"); + if (hostPos == -1) { + hostPos = uriString.Length(); + } - // extract host name - nsAutoCString hostSpec; - uriString.Left(hostSpec, hostPos); + // extract host name + nsAutoCString hostSpec; + uriString.Left(hostSpec, hostPos); - // insert url spec corresponding to host name - if (IsLikelyFTP(hostSpec)) - uriString.InsertLiteral("ftp://", 0); - else - uriString.InsertLiteral("http://", 0); - aFixupInfo->mFixupChangedProtocol = true; - } // end if checkprotocol + // insert url spec corresponding to host name + if (IsLikelyFTP(hostSpec)) { + uriString.InsertLiteral("ftp://", 0); + } else { + uriString.InsertLiteral("http://", 0); + } + aFixupInfo->mFixupChangedProtocol = true; + } // end if checkprotocol - return NS_NewURI(aURI, uriString, nullptr); + return NS_NewURI(aURI, uriString, nullptr); } - -bool nsDefaultURIFixup::PossiblyHostPortUrl(const nsACString &aUrl) +bool +nsDefaultURIFixup::PossiblyHostPortUrl(const nsACString& aUrl) { - // Oh dear, the protocol is invalid. Test if the protocol might - // actually be a url without a protocol: - // - // http://www.faqs.org/rfcs/rfc1738.html - // http://www.faqs.org/rfcs/rfc2396.html - // - // e.g. Anything of the form: - // - // <hostname>:<port> or - // <hostname>:<port>/ - // - // Where <hostname> is a string of alphanumeric characters and dashes - // separated by dots. - // and <port> is a 5 or less digits. This actually breaks the rfc2396 - // definition of a scheme which allows dots in schemes. - // - // Note: - // People expecting this to work with - // <user>:<password>@<host>:<port>/<url-path> will be disappointed! - // - // Note: Parser could be a lot tighter, tossing out silly hostnames - // such as those containing consecutive dots and so on. - - // Read the hostname which should of the form - // [a-zA-Z0-9\-]+(\.[a-zA-Z0-9\-]+)*: + // Oh dear, the protocol is invalid. Test if the protocol might + // actually be a url without a protocol: + // + // http://www.faqs.org/rfcs/rfc1738.html + // http://www.faqs.org/rfcs/rfc2396.html + // + // e.g. Anything of the form: + // + // <hostname>:<port> or + // <hostname>:<port>/ + // + // Where <hostname> is a string of alphanumeric characters and dashes + // separated by dots. + // and <port> is a 5 or less digits. This actually breaks the rfc2396 + // definition of a scheme which allows dots in schemes. + // + // Note: + // People expecting this to work with + // <user>:<password>@<host>:<port>/<url-path> will be disappointed! + // + // Note: Parser could be a lot tighter, tossing out silly hostnames + // such as those containing consecutive dots and so on. - nsACString::const_iterator iterBegin; - nsACString::const_iterator iterEnd; - aUrl.BeginReading(iterBegin); - aUrl.EndReading(iterEnd); - nsACString::const_iterator iter = iterBegin; + // Read the hostname which should of the form + // [a-zA-Z0-9\-]+(\.[a-zA-Z0-9\-]+)*: + + nsACString::const_iterator iterBegin; + nsACString::const_iterator iterEnd; + aUrl.BeginReading(iterBegin); + aUrl.EndReading(iterEnd); + nsACString::const_iterator iter = iterBegin; - while (iter != iterEnd) - { - uint32_t chunkSize = 0; - // Parse a chunk of the address - while (iter != iterEnd && - (*iter == '-' || - nsCRT::IsAsciiAlpha(*iter) || - nsCRT::IsAsciiDigit(*iter))) - { - ++chunkSize; - ++iter; - } - if (chunkSize == 0 || iter == iterEnd) - { - return false; - } - if (*iter == ':') - { - // Go onto checking the for the digits - break; - } - if (*iter != '.') - { - // Whatever it is, it ain't a hostname! - return false; - } - ++iter; + while (iter != iterEnd) { + uint32_t chunkSize = 0; + // Parse a chunk of the address + while (iter != iterEnd && + (*iter == '-' || + nsCRT::IsAsciiAlpha(*iter) || + nsCRT::IsAsciiDigit(*iter))) { + ++chunkSize; + ++iter; } - if (iter == iterEnd) - { - // No point continuing since there is no colon - return false; + if (chunkSize == 0 || iter == iterEnd) { + return false; + } + if (*iter == ':') { + // Go onto checking the for the digits + break; + } + if (*iter != '.') { + // Whatever it is, it ain't a hostname! + return false; } ++iter; + } + if (iter == iterEnd) { + // No point continuing since there is no colon + return false; + } + ++iter; - // Count the number of digits after the colon and before the - // next forward slash (or end of string) + // Count the number of digits after the colon and before the + // next forward slash (or end of string) - uint32_t digitCount = 0; - while (iter != iterEnd && digitCount <= 5) - { - if (nsCRT::IsAsciiDigit(*iter)) - { - digitCount++; - } - else if (*iter == '/') - { - break; - } - else - { - // Whatever it is, it ain't a port! - return false; - } - ++iter; + uint32_t digitCount = 0; + while (iter != iterEnd && digitCount <= 5) { + if (nsCRT::IsAsciiDigit(*iter)) { + digitCount++; + } else if (*iter == '/') { + break; + } else { + // Whatever it is, it ain't a port! + return false; } - if (digitCount == 0 || digitCount > 5) - { - // No digits or more digits than a port would have. - return false; - } + ++iter; + } + if (digitCount == 0 || digitCount > 5) { + // No digits or more digits than a port would have. + return false; + } - // Yes, it's possibly a host:port url - return true; + // Yes, it's possibly a host:port url + return true; } -bool nsDefaultURIFixup::PossiblyByteExpandedFileName(const nsAString& aIn) +bool +nsDefaultURIFixup::PossiblyByteExpandedFileName(const nsAString& aIn) { - // XXXXX HACK XXXXX : please don't copy this code. - // There are cases where aIn contains the locale byte chars padded to short - // (thus the name "ByteExpanded"); whereas other cases - // have proper Unicode code points. - // This is a temporary fix. Please refer to 58866, 86948 + // XXXXX HACK XXXXX : please don't copy this code. + // There are cases where aIn contains the locale byte chars padded to short + // (thus the name "ByteExpanded"); whereas other cases + // have proper Unicode code points. + // This is a temporary fix. Please refer to 58866, 86948 - nsReadingIterator<char16_t> iter; - nsReadingIterator<char16_t> iterEnd; - aIn.BeginReading(iter); - aIn.EndReading(iterEnd); - while (iter != iterEnd) - { - if (*iter >= 0x0080 && *iter <= 0x00FF) - return true; - ++iter; + nsReadingIterator<char16_t> iter; + nsReadingIterator<char16_t> iterEnd; + aIn.BeginReading(iter); + aIn.EndReading(iterEnd); + while (iter != iterEnd) { + if (*iter >= 0x0080 && *iter <= 0x00FF) { + return true; } - return false; + ++iter; + } + return false; } nsresult -nsDefaultURIFixup::KeywordURIFixup(const nsACString & aURIString, +nsDefaultURIFixup::KeywordURIFixup(const nsACString& aURIString, nsDefaultURIFixupInfo* aFixupInfo, - nsIInputStream **aPostData) + nsIInputStream** aPostData) { - // These are keyword formatted strings - // "what is mozilla" - // "what is mozilla?" - // "docshell site:mozilla.org" - has no dot/colon in the first space-separated substring - // "?mozilla" - anything that begins with a question mark - // "?site:mozilla.org docshell" - // Things that have a quote before the first dot/colon - // "mozilla" - checked against a whitelist to see if it's a host or not - // ".mozilla", "mozilla." - ditto + // These are keyword formatted strings + // "what is mozilla" + // "what is mozilla?" + // "docshell site:mozilla.org" - has no dot/colon in the first space-separated substring + // "?mozilla" - anything that begins with a question mark + // "?site:mozilla.org docshell" + // Things that have a quote before the first dot/colon + // "mozilla" - checked against a whitelist to see if it's a host or not + // ".mozilla", "mozilla." - ditto - // These are not keyword formatted strings - // "www.blah.com" - first space-separated substring contains a dot, doesn't start with "?" - // "www.blah.com stuff" - // "nonQualifiedHost:80" - first space-separated substring contains a colon, doesn't start with "?" - // "nonQualifiedHost:80 args" - // "nonQualifiedHost?" - // "nonQualifiedHost?args" - // "nonQualifiedHost?some args" - // "blah.com." + // These are not keyword formatted strings + // "www.blah.com" - first space-separated substring contains a dot, doesn't start with "?" + // "www.blah.com stuff" + // "nonQualifiedHost:80" - first space-separated substring contains a colon, doesn't start with "?" + // "nonQualifiedHost:80 args" + // "nonQualifiedHost?" + // "nonQualifiedHost?args" + // "nonQualifiedHost?some args" + // "blah.com." - // Note: uint32_t(kNotFound) is greater than any actual location - // in practice. So if we cast all locations to uint32_t, then a < - // b guarantees that either b is kNotFound and a is found, or both - // are found and a found before b. + // Note: uint32_t(kNotFound) is greater than any actual location + // in practice. So if we cast all locations to uint32_t, then a < + // b guarantees that either b is kNotFound and a is found, or both + // are found and a found before b. - uint32_t firstDotLoc = uint32_t(kNotFound); - uint32_t lastDotLoc = uint32_t(kNotFound); - uint32_t firstColonLoc = uint32_t(kNotFound); - uint32_t firstQuoteLoc = uint32_t(kNotFound); - uint32_t firstSpaceLoc = uint32_t(kNotFound); - uint32_t firstQMarkLoc = uint32_t(kNotFound); - uint32_t lastLSBracketLoc = uint32_t(kNotFound); - uint32_t lastSlashLoc = uint32_t(kNotFound); - uint32_t pos = 0; - uint32_t foundDots = 0; - uint32_t foundColons = 0; - uint32_t foundDigits = 0; - uint32_t foundRSBrackets = 0; - bool looksLikeIpv6 = true; - bool hasAsciiAlpha = false; + uint32_t firstDotLoc = uint32_t(kNotFound); + uint32_t lastDotLoc = uint32_t(kNotFound); + uint32_t firstColonLoc = uint32_t(kNotFound); + uint32_t firstQuoteLoc = uint32_t(kNotFound); + uint32_t firstSpaceLoc = uint32_t(kNotFound); + uint32_t firstQMarkLoc = uint32_t(kNotFound); + uint32_t lastLSBracketLoc = uint32_t(kNotFound); + uint32_t lastSlashLoc = uint32_t(kNotFound); + uint32_t pos = 0; + uint32_t foundDots = 0; + uint32_t foundColons = 0; + uint32_t foundDigits = 0; + uint32_t foundRSBrackets = 0; + bool looksLikeIpv6 = true; + bool hasAsciiAlpha = false; - nsACString::const_iterator iterBegin; - nsACString::const_iterator iterEnd; - aURIString.BeginReading(iterBegin); - aURIString.EndReading(iterEnd); - nsACString::const_iterator iter = iterBegin; + nsACString::const_iterator iterBegin; + nsACString::const_iterator iterEnd; + aURIString.BeginReading(iterBegin); + aURIString.EndReading(iterEnd); + nsACString::const_iterator iter = iterBegin; - while (iter != iterEnd) { - if (pos >= 1 && foundRSBrackets == 0) { - if (!(lastLSBracketLoc == 0 && - (*iter == ':' || - *iter == '.' || - *iter == ']' || - (*iter >= 'a' && *iter <= 'f') || - (*iter >= 'A' && *iter <= 'F') || - nsCRT::IsAsciiDigit(*iter)))) { - looksLikeIpv6 = false; - } - } - if (*iter == '.') { - ++foundDots; - lastDotLoc = pos; - if (firstDotLoc == uint32_t(kNotFound)) { - firstDotLoc = pos; - } - } else if (*iter == ':') { - ++foundColons; - if (firstColonLoc == uint32_t(kNotFound)) { - firstColonLoc = pos; - } - } else if (*iter == ' ' && firstSpaceLoc == uint32_t(kNotFound)) { - firstSpaceLoc = pos; - } else if (*iter == '?' && firstQMarkLoc == uint32_t(kNotFound)) { - firstQMarkLoc = pos; - } else if ((*iter == '\'' || *iter == '"') && firstQuoteLoc == uint32_t(kNotFound)) { - firstQuoteLoc = pos; - } else if (*iter == '[') { - lastLSBracketLoc = pos; - } else if (*iter == ']') { - foundRSBrackets++; - } else if (*iter == '/') { - lastSlashLoc = pos; - } else if (nsCRT::IsAsciiAlpha(*iter)) { - hasAsciiAlpha = true; - } else if (nsCRT::IsAsciiDigit(*iter)) { - ++foundDigits; - } - - pos++; - iter++; + while (iter != iterEnd) { + if (pos >= 1 && foundRSBrackets == 0) { + if (!(lastLSBracketLoc == 0 && + (*iter == ':' || + *iter == '.' || + *iter == ']' || + (*iter >= 'a' && *iter <= 'f') || + (*iter >= 'A' && *iter <= 'F') || + nsCRT::IsAsciiDigit(*iter)))) { + looksLikeIpv6 = false; + } } - - if (lastLSBracketLoc > 0 || foundRSBrackets != 1) { - looksLikeIpv6 = false; + if (*iter == '.') { + ++foundDots; + lastDotLoc = pos; + if (firstDotLoc == uint32_t(kNotFound)) { + firstDotLoc = pos; + } + } else if (*iter == ':') { + ++foundColons; + if (firstColonLoc == uint32_t(kNotFound)) { + firstColonLoc = pos; + } + } else if (*iter == ' ' && firstSpaceLoc == uint32_t(kNotFound)) { + firstSpaceLoc = pos; + } else if (*iter == '?' && firstQMarkLoc == uint32_t(kNotFound)) { + firstQMarkLoc = pos; + } else if ((*iter == '\'' || *iter == '"') && + firstQuoteLoc == uint32_t(kNotFound)) { + firstQuoteLoc = pos; + } else if (*iter == '[') { + lastLSBracketLoc = pos; + } else if (*iter == ']') { + foundRSBrackets++; + } else if (*iter == '/') { + lastSlashLoc = pos; + } else if (nsCRT::IsAsciiAlpha(*iter)) { + hasAsciiAlpha = true; + } else if (nsCRT::IsAsciiDigit(*iter)) { + ++foundDigits; } - nsAutoCString asciiHost; - nsAutoCString host; + pos++; + iter++; + } - bool isValidAsciiHost = aFixupInfo->mFixedURI && - NS_SUCCEEDED(aFixupInfo->mFixedURI->GetAsciiHost(asciiHost)) && - !asciiHost.IsEmpty(); + if (lastLSBracketLoc > 0 || foundRSBrackets != 1) { + looksLikeIpv6 = false; + } + + nsAutoCString asciiHost; + nsAutoCString host; - bool isValidHost = aFixupInfo->mFixedURI && - NS_SUCCEEDED(aFixupInfo->mFixedURI->GetHost(host)) && - !host.IsEmpty(); + bool isValidAsciiHost = + aFixupInfo->mFixedURI && + NS_SUCCEEDED(aFixupInfo->mFixedURI->GetAsciiHost(asciiHost)) && + !asciiHost.IsEmpty(); - // If there are 2 dots and only numbers between them, an optional port number - // and a trailing slash, then don't do a keyword lookup - if (foundDots == 2 && lastSlashLoc == pos - 1 && - ((foundDots + foundDigits == pos - 1) || - (foundColons == 1 && firstColonLoc > lastDotLoc && - foundDots + foundDigits + foundColons == pos - 1))) { - return NS_OK; - } + bool isValidHost = + aFixupInfo->mFixedURI && + NS_SUCCEEDED(aFixupInfo->mFixedURI->GetHost(host)) && + !host.IsEmpty(); + + // If there are 2 dots and only numbers between them, an optional port number + // and a trailing slash, then don't do a keyword lookup + if (foundDots == 2 && lastSlashLoc == pos - 1 && + ((foundDots + foundDigits == pos - 1) || + (foundColons == 1 && firstColonLoc > lastDotLoc && + foundDots + foundDigits + foundColons == pos - 1))) { + return NS_OK; + } - uint32_t posWithNoTrailingSlash = pos; - if (lastSlashLoc == pos - 1) { - posWithNoTrailingSlash -= 1; - } - // If there are 3 dots and only numbers between them, an optional port number - // and an optional trailling slash, then don't do a keyword lookup (ipv4) - if (foundDots == 3 && - ((foundDots + foundDigits == posWithNoTrailingSlash) || - (foundColons == 1 && firstColonLoc > lastDotLoc && - foundDots + foundDigits + foundColons == posWithNoTrailingSlash))) { - return NS_OK; - } + uint32_t posWithNoTrailingSlash = pos; + if (lastSlashLoc == pos - 1) { + posWithNoTrailingSlash -= 1; + } + // If there are 3 dots and only numbers between them, an optional port number + // and an optional trailling slash, then don't do a keyword lookup (ipv4) + if (foundDots == 3 && + ((foundDots + foundDigits == posWithNoTrailingSlash) || + (foundColons == 1 && firstColonLoc > lastDotLoc && + foundDots + foundDigits + foundColons == posWithNoTrailingSlash))) { + return NS_OK; + } - // If there are only colons and only hexadecimal characters ([a-z][0-9]) - // enclosed in [], then don't do a keyword lookup - if (looksLikeIpv6) { - return NS_OK; - } + // If there are only colons and only hexadecimal characters ([a-z][0-9]) + // enclosed in [], then don't do a keyword lookup + if (looksLikeIpv6) { + return NS_OK; + } - nsresult rv = NS_OK; - // We do keyword lookups if a space or quote preceded the dot, colon - // or question mark (or if the latter is not found, or if the input starts with a question mark) - if (((firstSpaceLoc < firstDotLoc || firstQuoteLoc < firstDotLoc) && - (firstSpaceLoc < firstColonLoc || firstQuoteLoc < firstColonLoc) && - (firstSpaceLoc < firstQMarkLoc || firstQuoteLoc < firstQMarkLoc)) || firstQMarkLoc == 0) { - rv = TryKeywordFixupForURIInfo(aFixupInfo->mOriginalInput, aFixupInfo, aPostData); + nsresult rv = NS_OK; + // We do keyword lookups if a space or quote preceded the dot, colon + // or question mark (or if the latter is not found, or if the input starts + // with a question mark) + if (((firstSpaceLoc < firstDotLoc || firstQuoteLoc < firstDotLoc) && + (firstSpaceLoc < firstColonLoc || firstQuoteLoc < firstColonLoc) && + (firstSpaceLoc < firstQMarkLoc || firstQuoteLoc < firstQMarkLoc)) || + firstQMarkLoc == 0) { + rv = TryKeywordFixupForURIInfo(aFixupInfo->mOriginalInput, aFixupInfo, + aPostData); // ... or when the host is the same as asciiHost and there are no // characters from [a-z][A-Z] - } else if (isValidAsciiHost && isValidHost && !hasAsciiAlpha && - host.EqualsIgnoreCase(asciiHost.get())) { - if (!sDNSFirstForSingleWords) { - rv = TryKeywordFixupForURIInfo(aFixupInfo->mOriginalInput, aFixupInfo, aPostData); - } + } else if (isValidAsciiHost && isValidHost && !hasAsciiAlpha && + host.EqualsIgnoreCase(asciiHost.get())) { + if (!sDNSFirstForSingleWords) { + rv = TryKeywordFixupForURIInfo(aFixupInfo->mOriginalInput, aFixupInfo, + aPostData); } - // ... or if there is no question mark or colon, and there is either no - // dot, or exactly 1 and it is the first or last character of the input: - else if ((firstDotLoc == uint32_t(kNotFound) || - (foundDots == 1 && (firstDotLoc == 0 || firstDotLoc == aURIString.Length() - 1))) && - firstColonLoc == uint32_t(kNotFound) && firstQMarkLoc == uint32_t(kNotFound)) { + } + // ... or if there is no question mark or colon, and there is either no + // dot, or exactly 1 and it is the first or last character of the input: + else if ((firstDotLoc == uint32_t(kNotFound) || + (foundDots == 1 && (firstDotLoc == 0 || + firstDotLoc == aURIString.Length() - 1))) && + firstColonLoc == uint32_t(kNotFound) && + firstQMarkLoc == uint32_t(kNotFound)) { + if (isValidAsciiHost && IsDomainWhitelisted(asciiHost, firstDotLoc)) { + return NS_OK; + } - if (isValidAsciiHost && IsDomainWhitelisted(asciiHost, firstDotLoc)) { - return NS_OK; - } + // ... unless there are no dots, and a slash, and alpha characters, and + // this is a valid host: + if (firstDotLoc == uint32_t(kNotFound) && + lastSlashLoc != uint32_t(kNotFound) && + hasAsciiAlpha && isValidAsciiHost) { + return NS_OK; + } - // ... unless there are no dots, and a slash, and alpha characters, and this is a valid host: - if (firstDotLoc == uint32_t(kNotFound) && lastSlashLoc != uint32_t(kNotFound) && - hasAsciiAlpha && isValidAsciiHost) { - return NS_OK; - } - - - // If we get here, we don't have a valid URI, or we did but the - // host is not whitelisted, so we do a keyword search *anyway*: - rv = TryKeywordFixupForURIInfo(aFixupInfo->mOriginalInput, aFixupInfo, aPostData); - } - return rv; + // If we get here, we don't have a valid URI, or we did but the + // host is not whitelisted, so we do a keyword search *anyway*: + rv = TryKeywordFixupForURIInfo(aFixupInfo->mOriginalInput, aFixupInfo, + aPostData); + } + return rv; } -bool nsDefaultURIFixup::IsDomainWhitelisted(const nsAutoCString aAsciiHost, - const uint32_t aDotLoc) +bool +nsDefaultURIFixup::IsDomainWhitelisted(const nsAutoCString aAsciiHost, + const uint32_t aDotLoc) { - if (sDNSFirstForSingleWords) { - return true; - } - // Check if this domain is whitelisted as an actual - // domain (which will prevent a keyword query) - // NB: any processing of the host here should stay in sync with - // code in the front-end(s) that set the pref. - - nsAutoCString pref("browser.fixup.domainwhitelist."); + if (sDNSFirstForSingleWords) { + return true; + } + // Check if this domain is whitelisted as an actual + // domain (which will prevent a keyword query) + // NB: any processing of the host here should stay in sync with + // code in the front-end(s) that set the pref. - if (aDotLoc == aAsciiHost.Length() - 1) { - pref.Append(Substring(aAsciiHost, 0, aAsciiHost.Length() - 1)); - } else { - pref.Append(aAsciiHost); - } - - return Preferences::GetBool(pref.get(), false); -} - + nsAutoCString pref("browser.fixup.domainwhitelist."); -nsresult NS_NewURIFixup(nsIURIFixup **aURIFixup) -{ - nsDefaultURIFixup *fixup = new nsDefaultURIFixup; - if (fixup == nullptr) - { - return NS_ERROR_OUT_OF_MEMORY; - } - return fixup->QueryInterface(NS_GET_IID(nsIURIFixup), (void **) aURIFixup); + if (aDotLoc == aAsciiHost.Length() - 1) { + pref.Append(Substring(aAsciiHost, 0, aAsciiHost.Length() - 1)); + } else { + pref.Append(aAsciiHost); + } + + return Preferences::GetBool(pref.get(), false); } - /* Implementation of nsIURIFixupInfo */ NS_IMPL_ISUPPORTS(nsDefaultURIFixupInfo, nsIURIFixupInfo) -nsDefaultURIFixupInfo::nsDefaultURIFixupInfo(const nsACString& aOriginalInput): - mFixupChangedProtocol(false), - mFixupCreatedAlternateURI(false) +nsDefaultURIFixupInfo::nsDefaultURIFixupInfo(const nsACString& aOriginalInput) + : mFixupChangedProtocol(false) + , mFixupCreatedAlternateURI(false) { mOriginalInput = aOriginalInput; } - nsDefaultURIFixupInfo::~nsDefaultURIFixupInfo() { } NS_IMETHODIMP nsDefaultURIFixupInfo::GetConsumer(nsISupports** aConsumer) { - *aConsumer = mConsumer; - NS_IF_ADDREF(*aConsumer); - return NS_OK; + *aConsumer = mConsumer; + NS_IF_ADDREF(*aConsumer); + return NS_OK; } NS_IMETHODIMP nsDefaultURIFixupInfo::SetConsumer(nsISupports* aConsumer) { - mConsumer = aConsumer; - return NS_OK; + mConsumer = aConsumer; + return NS_OK; } NS_IMETHODIMP nsDefaultURIFixupInfo::GetPreferredURI(nsIURI** aPreferredURI) { - *aPreferredURI = mPreferredURI; - NS_IF_ADDREF(*aPreferredURI); - return NS_OK; + *aPreferredURI = mPreferredURI; + NS_IF_ADDREF(*aPreferredURI); + return NS_OK; } NS_IMETHODIMP nsDefaultURIFixupInfo::GetFixedURI(nsIURI** aFixedURI) { - *aFixedURI = mFixedURI; - NS_IF_ADDREF(*aFixedURI); - return NS_OK; + *aFixedURI = mFixedURI; + NS_IF_ADDREF(*aFixedURI); + return NS_OK; } NS_IMETHODIMP -nsDefaultURIFixupInfo::GetKeywordProviderName(nsAString& aOut) +nsDefaultURIFixupInfo::GetKeywordProviderName(nsAString& aResult) { - aOut = mKeywordProviderName; - return NS_OK; + aResult = mKeywordProviderName; + return NS_OK; } NS_IMETHODIMP -nsDefaultURIFixupInfo::GetKeywordAsSent(nsAString& aOut) +nsDefaultURIFixupInfo::GetKeywordAsSent(nsAString& aResult) { - aOut = mKeywordAsSent; - return NS_OK; + aResult = mKeywordAsSent; + return NS_OK; } NS_IMETHODIMP -nsDefaultURIFixupInfo::GetFixupChangedProtocol(bool* aOut) +nsDefaultURIFixupInfo::GetFixupChangedProtocol(bool* aResult) { - *aOut = mFixupChangedProtocol; - return NS_OK; + *aResult = mFixupChangedProtocol; + return NS_OK; } NS_IMETHODIMP -nsDefaultURIFixupInfo::GetFixupCreatedAlternateURI(bool* aOut) +nsDefaultURIFixupInfo::GetFixupCreatedAlternateURI(bool* aResult) { - *aOut = mFixupCreatedAlternateURI; - return NS_OK; + *aResult = mFixupCreatedAlternateURI; + return NS_OK; } NS_IMETHODIMP -nsDefaultURIFixupInfo::GetOriginalInput(nsACString& aInput) +nsDefaultURIFixupInfo::GetOriginalInput(nsACString& aResult) { - aInput = mOriginalInput; - return NS_OK; + aResult = mOriginalInput; + return NS_OK; }
--- a/docshell/base/nsDefaultURIFixup.h +++ b/docshell/base/nsDefaultURIFixup.h @@ -1,70 +1,70 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * This Source Code Form is subject to the terms of the Mozilla Public +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef NSDEFAULTURIFIXUP_H #define NSDEFAULTURIFIXUP_H #include "nsIURIFixup.h" class nsDefaultURIFixupInfo; /* Header file */ class nsDefaultURIFixup : public nsIURIFixup { public: - NS_DECL_ISUPPORTS - NS_DECL_NSIURIFIXUP + NS_DECL_ISUPPORTS + NS_DECL_NSIURIFIXUP - nsDefaultURIFixup(); + nsDefaultURIFixup(); protected: - virtual ~nsDefaultURIFixup(); + virtual ~nsDefaultURIFixup(); private: - /* additional members */ - nsresult FileURIFixup(const nsACString &aStringURI, nsIURI** aURI); - nsresult ConvertFileToStringURI(const nsACString& aIn, nsCString& aOut); - nsresult FixupURIProtocol(const nsACString& aIn, - nsDefaultURIFixupInfo* aFixupInfo, - nsIURI** aURI); - nsresult KeywordURIFixup(const nsACString &aStringURI, - nsDefaultURIFixupInfo* aFixupInfo, - nsIInputStream** aPostData); - nsresult TryKeywordFixupForURIInfo(const nsACString &aStringURI, - nsDefaultURIFixupInfo* aFixupInfo, - nsIInputStream** aPostData); - bool PossiblyByteExpandedFileName(const nsAString& aIn); - bool PossiblyHostPortUrl(const nsACString& aUrl); - bool MakeAlternateURI(nsIURI *aURI); - bool IsLikelyFTP(const nsCString& aHostSpec); - bool IsDomainWhitelisted(const nsAutoCString aAsciiHost, - const uint32_t aDotLoc); + /* additional members */ + nsresult FileURIFixup(const nsACString& aStringURI, nsIURI** aURI); + nsresult ConvertFileToStringURI(const nsACString& aIn, nsCString& aResult); + nsresult FixupURIProtocol(const nsACString& aIn, + nsDefaultURIFixupInfo* aFixupInfo, + nsIURI** aURI); + nsresult KeywordURIFixup(const nsACString& aStringURI, + nsDefaultURIFixupInfo* aFixupInfo, + nsIInputStream** aPostData); + nsresult TryKeywordFixupForURIInfo(const nsACString& aStringURI, + nsDefaultURIFixupInfo* aFixupInfo, + nsIInputStream** aPostData); + bool PossiblyByteExpandedFileName(const nsAString& aIn); + bool PossiblyHostPortUrl(const nsACString& aUrl); + bool MakeAlternateURI(nsIURI* aURI); + bool IsLikelyFTP(const nsCString& aHostSpec); + bool IsDomainWhitelisted(const nsAutoCString aAsciiHost, + const uint32_t aDotLoc); }; class nsDefaultURIFixupInfo : public nsIURIFixupInfo { public: - NS_DECL_ISUPPORTS - NS_DECL_NSIURIFIXUPINFO + NS_DECL_ISUPPORTS + NS_DECL_NSIURIFIXUPINFO - explicit nsDefaultURIFixupInfo(const nsACString& aOriginalInput); + explicit nsDefaultURIFixupInfo(const nsACString& aOriginalInput); - friend class nsDefaultURIFixup; + friend class nsDefaultURIFixup; protected: - virtual ~nsDefaultURIFixupInfo(); + virtual ~nsDefaultURIFixupInfo(); private: - nsCOMPtr<nsISupports> mConsumer; - nsCOMPtr<nsIURI> mPreferredURI; - nsCOMPtr<nsIURI> mFixedURI; - bool mFixupChangedProtocol; - bool mFixupCreatedAlternateURI; - nsString mKeywordProviderName; - nsString mKeywordAsSent; - nsAutoCString mOriginalInput; + nsCOMPtr<nsISupports> mConsumer; + nsCOMPtr<nsIURI> mPreferredURI; + nsCOMPtr<nsIURI> mFixedURI; + bool mFixupChangedProtocol; + bool mFixupCreatedAlternateURI; + nsString mKeywordProviderName; + nsString mKeywordAsSent; + nsAutoCString mOriginalInput; }; #endif
--- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -1,10 +1,10 @@ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=2 sw=2 tw=80 et: */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsDocShell.h" #include <algorithm> @@ -26,16 +26,17 @@ #include "mozilla/VisualEventTracer.h" #include "URIUtils.h" #include "nsIContent.h" #include "nsIContentInlines.h" #include "nsIDocument.h" #include "nsIDOMDocument.h" #include "nsIDOMElement.h" + #include "nsIDOMStorage.h" #include "nsIContentViewer.h" #include "nsIDocumentLoaderFactory.h" #include "nsCURILoader.h" #include "nsDocShellCID.h" #include "nsDOMCID.h" #include "nsNetUtil.h" #include "mozilla/net/ReferrerPolicy.h" @@ -225,17 +226,17 @@ static int32_t gNumberOfDocumentsLoading // Global count of existing docshells. static int32_t gDocShellCount = 0; // Global count of docshells with the private attribute set static uint32_t gNumberOfPrivateDocShells = 0; // Global reference to the URI fixup service. -nsIURIFixup *nsDocShell::sURIFixup = 0; +nsIURIFixup* nsDocShell::sURIFixup = 0; // True means we validate window targets to prevent frameset // spoofing. Initialize this to a non-bolean value so we know to check // the pref on the creation of the first docshell. static uint32_t gValidateOrigin = 0xffffffff; // Hint for native dispatch of events on how long to delay after // all documents have loaded in milliseconds before favoring normal @@ -249,24 +250,25 @@ static PRLogModuleInfo* gDocShellLog; #endif static PRLogModuleInfo* gDocShellLeakLog; #endif const char kBrandBundleURL[] = "chrome://branding/locale/brand.properties"; const char kAppstringsBundleURL[] = "chrome://global/locale/appstrings.properties"; static void -FavorPerformanceHint(bool perfOverStarvation) -{ - nsCOMPtr<nsIAppShell> appShell = do_GetService(kAppShellCID); - if (appShell) { - appShell->FavorPerformanceHint(perfOverStarvation, - Preferences::GetUint("docshell.event_starvation_delay_hint", - NS_EVENT_STARVATION_DELAY_HINT)); - } +FavorPerformanceHint(bool aPerfOverStarvation) +{ + nsCOMPtr<nsIAppShell> appShell = do_GetService(kAppShellCID); + if (appShell) { + appShell->FavorPerformanceHint( + aPerfOverStarvation, + Preferences::GetUint("docshell.event_starvation_delay_hint", + NS_EVENT_STARVATION_DELAY_HINT)); + } } //***************************************************************************** // <a ping> support //***************************************************************************** #define PREF_PINGS_ENABLED "browser.send_pings" #define PREF_PINGS_MAX_PER_LINK "browser.send_pings.max_per_link" @@ -284,163 +286,171 @@ FavorPerformanceHint(bool perfOverStarva // imposed, then we still allow for pings to cross over to different // protocols and ports for flexibility and because it is not possible to send // a ping via FTP. // // @returns // true if pings are enabled and false otherwise. // static bool -PingsEnabled(int32_t *maxPerLink, bool *requireSameHost) +PingsEnabled(int32_t* aMaxPerLink, bool* aRequireSameHost) { bool allow = Preferences::GetBool(PREF_PINGS_ENABLED, false); - *maxPerLink = 1; - *requireSameHost = true; + *aMaxPerLink = 1; + *aRequireSameHost = true; if (allow) { - Preferences::GetInt(PREF_PINGS_MAX_PER_LINK, maxPerLink); - Preferences::GetBool(PREF_PINGS_REQUIRE_SAME_HOST, requireSameHost); + Preferences::GetInt(PREF_PINGS_MAX_PER_LINK, aMaxPerLink); + Preferences::GetBool(PREF_PINGS_REQUIRE_SAME_HOST, aRequireSameHost); } return allow; } static bool -CheckPingURI(nsIURI* uri, nsIContent* content) -{ - if (!uri) +CheckPingURI(nsIURI* aURI, nsIContent* aContent) +{ + if (!aURI) { return false; + } // Check with nsIScriptSecurityManager nsCOMPtr<nsIScriptSecurityManager> ssmgr = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID); NS_ENSURE_TRUE(ssmgr, false); - nsresult rv = - ssmgr->CheckLoadURIWithPrincipal(content->NodePrincipal(), uri, - nsIScriptSecurityManager::STANDARD); + nsresult rv = ssmgr->CheckLoadURIWithPrincipal( + aContent->NodePrincipal(), aURI, nsIScriptSecurityManager::STANDARD); if (NS_FAILED(rv)) { return false; } // Ignore non-HTTP(S) bool match; - if ((NS_FAILED(uri->SchemeIs("http", &match)) || !match) && - (NS_FAILED(uri->SchemeIs("https", &match)) || !match)) { + if ((NS_FAILED(aURI->SchemeIs("http", &match)) || !match) && + (NS_FAILED(aURI->SchemeIs("https", &match)) || !match)) { return false; } // Check with contentpolicy int16_t shouldLoad = nsIContentPolicy::ACCEPT; rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_PING, - uri, - content->NodePrincipal(), - content, + aURI, + aContent->NodePrincipal(), + aContent, EmptyCString(), // mime hint - nullptr, //extra + nullptr, // extra &shouldLoad); return NS_SUCCEEDED(rv) && NS_CP_ACCEPTED(shouldLoad); } -typedef void (* ForEachPingCallback)(void *closure, nsIContent *content, - nsIURI *uri, nsIIOService *ios); +typedef void (*ForEachPingCallback)(void* closure, nsIContent* content, + nsIURI* uri, nsIIOService* ios); static bool IsElementAnchor(nsIContent* aContent) { // Make sure we are dealing with either an <A> or <AREA> element in the HTML // or XHTML namespace. if (!aContent->IsHTML()) { return false; } nsIAtom* nameAtom = aContent->Tag(); return nameAtom == nsGkAtoms::a || nameAtom == nsGkAtoms::area; } static void -ForEachPing(nsIContent *content, ForEachPingCallback callback, void *closure) +ForEachPing(nsIContent* aContent, ForEachPingCallback aCallback, void* aClosure) { // NOTE: Using nsIDOMHTMLAnchorElement::GetPing isn't really worth it here // since we'd still need to parse the resulting string. Instead, we // just parse the raw attribute. It might be nice if the content node // implemented an interface that exposed an enumeration of nsIURIs. // Make sure we are dealing with either an <A> or <AREA> element in the HTML // or XHTML namespace. - if (!IsElementAnchor(content)) + if (!IsElementAnchor(aContent)) { return; + } nsCOMPtr<nsIAtom> pingAtom = do_GetAtom("ping"); - if (!pingAtom) + if (!pingAtom) { return; + } nsAutoString value; - content->GetAttr(kNameSpaceID_None, pingAtom, value); - if (value.IsEmpty()) + aContent->GetAttr(kNameSpaceID_None, pingAtom, value); + if (value.IsEmpty()) { return; + } nsCOMPtr<nsIIOService> ios = do_GetIOService(); - if (!ios) + if (!ios) { return; - - nsIDocument *doc = content->OwnerDoc(); + } + + nsIDocument* doc = aContent->OwnerDoc(); nsWhitespaceTokenizer tokenizer(value); while (tokenizer.hasMoreTokens()) { - nsCOMPtr<nsIURI> uri, baseURI = content->GetBaseURI(); + nsCOMPtr<nsIURI> uri, baseURI = aContent->GetBaseURI(); ios->NewURI(NS_ConvertUTF16toUTF8(tokenizer.nextToken()), doc->GetDocumentCharacterSet().get(), baseURI, getter_AddRefs(uri)); - if (CheckPingURI(uri, content)) { - callback(closure, content, uri, ios); + if (CheckPingURI(uri, aContent)) { + aCallback(aClosure, aContent, uri, ios); } } } //---------------------------------------------------------------------- // We wait this many milliseconds before killing the ping channel... #define PING_TIMEOUT 10000 static void -OnPingTimeout(nsITimer *timer, void *closure) -{ - nsILoadGroup *loadGroup = static_cast<nsILoadGroup *>(closure); - if (loadGroup) +OnPingTimeout(nsITimer* aTimer, void* aClosure) +{ + nsILoadGroup* loadGroup = static_cast<nsILoadGroup*>(aClosure); + if (loadGroup) { loadGroup->Cancel(NS_ERROR_ABORT); + } } // Check to see if two URIs have the same host or not static bool -IsSameHost(nsIURI *uri1, nsIURI *uri2) +IsSameHost(nsIURI* aUri1, nsIURI* aUri2) { nsAutoCString host1, host2; - uri1->GetAsciiHost(host1); - uri2->GetAsciiHost(host2); + aUri1->GetAsciiHost(host1); + aUri2->GetAsciiHost(host2); return host1.Equals(host2); } -class nsPingListener MOZ_FINAL : public nsIStreamListener - , public nsIInterfaceRequestor - , public nsIChannelEventSink +class nsPingListener MOZ_FINAL + : public nsIStreamListener + , public nsIInterfaceRequestor + , public nsIChannelEventSink { public: NS_DECL_ISUPPORTS NS_DECL_NSIREQUESTOBSERVER NS_DECL_NSISTREAMLISTENER NS_DECL_NSIINTERFACEREQUESTOR NS_DECL_NSICHANNELEVENTSINK - nsPingListener(bool requireSameHost, nsIContent* content, nsILoadGroup* loadGroup) - : mRequireSameHost(requireSameHost), - mContent(content), - mLoadGroup(loadGroup) - {} + nsPingListener(bool aRequireSameHost, nsIContent* aContent, + nsILoadGroup* aLoadGroup) + : mRequireSameHost(aRequireSameHost) + , mContent(aContent) + , mLoadGroup(aLoadGroup) + { + } nsresult StartTimeout(); private: ~nsPingListener(); bool mRequireSameHost; nsCOMPtr<nsIContent> mContent; @@ -473,204 +483,218 @@ nsPingListener::StartTimeout() return NS_OK; } } return NS_ERROR_OUT_OF_MEMORY; } NS_IMETHODIMP -nsPingListener::OnStartRequest(nsIRequest *request, nsISupports *context) -{ - return NS_OK; -} - -NS_IMETHODIMP -nsPingListener::OnDataAvailable(nsIRequest *request, nsISupports *context, - nsIInputStream *stream, uint64_t offset, - uint32_t count) +nsPingListener::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) +{ + return NS_OK; +} + +NS_IMETHODIMP +nsPingListener::OnDataAvailable(nsIRequest* aRequest, nsISupports* aContext, + nsIInputStream* aStream, uint64_t aOffset, + uint32_t aCount) { uint32_t result; - return stream->ReadSegments(NS_DiscardSegment, nullptr, count, &result); -} - -NS_IMETHODIMP -nsPingListener::OnStopRequest(nsIRequest *request, nsISupports *context, - nsresult status) + return aStream->ReadSegments(NS_DiscardSegment, nullptr, aCount, &result); +} + +NS_IMETHODIMP +nsPingListener::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext, + nsresult aStatus) { mLoadGroup = nullptr; if (mTimer) { mTimer->Cancel(); mTimer = nullptr; } return NS_OK; } NS_IMETHODIMP -nsPingListener::GetInterface(const nsIID &iid, void **result) -{ - if (iid.Equals(NS_GET_IID(nsIChannelEventSink))) { +nsPingListener::GetInterface(const nsIID& aIID, void** aResult) +{ + if (aIID.Equals(NS_GET_IID(nsIChannelEventSink))) { NS_ADDREF_THIS(); - *result = (nsIChannelEventSink *) this; + *aResult = (nsIChannelEventSink*)this; return NS_OK; } return NS_ERROR_NO_INTERFACE; } NS_IMETHODIMP -nsPingListener::AsyncOnChannelRedirect(nsIChannel *oldChan, nsIChannel *newChan, - uint32_t flags, - nsIAsyncVerifyRedirectCallback *callback) +nsPingListener::AsyncOnChannelRedirect(nsIChannel* aOldChan, + nsIChannel* aNewChan, + uint32_t aFlags, + nsIAsyncVerifyRedirectCallback* aCallback) { nsCOMPtr<nsIURI> newURI; - newChan->GetURI(getter_AddRefs(newURI)); - - if (!CheckPingURI(newURI, mContent)) + aNewChan->GetURI(getter_AddRefs(newURI)); + + if (!CheckPingURI(newURI, mContent)) { return NS_ERROR_ABORT; + } if (!mRequireSameHost) { - callback->OnRedirectVerifyCallback(NS_OK); + aCallback->OnRedirectVerifyCallback(NS_OK); return NS_OK; } // XXXbz should this be using something more like the nsContentUtils // same-origin checker? nsCOMPtr<nsIURI> oldURI; - oldChan->GetURI(getter_AddRefs(oldURI)); + aOldChan->GetURI(getter_AddRefs(oldURI)); NS_ENSURE_STATE(oldURI && newURI); - if (!IsSameHost(oldURI, newURI)) + if (!IsSameHost(oldURI, newURI)) { return NS_ERROR_ABORT; - - callback->OnRedirectVerifyCallback(NS_OK); - return NS_OK; -} - -struct SendPingInfo { + } + + aCallback->OnRedirectVerifyCallback(NS_OK); + return NS_OK; +} + +struct SendPingInfo +{ int32_t numPings; int32_t maxPings; - bool requireSameHost; - nsIURI *target; - nsIURI *referrer; + bool requireSameHost; + nsIURI* target; + nsIURI* referrer; uint32_t referrerPolicy; }; static void -SendPing(void *closure, nsIContent *content, nsIURI *uri, nsIIOService *ios) -{ - SendPingInfo *info = static_cast<SendPingInfo *>(closure); - if (info->maxPings > -1 && info->numPings >= info->maxPings) +SendPing(void* aClosure, nsIContent* aContent, nsIURI* aURI, + nsIIOService* aIOService) +{ + SendPingInfo* info = static_cast<SendPingInfo*>(aClosure); + if (info->maxPings > -1 && info->numPings >= info->maxPings) { return; + } if (info->requireSameHost) { // Make sure the referrer and the given uri share the same origin. We // only require the same hostname. The scheme and port may differ. - if (!IsSameHost(uri, info->referrer)) + if (!IsSameHost(aURI, info->referrer)) { return; - } - - nsIDocument *doc = content->OwnerDoc(); + } + } + + nsIDocument* doc = aContent->OwnerDoc(); nsCOMPtr<nsIChannel> chan; - ios->NewChannelFromURI(uri, getter_AddRefs(chan)); - if (!chan) + aIOService->NewChannelFromURI(aURI, getter_AddRefs(chan)); + if (!chan) { return; + } // Don't bother caching the result of this URI load. chan->SetLoadFlags(nsIRequest::INHIBIT_CACHING); nsCOMPtr<nsIHttpChannel> httpChan = do_QueryInterface(chan); - if (!httpChan) + if (!httpChan) { return; + } // This is needed in order for 3rd-party cookie blocking to work. nsCOMPtr<nsIHttpChannelInternal> httpInternal = do_QueryInterface(httpChan); - if (httpInternal) + if (httpInternal) { httpInternal->SetDocumentURI(doc->GetDocumentURI()); - + } httpChan->SetRequestMethod(NS_LITERAL_CSTRING("POST")); // Remove extraneous request headers (to reduce request size) httpChan->SetRequestHeader(NS_LITERAL_CSTRING("accept"), EmptyCString(), false); httpChan->SetRequestHeader(NS_LITERAL_CSTRING("accept-language"), EmptyCString(), false); httpChan->SetRequestHeader(NS_LITERAL_CSTRING("accept-encoding"), EmptyCString(), false); // Always send a Ping-To header. nsAutoCString pingTo; - if (NS_SUCCEEDED(info->target->GetSpec(pingTo))) + if (NS_SUCCEEDED(info->target->GetSpec(pingTo))) { httpChan->SetRequestHeader(NS_LITERAL_CSTRING("Ping-To"), pingTo, false); + } nsCOMPtr<nsIScriptSecurityManager> sm = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID); if (sm && info->referrer) { bool referrerIsSecure; uint32_t flags = nsIProtocolHandler::URI_SAFE_TO_LOAD_IN_SECURE_CONTEXT; nsresult rv = NS_URIChainHasFlags(info->referrer, flags, &referrerIsSecure); // Default to sending less data if NS_URIChainHasFlags() fails. referrerIsSecure = NS_FAILED(rv) || referrerIsSecure; bool sameOrigin = - NS_SUCCEEDED(sm->CheckSameOriginURI(info->referrer, uri, false)); + NS_SUCCEEDED(sm->CheckSameOriginURI(info->referrer, aURI, false)); // If both the address of the document containing the hyperlink being // audited and "ping URL" have the same origin or the document containing // the hyperlink being audited was not retrieved over an encrypted // connection, send a Ping-From header. if (sameOrigin || !referrerIsSecure) { nsAutoCString pingFrom; - if (NS_SUCCEEDED(info->referrer->GetSpec(pingFrom))) - httpChan->SetRequestHeader(NS_LITERAL_CSTRING("Ping-From"), pingFrom, false); + if (NS_SUCCEEDED(info->referrer->GetSpec(pingFrom))) { + httpChan->SetRequestHeader(NS_LITERAL_CSTRING("Ping-From"), pingFrom, + false); + } } // If the document containing the hyperlink being audited was not retrieved // over an encrypted connection and its address does not have the same // origin as "ping URL", send a referrer. - if (!sameOrigin && !referrerIsSecure) + if (!sameOrigin && !referrerIsSecure) { httpChan->SetReferrerWithPolicy(info->referrer, info->referrerPolicy); + } } nsCOMPtr<nsIUploadChannel2> uploadChan = do_QueryInterface(httpChan); - if (!uploadChan) + if (!uploadChan) { return; + } NS_NAMED_LITERAL_CSTRING(uploadData, "PING"); nsCOMPtr<nsIInputStream> uploadStream; NS_NewPostDataStream(getter_AddRefs(uploadStream), false, uploadData); - if (!uploadStream) + if (!uploadStream) { return; + } uploadChan->ExplicitSetUploadStream(uploadStream, - NS_LITERAL_CSTRING("text/ping"), uploadData.Length(), - NS_LITERAL_CSTRING("POST"), false); + NS_LITERAL_CSTRING("text/ping"), + uploadData.Length(), + NS_LITERAL_CSTRING("POST"), false); // The channel needs to have a loadgroup associated with it, so that we can // cancel the channel and any redirected channels it may create. - nsCOMPtr<nsILoadGroup> loadGroup = - do_CreateInstance(NS_LOADGROUP_CONTRACTID); - if (!loadGroup) + nsCOMPtr<nsILoadGroup> loadGroup = do_CreateInstance(NS_LOADGROUP_CONTRACTID); + if (!loadGroup) { return; + } chan->SetLoadGroup(loadGroup); // Construct a listener that merely discards any response. If successful at // opening the channel, then it is not necessary to hold a reference to the // channel. The networking subsystem will take care of that for us. - nsPingListener *pingListener = - new nsPingListener(info->requireSameHost, content, loadGroup); - if (!pingListener) - return; + nsPingListener* pingListener = + new nsPingListener(info->requireSameHost, aContent, loadGroup); nsCOMPtr<nsIStreamListener> listener(pingListener); // Observe redirects as well: nsCOMPtr<nsIInterfaceRequestor> callbacks = do_QueryInterface(listener); NS_ASSERTION(callbacks, "oops"); loadGroup->SetNotificationCallbacks(callbacks); @@ -686,1358 +710,1356 @@ SendPing(void *closure, nsIContent *cont // If we failed to setup the timer, then we should just cancel the channel // because we won't be able to ensure that it goes away in a timely manner. chan->Cancel(NS_ERROR_ABORT); } } // Spec: http://whatwg.org/specs/web-apps/current-work/#ping static void -DispatchPings(nsIContent *content, - nsIURI *target, - nsIURI *referrer, - uint32_t referrerPolicy) +DispatchPings(nsIContent* aContent, + nsIURI* aTarget, + nsIURI* aReferrer, + uint32_t aReferrerPolicy) { SendPingInfo info; - if (!PingsEnabled(&info.maxPings, &info.requireSameHost)) + if (!PingsEnabled(&info.maxPings, &info.requireSameHost)) { return; - if (info.maxPings == 0) + } + if (info.maxPings == 0) { return; + } info.numPings = 0; - info.target = target; - info.referrer = referrer; - info.referrerPolicy = referrerPolicy; - - ForEachPing(content, SendPing, &info); + info.target = aTarget; + info.referrer = aReferrer; + info.referrerPolicy = aReferrerPolicy; + + ForEachPing(aContent, SendPing, &info); } static nsDOMPerformanceNavigationType ConvertLoadTypeToNavigationType(uint32_t aLoadType) { // Not initialized, assume it's normal load. if (aLoadType == 0) { aLoadType = LOAD_NORMAL; } - nsDOMPerformanceNavigationType result = dom::PerformanceNavigation::TYPE_RESERVED; + auto result = dom::PerformanceNavigation::TYPE_RESERVED; switch (aLoadType) { case LOAD_NORMAL: case LOAD_NORMAL_EXTERNAL: case LOAD_NORMAL_BYPASS_CACHE: case LOAD_NORMAL_BYPASS_PROXY: case LOAD_NORMAL_BYPASS_PROXY_AND_CACHE: case LOAD_NORMAL_REPLACE: case LOAD_NORMAL_ALLOW_MIXED_CONTENT: case LOAD_LINK: case LOAD_STOP_CONTENT: case LOAD_REPLACE_BYPASS_CACHE: - result = dom::PerformanceNavigation::TYPE_NAVIGATE; - break; + result = dom::PerformanceNavigation::TYPE_NAVIGATE; + break; case LOAD_HISTORY: - result = dom::PerformanceNavigation::TYPE_BACK_FORWARD; - break; + result = dom::PerformanceNavigation::TYPE_BACK_FORWARD; + break; case LOAD_RELOAD_NORMAL: case LOAD_RELOAD_CHARSET_CHANGE: case LOAD_RELOAD_BYPASS_CACHE: case LOAD_RELOAD_BYPASS_PROXY: case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE: case LOAD_RELOAD_ALLOW_MIXED_CONTENT: - result = dom::PerformanceNavigation::TYPE_RELOAD; - break; + result = dom::PerformanceNavigation::TYPE_RELOAD; + break; case LOAD_STOP_CONTENT_AND_REPLACE: case LOAD_REFRESH: case LOAD_BYPASS_HISTORY: case LOAD_ERROR_PAGE: case LOAD_PUSHSTATE: - result = dom::PerformanceNavigation::TYPE_RESERVED; - break; + result = dom::PerformanceNavigation::TYPE_RESERVED; + break; default: - // NS_NOTREACHED("Unexpected load type value"); - result = dom::PerformanceNavigation::TYPE_RESERVED; - break; + // NS_NOTREACHED("Unexpected load type value"); + result = dom::PerformanceNavigation::TYPE_RESERVED; + break; } return result; } -static nsISHEntry* GetRootSHEntry(nsISHEntry *entry); +static nsISHEntry* GetRootSHEntry(nsISHEntry* aEntry); static void IncreasePrivateDocShellCount() { - gNumberOfPrivateDocShells++; - if (gNumberOfPrivateDocShells > 1 || - XRE_GetProcessType() != GeckoProcessType_Content) { - return; - } - - mozilla::dom::ContentChild* cc = mozilla::dom::ContentChild::GetSingleton(); - cc->SendPrivateDocShellsExist(true); + gNumberOfPrivateDocShells++; + if (gNumberOfPrivateDocShells > 1 || + XRE_GetProcessType() != GeckoProcessType_Content) { + return; + } + + mozilla::dom::ContentChild* cc = mozilla::dom::ContentChild::GetSingleton(); + cc->SendPrivateDocShellsExist(true); } static void DecreasePrivateDocShellCount() { - MOZ_ASSERT(gNumberOfPrivateDocShells > 0); - gNumberOfPrivateDocShells--; - if (!gNumberOfPrivateDocShells) - { - if (XRE_GetProcessType() == GeckoProcessType_Content) { - mozilla::dom::ContentChild* cc = mozilla::dom::ContentChild::GetSingleton(); - cc->SendPrivateDocShellsExist(false); - return; - } - - nsCOMPtr<nsIObserverService> obsvc = mozilla::services::GetObserverService(); - if (obsvc) { - obsvc->NotifyObservers(nullptr, "last-pb-context-exited", nullptr); - } - } + MOZ_ASSERT(gNumberOfPrivateDocShells > 0); + gNumberOfPrivateDocShells--; + if (!gNumberOfPrivateDocShells) { + if (XRE_GetProcessType() == GeckoProcessType_Content) { + dom::ContentChild* cc = dom::ContentChild::GetSingleton(); + cc->SendPrivateDocShellsExist(false); + return; + } + + nsCOMPtr<nsIObserverService> obsvc = services::GetObserverService(); + if (obsvc) { + obsvc->NotifyObservers(nullptr, "last-pb-context-exited", nullptr); + } + } } //***************************************************************************** //*** nsDocShell: Object Management //***************************************************************************** static uint64_t gDocshellIDCounter = 0; -// Note: operator new zeros our memory -nsDocShell::nsDocShell(): - nsDocLoader(), - mDefaultScrollbarPref(Scrollbar_Auto, Scrollbar_Auto), - mTreeOwner(nullptr), - mChromeEventHandler(nullptr), - mCharsetReloadState(eCharsetReloadInit), - mChildOffset(0), - mBusyFlags(BUSY_FLAGS_NONE), - mAppType(nsIDocShell::APP_TYPE_UNKNOWN), - mLoadType(0), - mMarginWidth(-1), - mMarginHeight(-1), - mItemType(typeContent), - mPreviousTransIndex(-1), - mLoadedTransIndex(-1), - mSandboxFlags(0), - mFullscreenAllowed(CHECK_ATTRIBUTES), - mCreated(false), - mAllowSubframes(true), - mAllowPlugins(true), - mAllowJavascript(true), - mAllowMetaRedirects(true), - mAllowImages(true), - mAllowMedia(true), - mAllowDNSPrefetch(true), - mAllowWindowControl(true), - mAllowContentRetargeting(true), - mCreatingDocument(false), - mUseErrorPages(false), - mObserveErrorPages(true), - mAllowAuth(true), - mAllowKeywordFixup(false), - mIsOffScreenBrowser(false), - mIsActive(true), - mIsPrerendered(false), - mIsAppTab(false), - mUseGlobalHistory(false), - mInPrivateBrowsing(false), - mUseRemoteTabs(false), - mDeviceSizeIsPageSize(false), - mWindowDraggingAllowed(false), - mCanExecuteScripts(false), - mFiredUnloadEvent(false), - mEODForCurrentDocument(false), - mURIResultedInDocument(false), - mIsBeingDestroyed(false), - mIsExecutingOnLoadHandler(false), - mIsPrintingOrPP(false), - mSavingOldViewer(false), +nsDocShell::nsDocShell() + : nsDocLoader() + , mDefaultScrollbarPref(Scrollbar_Auto, Scrollbar_Auto) + , mTreeOwner(nullptr) + , mChromeEventHandler(nullptr) + , mCharsetReloadState(eCharsetReloadInit) + , mChildOffset(0) + , mBusyFlags(BUSY_FLAGS_NONE) + , mAppType(nsIDocShell::APP_TYPE_UNKNOWN) + , mLoadType(0) + , mMarginWidth(-1) + , mMarginHeight(-1) + , mItemType(typeContent) + , mPreviousTransIndex(-1) + , mLoadedTransIndex(-1) + , mSandboxFlags(0) + , mFullscreenAllowed(CHECK_ATTRIBUTES) + , mCreated(false) + , mAllowSubframes(true) + , mAllowPlugins(true) + , mAllowJavascript(true) + , mAllowMetaRedirects(true) + , mAllowImages(true) + , mAllowMedia(true) + , mAllowDNSPrefetch(true) + , mAllowWindowControl(true) + , mAllowContentRetargeting(true) + , mCreatingDocument(false) + , mUseErrorPages(false) + , mObserveErrorPages(true) + , mAllowAuth(true) + , mAllowKeywordFixup(false) + , mIsOffScreenBrowser(false) + , mIsActive(true) + , mIsPrerendered(false) + , mIsAppTab(false) + , mUseGlobalHistory(false) + , mInPrivateBrowsing(false) + , mUseRemoteTabs(false) + , mDeviceSizeIsPageSize(false) + , mWindowDraggingAllowed(false) + , mCanExecuteScripts(false) + , mFiredUnloadEvent(false) + , mEODForCurrentDocument(false) + , mURIResultedInDocument(false) + , mIsBeingDestroyed(false) + , mIsExecutingOnLoadHandler(false) + , mIsPrintingOrPP(false) + , mSavingOldViewer(false) #ifdef DEBUG - mInEnsureScriptEnv(false), + , mInEnsureScriptEnv(false) #endif - mAffectPrivateSessionLifetime(true), - mInvisible(false), - mHasLoadedNonBlankURI(false), - mDefaultLoadFlags(nsIRequest::LOAD_NORMAL), - mBlankTiming(false), - mFrameType(eFrameTypeRegular), - mOwnOrContainingAppId(nsIScriptSecurityManager::UNKNOWN_APP_ID), - mParentCharsetSource(0), - mJSRunToCompletionDepth(0) -{ - mHistoryID = ++gDocshellIDCounter; - if (gDocShellCount++ == 0) { - NS_ASSERTION(sURIFixup == nullptr, - "Huh, sURIFixup not null in first nsDocShell ctor!"); - - CallGetService(NS_URIFIXUP_CONTRACTID, &sURIFixup); - } + , mAffectPrivateSessionLifetime(true) + , mInvisible(false) + , mHasLoadedNonBlankURI(false) + , mDefaultLoadFlags(nsIRequest::LOAD_NORMAL) + , mBlankTiming(false) + , mFrameType(eFrameTypeRegular) + , mOwnOrContainingAppId(nsIScriptSecurityManager::UNKNOWN_APP_ID) + , mParentCharsetSource(0) + , mJSRunToCompletionDepth(0) +{ + mHistoryID = ++gDocshellIDCounter; + if (gDocShellCount++ == 0) { + NS_ASSERTION(sURIFixup == nullptr, + "Huh, sURIFixup not null in first nsDocShell ctor!"); + + CallGetService(NS_URIFIXUP_CONTRACTID, &sURIFixup); + } #ifdef PR_LOGGING #ifdef DEBUG - if (! gDocShellLog) - gDocShellLog = PR_NewLogModule("nsDocShell"); + if (!gDocShellLog) { + gDocShellLog = PR_NewLogModule("nsDocShell"); + } #endif - if (nullptr == gDocShellLeakLog) - gDocShellLeakLog = PR_NewLogModule("nsDocShellLeak"); - if (gDocShellLeakLog) - PR_LOG(gDocShellLeakLog, PR_LOG_DEBUG, ("DOCSHELL %p created\n", this)); + if (!gDocShellLeakLog) { + gDocShellLeakLog = PR_NewLogModule("nsDocShellLeak"); + } + if (gDocShellLeakLog) { + PR_LOG(gDocShellLeakLog, PR_LOG_DEBUG, ("DOCSHELL %p created\n", this)); + } #endif #ifdef DEBUG // We're counting the number of |nsDocShells| to help find leaks ++gNumberOfDocShells; if (!PR_GetEnv("MOZ_QUIET")) { - printf_stderr("++DOCSHELL %p == %ld [pid = %d] [id = %llu]\n", - (void*) this, - gNumberOfDocShells, - getpid(), - AssertedCast<unsigned long long>(mHistoryID)); + printf_stderr("++DOCSHELL %p == %ld [pid = %d] [id = %llu]\n", + (void*)this, + gNumberOfDocShells, + getpid(), + AssertedCast<unsigned long long>(mHistoryID)); } #endif } nsDocShell::~nsDocShell() { - MOZ_ASSERT(!mProfileTimelineRecording); - - Destroy(); - - nsCOMPtr<nsISHistoryInternal> - shPrivate(do_QueryInterface(mSessionHistory)); - if (shPrivate) { - shPrivate->SetRootDocShell(nullptr); - } - - if (--gDocShellCount == 0) { - NS_IF_RELEASE(sURIFixup); - } + MOZ_ASSERT(!mProfileTimelineRecording); + + Destroy(); + + nsCOMPtr<nsISHistoryInternal> shPrivate(do_QueryInterface(mSessionHistory)); + if (shPrivate) { + shPrivate->SetRootDocShell(nullptr); + } + + if (--gDocShellCount == 0) { + NS_IF_RELEASE(sURIFixup); + } #ifdef PR_LOGGING - if (gDocShellLeakLog) - PR_LOG(gDocShellLeakLog, PR_LOG_DEBUG, ("DOCSHELL %p destroyed\n", this)); + if (gDocShellLeakLog) { + PR_LOG(gDocShellLeakLog, PR_LOG_DEBUG, ("DOCSHELL %p destroyed\n", this)); + } #endif #ifdef DEBUG - // We're counting the number of |nsDocShells| to help find leaks - --gNumberOfDocShells; - if (!PR_GetEnv("MOZ_QUIET")) { - printf_stderr("--DOCSHELL %p == %ld [pid = %d] [id = %llu]\n", - (void*) this, - gNumberOfDocShells, - getpid(), - AssertedCast<unsigned long long>(mHistoryID)); - } + // We're counting the number of |nsDocShells| to help find leaks + --gNumberOfDocShells; + if (!PR_GetEnv("MOZ_QUIET")) { + printf_stderr("--DOCSHELL %p == %ld [pid = %d] [id = %llu]\n", + (void*)this, + gNumberOfDocShells, + getpid(), + AssertedCast<unsigned long long>(mHistoryID)); + } #endif } nsresult nsDocShell::Init() { - nsresult rv = nsDocLoader::Init(); - NS_ENSURE_SUCCESS(rv, rv); - - NS_ASSERTION(mLoadGroup, "Something went wrong!"); - - mContentListener = new nsDSURIContentListener(this); - NS_ENSURE_TRUE(mContentListener, NS_ERROR_OUT_OF_MEMORY); - - rv = mContentListener->Init(); - NS_ENSURE_SUCCESS(rv, rv); - - // We want to hold a strong ref to the loadgroup, so it better hold a weak - // ref to us... use an InterfaceRequestorProxy to do this. - nsCOMPtr<nsIInterfaceRequestor> proxy = - new InterfaceRequestorProxy(static_cast<nsIInterfaceRequestor*> - (this)); - NS_ENSURE_TRUE(proxy, NS_ERROR_OUT_OF_MEMORY); - mLoadGroup->SetNotificationCallbacks(proxy); - - rv = nsDocLoader::AddDocLoaderAsChildOfRoot(this); - NS_ENSURE_SUCCESS(rv, rv); - - // Add as |this| a progress listener to itself. A little weird, but - // simpler than reproducing all the listener-notification logic in - // overrides of the various methods via which nsDocLoader can be - // notified. Note that this holds an nsWeakPtr to ourselves, so it's ok. - return AddProgressListener(this, nsIWebProgress::NOTIFY_STATE_DOCUMENT | + nsresult rv = nsDocLoader::Init(); + NS_ENSURE_SUCCESS(rv, rv); + + NS_ASSERTION(mLoadGroup, "Something went wrong!"); + + mContentListener = new nsDSURIContentListener(this); + NS_ENSURE_TRUE(mContentListener, NS_ERROR_OUT_OF_MEMORY); + + rv = mContentListener->Init(); + NS_ENSURE_SUCCESS(rv, rv); + + // We want to hold a strong ref to the loadgroup, so it better hold a weak + // ref to us... use an InterfaceRequestorProxy to do this. + nsCOMPtr<nsIInterfaceRequestor> proxy = + new InterfaceRequestorProxy(static_cast<nsIInterfaceRequestor*>(this)); + NS_ENSURE_TRUE(proxy, NS_ERROR_OUT_OF_MEMORY); + mLoadGroup->SetNotificationCallbacks(proxy); + + rv = nsDocLoader::AddDocLoaderAsChildOfRoot(this); + NS_ENSURE_SUCCESS(rv, rv); + + // Add as |this| a progress listener to itself. A little weird, but + // simpler than reproducing all the listener-notification logic in + // overrides of the various methods via which nsDocLoader can be + // notified. Note that this holds an nsWeakPtr to ourselves, so it's ok. + return AddProgressListener(this, nsIWebProgress::NOTIFY_STATE_DOCUMENT | nsIWebProgress::NOTIFY_STATE_NETWORK); - } void nsDocShell::DestroyChildren() { - nsCOMPtr<nsIDocShellTreeItem> shell; - nsTObserverArray<nsDocLoader*>::ForwardIterator iter(mChildList); - while (iter.HasMore()) { - shell = do_QueryObject(iter.GetNext()); - NS_ASSERTION(shell, "docshell has null child"); - - if (shell) { - shell->SetTreeOwner(nullptr); - } - } - - nsDocLoader::DestroyChildren(); + nsCOMPtr<nsIDocShellTreeItem> shell; + nsTObserverArray<nsDocLoader*>::ForwardIterator iter(mChildList); + while (iter.HasMore()) { + shell = do_QueryObject(iter.GetNext()); + NS_ASSERTION(shell, "docshell has null child"); + + if (shell) { + shell->SetTreeOwner(nullptr); + } + } + + nsDocLoader::DestroyChildren(); } //***************************************************************************** // nsDocShell::nsISupports //***************************************************************************** NS_IMPL_ADDREF_INHERITED(nsDocShell, nsDocLoader) NS_IMPL_RELEASE_INHERITED(nsDocShell, nsDocLoader) NS_INTERFACE_MAP_BEGIN(nsDocShell) - NS_INTERFACE_MAP_ENTRY(nsIDocShell) - NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeItem) - NS_INTERFACE_MAP_ENTRY(nsIWebNavigation) - NS_INTERFACE_MAP_ENTRY(nsIBaseWindow) - NS_INTERFACE_MAP_ENTRY(nsIScrollable) - NS_INTERFACE_MAP_ENTRY(nsITextScroll) - NS_INTERFACE_MAP_ENTRY(nsIDocCharset) - NS_INTERFACE_MAP_ENTRY(nsIRefreshURI) - NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener) - NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) - NS_INTERFACE_MAP_ENTRY(nsIContentViewerContainer) - NS_INTERFACE_MAP_ENTRY(nsIWebPageDescriptor) - NS_INTERFACE_MAP_ENTRY(nsIAuthPromptProvider) - NS_INTERFACE_MAP_ENTRY(nsILoadContext) - NS_INTERFACE_MAP_ENTRY(nsIWebShellServices) - NS_INTERFACE_MAP_ENTRY(nsILinkHandler) - NS_INTERFACE_MAP_ENTRY(nsIClipboardCommands) - NS_INTERFACE_MAP_ENTRY(nsIDOMStorageManager) + NS_INTERFACE_MAP_ENTRY(nsIDocShell) + NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeItem) + NS_INTERFACE_MAP_ENTRY(nsIWebNavigation) + NS_INTERFACE_MAP_ENTRY(nsIBaseWindow) + NS_INTERFACE_MAP_ENTRY(nsIScrollable) + NS_INTERFACE_MAP_ENTRY(nsITextScroll) + NS_INTERFACE_MAP_ENTRY(nsIDocCharset) + NS_INTERFACE_MAP_ENTRY(nsIRefreshURI) + NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener) + NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) + NS_INTERFACE_MAP_ENTRY(nsIContentViewerContainer) + NS_INTERFACE_MAP_ENTRY(nsIWebPageDescriptor) + NS_INTERFACE_MAP_ENTRY(nsIAuthPromptProvider) + NS_INTERFACE_MAP_ENTRY(nsILoadContext) + NS_INTERFACE_MAP_ENTRY(nsIWebShellServices) + NS_INTERFACE_MAP_ENTRY(nsILinkHandler) + NS_INTERFACE_MAP_ENTRY(nsIClipboardCommands) + NS_INTERFACE_MAP_ENTRY(nsIDOMStorageManager) NS_INTERFACE_MAP_END_INHERITING(nsDocLoader) ///***************************************************************************** // nsDocShell::nsIInterfaceRequestor //***************************************************************************** -NS_IMETHODIMP nsDocShell::GetInterface(const nsIID & aIID, void **aSink) -{ - NS_PRECONDITION(aSink, "null out param"); - - *aSink = nullptr; - - if (aIID.Equals(NS_GET_IID(nsICommandManager))) { - NS_ENSURE_SUCCESS(EnsureCommandHandler(), NS_ERROR_FAILURE); - *aSink = mCommandManager; - } - else if (aIID.Equals(NS_GET_IID(nsIURIContentListener))) { - *aSink = mContentListener; - } - else if ((aIID.Equals(NS_GET_IID(nsIScriptGlobalObject)) || +NS_IMETHODIMP +nsDocShell::GetInterface(const nsIID& aIID, void** aSink) +{ + NS_PRECONDITION(aSink, "null out param"); + + *aSink = nullptr; + + if (aIID.Equals(NS_GET_IID(nsICommandManager))) { + NS_ENSURE_SUCCESS(EnsureCommandHandler(), NS_ERROR_FAILURE); + *aSink = mCommandManager; + } else if (aIID.Equals(NS_GET_IID(nsIURIContentListener))) { + *aSink = mContentListener; + } else if ((aIID.Equals(NS_GET_IID(nsIScriptGlobalObject)) || aIID.Equals(NS_GET_IID(nsIGlobalObject)) || aIID.Equals(NS_GET_IID(nsPIDOMWindow)) || aIID.Equals(NS_GET_IID(nsIDOMWindow)) || aIID.Equals(NS_GET_IID(nsIDOMWindowInternal))) && NS_SUCCEEDED(EnsureScriptEnvironment())) { - return mScriptGlobal->QueryInterface(aIID, aSink); - } - else if (aIID.Equals(NS_GET_IID(nsIDOMDocument)) && + return mScriptGlobal->QueryInterface(aIID, aSink); + } else if (aIID.Equals(NS_GET_IID(nsIDOMDocument)) && NS_SUCCEEDED(EnsureContentViewer())) { - mContentViewer->GetDOMDocument((nsIDOMDocument **) aSink); - return *aSink ? NS_OK : NS_NOINTERFACE; - } - else if (aIID.Equals(NS_GET_IID(nsIDocument)) && + mContentViewer->GetDOMDocument((nsIDOMDocument**)aSink); + return *aSink ? NS_OK : NS_NOINTERFACE; + } else if (aIID.Equals(NS_GET_IID(nsIDocument)) && NS_SUCCEEDED(EnsureContentViewer())) { - nsCOMPtr<nsIDocument> doc = mContentViewer->GetDocument(); - doc.forget(aSink); - return *aSink ? NS_OK : NS_NOINTERFACE; - } - else if (aIID.Equals(NS_GET_IID(nsIApplicationCacheContainer))) { - *aSink = nullptr; - - // Return application cache associated with this docshell, if any - - nsCOMPtr<nsIContentViewer> contentViewer; - GetContentViewer(getter_AddRefs(contentViewer)); - if (!contentViewer) - return NS_ERROR_NO_INTERFACE; - - nsCOMPtr<nsIDOMDocument> domDoc; - contentViewer->GetDOMDocument(getter_AddRefs(domDoc)); - NS_ASSERTION(domDoc, "Should have a document."); - if (!domDoc) - return NS_ERROR_NO_INTERFACE; + nsCOMPtr<nsIDocument> doc = mContentViewer->GetDocument(); + doc.forget(aSink); + return *aSink ? NS_OK : NS_NOINTERFACE; + } else if (aIID.Equals(NS_GET_IID(nsIApplicationCacheContainer))) { + *aSink = nullptr; + + // Return application cache associated with this docshell, if any + + nsCOMPtr<nsIContentViewer> contentViewer; + GetContentViewer(getter_AddRefs(contentViewer)); + if (!contentViewer) { + return NS_ERROR_NO_INTERFACE; + } + + nsCOMPtr<nsIDOMDocument> domDoc; + contentViewer->GetDOMDocument(getter_AddRefs(domDoc)); + NS_ASSERTION(domDoc, "Should have a document."); + if (!domDoc) { + return NS_ERROR_NO_INTERFACE; + } #if defined(PR_LOGGING) && defined(DEBUG) - PR_LOG(gDocShellLog, PR_LOG_DEBUG, - ("nsDocShell[%p]: returning app cache container %p", - this, domDoc.get())); + PR_LOG(gDocShellLog, PR_LOG_DEBUG, + ("nsDocShell[%p]: returning app cache container %p", + this, domDoc.get())); #endif - return domDoc->QueryInterface(aIID, aSink); - } - else if (aIID.Equals(NS_GET_IID(nsIPrompt)) && + return domDoc->QueryInterface(aIID, aSink); + } else if (aIID.Equals(NS_GET_IID(nsIPrompt)) && NS_SUCCEEDED(EnsureScriptEnvironment())) { - nsresult rv; - nsCOMPtr<nsIWindowWatcher> wwatch = - do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - - // Get the an auth prompter for our window so that the parenting - // of the dialogs works as it should when using tabs. - nsIPrompt *prompt; - rv = wwatch->GetNewPrompter(mScriptGlobal, &prompt); - NS_ENSURE_SUCCESS(rv, rv); - - *aSink = prompt; - return NS_OK; - } - else if (aIID.Equals(NS_GET_IID(nsIAuthPrompt)) || + nsresult rv; + nsCOMPtr<nsIWindowWatcher> wwatch = + do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + // Get the an auth prompter for our window so that the parenting + // of the dialogs works as it should when using tabs. + nsIPrompt* prompt; + rv = wwatch->GetNewPrompter(mScriptGlobal, &prompt); + NS_ENSURE_SUCCESS(rv, rv); + + *aSink = prompt; + return NS_OK; + } else if (aIID.Equals(NS_GET_IID(nsIAuthPrompt)) || aIID.Equals(NS_GET_IID(nsIAuthPrompt2))) { - return NS_SUCCEEDED( - GetAuthPrompt(PROMPT_NORMAL, aIID, aSink)) ? - NS_OK : NS_NOINTERFACE; - } - else if (aIID.Equals(NS_GET_IID(nsISHistory))) { - nsCOMPtr<nsISHistory> shistory; - nsresult - rv = - GetSessionHistory(getter_AddRefs(shistory)); - if (NS_SUCCEEDED(rv) && shistory) { - *aSink = shistory; - NS_ADDREF((nsISupports *) * aSink); - return NS_OK; - } - return NS_NOINTERFACE; - } - else if (aIID.Equals(NS_GET_IID(nsIWebBrowserFind))) { - nsresult rv = EnsureFind(); - if (NS_FAILED(rv)) return rv; - - *aSink = mFind; - NS_ADDREF((nsISupports*)*aSink); - return NS_OK; - } - else if (aIID.Equals(NS_GET_IID(nsIEditingSession)) && NS_SUCCEEDED(EnsureEditorData())) { - nsCOMPtr<nsIEditingSession> editingSession; - mEditorData->GetEditingSession(getter_AddRefs(editingSession)); - if (editingSession) - { - *aSink = editingSession; - NS_ADDREF((nsISupports *)*aSink); - return NS_OK; - } - - return NS_NOINTERFACE; - } - else if (aIID.Equals(NS_GET_IID(nsIClipboardDragDropHookList)) - && NS_SUCCEEDED(EnsureTransferableHookData())) { - *aSink = mTransferableHookData; - NS_ADDREF((nsISupports *)*aSink); - return NS_OK; - } - else if (aIID.Equals(NS_GET_IID(nsISelectionDisplay))) { - nsIPresShell* shell = GetPresShell(); - if (shell) - return shell->QueryInterface(aIID,aSink); - } - else if (aIID.Equals(NS_GET_IID(nsIDocShellTreeOwner))) { - nsCOMPtr<nsIDocShellTreeOwner> treeOwner; - nsresult rv = GetTreeOwner(getter_AddRefs(treeOwner)); - if (NS_SUCCEEDED(rv) && treeOwner) - return treeOwner->QueryInterface(aIID, aSink); - } - else if (aIID.Equals(NS_GET_IID(nsITabChild))) { - nsCOMPtr<nsIDocShellTreeOwner> treeOwner; - nsresult rv = GetTreeOwner(getter_AddRefs(treeOwner)); - if (NS_SUCCEEDED(rv) && treeOwner) { - nsCOMPtr<nsIInterfaceRequestor> ir = do_QueryInterface(treeOwner); - if (ir) - return ir->GetInterface(aIID, aSink); - } - } - else if (aIID.Equals(NS_GET_IID(nsIContentFrameMessageManager))) { - nsCOMPtr<nsITabChild> tabChild = - do_GetInterface(static_cast<nsIDocShell*>(this)); - nsCOMPtr<nsIContentFrameMessageManager> mm; - if (tabChild) { - tabChild-> - GetMessageManager(getter_AddRefs(mm)); - } else { - nsCOMPtr<nsPIDOMWindow> win = GetWindow(); - if (win) { - mm = do_QueryInterface(win->GetParentTarget()); - } - } - *aSink = mm.get(); - } - else { - return nsDocLoader::GetInterface(aIID, aSink); - } - - NS_IF_ADDREF(((nsISupports *) * aSink)); - return *aSink ? NS_OK : NS_NOINTERFACE; + return NS_SUCCEEDED(GetAuthPrompt(PROMPT_NORMAL, aIID, aSink)) ? + NS_OK : NS_NOINTERFACE; + } else if (aIID.Equals(NS_GET_IID(nsISHistory))) { + nsCOMPtr<nsISHistory> shistory; + nsresult rv = GetSessionHistory(getter_AddRefs(shistory)); + if (NS_SUCCEEDED(rv) && shistory) { + *aSink = shistory; + NS_ADDREF((nsISupports*)*aSink); + return NS_OK; + } + return NS_NOINTERFACE; + } else if (aIID.Equals(NS_GET_IID(nsIWebBrowserFind))) { + nsresult rv = EnsureFind(); + if (NS_FAILED(rv)) { + return rv; + } + + *aSink = mFind; + NS_ADDREF((nsISupports*)*aSink); + return NS_OK; + } else if (aIID.Equals(NS_GET_IID(nsIEditingSession)) && + NS_SUCCEEDED(EnsureEditorData())) { + nsCOMPtr<nsIEditingSession> editingSession; + mEditorData->GetEditingSession(getter_AddRefs(editingSession)); + if (editingSession) { + *aSink = editingSession; + NS_ADDREF((nsISupports*)*aSink); + return NS_OK; + } + + return NS_NOINTERFACE; + } else if (aIID.Equals(NS_GET_IID(nsIClipboardDragDropHookList)) && + NS_SUCCEEDED(EnsureTransferableHookData())) { + *aSink = mTransferableHookData; + NS_ADDREF((nsISupports*)*aSink); + return NS_OK; + } else if (aIID.Equals(NS_GET_IID(nsISelectionDisplay))) { + nsIPresShell* shell = GetPresShell(); + if (shell) { + return shell->QueryInterface(aIID, aSink); + } + } else if (aIID.Equals(NS_GET_IID(nsIDocShellTreeOwner))) { + nsCOMPtr<nsIDocShellTreeOwner> treeOwner; + nsresult rv = GetTreeOwner(getter_AddRefs(treeOwner)); + if (NS_SUCCEEDED(rv) && treeOwner) { + return treeOwner->QueryInterface(aIID, aSink); + } + } else if (aIID.Equals(NS_GET_IID(nsITabChild))) { + nsCOMPtr<nsIDocShellTreeOwner> treeOwner; + nsresult rv = GetTreeOwner(getter_AddRefs(treeOwner)); + if (NS_SUCCEEDED(rv) && treeOwner) { + nsCOMPtr<nsIInterfaceRequestor> ir = do_QueryInterface(treeOwner); + if (ir) { + return ir->GetInterface(aIID, aSink); + } + } + } else if (aIID.Equals(NS_GET_IID(nsIContentFrameMessageManager))) { + nsCOMPtr<nsITabChild> tabChild = + do_GetInterface(static_cast<nsIDocShell*>(this)); + nsCOMPtr<nsIContentFrameMessageManager> mm; + if (tabChild) { + tabChild->GetMessageManager(getter_AddRefs(mm)); + } else { + nsCOMPtr<nsPIDOMWindow> win = GetWindow(); + if (win) { + mm = do_QueryInterface(win->GetParentTarget()); + } + } + *aSink = mm.get(); + } else { + return nsDocLoader::GetInterface(aIID, aSink); + } + + NS_IF_ADDREF(((nsISupports*)*aSink)); + return *aSink ? NS_OK : NS_NOINTERFACE; } uint32_t -nsDocShell:: -ConvertDocShellLoadInfoToLoadType(nsDocShellInfoLoadType aDocShellLoadType) -{ - uint32_t loadType = LOAD_NORMAL; - - switch (aDocShellLoadType) { +nsDocShell::ConvertDocShellLoadInfoToLoadType( + nsDocShellInfoLoadType aDocShellLoadType) +{ + uint32_t loadType = LOAD_NORMAL; + + switch (aDocShellLoadType) { case nsIDocShellLoadInfo::loadNormal: - loadType = LOAD_NORMAL; - break; + loadType = LOAD_NORMAL; + break; case nsIDocShellLoadInfo::loadNormalReplace: - loadType = LOAD_NORMAL_REPLACE; - break; + loadType = LOAD_NORMAL_REPLACE; + break; case nsIDocShellLoadInfo::loadNormalExternal: - loadType = LOAD_NORMAL_EXTERNAL; - break; + loadType = LOAD_NORMAL_EXTERNAL; + break; case nsIDocShellLoadInfo::loadHistory: - loadType = LOAD_HISTORY; - break; + loadType = LOAD_HISTORY; + break; case nsIDocShellLoadInfo::loadNormalBypassCache: - loadType = LOAD_NORMAL_BYPASS_CACHE; - break; + loadType = LOAD_NORMAL_BYPASS_CACHE; + break; case nsIDocShellLoadInfo::loadNormalBypassProxy: - loadType = LOAD_NORMAL_BYPASS_PROXY; - break; + loadType = LOAD_NORMAL_BYPASS_PROXY; + break; case nsIDocShellLoadInfo::loadNormalBypassProxyAndCache: - loadType = LOAD_NORMAL_BYPASS_PROXY_AND_CACHE; - break; + loadType = LOAD_NORMAL_BYPASS_PROXY_AND_CACHE; + break; case nsIDocShellLoadInfo::loadNormalAllowMixedContent: - loadType = LOAD_NORMAL_ALLOW_MIXED_CONTENT; - break; + loadType = LOAD_NORMAL_ALLOW_MIXED_CONTENT; + break; case nsIDocShellLoadInfo::loadReloadNormal: - loadType = LOAD_RELOAD_NORMAL; - break; + loadType = LOAD_RELOAD_NORMAL; + break; case nsIDocShellLoadInfo::loadReloadCharsetChange: - loadType = LOAD_RELOAD_CHARSET_CHANGE; - break; + loadType = LOAD_RELOAD_CHARSET_CHANGE; + break; case nsIDocShellLoadInfo::loadReloadBypassCache: - loadType = LOAD_RELOAD_BYPASS_CACHE; - break; + loadType = LOAD_RELOAD_BYPASS_CACHE; + break; case nsIDocShellLoadInfo::loadReloadBypassProxy: - loadType = LOAD_RELOAD_BYPASS_PROXY; - break; + loadType = LOAD_RELOAD_BYPASS_PROXY; + break; case nsIDocShellLoadInfo::loadReloadBypassProxyAndCache: - loadType = LOAD_RELOAD_BYPASS_PROXY_AND_CACHE; - break; + loadType = LOAD_RELOAD_BYPASS_PROXY_AND_CACHE; + break; case nsIDocShellLoadInfo::loadLink: - loadType = LOAD_LINK; - break; + loadType = LOAD_LINK; + break; case nsIDocShellLoadInfo::loadRefresh: - loadType = LOAD_REFRESH; - break; + loadType = LOAD_REFRESH; + break; case nsIDocShellLoadInfo::loadBypassHistory: - loadType = LOAD_BYPASS_HISTORY; - break; + loadType = LOAD_BYPASS_HISTORY; + break; case nsIDocShellLoadInfo::loadStopContent: - loadType = LOAD_STOP_CONTENT; - break; + loadType = LOAD_STOP_CONTENT; + break; case nsIDocShellLoadInfo::loadStopContentAndReplace: - loadType = LOAD_STOP_CONTENT_AND_REPLACE; - break; + loadType = LOAD_STOP_CONTENT_AND_REPLACE; + break; case nsIDocShellLoadInfo::loadPushState: - loadType = LOAD_PUSHSTATE; - break; + loadType = LOAD_PUSHSTATE; + break; case nsIDocShellLoadInfo::loadReplaceBypassCache: - loadType = LOAD_REPLACE_BYPASS_CACHE; - break; + loadType = LOAD_REPLACE_BYPASS_CACHE; + break; case nsIDocShellLoadInfo::loadReloadMixedContent: - loadType = LOAD_RELOAD_ALLOW_MIXED_CONTENT; - break; + loadType = LOAD_RELOAD_ALLOW_MIXED_CONTENT; + break; default: - NS_NOTREACHED("Unexpected nsDocShellInfoLoadType value"); - } - - return loadType; -} - + NS_NOTREACHED("Unexpected nsDocShellInfoLoadType value"); + } + + return loadType; +} nsDocShellInfoLoadType nsDocShell::ConvertLoadTypeToDocShellLoadInfo(uint32_t aLoadType) { - nsDocShellInfoLoadType docShellLoadType = nsIDocShellLoadInfo::loadNormal; - switch (aLoadType) { + nsDocShellInfoLoadType docShellLoadType = nsIDocShellLoadInfo::loadNormal; + switch (aLoadType) { case LOAD_NORMAL: - docShellLoadType = nsIDocShellLoadInfo::loadNormal; - break; + docShellLoadType = nsIDocShellLoadInfo::loadNormal; + break; case LOAD_NORMAL_REPLACE: - docShellLoadType = nsIDocShellLoadInfo::loadNormalReplace; - break; + docShellLoadType = nsIDocShellLoadInfo::loadNormalReplace; + break; case LOAD_NORMAL_EXTERNAL: - docShellLoadType = nsIDocShellLoadInfo::loadNormalExternal; - break; + docShellLoadType = nsIDocShellLoadInfo::loadNormalExternal; + break; case LOAD_NORMAL_BYPASS_CACHE: - docShellLoadType = nsIDocShellLoadInfo::loadNormalBypassCache; - break; + docShellLoadType = nsIDocShellLoadInfo::loadNormalBypassCache; + break; case LOAD_NORMAL_BYPASS_PROXY: - docShellLoadType = nsIDocShellLoadInfo::loadNormalBypassProxy; - break; + docShellLoadType = nsIDocShellLoadInfo::loadNormalBypassProxy; + break; case LOAD_NORMAL_BYPASS_PROXY_AND_CACHE: - docShellLoadType = nsIDocShellLoadInfo::loadNormalBypassProxyAndCache; - break; + docShellLoadType = nsIDocShellLoadInfo::loadNormalBypassProxyAndCache; + break; case LOAD_NORMAL_ALLOW_MIXED_CONTENT: - docShellLoadType = nsIDocShellLoadInfo::loadNormalAllowMixedContent; - break; + docShellLoadType = nsIDocShellLoadInfo::loadNormalAllowMixedContent; + break; case LOAD_HISTORY: - docShellLoadType = nsIDocShellLoadInfo::loadHistory; - break; + docShellLoadType = nsIDocShellLoadInfo::loadHistory; + break; case LOAD_RELOAD_NORMAL: - docShellLoadType = nsIDocShellLoadInfo::loadReloadNormal; - break; + docShellLoadType = nsIDocShellLoadInfo::loadReloadNormal; + break; case LOAD_RELOAD_CHARSET_CHANGE: - docShellLoadType = nsIDocShellLoadInfo::loadReloadCharsetChange; - break; + docShellLoadType = nsIDocShellLoadInfo::loadReloadCharsetChange; + break; case LOAD_RELOAD_BYPASS_CACHE: - docShellLoadType = nsIDocShellLoadInfo::loadReloadBypassCache; - break; + docShellLoadType = nsIDocShellLoadInfo::loadReloadBypassCache; + break; case LOAD_RELOAD_BYPASS_PROXY: - docShellLoadType = nsIDocShellLoadInfo::loadReloadBypassProxy; - break; + docShellLoadType = nsIDocShellLoadInfo::loadReloadBypassProxy; + break; case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE: - docShellLoadType = nsIDocShellLoadInfo::loadReloadBypassProxyAndCache; - break; + docShellLoadType = nsIDocShellLoadInfo::loadReloadBypassProxyAndCache; + break; case LOAD_LINK: - docShellLoadType = nsIDocShellLoadInfo::loadLink; - break; + docShellLoadType = nsIDocShellLoadInfo::loadLink; + break; case LOAD_REFRESH: - docShellLoadType = nsIDocShellLoadInfo::loadRefresh; - break; + docShellLoadType = nsIDocShellLoadInfo::loadRefresh; + break; case LOAD_BYPASS_HISTORY: case LOAD_ERROR_PAGE: - docShellLoadType = nsIDocShellLoadInfo::loadBypassHistory; - break; + docShellLoadType = nsIDocShellLoadInfo::loadBypassHistory; + break; case LOAD_STOP_CONTENT: - docShellLoadType = nsIDocShellLoadInfo::loadStopContent; - break; + docShellLoadType = nsIDocShellLoadInfo::loadStopContent; + break; case LOAD_STOP_CONTENT_AND_REPLACE: - docShellLoadType = nsIDocShellLoadInfo::loadStopContentAndReplace; - break; + docShellLoadType = nsIDocShellLoadInfo::loadStopContentAndReplace; + break; case LOAD_PUSHSTATE: - docShellLoadType = nsIDocShellLoadInfo::loadPushState; - break; + docShellLoadType = nsIDocShellLoadInfo::loadPushState; + break; case LOAD_REPLACE_BYPASS_CACHE: - docShellLoadType = nsIDocShellLoadInfo::loadReplaceBypassCache; - break; + docShellLoadType = nsIDocShellLoadInfo::loadReplaceBypassCache; + break; case LOAD_RELOAD_ALLOW_MIXED_CONTENT: - docShellLoadType = nsIDocShellLoadInfo::loadReloadMixedContent; - break; + docShellLoadType = nsIDocShellLoadInfo::loadReloadMixedContent; + break; default: - NS_NOTREACHED("Unexpected load type value"); - } - - return docShellLoadType; + NS_NOTREACHED("Unexpected load type value"); + } + + return docShellLoadType; } //***************************************************************************** // nsDocShell::nsIDocShell //***************************************************************************** NS_IMETHODIMP -nsDocShell::LoadURI(nsIURI * aURI, - nsIDocShellLoadInfo * aLoadInfo, +nsDocShell::LoadURI(nsIURI* aURI, + nsIDocShellLoadInfo* aLoadInfo, uint32_t aLoadFlags, bool aFirstParty) { - NS_PRECONDITION(aLoadInfo || (aLoadFlags & EXTRA_LOAD_FLAGS) == 0, - "Unexpected flags"); - NS_PRECONDITION((aLoadFlags & 0xf) == 0, "Should not have these flags set"); - - // Note: we allow loads to get through here even if mFiredUnloadEvent is - // true; that case will get handled in LoadInternal or LoadHistoryEntry, - // so we pass false as the second parameter to IsNavigationAllowed. - // However, we don't allow the page to change location *in the middle of* - // firing beforeunload, so we do need to check if *beforeunload* is currently - // firing, so we call IsNavigationAllowed rather than just IsPrintingOrPP. - if (!IsNavigationAllowed(true, false)) { - return NS_OK; // JS may not handle returning of an error code - } - - if (DoAppRedirectIfNeeded(aURI, aLoadInfo, aFirstParty)) { - return NS_OK; - } - - nsCOMPtr<nsIURI> referrer; - nsCOMPtr<nsIInputStream> postStream; - nsCOMPtr<nsIInputStream> headersStream; - nsCOMPtr<nsISupports> owner; - bool inheritOwner = false; - bool ownerIsExplicit = false; - bool sendReferrer = true; - uint32_t referrerPolicy = mozilla::net::RP_Default; - bool isSrcdoc = false; - nsCOMPtr<nsISHEntry> shEntry; - nsXPIDLString target; - nsAutoString srcdoc; - nsCOMPtr<nsIDocShell> sourceDocShell; - nsCOMPtr<nsIURI> baseURI; - - uint32_t loadType = MAKE_LOAD_TYPE(LOAD_NORMAL, aLoadFlags); - - NS_ENSURE_ARG(aURI); - - if (!StartupTimeline::HasRecord(StartupTimeline::FIRST_LOAD_URI) && - mItemType == typeContent && !NS_IsAboutBlank(aURI)) { - StartupTimeline::RecordOnce(StartupTimeline::FIRST_LOAD_URI); - } - - // Extract the info from the DocShellLoadInfo struct... - if (aLoadInfo) { - aLoadInfo->GetReferrer(getter_AddRefs(referrer)); - - nsDocShellInfoLoadType lt = nsIDocShellLoadInfo::loadNormal; - aLoadInfo->GetLoadType(<); - // Get the appropriate loadType from nsIDocShellLoadInfo type - loadType = ConvertDocShellLoadInfoToLoadType(lt); - - aLoadInfo->GetOwner(getter_AddRefs(owner)); - aLoadInfo->GetInheritOwner(&inheritOwner); - aLoadInfo->GetOwnerIsExplicit(&ownerIsExplicit); - aLoadInfo->GetSHEntry(getter_AddRefs(shEntry)); - aLoadInfo->GetTarget(getter_Copies(target)); - aLoadInfo->GetPostDataStream(getter_AddRefs(postStream)); - aLoadInfo->GetHeadersStream(getter_AddRefs(headersStream)); - aLoadInfo->GetSendReferrer(&sendReferrer); - aLoadInfo->GetReferrerPolicy(&referrerPolicy); - aLoadInfo->GetIsSrcdocLoad(&isSrcdoc); - aLoadInfo->GetSrcdocData(srcdoc); - aLoadInfo->GetSourceDocShell(getter_AddRefs(sourceDocShell)); - aLoadInfo->GetBaseURI(getter_AddRefs(baseURI)); - } + NS_PRECONDITION(aLoadInfo || (aLoadFlags & EXTRA_LOAD_FLAGS) == 0, + "Unexpected flags"); + NS_PRECONDITION((aLoadFlags & 0xf) == 0, "Should not have these flags set"); + + // Note: we allow loads to get through here even if mFiredUnloadEvent is + // true; that case will get handled in LoadInternal or LoadHistoryEntry, + // so we pass false as the second parameter to IsNavigationAllowed. + // However, we don't allow the page to change location *in the middle of* + // firing beforeunload, so we do need to check if *beforeunload* is currently + // firing, so we call IsNavigationAllowed rather than just IsPrintingOrPP. + if (!IsNavigationAllowed(true, false)) { + return NS_OK; // JS may not handle returning of an error code + } + + if (DoAppRedirectIfNeeded(aURI, aLoadInfo, aFirstParty)) { + return NS_OK; + } + + nsCOMPtr<nsIURI> referrer; + nsCOMPtr<nsIInputStream> postStream; + nsCOMPtr<nsIInputStream> headersStream; + nsCOMPtr<nsISupports> owner; + bool inheritOwner = false; + bool ownerIsExplicit = false; + bool sendReferrer = true; + uint32_t referrerPolicy = mozilla::net::RP_Default; + bool isSrcdoc = false; + nsCOMPtr<nsISHEntry> shEntry; + nsXPIDLString target; + nsAutoString srcdoc; + nsCOMPtr<nsIDocShell> sourceDocShell; + nsCOMPtr<nsIURI> baseURI; + + uint32_t loadType = MAKE_LOAD_TYPE(LOAD_NORMAL, aLoadFlags); + + NS_ENSURE_ARG(aURI); + + if (!StartupTimeline::HasRecord(StartupTimeline::FIRST_LOAD_URI) && + mItemType == typeContent && !NS_IsAboutBlank(aURI)) { + StartupTimeline::RecordOnce(StartupTimeline::FIRST_LOAD_URI); + } + + // Extract the info from the DocShellLoadInfo struct... + if (aLoadInfo) { + aLoadInfo->GetReferrer(getter_AddRefs(referrer)); + + nsDocShellInfoLoadType lt = nsIDocShellLoadInfo::loadNormal; + aLoadInfo->GetLoadType(<); + // Get the appropriate loadType from nsIDocShellLoadInfo type + loadType = ConvertDocShellLoadInfoToLoadType(lt); + + aLoadInfo->GetOwner(getter_AddRefs(owner)); + aLoadInfo->GetInheritOwner(&inheritOwner); + aLoadInfo->GetOwnerIsExplicit(&ownerIsExplicit); + aLoadInfo->GetSHEntry(getter_AddRefs(shEntry)); + aLoadInfo->GetTarget(getter_Copies(target)); + aLoadInfo->GetPostDataStream(getter_AddRefs(postStream)); + aLoadInfo->GetHeadersStream(getter_AddRefs(headersStream)); + aLoadInfo->GetSendReferrer(&sendReferrer); + aLoadInfo->GetReferrerPolicy(&referrerPolicy); + aLoadInfo->GetIsSrcdocLoad(&isSrcdoc); + aLoadInfo->GetSrcdocData(srcdoc); + aLoadInfo->GetSourceDocShell(getter_AddRefs(sourceDocShell)); + aLoadInfo->GetBaseURI(getter_AddRefs(baseURI)); + } #if defined(PR_LOGGING) && defined(DEBUG) - if (PR_LOG_TEST(gDocShellLog, PR_LOG_DEBUG)) { - nsAutoCString uristr; - aURI->GetAsciiSpec(uristr); - PR_LOG(gDocShellLog, PR_LOG_DEBUG, - ("nsDocShell[%p]: loading %s with flags 0x%08x", - this, uristr.get(), aLoadFlags)); - } + if (PR_LOG_TEST(gDocShellLog, PR_LOG_DEBUG)) { + nsAutoCString uristr; + aURI->GetAsciiSpec(uristr); + PR_LOG(gDocShellLog, PR_LOG_DEBUG, + ("nsDocShell[%p]: loading %s with flags 0x%08x", + this, uristr.get(), aLoadFlags)); + } #endif - if (!shEntry && - !LOAD_TYPE_HAS_FLAGS(loadType, LOAD_FLAGS_REPLACE_HISTORY)) { - // First verify if this is a subframe. - nsCOMPtr<nsIDocShellTreeItem> parentAsItem; - GetSameTypeParent(getter_AddRefs(parentAsItem)); - nsCOMPtr<nsIDocShell> parentDS(do_QueryInterface(parentAsItem)); - uint32_t parentLoadType; - - if (parentDS && parentDS != static_cast<nsIDocShell *>(this)) { - /* OK. It is a subframe. Checkout the - * parent's loadtype. If the parent was loaded thro' a history - * mechanism, then get the SH entry for the child from the parent. - * This is done to restore frameset navigation while going back/forward. - * If the parent was loaded through any other loadType, set the - * child's loadType too accordingly, so that session history does not - * get confused. - */ - - // Get the parent's load type - parentDS->GetLoadType(&parentLoadType); - - // Get the ShEntry for the child from the parent - nsCOMPtr<nsISHEntry> currentSH; - bool oshe = false; - parentDS->GetCurrentSHEntry(getter_AddRefs(currentSH), &oshe); - bool dynamicallyAddedChild = mDynamicallyCreated; - if (!dynamicallyAddedChild && !oshe && currentSH) { - currentSH->HasDynamicallyAddedChild(&dynamicallyAddedChild); - } - if (!dynamicallyAddedChild) { - // Only use the old SHEntry, if we're sure enough that - // it wasn't originally for some other frame. - parentDS->GetChildSHEntry(mChildOffset, getter_AddRefs(shEntry)); - } - - // Make some decisions on the child frame's loadType based on the - // parent's loadType. - if (mCurrentURI == nullptr) { - // This is a newly created frame. Check for exception cases first. - // By default the subframe will inherit the parent's loadType. - if (shEntry && (parentLoadType == LOAD_NORMAL || - parentLoadType == LOAD_LINK || - parentLoadType == LOAD_NORMAL_EXTERNAL)) { - // The parent was loaded normally. In this case, this *brand new* child really shouldn't - // have a SHEntry. If it does, it could be because the parent is replacing an - // existing frame with a new frame, in the onLoadHandler. We don't want this - // url to get into session history. Clear off shEntry, and set load type to - // LOAD_BYPASS_HISTORY. - bool inOnLoadHandler=false; - parentDS->GetIsExecutingOnLoadHandler(&inOnLoadHandler); - if (inOnLoadHandler) { - loadType = LOAD_NORMAL_REPLACE; - shEntry = nullptr; - } - } else if (parentLoadType == LOAD_REFRESH) { - // Clear shEntry. For refresh loads, we have to load - // what comes thro' the pipe, not what's in history. - shEntry = nullptr; - } else if ((parentLoadType == LOAD_BYPASS_HISTORY) || - (shEntry && - ((parentLoadType & LOAD_CMD_HISTORY) || - (parentLoadType == LOAD_RELOAD_NORMAL) || - (parentLoadType == LOAD_RELOAD_CHARSET_CHANGE)))) { - // If the parent url, bypassed history or was loaded from - // history, pass on the parent's loadType to the new child - // frame too, so that the child frame will also - // avoid getting into history. - loadType = parentLoadType; - } else if (parentLoadType == LOAD_ERROR_PAGE) { - // If the parent document is an error page, we don't - // want to update global/session history. However, - // this child frame is not an error page. - loadType = LOAD_BYPASS_HISTORY; - } else if ((parentLoadType == LOAD_RELOAD_BYPASS_CACHE) || - (parentLoadType == LOAD_RELOAD_BYPASS_PROXY) || - (parentLoadType == LOAD_RELOAD_BYPASS_PROXY_AND_CACHE)) { - // the new frame should inherit the parent's load type so that it also - // bypasses the cache and/or proxy - loadType = parentLoadType; - } - } else { - // This is a pre-existing subframe. If the load was not originally initiated - // by session history, (if (!shEntry) condition succeeded) and mCurrentURI is not null, - // it is possible that a parent's onLoadHandler or even self's onLoadHandler is loading - // a new page in this child. Check parent's and self's busy flag and if it is set, - // we don't want this onLoadHandler load to get in to session history. - uint32_t parentBusy = BUSY_FLAGS_NONE; - uint32_t selfBusy = BUSY_FLAGS_NONE; - parentDS->GetBusyFlags(&parentBusy); - GetBusyFlags(&selfBusy); - if (parentBusy & BUSY_FLAGS_BUSY || - selfBusy & BUSY_FLAGS_BUSY) { - loadType = LOAD_NORMAL_REPLACE; - shEntry = nullptr; - } - } - } //parentDS - else { - // This is the root docshell. If we got here while - // executing an onLoad Handler,this load will not go - // into session history. - bool inOnLoadHandler=false; - GetIsExecutingOnLoadHandler(&inOnLoadHandler); - if (inOnLoadHandler) { - loadType = LOAD_NORMAL_REPLACE; - } + if (!shEntry && + !LOAD_TYPE_HAS_FLAGS(loadType, LOAD_FLAGS_REPLACE_HISTORY)) { + // First verify if this is a subframe. + nsCOMPtr<nsIDocShellTreeItem> parentAsItem; + GetSameTypeParent(getter_AddRefs(parentAsItem)); + nsCOMPtr<nsIDocShell> parentDS(do_QueryInterface(parentAsItem)); + uint32_t parentLoadType; + + if (parentDS && parentDS != static_cast<nsIDocShell*>(this)) { + /* OK. It is a subframe. Checkout the + * parent's loadtype. If the parent was loaded thro' a history + * mechanism, then get the SH entry for the child from the parent. + * This is done to restore frameset navigation while going back/forward. + * If the parent was loaded through any other loadType, set the + * child's loadType too accordingly, so that session history does not + * get confused. + */ + + // Get the parent's load type + parentDS->GetLoadType(&parentLoadType); + + // Get the ShEntry for the child from the parent + nsCOMPtr<nsISHEntry> currentSH; + bool oshe = false; + parentDS->GetCurrentSHEntry(getter_AddRefs(currentSH), &oshe); + bool dynamicallyAddedChild = mDynamicallyCreated; + if (!dynamicallyAddedChild && !oshe && currentSH) { + currentSH->HasDynamicallyAddedChild(&dynamicallyAddedChild); + } + if (!dynamicallyAddedChild) { + // Only use the old SHEntry, if we're sure enough that + // it wasn't originally for some other frame. + parentDS->GetChildSHEntry(mChildOffset, getter_AddRefs(shEntry)); + } + + // Make some decisions on the child frame's loadType based on the + // parent's loadType. + if (!mCurrentURI) { + // This is a newly created frame. Check for exception cases first. + // By default the subframe will inherit the parent's loadType. + if (shEntry && (parentLoadType == LOAD_NORMAL || + parentLoadType == LOAD_LINK || + parentLoadType == LOAD_NORMAL_EXTERNAL)) { + // The parent was loaded normally. In this case, this *brand new* + // child really shouldn't have a SHEntry. If it does, it could be + // because the parent is replacing an existing frame with a new frame, + // in the onLoadHandler. We don't want this url to get into session + // history. Clear off shEntry, and set load type to + // LOAD_BYPASS_HISTORY. + bool inOnLoadHandler = false; + parentDS->GetIsExecutingOnLoadHandler(&inOnLoadHandler); + if (inOnLoadHandler) { + loadType = LOAD_NORMAL_REPLACE; + shEntry = nullptr; + } + } else if (parentLoadType == LOAD_REFRESH) { + // Clear shEntry. For refresh loads, we have to load + // what comes thro' the pipe, not what's in history. + shEntry = nullptr; + } else if ((parentLoadType == LOAD_BYPASS_HISTORY) || + (shEntry && + ((parentLoadType & LOAD_CMD_HISTORY) || + (parentLoadType == LOAD_RELOAD_NORMAL) || + (parentLoadType == LOAD_RELOAD_CHARSET_CHANGE)))) { + // If the parent url, bypassed history or was loaded from + // history, pass on the parent's loadType to the new child + // frame too, so that the child frame will also + // avoid getting into history. + loadType = parentLoadType; + } else if (parentLoadType == LOAD_ERROR_PAGE) { + // If the parent document is an error page, we don't + // want to update global/session history. However, + // this child frame is not an error page. + loadType = LOAD_BYPASS_HISTORY; + } else if ((parentLoadType == LOAD_RELOAD_BYPASS_CACHE) || + (parentLoadType == LOAD_RELOAD_BYPASS_PROXY) || + (parentLoadType == LOAD_RELOAD_BYPASS_PROXY_AND_CACHE)) { + // the new frame should inherit the parent's load type so that it also + // bypasses the cache and/or proxy + loadType = parentLoadType; } - } // !shEntry - - if (shEntry) { + } else { + // This is a pre-existing subframe. If the load was not originally + // initiated by session history, (if (!shEntry) condition succeeded) and + // mCurrentURI is not null, it is possible that a parent's onLoadHandler + // or even self's onLoadHandler is loading a new page in this child. + // Check parent's and self's busy flag and if it is set, we don't want + // this onLoadHandler load to get in to session history. + uint32_t parentBusy = BUSY_FLAGS_NONE; + uint32_t selfBusy = BUSY_FLAGS_NONE; + parentDS->GetBusyFlags(&parentBusy); + GetBusyFlags(&selfBusy); + if (parentBusy & BUSY_FLAGS_BUSY || + selfBusy & BUSY_FLAGS_BUSY) { + loadType = LOAD_NORMAL_REPLACE; + shEntry = nullptr; + } + } + } // parentDS + else { + // This is the root docshell. If we got here while + // executing an onLoad Handler,this load will not go + // into session history. + bool inOnLoadHandler = false; + GetIsExecutingOnLoadHandler(&inOnLoadHandler); + if (inOnLoadHandler) { + loadType = LOAD_NORMAL_REPLACE; + } + } + } // !shEntry + + if (shEntry) { #ifdef DEBUG - PR_LOG(gDocShellLog, PR_LOG_DEBUG, - ("nsDocShell[%p]: loading from session history", this)); + PR_LOG(gDocShellLog, PR_LOG_DEBUG, + ("nsDocShell[%p]: loading from session history", this)); #endif - return LoadHistoryEntry(shEntry, loadType); - } - - // On history navigation via Back/Forward buttons, don't execute - // automatic JavaScript redirection such as |location.href = ...| or - // |window.open()| - // - // LOAD_NORMAL: window.open(...) etc. - // LOAD_STOP_CONTENT: location.href = ..., location.assign(...) - if ((loadType == LOAD_NORMAL || loadType == LOAD_STOP_CONTENT) && - ShouldBlockLoadingForBackButton()) { - return NS_OK; - } - - // Perform the load... - - // We need an owner (a referring principal). - // - // If ownerIsExplicit is not set there are 4 possibilities: - // (1) If the system principal or an expanded principal was passed - // in and we're a typeContent docshell, inherit the principal - // from the current document instead. - // (2) In all other cases when the principal passed in is not null, - // use that principal. - // (3) If the caller has allowed inheriting from the current document, - // or if we're being called from system code (eg chrome JS or pure - // C++) then inheritOwner should be true and InternalLoad will get - // an owner from the current document. If none of these things are - // true, then - // (4) we pass a null owner into the channel, and an owner will be - // created later from the channel's internal data. - // - // If ownerIsExplicit *is* set, there are 4 possibilities - // (1) If the system principal or an expanded principal was passed in - // and we're a typeContent docshell, return an error. - // (2) In all other cases when the principal passed in is not null, - // use that principal. - // (3) If the caller has allowed inheriting from the current document, - // then inheritOwner should be true and InternalLoad will get an owner - // from the current document. If none of these things are true, then - // (4) we pass a null owner into the channel, and an owner will be - // created later from the channel's internal data. - // - // NOTE: This all only works because the only thing the owner is used - // for in InternalLoad is data:, javascript:, and about:blank - // URIs. For other URIs this would all be dead wrong! - - if (owner && mItemType != typeChrome) { - nsCOMPtr<nsIPrincipal> ownerPrincipal = do_QueryInterface(owner); - if (nsContentUtils::IsSystemOrExpandedPrincipal(ownerPrincipal)) { - if (ownerIsExplicit) { - return NS_ERROR_DOM_SECURITY_ERR; - } - owner = nullptr; - inheritOwner = true; - } - } - if (!owner && !inheritOwner && !ownerIsExplicit) { - // See if there's system or chrome JS code running - inheritOwner = nsContentUtils::IsCallerChrome(); - } - - if (aLoadFlags & LOAD_FLAGS_DISALLOW_INHERIT_OWNER) { - inheritOwner = false; - owner = do_CreateInstance("@mozilla.org/nullprincipal;1"); - } - - uint32_t flags = 0; - - if (inheritOwner) - flags |= INTERNAL_LOAD_FLAGS_INHERIT_OWNER; - - if (!sendReferrer) - flags |= INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER; - - if (aLoadFlags & LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP) - flags |= INTERNAL_LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP; - - if (aLoadFlags & LOAD_FLAGS_FIRST_LOAD) - flags |= INTERNAL_LOAD_FLAGS_FIRST_LOAD; - - if (aLoadFlags & LOAD_FLAGS_BYPASS_CLASSIFIER) - flags |= INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER; - - if (aLoadFlags & LOAD_FLAGS_FORCE_ALLOW_COOKIES) - flags |= INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES; - - if (isSrcdoc) - flags |= INTERNAL_LOAD_FLAGS_IS_SRCDOC; - - return InternalLoad(aURI, - referrer, - referrerPolicy, - owner, - flags, - target.get(), - nullptr, // No type hint - NullString(), // No forced download - postStream, - headersStream, - loadType, - nullptr, // No SHEntry - aFirstParty, - srcdoc, - sourceDocShell, - baseURI, - nullptr, // No nsIDocShell - nullptr); // No nsIRequest -} - -NS_IMETHODIMP -nsDocShell::LoadStream(nsIInputStream *aStream, nsIURI * aURI, - const nsACString &aContentType, - const nsACString &aContentCharset, - nsIDocShellLoadInfo * aLoadInfo) -{ - NS_ENSURE_ARG(aStream); - - mAllowKeywordFixup = false; - - // if the caller doesn't pass in a URI we need to create a dummy URI. necko - // currently requires a URI in various places during the load. Some consumers - // do as well. - nsCOMPtr<nsIURI> uri = aURI; - if (!uri) { - // HACK ALERT - nsresult rv = NS_OK; - uri = do_CreateInstance(NS_SIMPLEURI_CONTRACTID, &rv); - if (NS_FAILED(rv)) - return rv; - // Make sure that the URI spec "looks" like a protocol and path... - // For now, just use a bogus protocol called "internal" - rv = uri->SetSpec(NS_LITERAL_CSTRING("internal:load-stream")); - if (NS_FAILED(rv)) - return rv; - } - - uint32_t loadType = LOAD_NORMAL; - if (aLoadInfo) { - nsDocShellInfoLoadType lt = nsIDocShellLoadInfo::loadNormal; - (void) aLoadInfo->GetLoadType(<); - // Get the appropriate LoadType from nsIDocShellLoadInfo type - loadType = ConvertDocShellLoadInfoToLoadType(lt); - } - - NS_ENSURE_SUCCESS(Stop(nsIWebNavigation::STOP_NETWORK), NS_ERROR_FAILURE); - - mLoadType = loadType; - - nsCOMPtr<nsISupports> owner; - aLoadInfo->GetOwner(getter_AddRefs(owner)); - nsCOMPtr<nsIPrincipal> requestingPrincipal = do_QueryInterface(owner); - if (!requestingPrincipal) { - requestingPrincipal = nsContentUtils::GetSystemPrincipal(); - } - - // build up a channel for this stream. - nsCOMPtr<nsIChannel> channel; - nsresult rv = - NS_NewInputStreamChannel(getter_AddRefs(channel), - uri, - aStream, - requestingPrincipal, - nsILoadInfo::SEC_NORMAL, - nsIContentPolicy::TYPE_OTHER, - aContentType, - aContentCharset); - NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); - - nsCOMPtr<nsIURILoader> - uriLoader(do_GetService(NS_URI_LOADER_CONTRACTID)); - NS_ENSURE_TRUE(uriLoader, NS_ERROR_FAILURE); - - NS_ENSURE_SUCCESS(DoChannelLoad(channel, uriLoader, false), - NS_ERROR_FAILURE); - return NS_OK; -} - -NS_IMETHODIMP -nsDocShell::CreateLoadInfo(nsIDocShellLoadInfo ** aLoadInfo) -{ - nsDocShellLoadInfo *loadInfo = new nsDocShellLoadInfo(); - NS_ENSURE_TRUE(loadInfo, NS_ERROR_OUT_OF_MEMORY); - nsCOMPtr<nsIDocShellLoadInfo> localRef(loadInfo); - - *aLoadInfo = localRef; - NS_ADDREF(*aLoadInfo); - return NS_OK; -} - + return LoadHistoryEntry(shEntry, loadType); + } + + // On history navigation via Back/Forward buttons, don't execute + // automatic JavaScript redirection such as |location.href = ...| or + // |window.open()| + // + // LOAD_NORMAL: window.open(...) etc. + // LOAD_STOP_CONTENT: location.href = ..., location.assign(...) + if ((loadType == LOAD_NORMAL || loadType == LOAD_STOP_CONTENT) && + ShouldBlockLoadingForBackButton()) { + return NS_OK; + } + + // Perform the load... + + // We need an owner (a referring principal). + // + // If ownerIsExplicit is not set there are 4 possibilities: + // (1) If the system principal or an expanded principal was passed + // in and we're a typeContent docshell, inherit the principal + // from the current document instead. + // (2) In all other cases when the principal passed in is not null, + // use that principal. + // (3) If the caller has allowed inheriting from the current document, + // or if we're being called from system code (eg chrome JS or pure + // C++) then inheritOwner should be true and InternalLoad will get + // an owner from the current document. If none of these things are + // true, then + // (4) we pass a null owner into the channel, and an owner will be + // created later from the channel's internal data. + // + // If ownerIsExplicit *is* set, there are 4 possibilities + // (1) If the system principal or an expanded principal was passed in + // and we're a typeContent docshell, return an error. + // (2) In all other cases when the principal passed in is not null, + // use that principal. + // (3) If the caller has allowed inheriting from the current document, + // then inheritOwner should be true and InternalLoad will get an owner + // from the current document. If none of these things are true, then + // (4) we pass a null owner into the channel, and an owner will be + // created later from the channel's internal data. + // + // NOTE: This all only works because the only thing the owner is used + // for in InternalLoad is data:, javascript:, and about:blank + // URIs. For other URIs this would all be dead wrong! + + if (owner && mItemType != typeChrome) { + nsCOMPtr<nsIPrincipal> ownerPrincipal = do_QueryInterface(owner); + if (nsContentUtils::IsSystemOrExpandedPrincipal(ownerPrincipal)) { + if (ownerIsExplicit) { + return NS_ERROR_DOM_SECURITY_ERR; + } + owner = nullptr; + inheritOwner = true; + } + } + if (!owner && !inheritOwner && !ownerIsExplicit) { + // See if there's system or chrome JS code running + inheritOwner = nsContentUtils::IsCallerChrome(); + } + + if (aLoadFlags & LOAD_FLAGS_DISALLOW_INHERIT_OWNER) { + inheritOwner = false; + owner = do_CreateInstance("@mozilla.org/nullprincipal;1"); + } + + uint32_t flags = 0; + + if (inheritOwner) { + flags |= INTERNAL_LOAD_FLAGS_INHERIT_OWNER; + } + + if (!sendReferrer) { + flags |= INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER; + } + + if (aLoadFlags & LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP) { + flags |= INTERNAL_LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP; + } + + if (aLoadFlags & LOAD_FLAGS_FIRST_LOAD) { + flags |= INTERNAL_LOAD_FLAGS_FIRST_LOAD; + } + + if (aLoadFlags & LOAD_FLAGS_BYPASS_CLASSIFIER) { + flags |= INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER; + } + + if (aLoadFlags & LOAD_FLAGS_FORCE_ALLOW_COOKIES) { + flags |= INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES; + } + + if (isSrcdoc) { + flags |= INTERNAL_LOAD_FLAGS_IS_SRCDOC; + } + + return InternalLoad(aURI, + referrer, + referrerPolicy, + owner, + flags, + target.get(), + nullptr, // No type hint + NullString(), // No forced download + postStream, + headersStream, + loadType, + nullptr, // No SHEntry + aFirstParty, + srcdoc, + sourceDocShell, + baseURI, + nullptr, // No nsIDocShell + nullptr); // No nsIRequest +} + +NS_IMETHODIMP +nsDocShell::LoadStream(nsIInputStream* aStream, nsIURI* aURI, + const nsACString& aContentType, + const nsACString& aContentCharset, + nsIDocShellLoadInfo* aLoadInfo) +{ + NS_ENSURE_ARG(aStream); + + mAllowKeywordFixup = false; + + // if the caller doesn't pass in a URI we need to create a dummy URI. necko + // currently requires a URI in various places during the load. Some consumers + // do as well. + nsCOMPtr<nsIURI> uri = aURI; + if (!uri) { + // HACK ALERT + nsresult rv = NS_OK; + uri = do_CreateInstance(NS_SIMPLEURI_CONTRACTID, &rv); + if (NS_FAILED(rv)) { + return rv; + } + // Make sure that the URI spec "looks" like a protocol and path... + // For now, just use a bogus protocol called "internal" + rv = uri->SetSpec(NS_LITERAL_CSTRING("internal:load-stream")); + if (NS_FAILED(rv)) { + return rv; + } + } + + uint32_t loadType = LOAD_NORMAL; + if (aLoadInfo) { + nsDocShellInfoLoadType lt = nsIDocShellLoadInfo::loadNormal; + (void)aLoadInfo->GetLoadType(<); + // Get the appropriate LoadType from nsIDocShellLoadInfo type + loadType = ConvertDocShellLoadInfoToLoadType(lt); + } + + NS_ENSURE_SUCCESS(Stop(nsIWebNavigation::STOP_NETWORK), NS_ERROR_FAILURE); + + mLoadType = loadType; + + nsCOMPtr<nsISupports> owner; + aLoadInfo->GetOwner(getter_AddRefs(owner)); + nsCOMPtr<nsIPrincipal> requestingPrincipal = do_QueryInterface(owner); + if (!requestingPrincipal) { + requestingPrincipal = nsContentUtils::GetSystemPrincipal(); + } + + // build up a channel for this stream. + nsCOMPtr<nsIChannel> channel; + nsresult rv = NS_NewInputStreamChannel(getter_AddRefs(channel), + uri, + aStream, + requestingPrincipal, + nsILoadInfo::SEC_NORMAL, + nsIContentPolicy::TYPE_OTHER, + aContentType, + aContentCharset); + NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE); + + nsCOMPtr<nsIURILoader> uriLoader(do_GetService(NS_URI_LOADER_CONTRACTID)); + NS_ENSURE_TRUE(uriLoader, NS_ERROR_FAILURE); + + NS_ENSURE_SUCCESS(DoChannelLoad(channel, uriLoader, false), + NS_ERROR_FAILURE); + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::CreateLoadInfo(nsIDocShellLoadInfo** aLoadInfo) +{ + nsDocShellLoadInfo* loadInfo = new nsDocShellLoadInfo(); + NS_ENSURE_TRUE(loadInfo, NS_ERROR_OUT_OF_MEMORY); + nsCOMPtr<nsIDocShellLoadInfo> localRef(loadInfo); + + *aLoadInfo = localRef; + NS_ADDREF(*aLoadInfo); + return NS_OK; +} /* - * Reset state to a new content model within the current document and the document - * viewer. Called by the document before initiating an out of band document.write(). + * Reset state to a new content model within the current document and the + * document viewer. Called by the document before initiating an out of band + * document.write(). */ NS_IMETHODIMP nsDocShell::PrepareForNewContentModel() { mEODForCurrentDocument = false; return NS_OK; } - NS_IMETHODIMP nsDocShell::FirePageHideNotification(bool aIsUnload) { - if (mContentViewer && !mFiredUnloadEvent) { - // Keep an explicit reference since calling PageHide could release - // mContentViewer - nsCOMPtr<nsIContentViewer> kungFuDeathGrip(mContentViewer); - mFiredUnloadEvent = true; - - if (mTiming) { - mTiming->NotifyUnloadEventStart(); - } - - mContentViewer->PageHide(aIsUnload); - - if (mTiming) { - mTiming->NotifyUnloadEventEnd(); - } - - nsAutoTArray<nsCOMPtr<nsIDocShell>, 8> kids; - uint32_t n = mChildList.Length(); - kids.SetCapacity(n); - for (uint32_t i = 0; i < n; i++) { - kids.AppendElement(do_QueryInterface(ChildAt(i))); - } - - n = kids.Length(); - for (uint32_t i = 0; i < n; ++i) { - if (kids[i]) { - kids[i]->FirePageHideNotification(aIsUnload); - } - } - // Now make sure our editor, if any, is detached before we go - // any farther. - DetachEditorFromWindow(); - } - - return NS_OK; + if (mContentViewer && !mFiredUnloadEvent) { + // Keep an explicit reference since calling PageHide could release + // mContentViewer + nsCOMPtr<nsIContentViewer> kungFuDeathGrip(mContentViewer); + mFiredUnloadEvent = true; + + if (mTiming) { + mTiming->NotifyUnloadEventStart(); + } + + mContentViewer->PageHide(aIsUnload); + + if (mTiming) { + mTiming->NotifyUnloadEventEnd(); + } + + nsAutoTArray<nsCOMPtr<nsIDocShell>, 8> kids; + uint32_t n = mChildList.Length(); + kids.SetCapacity(n); + for (uint32_t i = 0; i < n; i++) { + kids.AppendElement(do_QueryInterface(ChildAt(i))); + } + + n = kids.Length(); + for (uint32_t i = 0; i < n; ++i) { + if (kids[i]) { + kids[i]->FirePageHideNotification(aIsUnload); + } + } + // Now make sure our editor, if any, is detached before we go + // any farther. + DetachEditorFromWindow(); + } + + return NS_OK; } void nsDocShell::MaybeInitTiming() { - if (mTiming && !mBlankTiming) { - return; - } - - if (mScriptGlobal && mBlankTiming) { - nsPIDOMWindow* innerWin = mScriptGlobal->GetCurrentInnerWindow(); - if (innerWin && innerWin->GetPerformance()) { - mTiming = innerWin->GetPerformance()->GetDOMTiming(); - mBlankTiming = false; - } - } - - if (!mTiming) { - mTiming = new nsDOMNavigationTiming(); - } - - mTiming->NotifyNavigationStart(); -} - + if (mTiming && !mBlankTiming) { + return; + } + + if (mScriptGlobal && mBlankTiming) { + nsPIDOMWindow* innerWin = mScriptGlobal->GetCurrentInnerWindow(); + if (innerWin && innerWin->GetPerformance()) { + mTiming = innerWin->GetPerformance()->GetDOMTiming(); + mBlankTiming = false; + } + } + + if (!mTiming) { + mTiming = new nsDOMNavigationTiming(); + } + + mTiming->NotifyNavigationStart(); +} // // Bug 13871: Prevent frameset spoofing // // This routine answers: 'Is origin's document from same domain as // target's document?' // // file: uris are considered the same domain for the purpose of // frame navigation regardless of script accessibility (bug 420425) // -/* static */ -bool +/* static */ bool nsDocShell::ValidateOrigin(nsIDocShellTreeItem* aOriginTreeItem, nsIDocShellTreeItem* aTargetTreeItem) { - // We want to bypass this check for chrome callers, but only if there's - // JS on the stack. System callers still need to do it. - if (nsContentUtils::GetCurrentJSContext() && nsContentUtils::IsCallerChrome()) { - return true; - } - - MOZ_ASSERT(aOriginTreeItem && aTargetTreeItem, "need two docshells"); - - // Get origin document principal - nsCOMPtr<nsIDocument> originDocument = aOriginTreeItem->GetDocument(); - NS_ENSURE_TRUE(originDocument, false); - - // Get target principal - nsCOMPtr<nsIDocument> targetDocument = aTargetTreeItem->GetDocument(); - NS_ENSURE_TRUE(targetDocument, false); - - bool equal; - nsresult rv = originDocument->NodePrincipal()->Equals(targetDocument->NodePrincipal(), - &equal); - if (NS_SUCCEEDED(rv) && equal) { - return true; - } - - // Not strictly equal, special case if both are file: uris - bool originIsFile = false; - bool targetIsFile = false; - nsCOMPtr<nsIURI> originURI; - nsCOMPtr<nsIURI> targetURI; - nsCOMPtr<nsIURI> innerOriginURI; - nsCOMPtr<nsIURI> innerTargetURI; - - rv = originDocument->NodePrincipal()->GetURI(getter_AddRefs(originURI)); - if (NS_SUCCEEDED(rv) && originURI) - innerOriginURI = NS_GetInnermostURI(originURI); - - rv = targetDocument->NodePrincipal()->GetURI(getter_AddRefs(targetURI)); - if (NS_SUCCEEDED(rv) && targetURI) - innerTargetURI = NS_GetInnermostURI(targetURI); - - return innerOriginURI && innerTargetURI && - NS_SUCCEEDED(innerOriginURI->SchemeIs("file", &originIsFile)) && - NS_SUCCEEDED(innerTargetURI->SchemeIs("file", &targetIsFile)) && - originIsFile && targetIsFile; + // We want to bypass this check for chrome callers, but only if there's + // JS on the stack. System callers still need to do it. + if (nsContentUtils::GetCurrentJSContext() && + nsContentUtils::IsCallerChrome()) { + return true; + } + + MOZ_ASSERT(aOriginTreeItem && aTargetTreeItem, "need two docshells"); + + // Get origin document principal + nsCOMPtr<nsIDocument> originDocument = aOriginTreeItem->GetDocument(); + NS_ENSURE_TRUE(originDocument, false); + + // Get target principal + nsCOMPtr<nsIDocument> targetDocument = aTargetTreeItem->GetDocument(); + NS_ENSURE_TRUE(targetDocument, false); + + bool equal; + nsresult rv = originDocument->NodePrincipal()->Equals( + targetDocument->NodePrincipal(), &equal); + if (NS_SUCCEEDED(rv) && equal) { + return true; + } + + // Not strictly equal, special case if both are file: uris + bool originIsFile = false; + bool targetIsFile = false; + nsCOMPtr<nsIURI> originURI; + nsCOMPtr<nsIURI> targetURI; + nsCOMPtr<nsIURI> innerOriginURI; + nsCOMPtr<nsIURI> innerTargetURI; + + rv = originDocument->NodePrincipal()->GetURI(getter_AddRefs(originURI)); + if (NS_SUCCEEDED(rv) && originURI) { + innerOriginURI = NS_GetInnermostURI(originURI); + } + + rv = targetDocument->NodePrincipal()->GetURI(getter_AddRefs(targetURI)); + if (NS_SUCCEEDED(rv) && targetURI) { + innerTargetURI = NS_GetInnermostURI(targetURI); + } + + return innerOriginURI && innerTargetURI && + NS_SUCCEEDED(innerOriginURI->SchemeIs("file", &originIsFile)) && + NS_SUCCEEDED(innerTargetURI->SchemeIs("file", &targetIsFile)) && + originIsFile && targetIsFile; } nsresult nsDocShell::GetEldestPresContext(nsPresContext** aPresContext) { - NS_ENSURE_ARG_POINTER(aPresContext); - *aPresContext = nullptr; - - nsCOMPtr<nsIContentViewer> viewer = mContentViewer; - while (viewer) { - nsCOMPtr<nsIContentViewer> prevViewer; - viewer->GetPreviousViewer(getter_AddRefs(prevViewer)); - if (!prevViewer) { - return viewer->GetPresContext(aPresContext); - } - viewer = prevViewer; - } - - return NS_OK; -} - -NS_IMETHODIMP -nsDocShell::GetPresContext(nsPresContext ** aPresContext) -{ - NS_ENSURE_ARG_POINTER(aPresContext); - *aPresContext = nullptr; - - if (!mContentViewer) - return NS_OK; - - return mContentViewer->GetPresContext(aPresContext); + NS_ENSURE_ARG_POINTER(aPresContext); + *aPresContext = nullptr; + + nsCOMPtr<nsIContentViewer> viewer = mContentViewer; + while (viewer) { + nsCOMPtr<nsIContentViewer> prevViewer; + viewer->GetPreviousViewer(getter_AddRefs(prevViewer)); + if (!prevViewer) { + return viewer->GetPresContext(aPresContext); + } + viewer = prevViewer; + } + + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::GetPresContext(nsPresContext** aPresContext) +{ + NS_ENSURE_ARG_POINTER(aPresContext); + *aPresContext = nullptr; + + if (!mContentViewer) { + return NS_OK; + } + + return mContentViewer->GetPresContext(aPresContext); } NS_IMETHODIMP_(nsIPresShell*) nsDocShell::GetPresShell() { - nsRefPtr<nsPresContext> presContext; - (void) GetPresContext(getter_AddRefs(presContext)); - return presContext ? presContext->GetPresShell() : nullptr; + nsRefPtr<nsPresContext> presContext; + (void)GetPresContext(getter_AddRefs(presContext)); + return presContext ? presContext->GetPresShell() : nullptr; } NS_IMETHODIMP nsDocShell::GetEldestPresShell(nsIPresShell** aPresShell) { - nsresult rv = NS_OK; - - NS_ENSURE_ARG_POINTER(aPresShell); - *aPresShell = nullptr; - - nsRefPtr<nsPresContext> presContext; - (void) GetEldestPresContext(getter_AddRefs(presContext)); - - if (presContext) { - NS_IF_ADDREF(*aPresShell = presContext->GetPresShell()); - } - - return rv; -} - -NS_IMETHODIMP -nsDocShell::GetContentViewer(nsIContentViewer ** aContentViewer) -{ - NS_ENSURE_ARG_POINTER(aContentViewer); - - *aContentViewer = mContentViewer; - NS_IF_ADDREF(*aContentViewer); - return NS_OK; + nsresult rv = NS_OK; + + NS_ENSURE_ARG_POINTER(aPresShell); + *aPresShell = nullptr; + + nsRefPtr<nsPresContext> presContext; + (void)GetEldestPresContext(getter_AddRefs(presContext)); + + if (presContext) { + NS_IF_ADDREF(*aPresShell = presContext->GetPresShell()); + } + + return rv; +} + +NS_IMETHODIMP +nsDocShell::GetContentViewer(nsIContentViewer** aContentViewer) +{ + NS_ENSURE_ARG_POINTER(aContentViewer); + + *aContentViewer = mContentViewer; + NS_IF_ADDREF(*aContentViewer); + return NS_OK; } NS_IMETHODIMP nsDocShell::SetChromeEventHandler(nsIDOMEventTarget* aChromeEventHandler) { - // Weak reference. Don't addref. - nsCOMPtr<EventTarget> handler = do_QueryInterface(aChromeEventHandler); - mChromeEventHandler = handler.get(); - - if (mScriptGlobal) { - mScriptGlobal->SetChromeEventHandler(mChromeEventHandler); - } - - return NS_OK; + // Weak reference. Don't addref. + nsCOMPtr<EventTarget> handler = do_QueryInterface(aChromeEventHandler); + mChromeEventHandler = handler.get(); + + if (mScriptGlobal) { + mScriptGlobal->SetChromeEventHandler(mChromeEventHandler); + } + + return NS_OK; } NS_IMETHODIMP nsDocShell::GetChromeEventHandler(nsIDOMEventTarget** aChromeEventHandler) { - NS_ENSURE_ARG_POINTER(aChromeEventHandler); - nsCOMPtr<EventTarget> handler = mChromeEventHandler; - handler.forget(aChromeEventHandler); - return NS_OK; + NS_ENSURE_ARG_POINTER(aChromeEventHandler); + nsCOMPtr<EventTarget> handler = mChromeEventHandler; + handler.forget(aChromeEventHandler); + return NS_OK; } /* void setCurrentURI (in nsIURI uri); */ NS_IMETHODIMP -nsDocShell::SetCurrentURI(nsIURI *aURI) -{ - // Note that securityUI will set STATE_IS_INSECURE, even if - // the scheme of |aURI| is "https". - SetCurrentURI(aURI, nullptr, true, 0); - return NS_OK; +nsDocShell::SetCurrentURI(nsIURI* aURI) +{ + // Note that securityUI will set STATE_IS_INSECURE, even if + // the scheme of |aURI| is "https". + SetCurrentURI(aURI, nullptr, true, 0); + return NS_OK; } bool -nsDocShell::SetCurrentURI(nsIURI *aURI, nsIRequest *aRequest, +nsDocShell::SetCurrentURI(nsIURI* aURI, nsIRequest* aRequest, bool aFireOnLocationChange, uint32_t aLocationFlags) { #ifdef PR_LOGGING - if (gDocShellLeakLog && PR_LOG_TEST(gDocShellLeakLog, PR_LOG_DEBUG)) { - nsAutoCString spec; - if (aURI) - aURI->GetSpec(spec); - PR_LogPrint("DOCSHELL %p SetCurrentURI %s\n", this, spec.get()); - } + if (gDocShellLeakLog && PR_LOG_TEST(gDocShellLeakLog, PR_LOG_DEBUG)) { + nsAutoCString spec; + if (aURI) { + aURI->GetSpec(spec); + } + PR_LogPrint("DOCSHELL %p SetCurrentURI %s\n", this, spec.get()); + } #endif - // We don't want to send a location change when we're displaying an error - // page, and we don't want to change our idea of "current URI" either - if (mLoadType == LOAD_ERROR_PAGE) { - return false; - } - - mCurrentURI = NS_TryToMakeImmutable(aURI); - - if (!NS_IsAboutBlank(mCurrentURI)) { - mHasLoadedNonBlankURI = true; - } - - bool isRoot = false; // Is this the root docshell - bool isSubFrame = false; // Is this a subframe navigation? - - nsCOMPtr<nsIDocShellTreeItem> root; - - GetSameTypeRootTreeItem(getter_AddRefs(root)); - if (root.get() == static_cast<nsIDocShellTreeItem *>(this)) - { - // This is the root docshell - isRoot = true; - } - if (mLSHE) { - mLSHE->GetIsSubFrame(&isSubFrame); - } - - // nsDocShell owns a URLSearchParams that is used by - // window.location.searchParams to be in sync with the current location. - if (!mURLSearchParams) { - mURLSearchParams = new URLSearchParams(); - } - - nsAutoCString search; - - nsCOMPtr<nsIURL> url(do_QueryInterface(mCurrentURI)); - if (url) { - nsresult rv = url->GetQuery(search); - if (NS_FAILED(rv)) { - NS_WARNING("Failed to get the query from a nsIURL."); - } - } - - mURLSearchParams->ParseInput(search, nullptr); - - if (!isSubFrame && !isRoot) { - /* - * We don't want to send OnLocationChange notifications when - * a subframe is being loaded for the first time, while - * visiting a frameset page - */ - return false; - } - - if (aFireOnLocationChange) { - FireOnLocationChange(this, aRequest, aURI, aLocationFlags); - } - return !aFireOnLocationChange; + // We don't want to send a location change when we're displaying an error + // page, and we don't want to change our idea of "current URI" either + if (mLoadType == LOAD_ERROR_PAGE) { + return false; + } + + mCurrentURI = NS_TryToMakeImmutable(aURI); + + if (!NS_IsAboutBlank(mCurrentURI)) { + mHasLoadedNonBlankURI = true; + } + + bool isRoot = false; // Is this the root docshell + bool isSubFrame = false; // Is this a subframe navigation? + + nsCOMPtr<nsIDocShellTreeItem> root; + + GetSameTypeRootTreeItem(getter_AddRefs(root)); + if (root.get() == static_cast<nsIDocShellTreeItem*>(this)) { + // This is the root docshell + isRoot = true; + } + if (mLSHE) { + mLSHE->GetIsSubFrame(&isSubFrame); + } + + // nsDocShell owns a URLSearchParams that is used by + // window.location.searchParams to be in sync with the current location. + if (!mURLSearchParams) { + mURLSearchParams = new URLSearchParams(); + } + + nsAutoCString search; + + nsCOMPtr<nsIURL> url(do_QueryInterface(mCurrentURI)); + if (url) { + nsresult rv = url->GetQuery(search); + if (NS_FAILED(rv)) { + NS_WARNING("Failed to get the query from a nsIURL."); + } + } + + mURLSearchParams->ParseInput(search, nullptr); + + if (!isSubFrame && !isRoot) { + /* + * We don't want to send OnLocationChange notifications when + * a subframe is being loaded for the first time, while + * visiting a frameset page + */ + return false; + } + + if (aFireOnLocationChange) { + FireOnLocationChange(this, aRequest, aURI, aLocationFlags); + } + return !aFireOnLocationChange; } NS_IMETHODIMP nsDocShell::GetCharset(nsACString& aCharset) { - aCharset.Truncate(); - - nsIPresShell* presShell = GetPresShell(); - NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE); - nsIDocument *doc = presShell->GetDocument(); - NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE); - aCharset = doc->GetDocumentCharacterSet(); - return NS_OK; + aCharset.Truncate(); + + nsIPresShell* presShell = GetPresShell(); + NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE); + nsIDocument* doc = presShell->GetDocument(); + NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE); + aCharset = doc->GetDocumentCharacterSet(); + return NS_OK; } NS_IMETHODIMP nsDocShell::GatherCharsetMenuTelemetry() { nsCOMPtr<nsIContentViewer> viewer; GetContentViewer(getter_AddRefs(viewer)); if (!viewer) { @@ -2104,21 +2126,22 @@ nsDocShell::GatherCharsetMenuTelemetry() break; } return NS_OK; } NS_IMETHODIMP nsDocShell::SetCharset(const nsACString& aCharset) { - // set the charset override - return SetForcedCharset(aCharset); -} - -NS_IMETHODIMP nsDocShell::SetForcedCharset(const nsACString& aCharset) + // set the charset override + return SetForcedCharset(aCharset); +} + +NS_IMETHODIMP +nsDocShell::SetForcedCharset(const nsACString& aCharset) { if (aCharset.IsEmpty()) { mForcedCharset.Truncate(); return NS_OK; } nsAutoCString encoding; if (!EncodingUtils::FindEncodingForLabel(aCharset, encoding)) { // Reject unknown labels @@ -2127,17 +2150,18 @@ NS_IMETHODIMP nsDocShell::SetForcedChars if (!EncodingUtils::IsAsciiCompatible(encoding)) { // Reject XSS hazards return NS_ERROR_INVALID_ARG; } mForcedCharset = encoding; return NS_OK; } -NS_IMETHODIMP nsDocShell::GetForcedCharset(nsACString& aResult) +NS_IMETHODIMP +nsDocShell::GetForcedCharset(nsACString& aResult) { aResult = mForcedCharset; return NS_OK; } void nsDocShell::SetParentCharset(const nsACString& aCharset, int32_t aCharsetSource, @@ -2154,463 +2178,481 @@ nsDocShell::GetParentCharset(nsACString& nsIPrincipal** aPrincipal) { aCharset = mParentCharset; *aCharsetSource = mParentCharsetSource; NS_IF_ADDREF(*aPrincipal = mParentCharsetPrincipal); } NS_IMETHODIMP -nsDocShell::GetChannelIsUnsafe(bool *aUnsafe) -{ - *aUnsafe = false; - - nsIChannel* channel = GetCurrentDocChannel(); - if (!channel) { - return NS_OK; - } - - nsCOMPtr<nsIJARChannel> jarChannel = do_QueryInterface(channel); - if (!jarChannel) { - return NS_OK; - } - - return jarChannel->GetIsUnsafe(aUnsafe); +nsDocShell::GetChannelIsUnsafe(bool* aUnsafe) +{ + *aUnsafe = false; + + nsIChannel* channel = GetCurrentDocChannel(); + if (!channel) { + return NS_OK; + } + + nsCOMPtr<nsIJARChannel> jarChannel = do_QueryInterface(channel); + if (!jarChannel) { + return NS_OK; + } + + return jarChannel->GetIsUnsafe(aUnsafe); } NS_IMETHODIMP nsDocShell::GetHasMixedActiveContentLoaded(bool* aHasMixedActiveContentLoaded) { - nsCOMPtr<nsIDocument> doc(GetDocument()); - *aHasMixedActiveContentLoaded = doc && doc->GetHasMixedActiveContentLoaded(); - return NS_OK; + nsCOMPtr<nsIDocument> doc(GetDocument()); + *aHasMixedActiveContentLoaded = doc && doc->GetHasMixedActiveContentLoaded(); + return NS_OK; } NS_IMETHODIMP nsDocShell::GetHasMixedActiveContentBlocked(bool* aHasMixedActiveContentBlocked) { - nsCOMPtr<nsIDocument> doc(GetDocument()); - *aHasMixedActiveContentBlocked = doc && doc->GetHasMixedActiveContentBlocked(); - return NS_OK; + nsCOMPtr<nsIDocument> doc(GetDocument()); + *aHasMixedActiveContentBlocked = + doc && doc->GetHasMixedActiveContentBlocked(); + return NS_OK; } NS_IMETHODIMP nsDocShell::GetHasMixedDisplayContentLoaded(bool* aHasMixedDisplayContentLoaded) { - nsCOMPtr<nsIDocument> doc(GetDocument()); - *aHasMixedDisplayContentLoaded = doc && doc->GetHasMixedDisplayContentLoaded(); - return NS_OK; -} - -NS_IMETHODIMP -nsDocShell::GetHasMixedDisplayContentBlocked(bool* aHasMixedDisplayContentBlocked) -{ - nsCOMPtr<nsIDocument> doc(GetDocument()); - *aHasMixedDisplayContentBlocked = doc && doc->GetHasMixedDisplayContentBlocked(); - return NS_OK; + nsCOMPtr<nsIDocument> doc(GetDocument()); + *aHasMixedDisplayContentLoaded = + doc && doc->GetHasMixedDisplayContentLoaded(); + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::GetHasMixedDisplayContentBlocked( + bool* aHasMixedDisplayContentBlocked) +{ + nsCOMPtr<nsIDocument> doc(GetDocument()); + *aHasMixedDisplayContentBlocked = + doc && doc->GetHasMixedDisplayContentBlocked(); + return NS_OK; } NS_IMETHODIMP nsDocShell::GetHasTrackingContentBlocked(bool* aHasTrackingContentBlocked) { - nsCOMPtr<nsIDocument> doc(GetDocument()); - *aHasTrackingContentBlocked = doc && doc->GetHasTrackingContentBlocked(); - return NS_OK; + nsCOMPtr<nsIDocument> doc(GetDocument()); + *aHasTrackingContentBlocked = doc && doc->GetHasTrackingContentBlocked(); + return NS_OK; } NS_IMETHODIMP nsDocShell::GetHasTrackingContentLoaded(bool* aHasTrackingContentLoaded) { - nsCOMPtr<nsIDocument> doc(GetDocument()); - *aHasTrackingContentLoaded = doc && doc->GetHasTrackingContentLoaded(); - return NS_OK; -} - -NS_IMETHODIMP -nsDocShell::GetAllowPlugins(bool * aAllowPlugins) -{ - NS_ENSURE_ARG_POINTER(aAllowPlugins); - - *aAllowPlugins = mAllowPlugins; - if (!mAllowPlugins) { - return NS_OK; - } - - bool unsafe; - *aAllowPlugins = NS_SUCCEEDED(GetChannelIsUnsafe(&unsafe)) && !unsafe; - return NS_OK; + nsCOMPtr<nsIDocument> doc(GetDocument()); + *aHasTrackingContentLoaded = doc && doc->GetHasTrackingContentLoaded(); + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::GetAllowPlugins(bool* aAllowPlugins) +{ + NS_ENSURE_ARG_POINTER(aAllowPlugins); + + *aAllowPlugins = mAllowPlugins; + if (!mAllowPlugins) { + return NS_OK; + } + + bool unsafe; + *aAllowPlugins = NS_SUCCEEDED(GetChannelIsUnsafe(&unsafe)) && !unsafe; + return NS_OK; } NS_IMETHODIMP nsDocShell::SetAllowPlugins(bool aAllowPlugins) { - mAllowPlugins = aAllowPlugins; - //XXX should enable or disable a plugin host - return NS_OK; -} - -NS_IMETHODIMP -nsDocShell::GetAllowJavascript(bool * aAllowJavascript) -{ - NS_ENSURE_ARG_POINTER(aAllowJavascript); - - *aAllowJavascript = mAllowJavascript; - return NS_OK; + mAllowPlugins = aAllowPlugins; + // XXX should enable or disable a plugin host + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::GetAllowJavascript(bool* aAllowJavascript) +{ + NS_ENSURE_ARG_POINTER(aAllowJavascript); + + *aAllowJavascript = mAllowJavascript; + return NS_OK; } NS_IMETHODIMP nsDocShell::SetAllowJavascript(bool aAllowJavascript) { - mAllowJavascript = aAllowJavascript; - RecomputeCanExecuteScripts(); - return NS_OK; + mAllowJavascript = aAllowJavascript; + RecomputeCanExecuteScripts(); + return NS_OK; } NS_IMETHODIMP nsDocShell::GetUsePrivateBrowsing(bool* aUsePrivateBrowsing) { - NS_ENSURE_ARG_POINTER(aUsePrivateBrowsing); - - *aUsePrivateBrowsing = mInPrivateBrowsing; - return NS_OK; + NS_ENSURE_ARG_POINTER(aUsePrivateBrowsing); + + *aUsePrivateBrowsing = mInPrivateBrowsing; + return NS_OK; } NS_IMETHODIMP nsDocShell::SetUsePrivateBrowsing(bool aUsePrivateBrowsing) { - nsContentUtils::ReportToConsoleNonLocalized( - NS_LITERAL_STRING("Only internal code is allowed to set the usePrivateBrowsing attribute"), - nsIScriptError::warningFlag, - NS_LITERAL_CSTRING("Internal API Used"), - mContentViewer ? mContentViewer->GetDocument() : nullptr); - - return SetPrivateBrowsing(aUsePrivateBrowsing); + nsContentUtils::ReportToConsoleNonLocalized( + NS_LITERAL_STRING("Only internal code is allowed to set the usePrivateBrowsing attribute"), + nsIScriptError::warningFlag, + NS_LITERAL_CSTRING("Internal API Used"), + mContentViewer ? mContentViewer->GetDocument() : nullptr); + + return SetPrivateBrowsing(aUsePrivateBrowsing); } NS_IMETHODIMP nsDocShell::SetPrivateBrowsing(bool aUsePrivateBrowsing) { - bool changed = aUsePrivateBrowsing != mInPrivateBrowsing; - if (changed) { - mInPrivateBrowsing = aUsePrivateBrowsing; - if (mAffectPrivateSessionLifetime) { - if (aUsePrivateBrowsing) { - IncreasePrivateDocShellCount(); - } else { - DecreasePrivateDocShellCount(); - } - } - } - - nsTObserverArray<nsDocLoader*>::ForwardIterator iter(mChildList); + bool changed = aUsePrivateBrowsing != mInPrivateBrowsing; + if (changed) { + mInPrivateBrowsing = aUsePrivateBrowsing; + if (mAffectPrivateSessionLifetime) { + if (aUsePrivateBrowsing) { + IncreasePrivateDocShellCount(); + } else { + DecreasePrivateDocShellCount(); + } + } + } + + nsTObserverArray<nsDocLoader*>::ForwardIterator iter(mChildList); + while (iter.HasMore()) { + nsCOMPtr<nsILoadContext> shell = do_QueryObject(iter.GetNext()); + if (shell) { + shell->SetPrivateBrowsing(aUsePrivateBrowsing); + } + } + + if (changed) { + nsTObserverArray<nsWeakPtr>::ForwardIterator iter(mPrivacyObservers); while (iter.HasMore()) { - nsCOMPtr<nsILoadContext> shell = do_QueryObject(iter.GetNext()); - if (shell) { - shell->SetPrivateBrowsing(aUsePrivateBrowsing); - } - } - - if (changed) { - nsTObserverArray<nsWeakPtr>::ForwardIterator iter(mPrivacyObservers); - while (iter.HasMore()) { - nsWeakPtr ref = iter.GetNext(); - nsCOMPtr<nsIPrivacyTransitionObserver> obs = do_QueryReferent(ref); - if (!obs) { - mPrivacyObservers.RemoveElement(ref); - } else { - obs->PrivateModeChanged(aUsePrivateBrowsing); - } - } - } - return NS_OK; + nsWeakPtr ref = iter.GetNext(); + nsCOMPtr<nsIPrivacyTransitionObserver> obs = do_QueryReferent(ref); + if (!obs) { + mPrivacyObservers.RemoveElement(ref); + } else { + obs->PrivateModeChanged(aUsePrivateBrowsing); + } + } + } + return NS_OK; } NS_IMETHODIMP nsDocShell::GetHasLoadedNonBlankURI(bool* aResult) { - NS_ENSURE_ARG_POINTER(aResult); - - *aResult = mHasLoadedNonBlankURI; - return NS_OK; + NS_ENSURE_ARG_POINTER(aResult); + + *aResult = mHasLoadedNonBlankURI; + return NS_OK; } NS_IMETHODIMP nsDocShell::GetUseRemoteTabs(bool* aUseRemoteTabs) { - NS_ENSURE_ARG_POINTER(aUseRemoteTabs); - - *aUseRemoteTabs = mUseRemoteTabs; - return NS_OK; + NS_ENSURE_ARG_POINTER(aUseRemoteTabs); + + *aUseRemoteTabs = mUseRemoteTabs; + return NS_OK; } NS_IMETHODIMP nsDocShell::SetRemoteTabs(bool aUseRemoteTabs) { #ifdef MOZ_CRASHREPORTER - if (aUseRemoteTabs) { - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("DOMIPCEnabled"), - NS_LITERAL_CSTRING("1")); - } + if (aUseRemoteTabs) { + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("DOMIPCEnabled"), + NS_LITERAL_CSTRING("1")); + } #endif - mUseRemoteTabs = aUseRemoteTabs; - return NS_OK; + mUseRemoteTabs = aUseRemoteTabs; + return NS_OK; } NS_IMETHODIMP nsDocShell::SetAffectPrivateSessionLifetime(bool aAffectLifetime) { - bool change = aAffectLifetime != mAffectPrivateSessionLifetime; - if (change && mInPrivateBrowsing) { - if (aAffectLifetime) { - IncreasePrivateDocShellCount(); - } else { - DecreasePrivateDocShellCount(); - } - } - mAffectPrivateSessionLifetime = aAffectLifetime; - - nsTObserverArray<nsDocLoader*>::ForwardIterator iter(mChildList); - while (iter.HasMore()) { - nsCOMPtr<nsIDocShell> shell = do_QueryObject(iter.GetNext()); - if (shell) { - shell->SetAffectPrivateSessionLifetime(aAffectLifetime); - } - } - return NS_OK; + bool change = aAffectLifetime != mAffectPrivateSessionLifetime; + if (change && mInPrivateBrowsing) { + if (aAffectLifetime) { + IncreasePrivateDocShellCount(); + } else { + DecreasePrivateDocShellCount(); + } + } + mAffectPrivateSessionLifetime = aAffectLifetime; + + nsTObserverArray<nsDocLoader*>::ForwardIterator iter(mChildList); + while (iter.HasMore()) { + nsCOMPtr<nsIDocShell> shell = do_QueryObject(iter.GetNext()); + if (shell) { + shell->SetAffectPrivateSessionLifetime(aAffectLifetime); + } + } + return NS_OK; } NS_IMETHODIMP nsDocShell::GetAffectPrivateSessionLifetime(bool* aAffectLifetime) { - *aAffectLifetime = mAffectPrivateSessionLifetime; - return NS_OK; -} - -NS_IMETHODIMP -nsDocShell::AddWeakPrivacyTransitionObserver(nsIPrivacyTransitionObserver* aObserver) -{ - nsWeakPtr weakObs = do_GetWeakReference(aObserver); - if (!weakObs) { - return NS_ERROR_NOT_AVAILABLE; - } - return mPrivacyObservers.AppendElement(weakObs) ? NS_OK : NS_ERROR_FAILURE; + *aAffectLifetime = mAffectPrivateSessionLifetime; + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::AddWeakPrivacyTransitionObserver( + nsIPrivacyTransitionObserver* aObserver) +{ + nsWeakPtr weakObs = do_GetWeakReference(aObserver); + if (!weakObs) { + return NS_ERROR_NOT_AVAILABLE; + } + return mPrivacyObservers.AppendElement(weakObs) ? NS_OK : NS_ERROR_FAILURE; } NS_IMETHODIMP nsDocShell::AddWeakReflowObserver(nsIReflowObserver* aObserver) { - nsWeakPtr weakObs = do_GetWeakReference(aObserver); - if (!weakObs) { - return NS_ERROR_FAILURE; - } - return mReflowObservers.AppendElement(weakObs) ? NS_OK : NS_ERROR_FAILURE; + nsWeakPtr weakObs = do_GetWeakReference(aObserver); + if (!weakObs) { + return NS_ERROR_FAILURE; + } + return mReflowObservers.AppendElement(weakObs) ? NS_OK : NS_ERROR_FAILURE; } NS_IMETHODIMP nsDocShell::RemoveWeakReflowObserver(nsIReflowObserver* aObserver) { - nsWeakPtr obs = do_GetWeakReference(aObserver); - return mReflowObservers.RemoveElement(obs) ? NS_OK : NS_ERROR_FAILURE; + nsWeakPtr obs = do_GetWeakReference(aObserver); + return mReflowObservers.RemoveElement(obs) ? NS_OK : NS_ERROR_FAILURE; } NS_IMETHODIMP nsDocShell::NotifyReflowObservers(bool aInterruptible, DOMHighResTimeStamp aStart, DOMHighResTimeStamp aEnd) { - nsTObserverArray<nsWeakPtr>::ForwardIterator iter(mReflowObservers); - while (iter.HasMore()) { - nsWeakPtr ref = iter.GetNext(); - nsCOMPtr<nsIReflowObserver> obs = do_QueryReferent(ref); - if (!obs) { - mReflowObservers.RemoveElement(ref); - } else if (aInterruptible) { - obs->ReflowInterruptible(aStart, aEnd); - } else { - obs->Reflow(aStart, aEnd); - } - } - return NS_OK; -} - -NS_IMETHODIMP nsDocShell::GetAllowMetaRedirects(bool * aReturn) -{ - NS_ENSURE_ARG_POINTER(aReturn); - - *aReturn = mAllowMetaRedirects; - if (!mAllowMetaRedirects) { - return NS_OK; - } - - bool unsafe; - *aReturn = NS_SUCCEEDED(GetChannelIsUnsafe(&unsafe)) && !unsafe; - return NS_OK; -} - -NS_IMETHODIMP nsDocShell::SetAllowMetaRedirects(bool aValue) -{ - mAllowMetaRedirects = aValue; - return NS_OK; -} - -NS_IMETHODIMP nsDocShell::GetAllowSubframes(bool * aAllowSubframes) -{ - NS_ENSURE_ARG_POINTER(aAllowSubframes); - - *aAllowSubframes = mAllowSubframes; - return NS_OK; -} - -NS_IMETHODIMP nsDocShell::SetAllowSubframes(bool aAllowSubframes) -{ - mAllowSubframes = aAllowSubframes; - return NS_OK; -} - -NS_IMETHODIMP nsDocShell::GetAllowImages(bool * aAllowImages) -{ - NS_ENSURE_ARG_POINTER(aAllowImages); - - *aAllowImages = mAllowImages; - return NS_OK; -} - -NS_IMETHODIMP nsDocShell::SetAllowImages(bool aAllowImages) -{ - mAllowImages = aAllowImages; - return NS_OK; -} - -NS_IMETHODIMP nsDocShell::GetAllowMedia(bool * aAllowMedia) -{ - *aAllowMedia = mAllowMedia; - return NS_OK; -} - -NS_IMETHODIMP nsDocShell::SetAllowMedia(bool aAllowMedia) -{ - mAllowMedia = aAllowMedia; - - // Mute or unmute audio contexts attached to the inner window. - if (mScriptGlobal) { - nsPIDOMWindow* innerWin = mScriptGlobal->GetCurrentInnerWindow(); - if (innerWin) { - if (aAllowMedia) { - innerWin->UnmuteAudioContexts(); - } else { - innerWin->MuteAudioContexts(); - } - } - } - - return NS_OK; -} - -NS_IMETHODIMP nsDocShell::GetAllowDNSPrefetch(bool * aAllowDNSPrefetch) -{ - *aAllowDNSPrefetch = mAllowDNSPrefetch; - return NS_OK; -} - -NS_IMETHODIMP nsDocShell::SetAllowDNSPrefetch(bool aAllowDNSPrefetch) -{ - mAllowDNSPrefetch = aAllowDNSPrefetch; - return NS_OK; -} - -NS_IMETHODIMP nsDocShell::GetAllowWindowControl(bool * aAllowWindowControl) -{ - *aAllowWindowControl = mAllowWindowControl; - return NS_OK; -} - -NS_IMETHODIMP nsDocShell::SetAllowWindowControl(bool aAllowWindowControl) -{ - mAllowWindowControl = aAllowWindowControl; - return NS_OK; + nsTObserverArray<nsWeakPtr>::ForwardIterator iter(mReflowObservers); + while (iter.HasMore()) { + nsWeakPtr ref = iter.GetNext(); + nsCOMPtr<nsIReflowObserver> obs = do_QueryReferent(ref); + if (!obs) { + mReflowObservers.RemoveElement(ref); + } else if (aInterruptible) { + obs->ReflowInterruptible(aStart, aEnd); + } else { + obs->Reflow(aStart, aEnd); + } + } + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::GetAllowMetaRedirects(bool* aReturn) +{ + NS_ENSURE_ARG_POINTER(aReturn); + + *aReturn = mAllowMetaRedirects; + if (!mAllowMetaRedirects) { + return NS_OK; + } + + bool unsafe; + *aReturn = NS_SUCCEEDED(GetChannelIsUnsafe(&unsafe)) && !unsafe; + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::SetAllowMetaRedirects(bool aValue) +{ + mAllowMetaRedirects = aValue; + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::GetAllowSubframes(bool* aAllowSubframes) +{ + NS_ENSURE_ARG_POINTER(aAllowSubframes); + + *aAllowSubframes = mAllowSubframes; + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::SetAllowSubframes(bool aAllowSubframes) +{ + mAllowSubframes = aAllowSubframes; + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::GetAllowImages(bool* aAllowImages) +{ + NS_ENSURE_ARG_POINTER(aAllowImages); + + *aAllowImages = mAllowImages; + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::SetAllowImages(bool aAllowImages) +{ + mAllowImages = aAllowImages; + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::GetAllowMedia(bool* aAllowMedia) +{ + *aAllowMedia = mAllowMedia; + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::SetAllowMedia(bool aAllowMedia) +{ + mAllowMedia = aAllowMedia; + + // Mute or unmute audio contexts attached to the inner window. + if (mScriptGlobal) { + nsPIDOMWindow* innerWin = mScriptGlobal->GetCurrentInnerWindow(); + if (innerWin) { + if (aAllowMedia) { + innerWin->UnmuteAudioContexts(); + } else { + innerWin->MuteAudioContexts(); + } + } + } + + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::GetAllowDNSPrefetch(bool* aAllowDNSPrefetch) +{ + *aAllowDNSPrefetch = mAllowDNSPrefetch; + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::SetAllowDNSPrefetch(bool aAllowDNSPrefetch) +{ + mAllowDNSPrefetch = aAllowDNSPrefetch; + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::GetAllowWindowControl(bool* aAllowWindowControl) +{ + *aAllowWindowControl = mAllowWindowControl; + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::SetAllowWindowControl(bool aAllowWindowControl) +{ + mAllowWindowControl = aAllowWindowControl; + return NS_OK; } NS_IMETHODIMP nsDocShell::GetAllowContentRetargeting(bool* aAllowContentRetargeting) { - *aAllowContentRetargeting = mAllowContentRetargeting; - return NS_OK; + *aAllowContentRetargeting = mAllowContentRetargeting; + return NS_OK; } NS_IMETHODIMP nsDocShell::SetAllowContentRetargeting(bool aAllowContentRetargeting) { - mAllowContentRetargeting = aAllowContentRetargeting; - return NS_OK; + mAllowContentRetargeting = aAllowContentRetargeting; + return NS_OK; } NS_IMETHODIMP nsDocShell::GetFullscreenAllowed(bool* aFullscreenAllowed) { - NS_ENSURE_ARG_POINTER(aFullscreenAllowed); - - // Browsers and apps have their mFullscreenAllowed retrieved from their - // corresponding iframe in their parent upon creation. - if (mFullscreenAllowed != CHECK_ATTRIBUTES) { - *aFullscreenAllowed = (mFullscreenAllowed == PARENT_ALLOWS); - return NS_OK; - } - - // Assume false until we determine otherwise... - *aFullscreenAllowed = false; - - // For non-browsers/apps, check that the enclosing iframe element - // has the allowfullscreen attribute set to true. If any ancestor - // iframe does not have mozallowfullscreen=true, then fullscreen is - // prohibited. - nsCOMPtr<nsPIDOMWindow> win = GetWindow(); - if (!win) { - return NS_OK; - } - nsCOMPtr<Element> frameElement = win->GetFrameElementInternal(); - if (frameElement && - frameElement->IsHTML(nsGkAtoms::iframe) && - !frameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::allowfullscreen) && - !frameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::mozallowfullscreen)) { - return NS_OK; - } - - // If we have no parent then we're the root docshell; no ancestor of the - // original docshell doesn't have a allowfullscreen attribute, so - // report fullscreen as allowed. - nsRefPtr<nsDocShell> parent = GetParentDocshell(); - if (!parent) { - *aFullscreenAllowed = true; - return NS_OK; - } - - // Otherwise, we have a parent, continue the checking for - // mozFullscreenAllowed in the parent docshell's ancestors. - return parent->GetFullscreenAllowed(aFullscreenAllowed); + NS_ENSURE_ARG_POINTER(aFullscreenAllowed); + + // Browsers and apps have their mFullscreenAllowed retrieved from their + // corresponding iframe in their parent upon creation. + if (mFullscreenAllowed != CHECK_ATTRIBUTES) { + *aFullscreenAllowed = (mFullscreenAllowed == PARENT_ALLOWS); + return NS_OK; + } + + // Assume false until we determine otherwise... + *aFullscreenAllowed = false; + + // For non-browsers/apps, check that the enclosing iframe element + // has the allowfullscreen attribute set to true. If any ancestor + // iframe does not have mozallowfullscreen=true, then fullscreen is + // prohibited. + nsCOMPtr<nsPIDOMWindow> win = GetWindow(); + if (!win) { + return NS_OK; + } + nsCOMPtr<Element> frameElement = win->GetFrameElementInternal(); + if (frameElement && + frameElement->IsHTML(nsGkAtoms::iframe) && + !frameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::allowfullscreen) && + !frameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::mozallowfullscreen)) { + return NS_OK; + } + + // If we have no parent then we're the root docshell; no ancestor of the + // original docshell doesn't have a allowfullscreen attribute, so + // report fullscreen as allowed. + nsRefPtr<nsDocShell> parent = GetParentDocshell(); + if (!parent) { + *aFullscreenAllowed = true; + return NS_OK; + } + + // Otherwise, we have a parent, continue the checking for + // mozFullscreenAllowed in the parent docshell's ancestors. + return parent->GetFullscreenAllowed(aFullscreenAllowed); } NS_IMETHODIMP nsDocShell::SetFullscreenAllowed(bool aFullscreenAllowed) { - if (!nsIDocShell::GetIsBrowserOrApp()) { - // Only allow setting of fullscreenAllowed on content/process boundaries. - // At non-boundaries the fullscreenAllowed attribute is calculated based on - // whether all enclosing frames have the "mozFullscreenAllowed" attribute - // set to "true". fullscreenAllowed is set at the process boundaries to - // propagate the value of the parent's "mozFullscreenAllowed" attribute - // across process boundaries. - return NS_ERROR_UNEXPECTED; - } - mFullscreenAllowed = (aFullscreenAllowed ? PARENT_ALLOWS : PARENT_PROHIBITS); - return NS_OK; -} - -NS_IMETHODIMP -nsDocShell::GetMayEnableCharacterEncodingMenu(bool* aMayEnableCharacterEncodingMenu) + if (!nsIDocShell::GetIsBrowserOrApp()) { + // Only allow setting of fullscreenAllowed on content/process boundaries. + // At non-boundaries the fullscreenAllowed attribute is calculated based on + // whether all enclosing frames have the "mozFullscreenAllowed" attribute + // set to "true". fullscreenAllowed is set at the process boundaries to + // propagate the value of the parent's "mozFullscreenAllowed" attribute + // across process boundaries. + return NS_ERROR_UNEXPECTED; + } + mFullscreenAllowed = (aFullscreenAllowed ? PARENT_ALLOWS : PARENT_PROHIBITS); + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::GetMayEnableCharacterEncodingMenu( + bool* aMayEnableCharacterEncodingMenu) { *aMayEnableCharacterEncodingMenu = false; if (!mContentViewer) { return NS_OK; } nsIDocument* doc = mContentViewer->GetDocument(); if (!doc) { return NS_OK; @@ -2619,242 +2661,253 @@ nsDocShell::GetMayEnableCharacterEncodin return NS_OK; } *aMayEnableCharacterEncodingMenu = true; return NS_OK; } NS_IMETHODIMP -nsDocShell::GetDocShellEnumerator(int32_t aItemType, int32_t aDirection, nsISimpleEnumerator **outEnum) -{ - NS_ENSURE_ARG_POINTER(outEnum); - *outEnum = nullptr; - - nsRefPtr<nsDocShellEnumerator> docShellEnum; - if (aDirection == ENUMERATE_FORWARDS) - docShellEnum = new nsDocShellForwardsEnumerator; - else - docShellEnum = new nsDocShellBackwardsEnumerator; - - if (!docShellEnum) return NS_ERROR_OUT_OF_MEMORY; - - nsresult rv = docShellEnum->SetEnumDocShellType(aItemType); - if (NS_FAILED(rv)) return rv; - - rv = docShellEnum->SetEnumerationRootItem((nsIDocShellTreeItem *)this); - if (NS_FAILED(rv)) return rv; - - rv = docShellEnum->First(); - if (NS_FAILED(rv)) return rv; - - rv = docShellEnum->QueryInterface(NS_GET_IID(nsISimpleEnumerator), (void **)outEnum); - +nsDocShell::GetDocShellEnumerator(int32_t aItemType, int32_t aDirection, + nsISimpleEnumerator** aResult) +{ + NS_ENSURE_ARG_POINTER(aResult); + *aResult = nullptr; + + nsRefPtr<nsDocShellEnumerator> docShellEnum; + if (aDirection == ENUMERATE_FORWARDS) { + docShellEnum = new nsDocShellForwardsEnumerator; + } else { + docShellEnum = new nsDocShellBackwardsEnumerator; + } + + if (!docShellEnum) { + return NS_ERROR_OUT_OF_MEMORY; + } + + nsresult rv = docShellEnum->SetEnumDocShellType(aItemType); + if (NS_FAILED(rv)) { return rv; -} - -NS_IMETHODIMP -nsDocShell::GetAppType(uint32_t * aAppType) -{ - *aAppType = mAppType; - return NS_OK; + } + + rv = docShellEnum->SetEnumerationRootItem((nsIDocShellTreeItem*)this); + if (NS_FAILED(rv)) { + return rv; + } + + rv = docShellEnum->First(); + if (NS_FAILED(rv)) { + return rv; + } + + rv = docShellEnum->QueryInterface(NS_GET_IID(nsISimpleEnumerator), + (void**)aResult); + + return rv; +} + +NS_IMETHODIMP +nsDocShell::GetAppType(uint32_t* aAppType) +{ + *aAppType = mAppType; + return NS_OK; } NS_IMETHODIMP nsDocShell::SetAppType(uint32_t aAppType) { - mAppType = aAppType; - return NS_OK; -} - - -NS_IMETHODIMP -nsDocShell::GetAllowAuth(bool * aAllowAuth) -{ - *aAllowAuth = mAllowAuth; - return NS_OK; + mAppType = aAppType; + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::GetAllowAuth(bool* aAllowAuth) +{ + *aAllowAuth = mAllowAuth; + return NS_OK; } NS_IMETHODIMP nsDocShell::SetAllowAuth(bool aAllowAuth) { - mAllowAuth = aAllowAuth; - return NS_OK; -} - -NS_IMETHODIMP -nsDocShell::GetZoom(float *zoom) -{ - NS_ENSURE_ARG_POINTER(zoom); - *zoom = 1.0f; - return NS_OK; -} - -NS_IMETHODIMP -nsDocShell::SetZoom(float zoom) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -nsDocShell::GetMarginWidth(int32_t * aWidth) -{ - NS_ENSURE_ARG_POINTER(aWidth); - - *aWidth = mMarginWidth; - return NS_OK; + mAllowAuth = aAllowAuth; + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::GetZoom(float* aZoom) +{ + NS_ENSURE_ARG_POINTER(aZoom); + *aZoom = 1.0f; + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::SetZoom(float aZoom) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsDocShell::GetMarginWidth(int32_t* aWidth) +{ + NS_ENSURE_ARG_POINTER(aWidth); + + *aWidth = mMarginWidth; + return NS_OK; } NS_IMETHODIMP nsDocShell::SetMarginWidth(int32_t aWidth) { - mMarginWidth = aWidth; - return NS_OK; -} - -NS_IMETHODIMP -nsDocShell::GetMarginHeight(int32_t * aHeight) -{ - NS_ENSURE_ARG_POINTER(aHeight); - - *aHeight = mMarginHeight; - return NS_OK; + mMarginWidth = aWidth; + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::GetMarginHeight(int32_t* aHeight) +{ + NS_ENSURE_ARG_POINTER(aHeight); + + *aHeight = mMarginHeight; + return NS_OK; } NS_IMETHODIMP nsDocShell::SetMarginHeight(int32_t aHeight) { - mMarginHeight = aHeight; - return NS_OK; -} - -NS_IMETHODIMP -nsDocShell::GetBusyFlags(uint32_t * aBusyFlags) -{ - NS_ENSURE_ARG_POINTER(aBusyFlags); - - *aBusyFlags = mBusyFlags; - return NS_OK; + mMarginHeight = aHeight; + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::GetBusyFlags(uint32_t* aBusyFlags) +{ + NS_ENSURE_ARG_POINTER(aBusyFlags); + + *aBusyFlags = mBusyFlags; + return NS_OK; } NS_IMETHODIMP nsDocShell::TabToTreeOwner(bool aForward, bool* aTookFocus) { - NS_ENSURE_ARG_POINTER(aTookFocus); - - nsCOMPtr<nsIWebBrowserChromeFocus> chromeFocus = do_GetInterface(mTreeOwner); - if (chromeFocus) { - if (aForward) - *aTookFocus = NS_SUCCEEDED(chromeFocus->FocusNextElement()); - else - *aTookFocus = NS_SUCCEEDED(chromeFocus->FocusPrevElement()); - } else - *aTookFocus = false; - - return NS_OK; -} - -NS_IMETHODIMP -nsDocShell::GetSecurityUI(nsISecureBrowserUI **aSecurityUI) -{ - NS_IF_ADDREF(*aSecurityUI = mSecurityUI); - return NS_OK; -} - -NS_IMETHODIMP -nsDocShell::SetSecurityUI(nsISecureBrowserUI *aSecurityUI) -{ - mSecurityUI = aSecurityUI; - mSecurityUI->SetDocShell(this); - return NS_OK; -} - -NS_IMETHODIMP -nsDocShell::GetUseErrorPages(bool *aUseErrorPages) -{ - *aUseErrorPages = UseErrorPages(); - return NS_OK; + NS_ENSURE_ARG_POINTER(aTookFocus); + + nsCOMPtr<nsIWebBrowserChromeFocus> chromeFocus = do_GetInterface(mTreeOwner); + if (chromeFocus) { + if (aForward) { + *aTookFocus = NS_SUCCEEDED(chromeFocus->FocusNextElement()); + } else { + *aTookFocus = NS_SUCCEEDED(chromeFocus->FocusPrevElement()); + } + } else { + *aTookFocus = false; + } + + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::GetSecurityUI(nsISecureBrowserUI** aSecurityUI) +{ + NS_IF_ADDREF(*aSecurityUI = mSecurityUI); + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::SetSecurityUI(nsISecureBrowserUI* aSecurityUI) +{ + mSecurityUI = aSecurityUI; + mSecurityUI->SetDocShell(this); + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::GetUseErrorPages(bool* aUseErrorPages) +{ + *aUseErrorPages = UseErrorPages(); + return NS_OK; } NS_IMETHODIMP nsDocShell::SetUseErrorPages(bool aUseErrorPages) { - // If mUseErrorPages is set explicitly, stop using sUseErrorPages. - if (mObserveErrorPages) { - mObserveErrorPages = false; - } - mUseErrorPages = aUseErrorPages; - return NS_OK; -} - -NS_IMETHODIMP -nsDocShell::GetPreviousTransIndex(int32_t *aPreviousTransIndex) -{ - *aPreviousTransIndex = mPreviousTransIndex; - return NS_OK; -} - -NS_IMETHODIMP -nsDocShell::GetLoadedTransIndex(int32_t *aLoadedTransIndex) -{ - *aLoadedTransIndex = mLoadedTransIndex; - return NS_OK; + // If mUseErrorPages is set explicitly, stop using sUseErrorPages. + if (mObserveErrorPages) { + mObserveErrorPages = false; + } + mUseErrorPages = aUseErrorPages; + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::GetPreviousTransIndex(int32_t* aPreviousTransIndex) +{ + *aPreviousTransIndex = mPreviousTransIndex; + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::GetLoadedTransIndex(int32_t* aLoadedTransIndex) +{ + *aLoadedTransIndex = mLoadedTransIndex; + return NS_OK; } NS_IMETHODIMP nsDocShell::HistoryPurged(int32_t aNumEntries) { - // These indices are used for fastback cache eviction, to determine - // which session history entries are candidates for content viewer - // eviction. We need to adjust by the number of entries that we - // just purged from history, so that we look at the right session history - // entries during eviction. - mPreviousTransIndex = std::max(-1, mPreviousTransIndex - aNumEntries); - mLoadedTransIndex = std::max(0, mLoadedTransIndex - aNumEntries); - - nsTObserverArray<nsDocLoader*>::ForwardIterator iter(mChildList); - while (iter.HasMore()) { - nsCOMPtr<nsIDocShell> shell = do_QueryObject(iter.GetNext()); - if (shell) { - shell->HistoryPurged(aNumEntries); - } - } - - return NS_OK; + // These indices are used for fastback cache eviction, to determine + // which session history entries are candidates for content viewer + // eviction. We need to adjust by the number of entries that we + // just purged from history, so that we look at the right session history + // entries during eviction. + mPreviousTransIndex = std::max(-1, mPreviousTransIndex - aNumEntries); + mLoadedTransIndex = std::max(0, mLoadedTransIndex - aNumEntries); + + nsTObserverArray<nsDocLoader*>::ForwardIterator iter(mChildList); + while (iter.HasMore()) { + nsCOMPtr<nsIDocShell> shell = do_QueryObject(iter.GetNext()); + if (shell) { + shell->HistoryPurged(aNumEntries); + } + } + + return NS_OK; } nsresult nsDocShell::HistoryTransactionRemoved(int32_t aIndex) { - // These indices are used for fastback cache eviction, to determine - // which session history entries are candidates for content viewer - // eviction. We need to adjust by the number of entries that we - // just purged from history, so that we look at the right session history - // entries during eviction. - if (aIndex == mPreviousTransIndex) { - mPreviousTransIndex = -1; - } else if (aIndex < mPreviousTransIndex) { - --mPreviousTransIndex; - } - if (mLoadedTransIndex == aIndex) { - mLoadedTransIndex = 0; - } else if (aIndex < mLoadedTransIndex) { - --mLoadedTransIndex; - } - - nsTObserverArray<nsDocLoader*>::ForwardIterator iter(mChildList); - while (iter.HasMore()) { - nsCOMPtr<nsIDocShell> shell = do_QueryObject(iter.GetNext()); - if (shell) { - static_cast<nsDocShell*>(shell.get())-> - HistoryTransactionRemoved(aIndex); - } - } - - return NS_OK; + // These indices are used for fastback cache eviction, to determine + // which session history entries are candidates for content viewer + // eviction. We need to adjust by the number of entries that we + // just purged from history, so that we look at the right session history + // entries during eviction. + if (aIndex == mPreviousTransIndex) { + mPreviousTransIndex = -1; + } else if (aIndex < mPreviousTransIndex) { + --mPreviousTransIndex; + } + if (mLoadedTransIndex == aIndex) { + mLoadedTransIndex = 0; + } else if (aIndex < mLoadedTransIndex) { + --mLoadedTransIndex; + } + + nsTObserverArray<nsDocLoader*>::ForwardIterator iter(mChildList); + while (iter.HasMore()) { + nsCOMPtr<nsIDocShell> shell = do_QueryObject(iter.GetNext()); + if (shell) { + static_cast<nsDocShell*>(shell.get())->HistoryTransactionRemoved(aIndex); + } + } + + return NS_OK; } unsigned long nsDocShell::gProfileTimelineRecordingsCount = 0; NS_IMETHODIMP nsDocShell::SetRecordProfileTimelineMarkers(bool aValue) { bool currentValue = nsIDocShell::GetRecordProfileTimelineMarkers(); @@ -2877,45 +2930,47 @@ nsDocShell::SetRecordProfileTimelineMark NS_IMETHODIMP nsDocShell::GetRecordProfileTimelineMarkers(bool* aValue) { *aValue = mProfileTimelineRecording; return NS_OK; } nsresult -nsDocShell::PopProfileTimelineMarkers(JSContext* aCx, - JS::MutableHandle<JS::Value> aProfileTimelineMarkers) +nsDocShell::PopProfileTimelineMarkers( + JSContext* aCx, + JS::MutableHandle<JS::Value> aProfileTimelineMarkers) { // Looping over all markers gathered so far at the docShell level, whenever a // START marker is found, look for the corresponding END marker and build a // {name,start,end} JS object. // Paint markers are different because paint is handled at root docShell level // in the information that a paint was done is then stored at each sub // docShell level but we can only be sure that a paint did happen in a // docShell if an Layer marker type was recorded too. nsTArray<mozilla::dom::ProfileTimelineMarker> profileTimelineMarkers; - SequenceRooter<mozilla::dom::ProfileTimelineMarker> rooter(aCx, &profileTimelineMarkers); + SequenceRooter<mozilla::dom::ProfileTimelineMarker> rooter( + aCx, &profileTimelineMarkers); // If we see an unpaired START, we keep it around for the next call // to PopProfileTimelineMarkers. We store the kept START objects in // this array. nsTArray<TimelineMarker*> keptMarkers; for (uint32_t i = 0; i < mProfileTimelineMarkers.Length(); ++i) { TimelineMarker* startPayload = mProfileTimelineMarkers[i]; const char* startMarkerName = startPayload->GetName(); bool hasSeenPaintedLayer = false; bool isPaint = strcmp(startMarkerName, "Paint") == 0; // If we are processing a Paint marker, we append information from // all the embedded Layer markers to this array. - mozilla::dom::Sequence<mozilla::dom::ProfileTimelineLayerRect> layerRectangles; + dom::Sequence<dom::ProfileTimelineLayerRect> layerRectangles; if (startPayload->GetMetaData() == TRACING_INTERVAL_START) { bool hasSeenEnd = false; // DOM events can be nested, so we must take care when searching // for the matching end. It doesn't hurt to apply this logic to // all event types. uint32_t markerDepth = 0; @@ -2987,17 +3042,18 @@ nsDocShell::PopProfileTimelineMarkers(JS return NS_OK; } nsresult nsDocShell::Now(DOMHighResTimeStamp* aWhen) { bool ignore; - *aWhen = (TimeStamp::Now() - TimeStamp::ProcessCreation(ignore)).ToMilliseconds(); + *aWhen = + (TimeStamp::Now() - TimeStamp::ProcessCreation(ignore)).ToMilliseconds(); return NS_OK; } void nsDocShell::AddProfileTimelineMarker(const char* aName, TracingMetadata aMetaData) { if (mProfileTimelineRecording) { @@ -3050,1464 +3106,1450 @@ nsDocShell::ClearProfileTimelineMarkers( delete mProfileTimelineMarkers[i]; } mProfileTimelineMarkers.Clear(); } nsIDOMStorageManager* nsDocShell::TopSessionStorageManager() { - nsresult rv; - - nsCOMPtr<nsIDocShellTreeItem> topItem; - rv = GetSameTypeRootTreeItem(getter_AddRefs(topItem)); - if (NS_FAILED(rv)) { - return nullptr; - } - - if (!topItem) { - return nullptr; - } - - nsDocShell* topDocShell = static_cast<nsDocShell*>(topItem.get()); - if (topDocShell != this) { - return topDocShell->TopSessionStorageManager(); - } - - if (!mSessionStorageManager) { - mSessionStorageManager = - do_CreateInstance("@mozilla.org/dom/sessionStorage-manager;1"); - } - - return mSessionStorageManager; + nsresult rv; + + nsCOMPtr<nsIDocShellTreeItem> topItem; + rv = GetSameTypeRootTreeItem(getter_AddRefs(topItem)); + if (NS_FAILED(rv)) { + return nullptr; + } + + if (!topItem) { + return nullptr; + } + + nsDocShell* topDocShell = static_cast<nsDocShell*>(topItem.get()); + if (topDocShell != this) { + return topDocShell->TopSessionStorageManager(); + } + + if (!mSessionStorageManager) { + mSessionStorageManager = + do_CreateInstance("@mozilla.org/dom/sessionStorage-manager;1"); + } + + return mSessionStorageManager; } NS_IMETHODIMP nsDocShell::GetSessionStorageForPrincipal(nsIPrincipal* aPrincipal, const nsAString& aDocumentURI, bool aCreate, nsIDOMStorage** aStorage) { - nsCOMPtr<nsIDOMStorageManager> manager = TopSessionStorageManager(); - if (!manager) { - return NS_ERROR_UNEXPECTED; - } - - nsCOMPtr<nsIDOMWindow> domWin = do_GetInterface(GetAsSupports(this)); - - if (aCreate) { - return manager->CreateStorage(domWin, aPrincipal, aDocumentURI, - mInPrivateBrowsing, aStorage); - } - - return manager->GetStorage(domWin, aPrincipal, mInPrivateBrowsing, - aStorage); + nsCOMPtr<nsIDOMStorageManager> manager = TopSessionStorageManager(); + if (!manager) { + return NS_ERROR_UNEXPECTED; + } + + nsCOMPtr<nsIDOMWindow> domWin = do_GetInterface(GetAsSupports(this)); + + if (aCreate) { + return manager->CreateStorage(domWin, aPrincipal, aDocumentURI, + mInPrivateBrowsing, aStorage); + } + + return manager->GetStorage(domWin, aPrincipal, mInPrivateBrowsing, aStorage); } nsresult -nsDocShell::AddSessionStorage(nsIPrincipal* aPrincipal, - nsIDOMStorage* aStorage) -{ - nsRefPtr<DOMStorage> storage = static_cast<DOMStorage*>(aStorage); - if (!storage) { - return NS_ERROR_UNEXPECTED; - } - - nsIPrincipal* storagePrincipal = storage->GetPrincipal(); - if (storagePrincipal != aPrincipal) { - NS_ERROR("Wanting to add a sessionStorage for different principal"); - return NS_ERROR_DOM_SECURITY_ERR; - } - - nsCOMPtr<nsIDOMStorageManager> manager = TopSessionStorageManager(); - if (!manager) { - return NS_ERROR_UNEXPECTED; - } - - return manager->CloneStorage(aStorage); +nsDocShell::AddSessionStorage(nsIPrincipal* aPrincipal, nsIDOMStorage* aStorage) +{ + nsRefPtr<DOMStorage> storage = static_cast<DOMStorage*>(aStorage); + if (!storage) { + return NS_ERROR_UNEXPECTED; + } + + nsIPrincipal* storagePrincipal = storage->GetPrincipal(); + if (storagePrincipal != aPrincipal) { + NS_ERROR("Wanting to add a sessionStorage for different principal"); + return NS_ERROR_DOM_SECURITY_ERR; + } + + nsCOMPtr<nsIDOMStorageManager> manager = TopSessionStorageManager(); + if (!manager) { + return NS_ERROR_UNEXPECTED; + } + + return manager->CloneStorage(aStorage); } NS_IMETHODIMP nsDocShell::GetCurrentDocumentChannel(nsIChannel** aResult) { - NS_IF_ADDREF(*aResult = GetCurrentDocChannel()); - return NS_OK; + NS_IF_ADDREF(*aResult = GetCurrentDocChannel()); + return NS_OK; } nsIChannel* nsDocShell::GetCurrentDocChannel() { - if (mContentViewer) { - nsIDocument* doc = mContentViewer->GetDocument(); - if (doc) { - return doc->GetChannel(); - } - } - return nullptr; + if (mContentViewer) { + nsIDocument* doc = mContentViewer->GetDocument(); + if (doc) { + return doc->GetChannel(); + } + } + return nullptr; } NS_IMETHODIMP nsDocShell::AddWeakScrollObserver(nsIScrollObserver* aObserver) { - nsWeakPtr weakObs = do_GetWeakReference(aObserver); - if (!weakObs) { - return NS_ERROR_FAILURE; - } - return mScrollObservers.AppendElement(weakObs) ? NS_OK : NS_ERROR_FAILURE; + nsWeakPtr weakObs = do_GetWeakReference(aObserver); + if (!weakObs) { + return NS_ERROR_FAILURE; + } + return mScrollObservers.AppendElement(weakObs) ? NS_OK : NS_ERROR_FAILURE; } NS_IMETHODIMP nsDocShell::RemoveWeakScrollObserver(nsIScrollObserver* aObserver) { - nsWeakPtr obs = do_GetWeakReference(aObserver); - return mScrollObservers.RemoveElement(obs) ? NS_OK : NS_ERROR_FAILURE; + nsWeakPtr obs = do_GetWeakReference(aObserver); + return mScrollObservers.RemoveElement(obs) ? NS_OK : NS_ERROR_FAILURE; } void nsDocShell::NotifyAsyncPanZoomStarted(const mozilla::CSSIntPoint aScrollPos) { - nsTObserverArray<nsWeakPtr>::ForwardIterator iter(mScrollObservers); - while (iter.HasMore()) { - nsWeakPtr ref = iter.GetNext(); - nsCOMPtr<nsIScrollObserver> obs = do_QueryReferent(ref); - if (obs) { - obs->AsyncPanZoomStarted(aScrollPos); - } else { - mScrollObservers.RemoveElement(ref); - } - } - - // Also notify child docshell - for (uint32_t i = 0; i < mChildList.Length(); ++i) { - nsCOMPtr<nsIDocShell> kid = do_QueryInterface(ChildAt(i)); - if (kid) { - nsDocShell* docShell = static_cast<nsDocShell*>(kid.get()); - docShell->NotifyAsyncPanZoomStarted(aScrollPos); - } - } + nsTObserverArray<nsWeakPtr>::ForwardIterator iter(mScrollObservers); + while (iter.HasMore()) { + nsWeakPtr ref = iter.GetNext(); + nsCOMPtr<nsIScrollObserver> obs = do_QueryReferent(ref); + if (obs) { + obs->AsyncPanZoomStarted(aScrollPos); + } else { + mScrollObservers.RemoveElement(ref); + } + } + + // Also notify child docshell + for (uint32_t i = 0; i < mChildList.Length(); ++i) { + nsCOMPtr<nsIDocShell> kid = do_QueryInterface(ChildAt(i)); + if (kid) { + nsDocShell* docShell = static_cast<nsDocShell*>(kid.get()); + docShell->NotifyAsyncPanZoomStarted(aScrollPos); + } + } } void nsDocShell::NotifyAsyncPanZoomStopped(const mozilla::CSSIntPoint aScrollPos) { - nsTObserverArray<nsWeakPtr>::ForwardIterator iter(mScrollObservers); - while (iter.HasMore()) { - nsWeakPtr ref = iter.GetNext(); - nsCOMPtr<nsIScrollObserver> obs = do_QueryReferent(ref); - if (obs) { - obs->AsyncPanZoomStopped(aScrollPos); - } else { - mScrollObservers.RemoveElement(ref); - } - } - - // Also notify child docshell - for (uint32_t i = 0; i < mChildList.Length(); ++i) { - nsCOMPtr<nsIDocShell> kid = do_QueryInterface(ChildAt(i)); - if (kid) { - nsDocShell* docShell = static_cast<nsDocShell*>(kid.get()); - docShell->NotifyAsyncPanZoomStopped(aScrollPos); - } - } + nsTObserverArray<nsWeakPtr>::ForwardIterator iter(mScrollObservers); + while (iter.HasMore()) { + nsWeakPtr ref = iter.GetNext(); + nsCOMPtr<nsIScrollObserver> obs = do_QueryReferent(ref); + if (obs) { + obs->AsyncPanZoomStopped(aScrollPos); + } else { + mScrollObservers.RemoveElement(ref); + } + } + + // Also notify child docshell + for (uint32_t i = 0; i < mChildList.Length(); ++i) { + nsCOMPtr<nsIDocShell> kid = do_QueryInterface(ChildAt(i)); + if (kid) { + nsDocShell* docShell = static_cast<nsDocShell*>(kid.get()); + docShell->NotifyAsyncPanZoomStopped(aScrollPos); + } + } } NS_IMETHODIMP nsDocShell::NotifyScrollObservers() { - nsTObserverArray<nsWeakPtr>::ForwardIterator iter(mScrollObservers); - while (iter.HasMore()) { - nsWeakPtr ref = iter.GetNext(); - nsCOMPtr<nsIScrollObserver> obs = do_QueryReferent(ref); - if (obs) { - obs->ScrollPositionChanged(); - } else { - mScrollObservers.RemoveElement(ref); - } - } - return NS_OK; + nsTObserverArray<nsWeakPtr>::ForwardIterator iter(mScrollObservers); + while (iter.HasMore()) { + nsWeakPtr ref = iter.GetNext(); + nsCOMPtr<nsIScrollObserver> obs = do_QueryReferent(ref); + if (obs) { + obs->ScrollPositionChanged(); + } else { + mScrollObservers.RemoveElement(ref); + } + } + return NS_OK; } //***************************************************************************** // nsDocShell::nsIDocShellTreeItem //***************************************************************************** NS_IMETHODIMP nsDocShell::GetName(nsAString& aName) { - aName = mName; - return NS_OK; + aName = mName; + return NS_OK; } NS_IMETHODIMP nsDocShell::SetName(const nsAString& aName) { - mName = aName; - return NS_OK; -} - -NS_IMETHODIMP -nsDocShell::NameEquals(const char16_t *aName, bool *_retval) -{ - NS_ENSURE_ARG_POINTER(aName); - NS_ENSURE_ARG_POINTER(_retval); - *_retval = mName.Equals(aName); - return NS_OK; + mName = aName; + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::NameEquals(const char16_t* aName, bool* aResult) +{ + NS_ENSURE_ARG_POINTER(aName); + NS_ENSURE_ARG_POINTER(aResult); + *aResult = mName.Equals(aName); + return NS_OK; } /* virtual */ int32_t nsDocShell::ItemType() { - return mItemType; -} - -NS_IMETHODIMP -nsDocShell::GetItemType(int32_t * aItemType) -{ - NS_ENSURE_ARG_POINTER(aItemType); - - *aItemType = ItemType(); - return NS_OK; + return mItemType; +} + +NS_IMETHODIMP +nsDocShell::GetItemType(int32_t* aItemType) +{ + NS_ENSURE_ARG_POINTER(aItemType); + + *aItemType = ItemType(); + return NS_OK; } NS_IMETHODIMP nsDocShell::SetItemType(int32_t aItemType) { - NS_ENSURE_ARG((aItemType == typeChrome) || (typeContent == aItemType)); - - // Only allow setting the type on root docshells. Those would be the ones - // that have the docloader service as mParent or have no mParent at all. - nsCOMPtr<nsIDocumentLoader> docLoaderService = - do_GetService(NS_DOCUMENTLOADER_SERVICE_CONTRACTID); - NS_ENSURE_TRUE(docLoaderService, NS_ERROR_UNEXPECTED); - - NS_ENSURE_STATE(!mParent || mParent == docLoaderService); - - mItemType = aItemType; - - // disable auth prompting for anything but content - mAllowAuth = mItemType == typeContent; - - nsRefPtr<nsPresContext> presContext = nullptr; - GetPresContext(getter_AddRefs(presContext)); - if (presContext) { - presContext->UpdateIsChrome(); - } - - return NS_OK; -} - -NS_IMETHODIMP -nsDocShell::GetParent(nsIDocShellTreeItem ** aParent) -{ - if (!mParent) { - *aParent = nullptr; - } else { - CallQueryInterface(mParent, aParent); - } - // Note that in the case when the parent is not an nsIDocShellTreeItem we - // don't want to throw; we just want to return null. - return NS_OK; + NS_ENSURE_ARG((aItemType == typeChrome) || (typeContent == aItemType)); + + // Only allow setting the type on root docshells. Those would be the ones + // that have the docloader service as mParent or have no mParent at all. + nsCOMPtr<nsIDocumentLoader> docLoaderService = + do_GetService(NS_DOCUMENTLOADER_SERVICE_CONTRACTID); + NS_ENSURE_TRUE(docLoaderService, NS_ERROR_UNEXPECTED); + + NS_ENSURE_STATE(!mParent || mParent == docLoaderService); + + mItemType = aItemType; + + // disable auth prompting for anything but content + mAllowAuth = mItemType == typeContent; + + nsRefPtr<nsPresContext> presContext = nullptr; + GetPresContext(getter_AddRefs(presContext)); + if (presContext) { + presContext->UpdateIsChrome(); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsDocShell::GetParent(nsIDocShellTreeItem** aParent) +{ + if (!mParent) { + *aParent = nullptr; + } else { + CallQueryInterface(mParent, aParent); + } + // Note that in the case when the parent is not an nsIDocShellTreeItem we + // don't want to throw; we just want to return null. + return NS_OK; } already_AddRefed<nsDocShell> nsDocShell::GetParentDocshell() { - nsCOMPtr<nsIDocShell> docshell = do_QueryInterface(GetAsSupports(mParent)); - return docshell.forget().downcast<nsDocShell>(); + nsCOMPtr<nsIDocShell> docshell = do_QueryInterface(GetAsSupports(mParent)); + return docshell.forget().downcast<nsDocShell>(); } void nsDocShell::RecomputeCanExecuteScripts() { - bool old = mCanExecuteScripts; - nsRefPtr<nsDocShell> parent = GetParentDocshell(); - - // If we have no tree owner, that means that we've been detached from the - // docshell tree (this is distinct from having no parent dochshell, which - // is the case for root docshells). It would be nice to simply disallow - // script in detached docshells, but bug 986542 demonstrates that this - // behavior breaks at least one website. - // - // So instead, we use our previous value, unless mAllowJavascript has been