Merge from cvs-trunk-mirror to mozilla-central.
--HG-- rename : js/src/jsarray.c => js/src/jsarray.cpp
|
@ -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,33 +1969,12 @@ 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 {
|
||||
// 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 {
|
||||
value = decodeURI(value)
|
||||
// 1. decodeURI decodes %25 to %, which creates unintended
|
||||
// encoding sequences. Re-encode it, unless it's part of
|
||||
// a sequence that survived decodeURI, i.e. one for:
|
||||
// ';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '#'
|
||||
// (RFC 3987 section 3.2)
|
||||
// 2. Re-encode whitespace so that it doesn't get eaten away
|
||||
// by the location bar (bug 410726).
|
||||
.replace(/%(?!3B|2F|3F|3A|40|26|3D|2B|24|2C|23)|[\r\n\t]/ig,
|
||||
encodeURIComponent);
|
||||
} catch (e) {}
|
||||
|
||||
// Encode bidirectional formatting characters.
|
||||
// (RFC 3987 sections 3.2 and 4.1 paragraph 6)
|
||||
value = value.replace(/[\u200e\u200f\u202a\u202b\u202c\u202d\u202e]/g,
|
||||
encodeURIComponent);
|
||||
|
||||
value = losslessDecodeURI(aURI);
|
||||
state = "valid";
|
||||
}
|
||||
}
|
||||
|
@ -2004,6 +1983,30 @@ function URLBarSetURI(aURI, aMustUseURI) {
|
|||
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 {
|
||||
value = decodeURI(value)
|
||||
// 1. decodeURI decodes %25 to %, which creates unintended
|
||||
// encoding sequences. Re-encode it, unless it's part of
|
||||
// a sequence that survived decodeURI, i.e. one for:
|
||||
// ';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '#'
|
||||
// (RFC 3987 section 3.2)
|
||||
// 2. Re-encode whitespace so that it doesn't get eaten away
|
||||
// by the location bar (bug 410726).
|
||||
.replace(/%(?!3B|2F|3F|3A|40|26|3D|2B|24|2C|23)|[\r\n\t]/ig,
|
||||
encodeURIComponent);
|
||||
} catch (e) {}
|
||||
|
||||
// Encode bidirectional formatting characters.
|
||||
// (RFC 3987 sections 3.2 and 4.1 paragraph 6)
|
||||
value = value.replace(/[\u200e\u200f\u202a\u202b\u202c\u202d\u202e]/g,
|
||||
encodeURIComponent);
|
||||
return value;
|
||||
}
|
||||
|
||||
// Replace the urlbar's value with the url of the page.
|
||||
function handleURLBarRevert() {
|
||||
var throbberElement = document.getElementById("navigator-throbber");
|
||||
|
|
|
@ -108,8 +108,8 @@
|
|||
</keyset>
|
||||
|
||||
<menupopup id="picontext">
|
||||
<menuitem label="&selectall.label;" command="cmd_selectall" accesskey="&selectall.accesskey;"/>
|
||||
<menuitem label="©.label;" command="cmd_copy" accesskey="©.accesskey;"/>
|
||||
<menuitem id="menu_selectall" label="&selectall.label;" command="cmd_selectall" accesskey="&selectall.accesskey;"/>
|
||||
<menuitem id="menu_copy" label="©.label;" command="cmd_copy" accesskey="©.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
|
||||
this.value = val;
|
||||
}
|
||||
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");
|
||||
}
|
||||
|
|
Двоичные данные
browser/themes/winstripe/browser/Bookmarks-folder-aero.png
До Ширина: | Высота: | Размер: 386 B После Ширина: | Высота: | Размер: 361 B |
Двоичные данные
browser/themes/winstripe/browser/Go-arrow-aero.png
До Ширина: | Высота: | Размер: 937 B После Ширина: | Высота: | Размер: 684 B |
Двоичные данные
browser/themes/winstripe/browser/Go-arrow-rtl-aero.png
До Ширина: | Высота: | Размер: 933 B После Ширина: | Высота: | Размер: 681 B |
Двоичные данные
browser/themes/winstripe/browser/Go-arrow-rtl.png
До Ширина: | Высота: | Размер: 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 |
Двоичные данные
browser/themes/winstripe/browser/Search-glass-aero.png
До Ширина: | Высота: | Размер: 1.3 KiB После Ширина: | Высота: | Размер: 821 B |
Двоичные данные
browser/themes/winstripe/browser/Search-glass-rtl-aero.png
До Ширина: | Высота: | Размер: 1.3 KiB После Ширина: | Высота: | Размер: 828 B |
Двоичные данные
browser/themes/winstripe/browser/Search-glass-rtl.png
До Ширина: | Высота: | Размер: 1.2 KiB После Ширина: | Высота: | Размер: 682 B |
Двоичные данные
browser/themes/winstripe/browser/Search-glass.png
До Ширина: | Высота: | Размер: 1.1 KiB После Ширина: | Высота: | Размер: 707 B |
Двоичные данные
browser/themes/winstripe/browser/Toolbar-aero.png
До Ширина: | Высота: | Размер: 120 KiB После Ширина: | Высота: | Размер: 74 KiB |
Двоичные данные
browser/themes/winstripe/browser/Toolbar-small-aero.png
До Ширина: | Высота: | Размер: 57 KiB После Ширина: | Высота: | Размер: 21 KiB |
Двоичные данные
browser/themes/winstripe/browser/Toolbar-small.png
До Ширина: | Высота: | Размер: 60 KiB После Ширина: | Высота: | Размер: 24 KiB |
Двоичные данные
browser/themes/winstripe/browser/Toolbar.png
До Ширина: | Высота: | Размер: 111 KiB После Ширина: | Высота: | Размер: 68 KiB |
Двоичные данные
browser/themes/winstripe/browser/feeds/audioFeedIcon-aero.png
До Ширина: | Высота: | Размер: 1.8 KiB После Ширина: | Высота: | Размер: 1.8 KiB |
Двоичные данные
browser/themes/winstripe/browser/feeds/audioFeedIcon.png
До Ширина: | Высота: | Размер: 1.8 KiB После Ширина: | Высота: | Размер: 1.8 KiB |
Двоичные данные
browser/themes/winstripe/browser/feeds/feedIcon-aero.png
До Ширина: | Высота: | Размер: 1.8 KiB После Ширина: | Высота: | Размер: 1.8 KiB |
Двоичные данные
browser/themes/winstripe/browser/feeds/feedIcon.png
До Ширина: | Высота: | Размер: 1.8 KiB После Ширина: | Высота: | Размер: 1.8 KiB |
Двоичные данные
browser/themes/winstripe/browser/feeds/videoFeedIcon-aero.png
До Ширина: | Высота: | Размер: 1.8 KiB После Ширина: | Высота: | Размер: 1.8 KiB |
Двоичные данные
browser/themes/winstripe/browser/feeds/videoFeedIcon.png
До Ширина: | Высота: | Размер: 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 |
Двоичные данные
browser/themes/winstripe/browser/identity-aero.png
До Ширина: | Высота: | Размер: 19 KiB После Ширина: | Высота: | Размер: 13 KiB |
Двоичные данные
browser/themes/winstripe/browser/identity.png
До Ширина: | Высота: | Размер: 19 KiB После Ширина: | Высота: | Размер: 14 KiB |
Двоичные данные
browser/themes/winstripe/browser/livemark-folder-aero.png
До Ширина: | Высота: | Размер: 531 B После Ширина: | Высота: | Размер: 505 B |
Двоичные данные
browser/themes/winstripe/browser/livemark-folder.png
До Ширина: | Высота: | Размер: 535 B После Ширина: | Высота: | Размер: 467 B |
Двоичные данные
browser/themes/winstripe/browser/menu-back-aero.png
До Ширина: | Высота: | Размер: 459 B После Ширина: | Высота: | Размер: 435 B |
Двоичные данные
browser/themes/winstripe/browser/menu-back.png
До Ширина: | Высота: | Размер: 367 B После Ширина: | Высота: | Размер: 341 B |
Двоичные данные
browser/themes/winstripe/browser/menu-forward-aero.png
До Ширина: | Высота: | Размер: 454 B После Ширина: | Высота: | Размер: 434 B |
Двоичные данные
browser/themes/winstripe/browser/menu-forward.png
До Ширина: | Высота: | Размер: 370 B После Ширина: | Высота: | Размер: 343 B |
Двоичные данные
browser/themes/winstripe/browser/pageInfo-aero.png
До Ширина: | Высота: | Размер: 25 KiB После Ширина: | Высота: | Размер: 8.4 KiB |
Двоичные данные
browser/themes/winstripe/browser/pageInfo.png
До Ширина: | Высота: | Размер: 24 KiB После Ширина: | Высота: | Размер: 8.3 KiB |
Двоичные данные
browser/themes/winstripe/browser/places/bookmarksMenu-aero.png
До Ширина: | Высота: | Размер: 376 B После Ширина: | Высота: | Размер: 346 B |
Двоичные данные
browser/themes/winstripe/browser/places/bookmarksMenu.png
До Ширина: | Высота: | Размер: 372 B После Ширина: | Высота: | Размер: 371 B |
Двоичные данные
browser/themes/winstripe/browser/places/bookmarksToolbar.png
До Ширина: | Высота: | Размер: 288 B После Ширина: | Высота: | Размер: 272 B |
Двоичные данные
browser/themes/winstripe/browser/places/collapse-aero.png
До Ширина: | Высота: | Размер: 393 B После Ширина: | Высота: | Размер: 316 B |
Двоичные данные
browser/themes/winstripe/browser/places/collapse.png
До Ширина: | Высота: | Размер: 434 B После Ширина: | Высота: | Размер: 335 B |
Двоичные данные
browser/themes/winstripe/browser/places/expand-aero.png
До Ширина: | Высота: | Размер: 394 B После Ширина: | Высота: | Размер: 325 B |
Двоичные данные
browser/themes/winstripe/browser/places/expand.png
До Ширина: | Высота: | Размер: 428 B После Ширина: | Высота: | Размер: 335 B |
Двоичные данные
browser/themes/winstripe/browser/places/minus-aero.png
До Ширина: | Высота: | Размер: 282 B После Ширина: | Высота: | Размер: 271 B |
Двоичные данные
browser/themes/winstripe/browser/places/minus.png
До Ширина: | Высота: | Размер: 332 B После Ширина: | Высота: | Размер: 293 B |
Двоичные данные
browser/themes/winstripe/browser/places/plus-aero.png
До Ширина: | Высота: | Размер: 346 B После Ширина: | Высота: | Размер: 307 B |
Двоичные данные
browser/themes/winstripe/browser/places/plus.png
До Ширина: | Высота: | Размер: 373 B После Ширина: | Высота: | Размер: 308 B |
Двоичные данные
browser/themes/winstripe/browser/places/starPage-aero.png
До Ширина: | Высота: | Размер: 718 B После Ширина: | Высота: | Размер: 393 B |
Двоичные данные
browser/themes/winstripe/browser/places/starPage.png
До Ширина: | Высота: | Размер: 639 B После Ширина: | Высота: | Размер: 352 B |
Двоичные данные
browser/themes/winstripe/browser/places/starred48-aero.png
До Ширина: | Высота: | Размер: 1.9 KiB После Ширина: | Высота: | Размер: 1.9 KiB |
Двоичные данные
browser/themes/winstripe/browser/places/starred48.png
До Ширина: | Высота: | Размер: 1.7 KiB После Ширина: | Высота: | Размер: 1.7 KiB |
Двоичные данные
browser/themes/winstripe/browser/places/tag-aero.png
До Ширина: | Высота: | Размер: 755 B После Ширина: | Высота: | Размер: 676 B |
Двоичные данные
browser/themes/winstripe/browser/places/tag.png
До Ширина: | Высота: | Размер: 548 B После Ширина: | Высота: | Размер: 517 B |
Двоичные данные
browser/themes/winstripe/browser/places/view-aero.png
До Ширина: | Высота: | Размер: 189 B После Ширина: | Высота: | Размер: 181 B |
Двоичные данные
browser/themes/winstripe/browser/places/view.png
До Ширина: | Высота: | Размер: 189 B После Ширина: | Высота: | Размер: 181 B |
Двоичные данные
browser/themes/winstripe/browser/preferences/Options-aero.png
До Ширина: | Высота: | Размер: 26 KiB После Ширина: | Высота: | Размер: 9.0 KiB |
Двоичные данные
browser/themes/winstripe/browser/preferences/Options.png
До Ширина: | Высота: | Размер: 26 KiB После Ширина: | Высота: | Размер: 9.2 KiB |
Двоичные данные
browser/themes/winstripe/browser/preferences/alwaysAsk.png
До Ширина: | Высота: | Размер: 491 B После Ширина: | Высота: | Размер: 446 B |
До Ширина: | Высота: | Размер: 869 B После Ширина: | Высота: | Размер: 599 B |
Двоичные данные
browser/themes/winstripe/browser/tabbrowser/tab-arrow-end.png
До Ширина: | Высота: | Размер: 825 B После Ширина: | Высота: | Размер: 509 B |
До Ширина: | Высота: | Размер: 882 B После Ширина: | Высота: | Размер: 624 B |
Двоичные данные
browser/themes/winstripe/browser/tabbrowser/tab-arrow-start.png
До Ширина: | Высота: | Размер: 837 B После Ширина: | Высота: | Размер: 527 B |
Двоичные данные
browser/themes/winstripe/browser/tabbrowser/tabDragIndicator.png
До Ширина: | Высота: | Размер: 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 \
|
||||
|
|
|
@ -165,12 +165,15 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsContentSink)
|
|||
if (tmp->mDocument) {
|
||||
tmp->mDocument->RemoveObserver(tmp);
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mParser)
|
||||
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_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;
|
||||
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
|
||||
NS_ENSURE_TRUE(secMan, NS_ERROR_NOT_AVAILABLE);
|
||||
nsresult rv;
|
||||
if (!mPrincipal) {
|
||||
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
|
||||
NS_ENSURE_TRUE(secMan, NS_ERROR_NOT_AVAILABLE);
|
||||
nsresult rv =
|
||||
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,
|
||||
NS_LITERAL_STRING("pluginurl"), eIgnoreCase)) {
|
||||
return GetPluginDisabledState(aContentType);
|
||||
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,10 +218,12 @@ nsSyncLoader::LoadDocument(nsIChannel* aChannel,
|
|||
}
|
||||
|
||||
if (aLoaderPrincipal) {
|
||||
listener = new nsCrossSiteListenerProxy(listener, aLoaderPrincipal,
|
||||
mChannel, &rv);
|
||||
NS_ENSURE_TRUE(listener, NS_ERROR_OUT_OF_MEMORY);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
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);
|
||||
}
|
||||
|
||||
// Register as a load listener on the document
|
||||
|
@ -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);
|
||||
}
|
||||
// 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)
|
||||
|
|