lists.torproject.org
Sign In Sign Up
Manage this list Sign In Sign Up

Keyboard Shortcuts

Thread View

  • j: Next unread message
  • k: Previous unread message
  • j a: Jump to all threads
  • j l: Jump to MailingList overview

tbb-commits

Thread Start a new thread
Threads by month
  • ----- 2026 -----
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2025 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2024 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2023 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2022 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2021 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2020 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2019 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2018 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2017 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2016 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2015 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
  • January
  • ----- 2014 -----
  • December
  • November
  • October
  • September
  • August
  • July
  • June
  • May
  • April
  • March
  • February
tbb-commits@lists.torproject.org

  • 1 participants
  • 20633 discussions
[tor-browser/tor-browser-52.8.0esr-7.5-1] Bug 1444532 - Fix a leak in SHA256 in nsHttpConnectionInfo.cpp. r=mayhemer, a=jcristau
by gk@torproject.org 20 Jun '18

20 Jun '18
commit 4edbd21ab9244671cb77cf9a4de5e1126079146e Author: David Keeler <dkeeler(a)mozilla.com> Date: Fri Mar 9 14:16:57 2018 -0800 Bug 1444532 - Fix a leak in SHA256 in nsHttpConnectionInfo.cpp. r=mayhemer, a=jcristau The original code (from bug 1200802) declared an XPCOM object as a static bare pointer, which for future reference is probably never the right thing to do. It might have worked if it was cleared before shutdown but it never was. MozReview-Commit-ID: EMe7wgzm6zv --HG-- extra : rebase_source : 16c36a76e39b762e87c7d3c74e64204d7ca9929d extra : source : ad1e07a06363096efbfbf115cbc274c4ee9dcd40 --- netwerk/protocol/http/nsHttpConnectionInfo.cpp | 28 +++++++++++--------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/netwerk/protocol/http/nsHttpConnectionInfo.cpp b/netwerk/protocol/http/nsHttpConnectionInfo.cpp index e965fd1cc2e9..4b9c84a7ed62 100644 --- a/netwerk/protocol/http/nsHttpConnectionInfo.cpp +++ b/netwerk/protocol/http/nsHttpConnectionInfo.cpp @@ -14,33 +14,29 @@ #define LOG_ENABLED() LOG5_ENABLED() #include "nsHttpConnectionInfo.h" + #include "mozilla/net/DNS.h" -#include "prnetdb.h" -#include "nsICryptoHash.h" #include "nsComponentManagerUtils.h" +#include "nsICryptoHash.h" #include "nsIProtocolProxyService.h" +#include "nsNetCID.h" +#include "prnetdb.h" static nsresult SHA256(const char* aPlainText, nsAutoCString& aResult) { - static nsICryptoHash* hasher = nullptr; - nsresult rv; - if (!hasher) { - rv = CallCreateInstance("@mozilla.org/security/hash;1", &hasher); + nsresult rv; + nsCOMPtr<nsICryptoHash> hasher = + do_CreateInstance(NS_CRYPTO_HASH_CONTRACTID, &rv); if (NS_FAILED(rv)) { LOG(("nsHttpDigestAuth: no crypto hash!\n")); return rv; } - } - - rv = hasher->Init(nsICryptoHash::SHA256); - NS_ENSURE_SUCCESS(rv, rv); - - rv = hasher->Update((unsigned char*) aPlainText, strlen(aPlainText)); - NS_ENSURE_SUCCESS(rv, rv); - - rv = hasher->Finish(false, aResult); - return rv; + rv = hasher->Init(nsICryptoHash::SHA256); + NS_ENSURE_SUCCESS(rv, rv); + rv = hasher->Update((unsigned char*) aPlainText, strlen(aPlainText)); + NS_ENSURE_SUCCESS(rv, rv); + return hasher->Finish(false, aResult); } namespace mozilla {
1 0
0 0
[tor-browser/tor-browser-52.8.0esr-7.5-1] Bug 25458: UI customization half-broken in Tor Browser 8.0a3
by gk@torproject.org 20 Jun '18

20 Jun '18
commit dfc72b77f566b3dd98f08db0e4a8e7bedcf050a1 Author: Richard Pospesel <richard(a)torproject.org> Date: Fri Apr 20 16:03:41 2018 -0700 Bug 25458: UI customization half-broken in Tor Browser 8.0a3 Fixed fallout from #25147. Some of the functionality of the UI Customize screen is dependent on setting innerHTML on divs. Since the code runs in the System context, the HTML was being sanitized and broke page functionality. The offending statements have been switched to the unsafeSetInnerHTML() method which bypasses sanitization in System context. --- browser/components/customizableui/CustomizeMode.jsm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/browser/components/customizableui/CustomizeMode.jsm b/browser/components/customizableui/CustomizeMode.jsm index 49868cdbd4a0..4c32fd867c09 100644 --- a/browser/components/customizableui/CustomizeMode.jsm +++ b/browser/components/customizableui/CustomizeMode.jsm @@ -690,13 +690,13 @@ CustomizeMode.prototype = { // Put the tip contents in the popup. let bundle = this.document.getElementById("bundle_browser"); const kLabelClass = "customization-tipPanel-link"; - messageNode.innerHTML = bundle.getFormattedString("customizeTips.tip0", [ + messageNode.unsafeSetInnerHTML(bundle.getFormattedString("customizeTips.tip0", [ "<label class=\"customization-tipPanel-em\" value=\"" + bundle.getString("customizeTips.tip0.hint") + "\"/>", this.document.getElementById("bundle_brand").getString("brandShortName"), "<label class=\"" + kLabelClass + " text-link\" value=\"" + bundle.getString("customizeTips.tip0.learnMore") + "\"/>" - ]); + ])); messageNode.querySelector("." + kLabelClass).addEventListener("click", () => { let url = Services.urlFormatter.formatURLPref("browser.customizemode.tip0.learnMoreUrl");
1 0
0 0
[tor-browser/tor-browser-52.8.0esr-7.5-1] Bug 25147: Sanitize HTML fragments created for chrome-privileged documents
by gk@torproject.org 20 Jun '18

20 Jun '18
commit 8c3c7dcd7e71ae7ca9237fef555efb602ddc7bcc Author: Richard Pospesel <richard(a)torproject.org> Date: Thu Mar 1 14:12:08 2018 -0800 Bug 25147: Sanitize HTML fragments created for chrome-privileged documents Ported over firefox patch c2db4a50dc5c (Bug 1432966) --- .../tests/mochitest/events/test_mutation.html | 4 +- browser/base/content/browser-media.js | 59 ++++++------ .../customizableui/CustomizableWidgets.jsm | 2 +- browser/modules/webrtcUI.jsm | 21 +++-- .../client/responsive.html/components/browser.js | 7 ++ devtools/shared/gcli/source/lib/gcli/util/util.js | 6 +- .../tests/browser/browser_l10n_localizeMarkup.js | 4 +- dom/base/Element.cpp | 6 ++ dom/base/Element.h | 1 + dom/base/FragmentOrElement.cpp | 13 ++- dom/base/FragmentOrElement.h | 3 +- dom/base/nsContentUtils.cpp | 60 ++++++++++-- dom/base/nsContentUtils.h | 26 +++++- dom/base/nsDocument.cpp | 12 ++- dom/base/nsIDocument.h | 6 ++ dom/base/test/chrome.ini | 1 + dom/base/test/chrome/test_bug683852.xul | 4 +- dom/base/test/test_fragment_sanitization.xul | 101 +++++++++++++++++++++ dom/webidl/Document.webidl | 5 + dom/webidl/Element.webidl | 10 ++ layout/style/test/chrome/bug418986-2.js | 16 +++- mobile/android/chrome/content/config.js | 4 +- toolkit/content/tests/chrome/test_bug570192.xul | 4 +- toolkit/mozapps/extensions/content/extensions.js | 2 +- 24 files changed, 309 insertions(+), 68 deletions(-) diff --git a/accessible/tests/mochitest/events/test_mutation.html b/accessible/tests/mochitest/events/test_mutation.html index 232a0972777f..63dd74ca4775 100644 --- a/accessible/tests/mochitest/events/test_mutation.html +++ b/accessible/tests/mochitest/events/test_mutation.html @@ -348,8 +348,8 @@ this.invoke = function insertReferredElm_invoke() { - this.containerNode.innerHTML = - "<span id='insertReferredElms_span'></span><input aria-labelledby='insertReferredElms_span'>"; + this.containerNode.unsafeSetInnerHTML( + "<span id='insertReferredElms_span'></span><input aria-labelledby='insertReferredElms_span'>"); } this.getID = function insertReferredElm_getID() diff --git a/browser/base/content/browser-media.js b/browser/base/content/browser-media.js index 81e7faf17aad..c1ed8f9399fa 100644 --- a/browser/base/content/browser-media.js +++ b/browser/base/content/browser-media.js @@ -41,11 +41,23 @@ var gEMEHandler = { } return true; }, - getLearnMoreLink: function(msgId) { - let text = gNavigatorBundle.getString("emeNotifications." + msgId + ".learnMoreLabel"); + getEMEDisabledFragment(msgId) { + let mainMessage = gNavigatorBundle.getString("emeNotifications.drmContentDisabled.message"); + let [prefix, suffix] = mainMessage.split(/%(?:1\$)?S/).map(s => document.createTextNode(s)); + let text = gNavigatorBundle.getString("emeNotifications.drmContentDisabled.learnMoreLabel"); let baseURL = Services.urlFormatter.formatURLPref("app.support.baseURL"); - return "<label class='text-link' href='" + baseURL + "drm-content'>" + - text + "</label>"; + let link = document.createElement("label"); + link.className = "text-link"; + link.setAttribute("href", baseURL + "drm-content"); + link.textContent = text; + + let fragment = document.createDocumentFragment(); + [prefix, link, suffix].forEach(n => fragment.appendChild(n)); + return fragment; + }, + getMessageWithBrandName(notificationId) { + let msgId = "emeNotifications." + notificationId + ".message"; + return gNavigatorBundle.getFormattedString(msgId, [this._brandShortName]); }, receiveMessage: function({target: browser, data: data}) { let parsedData; @@ -63,7 +75,8 @@ var gEMEHandler = { let notificationId; let buttonCallback; - let params = []; + // Notification message can be either a string or a DOM fragment. + let notificationMessage; switch (status) { case "available": case "cdm-created": @@ -77,18 +90,18 @@ var gEMEHandler = { case "api-disabled": case "cdm-disabled": notificationId = "drmContentDisabled"; - buttonCallback = gEMEHandler.ensureEMEEnabled.bind(gEMEHandler, browser, keySystem) - params = [this.getLearnMoreLink(notificationId)]; + buttonCallback = gEMEHandler.ensureEMEEnabled.bind(gEMEHandler, browser, keySystem); + notificationMessage = this.getEMEDisabledFragment(); break; case "cdm-insufficient-version": notificationId = "drmContentCDMInsufficientVersion"; - params = [this._brandShortName]; + notificationMessage = this.getMessageWithBrandName(notificationId); break; case "cdm-not-installed": notificationId = "drmContentCDMInstalling"; - params = [this._brandShortName]; + notificationMessage = this.getMessageWithBrandName(notificationId); break; case "cdm-not-supported": @@ -100,43 +113,27 @@ var gEMEHandler = { return; } - this.showNotificationBar(browser, notificationId, keySystem, params, buttonCallback); - }, - showNotificationBar: function(browser, notificationId, keySystem, labelParams, callback) { + // Now actually create the notification + let box = gBrowser.getNotificationBox(browser); if (box.getNotificationWithValue(notificationId)) { return; } - let msgPrefix = "emeNotifications." + notificationId + "."; - let msgId = msgPrefix + "message"; - - let message = labelParams.length ? - gNavigatorBundle.getFormattedString(msgId, labelParams) : - gNavigatorBundle.getString(msgId); - let buttons = []; - if (callback) { + if (buttonCallback) { + let msgPrefix = "emeNotifications." + notificationId + "."; let btnLabelId = msgPrefix + "button.label"; let btnAccessKeyId = msgPrefix + "button.accesskey"; buttons.push({ label: gNavigatorBundle.getString(btnLabelId), accessKey: gNavigatorBundle.getString(btnAccessKeyId), - callback: callback + callback: buttonCallback, }); } let iconURL = "chrome://browser/skin/drm-icon.svg#chains-black"; - - // Do a little dance to get rich content into the notification: - let fragment = document.createDocumentFragment(); - let descriptionContainer = document.createElement("description"); - descriptionContainer.innerHTML = message; - while (descriptionContainer.childNodes.length) { - fragment.appendChild(descriptionContainer.childNodes[0]); - } - - box.appendNotification(fragment, notificationId, iconURL, box.PRIORITY_WARNING_MEDIUM, + box.appendNotification(notificationMessage, notificationId, iconURL, box.PRIORITY_WARNING_MEDIUM, buttons); }, showPopupNotificationForSuccess: function(browser, keySystem) { diff --git a/browser/components/customizableui/CustomizableWidgets.jsm b/browser/components/customizableui/CustomizableWidgets.jsm index 907e2e0f75b7..b18249a35811 100644 --- a/browser/components/customizableui/CustomizableWidgets.jsm +++ b/browser/components/customizableui/CustomizableWidgets.jsm @@ -327,7 +327,7 @@ const CustomizableWidgets = [ let promoParentElt = doc.getElementById("PanelUI-remotetabs-mobile-promo"); // Put it all together... let contents = bundle.getFormattedString("appMenuRemoteTabs.mobilePromo.text2", formatArgs); - promoParentElt.innerHTML = contents; + promoParentElt.unsafeSetInnerHTML(contents); // We manually manage the "click" event to open the promo links because // allowing the "text-link" widget handle it has 2 problems: (1) it only // supports button 0 and (2) it's tricky to intercept when it does the diff --git a/browser/modules/webrtcUI.jsm b/browser/modules/webrtcUI.jsm index b24135bfc959..ddcf09260f97 100644 --- a/browser/modules/webrtcUI.jsm +++ b/browser/modules/webrtcUI.jsm @@ -536,21 +536,26 @@ function prompt(aBrowser, aRequest) { bundle.getString("getUserMedia.shareScreen.learnMoreLabel"); let baseURL = Services.urlFormatter.formatURLPref("app.support.baseURL"); - let learnMore = - "<label class='text-link' href='" + baseURL + "screenshare-safety'>" + - learnMoreText + "</label>"; + + let learnMore = chromeWin.document.createElement("label"); + learnMore.className = "text-link"; + learnMore.setAttribute("href", baseURL + "screenshare-safety"); + learnMore.textContent = learnMoreText; if (type == "screen") { string = bundle.getFormattedString("getUserMedia.shareScreenWarning.message", - [learnMore]); - } - else { + ["<>"]); + } else { let brand = chromeDoc.getElementById("bundle_brand").getString("brandShortName"); string = bundle.getFormattedString("getUserMedia.shareFirefoxWarning.message", - [brand, learnMore]); + [brand, "<>"]); } - warning.innerHTML = string; + + let [pre, post] = string.split("<>"); + warning.textContent = pre; + warning.appendChild(learnMore); + warning.appendChild(chromeWin.document.createTextNode(post)); } let perms = Services.perms; diff --git a/devtools/client/responsive.html/components/browser.js b/devtools/client/responsive.html/components/browser.js index f2902905b522..91f709f0cb8a 100644 --- a/devtools/client/responsive.html/components/browser.js +++ b/devtools/client/responsive.html/components/browser.js @@ -16,6 +16,13 @@ const Types = require("../types"); const e10s = require("../utils/e10s"); const message = require("../utils/message"); +// Allow creation of HTML fragments without automatic sanitization, even +// though we're in a chrome-privileged document. +// This is, unfortunately, necessary in order to React to function +// correctly. + +document.allowUnsafeHTML = true; + module.exports = createClass({ /** diff --git a/devtools/shared/gcli/source/lib/gcli/util/util.js b/devtools/shared/gcli/source/lib/gcli/util/util.js index 065bf36c07db..cfc18062e1c5 100644 --- a/devtools/shared/gcli/source/lib/gcli/util/util.js +++ b/devtools/shared/gcli/source/lib/gcli/util/util.js @@ -498,7 +498,11 @@ exports.setContents = function(elem, contents) { return; } - if ('innerHTML' in elem) { + if ('unsafeSetInnerHTML' in elem) { + // FIXME: Stop relying on unsanitized HTML. + elem.unsafeSetInnerHTML(contents); + } + else if ('innerHTML' in elem) { elem.innerHTML = contents; } else { diff --git a/devtools/shared/tests/browser/browser_l10n_localizeMarkup.js b/devtools/shared/tests/browser/browser_l10n_localizeMarkup.js index f33a5a331c51..59bbb308ba44 100644 --- a/devtools/shared/tests/browser/browser_l10n_localizeMarkup.js +++ b/devtools/shared/tests/browser/browser_l10n_localizeMarkup.js @@ -18,7 +18,7 @@ add_task(function* () { info("Create the test markup"); let div = document.createElement("div"); - div.innerHTML = + div.unsafeSetInnerHTML( `<div data-localization-bundle="devtools/client/locales/startup.properties"> <div id="d0" data-localization="content=inspector.someInvalidKey"></div> <div id="d1" data-localization="content=inspector.label">Text will disappear</div> @@ -32,7 +32,7 @@ add_task(function* () { <div id="d5" data-localization="content=toolbox.defaultTitle"></div> </div> </div> - `; + `); info("Use localization helper to localize the test markup"); localizeMarkup(div); diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index 09c6b39da574..daf5d6aa98bf 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -3564,6 +3564,12 @@ Element::SetInnerHTML(const nsAString& aInnerHTML, ErrorResult& aError) } void +Element::UnsafeSetInnerHTML(const nsAString& aInnerHTML, ErrorResult& aError) +{ + SetInnerHTMLInternal(aInnerHTML, aError, true); +} + +void Element::GetOuterHTML(nsAString& aOuterHTML) { GetMarkup(true, aOuterHTML); diff --git a/dom/base/Element.h b/dom/base/Element.h index 5d878df60668..94991b26a641 100644 --- a/dom/base/Element.h +++ b/dom/base/Element.h @@ -896,6 +896,7 @@ public: NS_IMETHOD GetInnerHTML(nsAString& aInnerHTML); virtual void SetInnerHTML(const nsAString& aInnerHTML, ErrorResult& aError); + void UnsafeSetInnerHTML(const nsAString& aInnerHTML, ErrorResult& aError); void GetOuterHTML(nsAString& aOuterHTML); void SetOuterHTML(const nsAString& aOuterHTML, ErrorResult& aError); void InsertAdjacentHTML(const nsAString& aPosition, const nsAString& aText, diff --git a/dom/base/FragmentOrElement.cpp b/dom/base/FragmentOrElement.cpp index 4ad10931a8d0..c83a76dc2603 100644 --- a/dom/base/FragmentOrElement.cpp +++ b/dom/base/FragmentOrElement.cpp @@ -2183,7 +2183,8 @@ ContainsMarkup(const nsAString& aStr) } void -FragmentOrElement::SetInnerHTMLInternal(const nsAString& aInnerHTML, ErrorResult& aError) +FragmentOrElement::SetInnerHTMLInternal(const nsAString& aInnerHTML, ErrorResult& aError, + bool aNeverSanitize) { FragmentOrElement* target = this; // Handle template case. @@ -2237,6 +2238,9 @@ FragmentOrElement::SetInnerHTMLInternal(const nsAString& aInnerHTML, ErrorResult contextNameSpaceID = shadowRoot->GetHost()->GetNameSpaceID(); } + auto sanitize = (aNeverSanitize ? nsContentUtils::NeverSanitize + : nsContentUtils::SanitizeSystemPrivileged); + if (doc->IsHTMLDocument()) { int32_t oldChildCount = target->GetChildCount(); aError = nsContentUtils::ParseFragmentHTML(aInnerHTML, @@ -2245,14 +2249,17 @@ FragmentOrElement::SetInnerHTMLInternal(const nsAString& aInnerHTML, ErrorResult contextNameSpaceID, doc->GetCompatibilityMode() == eCompatibility_NavQuirks, - true); + true, + sanitize); mb.NodesAdded(); // HTML5 parser has notified, but not fired mutation events. nsContentUtils::FireMutationEventsForDirectParsing(doc, target, oldChildCount); } else { RefPtr<DocumentFragment> df = - nsContentUtils::CreateContextualFragment(target, aInnerHTML, true, aError); + nsContentUtils::CreateContextualFragment(target, aInnerHTML, true, + sanitize, + aError); if (!aError.Failed()) { // Suppress assertion about node removal mutation events that can't have // listeners anyway, because no one has had the chance to register mutation diff --git a/dom/base/FragmentOrElement.h b/dom/base/FragmentOrElement.h index 3cb5575fe063..c6ed7ab85e41 100644 --- a/dom/base/FragmentOrElement.h +++ b/dom/base/FragmentOrElement.h @@ -357,7 +357,8 @@ public: protected: void GetMarkup(bool aIncludeSelf, nsAString& aMarkup); - void SetInnerHTMLInternal(const nsAString& aInnerHTML, ErrorResult& aError); + void SetInnerHTMLInternal(const nsAString& aInnerHTML, ErrorResult& aError, + bool aNeverSanitize = false); // Override from nsINode virtual nsINode::nsSlots* CreateSlots() override; diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index f93274280f7c..182a1686d5fe 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -155,6 +155,7 @@ #include "nsIObserverService.h" #include "nsIOfflineCacheUpdate.h" #include "nsIParser.h" +#include "nsIParserUtils.h" #include "nsIParserService.h" #include "nsIPermissionManager.h" #include "nsIPluginHost.h" @@ -195,6 +196,7 @@ #include "nsTextFragment.h" #include "nsTextNode.h" #include "nsThreadUtils.h" +#include "nsTreeSanitizer.h" #include "nsUnicharUtilCIID.h" #include "nsUnicodeProperties.h" #include "nsViewManager.h" @@ -4576,6 +4578,7 @@ already_AddRefed<DocumentFragment> nsContentUtils::CreateContextualFragment(nsINode* aContextNode, const nsAString& aFragment, bool aPreventScriptExecution, + SanitizeFragments aSanitize, ErrorResult& aRv) { if (!aContextNode) { @@ -4611,14 +4614,16 @@ nsContentUtils::CreateContextualFragment(nsINode* aContextNode, contextAsContent->GetNameSpaceID(), (document->GetCompatibilityMode() == eCompatibility_NavQuirks), - aPreventScriptExecution); + aPreventScriptExecution, + aSanitize); } else { aRv = ParseFragmentHTML(aFragment, frag, nsGkAtoms::body, kNameSpaceID_XHTML, (document->GetCompatibilityMode() == eCompatibility_NavQuirks), - aPreventScriptExecution); + aPreventScriptExecution, + aSanitize); } return frag.forget(); @@ -4682,7 +4687,8 @@ nsContentUtils::CreateContextualFragment(nsINode* aContextNode, nsCOMPtr<nsIDOMDocumentFragment> frag; aRv = ParseFragmentXML(aFragment, document, tagStack, - aPreventScriptExecution, getter_AddRefs(frag)); + aPreventScriptExecution, getter_AddRefs(frag), + aSanitize); return frag.forget().downcast<DocumentFragment>(); } @@ -4709,7 +4715,8 @@ nsContentUtils::ParseFragmentHTML(const nsAString& aSourceBuffer, nsIAtom* aContextLocalName, int32_t aContextNamespace, bool aQuirks, - bool aPreventScriptExecution) + bool aPreventScriptExecution, + SanitizeFragments aSanitize) { AutoTimelineMarker m(aTargetNode->OwnerDoc()->GetDocShell(), "Parse HTML"); @@ -4723,13 +4730,39 @@ nsContentUtils::ParseFragmentHTML(const nsAString& aSourceBuffer, NS_ADDREF(sHTMLFragmentParser = new nsHtml5StringParser()); // Now sHTMLFragmentParser owns the object } + + nsIContent* target = aTargetNode; + + // If this is a chrome-privileged document, create a fragment first, and + // sanitize it before insertion. + RefPtr<DocumentFragment> fragment; + if (aSanitize != NeverSanitize && !aTargetNode->OwnerDoc()->AllowUnsafeHTML()) { + fragment = new DocumentFragment(aTargetNode->OwnerDoc()->NodeInfoManager()); + target = fragment; + } + nsresult rv = sHTMLFragmentParser->ParseFragment(aSourceBuffer, - aTargetNode, + target, aContextLocalName, aContextNamespace, aQuirks, aPreventScriptExecution); + NS_ENSURE_SUCCESS(rv, rv); + + if (fragment) { + // Don't fire mutation events for nodes removed by the sanitizer. + nsAutoScriptBlockerSuppressNodeRemoved scriptBlocker; + + nsTreeSanitizer sanitizer(nsIParserUtils::SanitizerAllowStyle | + nsIParserUtils::SanitizerAllowComments); + sanitizer.Sanitize(fragment); + + ErrorResult error; + aTargetNode->AppendChild(*fragment, error); + rv = error.StealNSResult(); + } + return rv; } @@ -4764,7 +4797,8 @@ nsContentUtils::ParseFragmentXML(const nsAString& aSourceBuffer, nsIDocument* aDocument, nsTArray<nsString>& aTagStack, bool aPreventScriptExecution, - nsIDOMDocumentFragment** aReturn) + nsIDOMDocumentFragment** aReturn, + SanitizeFragments aSanitize) { AutoTimelineMarker m(aDocument->GetDocShell(), "Parse XML"); @@ -4803,6 +4837,20 @@ nsContentUtils::ParseFragmentXML(const nsAString& aSourceBuffer, rv = sXMLFragmentSink->FinishFragmentParsing(aReturn); sXMLFragmentParser->Reset(); + NS_ENSURE_SUCCESS(rv, rv); + + // If this is a chrome-privileged document, sanitize the fragment before + // returning. + if (aSanitize != NeverSanitize && !aDocument->AllowUnsafeHTML()) { + // Don't fire mutation events for nodes removed by the sanitizer. + nsAutoScriptBlockerSuppressNodeRemoved scriptBlocker; + + RefPtr<DocumentFragment> fragment = static_cast<DocumentFragment*>(*aReturn); + + nsTreeSanitizer sanitizer(nsIParserUtils::SanitizerAllowStyle | + nsIParserUtils::SanitizerAllowComments); + sanitizer.Sanitize(fragment); + } return rv; } diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index 08c5cbf02e25..f2de4a16be5d 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -1344,6 +1344,11 @@ public: static bool IsValidNodeName(nsIAtom *aLocalName, nsIAtom *aPrefix, int32_t aNamespaceID); + enum SanitizeFragments { + SanitizeSystemPrivileged, + NeverSanitize, + }; + /** * Creates a DocumentFragment from text using a context node to resolve * namespaces. @@ -1357,6 +1362,8 @@ public: * @param aFragment the string which is parsed to a DocumentFragment * @param aReturn the resulting fragment * @param aPreventScriptExecution whether to mark scripts as already started + * @param aSanitize whether the fragment should be sanitized prior to + * injection */ static nsresult CreateContextualFragment(nsINode* aContextNode, const nsAString& aFragment, @@ -1365,7 +1372,16 @@ public: static already_AddRefed<mozilla::dom::DocumentFragment> CreateContextualFragment(nsINode* aContextNode, const nsAString& aFragment, bool aPreventScriptExecution, + SanitizeFragments aSanitize, mozilla::ErrorResult& aRv); + static already_AddRefed<mozilla::dom::DocumentFragment> + CreateContextualFragment(nsINode* aContextNode, const nsAString& aFragment, + bool aPreventScriptExecution, + mozilla::ErrorResult& aRv) + { + return CreateContextualFragment(aContextNode, aFragment, aPreventScriptExecution, + SanitizeSystemPrivileged, aRv); + } /** * Invoke the fragment parsing algorithm (innerHTML) using the HTML parser. @@ -1378,6 +1394,8 @@ public: * @param aPreventScriptExecution true to prevent scripts from executing; * don't set to false when parsing into a target node that has been * bound to tree. + * @param aSanitize whether the fragment should be sanitized prior to + * injection * @return NS_ERROR_DOM_INVALID_STATE_ERR if a re-entrant attempt to parse * fragments is made, NS_ERROR_OUT_OF_MEMORY if aSourceBuffer is too * long and NS_OK otherwise. @@ -1387,7 +1405,8 @@ public: nsIAtom* aContextLocalName, int32_t aContextNamespace, bool aQuirks, - bool aPreventScriptExecution); + bool aPreventScriptExecution, + SanitizeFragments aSanitize = SanitizeSystemPrivileged); /** * Invoke the fragment parsing algorithm (innerHTML) using the XML parser. @@ -1397,6 +1416,8 @@ public: * @param aTagStack the namespace mapping context * @param aPreventExecution whether to mark scripts as already started * @param aReturn the result fragment + * @param aSanitize whether the fragment should be sanitized prior to + * injection * @return NS_ERROR_DOM_INVALID_STATE_ERR if a re-entrant attempt to parse * fragments is made, a return code from the XML parser. */ @@ -1404,7 +1425,8 @@ public: nsIDocument* aDocument, nsTArray<nsString>& aTagStack, bool aPreventScriptExecution, - nsIDOMDocumentFragment** aReturn); + nsIDOMDocumentFragment** aReturn, + SanitizeFragments aSanitize = SanitizeSystemPrivileged); /** * Parse a string into a document using the HTML parser. diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 25e5d28d6c76..ba35493ad886 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -1315,7 +1315,8 @@ nsIDocument::nsIDocument() mFrameRequestCallbacksScheduled(false), mBidiOptions(IBMBIDI_DEFAULT_BIDI_OPTIONS), mPartID(0), - mUserHasInteracted(false) + mUserHasInteracted(false), + mAllowUnsafeHTML(false) { SetIsInDocument(); @@ -2659,7 +2660,7 @@ nsDocument::InitCSP(nsIChannel* aChannel) (cspSandboxFlags & SANDBOXED_ORIGIN) && !(mSandboxFlags & SANDBOXED_ORIGIN); mSandboxFlags |= cspSandboxFlags; - + if (needNewNullPrincipal) { principal = nsNullPrincipal::CreateWithInheritedAttributes(principal); principal->SetCsp(csp); @@ -5734,6 +5735,13 @@ nsDocument::CustomElementConstructor(JSContext* aCx, unsigned aArgc, JS::Value* } bool +nsIDocument::AllowUnsafeHTML() const +{ + return (!nsContentUtils::IsSystemPrincipal(NodePrincipal()) || + mAllowUnsafeHTML); +} + +bool nsDocument::IsWebComponentsEnabled(JSContext* aCx, JSObject* aObject) { JS::Rooted<JSObject*> obj(aCx, aObject); diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h index 5715fd233477..3ff69a6e8e1d 100644 --- a/dom/base/nsIDocument.h +++ b/dom/base/nsIDocument.h @@ -2660,6 +2660,8 @@ public: CreateAttributeNS(const nsAString& aNamespaceURI, const nsAString& aQualifiedName, mozilla::ErrorResult& rv); + void SetAllowUnsafeHTML(bool aAllow) { mAllowUnsafeHTML = aAllow; } + bool AllowUnsafeHTML() const; void GetInputEncoding(nsAString& aInputEncoding) const; already_AddRefed<mozilla::dom::Location> GetLocation() const; void GetReferrer(nsAString& aReferrer) const; @@ -3206,6 +3208,10 @@ protected: // UpdateFrameRequestCallbackSchedulingState. bool mFrameRequestCallbacksScheduled : 1; + // True if unsafe HTML fragments should be allowed in chrome-privileged + // documents. + bool mAllowUnsafeHTML : 1; + enum Type { eUnknown, // should never be used eHTML, diff --git a/dom/base/test/chrome.ini b/dom/base/test/chrome.ini index f7e67ef6b9cb..8d4a9cd09a9c 100644 --- a/dom/base/test/chrome.ini +++ b/dom/base/test/chrome.ini @@ -16,6 +16,7 @@ support-files = [test_copypaste.xul] subsuite = clipboard [test_domrequesthelper.xul] +[test_fragment_sanitization.xul] [test_messagemanager_principal.html] [test_messagemanager_send_principal.html] skip-if = buildapp == 'mulet' diff --git a/dom/base/test/chrome/test_bug683852.xul b/dom/base/test/chrome/test_bug683852.xul index cebc8f3583bc..e7e106f7a483 100644 --- a/dom/base/test/chrome/test_bug683852.xul +++ b/dom/base/test/chrome/test_bug683852.xul @@ -20,6 +20,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=683852 /** Test for Bug 683852 **/ SimpleTest.waitForExplicitFinish(); + const NS_HTML = "http://www.w3.org/1999/xhtml"; + function startTest() { is(document.contains(document), true, "Document should contain itself!"); @@ -48,7 +50,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=683852 document.documentElement.appendChild(pi); document.contains(pi, true, "Document should contain processing instruction"); - var df = document.createRange().createContextualFragment("<div>foo</div>"); + var df = document.createRange().createContextualFragment(`<div xmlns="${NS_HTML}">foo</div>`); is(df.contains(df.firstChild), true, "Document fragment should contain its child"); is(df.contains(df.firstChild.firstChild), true, "Document fragment should contain its descendant"); diff --git a/dom/base/test/test_fragment_sanitization.xul b/dom/base/test/test_fragment_sanitization.xul new file mode 100644 index 000000000000..0c91b210125c --- /dev/null +++ b/dom/base/test/test_fragment_sanitization.xul @@ -0,0 +1,101 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1432966 +--> +<window title="Mozilla Bug 1432966" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SpawnTask.js"/> + + <script type="application/javascript"><![CDATA[ + +var { classes: Cc, interfaces: Ci } = Components; + +const NS_HTML = "http://www.w3.org/1999/xhtml"; + +function awaitLoad(frame) { + return new Promise(resolve => { + frame.addEventListener("load", resolve, {once: true}); + }); +} + +async function testFrame(frame, html, expected = html) { + document.querySelector("body").appendChild(frame); + await awaitLoad(frame); + + // Remove the xmlns attributes that will be automatically added when we're + // in an XML document, and break the comparison. + function unNS(text) { + return text.replace(RegExp(` xmlns="${NS_HTML}"`, "g"), ""); + } + + let doc = frame.contentDocument; + let body = doc.body || doc.documentElement; + + let div = doc.createElementNS(NS_HTML, "div"); + body.appendChild(div); + + div.innerHTML = html; + is(unNS(div.innerHTML), expected, "innerHTML value"); + + div.innerHTML = "<div></div>"; + div.firstChild.outerHTML = html; + is(unNS(div.innerHTML), expected, "outerHTML value"); + + div.textContent = ""; + div.insertAdjacentHTML("beforeend", html); + is(unNS(div.innerHTML), expected, "insertAdjacentHTML('beforeend') value"); + + div.innerHTML = "<a>foo</a>"; + div.firstChild.insertAdjacentHTML("afterend", html); + is(unNS(div.innerHTML), "<a>foo</a>" + expected, "insertAdjacentHTML('afterend') value"); + + frame.remove(); +} + +add_task(async function test_fragment_sanitization() { + const XUL_URL = "chrome://global/content/win.xul"; + const HTML_URL = "chrome://mochitests/content/chrome/dom/base/test/file_empty.html"; + + const HTML = '<a onclick="foo()" href="javascript:foo"><script>bar()<\/script>Meh.</a><a href="http://foo/"></a>'; + const SANITIZED = '<a>Meh.</a><a href="http://foo/"></a>'; + + info("Test content HTML document"); + { + let frame = document.createElementNS(NS_HTML, "iframe"); + frame.src = "http://example.com/"; + + await testFrame(frame, HTML); + } + + info("Test chrome HTML document"); + { + let frame = document.createElementNS(NS_HTML, "iframe"); + frame.src = HTML_URL; + + await testFrame(frame, HTML, SANITIZED); + } + + info("Test chrome XUL document"); + { + let frame = document.createElementNS(NS_HTML, "iframe"); + frame.src = XUL_URL; + + await testFrame(frame, HTML, SANITIZED); + } +}); + + ]]></script> + + <description style="-moz-user-focus: normal; -moz-user-select: text;"><![CDATA[ + hello + world + ]]></description> + + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1432966" + target="_blank">Mozilla Bug 1432966</a> + </body> +</window> diff --git a/dom/webidl/Document.webidl b/dom/webidl/Document.webidl index c895fad39275..ed071cbbd375 100644 --- a/dom/webidl/Document.webidl +++ b/dom/webidl/Document.webidl @@ -95,6 +95,11 @@ interface Document : Node { Attr createAttribute(DOMString name); [NewObject, Throws] Attr createAttributeNS(DOMString? namespace, DOMString name); + + // Allows setting innerHTML without automatic sanitization. + // Do not use this. + [ChromeOnly] + attribute boolean allowUnsafeHTML; }; // http://www.whatwg.org/specs/web-apps/current-work/#the-document-object diff --git a/dom/webidl/Element.webidl b/dom/webidl/Element.webidl index ca5f1b35cd78..a66327ff96cd 100644 --- a/dom/webidl/Element.webidl +++ b/dom/webidl/Element.webidl @@ -216,6 +216,16 @@ partial interface Element { attribute DOMString outerHTML; [Throws] void insertAdjacentHTML(DOMString position, DOMString text); + + /** + * Like the innerHTML setter, but does not sanitize its values, even in + * chrome-privileged documents. + * + * If you're thinking about using this, don't. You have many, much better + * options. + */ + [ChromeOnly, Throws] + void unsafeSetInnerHTML(DOMString html); }; // http://www.w3.org/TR/selectors-api/#interface-definitions diff --git a/layout/style/test/chrome/bug418986-2.js b/layout/style/test/chrome/bug418986-2.js index 4336f4abdb2c..2fcad6d70e0b 100644 --- a/layout/style/test/chrome/bug418986-2.js +++ b/layout/style/test/chrome/bug418986-2.js @@ -222,13 +222,23 @@ var green = (function () { return getComputedStyle(temp).backgroundColor; })(); +// Injected HTML will automatically be sanitized when we're in a chrome +// document unless we use `unsafeSetInnerHTML`. That function doesn't +// exist in non-chrome documents, so add a stub to allow the same code +// to run in both. +if (!Element.prototype.unsafeSetInnerHTML) { + Element.prototype.unsafeSetInnerHTML = html => { + this.innerHTML = html; + }; +} + // __testCSS(resisting)__. // Creates a series of divs and CSS using media queries to set their // background color. If all media queries match as expected, then // all divs should have a green background color. var testCSS = function (resisting) { - document.getElementById("display").innerHTML = generateHtmlLines(resisting); - document.getElementById("test-css").innerHTML = generateCSSLines(resisting); + document.getElementById("display").unsafeSetInnerHTML(generateHtmlLines(resisting)); + document.getElementById("test-css").unsafeSetInnerHTML(generateCSSLines(resisting)); let cssTestDivs = document.querySelectorAll(".spoof,.suppress"); for (let div of cssTestDivs) { let color = window.getComputedStyle(div).backgroundColor; @@ -272,7 +282,7 @@ var testMediaQueriesInPictureElements = function* (resisting) { lines += "</picture><br/>\n"; } } - document.getElementById("pictures").innerHTML = lines; + document.getElementById("pictures").unsafeSetInnerHTML(lines); var testImages = document.getElementsByClassName("testImage"); yield sleep(0); for (let testImage of testImages) { diff --git a/mobile/android/chrome/content/config.js b/mobile/android/chrome/content/config.js index 2c868f175ee8..83f93a51c86a 100644 --- a/mobile/android/chrome/content/config.js +++ b/mobile/android/chrome/content/config.js @@ -599,7 +599,7 @@ Pref.prototype = { this.li.setAttribute("contextmenu", "prefs-context-menu"); // Create list item outline, bind to object actions - this.li.innerHTML = + this.li.unsafeSetInnerHTML( "<div class='pref-name' " + "onclick='AboutConfig.selectOrToggleBoolPref(event);'>" + this.name + @@ -623,7 +623,7 @@ Pref.prototype = { "<div class='pref-button down' " + "onclick='AboutConfig.incrOrDecrIntPref(event, -1);'>" + "</div>" + - "</div>"; + "</div>"); // Delay providing the list item values, until the LI is returned and added to the document setTimeout(this._valueSetup.bind(this), INNERHTML_VALUE_DELAY); diff --git a/toolkit/content/tests/chrome/test_bug570192.xul b/toolkit/content/tests/chrome/test_bug570192.xul index 09f73e932b5d..91c55805c9da 100644 --- a/toolkit/content/tests/chrome/test_bug570192.xul +++ b/toolkit/content/tests/chrome/test_bug570192.xul @@ -36,8 +36,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=570192 addLoadEvent(function() { try { var content = document.getElementById("content"); - content.innerHTML = '<textbox newlines="pasteintact" ' + - 'xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"/>'; + content.unsafeSetInnerHTML('<textbox newlines="pasteintact" ' + + 'xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"/>'); var textbox = content.firstChild; ok(textbox, "created the textbox"); ok(!textbox.editor, "do we have an editor?"); diff --git a/toolkit/mozapps/extensions/content/extensions.js b/toolkit/mozapps/extensions/content/extensions.js index 1e5f33b0a251..771008ed3bf8 100644 --- a/toolkit/mozapps/extensions/content/extensions.js +++ b/toolkit/mozapps/extensions/content/extensions.js @@ -3078,7 +3078,7 @@ var gDetailView = { // plugins without having bug 624602 fixed yet, and intentionally ignores // localisation. if (aAddon.isGMPlugin) { - fullDesc.innerHTML = aAddon.fullDescription; + fullDesc.unsafeSetInnerHTML(aAddon.fullDescription); } else { fullDesc.textContent = aAddon.fullDescription; }
1 0
0 0
[tor-browser/tor-browser-60.0.1esr-8.0-1] fixup! TB4: Tor Browser's Firefox preference overrides.
by gk@torproject.org 20 Jun '18

20 Jun '18
commit 89614962f2ac1fa333b16c708a890167e9ec1b4e Author: Georg Koppen <gk(a)torproject.org> Date: Wed Jun 20 09:13:28 2018 +0000 fixup! TB4: Tor Browser's Firefox preference overrides. Fixes our bug 26424 (disabling UNC paths) and activates Mozilla's fix for https://bugzilla.mozilla.org/show_bug.cgi?id=1413868. --- browser/app/profile/000-tor-browser.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/browser/app/profile/000-tor-browser.js b/browser/app/profile/000-tor-browser.js index 4289b7bcc5f9..cd901374ed9f 100644 --- a/browser/app/profile/000-tor-browser.js +++ b/browser/app/profile/000-tor-browser.js @@ -250,6 +250,8 @@ pref("devtools.appmanager.enabled", false); pref("devtools.debugger.chrome-debugging-host", "127.0.0.1"); // Disable mozTCPSocket for sure (bug 18863) pref("dom.mozTCPSocket.enabled", false); +// Disable using UNC paths (bug 26424 and Mozilla's bug 1413868) +pref("network.file.disable_unc_paths", true); // Security slider pref("svg.in-content.enabled", true);
1 0
0 0
[tor-browser/tor-browser-52.8.0esr-7.5-1] Bug 1448771 - Update hnjstdio to handle additional functions from stdio.h that libhyphen wants to use. r=glandium, a=RyanVM
by gk@torproject.org 20 Jun '18

20 Jun '18
commit 20a839344bbb11759a15d38d283a9ff8862da30b Author: Jonathan Kew <jkew(a)mozilla.com> Date: Wed Mar 28 10:17:51 2018 +0100 Bug 1448771 - Update hnjstdio to handle additional functions from stdio.h that libhyphen wants to use. r=glandium, a=RyanVM --HG-- extra : source : 846bcaa210aa2264bec412c0595113964fafc972 --- intl/hyphenation/glue/hnjalloc.h | 6 +++++ intl/hyphenation/glue/hnjstdio.cpp | 50 ++++++++++++++++++++++++++------------ 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/intl/hyphenation/glue/hnjalloc.h b/intl/hyphenation/glue/hnjalloc.h index fec3a4bc9009..5cee1be1b6d7 100644 --- a/intl/hyphenation/glue/hnjalloc.h +++ b/intl/hyphenation/glue/hnjalloc.h @@ -31,6 +31,8 @@ #define fopen(path,mode) hnjFopen(path,mode) #define fclose(file) hnjFclose(file) #define fgets(buf,count,file) hnjFgets(buf,count,file) +#define feof(file) hnjFeof(file) +#define fgetc(file) hnjFgetc(file) typedef struct hnjFile_ hnjFile; @@ -44,6 +46,10 @@ int hnjFclose(hnjFile* f); char* hnjFgets(char* s, int n, hnjFile* f); +int hnjFeof(hnjFile* f); + +int hnjFgetc(hnjFile* f); + #ifdef __cplusplus } #endif diff --git a/intl/hyphenation/glue/hnjstdio.cpp b/intl/hyphenation/glue/hnjstdio.cpp index 660ebaf13291..8d50ae17f57b 100644 --- a/intl/hyphenation/glue/hnjstdio.cpp +++ b/intl/hyphenation/glue/hnjstdio.cpp @@ -22,6 +22,7 @@ struct hnjFile_ { char mBuffer[BUFSIZE]; uint32_t mCurPos; uint32_t mLimit; + bool mEOF; }; // replacement for fopen() @@ -58,6 +59,7 @@ hnjFopen(const char* aURISpec, const char* aMode) f->mStream = instream; f->mCurPos = 0; f->mLimit = 0; + f->mEOF = false; return f; } @@ -79,6 +81,27 @@ hnjFclose(hnjFile* f) return result; } +// replacement for fgetc() +int +hnjFgetc(hnjFile* f) +{ + if (f->mCurPos >= f->mLimit) { + f->mCurPos = 0; + + nsresult rv = f->mStream->Read(f->mBuffer, BUFSIZE, &f->mLimit); + if (NS_FAILED(rv)) { + f->mLimit = 0; + } + + if (f->mLimit == 0) { + f->mEOF = true; + return EOF; + } + } + + return f->mBuffer[f->mCurPos++]; +} + // replacement for fgets() // (not a full reimplementation, but sufficient for libhyphen's needs) char* @@ -88,24 +111,15 @@ hnjFgets(char* s, int n, hnjFile* f) int i = 0; while (i < n - 1) { - if (f->mCurPos < f->mLimit) { - char c = f->mBuffer[f->mCurPos++]; - s[i++] = c; - if (c == '\n' || c == '\r') { - break; - } - continue; - } - - f->mCurPos = 0; + int c = hnjFgetc(f); - nsresult rv = f->mStream->Read(f->mBuffer, BUFSIZE, &f->mLimit); - if (NS_FAILED(rv)) { - f->mLimit = 0; - return nullptr; + if (c == EOF) { + break; } - if (f->mLimit == 0) { + s[i++] = c; + + if (c == '\n' || c == '\r') { break; } } @@ -117,3 +131,9 @@ hnjFgets(char* s, int n, hnjFile* f) s[i] = '\0'; // null-terminate the returned string return s; } + +int +hnjFeof(hnjFile* f) +{ + return f->mEOF ? EOF : 0; +}
1 0
0 0
[tor-browser/tor-browser-52.8.0esr-7.5-1] Bug 1448771 - Merge fix from upstream. r=ryanvm, a=RyanVM
by gk@torproject.org 20 Jun '18

20 Jun '18
commit 12148cf644e5820182306788a3d3309baf8c2720 Author: Jonathan Kew <jkew(a)mozilla.com> Date: Mon Mar 26 20:35:48 2018 +0100 Bug 1448771 - Merge fix from upstream. r=ryanvm, a=RyanVM --HG-- extra : source : f5db47b5c6416a3cef546de1aa9089d98109f95f --- intl/hyphenation/hyphen/hyphen.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/intl/hyphenation/hyphen/hyphen.c b/intl/hyphenation/hyphen/hyphen.c index 9a132d0262f2..9f2b7112c848 100644 --- a/intl/hyphenation/hyphen/hyphen.c +++ b/intl/hyphenation/hyphen/hyphen.c @@ -438,11 +438,25 @@ for (k = 0; k < 2; k++) { } if (k == 0 || nextlevel) { - while (fgets (buf, sizeof(buf), f) != NULL) { + while (fgets(buf, sizeof(buf), f) != NULL) { + + /* discard lines that don't fit in buffer */ + if (!feof(f) && strchr(buf, '\n') == NULL) { + int c; + while ((c = fgetc(f)) != '\n' && c != EOF); + /* issue warning if not a comment */ + if (buf[0] != '%') { + fprintf(stderr, "Warning: skipping too long pattern (more than %lu chars)\n", sizeof(buf)); + } + continue; + } + if (strncmp(buf, "NEXTLEVEL", 9) == 0) { - nextlevel = 1; - break; - } else if (buf[0] != '%') hnj_hyphen_load_line(buf, dict[k], hashtab); + nextlevel = 1; + break; + } else if (buf[0] != '%') { + hnj_hyphen_load_line(buf, dict[k], hashtab); + } } } else if (k == 1) { /* default first level: hyphen and ASCII apostrophe */
1 0
0 0
[tor-browser/tor-browser-52.8.0esr-7.5-1] Bug 21537: Mark .onion cookies as secure
by gk@torproject.org 20 Jun '18

20 Jun '18
commit 1f33ee1778b0ad0f696977fbcbae67f72d34b99f Author: Georg Koppen <gk(a)torproject.org> Date: Fri Apr 13 16:59:24 2018 +0000 Bug 21537: Mark .onion cookies as secure --- netwerk/cookie/nsCookieService.cpp | 60 ++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/netwerk/cookie/nsCookieService.cpp b/netwerk/cookie/nsCookieService.cpp index cf1d91e2df36..f9390d7ef093 100644 --- a/netwerk/cookie/nsCookieService.cpp +++ b/netwerk/cookie/nsCookieService.cpp @@ -3112,6 +3112,26 @@ PathMatches(nsCookie* aCookie, const nsACString& aPath) { return true; } +static bool +IsSecureHost(nsIURI *aHostURI) { + bool isSecure = true; + // If SchemeIs fails, assume an insecure connection, to be on the safe side. + if (aHostURI && NS_FAILED(aHostURI->SchemeIs("https", &isSecure))) { + isSecure = false; + } + // In case HTTPS is not used check whether we have a .onion host in which + // case the cookie is secure, too. + if (aHostURI && !isSecure) { + nsresult rv; + nsAutoCString hostFromURI; + rv = aHostURI->GetAsciiHost(hostFromURI); + if (NS_SUCCEEDED(rv)) { + isSecure = StringEndsWith(hostFromURI, NS_LITERAL_CSTRING(".onion")); + } + } + return isSecure; +} + void nsCookieService::GetCookieStringInternal(nsIURI *aHostURI, bool aIsForeign, @@ -3164,13 +3184,10 @@ nsCookieService::GetCookieStringInternal(nsIURI *aHostURI, // If it changes, please update that function, or file a bug for someone // else to do so. - // check if aHostURI is using an https secure protocol. - // if it isn't, then we can't send a secure cookie over the connection. - // if SchemeIs fails, assume an insecure connection, to be on the safe side - bool isSecure; - if (NS_FAILED(aHostURI->SchemeIs("https", &isSecure))) { - isSecure = false; - } + // Check if aHostURI is using the HTTPS protocol or if the domain is a + // .onion. If it isn't, then we can't send a secure cookie over the + // connection. + bool isSecure = IsSecureHost(aHostURI); nsCookie *cookie; AutoTArray<nsCookie*, 8> foundCookieList; @@ -3316,20 +3333,10 @@ nsCookieService::SetCookieInternal(nsIURI *aHostURI, // so we can handle them separately. bool newCookie = ParseAttributes(aCookieHeader, cookieAttributes); - // Collect telemetry on how often secure cookies are set from non-secure - // origins, and vice-versa. - // - // 0 = nonsecure and "http:" - // 1 = nonsecure and "https:" - // 2 = secure and "http:" - // 3 = secure and "https:" - bool isHTTPS; - nsresult rv = aHostURI->SchemeIs("https", &isHTTPS); - if (NS_SUCCEEDED(rv)) { - Telemetry::Accumulate(Telemetry::COOKIE_SCHEME_SECURITY, - ((cookieAttributes.isSecure)? 0x02 : 0x00) | - ((isHTTPS)? 0x01 : 0x00)); - } + // Check if aHostURI is using the HTTPS protocol or if the domain is a + // .onion. If it isn't, then we can't send a secure cookie over the + // connection. + bool isSecure = IsSecureHost(aHostURI); int64_t currentTimeInUsec = PR_Now(); @@ -3369,7 +3376,7 @@ nsCookieService::SetCookieInternal(nsIURI *aHostURI, return newCookie; } // magic prefix checks. MUST be run after CheckDomain() and CheckPath() - if (!CheckPrefixes(cookieAttributes, isHTTPS)) { + if (!CheckPrefixes(cookieAttributes, isSecure)) { COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, savedCookieHeader, "failed the prefix tests"); return newCookie; } @@ -3457,13 +3464,10 @@ nsCookieService::AddInternal(const nsCookieKey &aKey, return; } - bool isSecure = true; - if (aHostURI && NS_FAILED(aHostURI->SchemeIs("https", &isSecure))) { - isSecure = false; - } + bool isSecure = IsSecureHost(aHostURI); - // If the new cookie is non-https and wants to set secure flag, - // browser have to ignore this new cookie. + // If the new cookie is non-https or not set by a .onion domain, and wants to + // set secure flag, browser have to ignore this new cookie. // (draft-ietf-httpbis-cookie-alone section 3.1) if (mLeaveSecureAlone && aCookie->IsSecure() && !isSecure) { COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, aCookieHeader,
1 0
0 0
[tor-browser/tor-browser-52.8.0esr-7.5-1] Bug 1334776 - ResponseHeader Visitor will get original header casing. We need to fix it at some places in devtools.
by gk@torproject.org 20 Jun '18

20 Jun '18
commit 1a800384e6ee8c909a1147737cdebad189f6ca3d Author: Dragana Damjanovic <dd.mozilla(a)gmail.com> Date: Thu Apr 27 16:48:43 2017 +0200 Bug 1334776 - ResponseHeader Visitor will get original header casing. We need to fix it at some places in devtools. Backported to TBB/ESR52 by Arthur Edelstein <arthuredelstein(a)gmail.com> Fixes bug 25938. --- devtools/client/netmonitor/filter-predicates.js | 4 ++-- .../client/netmonitor/test/browser_net_copy_headers.js | 16 ++++++++-------- devtools/client/netmonitor/test/browser_net_filter-01.js | 4 ++-- .../netmonitor/test/browser_net_timing-division.js | 4 ++-- devtools/client/shared/AppCacheUtils.jsm | 8 ++++---- devtools/client/shared/curl.js | 8 ++++---- .../webconsole/net/test/mochitest/browser_net_headers.js | 4 ++-- ...er_webconsole_bug_630733_response_redirect_headers.js | 2 +- devtools/shared/webconsole/test/test_network_get.html | 8 ++++---- .../shared/webconsole/test/test_network_longstring.html | 4 ++-- devtools/shared/webconsole/test/test_network_post.html | 8 ++++---- 11 files changed, 35 insertions(+), 35 deletions(-) diff --git a/devtools/client/netmonitor/filter-predicates.js b/devtools/client/netmonitor/filter-predicates.js index 9c8e49c622b2..75ee422aad60 100644 --- a/devtools/client/netmonitor/filter-predicates.js +++ b/devtools/client/netmonitor/filter-predicates.js @@ -72,7 +72,7 @@ function isWS({ requestHeaders, responseHeaders }) { // Find the 'upgrade' header. let upgradeHeader = requestHeaders.headers.find(header => { - return (header.name == "Upgrade"); + return (header.name.toLowerCase() == "upgrade"); }); // If no header found on request, check response - mainly to get @@ -81,7 +81,7 @@ function isWS({ requestHeaders, responseHeaders }) { if (!upgradeHeader && responseHeaders && Array.isArray(responseHeaders.headers)) { upgradeHeader = responseHeaders.headers.find(header => { - return (header.name == "Upgrade"); + return (header.name.toLowerCase() == "upgrade"); }); } diff --git a/devtools/client/netmonitor/test/browser_net_copy_headers.js b/devtools/client/netmonitor/test/browser_net_copy_headers.js index 36ce2fb34789..bb582c8e1359 100644 --- a/devtools/client/netmonitor/test/browser_net_copy_headers.js +++ b/devtools/client/netmonitor/test/browser_net_copy_headers.js @@ -49,12 +49,12 @@ add_task(function* () { const EXPECTED_RESPONSE_HEADERS = [ `${httpVersion} ${status} ${statusText}`, - "Last-Modified: Sun, 3 May 2015 11:11:11 GMT", - "Content-Type: text/html", - "Content-Length: 465", - "Connection: close", - "Server: httpd.js", - "Date: Sun, 3 May 2015 11:11:11 GMT" + "last-modified: Sun, 3 May 2015 11:11:11 GMT", + "content-type: text/html", + "content-length: 465", + "connection: close", + "server: httpd.js", + "date: Sun, 3 May 2015 11:11:11 GMT" ].join("\n"); yield waitForClipboardPromise(function setup() { @@ -62,8 +62,8 @@ add_task(function* () { }, function validate(result) { // Fake the "Last-Modified" and "Date" headers because they will vary: result = String(result) - .replace(/Last-Modified: [^\n]+ GMT/, "Last-Modified: Sun, 3 May 2015 11:11:11 GMT") - .replace(/Date: [^\n]+ GMT/, "Date: Sun, 3 May 2015 11:11:11 GMT"); + .replace(/last-modified: [^\n]+ GMT/, "last-modified: Sun, 3 May 2015 11:11:11 GMT") + .replace(/date: [^\n]+ GMT/, "date: Sun, 3 May 2015 11:11:11 GMT"); return result === EXPECTED_RESPONSE_HEADERS; }); info("Clipboard contains the currently selected item's response headers."); diff --git a/devtools/client/netmonitor/test/browser_net_filter-01.js b/devtools/client/netmonitor/test/browser_net_filter-01.js index b0d76c6293e0..7b3a8c457dd3 100644 --- a/devtools/client/netmonitor/test/browser_net_filter-01.js +++ b/devtools/client/netmonitor/test/browser_net_filter-01.js @@ -181,9 +181,9 @@ add_task(function* () { "The details pane should still be visible after filtering."); is(RequestsMenu.items.length, visibility.length, - "There should be a specific amount of items in the requests menu."); + "There should be a specific amount of items in the requests menu."); is(RequestsMenu.visibleItems.length, visibility.filter(e => e).length, - "There should be a specific amount of visbile items in the requests menu."); + "There should be a specific amount of visbile items in the requests menu."); for (let i = 0; i < visibility.length; i++) { is(RequestsMenu.getItemAtIndex(i).target.hidden, !visibility[i], diff --git a/devtools/client/netmonitor/test/browser_net_timing-division.js b/devtools/client/netmonitor/test/browser_net_timing-division.js index 0114ba235500..ff2379dc28c4 100644 --- a/devtools/client/netmonitor/test/browser_net_timing-division.js +++ b/devtools/client/netmonitor/test/browser_net_timing-division.js @@ -48,9 +48,9 @@ add_task(function* () { let lastRequest = RequestsMenu.getItemAtIndex(1); info("First request happened at: " + - firstRequest.attachment.responseHeaders.headers.find(e => e.name == "Date").value); + firstRequest.attachment.responseHeaders.headers.find(e => e.name == "date").value); info("Last request happened at: " + - lastRequest.attachment.responseHeaders.headers.find(e => e.name == "Date").value); + lastRequest.attachment.responseHeaders.headers.find(e => e.name == "date").value); ok(secDivs.length, "There should be at least one division on the seconds time scale."); diff --git a/devtools/client/shared/AppCacheUtils.jsm b/devtools/client/shared/AppCacheUtils.jsm index a2beca993c32..7c8007d9ffe2 100644 --- a/devtools/client/shared/AppCacheUtils.jsm +++ b/devtools/client/shared/AppCacheUtils.jsm @@ -86,7 +86,7 @@ AppCacheUtils.prototype = { _parseManifest: function ACU__parseManifest(uriInfo) { let deferred = defer(); let manifestName = uriInfo.name; - let manifestLastModified = new Date(uriInfo.responseHeaders["Last-Modified"]); + let manifestLastModified = new Date(uriInfo.responseHeaders["last-modified"]); if (uriInfo.charset.toLowerCase() != "utf-8") { this._addError(0, "notUTF8", uriInfo.charset); @@ -158,7 +158,7 @@ AppCacheUtils.prototype = { // Check that the resource was not modified after the manifest was last // modified. If it was then the manifest file should be refreshed. let resourceLastModified = - new Date(uriInfo.responseHeaders["Last-Modified"]); + new Date(uriInfo.responseHeaders["last-modified"]); if (manifestLastModified < resourceLastModified) { this._addError(parsedUri.line, "fileChangedButNotManifest", @@ -230,12 +230,12 @@ AppCacheUtils.prototype = { result.requestHeaders = {}; request.visitRequestHeaders(function (header, value) { - result.requestHeaders[header] = value; + result.requestHeaders[header.toLowerCase()] = value; }); result.responseHeaders = {}; request.visitResponseHeaders(function (header, value) { - result.responseHeaders[header] = value; + result.responseHeaders[header.toLowerCase()] = value; }); deferred.resolve(result); diff --git a/devtools/client/shared/curl.js b/devtools/client/shared/curl.js index 978cbad9c845..ae954fe9f412 100644 --- a/devtools/client/shared/curl.js +++ b/devtools/client/shared/curl.js @@ -80,14 +80,14 @@ const Curl = { postDataText = data.postDataText; postData.push("--data"); postData.push(escapeString(utils.writePostDataTextParams(postDataText))); - ignoredHeaders.add("Content-Length"); + ignoredHeaders.add("content-length"); } else if (multipartRequest) { postDataText = data.postDataText; postData.push("--data-binary"); let boundary = utils.getMultipartBoundary(data); let text = utils.removeBinaryDataFromMultipartText(postDataText, boundary); postData.push(escapeString(text)); - ignoredHeaders.add("Content-Length"); + ignoredHeaders.add("content-length"); } // Add method. @@ -118,11 +118,11 @@ const Curl = { } for (let i = 0; i < headers.length; i++) { let header = headers[i]; - if (header.name === "Accept-Encoding") { + if (header.name.toLowerCase() === "accept-encoding") { command.push("--compressed"); continue; } - if (ignoredHeaders.has(header.name)) { + if (ignoredHeaders.has(header.name.toLowerCase())) { continue; } command.push("-H"); diff --git a/devtools/client/webconsole/net/test/mochitest/browser_net_headers.js b/devtools/client/webconsole/net/test/mochitest/browser_net_headers.js index 4a47074ee194..14cde846c20c 100644 --- a/devtools/client/webconsole/net/test/mochitest/browser_net_headers.js +++ b/devtools/client/webconsole/net/test/mochitest/browser_net_headers.js @@ -26,11 +26,11 @@ add_task(function* () { // Select "Headers" tab let tabBody = yield selectNetInfoTab(hud, netInfoBody, "headers"); let paramName = tabBody.querySelector( - ".netInfoParamName > span[title='Content-Type']"); + ".netInfoParamName > span[title='content-type']"); // Verify "Content-Type" header (name and value) ok(paramName, "Header name must exist"); - is(paramName.textContent, "Content-Type", + is(paramName.textContent, "content-type", "The header name must have proper value"); let paramValue = paramName.parentNode.nextSibling; diff --git a/devtools/client/webconsole/test/browser_webconsole_bug_630733_response_redirect_headers.js b/devtools/client/webconsole/test/browser_webconsole_bug_630733_response_redirect_headers.js index 5097499538c9..da4bdcf122ec 100644 --- a/devtools/client/webconsole/test/browser_webconsole_bug_630733_response_redirect_headers.js +++ b/devtools/client/webconsole/test/browser_webconsole_bug_630733_response_redirect_headers.js @@ -87,7 +87,7 @@ function getContent() { function performTest() { function readHeader(name) { for (let header of headers) { - if (header.name == name) { + if (header.name.toLowerCase() == name.toLowerCase()) { return header.value; } } diff --git a/devtools/shared/webconsole/test/test_network_get.html b/devtools/shared/webconsole/test/test_network_get.html index 710c9b0d7516..c2313be12a30 100644 --- a/devtools/shared/webconsole/test/test_network_get.html +++ b/devtools/shared/webconsole/test/test_network_get.html @@ -196,13 +196,13 @@ function onResponseHeaders(aState, aResponse) ok(!!aResponse.rawHeaders, "response rawHeaders available"); checkHeadersOrCookies(aResponse.headers, { - "Content-Type": /^application\/(json|octet-stream)$/, - "Content-Length": /^\d+$/, + "content-type": /^application\/(json|octet-stream)$/, + "content-length": /^\d+$/, }); checkRawHeaders(aResponse.rawHeaders, { - "Content-Type": /^application\/(json|octet-stream)$/, - "Content-Length": /^\d+$/, + "content-type": /^application\/(json|octet-stream)$/, + "content-length": /^\d+$/, }); onResponseCookies = onResponseCookies.bind(null, aState); diff --git a/devtools/shared/webconsole/test/test_network_longstring.html b/devtools/shared/webconsole/test/test_network_longstring.html index d55136896917..9e6ea7771b63 100644 --- a/devtools/shared/webconsole/test/test_network_longstring.html +++ b/devtools/shared/webconsole/test/test_network_longstring.html @@ -212,8 +212,8 @@ function onResponseHeaders(aState, aResponse) ok(aResponse.headersSize > 0, "response headersSize > 0"); checkHeadersOrCookies(aResponse.headers, { - "Content-Type": /^application\/(json|octet-stream)$/, - "Content-Length": /^\d+$/, + "content-type": /^application\/(json|octet-stream)$/, + "content-length": /^\d+$/, "x-very-short": "hello world", "x-very-long": { "type": "longString", diff --git a/devtools/shared/webconsole/test/test_network_post.html b/devtools/shared/webconsole/test/test_network_post.html index d96b9b0b7c24..a0b8edb648f8 100644 --- a/devtools/shared/webconsole/test/test_network_post.html +++ b/devtools/shared/webconsole/test/test_network_post.html @@ -204,13 +204,13 @@ function onResponseHeaders(aState, aResponse) ok(!!aResponse.rawHeaders, "response rawHeaders available"); checkHeadersOrCookies(aResponse.headers, { - "Content-Type": /^application\/(json|octet-stream)$/, - "Content-Length": /^\d+$/, + "content-type": /^application\/(json|octet-stream)$/, + "content-length": /^\d+$/, }); checkRawHeaders(aResponse.rawHeaders, { - "Content-Type": /^application\/(json|octet-stream)$/, - "Content-Length": /^\d+$/, + "content-type": /^application\/(json|octet-stream)$/, + "content-length": /^\d+$/, }); onResponseCookies = onResponseCookies.bind(null, aState);
1 0
0 0
[tor-browser/tor-browser-52.8.0esr-7.5-1] fixup! TB4: Tor Browser's Firefox preference overrides.
by gk@torproject.org 20 Jun '18

20 Jun '18
commit 76a19c911a7c847756d8ca20a70affdbcad56011 Author: Georg Koppen <gk(a)torproject.org> Date: Wed Jun 20 09:13:28 2018 +0000 fixup! TB4: Tor Browser's Firefox preference overrides. Fixes our bug 26424 (disabling UNC paths) and activates Mozilla's fix for https://bugzilla.mozilla.org/show_bug.cgi?id=1413868. --- browser/app/profile/000-tor-browser.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/browser/app/profile/000-tor-browser.js b/browser/app/profile/000-tor-browser.js index 6fa34860a7b5..f27c5dd93e04 100644 --- a/browser/app/profile/000-tor-browser.js +++ b/browser/app/profile/000-tor-browser.js @@ -255,6 +255,8 @@ pref("devtools.appmanager.enabled", false); pref("devtools.debugger.chrome-debugging-host", "127.0.0.1"); // Disable mozTCPSocket for sure (bug 18863) pref("dom.mozTCPSocket.enabled", false); +// Disable using UNC paths (bug 26424 and Mozilla's bug 1413868) +pref("network.file.disable_unc_paths", true); // Security slider pref("svg.in-content.enabled", true);
1 0
0 0
[tor-browser/tor-browser-52.8.0esr-7.5-1] Bug 1334776 - Store header names into nsHttpHeaderArray. r=mcmanus
by gk@torproject.org 20 Jun '18

20 Jun '18
commit cd2dd6a72bef0d0d5d405af3a1913bebb820fc02 Author: Dragana Damjanovic <dd.mozilla(a)gmail.com> Date: Thu Apr 27 16:48:36 2017 +0200 Bug 1334776 - Store header names into nsHttpHeaderArray. r=mcmanus Backported to TBB/ESR52 by Arthur Edelstein <arthuredelstein(a)gmail.com> --- dom/security/test/cors/test_CrossSiteXHR.html | 2 +- netwerk/protocol/http/HttpBaseChannel.cpp | 18 +--- netwerk/protocol/http/PHttpChannelParams.h | 15 +++- netwerk/protocol/http/nsHttpHeaderArray.cpp | 100 +++++++++++++++++---- netwerk/protocol/http/nsHttpHeaderArray.h | 36 ++++++-- netwerk/protocol/http/nsHttpRequestHead.cpp | 23 ++++- netwerk/protocol/http/nsHttpRequestHead.h | 4 +- netwerk/protocol/http/nsHttpResponseHead.cpp | 50 ++++++++--- netwerk/protocol/http/nsHttpResponseHead.h | 6 +- netwerk/test/unit/test_bug1064258.js | 2 +- .../test/unit/test_original_sent_received_head.js | 14 +-- 11 files changed, 204 insertions(+), 66 deletions(-) diff --git a/dom/security/test/cors/test_CrossSiteXHR.html b/dom/security/test/cors/test_CrossSiteXHR.html index b3cda3b871f3..d9aef5c60cd0 100644 --- a/dom/security/test/cors/test_CrossSiteXHR.html +++ b/dom/security/test/cors/test_CrossSiteXHR.html @@ -743,7 +743,7 @@ function runTest() { is(res.responseHeaders[header], test.responseHeaders[header], "|xhr.getResponseHeader()|wrong response header (" + header + ") in test for " + test.toSource()); - is(res.allResponseHeaders[header], test.responseHeaders[header], + is(res.allResponseHeaders[header.toLowerCase()], test.responseHeaders[header], "|xhr.getAllResponseHeaderss()|wrong response header (" + header + ") in test for " + test.toSource()); } diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/HttpBaseChannel.cpp index e68bff1d115e..97120b97a5d3 100644 --- a/netwerk/protocol/http/HttpBaseChannel.cpp +++ b/netwerk/protocol/http/HttpBaseChannel.cpp @@ -1678,13 +1678,7 @@ HttpBaseChannel::SetRequestHeader(const nsACString& aHeader, return NS_ERROR_INVALID_ARG; } - nsHttpAtom atom = nsHttp::ResolveAtom(flatHeader.get()); - if (!atom) { - NS_WARNING("failed to resolve atom"); - return NS_ERROR_NOT_AVAILABLE; - } - - return mRequestHead.SetHeader(atom, flatValue, aMerge); + return mRequestHead.SetHeader(aHeader, flatValue, aMerge); } NS_IMETHODIMP @@ -1701,13 +1695,7 @@ HttpBaseChannel::SetEmptyRequestHeader(const nsACString& aHeader) return NS_ERROR_INVALID_ARG; } - nsHttpAtom atom = nsHttp::ResolveAtom(flatHeader.get()); - if (!atom) { - NS_WARNING("failed to resolve atom"); - return NS_ERROR_NOT_AVAILABLE; - } - - return mRequestHead.SetEmptyHeader(atom); + return mRequestHead.SetEmptyHeader(aHeader); } NS_IMETHODIMP @@ -1763,7 +1751,7 @@ HttpBaseChannel::SetResponseHeader(const nsACString& header, mResponseHeadersModified = true; - return mResponseHead->SetHeader(atom, value, merge); + return mResponseHead->SetHeader(header, value, merge); } NS_IMETHODIMP diff --git a/netwerk/protocol/http/PHttpChannelParams.h b/netwerk/protocol/http/PHttpChannelParams.h index 4df5c7832ee8..b04f57306c58 100644 --- a/netwerk/protocol/http/PHttpChannelParams.h +++ b/netwerk/protocol/http/PHttpChannelParams.h @@ -98,7 +98,11 @@ struct ParamTraits<mozilla::net::nsHttpHeaderArray::nsEntry> static void Write(Message* aMsg, const paramType& aParam) { - WriteParam(aMsg, aParam.header); + if (aParam.headerNameOriginal.IsEmpty()) { + WriteParam(aMsg, aParam.header); + } else { + WriteParam(aMsg, aParam.headerNameOriginal); + } WriteParam(aMsg, aParam.value); switch (aParam.variety) { case mozilla::net::nsHttpHeaderArray::eVarietyUnknown: @@ -124,11 +128,18 @@ struct ParamTraits<mozilla::net::nsHttpHeaderArray::nsEntry> static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) { uint8_t variety; - if (!ReadParam(aMsg, aIter, &aResult->header) || + nsAutoCString header; + if (!ReadParam(aMsg, aIter, &header) || !ReadParam(aMsg, aIter, &aResult->value) || !ReadParam(aMsg, aIter, &variety)) return false; + mozilla::net::nsHttpAtom atom = mozilla::net::nsHttp::ResolveAtom(header); + aResult->header = atom; + if (!header.Equals(atom.get())) { + aResult->headerNameOriginal = header; + } + switch (variety) { case 0: aResult->variety = mozilla::net::nsHttpHeaderArray::eVarietyUnknown; diff --git a/netwerk/protocol/http/nsHttpHeaderArray.cpp b/netwerk/protocol/http/nsHttpHeaderArray.cpp index 670300dea50b..98c5a6b9ba47 100644 --- a/netwerk/protocol/http/nsHttpHeaderArray.cpp +++ b/netwerk/protocol/http/nsHttpHeaderArray.cpp @@ -18,8 +18,33 @@ namespace net { //----------------------------------------------------------------------------- // nsHttpHeaderArray <public> //----------------------------------------------------------------------------- + +nsresult +nsHttpHeaderArray::SetHeader(const nsACString &headerName, + const nsACString &value, + bool merge, + nsHttpHeaderArray::HeaderVariety variety) +{ + nsHttpAtom header = nsHttp::ResolveAtom(PromiseFlatCString(headerName).get()); + if (!header) { + NS_WARNING("failed to resolve atom"); + return NS_ERROR_NOT_AVAILABLE; + } + return SetHeader(header, headerName, value, merge, variety); +} + +nsresult +nsHttpHeaderArray::SetHeader(nsHttpAtom header, + const nsACString &value, + bool merge, + nsHttpHeaderArray::HeaderVariety variety) +{ + return SetHeader(header, EmptyCString(), value, merge, variety); +} + nsresult nsHttpHeaderArray::SetHeader(nsHttpAtom header, + const nsACString &headerName, const nsACString &value, bool merge, nsHttpHeaderArray::HeaderVariety variety) @@ -51,7 +76,7 @@ nsHttpHeaderArray::SetHeader(nsHttpAtom header, MOZ_ASSERT(!entry || variety != eVarietyRequestDefault, "Cannot set default entry which overrides existing entry!"); if (!entry) { - return SetHeader_internal(header, value, variety); + return SetHeader_internal(header, headerName, value, variety); } else if (merge && !IsSingletonHeader(header)) { return MergeHeader(header, entry, value, variety); } else { @@ -59,7 +84,7 @@ nsHttpHeaderArray::SetHeader(nsHttpAtom header, if (entry->variety == eVarietyResponseNetOriginalAndResponse) { MOZ_ASSERT(variety == eVarietyResponse); entry->variety = eVarietyResponseNetOriginal; - return SetHeader_internal(header, value, variety); + return SetHeader_internal(header, headerName, value, variety); } else { entry->value = value; entry->variety = variety; @@ -71,6 +96,7 @@ nsHttpHeaderArray::SetHeader(nsHttpAtom header, nsresult nsHttpHeaderArray::SetHeader_internal(nsHttpAtom header, + const nsACString &headerName, const nsACString &value, nsHttpHeaderArray::HeaderVariety variety) { @@ -79,14 +105,26 @@ nsHttpHeaderArray::SetHeader_internal(nsHttpAtom header, return NS_ERROR_OUT_OF_MEMORY; } entry->header = header; + // Only save original form of a header if it is different than the header + // atom string. + if (!headerName.Equals(header.get())) { + entry->headerNameOriginal = headerName; + } entry->value = value; entry->variety = variety; return NS_OK; } nsresult -nsHttpHeaderArray::SetEmptyHeader(nsHttpAtom header, HeaderVariety variety) +nsHttpHeaderArray::SetEmptyHeader(const nsACString &headerName, + HeaderVariety variety) { + nsHttpAtom header = nsHttp::ResolveAtom(PromiseFlatCString(headerName).get()); + if (!header) { + NS_WARNING("failed to resolve atom"); + return NS_ERROR_NOT_AVAILABLE; + } + MOZ_ASSERT((variety == eVarietyResponse) || (variety == eVarietyRequestDefault) || (variety == eVarietyRequestOverride), @@ -104,11 +142,12 @@ nsHttpHeaderArray::SetEmptyHeader(nsHttpAtom header, HeaderVariety variety) entry->variety = eVarietyResponseNetOriginal; } - return SetHeader_internal(header, EmptyCString(), variety); + return SetHeader_internal(header, headerName, EmptyCString(), variety); } nsresult nsHttpHeaderArray::SetHeaderFromNet(nsHttpAtom header, + const nsACString &headerNameOriginal, const nsACString &value, bool response) { @@ -125,7 +164,7 @@ nsHttpHeaderArray::SetHeaderFromNet(nsHttpAtom header, LOG(("Ignoring Empty Header: %s\n", header.get())); if (response) { // Set header as original but not as response header. - return SetHeader_internal(header, value, + return SetHeader_internal(header, headerNameOriginal, value, eVarietyResponseNetOriginal); } return NS_OK; // ignore empty headers by default @@ -135,7 +174,7 @@ nsHttpHeaderArray::SetHeaderFromNet(nsHttpAtom header, if (response) { variety = eVarietyResponseNetOriginalAndResponse; } - return SetHeader_internal(header, value, variety); + return SetHeader_internal(header, headerNameOriginal, value, variety); } else if (!IsSingletonHeader(header)) { HeaderVariety variety = eVarietyRequestOverride; @@ -147,7 +186,7 @@ nsHttpHeaderArray::SetHeaderFromNet(nsHttpAtom header, return rv; } if (response) { - rv = SetHeader_internal(header, value, + rv = SetHeader_internal(header, headerNameOriginal, value, eVarietyResponseNetOriginal); } return rv; @@ -164,7 +203,7 @@ nsHttpHeaderArray::SetHeaderFromNet(nsHttpAtom header, } if (response) { - return SetHeader_internal(header, value, + return SetHeader_internal(header, headerNameOriginal, value, eVarietyResponseNetOriginal); } } @@ -174,6 +213,7 @@ nsHttpHeaderArray::SetHeaderFromNet(nsHttpAtom header, nsresult nsHttpHeaderArray::SetResponseHeaderFromCache(nsHttpAtom header, + const nsACString &headerNameOriginal, const nsACString &value, nsHttpHeaderArray::HeaderVariety variety) { @@ -183,7 +223,7 @@ nsHttpHeaderArray::SetResponseHeaderFromCache(nsHttpAtom header, "eVarietyResponseNetOriginal"); if (variety == eVarietyResponseNetOriginal) { - return SetHeader_internal(header, value, + return SetHeader_internal(header, headerNameOriginal, value, eVarietyResponseNetOriginal); } else { nsTArray<nsEntry>::index_type index = 0; @@ -203,7 +243,8 @@ nsHttpHeaderArray::SetResponseHeaderFromCache(nsHttpAtom header, } } while (index != mHeaders.NoIndex); // If we are here, we have not found an entry so add a new one. - return SetHeader_internal(header, value, eVarietyResponse); + return SetHeader_internal(header, headerNameOriginal, value, + eVarietyResponse); } } @@ -260,8 +301,16 @@ nsHttpHeaderArray::GetOriginalHeader(nsHttpAtom aHeader, if (entry.variety == eVarietyResponse) { continue; } + + nsAutoCString hdr; + if (entry.headerNameOriginal.IsEmpty()) { + hdr = nsDependentCString(entry.header); + } else { + hdr = entry.headerNameOriginal; + } + rv = NS_OK; - if (NS_FAILED(aVisitor->VisitHeader(nsDependentCString(entry.header), + if (NS_FAILED(aVisitor->VisitHeader(hdr, entry.value))) { break; } @@ -298,8 +347,14 @@ nsHttpHeaderArray::VisitHeaders(nsIHttpHeaderVisitor *visitor, nsHttpHeaderArray } else if (filter == eFilterResponseOriginal && entry.variety == eVarietyResponse) { continue; } - rv = visitor->VisitHeader( - nsDependentCString(entry.header), entry.value); + + nsAutoCString hdr; + if (entry.headerNameOriginal.IsEmpty()) { + hdr = nsDependentCString(entry.header); + } else { + hdr = entry.headerNameOriginal; + } + rv = visitor->VisitHeader(hdr, entry.value); if NS_FAILED(rv) { return rv; } @@ -310,6 +365,7 @@ nsHttpHeaderArray::VisitHeaders(nsIHttpHeaderVisitor *visitor, nsHttpHeaderArray /*static*/ nsresult nsHttpHeaderArray::ParseHeaderLine(const nsACString& line, nsHttpAtom *hdr, + nsACString *headerName, nsACString *val) { // @@ -360,6 +416,7 @@ nsHttpHeaderArray::ParseHeaderLine(const nsACString& line, // assign return values if (hdr) *hdr = atom; if (val) val->Assign(p, p2 - p + 1); + if (headerName) headerName->Assign(sub); return NS_OK; } @@ -397,7 +454,11 @@ nsHttpHeaderArray::Flatten(nsACString &buf, bool pruneProxyHeaders, continue; } - buf.Append(entry.header); + if (entry.headerNameOriginal.IsEmpty()) { + buf.Append(entry.header); + } else { + buf.Append(entry.headerNameOriginal); + } buf.AppendLiteral(": "); buf.Append(entry.value); buf.AppendLiteral("\r\n"); @@ -415,7 +476,12 @@ nsHttpHeaderArray::FlattenOriginalHeader(nsACString &buf) continue; } - buf.Append(entry.header); + if (entry.headerNameOriginal.IsEmpty()) { + buf.Append(entry.header); + } else { + buf.Append(entry.headerNameOriginal); + } + buf.AppendLiteral(": "); buf.Append(entry.value); buf.AppendLiteral("\r\n"); @@ -423,11 +489,13 @@ nsHttpHeaderArray::FlattenOriginalHeader(nsACString &buf) } const char * -nsHttpHeaderArray::PeekHeaderAt(uint32_t index, nsHttpAtom &header) const +nsHttpHeaderArray::PeekHeaderAt(uint32_t index, nsHttpAtom &header, + nsACString &headerNameOriginal) const { const nsEntry &entry = mHeaders[index]; header = entry.header; + headerNameOriginal = entry.headerNameOriginal; return entry.value.get(); } diff --git a/netwerk/protocol/http/nsHttpHeaderArray.h b/netwerk/protocol/http/nsHttpHeaderArray.h index 91b91f04aa1c..4c4b92911a5d 100644 --- a/netwerk/protocol/http/nsHttpHeaderArray.h +++ b/netwerk/protocol/http/nsHttpHeaderArray.h @@ -49,19 +49,30 @@ public: }; // Used by internal setters: to set header from network use SetHeaderFromNet + nsresult SetHeader(const nsACString &headerName, + const nsACString &value, + bool merge, HeaderVariety variety); nsresult SetHeader(nsHttpAtom header, const nsACString &value, bool merge, HeaderVariety variety); + nsresult SetHeader(nsHttpAtom header, + const nsACString &headerName, + const nsACString &value, + bool merge, HeaderVariety variety); // Used by internal setters to set an empty header - nsresult SetEmptyHeader(nsHttpAtom header, HeaderVariety variety); + nsresult SetEmptyHeader(const nsACString &headerName, HeaderVariety variety); // Merges supported headers. For other duplicate values, determines if error // needs to be thrown or 1st value kept. // For the response header we keep the original headers as well. - nsresult SetHeaderFromNet(nsHttpAtom header, const nsACString &value, + nsresult SetHeaderFromNet(nsHttpAtom header, + const nsACString &headerNameOriginal, + const nsACString &value, bool response); - nsresult SetResponseHeaderFromCache(nsHttpAtom header, const nsACString &value, + nsresult SetResponseHeaderFromCache(nsHttpAtom header, + const nsACString &headerNameOriginal, + const nsACString &value, HeaderVariety variety); nsresult GetHeader(nsHttpAtom header, nsACString &value) const; @@ -97,15 +108,17 @@ public: // parse a header line, return the header atom and a pointer to the // header value (the substring of the header line -- do not free). static nsresult ParseHeaderLine(const nsACString& line, - nsHttpAtom *header=nullptr, - nsACString* value=nullptr); + nsHttpAtom *header = nullptr, + nsACString *headerNameOriginal = nullptr, + nsACString* value = nullptr); void Flatten(nsACString &, bool pruneProxyHeaders, bool pruneTransients); void FlattenOriginalHeader(nsACString &); uint32_t Count() const { return mHeaders.Length(); } - const char *PeekHeaderAt(uint32_t i, nsHttpAtom &header) const; + const char *PeekHeaderAt(uint32_t i, nsHttpAtom &header, + nsACString &headerNameOriginal) const; void Clear(); @@ -113,6 +126,7 @@ public: struct nsEntry { nsHttpAtom header; + nsCString headerNameOriginal; nsCString value; HeaderVariety variety = eVarietyUnknown; @@ -140,7 +154,9 @@ private: int32_t LookupEntry(nsHttpAtom header, nsEntry **); nsresult MergeHeader(nsHttpAtom header, nsEntry *entry, const nsACString &value, HeaderVariety variety); - nsresult SetHeader_internal(nsHttpAtom header, const nsACString &value, + nsresult SetHeader_internal(nsHttpAtom header, + const nsACString &headerName, + const nsACString &value, HeaderVariety variety); // Header cannot be merged: only one value possible @@ -257,7 +273,11 @@ nsHttpHeaderArray::MergeHeader(nsHttpAtom header, if (entry->variety == eVarietyResponseNetOriginalAndResponse) { MOZ_ASSERT(variety == eVarietyResponse); entry->variety = eVarietyResponseNetOriginal; - nsresult rv = SetHeader_internal(header, newValue, eVarietyResponse); + // Copy entry->headerNameOriginal because in SetHeader_internal we are going + // to a new one and a realocation can happen. + nsCString headerNameOriginal = entry->headerNameOriginal; + nsresult rv = SetHeader_internal(header, headerNameOriginal, + newValue, eVarietyResponse); if (NS_FAILED(rv)) { return rv; } diff --git a/netwerk/protocol/http/nsHttpRequestHead.cpp b/netwerk/protocol/http/nsHttpRequestHead.cpp index 094a79457094..b366a8d54264 100644 --- a/netwerk/protocol/http/nsHttpRequestHead.cpp +++ b/netwerk/protocol/http/nsHttpRequestHead.cpp @@ -131,6 +131,20 @@ nsHttpRequestHead::Origin(nsACString &aOrigin) } nsresult +nsHttpRequestHead::SetHeader(const nsACString &h, const nsACString &v, + bool m /*= false*/) +{ + ReentrantMonitorAutoEnter mon(mReentrantMonitor); + + if (mInVisitHeaders) { + return NS_ERROR_FAILURE; + } + + return mHeaders.SetHeader(h, v, m, + nsHttpHeaderArray::eVarietyRequestOverride); +} + +nsresult nsHttpRequestHead::SetHeader(nsHttpAtom h, const nsACString &v, bool m /*= false*/) { @@ -158,7 +172,7 @@ nsHttpRequestHead::SetHeader(nsHttpAtom h, const nsACString &v, bool m, } nsresult -nsHttpRequestHead::SetEmptyHeader(nsHttpAtom h) +nsHttpRequestHead::SetEmptyHeader(const nsACString &h) { ReentrantMonitorAutoEnter mon(mReentrantMonitor); @@ -253,6 +267,7 @@ nsHttpRequestHead::ParseHeaderSet(const char *buffer) { ReentrantMonitorAutoEnter mon(mReentrantMonitor); nsHttpAtom hdr; + nsAutoCString headerNameOriginal; nsAutoCString val; while (buffer) { const char *eof = strchr(buffer, '\r'); @@ -262,9 +277,13 @@ nsHttpRequestHead::ParseHeaderSet(const char *buffer) if (NS_SUCCEEDED(nsHttpHeaderArray::ParseHeaderLine( nsDependentCSubstring(buffer, eof - buffer), &hdr, + &headerNameOriginal, &val))) { - mHeaders.SetHeaderFromNet(hdr, val, false); + mHeaders.SetHeaderFromNet(hdr, + headerNameOriginal, + val, + false); } buffer = eof + 1; if (*buffer == '\n') { diff --git a/netwerk/protocol/http/nsHttpRequestHead.h b/netwerk/protocol/http/nsHttpRequestHead.h index 415968083477..b7020d33a0ac 100644 --- a/netwerk/protocol/http/nsHttpRequestHead.h +++ b/netwerk/protocol/http/nsHttpRequestHead.h @@ -57,10 +57,12 @@ public: int32_t port); void Origin(nsACString &aOrigin); + nsresult SetHeader(const nsACString &h, const nsACString &v, + bool m=false); nsresult SetHeader(nsHttpAtom h, const nsACString &v, bool m=false); nsresult SetHeader(nsHttpAtom h, const nsACString &v, bool m, nsHttpHeaderArray::HeaderVariety variety); - nsresult SetEmptyHeader(nsHttpAtom h); + nsresult SetEmptyHeader(const nsACString &h); nsresult GetHeader(nsHttpAtom h, nsACString &v); nsresult ClearHeader(nsHttpAtom h); diff --git a/netwerk/protocol/http/nsHttpResponseHead.cpp b/netwerk/protocol/http/nsHttpResponseHead.cpp index 6d384c48872e..fa6430b8231f 100644 --- a/netwerk/protocol/http/nsHttpResponseHead.cpp +++ b/netwerk/protocol/http/nsHttpResponseHead.cpp @@ -137,6 +137,26 @@ nsHttpResponseHead::Immutable() } nsresult +nsHttpResponseHead::SetHeader(const nsACString &hdr, + const nsACString &val, + bool merge) +{ + ReentrantMonitorAutoEnter monitor(mReentrantMonitor); + + if (mInVisitHeaders) { + return NS_ERROR_FAILURE; + } + + nsHttpAtom atom = nsHttp::ResolveAtom(PromiseFlatCString(hdr).get()); + if (!atom) { + NS_WARNING("failed to resolve atom"); + return NS_ERROR_NOT_AVAILABLE; + } + + return SetHeader_locked(atom, hdr, val, merge); +} + +nsresult nsHttpResponseHead::SetHeader(nsHttpAtom hdr, const nsACString &val, bool merge) @@ -147,24 +167,25 @@ nsHttpResponseHead::SetHeader(nsHttpAtom hdr, return NS_ERROR_FAILURE; } - return SetHeader_locked(hdr, val, merge); + return SetHeader_locked(hdr, EmptyCString(), val, merge); } nsresult -nsHttpResponseHead::SetHeader_locked(nsHttpAtom hdr, +nsHttpResponseHead::SetHeader_locked(nsHttpAtom atom, + const nsACString &hdr, const nsACString &val, bool merge) { - nsresult rv = mHeaders.SetHeader(hdr, val, merge, + nsresult rv = mHeaders.SetHeader(atom, hdr, val, merge, nsHttpHeaderArray::eVarietyResponse); if (NS_FAILED(rv)) return rv; // respond to changes in these headers. we need to reparse the entire // header since the change may have merged in additional values. - if (hdr == nsHttp::Cache_Control) - ParseCacheControl(mHeaders.PeekHeader(hdr)); - else if (hdr == nsHttp::Pragma) - ParsePragma(mHeaders.PeekHeader(hdr)); + if (atom == nsHttp::Cache_Control) + ParseCacheControl(mHeaders.PeekHeader(atom)); + else if (atom == nsHttp::Pragma) + ParsePragma(mHeaders.PeekHeader(atom)); return NS_OK; } @@ -316,6 +337,7 @@ nsHttpResponseHead::ParseCachedOriginalHeaders(char *block) char *p = block; nsHttpAtom hdr = {0}; + nsAutoCString headerNameOriginal; nsAutoCString val; nsresult rv; @@ -331,12 +353,13 @@ nsHttpResponseHead::ParseCachedOriginalHeaders(char *block) *p = 0; if (NS_FAILED(nsHttpHeaderArray::ParseHeaderLine( - nsDependentCString(block, p - block), &hdr, &val))) { + nsDependentCString(block, p - block), &hdr, &headerNameOriginal, &val))) { return NS_OK; } rv = mHeaders.SetResponseHeaderFromCache(hdr, + headerNameOriginal, val, nsHttpHeaderArray::eVarietyResponseNetOriginal); @@ -567,18 +590,21 @@ nsresult nsHttpResponseHead::ParseHeaderLine_locked(const nsACString &line, bool originalFromNetHeaders) { nsHttpAtom hdr = {0}; + nsAutoCString headerNameOriginal; nsAutoCString val; - if (NS_FAILED(nsHttpHeaderArray::ParseHeaderLine(line, &hdr, &val))) { + if (NS_FAILED(nsHttpHeaderArray::ParseHeaderLine(line, &hdr, &headerNameOriginal, &val))) { return NS_OK; } nsresult rv; if (originalFromNetHeaders) { rv = mHeaders.SetHeaderFromNet(hdr, + headerNameOriginal, val, true); } else { rv = mHeaders.SetResponseHeaderFromCache(hdr, + headerNameOriginal, val, nsHttpHeaderArray::eVarietyResponse); } @@ -856,7 +882,8 @@ nsHttpResponseHead::UpdateHeaders(nsHttpResponseHead *aOther) uint32_t i, count = aOther->mHeaders.Count(); for (i=0; i<count; ++i) { nsHttpAtom header; - const char *val = aOther->mHeaders.PeekHeaderAt(i, header); + nsAutoCString headerNameOriginal; + const char *val = aOther->mHeaders.PeekHeaderAt(i, header, headerNameOriginal); if (!val) { continue; @@ -890,7 +917,8 @@ nsHttpResponseHead::UpdateHeaders(nsHttpResponseHead *aOther) LOG(("new response header [%s: %s]\n", header.get(), val)); // overwrite the current header value with the new value... - SetHeader_locked(header, nsDependentCString(val)); + SetHeader_locked(header, headerNameOriginal, + nsDependentCString(val)); } } diff --git a/netwerk/protocol/http/nsHttpResponseHead.h b/netwerk/protocol/http/nsHttpResponseHead.h index 0a912f4b403b..8b51386ea229 100644 --- a/netwerk/protocol/http/nsHttpResponseHead.h +++ b/netwerk/protocol/http/nsHttpResponseHead.h @@ -65,6 +65,8 @@ public: */ int64_t TotalEntitySize(); + nsresult SetHeader(const nsACString &h, const nsACString &v, + bool m=false); nsresult SetHeader(nsHttpAtom h, const nsACString &v, bool m=false); nsresult GetHeader(nsHttpAtom h, nsACString &v); void ClearHeader(nsHttpAtom h); @@ -137,8 +139,8 @@ public: bool HasContentType(); bool HasContentCharset(); private: - nsresult SetHeader_locked(nsHttpAtom h, const nsACString &v, - bool m=false); + nsresult SetHeader_locked(nsHttpAtom atom, const nsACString &h, + const nsACString &v, bool m=false); void AssignDefaultStatusText(); void ParseVersion(const char *); void ParseCacheControl(const char *); diff --git a/netwerk/test/unit/test_bug1064258.js b/netwerk/test/unit/test_bug1064258.js index 3f76837ae935..da982c2d6f07 100644 --- a/netwerk/test/unit/test_bug1064258.js +++ b/netwerk/test/unit/test_bug1064258.js @@ -133,7 +133,7 @@ function cacheCheck2(status, entry) do_check_eq(entry.dataSize, 0); try { do_check_neq(entry.getMetaDataElement("response-head"), null); - do_check_true(entry.getMetaDataElement("response-head").match('Etag: testetag')); + do_check_true(entry.getMetaDataElement("response-head").match('etag: testetag')); } catch (ex) { do_throw("Missing response head"); diff --git a/netwerk/test/unit/test_original_sent_received_head.js b/netwerk/test/unit/test_original_sent_received_head.js index c4d02d5d2299..eab359a108ae 100644 --- a/netwerk/test/unit/test_original_sent_received_head.js +++ b/netwerk/test/unit/test_original_sent_received_head.js @@ -114,11 +114,11 @@ function checkResponse(request, data, context) { var locationHeaderFound = 0; request.visitResponseHeaders({ visitHeader: function visit(aName, aValue) { - if (aName == "Link") { + if (aName == "link") { linkHeaderFound++; do_check_eq(aValue, "value1, value2"); } - if (aName == "Location") { + if (aName == "location") { locationHeaderFound++; do_check_eq(aValue, "loc"); } @@ -132,7 +132,7 @@ function checkResponse(request, data, context) { var locationOrgHeaderFound = 0; request.visitOriginalResponseHeaders({ visitHeader: function visitOrg(aName, aValue) { - if (aName == "Link") { + if (aName == "link") { if (linkOrgHeaderFound == 0) { do_check_eq(aValue, ""); } else if (linkOrgHeaderFound == 1 ) { @@ -142,7 +142,7 @@ function checkResponse(request, data, context) { } linkOrgHeaderFound++; } - if (aName == "Location") { + if (aName == "location") { locationOrgHeaderFound++; do_check_eq(aValue, "loc"); } @@ -176,7 +176,7 @@ function checkResponse(request, data, context) { var locationOrgHeaderFound2 = 0; request.visitOriginalResponseHeaders({ visitHeader: function visitOrg(aName, aValue) { - if (aName == "Link") { + if (aName == "link") { if (linkOrgHeaderFound2 == 0) { do_check_eq(aValue, ""); } else if (linkOrgHeaderFound2 == 1 ) { @@ -186,7 +186,7 @@ function checkResponse(request, data, context) { } linkOrgHeaderFound2++; } - if (aName == "Location") { + if (aName == "location") { locationOrgHeaderFound2++; do_check_eq(aValue, "loc"); } @@ -199,7 +199,7 @@ function checkResponse(request, data, context) { if (dbg) { print("============== Test GetResponseHeader"); } var linkOrgHeaderFound3 = 0; - request.getOriginalResponseHeader("Link",{ + request.getOriginalResponseHeader("link",{ visitHeader: function visitOrg(aName, aValue) { if (linkOrgHeaderFound3 == 0) { do_check_eq(aValue, "");
1 0
0 0
  • ← Newer
  • 1
  • ...
  • 1685
  • 1686
  • 1687
  • 1688
  • 1689
  • 1690
  • 1691
  • ...
  • 2064
  • Older →

HyperKitty Powered by HyperKitty version 1.3.12.