Merge from cvs-trunk-mirror to mozilla-central.

--HG--
rename : js/src/jsarray.c => js/src/jsarray.cpp
This commit is contained in:
jorendorff@mozilla.com 2008-03-28 13:01:14 -05:00
Родитель 85a4369875 185d2dcf82
Коммит c7223c1621
369 изменённых файлов: 4414 добавлений и 4643 удалений

Просмотреть файл

@ -296,9 +296,6 @@ __try {
if (NS_FAILED(xpAccessible->GetName(name)))
return E_FAIL;
if (name.IsEmpty())
return S_FALSE;
*pszName = ::SysAllocStringLen(name.get(), name.Length());
if (!*pszName)
return E_OUTOFMEMORY;

Просмотреть файл

@ -640,12 +640,6 @@ pref("browser.sessionstore.max_tabs_undo", 10);
// allow META refresh by default
pref("accessibility.blockautorefresh", false);
// import bookmarks.html into Places bookmarks
pref("browser.places.importBookmarksHTML", true);
// if false, will add the "Smart Bookmarks" folder to the personal toolbar
pref("browser.places.createdSmartBookmarks", false);
// If true, will migrate uri post-data annotations to
// bookmark post-data annotations (bug 398914)
// XXX to be removed after beta 2 (bug 391419)

Просмотреть файл

@ -76,7 +76,8 @@
accesskey="&helpMenu.accesskey;">
#endif
<menupopup id="menu_HelpPopup" onpopupshowing="buildHelpMenu();">
<menuitem oncommand="openHelpLink('firefox-help')"
<menuitem id="menu_openHelp"
oncommand="openHelpLink('firefox-help')"
#ifdef XP_MACOSX
label="&helpContentsMac.label;"
key="key_openHelpMacFrontend"/>

Просмотреть файл

@ -376,7 +376,8 @@
<observes element="Browser:Forward" attribute="disabled" />
</menuitem>
<menuitem label="&historyHomeCmd.label;"
<menuitem id="historyMenuHome"
label="&historyHomeCmd.label;"
oncommand="BrowserGoHome(event);"
onclick="checkForMiddleClick(this, event);"
key="goHome"/>

Просмотреть файл

@ -167,9 +167,14 @@ var StarUI = {
var bundle = this._element("bundle_browser");
// "Page Bookmarked" title
// Set panel title:
// if we are batching, i.e. the bookmark has been added now,
// then show Page Bookmarked, else if the bookmark did already exist,
// we are about editing it, then use Edit This Bookmark.
this._element("editBookmarkPanelTitle").value =
bundle.getString("editBookmarkPanel.pageBookmarkedTitle");
this._batching ?
bundle.getString("editBookmarkPanel.pageBookmarkedTitle") :
bundle.getString("editBookmarkPanel.editBookmarkTitle");
// No description; show the Done, Cancel;
// hide the Edit, Undo buttons

Просмотреть файл

@ -1950,11 +1950,11 @@ function checkForDirectoryListing()
}
}
function URLBarSetURI(aURI, aMustUseURI) {
function URLBarSetURI(aURI) {
var value = getBrowser().userTypedValue;
var state = "invalid";
if (!value || aMustUseURI) {
if (!value) {
if (aURI) {
// If the url has "wyciwyg://" as the protocol, strip it off.
// Nobody wants to see it on the urlbar for dynamically generated
@ -1969,13 +1969,22 @@ function URLBarSetURI(aURI, aMustUseURI) {
aURI = getWebNavigation().currentURI;
}
value = aURI.spec;
if (value == "about:blank") {
if (aURI.spec == "about:blank") {
// Replace "about:blank" with an empty string
// only if there's no opener (bug 370555).
if (!content.opener)
value = "";
value = content.opener ? aURI.spec : "";
} else {
value = losslessDecodeURI(aURI);
state = "valid";
}
}
gURLBar.value = value;
SetPageProxyState(state);
}
function losslessDecodeURI(aURI) {
var value = aURI.spec;
// Try to decode as UTF-8 if there's no encoding sequence that we would break.
if (!/%25(?:3B|2F|3F|3A|40|26|3D|2B|24|2C|23)/i.test(value))
try {
@ -1995,13 +2004,7 @@ function URLBarSetURI(aURI, aMustUseURI) {
// (RFC 3987 sections 3.2 and 4.1 paragraph 6)
value = value.replace(/[\u200e\u200f\u202a\u202b\u202c\u202d\u202e]/g,
encodeURIComponent);
state = "valid";
}
}
gURLBar.value = value;
SetPageProxyState(state);
return value;
}
// Replace the urlbar's value with the url of the page.

Просмотреть файл

@ -108,8 +108,8 @@
</keyset>
<menupopup id="picontext">
<menuitem label="&selectall.label;" command="cmd_selectall" accesskey="&selectall.accesskey;"/>
<menuitem label="&copy.label;" command="cmd_copy" accesskey="&copy.accesskey;"/>
<menuitem id="menu_selectall" label="&selectall.label;" command="cmd_selectall" accesskey="&selectall.accesskey;"/>
<menuitem id="menu_copy" label="&copy.label;" command="cmd_copy" accesskey="&copy.accesskey;"/>
</menupopup>
<stack id="topStackBar">

Просмотреть файл

@ -247,16 +247,13 @@
onget="return this.value;">
<setter>
<![CDATA[
// Force load the value into the urlbar to get it unescaped
try {
let uri = Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService).
newURI(val, null, null);
URLBarSetURI(uri, true);
} catch (ex) {
// Incase the value isn't actually a URI
val = losslessDecodeURI(uri);
} catch (ex) { }
this.value = val;
}
// Completing a result should simulate the user typing the result, so
// fire an input event.

Просмотреть файл

@ -820,16 +820,16 @@ FeedWriter.prototype = {
var stringLabel = "alwaysUseForFeeds";
switch (this._getFeedType()) {
case Ci.nsIFeed.TYPE_VIDEO:
stringlabel = "alwaysUseForVideoPodcasts";
stringLabel = "alwaysUseForVideoPodcasts";
break;
case Ci.nsIFeed.TYPE_AUDIO:
stringlabel = "alwaysUseForAudioPodcasts";
stringLabel = "alwaysUseForAudioPodcasts";
break;
}
this._contentSandbox.checkbox = checkbox;
this._contentSandbox.label = this._getFormattedString(stringlabel, [handlerName]);
this._contentSandbox.label = this._getFormattedString(stringLabel, [handlerName]);
var codeStr = "checkbox.setAttribute('label', label);";
Cu.evalInSandbox(codeStr, this._contentSandbox);

Просмотреть файл

@ -401,6 +401,14 @@ BrowserGlue.prototype = {
} catch(ex) {}
if (!importBookmarks) {
+ /**
+ * These prefs are set by the backend services upon creation (or recreation)
+ * of the Places db:
+ * - browser.places.importBookmarksHTML
+ * Set to false by the history service to indicate we need to re-import.
+ * - browser.places.createdSmartBookmarks
+ * Set during HTML import to indicate that the queries were created.
+ */
// Call it here for Fx3 profiles created before the Places folder
// has been added, otherwise it's called during import.
this.ensurePlacesDefaultQueriesInitialized();
@ -417,6 +425,9 @@ BrowserGlue.prototype = {
else {
// if there's no json backup use bookmarks.html
// ensurePlacesDefaultQueriesInitialized() is called by import.
prefBranch.setBoolPref("browser.places.createdSmartBookmarks", false);
var dirService = Cc["@mozilla.org/file/directory_service;1"].
getService(Ci.nsIProperties);
var bookmarksFile = dirService.get("BMarks", Ci.nsILocalFile);

Просмотреть файл

@ -171,8 +171,8 @@ var PlacesUIUtils = {
/**
* Get a transaction for copying a uri item from one container to another
* as a bookmark.
* @param aURI
* The URI of the item being copied
* @param aData
* JSON object of dropped or pasted item properties
* @param aContainer
* The container being copied into
* @param aIndex
@ -187,8 +187,8 @@ var PlacesUIUtils = {
/**
* Get a transaction for copying a bookmark item from one container to
* another.
* @param aID
* The identifier of the bookmark item being copied
* @param aData
* JSON object of dropped or pasted item properties
* @param aContainer
* The container being copied into
* @param aIndex
@ -215,6 +215,17 @@ var PlacesUIUtils = {
childTxns.push(this.ptm.editItemDateAdded(null, aData.dateAdded));
if (aData.lastModified)
childTxns.push(this.ptm.editItemLastModified(null, aData.lastModified));
if (aData.tags) {
var tags = aData.tags.split(", ");
// filter out tags already present, so that undo doesn't remove them
// from pre-existing bookmarks
var storedTags = PlacesUtils.tagging.getTagsForURI(itemURL, {});
tags = tags.filter(function (aTag) {
return (storedTags.indexOf(aTag) == -1);
}, this);
if (tags.length)
childTxns.push(this.ptm.tagURI(itemURL, tags));
}
return this.ptm.createItem(itemURL, aContainer, aIndex, itemTitle, keyword,
annos, childTxns);

Просмотреть файл

@ -103,6 +103,7 @@ bin/components/downloads.xpt
bin/components/editor.xpt
bin/components/embed_base.xpt
bin/components/exthandler.xpt
bin/components/exthelper.xpt
bin/components/fastfind.xpt
bin/components/feeds.xpt
bin/components/filepicker.xpt

Просмотреть файл

@ -114,6 +114,7 @@ bin\components\downloads.xpt
bin\components\editor.xpt
bin\components\embed_base.xpt
bin\components\exthandler.xpt
bin\components\exthelper.xpt
bin\components\fastfind.xpt
bin\components\feeds.xpt
bin\components\find.xpt

Просмотреть файл

@ -133,3 +133,4 @@ pausedDownloads=One paused download;#1 paused downloads
editBookmarkPanel.pageBookmarkedTitle=Page Bookmarked
editBookmarkPanel.pageBookmarkedDescription=%S will always remember this page for you.
editBookmarkPanel.bookmarkedRemovedTitle=Bookmark Removed
editBookmarkPanel.editBookmarkTitle=Edit This Bookmark

Просмотреть файл

@ -211,6 +211,7 @@ menuitem:not([type]) {
-moz-binding: url("chrome://global/content/bindings/menu.xml#menuitem-iconic");
}
#placesContext_open\:newwindow,
menuitem[command="cmd_newNavigator"],
#context-openlink,
#context-openframe {
@ -218,6 +219,8 @@ menuitem[command="cmd_newNavigator"],
-moz-image-region: rect(0px 80px 16px 64px);
}
#placesContext_open\:newtab,
#placesContext_openContainer\:tabs,
menuitem[command="cmd_newNavigatorTab"],
#context-openlinkintab,
#context-openframeintab {
@ -341,6 +344,8 @@ menuitem[command="Browser:Stop"][disabled],
list-style-image: url("moz-icon://stock/gtk-stop?size=menu&state=disabled");
}
#placesContext_reload,
#placesContext_reloadMicrosummary,
menuitem[command="Browser:Reload"],
#context-reload,
#context-reloadframe {
@ -404,7 +409,7 @@ menuitem[key="goForwardKb"][disabled][chromedir="rtl"],
list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=menu&state=disabled");
}
menuitem[command="Browser:Home"] {
#historyMenuHome {
list-style-image: url("moz-icon://stock/gtk-home?size=menu");
}
@ -429,6 +434,7 @@ menuitem[command="View:PageInfo"],
list-style-image: url("moz-icon://stock/gtk-info?size=menu");
}
#placesContext_show\:info,
#context-metadata {
list-style-image: url("moz-icon://stock/gtk-properties?size=menu");
}

Просмотреть файл

@ -284,3 +284,16 @@ treechildren::-moz-tree-cell-text(broken) {
font-weight: bold;
margin: 2px 10px 0px 10px;
}
/* Icons for context menus */
menuitem:not([type]) {
-moz-binding: url("chrome://global/content/bindings/menu.xml#menuitem-iconic");
}
#menu_selectall {
list-style-image: url("moz-icon://stock/gtk-select-all?size=menu");
}
#menu_copy {
list-style-image: url("moz-icon://stock/gtk-copy?size=menu");
}

Просмотреть файл

@ -138,16 +138,25 @@ menuitem[cmd="cmd_selectAll"][disabled] {
list-style-image: url("moz-icon://stock/gtk-select-all?size=menu&state=disabled");
}
#placesContext_open\:newwindow,
menuitem[command="placesCmd_open:window"] {
list-style-image: url("chrome://browser/skin/Toolbar-small.png");
-moz-image-region: rect(0px 80px 16px 64px);
}
#placesContext_open\:newtab,
#placesContext_openContainer\:tabs,
menuitem[command="placesCmd_open:tab"] {
list-style-image: url("chrome://browser/skin/Toolbar-small.png");
-moz-image-region: rect(0px 64px 16px 48px);
}
#placesContext_show\:info,
menuitem[command="placesCmd_show:info"] {
list-style-image: url("moz-icon://stock/gtk-properties?size=menu");
}
#placesContext_reload,
#placesContext_reloadMicrosummary {
list-style-image: url("moz-icon://stock/gtk-refresh?size=menu");
}

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 386 B

После

Ширина:  |  Высота:  |  Размер: 361 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 937 B

После

Ширина:  |  Высота:  |  Размер: 684 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 933 B

После

Ширина:  |  Высота:  |  Размер: 681 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 584 B

После

Ширина:  |  Высота:  |  Размер: 414 B

Двоичные данные
browser/themes/winstripe/browser/Go-arrow.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 570 B

После

Ширина:  |  Высота:  |  Размер: 412 B

Двоичные данные
browser/themes/winstripe/browser/Info-aero.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 762 B

После

Ширина:  |  Высота:  |  Размер: 662 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.3 KiB

После

Ширина:  |  Высота:  |  Размер: 821 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.3 KiB

После

Ширина:  |  Высота:  |  Размер: 828 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.2 KiB

После

Ширина:  |  Высота:  |  Размер: 682 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.1 KiB

После

Ширина:  |  Высота:  |  Размер: 707 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 120 KiB

После

Ширина:  |  Высота:  |  Размер: 74 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 57 KiB

После

Ширина:  |  Высота:  |  Размер: 21 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 60 KiB

После

Ширина:  |  Высота:  |  Размер: 24 KiB

Двоичные данные
browser/themes/winstripe/browser/Toolbar.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 111 KiB

После

Ширина:  |  Высота:  |  Размер: 68 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.8 KiB

После

Ширина:  |  Высота:  |  Размер: 1.8 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.8 KiB

После

Ширина:  |  Высота:  |  Размер: 1.8 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.8 KiB

После

Ширина:  |  Высота:  |  Размер: 1.8 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.8 KiB

После

Ширина:  |  Высота:  |  Размер: 1.8 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.8 KiB

После

Ширина:  |  Высота:  |  Размер: 1.8 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.8 KiB

После

Ширина:  |  Высота:  |  Размер: 1.8 KiB

Двоичные данные
browser/themes/winstripe/browser/icon-aero.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 953 B

После

Ширина:  |  Высота:  |  Размер: 824 B

Двоичные данные
browser/themes/winstripe/browser/icon.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 915 B

После

Ширина:  |  Высота:  |  Размер: 861 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 19 KiB

После

Ширина:  |  Высота:  |  Размер: 13 KiB

Двоичные данные
browser/themes/winstripe/browser/identity.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 19 KiB

После

Ширина:  |  Высота:  |  Размер: 14 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 531 B

После

Ширина:  |  Высота:  |  Размер: 505 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 535 B

После

Ширина:  |  Высота:  |  Размер: 467 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 459 B

После

Ширина:  |  Высота:  |  Размер: 435 B

Двоичные данные
browser/themes/winstripe/browser/menu-back.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 367 B

После

Ширина:  |  Высота:  |  Размер: 341 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 454 B

После

Ширина:  |  Высота:  |  Размер: 434 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 370 B

После

Ширина:  |  Высота:  |  Размер: 343 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 25 KiB

После

Ширина:  |  Высота:  |  Размер: 8.4 KiB

Двоичные данные
browser/themes/winstripe/browser/pageInfo.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 24 KiB

После

Ширина:  |  Высота:  |  Размер: 8.3 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 376 B

После

Ширина:  |  Высота:  |  Размер: 346 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 372 B

После

Ширина:  |  Высота:  |  Размер: 371 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 288 B

После

Ширина:  |  Высота:  |  Размер: 272 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 393 B

После

Ширина:  |  Высота:  |  Размер: 316 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 434 B

После

Ширина:  |  Высота:  |  Размер: 335 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 394 B

После

Ширина:  |  Высота:  |  Размер: 325 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 428 B

После

Ширина:  |  Высота:  |  Размер: 335 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 282 B

После

Ширина:  |  Высота:  |  Размер: 271 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 332 B

После

Ширина:  |  Высота:  |  Размер: 293 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 346 B

После

Ширина:  |  Высота:  |  Размер: 307 B

Двоичные данные
browser/themes/winstripe/browser/places/plus.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 373 B

После

Ширина:  |  Высота:  |  Размер: 308 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 718 B

После

Ширина:  |  Высота:  |  Размер: 393 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 639 B

После

Ширина:  |  Высота:  |  Размер: 352 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.9 KiB

После

Ширина:  |  Высота:  |  Размер: 1.9 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.7 KiB

После

Ширина:  |  Высота:  |  Размер: 1.7 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 755 B

После

Ширина:  |  Высота:  |  Размер: 676 B

Двоичные данные
browser/themes/winstripe/browser/places/tag.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 548 B

После

Ширина:  |  Высота:  |  Размер: 517 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 189 B

После

Ширина:  |  Высота:  |  Размер: 181 B

Двоичные данные
browser/themes/winstripe/browser/places/view.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 189 B

После

Ширина:  |  Высота:  |  Размер: 181 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 26 KiB

После

Ширина:  |  Высота:  |  Размер: 9.0 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 26 KiB

После

Ширина:  |  Высота:  |  Размер: 9.2 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 491 B

После

Ширина:  |  Высота:  |  Размер: 446 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 869 B

После

Ширина:  |  Высота:  |  Размер: 599 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 825 B

После

Ширина:  |  Высота:  |  Размер: 509 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 882 B

После

Ширина:  |  Высота:  |  Размер: 624 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 837 B

После

Ширина:  |  Высота:  |  Размер: 527 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 359 B

После

Ширина:  |  Высота:  |  Размер: 294 B

Просмотреть файл

@ -1378,9 +1378,14 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
rv = sourceBaseURI->GetScheme(sourceScheme);
if (NS_FAILED(rv)) return rv;
if (targetScheme.Equals(sourceScheme,
nsCaseInsensitiveCStringComparator()) &&
!sourceScheme.LowerCaseEqualsLiteral(NS_NULLPRINCIPAL_SCHEME))
if (sourceScheme.LowerCaseEqualsLiteral(NS_NULLPRINCIPAL_SCHEME)) {
// A null principal can target its own URI.
if (sourceURI == aTargetURI) {
return NS_OK;
}
}
else if (targetScheme.Equals(sourceScheme,
nsCaseInsensitiveCStringComparator()))
{
// every scheme can access another URI from the same scheme,
// as long as they don't represent null principals.

Просмотреть файл

@ -0,0 +1,14 @@
<html>
<head>
<script>
function loaded() {
var node = document;
var handler = function(operation, key, data, src, dst) { alert(data); };
node.setUserData("foo", "data", handler);
}
</script>
</head>
<body onload="loaded();">
<div id="elem"></div>
</body>
</html>

Просмотреть файл

@ -0,0 +1,19 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script>
function boom()
{
var div = document.getElementById("div");
div.textContent = String.fromCharCode(0xDCBF);
}
</script>
</head>
<body onload="boom();">
<div id="div"></div>
</body>
</html>

Просмотреть файл

@ -1,4 +1,5 @@
load 308120-1.xul
load 324871-1.html
load 325730-1.html
load 326618-1.html
load 326646-1.html
@ -19,6 +20,7 @@ load 354645-1.xul
load 366200-1.xhtml
load 369216-1.html
load 371466-1.xhtml
load 377360-1.xhtml
load 386000-1.html
load 386794-1.html
load 395469-1.xhtml

Просмотреть файл

@ -51,6 +51,7 @@
#include "nsIAtom.h"
#include "nsCompatibility.h"
#include "nsTObserverArray.h"
#include "nsNodeInfoManager.h"
class nsIContent;
class nsPresContext;
@ -80,7 +81,6 @@ class nsIObserver;
class nsScriptLoader;
class nsIContentSink;
class nsIScriptEventManager;
class nsNodeInfoManager;
class nsICSSLoader;
class nsHTMLStyleSheet;
class nsIHTMLCSSStyleSheet;
@ -97,8 +97,8 @@ class nsFrameLoader;
// IID for the nsIDocument interface
#define NS_IDOCUMENT_IID \
{ 0xd76acf2e, 0x4b55, 0x420c, \
{ 0xaa, 0xbf, 0x5c, 0x4d, 0xbf, 0xc9, 0x81, 0x08 } }
{ 0x0cf9986f, 0x6e27, 0x4c24, \
{ 0x9f, 0x43, 0x87, 0x01, 0x52, 0xf7, 0x4c, 0x0a } }
// Flag for AddStyleSheet().
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
@ -117,7 +117,6 @@ public:
nsIDocument()
: nsINode(nsnull),
mCharacterSet(NS_LITERAL_CSTRING("ISO-8859-1")),
mBindingManager(nsnull),
mNodeInfoManager(nsnull),
mCompatMode(eCompatibility_FullStandards),
mIsInitialDocumentInWindow(PR_FALSE),
@ -631,7 +630,7 @@ public:
nsBindingManager* BindingManager() const
{
return mBindingManager;
return mNodeInfoManager->GetBindingManager();
}
/**
@ -966,7 +965,6 @@ protected:
// releasing it) happens in the nsDocument destructor. We'd prefer to
// do it here but nsNodeInfoManager is a concrete class that we don't
// want to expose to users of the nsIDocument API outside of Gecko.
// XXX Same thing applies to mBindingManager
}
/**
@ -1001,7 +999,6 @@ protected:
// We'd like these to be nsRefPtrs, but that'd require us to include
// additional headers that we don't want to expose.
// The cleanup is handled by the nsDocument destructor.
nsBindingManager* mBindingManager; // [STRONG]
nsNodeInfoManager* mNodeInfoManager; // [STRONG]
nsICSSLoader* mCSSLoader; // [STRONG]

Просмотреть файл

@ -117,7 +117,6 @@ CPPSRCS = \
nsContentSink.cpp \
nsContentUtils.cpp \
nsCopySupport.cpp \
nsCrossSiteListenerProxy.cpp \
nsDataDocumentContentPolicy.cpp \
nsDOMAttribute.cpp \
nsDOMAttributeMap.cpp \

Просмотреть файл

@ -167,10 +167,13 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsContentSink)
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDocument)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mParser)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mNodeInfoManager)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsContentSink)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDocument)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mParser)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mNodeInfoManager,
nsNodeInfoManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END

Просмотреть файл

@ -1,969 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jonas Sicking <jonas@sicking.cc> (Original Author)
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsCrossSiteListenerProxy.h"
#include "nsIChannel.h"
#include "nsIHttpChannel.h"
#include "nsDOMError.h"
#include "nsContentUtils.h"
#include "nsIScriptSecurityManager.h"
#include "nsNetUtil.h"
#include "nsIParser.h"
#include "nsParserCIID.h"
#include "nsICharsetAlias.h"
#include "nsMimeTypes.h"
#include "nsIStreamConverterService.h"
#include "nsStringStream.h"
#include "nsParserUtils.h"
#include "nsGkAtoms.h"
#include "nsWhitespaceTokenizer.h"
#include "nsIChannelEventSink.h"
static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
NS_IMPL_ISUPPORTS7(nsCrossSiteListenerProxy, nsIStreamListener,
nsIRequestObserver, nsIContentSink, nsIXMLContentSink,
nsIExpatSink, nsIChannelEventSink, nsIInterfaceRequestor)
nsCrossSiteListenerProxy::nsCrossSiteListenerProxy(nsIStreamListener* aOuter,
nsIPrincipal* aRequestingPrincipal,
nsIChannel* aChannel,
nsresult* aResult)
: mOuterListener(aOuter),
mRequestingPrincipal(aRequestingPrincipal),
mAcceptState(eNotSet),
mHasForwardedRequest(PR_FALSE),
mHasBeenCrossSite(PR_FALSE)
{
aRequestingPrincipal->GetURI(getter_AddRefs(mRequestingURI));
aChannel->GetNotificationCallbacks(getter_AddRefs(mOuterNotificationCallbacks));
aChannel->SetNotificationCallbacks(this);
*aResult = UpdateChannel(aChannel);
}
nsresult
nsCrossSiteListenerProxy::ForwardRequest(PRBool aFromStop)
{
if (mHasForwardedRequest) {
return NS_OK;
}
mHasForwardedRequest = PR_TRUE;
if (mParser) {
mParser->Terminate();
mParser = nsnull;
mParserListener = nsnull;
}
if (mAcceptState != eAccept) {
mAcceptState = eDeny;
mOuterRequest->Cancel(NS_ERROR_DOM_BAD_URI);
mOuterListener->OnStartRequest(mOuterRequest, mOuterContext);
// Only call OnStopRequest here if we were called from OnStopRequest.
// Otherwise the call to Cancel will make us get an OnStopRequest later
// so we'll forward OnStopRequest then.
if (aFromStop) {
mOuterListener->OnStopRequest(mOuterRequest, mOuterContext,
NS_ERROR_DOM_BAD_URI);
}
// Clear this data just in case since it should never be forwarded.
mStoredData.Truncate();
return NS_ERROR_DOM_BAD_URI;
}
nsresult rv = mOuterListener->OnStartRequest(mOuterRequest, mOuterContext);
NS_ENSURE_SUCCESS(rv, rv);
if (!mStoredData.IsEmpty()) {
nsCOMPtr<nsIInputStream> stream;
rv = NS_NewCStringInputStream(getter_AddRefs(stream), mStoredData);
NS_ENSURE_SUCCESS(rv, rv);
rv = mOuterListener->OnDataAvailable(mOuterRequest, mOuterContext, stream,
0, mStoredData.Length());
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}
NS_IMETHODIMP
nsCrossSiteListenerProxy::OnStartRequest(nsIRequest* aRequest,
nsISupports* aContext)
{
mOuterRequest = aRequest;
mOuterContext = aContext;
// Check if the request failed
nsresult status;
nsresult rv = aRequest->GetStatus(&status);
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(status)) {
mAcceptState = eDeny;
return ForwardRequest(PR_FALSE);
}
// Check if this was actually a cross domain request
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
if (!channel) {
return NS_ERROR_DOM_BAD_URI;
}
nsCOMPtr<nsIURI> finalURI;
channel->GetURI(getter_AddRefs(finalURI));
if (!mHasBeenCrossSite) {
mAcceptState = eAccept;
return ForwardRequest(PR_FALSE);
}
nsCOMPtr<nsIHttpChannel> http = do_QueryInterface(channel);
if (http) {
PRBool succeeded;
rv = http->GetRequestSucceeded(&succeeded);
NS_ENSURE_SUCCESS(rv, rv);
if (!succeeded) {
mAcceptState = eDeny;
return ForwardRequest(PR_FALSE);
}
}
// Get the list of subdomains out of mRequestingURI
nsCString host;
rv = mRequestingURI->GetAsciiHost(host);
NS_ENSURE_SUCCESS(rv, rv);
PRInt32 nextDot, currDot = 0;
while ((nextDot = host.FindChar('.', currDot)) != -1) {
mReqSubdomains.AppendElement(Substring(host, currDot, nextDot - currDot));
currDot = nextDot + 1;
}
mReqSubdomains.AppendElement(Substring(host, currDot));
// Check the Access-Control header
if (http) {
nsCAutoString ac;
rv = http->GetResponseHeader(NS_LITERAL_CSTRING("Access-Control"), ac);
if (NS_SUCCEEDED(rv)) {
CheckHeader(ac);
}
}
if (mAcceptState == eDeny) {
return ForwardRequest(PR_FALSE);
}
// Set up a parser with us as a sink to look for PIs
mParser = do_CreateInstance(kCParserCID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
mParserListener = do_QueryInterface(mParser);
mParser->SetCommand(kLoadAsData);
mParser->SetContentSink(this);
mParser->Parse(finalURI);
// check channel's charset...
nsCAutoString charset(NS_LITERAL_CSTRING("UTF-8"));
PRInt32 charsetSource = kCharsetFromDocTypeDefault;
nsCAutoString charsetVal;
rv = channel->GetContentCharset(charsetVal);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsICharsetAlias> calias =
do_GetService(NS_CHARSETALIAS_CONTRACTID);
if (calias) {
nsCAutoString preferred;
rv = calias->GetPreferred(charsetVal, preferred);
if (NS_SUCCEEDED(rv)) {
charset = preferred;
charsetSource = kCharsetFromChannel;
}
}
}
mParser->SetDocumentCharset(charset, charsetSource);
nsCAutoString contentType;
channel->GetContentType(contentType);
// Time to sniff! Note: this should go away once file channels do
// sniffing themselves.
PRBool sniff;
if (NS_SUCCEEDED(finalURI->SchemeIs("file", &sniff)) && sniff &&
contentType.Equals(UNKNOWN_CONTENT_TYPE)) {
nsCOMPtr<nsIStreamConverterService> serv =
do_GetService("@mozilla.org/streamConverters;1", &rv);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIStreamListener> converter;
rv = serv->AsyncConvertData(UNKNOWN_CONTENT_TYPE,
"*/*",
mParserListener,
aContext,
getter_AddRefs(converter));
if (NS_SUCCEEDED(rv)) {
mParserListener = converter;
}
}
}
// Hold a local reference to make sure the parser doesn't go away
nsCOMPtr<nsIStreamListener> stackedListener = mParserListener;
return stackedListener->OnStartRequest(aRequest, aContext);
}
NS_IMETHODIMP
nsCrossSiteListenerProxy::OnStopRequest(nsIRequest* aRequest,
nsISupports* aContext,
nsresult aStatusCode)
{
if (mHasForwardedRequest) {
return mOuterListener->OnStopRequest(aRequest, aContext, aStatusCode);
}
mAcceptState = eDeny;
return ForwardRequest(PR_TRUE);
}
NS_METHOD
StringSegmentWriter(nsIInputStream *aInStream,
void *aClosure,
const char *aFromSegment,
PRUint32 aToOffset,
PRUint32 aCount,
PRUint32 *aWriteCount)
{
nsCString* dest = static_cast<nsCString*>(aClosure);
dest->Append(aFromSegment, aCount);
*aWriteCount = aCount;
return NS_OK;
}
NS_IMETHODIMP
nsCrossSiteListenerProxy::OnDataAvailable(nsIRequest* aRequest,
nsISupports* aContext,
nsIInputStream* aInputStream,
PRUint32 aOffset,
PRUint32 aCount)
{
if (mHasForwardedRequest) {
if (mAcceptState != eAccept) {
return NS_ERROR_DOM_BAD_URI;
}
return mOuterListener->OnDataAvailable(aRequest, aContext, aInputStream,
aOffset, aCount);
}
NS_ASSERTION(mStoredData.Length() == aOffset,
"Stored wrong amount of data");
PRUint32 read;
nsresult rv = aInputStream->ReadSegments(StringSegmentWriter, &mStoredData,
aCount, &read);
NS_ENSURE_SUCCESS(rv, rv);
NS_ASSERTION(read == aCount, "didn't store all of the stream");
nsCOMPtr<nsIInputStream> stream;
rv = NS_NewCStringInputStream(getter_AddRefs(stream),
Substring(mStoredData, aOffset));
NS_ENSURE_SUCCESS(rv, rv);
// Hold a local reference to make sure the parser doesn't go away
nsCOMPtr<nsIStreamListener> stackedListener = mParserListener;
rv = stackedListener->OnDataAvailable(aRequest, aContext, stream, aOffset,
aCount);
// When we forward the request we also terminate the parsing which will
// result in an error bubbling up to here. We want to ignore the error
// in that case.
if (mHasForwardedRequest) {
rv = mAcceptState == eAccept ? NS_OK : NS_ERROR_DOM_BAD_URI;
}
return rv;
}
NS_IMETHODIMP
nsCrossSiteListenerProxy::HandleStartElement(const PRUnichar *aName,
const PRUnichar **aAtts,
PRUint32 aAttsCount,
PRInt32 aIndex,
PRUint32 aLineNumber)
{
// We're done processing the prolog.
ForwardRequest(PR_FALSE);
// Stop the parser since we don't want to spend more cycles on parsing
// stuff.
return NS_ERROR_HTMLPARSER_STOPPARSING;
}
NS_IMETHODIMP
nsCrossSiteListenerProxy::HandleEndElement(const PRUnichar *aName)
{
NS_ASSERTION(mHasForwardedRequest, "Should have forwarded request");
return NS_OK;
}
NS_IMETHODIMP
nsCrossSiteListenerProxy::HandleComment(const PRUnichar *aName)
{
return NS_OK;
}
NS_IMETHODIMP
nsCrossSiteListenerProxy::HandleCDataSection(const PRUnichar *aData,
PRUint32 aLength)
{
NS_ASSERTION(mHasForwardedRequest, "Should have forwarded request");
return NS_OK;
}
NS_IMETHODIMP
nsCrossSiteListenerProxy::HandleDoctypeDecl(const nsAString & aSubset,
const nsAString & aName,
const nsAString & aSystemId,
const nsAString & aPublicId,
nsISupports *aCatalogData)
{
return NS_OK;
}
NS_IMETHODIMP
nsCrossSiteListenerProxy::HandleCharacterData(const PRUnichar *aData,
PRUint32 aLength)
{
return NS_OK;
}
NS_IMETHODIMP
nsCrossSiteListenerProxy::HandleProcessingInstruction(const PRUnichar *aTarget,
const PRUnichar *aData)
{
if (mHasForwardedRequest ||
!NS_LITERAL_STRING("access-control").Equals(aTarget)) {
return NS_OK;
}
nsDependentString data(aData);
PRBool seenType = PR_FALSE, seenExclude = PR_FALSE;
PRBool ruleIsAllow = PR_FALSE;
nsAutoString itemList, excludeList;
PRUint32 i;
for (i = 0;; ++i) {
nsAutoString attrName;
if (nsParserUtils::GetQuotedAttrNameAt(data, i, attrName) &&
attrName.IsEmpty()) {
break;
}
nsCOMPtr<nsIAtom> attr = do_GetAtom(attrName);
PRBool res;
if (!seenType && attrName.EqualsLiteral("allow")) {
seenType = PR_TRUE;
ruleIsAllow = PR_TRUE;
res = nsParserUtils::GetQuotedAttributeValue(data, attr, itemList);
}
else if (!seenType && attrName.EqualsLiteral("deny")) {
seenType = PR_TRUE;
ruleIsAllow = PR_FALSE;
res = nsParserUtils::GetQuotedAttributeValue(data, attr, itemList);
}
else if (!seenExclude && attrName.EqualsLiteral("exclude")) {
seenExclude = PR_TRUE;
res = nsParserUtils::GetQuotedAttributeValue(data, attr, excludeList);
}
else {
res = PR_FALSE;
}
if (!res) {
// parsing attribute value failed or unknown/duplicated attribute
mAcceptState = eDeny;
return ForwardRequest(PR_FALSE);
}
}
PRBool matchesRule = PR_FALSE;
nsWhitespaceTokenizer itemTok(itemList);
if (!itemTok.hasMoreTokens()) {
mAcceptState = eDeny;
return ForwardRequest(PR_FALSE);
}
while (itemTok.hasMoreTokens()) {
// Order is important here since we always want to call the function
matchesRule = VerifyAndMatchDomainPattern(
NS_ConvertUTF16toUTF8(itemTok.nextToken())) || matchesRule;
}
nsWhitespaceTokenizer excludeTok(excludeList);
while (excludeTok.hasMoreTokens()) {
// Order is important here since we always want to call the function
matchesRule = !VerifyAndMatchDomainPattern(
NS_ConvertUTF16toUTF8(excludeTok.nextToken())) && matchesRule;
}
if (matchesRule && mAcceptState != eDeny) {
mAcceptState = ruleIsAllow ? eAccept : eDeny;
}
if (mAcceptState == eDeny) {
return ForwardRequest(PR_FALSE);
}
return NS_OK;
}
NS_IMETHODIMP
nsCrossSiteListenerProxy::HandleXMLDeclaration(const PRUnichar *aVersion,
const PRUnichar *aEncoding,
PRInt32 aStandalone)
{
return NS_OK;
}
NS_IMETHODIMP
nsCrossSiteListenerProxy::ReportError(const PRUnichar *aErrorText,
const PRUnichar *aSourceText,
nsIScriptError *aError,
PRBool *_retval)
{
if (!mHasForwardedRequest) {
mAcceptState = eDeny;
return ForwardRequest(PR_FALSE);
}
return NS_OK;
}
NS_IMETHODIMP
nsCrossSiteListenerProxy::WillBuildModel()
{
nsCOMPtr<nsIDTD> dtd;
mParser->GetDTD(getter_AddRefs(dtd));
NS_ASSERTION(dtd, "missing dtd in WillBuildModel");
if (dtd && !(dtd->GetType() & NS_IPARSER_FLAG_XML)) {
ForwardRequest(PR_FALSE);
// Stop the parser since we don't want to spend more cycles on parsing
// stuff.
return NS_ERROR_HTMLPARSER_STOPPARSING;
}
return NS_OK;
}
// Moves aIter past the LWS (RFC2616) directly following it.
// Returns PR_TRUE and updates aIter if there was an LWS there,
// PR_FALSE otherwise
static PRBool
EatLWS(const char*& aIter, const char* aEnd)
{
if (aIter + 1 < aEnd && *aIter == '\r' && *(aIter + 1) == '\n') {
aIter += 2;
}
PRBool res = PR_FALSE;
while (aIter < aEnd && (*aIter == '\t' || *aIter == ' ')) {
++aIter;
res = PR_TRUE;
}
return res;
}
// Moves aIter past the string, given by aString, directly following it.
// Returns PR_TRUE and updates aIter if the string was there,
// PR_FALSE otherwise
static PRBool
EatString(const char*& aIter, const char* aEnd, const char* aString)
{
const char* local = aIter;
while (*aString && local < aEnd && *local == *aString) {
++local;
++aString;
}
if (*aString) {
return PR_FALSE;
}
aIter = local;
return PR_TRUE;
}
// Moves aIter to the first aChar following it.
// Returns The string between the aIters initial position and the
// found character if one was found.
// Returns an empty string otherwise.
static nsDependentCSubstring
EatToChar(const char*& aIter, const char* aEnd, char aChar)
{
const char* start = aIter;
while (aIter < aEnd) {
if (*aIter == aChar) {
return Substring(start, aIter);
}
++aIter;
}
static char emptyStatic[] = { '\0' };
aIter = start;
return Substring(emptyStatic, emptyStatic);
}
PRBool
nsCrossSiteListenerProxy::MatchPatternList(const char*& aIter, const char* aEnd)
{
PRBool matchesList = PR_FALSE;
PRBool hasItems = PR_FALSE;
for (;;) {
const char* start = aIter;
if (!EatLWS(aIter, aEnd)) {
break;
}
if (!EatString(aIter, aEnd, "<")) {
// restore iterator to before LWS since it wasn't part of the list
aIter = start;
break;
}
const nsACString& accessItem = EatToChar(aIter, aEnd, '>');
if (!EatString(aIter, aEnd, ">")) {
mAcceptState = eDeny;
break;
}
hasItems = PR_TRUE;
// Order is important here since we always want to call the function
matchesList = VerifyAndMatchDomainPattern(accessItem) || matchesList;
}
if (!hasItems) {
mAcceptState = eDeny;
}
return matchesList;
}
#define DENY_AND_RETURN \
mAcceptState = eDeny; \
return
void
nsCrossSiteListenerProxy::CheckHeader(const nsCString& aHeader)
{
const char* iter = aHeader.BeginReading();
const char* end = aHeader.EndReading();
// ruleset ::= LWS? rule LWS? ("," LWS? rule LWS?)*
while (iter < end) {
// eat LWS?
EatLWS(iter, end);
// rule ::= rule-type (LWS pattern)+ (LWS "exclude" (LWS pattern)+)?
// eat rule-type
PRBool ruleIsAllow;
if (EatString(iter, end, "deny")) {
ruleIsAllow = PR_FALSE;
}
else if (EatString(iter, end, "allow")) {
ruleIsAllow = PR_TRUE;
}
else {
DENY_AND_RETURN;
}
// eat (LWS pattern)+
PRBool matchesRule = MatchPatternList(iter, end);
PRBool ateLWS = EatLWS(iter, end);
// eat (LWS "exclude" (LWS pattern)+)?
if (ateLWS && EatString(iter, end, "exclude")) {
ateLWS = PR_FALSE;
// Order is important here since we always want to call the function
matchesRule = !MatchPatternList(iter, end) && matchesRule;
}
if (matchesRule && mAcceptState != eDeny) {
mAcceptState = ruleIsAllow ? eAccept : eDeny;
}
// eat LWS?
if (!ateLWS) {
EatLWS(iter, end);
}
if (iter != end) {
if (!EatString(iter, end, ",")) {
DENY_AND_RETURN;
}
}
}
}
// Moves aIter forward one character if the character at aIter is in [a-zA-Z]
// Returns PR_TRUE and updates aIter if such a character was found.
// PR_FALSE otherwise.
static PRBool
EatAlpha(nsACString::const_iterator& aIter, nsACString::const_iterator& aEnd)
{
if (aIter != aEnd && ((*aIter >= 'A' && *aIter <= 'Z') ||
(*aIter >= 'a' && *aIter <= 'z'))) {
++aIter;
return PR_TRUE;
}
return PR_FALSE;
}
// Moves aIter forward one character if the character at aIter is in [0-9]
// Returns PR_TRUE and updates aIter if such a character was found.
// PR_FALSE otherwise.
static PRBool
EatDigit(nsACString::const_iterator& aIter, nsACString::const_iterator& aEnd)
{
if (aIter != aEnd && *aIter >= '0' && *aIter <= '9') {
++aIter;
return PR_TRUE;
}
return PR_FALSE;
}
// Moves aIter forward one character if the character at aIter is aChar
// Returns PR_TRUE and updates aIter if aChar was found.
// PR_FALSE otherwise.
static PRBool
EatChar(nsACString::const_iterator& aIter, nsACString::const_iterator& aEnd,
char aChar)
{
if (aIter != aEnd && *aIter == aChar) {
++aIter;
return PR_TRUE;
}
return PR_FALSE;
}
// Moves aIter forward until it hits a subdomain terminator (* : or whitespace)
// or reaches the end
// access-item ::= (scheme "://")? domain-pattern (":" port)? | "*"
// domain-pattern ::= subdomain | "*." subdomain
// Returns PR_TRUE and updates aIter if a terminator is found.
// PR_FALSE otherwise.
static void
EatSubdomainChars(nsACString::const_iterator& aIter,
nsACString::const_iterator& aEnd)
{
NS_ASSERTION(aIter.get() <= aEnd.get(), "EatSubdomainChars failed");
// Make sure to not allow initial hyphens
if (*aIter == '-') {
return;
}
while (aIter != aEnd) {
unsigned char c = *aIter;
if (c <= 0x2c ||
0x2e <= c && c <= 0x2f ||
0x3a <= c && c <= 0x40 ||
0x5b <= c && c <= 0x60 ||
0x7b <= c && c <= 0x7f) {
return;
}
++aIter;
}
}
static PRBool
ACEEquals(const nsACString &aPattern, const nsCString &domain)
{
if (aPattern.LowerCaseEqualsASCII(domain.get(), domain.Length()))
return PR_TRUE;
// Convert subdomain patern to ACE
nsCString acePattern;
if (!NS_StringToACE(aPattern, acePattern))
return PR_FALSE;
return acePattern.LowerCaseEqualsASCII(domain.get(), domain.Length());
}
PRBool
nsCrossSiteListenerProxy::VerifyAndMatchDomainPattern(const nsACString& aPattern)
{
if (aPattern.EqualsLiteral("*")) {
return PR_TRUE;
}
// access-item ::= (scheme "://")? domain-pattern (":" port)? | "*"
nsACString::const_iterator start, iter, end;
aPattern.BeginReading(start);
aPattern.EndReading(end);
// (scheme "://")?
nsCString patternScheme;
nsACString::const_iterator schemeStart = start, schemeEnd = end;
if (FindInReadable(NS_LITERAL_CSTRING("://"), schemeStart, schemeEnd)) {
// There is a '://' in the string which means that it must start with
// a scheme.
iter = start;
if (!EatAlpha(iter, end)) {
DENY_AND_RETURN PR_FALSE;
}
while(EatAlpha(iter, end) ||
EatDigit(iter, end) ||
EatChar(iter, end, '+') ||
EatChar(iter, end, '-') ||
EatChar(iter, end, '.')) {}
if (iter != schemeStart) {
DENY_AND_RETURN PR_FALSE;
}
// Set the scheme
patternScheme = Substring(start, iter);
start = iter.advance(3);
}
// domain-pattern ::= subdomain | "*." subdomain
PRBool patternHasWild = PR_FALSE;
if (EatChar(start, end, '*')) {
if (!EatChar(start, end, '.')) {
DENY_AND_RETURN PR_FALSE;
}
patternHasWild = PR_TRUE;
}
nsTArray<nsCString> patternSubdomains;
// subdomain ::= label | subdomain "." label
do {
iter = start;
EatSubdomainChars(iter, end);
const nsDependentCSubstring& label = Substring(start, iter);
if (label.Last() == '-') {
DENY_AND_RETURN PR_FALSE;
}
start = iter;
// Save the label
patternSubdomains.AppendElement(label);
} while (EatChar(start, end, '.'));
// (":" port)?
PRInt32 patternPort = -1;
if (EatChar(start, end, ':')) {
iter = start;
while (EatDigit(iter, end)) {}
if (iter != start) {
PRInt32 ec;
patternPort = PromiseFlatCString(Substring(start, iter)).ToInteger(&ec);
NS_ASSERTION(NS_SUCCEEDED(ec), "ToInteger failed");
}
start = iter;
}
// Did we consume the whole pattern?
if (start != end) {
DENY_AND_RETURN PR_FALSE;
}
// Do checks at the end so that we make sure that the whole pattern is
// checked for syntax correctness first.
// Check scheme
PRBool res;
if (!patternScheme.IsEmpty() &&
(NS_FAILED(mRequestingURI->SchemeIs(patternScheme.get(), &res)) ||
!res)) {
return PR_FALSE;
}
// Check port
if (patternPort == -1 && !patternScheme.IsEmpty())
patternPort = NS_GetDefaultPort(patternScheme.get());
if (patternPort != -1 && patternPort != NS_GetRealPort(mRequestingURI)) {
return PR_FALSE;
}
// Check subdomain
PRUint32 patternPos = patternSubdomains.Length();
PRUint32 reqPos = mReqSubdomains.Length();
do {
--patternPos;
--reqPos;
if (!ACEEquals(patternSubdomains[patternPos], mReqSubdomains[reqPos])) {
return PR_FALSE;
}
} while (patternPos > 0 && reqPos > 0);
// Only matches if we've matched all of pattern and, if there is a wildcard, there
// is at least one more entry in mReqSubdomains.
return patternPos == 0 &&
(!patternHasWild || reqPos >= 1);
}
NS_IMETHODIMP
nsCrossSiteListenerProxy::GetInterface(const nsIID & aIID, void **aResult)
{
if (aIID.Equals(NS_GET_IID(nsIChannelEventSink))) {
*aResult = static_cast<nsIChannelEventSink*>(this);
NS_ADDREF_THIS();
return NS_OK;
}
return mOuterNotificationCallbacks ?
mOuterNotificationCallbacks->GetInterface(aIID, aResult) :
NS_ERROR_NO_INTERFACE;
}
NS_IMETHODIMP
nsCrossSiteListenerProxy::OnChannelRedirect(nsIChannel *aOldChannel,
nsIChannel *aNewChannel,
PRUint32 aFlags)
{
nsresult rv;
nsCOMPtr<nsIChannelEventSink> outer =
do_GetInterface(mOuterNotificationCallbacks);
if (outer) {
rv = outer->OnChannelRedirect(aOldChannel, aNewChannel, aFlags);
NS_ENSURE_SUCCESS(rv, rv);
}
return UpdateChannel(aNewChannel);
}
nsresult
nsCrossSiteListenerProxy::UpdateChannel(nsIChannel* aChannel)
{
nsCOMPtr<nsIURI> uri;
nsresult rv = aChannel->GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
// Check that the uri is ok to load
rv = nsContentUtils::GetSecurityManager()->
CheckLoadURIWithPrincipal(mRequestingPrincipal, uri,
nsIScriptSecurityManager::STANDARD);
NS_ENSURE_SUCCESS(rv, rv);
if (!mHasBeenCrossSite &&
NS_SUCCEEDED(mRequestingPrincipal->CheckMayLoad(uri, PR_FALSE))) {
return NS_OK;
}
nsCString userpass;
uri->GetUserPass(userpass);
NS_ENSURE_TRUE(userpass.IsEmpty(), NS_ERROR_DOM_BAD_URI);
// It's a cross site load
mHasBeenCrossSite = PR_TRUE;
// Work out the Referer-Root header
nsCString root, host;
rv = mRequestingURI->GetAsciiHost(host);
NS_ENSURE_SUCCESS(rv, rv);
if (!host.IsEmpty()) {
nsCString scheme;
rv = mRequestingURI->GetScheme(scheme);
NS_ENSURE_SUCCESS(rv, rv);
root = scheme + NS_LITERAL_CSTRING("://") + host;
// If needed, append the port
PRInt32 port;
mRequestingURI->GetPort(&port);
if (port != -1) {
PRInt32 defaultPort = NS_GetDefaultPort(scheme.get());
if (port != defaultPort) {
root.Append(":");
root.AppendInt(port);
}
}
}
else {
root.AssignLiteral("null");
}
// Now add the access-control-origin header
nsCOMPtr<nsIHttpChannel> http = do_QueryInterface(aChannel);
NS_ENSURE_TRUE(http, NS_ERROR_FAILURE);
return http->SetRequestHeader(NS_LITERAL_CSTRING("Access-Control-Origin"),
root, PR_FALSE);
}

Просмотреть файл

@ -1,109 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jonas Sicking <jonas@sicking.cc> (Original Author)
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsIStreamListener.h"
#include "nsIInterfaceRequestor.h"
#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsIURI.h"
#include "nsTArray.h"
#include "nsIContentSink.h"
#include "nsIXMLContentSink.h"
#include "nsIExpatSink.h"
#include "nsIInterfaceRequestor.h"
#include "nsIChannelEventSink.h"
class nsIURI;
class nsIParser;
class nsIPrincipal;
class nsCrossSiteListenerProxy : public nsIStreamListener,
public nsIXMLContentSink,
public nsIExpatSink,
public nsIInterfaceRequestor,
public nsIChannelEventSink
{
public:
nsCrossSiteListenerProxy(nsIStreamListener* aOuter,
nsIPrincipal* aRequestingPrincipal,
nsIChannel* aChannel,
nsresult* aResult);
NS_DECL_ISUPPORTS
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIEXPATSINK
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSICHANNELEVENTSINK
// nsIContentSink
NS_IMETHOD WillTokenize(void) { return NS_OK; }
NS_IMETHOD WillBuildModel(void);
NS_IMETHOD DidBuildModel() { return NS_OK; }
NS_IMETHOD WillInterrupt(void) { return NS_OK; }
NS_IMETHOD WillResume(void) { return NS_OK; }
NS_IMETHOD SetParser(nsIParser* aParser) { return NS_OK; }
virtual void FlushPendingNotifications(mozFlushType aType) { }
NS_IMETHOD SetDocumentCharset(nsACString& aCharset) { return NS_OK; }
virtual nsISupports *GetTarget() { return nsnull; }
private:
nsresult UpdateChannel(nsIChannel* aChannel);
nsresult ForwardRequest(PRBool aCallStop);
PRBool MatchPatternList(const char*& aIter, const char* aEnd);
void CheckHeader(const nsCString& aHeader);
PRBool VerifyAndMatchDomainPattern(const nsACString& aDomainPattern);
nsCOMPtr<nsIStreamListener> mOuterListener;
nsCOMPtr<nsIRequest> mOuterRequest;
nsCOMPtr<nsISupports> mOuterContext;
nsCOMPtr<nsIStreamListener> mParserListener;
nsCOMPtr<nsIParser> mParser;
nsCOMPtr<nsIURI> mRequestingURI;
nsCOMPtr<nsIPrincipal> mRequestingPrincipal;
nsCOMPtr<nsIInterfaceRequestor> mOuterNotificationCallbacks;
nsTArray<nsCString> mReqSubdomains;
nsCString mStoredData;
enum {
eAccept,
eDeny,
eNotSet
} mAcceptState;
PRBool mHasForwardedRequest;
PRBool mHasBeenCrossSite;
};

Просмотреть файл

@ -76,6 +76,7 @@ nsDOMAttribute::nsDOMAttribute(nsDOMAttributeMap *aAttrMap,
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMAttribute)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMAttribute)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNodeInfo)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mChild)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_LISTENERMANAGER
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_USERDATA

Просмотреть файл

@ -220,12 +220,21 @@ nsDOMParser::ParseFromStream(nsIInputStream *stream,
stream = bufferedStream;
}
// Here we have to cheat a little bit... Setting the base URI won't
// work if the document has a null principal, so use
// mOriginalPrincipal when creating the document, then reset the
// principal.
nsCOMPtr<nsIDOMDocument> domDocument;
rv = nsContentUtils::CreateDocument(EmptyString(), EmptyString(), nsnull,
mDocumentURI, mBaseURI, mPrincipal,
mDocumentURI, mBaseURI,
mOriginalPrincipal,
scriptHandlingObject,
getter_AddRefs(domDocument));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDocument> document(do_QueryInterface(domDocument));
if (!document) return NS_ERROR_FAILURE;
document->SetPrincipal(mPrincipal);
// Register as a load listener on the document
nsCOMPtr<nsPIDOMEventTarget> target(do_QueryInterface(domDocument));
@ -254,8 +263,6 @@ nsDOMParser::ParseFromStream(nsIInputStream *stream,
// Tell the document to start loading
nsCOMPtr<nsIStreamListener> listener;
nsCOMPtr<nsIDocument> document(do_QueryInterface(domDocument));
if (!document) return NS_ERROR_FAILURE;
mLoopingForSyncLoad = PR_TRUE;
@ -335,13 +342,24 @@ nsDOMParser::Init(nsIPrincipal* principal, nsIURI* documentURI,
mScriptHandlingObject = do_GetWeakReference(aScriptObject);
mPrincipal = principal;
if (!mPrincipal) {
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
NS_ENSURE_TRUE(secMan, NS_ERROR_NOT_AVAILABLE);
nsresult rv =
nsresult rv;
if (!mPrincipal) {
rv =
secMan->GetCodebasePrincipal(mDocumentURI, getter_AddRefs(mPrincipal));
NS_ENSURE_SUCCESS(rv, rv);
mOriginalPrincipal = mPrincipal;
} else {
mOriginalPrincipal = principal;
PRBool isSystem;
rv = secMan->IsSystemPrincipal(mPrincipal, &isSystem);
if (NS_FAILED(rv) || isSystem) {
// Don't give DOMParsers the system principal. Use a null
// principal instead.
mPrincipal = do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
}
}
NS_ENSURE_SUCCESS(rv, rv);
mBaseURI = baseURI;
// Note: if mBaseURI is null, fine. Leave it like that; that will use the
@ -349,6 +367,7 @@ nsDOMParser::Init(nsIPrincipal* principal, nsIURI* documentURI,
// nsDocument::SetBaseURI giving errors.
NS_POSTCONDITION(mPrincipal, "Must have principal");
NS_POSTCONDITION(mOriginalPrincipal, "Must have original principal");
NS_POSTCONDITION(mDocumentURI, "Must have document URI");
return NS_OK;
}

Просмотреть файл

@ -93,6 +93,7 @@ private:
};
nsCOMPtr<nsIPrincipal> mPrincipal;
nsCOMPtr<nsIPrincipal> mOriginalPrincipal;
nsCOMPtr<nsIURI> mDocumentURI;
nsCOMPtr<nsIURI> mBaseURI;
nsWeakPtr mScriptHandlingObject;

Просмотреть файл

@ -881,11 +881,6 @@ nsDocument::~nsDocument()
mStyleAttrStyleSheet->SetOwningDocument(nsnull);
}
if (mBindingManager) {
mBindingManager->DropDocumentReference();
NS_RELEASE(mBindingManager);
}
delete mHeaderData;
if (mBoxObjectTable) {
@ -1025,6 +1020,8 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDocument)
return NS_OK;
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNodeInfo)
// Traverse the mChildren nsAttrAndChildArray.
for (PRInt32 indx = PRInt32(tmp->mChildren.ChildCount()); indx > 0; --indx) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mChildren[i]");
@ -1035,7 +1032,8 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDocument)
// Traverse all nsIDocument pointer members.
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mCachedRootContent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(mBindingManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mNodeInfoManager,
nsNodeInfoManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mSecurityInfo)
// Traverse all nsDocument nsCOMPtrs.
@ -1116,7 +1114,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
nsresult
nsDocument::Init()
{
if (mBindingManager || mCSSLoader || mNodeInfoManager || mScriptLoader) {
if (mCSSLoader || mNodeInfoManager || mScriptLoader) {
return NS_ERROR_ALREADY_INITIALIZED;
}
@ -1124,10 +1122,6 @@ nsDocument::Init()
mRadioGroups.Init();
// Force initialization.
nsBindingManager *bindingManager = new nsBindingManager(this);
NS_ENSURE_TRUE(bindingManager, NS_ERROR_OUT_OF_MEMORY);
NS_ADDREF(mBindingManager = bindingManager);
nsINode::nsSlots* slots = GetSlots();
NS_ENSURE_TRUE(slots,NS_ERROR_OUT_OF_MEMORY);
@ -2707,7 +2701,7 @@ void
nsDocument::BeginUpdate(nsUpdateType aUpdateType)
{
if (mUpdateNestLevel == 0) {
mBindingManager->BeginOutermostUpdate();
BindingManager()->BeginOutermostUpdate();
}
++mUpdateNestLevel;
@ -2732,7 +2726,7 @@ nsDocument::EndUpdate(nsUpdateType aUpdateType)
if (mUpdateNestLevel == 0) {
// This set of updates may have created XBL bindings. Let the
// binding manager know we're done.
mBindingManager->EndOutermostUpdate();
BindingManager()->EndOutermostUpdate();
}
if (mUpdateNestLevel == 0) {
@ -3514,7 +3508,7 @@ nsDocument::AddBinding(nsIDOMElement* aContent, const nsAString& aURI)
subject = NodePrincipal();
}
return mBindingManager->AddLayeredBinding(content, uri, subject);
return BindingManager()->AddLayeredBinding(content, uri, subject);
}
NS_IMETHODIMP
@ -3534,7 +3528,7 @@ nsDocument::RemoveBinding(nsIDOMElement* aContent, const nsAString& aURI)
}
nsCOMPtr<nsIContent> content(do_QueryInterface(aContent));
return mBindingManager->RemoveLayeredBinding(content, uri);
return BindingManager()->RemoveLayeredBinding(content, uri);
}
NS_IMETHODIMP
@ -3560,7 +3554,7 @@ nsDocument::LoadBindingDocument(const nsAString& aURI)
subject = NodePrincipal();
}
mBindingManager->LoadBindingDocument(this, uri, subject);
BindingManager()->LoadBindingDocument(this, uri, subject);
return NS_OK;
}
@ -3648,7 +3642,7 @@ nsDocument::GetAnonymousNodes(nsIDOMElement* aElement,
*aResult = nsnull;
nsCOMPtr<nsIContent> content(do_QueryInterface(aElement));
return mBindingManager->GetAnonymousNodesFor(content, aResult);
return BindingManager()->GetAnonymousNodesFor(content, aResult);
}
NS_IMETHODIMP
@ -3802,7 +3796,7 @@ nsDocument::GetBoxObjectFor(nsIDOMElement* aElement, nsIBoxObject** aResult)
}
PRInt32 namespaceID;
nsCOMPtr<nsIAtom> tag = mBindingManager->ResolveTag(content, &namespaceID);
nsCOMPtr<nsIAtom> tag = BindingManager()->ResolveTag(content, &namespaceID);
nsCAutoString contractID("@mozilla.org/layout/xul-boxobject");
if (namespaceID == kNameSpaceID_XUL) {
@ -3857,19 +3851,19 @@ nsDocument::ClearBoxObjectFor(nsIContent* aContent)
nsresult
nsDocument::GetXBLChildNodesFor(nsIContent* aContent, nsIDOMNodeList** aResult)
{
return mBindingManager->GetXBLChildNodesFor(aContent, aResult);
return BindingManager()->GetXBLChildNodesFor(aContent, aResult);
}
nsresult
nsDocument::GetContentListFor(nsIContent* aContent, nsIDOMNodeList** aResult)
{
return mBindingManager->GetContentListFor(aContent, aResult);
return BindingManager()->GetContentListFor(aContent, aResult);
}
void
nsDocument::FlushSkinBindings()
{
mBindingManager->FlushSkinBindings();
BindingManager()->FlushSkinBindings();
}
nsresult

Просмотреть файл

@ -61,6 +61,7 @@
#include "nsCOMArray.h"
#include "nsNodeUtils.h"
#include "nsBindingManager.h"
#include "nsCCUncollectableMarker.h"
#include "pldhash.h"
#include "prprf.h"
@ -79,6 +80,19 @@ nsGenericDOMDataNode::~nsGenericDOMDataNode()
NS_IMPL_CYCLE_COLLECTION_CLASS(nsGenericDOMDataNode)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsGenericDOMDataNode)
nsIDocument* currentDoc = tmp->GetCurrentDoc();
if (currentDoc && nsCCUncollectableMarker::InGeneration(
currentDoc->GetMarkedCCGeneration())) {
return NS_OK;
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNodeInfo)
nsIDocument* ownerDoc = tmp->GetOwnerDoc();
if (ownerDoc) {
ownerDoc->BindingManager()->Traverse(tmp, cb);
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_LISTENERMANAGER
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_USERDATA
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_PRESERVED_WRAPPER

Просмотреть файл

@ -3506,9 +3506,16 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsGenericElement)
cb.NoteXPCOMChild(property);
}
// Traverse child content.
// Traverse attribute names and child content.
{
PRUint32 i;
PRUint32 attrs = tmp->mAttrsAndChildren.AttrCount();
for (i = 0; i < attrs; i++) {
const nsAttrName* name = tmp->mAttrsAndChildren.AttrNameAt(i);
if (!name->IsAtom())
cb.NoteXPCOMChild(name->NodeInfo());
}
PRUint32 kids = tmp->mAttrsAndChildren.ChildCount();
for (i = 0; i < kids; i++) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mAttrsAndChildren[i]");
@ -3516,6 +3523,8 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsGenericElement)
}
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNodeInfo)
// Traverse any DOM slots of interest.
{
nsDOMSlots *slots = tmp->GetExistingDOMSlots();

Просмотреть файл

@ -130,9 +130,19 @@ nsNodeInfo::Init(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID,
// nsISupports
NS_IMPL_ADDREF(nsNodeInfo)
NS_IMPL_RELEASE_WITH_DESTROY(nsNodeInfo, LastRelease())
NS_IMPL_QUERY_INTERFACE1(nsNodeInfo, nsINodeInfo)
NS_IMPL_CYCLE_COLLECTION_CLASS(nsNodeInfo)
NS_IMPL_CYCLE_COLLECTION_UNLINK_0(nsNodeInfo)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsNodeInfo)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mOwnerManager,
nsNodeInfoManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsNodeInfo)
NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_DESTROY(nsNodeInfo, LastRelease())
NS_INTERFACE_TABLE_HEAD(nsNodeInfo)
NS_INTERFACE_TABLE1(nsNodeInfo, nsINodeInfo)
NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsNodeInfo)
NS_INTERFACE_MAP_END
// nsINodeInfo

Просмотреть файл

@ -55,7 +55,8 @@ class nsFixedSizeAllocator;
class nsNodeInfo : public nsINodeInfo
{
public:
NS_DECL_ISUPPORTS
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(nsNodeInfo)
// nsINodeInfo
virtual void GetQualifiedName(nsAString &aQualifiedName) const;

Просмотреть файл

@ -52,6 +52,7 @@
#include "nsGkAtoms.h"
#include "nsComponentManagerUtils.h"
#include "nsLayoutStatics.h"
#include "nsBindingManager.h"
#ifdef MOZ_LOGGING
// so we can get logging even in release builds
@ -97,7 +98,8 @@ nsNodeInfoManager::nsNodeInfoManager()
mPrincipal(nsnull),
mTextNodeInfo(nsnull),
mCommentNodeInfo(nsnull),
mDocumentNodeInfo(nsnull)
mDocumentNodeInfo(nsnull),
mBindingManager(nsnull)
{
nsLayoutStatics::AddRef();
@ -124,6 +126,8 @@ nsNodeInfoManager::~nsNodeInfoManager()
// Note: mPrincipal may be null here if we never got inited correctly
NS_IF_RELEASE(mPrincipal);
NS_IF_RELEASE(mBindingManager);
#ifdef PR_LOGGING
if (gNodeInfoManagerLeakPRLog)
PR_LOG(gNodeInfoManagerLeakPRLog, PR_LOG_DEBUG,
@ -160,6 +164,14 @@ nsNodeInfoManager::Release()
return count;
}
NS_IMPL_CYCLE_COLLECTION_CLASS(nsNodeInfoManager)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsNodeInfoManager, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsNodeInfoManager, Release)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NATIVE_0(nsNodeInfoManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(nsNodeInfoManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(mBindingManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
nsresult
nsNodeInfoManager::Init(nsIDocument *aDocument)
{
@ -171,6 +183,13 @@ nsNodeInfoManager::Init(nsIDocument *aDocument)
&mPrincipal);
NS_ENSURE_TRUE(mPrincipal, rv);
if (aDocument) {
mBindingManager = new nsBindingManager(aDocument);
NS_ENSURE_TRUE(mBindingManager, NS_ERROR_OUT_OF_MEMORY);
NS_ADDREF(mBindingManager);
}
mDefaultPrincipal = mPrincipal;
mDocument = aDocument;
@ -187,6 +206,10 @@ nsNodeInfoManager::Init(nsIDocument *aDocument)
void
nsNodeInfoManager::DropDocumentReference()
{
if (mBindingManager) {
mBindingManager->DropDocumentReference();
}
mDocument = nsnull;
}

Просмотреть файл

@ -44,6 +44,7 @@
#include "nsCOMPtr.h" // for already_AddRefed
#include "plhash.h"
#include "nsCycleCollectionParticipant.h"
class nsIAtom;
class nsIDocument;
@ -57,6 +58,7 @@ class nsIDOMDocument;
class nsAString;
class nsIDOMNamedNodeMap;
class nsXULPrototypeDocument;
class nsBindingManager;
class nsNodeInfoManager
{
@ -64,6 +66,8 @@ public:
nsNodeInfoManager();
~nsNodeInfoManager();
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(nsNodeInfoManager)
nsrefcnt AddRef(void);
nsrefcnt Release(void);
@ -123,6 +127,11 @@ public:
void RemoveNodeInfo(nsNodeInfo *aNodeInfo);
nsBindingManager* GetBindingManager() const
{
return mBindingManager;
}
protected:
friend class nsDocument;
friend class nsXULPrototypeDocument;
@ -158,6 +167,9 @@ private:
nsINodeInfo *mTextNodeInfo; // WEAK to avoid circular ownership
nsINodeInfo *mCommentNodeInfo; // WEAK to avoid circular ownership
nsINodeInfo *mDocumentNodeInfo; // WEAK to avoid circular ownership
nsBindingManager* mBindingManager; // STRONG, but not nsCOMPtr to avoid
// include hell while inlining
// GetBindingManager().
};
#endif /* nsNodeInfoManager_h___ */

Просмотреть файл

@ -77,6 +77,7 @@
#include "nsNetUtil.h"
#include "nsPresShellIterator.h"
#include "nsMimeTypes.h"
#include "nsStyleUtil.h"
// Concrete classes
#include "nsFrameLoader.h"
@ -352,7 +353,8 @@ nsObjectLoadingContent::~nsObjectLoadingContent()
// nsIRequestObserver
NS_IMETHODIMP
nsObjectLoadingContent::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
nsObjectLoadingContent::OnStartRequest(nsIRequest *aRequest,
nsISupports *aContext)
{
if (aRequest != mChannel) {
// This is a bit of an edge case - happens when a new load starts before the
@ -408,6 +410,17 @@ nsObjectLoadingContent::OnStartRequest(nsIRequest *aRequest, nsISupports *aConte
mContentType = channelType;
}
nsCOMPtr<nsIURI> uri;
chan->GetURI(getter_AddRefs(uri));
if (mContentType.EqualsASCII(APPLICATION_OCTET_STREAM)) {
nsCAutoString extType;
if (IsPluginEnabledByExtension(uri, extType)) {
mContentType = extType;
chan->SetContentType(extType);
}
}
// Now find out what type the content is
// UnloadContent will set our type to null; need to be sure to only set it to
// the real value on success
@ -429,8 +442,6 @@ nsObjectLoadingContent::OnStartRequest(nsIRequest *aRequest, nsISupports *aConte
contentPolicyType = nsIContentPolicy::TYPE_OBJECT;
break;
}
nsCOMPtr<nsIURI> uri;
chan->GetURI(getter_AddRefs(uri));
nsCOMPtr<nsIContent> thisContent =
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
NS_ASSERTION(thisContent, "must be a content");
@ -1725,6 +1736,8 @@ nsObjectLoadingContent::GetPluginSupportState(nsIContent* aContent,
return GetPluginDisabledState(aContentType);
}
PRBool hasAlternateContent = PR_FALSE;
// Search for a child <param> with a pluginurl name
PRUint32 count = aContent->GetChildCount();
for (PRUint32 i = 0; i < count; ++i) {
@ -1732,13 +1745,19 @@ nsObjectLoadingContent::GetPluginSupportState(nsIContent* aContent,
NS_ASSERTION(child, "GetChildCount lied!");
if (child->IsNodeOfType(nsINode::eHTML) &&
child->Tag() == nsGkAtoms::param &&
child->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
child->Tag() == nsGkAtoms::param) {
if (child->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name,
NS_LITERAL_STRING("pluginurl"), eIgnoreCase)) {
return GetPluginDisabledState(aContentType);
}
} else if (!hasAlternateContent) {
hasAlternateContent =
nsStyleUtil::IsSignificantChild(child, PR_TRUE, PR_FALSE);
}
return ePluginOtherState;
}
return hasAlternateContent ? ePluginOtherState :
GetPluginDisabledState(aContentType);
}
/* static */ nsObjectLoadingContent::PluginSupportState

Просмотреть файл

@ -59,7 +59,6 @@
#include "nsAutoPtr.h"
#include "nsLoadListenerProxy.h"
#include "nsStreamUtils.h"
#include "nsCrossSiteListenerProxy.h"
/**
* This class manages loading a single XML document
@ -219,9 +218,11 @@ nsSyncLoader::LoadDocument(nsIChannel* aChannel,
}
if (aLoaderPrincipal) {
listener = new nsCrossSiteListenerProxy(listener, aLoaderPrincipal,
mChannel, &rv);
NS_ENSURE_TRUE(listener, NS_ERROR_OUT_OF_MEMORY);
nsCOMPtr<nsIURI> docURI;
rv = aChannel->GetOriginalURI(getter_AddRefs(docURI));
NS_ENSURE_SUCCESS(rv, rv);
rv = aLoaderPrincipal->CheckMayLoad(docURI, PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
}
@ -368,6 +369,18 @@ nsSyncLoader::OnChannelRedirect(nsIChannel *aOldChannel,
mChannel = aNewChannel;
nsCOMPtr<nsIURI> oldURI;
nsresult rv = aOldChannel->GetURI(getter_AddRefs(oldURI));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIURI> newURI;
rv = aNewChannel->GetURI(getter_AddRefs(newURI));
NS_ENSURE_SUCCESS(rv, rv);
rv = nsContentUtils::GetSecurityManager()->
CheckSameOriginURI(oldURI, newURI, PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}

Просмотреть файл

@ -82,7 +82,6 @@
#include "nsContentPolicyUtils.h"
#include "nsContentErrors.h"
#include "nsLayoutStatics.h"
#include "nsCrossSiteListenerProxy.h"
#include "nsDOMError.h"
#include "nsIHTMLDocument.h"
#include "nsWhitespaceTokenizer.h"
@ -116,10 +115,8 @@
// access-control spec is supported
#define XML_HTTP_REQUEST_SYNCLOOPING (1 << 11) // Internal
#define XML_HTTP_REQUEST_MULTIPART (1 << 12) // Internal
#define XML_HTTP_REQUEST_USE_XSITE_AC (1 << 13) // Internal
#define XML_HTTP_REQUEST_NON_GET (1 << 14) // Internal
#define XML_HTTP_REQUEST_GOT_FINAL_STOP (1 << 15) // Internal
#define XML_HTTP_REQUEST_BACKGROUND (1 << 16) // Internal
#define XML_HTTP_REQUEST_GOT_FINAL_STOP (1 << 13) // Internal
#define XML_HTTP_REQUEST_BACKGROUND (1 << 14) // Internal
#define XML_HTTP_REQUEST_LOADSTATES \
(XML_HTTP_REQUEST_UNINITIALIZED | \
@ -130,8 +127,6 @@
XML_HTTP_REQUEST_SENT | \
XML_HTTP_REQUEST_STOPPED)
#define ACCESS_CONTROL_CACHE_SIZE 100
#define NS_BADCERTHANDLER_CONTRACTID \
"@mozilla.org/content/xmlhttprequest-bad-cert-handler;1"
@ -245,134 +240,6 @@ nsMultipartProxyListener::OnDataAvailable(nsIRequest *aRequest,
count);
}
// Class used as streamlistener and notification callback when
// doing the initial GET request for an access-control check
class nsACProxyListener : public nsIStreamListener,
public nsIInterfaceRequestor,
public nsIChannelEventSink
{
public:
nsACProxyListener(nsIChannel* aOuterChannel,
nsIStreamListener* aOuterListener,
nsISupports* aOuterContext,
nsIPrincipal* aReferrerPrincipal,
const nsACString& aRequestMethod)
: mOuterChannel(aOuterChannel), mOuterListener(aOuterListener),
mOuterContext(aOuterContext), mReferrerPrincipal(aReferrerPrincipal),
mRequestMethod(aRequestMethod)
{ }
NS_DECL_ISUPPORTS
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSICHANNELEVENTSINK
private:
nsCOMPtr<nsIChannel> mOuterChannel;
nsCOMPtr<nsIStreamListener> mOuterListener;
nsCOMPtr<nsISupports> mOuterContext;
nsCOMPtr<nsIPrincipal> mReferrerPrincipal;
nsCString mRequestMethod;
};
NS_IMPL_ISUPPORTS4(nsACProxyListener, nsIStreamListener, nsIRequestObserver,
nsIInterfaceRequestor, nsIChannelEventSink)
NS_IMETHODIMP
nsACProxyListener::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
{
nsresult status;
nsresult rv = aRequest->GetStatus(&status);
if (NS_SUCCEEDED(rv)) {
rv = status;
}
if (NS_SUCCEEDED(rv)) {
// Everything worked, check to see if there is an expiration time set on
// this access control list. If so go ahead and cache it.
nsCOMPtr<nsIHttpChannel> http = do_QueryInterface(aRequest, &rv);
// The "Access-Control-Max-Age" header should return an age in seconds.
nsCAutoString ageString;
http->GetResponseHeader(NS_LITERAL_CSTRING("Access-Control-Max-Age"),
ageString);
// Sanitize the string. We only allow 'delta-seconds' as specified by
// http://dev.w3.org/2006/waf/access-control (digits 0-9 with no leading or
// trailing non-whitespace characters). We don't allow a + or - character
// but PR_sscanf does so we ensure that the first character is actually a
// digit.
ageString.StripWhitespace();
if (ageString.CharAt(0) >= '0' || ageString.CharAt(0) <= '9') {
PRUint64 age;
PRInt32 convertedChars = PR_sscanf(ageString.get(), "%llu", &age);
if ((PRInt32)ageString.Length() == convertedChars &&
nsXMLHttpRequest::EnsureACCache()) {
// String seems fine, go ahead and cache.
nsCOMPtr<nsIURI> uri;
http->GetURI(getter_AddRefs(uri));
// PR_Now gives microseconds
PRTime expirationTime = PR_Now() + age * PR_USEC_PER_SEC;
nsXMLHttpRequest::sAccessControlCache->PutEntry(uri, mReferrerPrincipal,
expirationTime);
}
}
}
if (NS_SUCCEEDED(rv)) {
rv = mOuterChannel->AsyncOpen(mOuterListener, mOuterContext);
}
if (NS_FAILED(rv)) {
mOuterChannel->Cancel(rv);
mOuterListener->OnStartRequest(mOuterChannel, mOuterContext);
mOuterListener->OnStopRequest(mOuterChannel, mOuterContext, rv);
return rv;
}
return NS_OK;
}
NS_IMETHODIMP
nsACProxyListener::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext,
nsresult aStatus)
{
return NS_OK;
}
/** nsIStreamListener methods **/
NS_IMETHODIMP
nsACProxyListener::OnDataAvailable(nsIRequest *aRequest,
nsISupports *ctxt,
nsIInputStream *inStr,
PRUint32 sourceOffset,
PRUint32 count)
{
return NS_OK;
}
NS_IMETHODIMP
nsACProxyListener::OnChannelRedirect(nsIChannel *aOldChannel,
nsIChannel *aNewChannel,
PRUint32 aFlags)
{
// No redirects allowed for now.
return NS_ERROR_DOM_BAD_URI;
}
NS_IMETHODIMP
nsACProxyListener::GetInterface(const nsIID & aIID, void **aResult)
{
return QueryInterface(aIID, aResult);
}
/**
* Gets the nsIDocument given the script context. Will return nsnull on failure.
*
@ -399,155 +266,11 @@ GetDocumentFromScriptContext(nsIScriptContext *aScriptContext)
return doc;
}
void
nsAccessControlLRUCache::GetEntry(nsIURI* aURI,
nsIPrincipal* aPrincipal,
PRTime* _retval)
{
nsCAutoString key;
if (GetCacheKey(aURI, aPrincipal, key)) {
CacheEntry* entry;
if (GetEntryInternal(key, &entry)) {
*_retval = entry->value;
return;
}
}
*_retval = 0;
}
void
nsAccessControlLRUCache::PutEntry(nsIURI* aURI,
nsIPrincipal* aPrincipal,
PRTime aValue)
{
nsCString key;
if (!GetCacheKey(aURI, aPrincipal, key)) {
NS_WARNING("Invalid cache key!");
return;
}
CacheEntry* entry;
if (GetEntryInternal(key, &entry)) {
// Entry already existed, just update the expiration time and bail. The LRU
// list is updated as a result of the call to GetEntryInternal.
entry->value = aValue;
return;
}
// This is a new entry, allocate and insert into the table now so that any
// failures don't cause items to be removed from a full cache.
entry = new CacheEntry(key, aValue);
if (!entry) {
NS_WARNING("Failed to allocate new cache entry!");
return;
}
if (!mTable.Put(key, entry)) {
// Failed, clean up the new entry.
delete entry;
NS_WARNING("Failed to add entry to the access control cache!");
return;
}
PR_INSERT_LINK(entry, &mList);
NS_ASSERTION(mTable.Count() <= ACCESS_CONTROL_CACHE_SIZE + 1,
"Something is borked, too many entries in the cache!");
// Now enforce the max count.
if (mTable.Count() > ACCESS_CONTROL_CACHE_SIZE) {
// Try to kick out all the expired entries.
PRTime now = PR_Now();
mTable.Enumerate(RemoveExpiredEntries, &now);
// If that didn't remove anything then kick out the least recently used
// entry.
if (mTable.Count() > ACCESS_CONTROL_CACHE_SIZE) {
CacheEntry* lruEntry = static_cast<CacheEntry*>(PR_LIST_TAIL(&mList));
PR_REMOVE_LINK(lruEntry);
// This will delete 'lruEntry'.
mTable.Remove(lruEntry->key);
NS_ASSERTION(mTable.Count() >= ACCESS_CONTROL_CACHE_SIZE,
"Somehow tried to remove an entry that was never added!");
}
}
}
void
nsAccessControlLRUCache::Clear()
{
PR_INIT_CLIST(&mList);
mTable.Clear();
}
PRBool
nsAccessControlLRUCache::GetEntryInternal(const nsACString& aKey,
CacheEntry** _retval)
{
if (!mTable.Get(aKey, _retval))
return PR_FALSE;
// Move to the head of the list.
PR_REMOVE_LINK(*_retval);
PR_INSERT_LINK(*_retval, &mList);
return PR_TRUE;
}
/* static */ PR_CALLBACK PLDHashOperator
nsAccessControlLRUCache::RemoveExpiredEntries(const nsACString& aKey,
nsAutoPtr<CacheEntry>& aValue,
void* aUserData)
{
PRTime* now = static_cast<PRTime*>(aUserData);
if (*now >= aValue->value) {
// Expired, remove from the list as well as the hash table.
PR_REMOVE_LINK(aValue);
return PL_DHASH_REMOVE;
}
// Keep going.
return PL_DHASH_NEXT;
}
/* static */ PRBool
nsAccessControlLRUCache::GetCacheKey(nsIURI* aURI,
nsIPrincipal* aPrincipal,
nsACString& _retval)
{
NS_ASSERTION(aURI, "Null uri!");
NS_ASSERTION(aPrincipal, "Null principal!");
NS_NAMED_LITERAL_CSTRING(space, " ");
nsCOMPtr<nsIURI> uri;
nsresult rv = aPrincipal->GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, PR_FALSE);
nsCAutoString host;
if (uri) {
uri->GetHost(host);
}
nsCAutoString spec;
rv = aURI->GetSpec(spec);
NS_ENSURE_SUCCESS(rv, PR_FALSE);
_retval.Assign(host + space + spec);
return PR_TRUE;
}
/////////////////////////////////////////////
//
//
/////////////////////////////////////////////
// Will be initialized in nsXMLHttpRequest::EnsureACCache.
nsAccessControlLRUCache* nsXMLHttpRequest::sAccessControlCache = nsnull;
nsXMLHttpRequest::nsXMLHttpRequest()
: mState(XML_HTTP_REQUEST_UNINITIALIZED)
{
@ -1122,9 +845,6 @@ nsXMLHttpRequest::Abort()
if (mChannel) {
mChannel->Cancel(NS_BINDING_ABORTED);
}
if (mACGetChannel) {
mACGetChannel->Cancel(NS_BINDING_ABORTED);
}
mDocument = nsnull;
mResponseBody.Truncate();
mState |= XML_HTTP_REQUEST_ABORTED;
@ -1152,10 +872,6 @@ nsXMLHttpRequest::GetAllResponseHeaders(char **_retval)
NS_ENSURE_ARG_POINTER(_retval);
*_retval = nsnull;
if (mState & XML_HTTP_REQUEST_USE_XSITE_AC) {
return NS_OK;
}
nsCOMPtr<nsIHttpChannel> httpChannel = GetCurrentHttpChannel();
if (httpChannel) {
@ -1184,37 +900,6 @@ nsXMLHttpRequest::GetResponseHeader(const nsACString& header,
nsresult rv = NS_OK;
_retval.Truncate();
// Check for dangerous headers
if (mState & XML_HTTP_REQUEST_USE_XSITE_AC) {
// Make sure we don't leak header information from denied cross-site
// requests.
if (mChannel) {
nsresult status;
mChannel->GetStatus(&status);
if (NS_FAILED(status)) {
return NS_OK;
}
}
const char *kCrossOriginSafeHeaders[] = {
"cache-control", "content-language", "content-type", "expires",
"last-modified", "pragma"
};
PRBool safeHeader = PR_FALSE;
PRUint32 i;
for (i = 0; i < NS_ARRAY_LENGTH(kCrossOriginSafeHeaders); ++i) {
if (header.LowerCaseEqualsASCII(kCrossOriginSafeHeaders[i])) {
safeHeader = PR_TRUE;
break;
}
}
if (!safeHeader) {
return NS_OK;
}
}
nsCOMPtr<nsIHttpChannel> httpChannel = GetCurrentHttpChannel();
if (httpChannel) {
@ -1416,34 +1101,6 @@ IsSameOrigin(nsIPrincipal* aPrincipal, nsIChannel* aChannel)
return NS_SUCCEEDED(rv);
}
nsresult
nsXMLHttpRequest::CheckChannelForCrossSiteRequest()
{
// First check if this is a same-origin request, or if cross-site requests
// are enabled.
if ((mState & XML_HTTP_REQUEST_XSITEENABLED) ||
IsSameOrigin(mPrincipal, mChannel)) {
return NS_OK;
}
// This is a cross-site request
// The request is now cross-site, so update flag.
mState |= XML_HTTP_REQUEST_USE_XSITE_AC;
// Remove dangerous headers
nsCOMPtr<nsIHttpChannel> http = do_QueryInterface(mChannel);
if (http) {
PRUint32 i;
for (i = 0; i < mExtraRequestHeaders.Length(); ++i) {
http->SetRequestHeader(mExtraRequestHeaders[i], EmptyCString(), PR_FALSE);
}
mExtraRequestHeaders.Clear();
}
return NS_OK;
}
/* noscript void openRequest (in AUTF8String method, in AUTF8String url, in boolean async, in AString user, in AString password); */
NS_IMETHODIMP
nsXMLHttpRequest::OpenRequest(const nsACString& method,
@ -1561,46 +1218,11 @@ nsXMLHttpRequest::OpenRequest(const nsACString& method,
// Chrome callers are always allowed to read from different origins.
mState |= XML_HTTP_REQUEST_XSITEENABLED;
}
else if (!(mState & XML_HTTP_REQUEST_XSITEENABLED) &&
!IsSameOrigin(mPrincipal, mChannel)) {
mState |= XML_HTTP_REQUEST_USE_XSITE_AC;
}
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mChannel));
if (httpChannel) {
rv = httpChannel->SetRequestMethod(method);
NS_ENSURE_SUCCESS(rv, rv);
if (!method.LowerCaseEqualsLiteral("get")) {
mState |= XML_HTTP_REQUEST_NON_GET;
}
}
// Do we need to set up an initial OPTIONS request to make sure that it is
// safe to make the request?
if ((mState & XML_HTTP_REQUEST_USE_XSITE_AC) &&
(mState & XML_HTTP_REQUEST_NON_GET)) {
// Check to see if this initial OPTIONS request has already been cached in
// our special Access Control Cache.
PRTime expiration = 0;
if (sAccessControlCache) {
sAccessControlCache->GetEntry(uri, mPrincipal, &expiration);
}
if (expiration <= PR_Now()) {
// Either it wasn't cached or the cached result has expired. Build a
// channel for the OPTIONS request.
rv = NS_NewChannel(getter_AddRefs(mACGetChannel), uri, nsnull, loadGroup,
nsnull, loadFlags);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIHttpChannel> acHttp = do_QueryInterface(mACGetChannel);
NS_ASSERTION(acHttp, "Failed to QI to nsIHttpChannel!");
rv = acHttp->SetRequestMethod(NS_LITERAL_CSTRING("OPTIONS"));
NS_ENSURE_SUCCESS(rv, rv);
}
}
ChangeState(XML_HTTP_REQUEST_OPENED);
@ -1644,7 +1266,7 @@ nsXMLHttpRequest::Open(const nsACString& method, const nsACString& url)
return NS_ERROR_FAILURE;
}
rv = secMan->CheckConnect(cx, targetURI, "XMLHttpRequest", "open-uri");
rv = secMan->CheckConnect(cx, targetURI, "XMLHttpRequest", "open");
if (NS_FAILED(rv))
{
// Security check failed.
@ -1799,7 +1421,18 @@ nsXMLHttpRequest::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
nsCOMPtr<nsIChannel> channel(do_QueryInterface(request));
NS_ENSURE_TRUE(channel, NS_ERROR_UNEXPECTED);
channel->SetOwner(mPrincipal);
nsCOMPtr<nsIPrincipal> documentPrincipal = mPrincipal;
if (IsSystemPrincipal(documentPrincipal)) {
// Don't give this document the system principal. We need to keep track of
// mPrincipal being system because we use it for various security checks
// that should be passing, but the document data shouldn't get a system
// principal.
nsresult rv;
documentPrincipal = do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
}
channel->SetOwner(documentPrincipal);
mReadRequest = request;
mContext = ctxt;
@ -1808,19 +1441,19 @@ nsXMLHttpRequest::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
nsIURI* uri = GetBaseURI();
// Create an empty document from it
// Create an empty document from it. Here we have to cheat a little bit...
// Setting the base URI to |uri| won't work if the document has a null
// principal, so use mPrincipal when creating the document, then reset the
// principal.
const nsAString& emptyStr = EmptyString();
nsCOMPtr<nsIScriptGlobalObject> global = do_QueryInterface(mOwner);
nsresult rv = nsContentUtils::CreateDocument(emptyStr, emptyStr, nsnull, uri,
uri, mPrincipal, global,
getter_AddRefs(mDocument));
NS_ENSURE_SUCCESS(rv, rv);
if (mState & XML_HTTP_REQUEST_USE_XSITE_AC) {
nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(mDocument);
if (htmlDoc) {
htmlDoc->DisableCookieAccess();
}
nsCOMPtr<nsIDocument> doc = do_QueryInterface(mDocument);
if (doc) {
doc->SetPrincipal(documentPrincipal);
}
// Reset responseBody
@ -2275,9 +1908,6 @@ nsXMLHttpRequest::Send(nsIVariant *aBody)
mState |= XML_HTTP_REQUEST_SYNCLOOPING;
}
rv = CheckChannelForCrossSiteRequest();
NS_ENSURE_SUCCESS(rv, rv);
// Hook us up to listen to redirects and the like
mChannel->GetNotificationCallbacks(getter_AddRefs(mNotificationCallbacks));
mChannel->SetNotificationCallbacks(this);
@ -2291,15 +1921,6 @@ nsXMLHttpRequest::Send(nsIVariant *aBody)
}
}
if (!(mState & XML_HTTP_REQUEST_XSITEENABLED)) {
// Always create a nsCrossSiteListenerProxy here even if it's
// a same-origin request right now, since it could be redirected.
listener = new nsCrossSiteListenerProxy(listener, mPrincipal, mChannel,
&rv);
NS_ENSURE_TRUE(listener, NS_ERROR_OUT_OF_MEMORY);
NS_ENSURE_SUCCESS(rv, rv);
}
// Bypass the network cache in cases where it makes no sense:
// 1) Multipart responses are very large and would likely be doomed by the
// cache once they grow too large, so they are not worth caching.
@ -2316,10 +1937,6 @@ nsXMLHttpRequest::Send(nsIVariant *aBody)
else if (mState & XML_HTTP_REQUEST_SYNCLOOPING) {
AddLoadFlags(mChannel,
nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY);
if (mACGetChannel) {
AddLoadFlags(mACGetChannel,
nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY);
}
}
// Since we expect XML data, set the type hint accordingly
@ -2327,24 +1944,8 @@ nsXMLHttpRequest::Send(nsIVariant *aBody)
// ignoring return value, as this is not critical
mChannel->SetContentType(NS_LITERAL_CSTRING("application/xml"));
// If we're doing a cross-site non-GET request we need to first do
// a GET request to the same URI. Set that up if needed
if (mACGetChannel) {
nsCOMPtr<nsIStreamListener> acListener =
new nsACProxyListener(mChannel, listener, nsnull, mPrincipal, method);
NS_ENSURE_TRUE(acListener, NS_ERROR_OUT_OF_MEMORY);
listener = new nsCrossSiteListenerProxy(acListener, mPrincipal,
mACGetChannel, &rv);
NS_ENSURE_TRUE(listener, NS_ERROR_OUT_OF_MEMORY);
NS_ENSURE_SUCCESS(rv, rv);
rv = mACGetChannel->AsyncOpen(listener, nsnull);
}
else {
// Start reading from the channel
rv = mChannel->AsyncOpen(listener, nsnull);
}
if (NS_FAILED(rv)) {
// Drop our ref to the channel to avoid cycles
@ -2383,19 +1984,6 @@ nsXMLHttpRequest::SetRequestHeader(const nsACString& header,
{
nsresult rv;
// Check that we haven't already opened the channel. We can't rely on
// the channel throwing from mChannel->SetRequestHeader since we might
// still be waiting for mACGetChannel to actually open mChannel
if (mACGetChannel) {
PRBool pending;
rv = mACGetChannel->IsPending(&pending);
NS_ENSURE_SUCCESS(rv, rv);
if (pending) {
return NS_ERROR_IN_PROGRESS;
}
}
if (!mChannel) // open() initializes mChannel, and open()
return NS_ERROR_FAILURE; // must be called before first setRequestHeader()
@ -2427,32 +2015,6 @@ nsXMLHttpRequest::SetRequestHeader(const nsACString& header,
return NS_OK;
}
}
// Check for dangerous cross-site headers
PRBool safeHeader = !!(mState & XML_HTTP_REQUEST_XSITEENABLED);
if (!safeHeader) {
const char *kCrossOriginSafeHeaders[] = {
"accept", "accept-language"
};
for (i = 0; i < NS_ARRAY_LENGTH(kCrossOriginSafeHeaders); ++i) {
if (header.LowerCaseEqualsASCII(kCrossOriginSafeHeaders[i])) {
safeHeader = PR_TRUE;
break;
}
}
}
if (!safeHeader) {
// The header is unsafe for cross-site requests. If this is a cross-site
// request throw an exception...
if (mState & XML_HTTP_REQUEST_USE_XSITE_AC) {
return NS_ERROR_FAILURE;
}
// ...otherwise just add it to mExtraRequestHeaders so that we can
// remove it in case we're redirected to another site
mExtraRequestHeaders.AppendElement(header);
}
}
// We need to set, not add to, the header.
@ -2693,18 +2255,19 @@ nsXMLHttpRequest::OnChannelRedirect(nsIChannel *aOldChannel,
NS_ENSURE_SUCCESS(rv, rv);
}
mChannel = aNewChannel;
rv = CheckChannelForCrossSiteRequest();
nsCOMPtr<nsIURI> oldURI;
rv = aOldChannel->GetURI(getter_AddRefs(oldURI));
NS_ENSURE_SUCCESS(rv, rv);
// Disable redirects for non-get cross-site requests entirely for now
// Note, do this after the call to CheckChannelForCrossSiteRequest
// to make sure that XML_HTTP_REQUEST_USE_XSITE_AC is up-to-date
if ((mState & XML_HTTP_REQUEST_NON_GET) &&
(mState & XML_HTTP_REQUEST_USE_XSITE_AC)) {
return NS_ERROR_DOM_BAD_URI;
}
nsCOMPtr<nsIURI> newURI;
rv = aNewChannel->GetURI(getter_AddRefs(newURI));
NS_ENSURE_SUCCESS(rv, rv);
rv = nsContentUtils::GetSecurityManager()->
CheckSameOriginURI(oldURI, newURI, PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
mChannel = aNewChannel;
return NS_OK;
}

Просмотреть файл

@ -70,65 +70,6 @@
class nsILoadGroup;
class nsAccessControlLRUCache
{
struct CacheEntry : public PRCList
{
CacheEntry(const nsACString& aKey, PRTime aValue)
: key(aKey), value(aValue)
{
MOZ_COUNT_CTOR(nsAccessControlLRUCache::CacheEntry);
}
~CacheEntry()
{
MOZ_COUNT_DTOR(nsAccessControlLRUCache::CacheEntry);
}
nsCString key;
PRTime value;
};
public:
nsAccessControlLRUCache()
{
MOZ_COUNT_CTOR(nsAccessControlLRUCache);
PR_INIT_CLIST(&mList);
}
~nsAccessControlLRUCache()
{
Clear();
MOZ_COUNT_DTOR(nsAccessControlLRUCache);
}
PRBool Initialize()
{
return mTable.Init();
}
void GetEntry(nsIURI* aURI, nsIPrincipal* aPrincipal,
PRTime* _retval);
void PutEntry(nsIURI* aURI, nsIPrincipal* aPrincipal,
PRTime aValue);
void Clear();
private:
PRBool GetEntryInternal(const nsACString& aKey, CacheEntry** _retval);
PR_STATIC_CALLBACK(PLDHashOperator)
RemoveExpiredEntries(const nsACString& aKey, nsAutoPtr<CacheEntry>& aValue,
void* aUserData);
static PRBool GetCacheKey(nsIURI* aURI, nsIPrincipal* aPrincipal,
nsACString& _retval);
nsClassHashtable<nsCStringHashKey, CacheEntry> mTable;
PRCList mList;
};
class nsXMLHttpRequest : public nsIXMLHttpRequest,
public nsIJSXMLHttpRequest,
public nsIDOMLoadListener,
@ -189,32 +130,6 @@ public:
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXMLHttpRequest, nsIXMLHttpRequest)
static PRBool EnsureACCache()
{
if (sAccessControlCache)
return PR_TRUE;
nsAutoPtr<nsAccessControlLRUCache> newCache(new nsAccessControlLRUCache());
NS_ENSURE_TRUE(newCache, PR_FALSE);
if (newCache->Initialize()) {
sAccessControlCache = newCache.forget();
return PR_TRUE;
}
return PR_FALSE;
}
static void ShutdownACCache()
{
if (sAccessControlCache) {
delete sAccessControlCache;
sAccessControlCache = nsnull;
}
}
static nsAccessControlLRUCache* sAccessControlCache;
protected:
nsresult DetectCharset(nsACString& aCharset);
@ -281,7 +196,6 @@ protected:
// mReadRequest is different from mChannel for multipart requests
nsCOMPtr<nsIRequest> mReadRequest;
nsCOMPtr<nsIDOMDocument> mDocument;
nsCOMPtr<nsIChannel> mACGetChannel;
nsCOMArray<nsIDOMEventListener> mLoadEventListeners;
nsCOMArray<nsIDOMEventListener> mErrorEventListeners;

Просмотреть файл

@ -131,31 +131,6 @@ _TEST_FILES = test_bug5141.html \
test_bug398243.html \
formReset.html \
bug382113_object.html \
test_CrossSiteXHR.html \
file_CrossSiteXHR_fail1.xml \
file_CrossSiteXHR_fail2.xml \
file_CrossSiteXHR_fail2.xml^headers^ \
file_CrossSiteXHR_fail3.xml \
file_CrossSiteXHR_fail4.xml \
file_CrossSiteXHR_pass1.xml \
file_CrossSiteXHR_pass1.xml^headers^ \
file_CrossSiteXHR_pass2.xml \
file_CrossSiteXHR_pass3.xml \
test_CrossSiteXHR2.html \
file_CrossSiteXHR2_inner.html \
file_CrossSiteXHR2_fail1.xml \
file_CrossSiteXHR2_fail1.xml^headers^ \
file_CrossSiteXHR2_fail2.xml \
file_CrossSiteXHR2_pass1.xml \
file_CrossSiteXHR2_pass1.xml^headers^ \
file_CrossSiteXHR2_pass2.xml \
file_CrossSiteXHR2_pass3.xml \
file_CrossSiteXHR2_pass3.xml^headers^ \
file_CrossSiteXHR2_pass3_redirect.xml \
test_CrossSiteXHR3.html \
file_CrossSiteXHR3_inner.html \
file_CrossSiteXHR3_pass1.xml^headers^ \
file_CrossSiteXHR3_pass1.xml \
test_bug326337.html \
file_bug326337_inner.html \
file_bug326337_outer.html \
@ -185,6 +160,14 @@ _TEST_FILES = test_bug5141.html \
test_bug421602.html \
test_bug422537.html \
test_bug424212.html \
test_bug425013.html \
test_XHR.html \
file_XHR_pass1.xml \
file_XHR_pass2.txt \
file_XHR_pass3.txt \
file_XHR_pass3.txt^headers^ \
file_XHR_fail1.txt \
file_XHR_fail1.txt^headers^ \
$(NULL)
libs:: $(_TEST_FILES)

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше