This commit is contained in:
Wes Kocher 2016-06-24 13:41:56 -07:00
Родитель 3b8f6019c4 ef24c234ed
Коммит bf02c9e2f4
51 изменённых файлов: 1261 добавлений и 578 удалений

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

@ -105,7 +105,7 @@ Link::TryDNSPrefetchPreconnectOrPrefetch()
nsCOMPtr<nsIDOMNode> domNode = GetAsDOMNode(mElement);
prefetchService->PrefetchURI(uri,
mElement->OwnerDoc()->GetDocumentURI(),
domNode, true);
domNode, linkTypes & nsStyleLinkElement::ePREFETCH);
return;
}
}

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

@ -160,7 +160,9 @@ nsContentPolicy::CheckPolicy(CPMethod policyMethod,
if (window) {
nsCOMPtr<nsIDocShell> docShell = window->GetDocShell();
nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(docShell);
loadContext->GetTopFrameElement(getter_AddRefs(topFrameElement));
if (loadContext) {
loadContext->GetTopFrameElement(getter_AddRefs(topFrameElement));
}
MOZ_ASSERT(window->IsOuterWindow());

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

@ -17,6 +17,7 @@
#include "mozilla/css/Loader.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/FragmentOrElement.h"
#include "mozilla/dom/HTMLLinkElement.h"
#include "mozilla/dom/ShadowRoot.h"
#include "mozilla/dom/SRILogHelper.h"
#include "mozilla/Preferences.h"
@ -435,13 +436,22 @@ nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
NS_ConvertUTF16toUTF8(integrity).get()));
}
// if referrer attributes are enabled in preferences, load the link's referrer
// attribute. If the link does not provide a referrer attribute, ignore this
// and use the document's referrer policy
net::ReferrerPolicy referrerPolicy = GetLinkReferrerPolicy();
if (referrerPolicy == net::RP_Unset) {
referrerPolicy = doc->GetReferrerPolicy();
}
// XXXbz clone the URI here to work around content policies modifying URIs.
nsCOMPtr<nsIURI> clonedURI;
uri->Clone(getter_AddRefs(clonedURI));
NS_ENSURE_TRUE(clonedURI, NS_ERROR_OUT_OF_MEMORY);
rv = doc->CSSLoader()->
LoadStyleLink(thisContent, clonedURI, title, media, isAlternate,
GetCORSMode(), doc->GetReferrerPolicy(), integrity,
GetCORSMode(), referrerPolicy, integrity,
aObserver, &isAlternate);
if (NS_FAILED(rv)) {
// Don't propagate LoadStyleLink() errors further than this, since some

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

@ -16,6 +16,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/CORSMode.h"
#include "mozilla/CSSStyleSheet.h"
#include "mozilla/net/ReferrerPolicy.h"
#include "nsCOMPtr.h"
#include "nsIStyleSheetLinkingElement.h"
#include "nsTArray.h"
@ -113,6 +114,11 @@ protected:
return mozilla::CORS_NONE;
}
virtual mozilla::net::ReferrerPolicy GetLinkReferrerPolicy()
{
return mozilla::net::RP_Unset;
}
// CC methods
void Unlink();
void Traverse(nsCycleCollectionTraversalCallback &cb);

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

@ -735,6 +735,9 @@ skip-if = e10s || os != 'linux' || buildapp != 'browser' # Already tests multipr
[test_innersize_scrollport.html]
[test_integer_attr_with_leading_zero.html]
[test_ipc_messagemanager_blob.html]
[test_link_prefetch.html]
skip-if = !e10s # Track Bug 1281415
[test_link_stylesheet.html]
[test_messagemanager_targetchain.html]
[test_meta_viewport0.html]
skip-if = (os != 'b2g' && os != 'android') # meta-viewport tag support is mobile-only

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

@ -152,6 +152,61 @@ function createRedirectImgTestCase(aParams, aAttributePolicy) {
</html>`;
}
// test page using link referrer attribute
function createLinkPageUsingRefferer(aMetaPolicy, aAttributePolicy, aNewAttributePolicy, aName, aRel, aStringBuilder, aSchemeFrom, aSchemeTo, aTestType) {
var metaString = "";
if (aMetaPolicy) {
metaString = `<meta name="referrer" content="${aMetaPolicy}">`;
}
var relString = "";
if (aRel) {
relString = `rel=${aRel}`;
}
var changeString = "";
var policy = aAttributePolicy ? aAttributePolicy : aMetaPolicy;
var elementString = aStringBuilder(policy, aName, relString, aSchemeFrom, aSchemeTo, aTestType);
if (aTestType === "setAttribute") {
changeString = `var link = document.getElementById("test_link");
link.setAttribute("referrerpolicy", "${aNewAttributePolicy}");
link.href = "${createTestUrl(policy, "test", aName, "link_element", aSchemeFrom, aSchemeTo)}";`;
} else if (aTestType === "property") {
changeString = `var link = document.getElementById("test_link");
link.referrerPolicy = "${aNewAttributePolicy}";
link.href = "${createTestUrl(policy, "test", aName, "link_element", aSchemeFrom, aSchemeTo)}";`;
}
return `<!DOCTYPE HTML>
<html>
<head>
${metaString}
${elementString}
</head>
<body>
<script>
${changeString}
</script>
</body>
</html>`;
}
function buildLinkString(aPolicy, aName, aRelString, aSchemeFrom, aSchemeTo, aTestType) {
var result;
var href = '';
var onChildComplete = `window.parent.postMessage("childLoadComplete", "http://mochi.test:8888");`
if (!aTestType) {
href = `href=${createTestUrl(aPolicy, "test", aName, "link_element", aSchemeFrom, aSchemeTo)}`;
}
if (!aPolicy) {
result = `<link ${aRelString} ${href} id="test_link" onload='${onChildComplete}' onerror='${onChildComplete}'>`;
} else {
result = `<link ${aRelString} ${href} referrerpolicy=${aPolicy} id="test_link" onload='${onChildComplete}' onerror='${onChildComplete}'>`;
}
return result;
}
function handleRequest(request, response) {
var params = new URLSearchParams(request.queryString);
var action = params.get("ACTION");
@ -314,6 +369,23 @@ function handleRequest(request, response) {
return;
}
var _getPage = createLinkPageUsingRefferer.bind(null, metaPolicy, attributePolicy, newAttributePolicy, name, rel);
var _getLinkPage = _getPage.bind(null, buildLinkString, schemeFrom, schemeTo);
// link
if (action === "generate-link-policy-test") {
response.write(_getLinkPage());
return;
}
if (action === "generate-link-policy-test-set-attribute") {
response.write(_getLinkPage("setAttribute"));
return;
}
if (action === "generate-link-policy-test-property") {
response.write(_getLinkPage("property"));
return;
}
response.write("I don't know action " + action);
return;
}

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

@ -0,0 +1,176 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test link policy attribute for Bug 1264165</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<!--
Testing that link referrer attributes are honoured correctly
https://bugzilla.mozilla.org/show_bug.cgi?id=1264165
-->
<script type="application/javascript;version=1.8">
const SJS = "://example.com/tests/dom/base/test/referrer_testserver.sjs?";
const PARAMS = ["ATTRIBUTE_POLICY", "NEW_ATTRIBUTE_POLICY", "META_POLICY", "REL", "SCHEME_FROM", "SCHEME_TO"];
const testCases = [
{ACTION: ["generate-link-policy-test"],
TESTS: [
{ATTRIBUTE_POLICY: 'unsafe-url',
NAME: 'prefetch-unsafe-url-with-origin-in-meta',
META_POLICY: 'origin',
REL: 'prefetch',
DESC: "prefetch-unsafe-url with origin in meta",
RESULT: 'full'},
{ATTRIBUTE_POLICY: 'origin',
NAME: 'prefetch-origin-with-unsafe-url-in-meta',
META_POLICY: 'unsafe-url',
REL: 'prefetch',
DESC: "prefetch-origin with unsafe-url in meta",
RESULT: 'origin'},
{ATTRIBUTE_POLICY: 'no-referrer',
NAME: 'prefetch-no-referrer-with-origin-in-meta',
META_POLICY: 'origin',
REL: 'prefetch',
DESC: "prefetch-no-referrer with origin in meta",
RESULT: 'none'},
{NAME: 'prefetch-no-referrer-in-meta',
META_POLICY: 'no-referrer',
REL: 'prefetch',
DESC: "prefetch-no-referrer in meta",
RESULT: 'none'},
// Downgrade.
{ATTRIBUTE_POLICY: 'no-referrer-when-downgrade',
NAME: 'prefetch-origin-in-meta-downgrade-in-attr',
META_POLICY: 'origin',
DESC: 'prefetch-origin in meta downgrade in attr',
REL: 'prefetch',
SCHEME_FROM: 'https',
SCHEME_TO: 'http',
RESULT: 'none'},
// No downgrade.
{ATTRIBUTE_POLICY: 'no-referrer-when-downgrade',
NAME: 'prefetch-origin-in-meta-downgrade-in-attr',
META_POLICY: 'origin',
DESC: 'prefetch-origin in meta downgrade in attr',
REL: 'prefetch',
SCHEME_FROM: 'https',
SCHEME_TO: 'https',
RESULT: 'full'},
{ATTRIBUTE_POLICY: 'origin',
NAME: 'prefetch-origin-with-no-meta',
META_POLICY: '',
REL: 'prefetch',
DESC: "prefetch-origin with no meta",
RESULT: 'origin'},
// Cross origin
{ATTRIBUTE_POLICY: 'origin-when-cross-origin',
NAME: 'prefetch-origin-when-cross-origin-with-no-meta',
META_POLICY: '',
SCHEME_FROM: 'https',
SCHEME_TO: 'http',
REL: 'prefetch',
DESC: "prefetch-origin-when-cross-origin with no meta",
RESULT: 'origin'},
{ATTRIBUTE_POLICY: 'origin-when-cross-origin',
NAME: 'prefetch-origin-when-cross-origin-with-no-referrer-in-meta',
META_POLICY: 'no-referrer',
SCHEME_FROM: 'https',
SCHEME_TO: 'http',
REL: 'prefetch',
DESC: "prefetch-origin-when-cross-origin with no-referrer in meta",
RESULT: 'origin'},
{ATTRIBUTE_POLICY: 'origin-when-cross-origin',
NAME: 'prefetch-origin-when-cross-origin-with-unsafe-url-in-meta',
META_POLICY: 'unsafe-url',
SCHEME_FROM: 'https',
SCHEME_TO: 'http',
REL: 'prefetch',
DESC: "prefetch-origin-when-cross-origin with unsafe-url in meta",
RESULT: 'origin'},
{ATTRIBUTE_POLICY: 'origin-when-cross-origin',
NAME: 'prefetch-origin-when-cross-origin-with-origin-in-meta',
META_POLICY: 'origin',
SCHEME_FROM: 'https',
SCHEME_TO: 'http',
REL: 'prefetch',
DESC: "prefetch-origin-when-cross-origin with origin in meta",
RESULT: 'origin'},
// Invalid
{ATTRIBUTE_POLICY: 'default',
NAME: 'prefetch-default-with-no-meta',
META_POLICY: '',
REL: 'prefetch',
DESC: "prefetch-default with no meta",
RESULT: 'full'},
{ATTRIBUTE_POLICY: 'something',
NAME: 'prefetch-something-with-no-meta',
META_POLICY: '',
REL: 'prefetch',
DESC: "prefetch-something with no meta",
RESULT: 'full'},
]},
{ACTION: ["generate-link-policy-test-set-attribute"],
TESTS: [
{ATTRIBUTE_POLICY: 'unsafe-url',
NEW_ATTRIBUTE_POLICY: 'no-referrer',
NAME: 'prefetch-no-referrer-unsafe-url-set-attribute-with-origin-in-meta',
META_POLICY: 'origin',
REL: 'prefetch',
DESC: "prefetch-no-referrer-set-attribute (orginally unsafe-url) with origin in meta",
RESULT: 'none'},
{ATTRIBUTE_POLICY: 'origin',
NEW_ATTRIBUTE_POLICY: 'unsafe-url',
NAME: 'prefetch-unsafe-url-origin-set-attribute-with-no-referrer-in-meta',
META_POLICY: 'no-referrer',
REL: 'prefetch',
DESC: "prefetch-unsafe-url-set-attribute(orginally origin) with no-referrer in meta",
RESULT: 'full'},
]},
{ACTION: ["generate-link-policy-test-property"],
TESTS: [
{ATTRIBUTE_POLICY: 'no-referrer',
NEW_ATTRIBUTE_POLICY: 'unsafe-url',
NAME: 'prefetch-unsafe-url-no-referrer-property-with-origin-in-meta',
META_POLICY: 'origin',
REL: 'prefetch',
DESC: "prefetch-unsafe-url-property (orginally no-referrer) with origin in meta",
RESULT: 'full'},
{ATTRIBUTE_POLICY: 'origin',
NEW_ATTRIBUTE_POLICY: 'unsafe-url',
NAME: 'prefetch-unsafe-url-origin-property-with-no-referrer-in-meta',
META_POLICY: 'no-referrer',
REL: 'prefetch',
DESC: "prefetch-unsafe-url-property (orginally origin) with no-referrer in meta",
RESULT: 'full'},
]},
];
</script>
<script type="application/javascript;version=1.7" src="/tests/dom/base/test/referrer_helper.js"></script>
</head>
<body onload="tests.next();">
<script type="application/javascript;version=1.7">
/**
* Listen for notifications that pretching finishes.
* XXX Bug 1268962 - Fire load/error events on <link rel="prefetch">
* Because there's no onload/onerror event fired, we catch prefetch-load-completed
* to test
* Simply remove this after bug 1268962 is fixed
*/
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
SpecialPowers.Services.obs.addObserver(function() { tests.next(); }, "prefetch-load-completed", false);
</script>
<iframe id="testframe"></iframe>
</body>
</html>

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

@ -0,0 +1,166 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test link policy attribute for Bug 1264165</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<!--
Testing that link referrer attributes are honoured correctly
https://bugzilla.mozilla.org/show_bug.cgi?id=1264165
-->
<script type="application/javascript;version=1.8">
const SJS = "://example.com/tests/dom/base/test/referrer_testserver.sjs?";
const PARAMS = ["ATTRIBUTE_POLICY", "NEW_ATTRIBUTE_POLICY", "META_POLICY", "REL", "SCHEME_FROM", "SCHEME_TO"];
const testCases = [
{ACTION: ["generate-link-policy-test"],
TESTS: [
{ATTRIBUTE_POLICY: 'unsafe-url',
NAME: 'stylesheet-unsafe-url-with-origin-in-meta',
META_POLICY: 'origin',
REL: 'stylesheet',
DESC: "stylesheet-unsafe-url with origin in meta",
RESULT: 'full'},
{ATTRIBUTE_POLICY: 'origin',
NAME: 'stylesheet-origin-with-unsafe-url-in-meta',
META_POLICY: 'unsafe-url',
REL: 'stylesheet',
DESC: "stylesheet-origin with unsafe-url in meta",
RESULT: 'origin'},
{ATTRIBUTE_POLICY: 'no-referrer',
NAME: 'stylesheet-no-referrer-with-origin-in-meta',
META_POLICY: 'origin',
REL: 'stylesheet',
DESC: "stylesheet-no-referrer with origin in meta",
RESULT: 'none'},
{NAME: 'stylesheet-no-referrer-in-meta',
META_POLICY: 'no-referrer',
REL: 'stylesheet',
DESC: "stylesheet-no-referrer in meta",
RESULT: 'none'},
// Downgrade.
{ATTRIBUTE_POLICY: 'no-referrer-when-downgrade',
NAME: 'stylesheet-origin-in-meta-downgrade-in-attr',
META_POLICY: 'origin',
DESC: 'stylesheet-origin in meta downgrade in attr',
REL: 'stylesheet',
SCHEME_FROM: 'https',
SCHEME_TO: 'http',
RESULT: 'none'},
// No downgrade.
{ATTRIBUTE_POLICY: 'no-referrer-when-downgrade',
NAME: 'stylesheet-origin-in-meta-downgrade-in-attr',
META_POLICY: 'origin',
DESC: 'stylesheet-origin in meta downgrade in attr',
REL: 'stylesheet',
SCHEME_FROM: 'https',
SCHEME_TO: 'https',
RESULT: 'full'},
{ATTRIBUTE_POLICY: 'origin',
NAME: 'stylesheet-origin-with-no-meta',
META_POLICY: '',
REL: 'stylesheet',
DESC: "stylesheet-origin with no meta",
RESULT: 'origin'},
// Cross origin
{ATTRIBUTE_POLICY: 'origin-when-cross-origin',
NAME: 'stylesheet-origin-when-cross-origin-with-no-meta',
META_POLICY: '',
SCHEME_FROM: 'https',
SCHEME_TO: 'http',
REL: 'stylesheet',
DESC: "stylesheet-origin-when-cross-origin with no meta",
RESULT: 'origin'},
{ATTRIBUTE_POLICY: 'origin-when-cross-origin',
NAME: 'stylesheet-origin-when-cross-origin-with-no-referrer-in-meta',
META_POLICY: 'no-referrer',
SCHEME_FROM: 'https',
SCHEME_TO: 'http',
REL: 'stylesheet',
DESC: "stylesheet-origin-when-cross-origin with no-referrer in meta",
RESULT: 'origin'},
{ATTRIBUTE_POLICY: 'origin-when-cross-origin',
NAME: 'stylesheet-origin-when-cross-origin-with-unsafe-url-in-meta',
META_POLICY: 'unsafe-url',
SCHEME_FROM: 'https',
SCHEME_TO: 'http',
REL: 'stylesheet',
DESC: "stylesheet-origin-when-cross-origin with unsafe-url in meta",
RESULT: 'origin'},
{ATTRIBUTE_POLICY: 'origin-when-cross-origin',
NAME: 'stylesheet-origin-when-cross-origin-with-origin-in-meta',
META_POLICY: 'origin',
SCHEME_FROM: 'https',
SCHEME_TO: 'http',
REL: 'stylesheet',
DESC: "stylesheet-origin-when-cross-origin with origin in meta",
RESULT: 'origin'},
// Invalid
{ATTRIBUTE_POLICY: 'default',
NAME: 'stylesheet-default-with-no-meta',
META_POLICY: '',
REL: 'stylesheet',
DESC: "stylesheet-default with no meta",
RESULT: 'full'},
{ATTRIBUTE_POLICY: 'something',
NAME: 'stylesheet-something-with-no-meta',
META_POLICY: '',
REL: 'stylesheet',
DESC: "stylesheet-something with no meta",
RESULT: 'full'},
]},
{ACTION: ["generate-link-policy-test-set-attribute"],
TESTS: [
{ATTRIBUTE_POLICY: 'unsafe-url',
NEW_ATTRIBUTE_POLICY: 'no-referrer',
NAME: 'stylesheet-no-referrer-unsafe-url-set-attribute-with-origin-in-meta',
META_POLICY: 'origin',
REL: 'stylesheet',
DESC: "stylesheet-no-referrer-set-attribute (orginally unsafe-url) with origin in meta",
RESULT: 'none'},
{ATTRIBUTE_POLICY: 'origin',
NEW_ATTRIBUTE_POLICY: 'unsafe-url',
NAME: 'stylesheet-unsafe-url-origin-set-attribute-with-no-referrer-in-meta',
META_POLICY: 'no-referrer',
REL: 'stylesheet',
DESC: "stylesheet-unsafe-url-set-attribute (orginally origin) with no-referrer in meta",
RESULT: 'full'},
]},
{ACTION: ["generate-link-policy-test-property"],
TESTS: [
{ATTRIBUTE_POLICY: 'no-referrer',
NEW_ATTRIBUTE_POLICY: 'unsafe-url',
NAME: 'stylesheet-unsafe-url-no-referrer-property-with-origin-in-meta',
META_POLICY: 'origin',
REL: 'stylesheet',
DESC: "stylesheet-unsafe-url-property (orginally no-referrer) with origin in meta",
RESULT: 'full'},
{ATTRIBUTE_POLICY: 'origin',
NEW_ATTRIBUTE_POLICY: 'unsafe-url',
NAME: 'stylesheet-unsafe-url-origin-property-with-no-referrer-in-meta',
META_POLICY: 'no-referrer',
REL: 'stylesheet',
DESC: "stylesheet-unsafe-url-property (orginally origin) with no-referrer in meta",
RESULT: 'full'},
]},
];
</script>
<script type="application/javascript;version=1.7" src="/tests/dom/base/test/referrer_helper.js"></script>
</head>
<body onload="tests.next();">
<iframe id="testframe"></iframe>
</body>
</html>

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

@ -150,6 +150,18 @@ public:
{
SetHTMLAttr(nsGkAtoms::integrity, aIntegrity, aRv);
}
void SetReferrerPolicy(const nsAString& aReferrer, ErrorResult& aError)
{
SetHTMLAttr(nsGkAtoms::referrerpolicy, aReferrer, aError);
}
void GetReferrerPolicy(nsAString& aReferrer)
{
GetEnumAttr(nsGkAtoms::referrerpolicy, EmptyCString().get(), aReferrer);
}
mozilla::net::ReferrerPolicy GetLinkReferrerPolicy() override
{
return GetReferrerPolicyAsEnum();
}
already_AddRefed<nsIDocument> GetImport();
already_AddRefed<ImportLoader> GetImportLoader()

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

@ -514,7 +514,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(HTMLMediaElement)
NS_INTERFACE_MAP_ENTRY(nsIDOMHTMLMediaElement)
NS_INTERFACE_MAP_ENTRY(nsIObserver)
NS_INTERFACE_MAP_ENTRY(nsIAudioChannelAgentCallback)
NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElement)
@ -2250,10 +2249,48 @@ HTMLMediaElement::LookupMediaElementURITable(nsIURI* aURI)
return nullptr;
}
class HTMLMediaElement::ShutdownObserver : public nsIObserver {
public:
NS_DECL_ISUPPORTS
NS_IMETHOD Observe(nsISupports*, const char* aTopic, const char16_t*) override {
MOZ_DIAGNOSTIC_ASSERT(mWeak);
if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
mWeak->NotifyShutdownEvent();
}
return NS_OK;
}
void Subscribe(HTMLMediaElement* aPtr) {
MOZ_DIAGNOSTIC_ASSERT(!mWeak);
mWeak = aPtr;
nsContentUtils::RegisterShutdownObserver(this);
}
void Unsubscribe() {
MOZ_DIAGNOSTIC_ASSERT(mWeak);
mWeak = nullptr;
nsContentUtils::UnregisterShutdownObserver(this);
}
void AddRefMediaElement() {
mWeak->AddRef();
}
void ReleaseMediaElement() {
mWeak->Release();
}
private:
virtual ~ShutdownObserver() {
MOZ_DIAGNOSTIC_ASSERT(!mWeak);
}
// Guaranteed to be valid by HTMLMediaElement.
HTMLMediaElement* mWeak = nullptr;
};
NS_IMPL_ISUPPORTS(HTMLMediaElement::ShutdownObserver, nsIObserver)
HTMLMediaElement::HTMLMediaElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
: nsGenericHTMLElement(aNodeInfo),
mWatchManager(this, AbstractThread::MainThread()),
mSrcStreamPausedCurrentTime(-1),
mShutdownObserver(new ShutdownObserver),
mCurrentLoadID(0),
mNetworkState(nsIDOMHTMLMediaElement::NETWORK_EMPTY),
mReadyState(nsIDOMHTMLMediaElement::HAVE_NOTHING, "HTMLMediaElement::mReadyState"),
@ -2330,6 +2367,8 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed<mozilla::dom::NodeInfo>& aNo
// Paradoxically, there is a self-edge whereby UpdateReadyStateInternal refuses
// to run until mReadyState reaches at least HAVE_METADATA by some other means.
mWatchManager.Watch(mReadyState, &HTMLMediaElement::UpdateReadyStateInternal);
mShutdownObserver->Subscribe(this);
}
HTMLMediaElement::~HTMLMediaElement()
@ -2337,6 +2376,8 @@ HTMLMediaElement::~HTMLMediaElement()
NS_ASSERTION(!mHasSelfReference,
"How can we be destroyed if we're still holding a self reference?");
mShutdownObserver->Unsubscribe();
if (mVideoFrameContainer) {
mVideoFrameContainer->ForgetElement();
}
@ -4248,6 +4289,10 @@ bool HTMLMediaElement::IsHidden() const
VideoFrameContainer* HTMLMediaElement::GetVideoFrameContainer()
{
if (mShuttingDown) {
return nullptr;
}
if (mVideoFrameContainer)
return mVideoFrameContainer;
@ -4605,10 +4650,10 @@ void HTMLMediaElement::AddRemoveSelfReference()
if (needSelfReference != mHasSelfReference) {
mHasSelfReference = needSelfReference;
if (needSelfReference) {
// The observer service will hold a strong reference to us. This
// The shutdown observer will hold a strong reference to us. This
// will do to keep us alive. We need to know about shutdown so that
// we can release our self-reference.
nsContentUtils::RegisterShutdownObserver(this);
mShutdownObserver->AddRefMediaElement();
} else {
// Dispatch Release asynchronously so that we don't destroy this object
// inside a call stack of method calls on this object
@ -4623,19 +4668,14 @@ void HTMLMediaElement::AddRemoveSelfReference()
void HTMLMediaElement::DoRemoveSelfReference()
{
// We don't need the shutdown observer anymore. Unregistering releases
// its reference to us, which we were using as our self-reference.
nsContentUtils::UnregisterShutdownObserver(this);
mShutdownObserver->ReleaseMediaElement();
}
nsresult HTMLMediaElement::Observe(nsISupports* aSubject,
const char* aTopic, const char16_t* aData)
void HTMLMediaElement::NotifyShutdownEvent()
{
if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
mShuttingDown = true;
AddRemoveSelfReference();
}
return NS_OK;
mShuttingDown = true;
ResetState();
AddRemoveSelfReference();
}
bool

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

@ -79,7 +79,6 @@ class VideoTrackList;
class HTMLMediaElement : public nsGenericHTMLElement,
public nsIDOMHTMLMediaElement,
public nsIObserver,
public MediaDecoderOwner,
public nsIAudioChannelAgentCallback,
public PrincipalChangeObserver<DOMMediaStream>
@ -114,8 +113,6 @@ public:
// nsIDOMHTMLMediaElement
NS_DECL_NSIDOMHTMLMEDIAELEMENT
NS_DECL_NSIOBSERVER
NS_DECL_NSIAUDIOCHANNELAGENTCALLBACK
// nsISupports
@ -740,6 +737,7 @@ protected:
class MediaStreamTrackListener;
class StreamListener;
class StreamSizeListener;
class ShutdownObserver;
MediaDecoderOwner::NextFrameStatus NextFrameStatus();
void SetDecoder(MediaDecoder* aDecoder) {
@ -987,6 +985,11 @@ protected:
*/
void DoRemoveSelfReference();
/**
* Called when "xpcom-shutdown" event is received.
*/
void NotifyShutdownEvent();
/**
* Possible values of the 'preload' attribute.
*/
@ -1240,6 +1243,8 @@ protected:
// mSrcStream.
RefPtr<StreamSizeListener> mMediaStreamSizeListener;
const RefPtr<ShutdownObserver> mShutdownObserver;
// Holds a reference to the MediaSource, if any, referenced by the src
// attribute on the media element.
RefPtr<MediaSource> mSrcMediaSource;

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

@ -8,7 +8,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1260664
<title>Test for Bug 1260664</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="reflect.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1260664">Mozilla Bug 1260664</a>
@ -25,7 +24,7 @@ SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(runTests);
function runTests() {
var elements = [ "iframe", "img", "a", "area" ];
var elements = [ "iframe", "img", "a", "area", "link" ];
for (var i = 0; i < elements.length; ++i) {
reflectLimitedEnumerated({

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

@ -1,7 +1,6 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
CheckMessage = Remember this decision
CheckLoadURIError = Security Error: Content at %S may not load or link to %S.
CheckSameOriginError = Security Error: Content at %S may not load data from %S.
ExternalDataError = Security Error: Content at %S attempted to load %S, but may not load external data when being used as an image.

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

@ -653,6 +653,7 @@ MediaDecoder::Shutdown()
// the hashtable iterating in MediaShutdownManager::Shutdown().
RefPtr<MediaDecoder> self = this;
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([self] () {
self->mVideoFrameContainer = nullptr;
MediaShutdownManager::Instance().Unregister(self);
});
AbstractThread::MainThread()->Dispatch(r.forget());
@ -706,6 +707,7 @@ MediaDecoder::FinishShutdown()
MOZ_ASSERT(NS_IsMainThread());
mDecoderStateMachine->BreakCycles();
SetStateMachine(nullptr);
mVideoFrameContainer = nullptr;
MediaShutdownManager::Instance().Unregister(this);
}

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

@ -666,7 +666,7 @@ protected:
// Counters related to decode and presentation of frames.
const RefPtr<FrameStatistics> mFrameStats;
const RefPtr<VideoFrameContainer> mVideoFrameContainer;
RefPtr<VideoFrameContainer> mVideoFrameContainer;
// Data needed to estimate playback data rate. The timeline used for
// this estimate is "decode time" (where the "current time" is the

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

@ -136,6 +136,7 @@ MediaFormatReader::Shutdown()
mDemuxer = nullptr;
mPlatform = nullptr;
mVideoFrameContainer = nullptr;
return MediaDecoderReader::Shutdown();
}

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

@ -29,6 +29,8 @@ interface HTMLLinkElement : HTMLElement {
attribute DOMString hreflang;
[SetterThrows, Pure]
attribute DOMString type;
[SetterThrows, Pure, Pref="network.http.enablePerElementReferrer"]
attribute DOMString referrerPolicy;
[PutForwards=value] readonly attribute DOMTokenList sizes;
};
HTMLLinkElement implements LinkStyle;

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

@ -408,6 +408,8 @@ class BaseCompiler
#endif
// The join registers are used to carry values out of blocks.
// JoinRegI32 and joinRegI64 must overlap: emitBrIf and
// emitBrTable assume that.
RegI32 joinRegI32;
RegI64 joinRegI64;
@ -1483,6 +1485,7 @@ class BaseCompiler
void pushJoinReg(AnyReg r) {
switch (r.tag) {
case AnyReg::NONE:
pushVoid();
break;
case AnyReg::I32:
pushI32(r.i32());
@ -1723,12 +1726,6 @@ class BaseCompiler
}
bool endFunction() {
// A frame greater than 256KB is implausible, probably an attack,
// so bail out.
if (maxFramePushed_ > 256 * 1024)
return false;
// Out-of-line prologue. Assumes that the in-line prologue has
// been executed and that a frame of size = localSize_ + sizeof(AsmJSFrame)
// has been allocated.
@ -1770,6 +1767,12 @@ class BaseCompiler
compileResults_.offsets().end = masm.currentOffset();
// A frame greater than 256KB is implausible, probably an attack,
// so fail the compilation.
if (maxFramePushed_ > 256 * 1024)
return false;
return true;
}
@ -2433,7 +2436,7 @@ class BaseCompiler
void lshiftI32(int32_t count, RegI32 srcDest) {
#if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
masm.shll(Imm32(count), srcDest.reg);
masm.shll(Imm32(count & 31), srcDest.reg);
#else
MOZ_CRASH("BaseCompiler platform hook: lshiftI32");
#endif
@ -2459,7 +2462,7 @@ class BaseCompiler
void rshiftI32(int32_t count, RegI32 srcDest) {
#if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
masm.sarl(Imm32(count), srcDest.reg);
masm.sarl(Imm32(count & 31), srcDest.reg);
#else
MOZ_CRASH("BaseCompiler platform hook: rshiftI32");
#endif
@ -2485,7 +2488,7 @@ class BaseCompiler
void rshiftU32(int32_t count, RegI32 srcDest) {
#if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
masm.shrl(Imm32(count), srcDest.reg);
masm.shrl(Imm32(count & 31), srcDest.reg);
#else
MOZ_CRASH("BaseCompiler platform hook: rshiftU32");
#endif
@ -4617,8 +4620,9 @@ BaseCompiler::emitBrIf()
// allowing a conditional expression to be left on the stack and
// reified here as part of the branch instruction.
// Don't use it for rc
if (type == ExprType::I32)
// We'll need the joinreg later, so don't use it for rc.
// We assume joinRegI32 and joinRegI64 overlap.
if (type == ExprType::I32 || type == ExprType::I64)
needI32(joinRegI32);
// Condition value is on top, always I32.
@ -4629,7 +4633,7 @@ BaseCompiler::emitBrIf()
if (IsVoid(type))
pushVoid();
if (type == ExprType::I32)
if (type == ExprType::I32 || type == ExprType::I64)
freeI32(joinRegI32);
// Save any value in the designated join register, where the
@ -4680,8 +4684,9 @@ BaseCompiler::emitBrTable()
if (!iter_.readBrTableEntry(type, &defaultDepth))
return false;
// We'll need this, so don't use it for rc
if (type == ExprType::I32)
// We'll need the joinreg later, so don't use it for rc.
// We assume joinRegI32 and joinRegI64 overlap.
if (type == ExprType::I32 || type == ExprType::I64)
needI32(joinRegI32);
// Table switch value always on top.
@ -4692,7 +4697,7 @@ BaseCompiler::emitBrTable()
if (IsVoid(type))
pushVoid();
if (type == ExprType::I32)
if (type == ExprType::I32 || type == ExprType::I64)
freeI32(joinRegI32);
AnyReg r = popJoinReg();
@ -4814,9 +4819,10 @@ void
BaseCompiler::pushReturned(ExprType type)
{
switch (type) {
case ExprType::Void:
case ExprType::Void: {
pushVoid();
break;
}
case ExprType::I32: {
RegI32 rv = needI32();
captureReturnedI32(rv);
@ -5375,6 +5381,7 @@ BaseCompiler::emitSelect()
RegI32 rc = popI32();
switch (type) {
case AnyType:
case ExprType::Void: {
popValueStackBy(2);
pushVoid();
@ -5659,15 +5666,21 @@ BaseCompiler::emitBody()
// every iteration.
if (overhead == 0) {
// Check every 50 expressions -- a happy medium between
// memory usage and checking overhead.
overhead = 50;
// Checking every 50 expressions should be safe, as the
// baseline JIT does very little allocation per expression.
CHECK(alloc_.ensureBallast());
CHECK(stk_.reserve(stk_.length() + 64));
overhead = 50;
} else {
overhead -= 1;
// The pushiest opcode is LOOP, which pushes two values
// per instance.
CHECK(stk_.reserve(stk_.length() + overhead * 2));
}
overhead--;
if (done())
return true;

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

@ -184,7 +184,8 @@ js::CheckTracedThing(JSTracer* trc, T* thing)
if (!trc->checkEdges())
return;
thing = MaybeForwarded(thing);
if (IsForwarded(thing))
thing = Forwarded(thing);
/* This function uses data that's not available in the nursery. */
if (IsInsideNursery(thing))
@ -235,8 +236,13 @@ js::CheckTracedThing(JSTracer* trc, T* thing)
* fact that allocated things may still contain the poison pattern if that
* part has not been overwritten. Also, background sweeping may be running
* and concurrently modifiying the free list.
*
* Tracing is done off main thread while compacting and reading the contents
* of the thing in IsThingPoisoned is racy so this check is skipped there.
*/
MOZ_ASSERT_IF(IsThingPoisoned(thing) && rt->isHeapBusy() && !rt->gc.isBackgroundSweeping(),
MOZ_ASSERT_IF(rt->isHeapBusy() && !zone->isGCCompacting() &&
!rt->gc.isBackgroundSweeping() &&
IsThingPoisoned(thing),
!InFreeList(thing->asTenured().arena(), thing));
#endif
}

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

@ -0,0 +1,16 @@
// |jit-test| test-also-wasm-baseline
load(libdir + "wasm.js");
// Bug 1281131 - be sure to reserve enough stack space
wasmEvalText(
`(module
(func $func0
${loopy(100)}
(nop)))`);
function loopy(n) {
if (n == 0)
return "(nop)";
return `(loop $out${n} $in${n} ${loopy(n-1)})`;
}

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

@ -0,0 +1,20 @@
// |jit-test| test-also-wasm-baseline
load(libdir + "wasm.js");
if (!hasI64())
quit(0);
// Bug 1280933, excerpted from binary test case provided there.
wasmEvalText(
`(module
(func $func0 (param $var0 i32) (result i32)
(i32.add
(block
(loop $label1 $label0
(block $label2
(br_table $label0 $label1 $label2 (i64.const 0) (get_local $var0)))
(set_local $var0 (i32.mul (i32.const 2) (get_local $var0))))
(set_local $var0 (i32.add (i32.const 4) (get_local $var0))))
(i32.const 1)))
(export "" 0))`);

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

@ -0,0 +1,32 @@
// |jit-test| test-also-wasm-baseline
load(libdir + "wasm.js");
// Bug 1280921
var m1 = wasmEvalText(
`(module
(type $type0 (func))
(func $func0
(select (unreachable) (return (nop)) (loop (i32.const 1))))
(export "" 0))`);
try {
m1();
} catch (e) {
if (!(e instanceof Error && e.message.match(/unreachable executed/)))
throw e;
}
var m2 = wasmEvalText(
`(module
(type $type0 (func))
(func $func0
(select (i32.const 26) (unreachable) (i32.const 3)))
(export "" 0))`);
try {
m2();
} catch (e) {
if (!(e instanceof Error && e.message.match(/unreachable executed/)))
throw e;
}

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

@ -0,0 +1,11 @@
// |jit-test| test-also-wasm-baseline
load(libdir + "wasm.js");
// Bug 1280926, extracted from binary
wasmEvalText(
`(module
(type $type0 (func (result i32)))
(export "" $func0)
(func $func0 (result i32)
(i32.shr_s (i32.const -40) (i32.const 34))))`);

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

@ -0,0 +1,30 @@
// |jit-test| test-also-wasm-baseline
load(libdir + "wasm.js");
// Bug 1280934, equivalent test case.
try {
wasmEvalText(
`(module
(func $func0 (result i32) ${locals()}
(i32.const 0))
(export "" 0))`);
} catch (e) {
// The wasm baseline compiler throws OOM on too-large frames, so
// handle that.
if (!String(e).match(/out of memory/))
throw e;
}
// The wasm baseline compiler cuts off frames at 256KB at the moment;
// the test case for bug 1280934 constructed a frame around 512KB so
// duplicate that here.
function locals() {
var s = "";
for ( var i=0 ; i < 64000 ; i++ )
s += "(local f64)\n";
return s;
}

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

@ -2470,11 +2470,20 @@ GCRuntime::updateCellPointers(MovingTracer* trc, Zone* zone, AllocKinds kinds, s
}
}
// Pointer updates run in three phases because of depdendencies between the
// different types of GC thing. The most important consideration is the
// dependency:
//
// object ---> shape ---> base shape
static const AllocKinds UpdatePhaseBaseShapes {
AllocKind::BASE_SHAPE
};
static const AllocKinds UpdatePhaseMisc {
AllocKind::SCRIPT,
AllocKind::LAZY_SCRIPT,
AllocKind::SHAPE,
AllocKind::BASE_SHAPE,
AllocKind::ACCESSOR_SHAPE,
AllocKind::OBJECT_GROUP,
AllocKind::STRING,
@ -2505,6 +2514,8 @@ GCRuntime::updateAllCellPointers(MovingTracer* trc, Zone* zone)
size_t bgTaskCount = CellUpdateBackgroundTaskCount();
updateCellPointers(trc, zone, UpdatePhaseBaseShapes, bgTaskCount);
updateCellPointers(trc, zone, UpdatePhaseMisc, bgTaskCount);
// Update TypeDescrs before all other objects as typed objects access these

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

@ -119,7 +119,7 @@ NS_IMPL_ISUPPORTS(nrappkitTimerCallback, nsITimerCallback)
NS_IMETHODIMP nrappkitTimerCallback::Notify(nsITimer *timer) {
r_log(LOG_GENERIC, LOG_DEBUG, "Timer callback fired (set in %s:%d)",
function_.c_str(), line_);
MOZ_ASSERT(timer == timer_);
MOZ_RELEASE_ASSERT(timer == timer_);
cb_(0, 0, cb_arg_);
// Allow the timer to go away.

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

@ -205,8 +205,8 @@ OnProxyAvailable(nsICancelable *request,
nsIProxyInfo *proxyinfo,
nsresult result) {
if (result == NS_ERROR_ABORT) {
// NS_ERROR_ABORT means that the PeerConnectionMedia is no longer waiting
if (!pcm_->mProxyRequest) {
// PeerConnectionMedia is no longer waiting
return NS_OK;
}
@ -217,6 +217,7 @@ OnProxyAvailable(nsICancelable *request,
}
pcm_->mProxyResolveCompleted = true;
pcm_->mProxyRequest = nullptr;
pcm_->FlushIceCtxOperationQueueIfReady();
return NS_OK;
@ -995,6 +996,7 @@ PeerConnectionMedia::SelfDestruct()
if (mProxyRequest) {
mProxyRequest->Cancel(NS_ERROR_ABORT);
mProxyRequest = nullptr;
}
// Shutdown the transport (async)

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

@ -37,7 +37,7 @@ NSSDialogs.prototype = {
if (!this.bundle) {
this.bundle = Services.strings.createBundle("chrome://browser/locale/pippki.properties");
}
return this.bundle.formatStringFromName(aName, argList, 1);
return this.bundle.formatStringFromName(aName, argList, argList.length);
},
getPrompt: function(aTitle, aText, aButtons) {
@ -143,6 +143,40 @@ NSSDialogs.prototype = {
this.showPrompt(p);
},
/**
* Returns a list of details of the given cert relevant for TLS client
* authentication.
*
* @param {nsIX509Cert} cert Cert to get the details of.
* @returns {String} <br/> delimited list of details.
*/
getCertDetails: function(cert) {
let detailLines = [
this.formatString("clientAuthAsk.issuedTo", [cert.subjectName]),
this.formatString("clientAuthAsk.serial", [cert.serialNumber]),
this.formatString("clientAuthAsk.validityPeriod",
[cert.validity.notBeforeLocalTime,
cert.validity.notAfterLocalTime]),
];
let keyUsages = cert.keyUsages;
if (keyUsages) {
detailLines.push(this.formatString("clientAuthAsk.keyUsages",
[keyUsages]));
}
let emailAddresses = cert.getEmailAddresses({});
if (emailAddresses.length > 0) {
let joinedAddresses = emailAddresses.join(", ");
detailLines.push(this.formatString("clientAuthAsk.emailAddresses",
[joinedAddresses]));
}
detailLines.push(this.formatString("clientAuthAsk.issuedBy",
[cert.issuerName]));
detailLines.push(this.formatString("clientAuthAsk.storedOn",
[cert.tokenName]));
return detailLines.join("<br/>");
},
viewCertDetails: function(details) {
let p = this.getPrompt(this.getString("clientAuthAsk.message3"),
'',
@ -151,56 +185,61 @@ NSSDialogs.prototype = {
this.showPrompt(p);
},
ChooseCertificate: function(aCtx, cn, organization, issuer, certNickList, certDetailsList, count, selectedIndex, canceled) {
let rememberSetting = true;
var pref = Cc['@mozilla.org/preferences-service;1']
.getService(Components.interfaces.nsIPrefService);
if (pref) {
pref = pref.getBranch(null);
try {
rememberSetting = pref.getBoolPref("security.remember_cert_checkbox_default_setting");
} catch (e) {
// pref is missing
}
chooseCertificate: function(ctx, cnAndPort, organization, issuerOrg, certList,
selectedIndex) {
let rememberSetting =
Services.prefs.getBoolPref("security.remember_cert_checkbox_default_setting");
let serverRequestedDetails = [
cnAndPort,
this.formatString("clientAuthAsk.organization", [organization]),
this.formatString("clientAuthAsk.issuer", [issuerOrg]),
].join("<br/>");
let certNickList = [];
let certDetailsList = [];
for (let i = 0; i < certList.length; i++) {
let cert = certList.queryElementAt(i, Ci.nsIX509Cert);
certNickList.push(this.formatString("clientAuthAsk.nickAndSerial",
[cert.nickname, cert.serialNumber]));
certDetailsList.push(this.getCertDetails(cert));
}
let organizationString = this.formatString("clientAuthAsk.organization",
[organization]);
let issuerString = this.formatString("clientAuthAsk.issuer",
[issuer]);
let serverRequestedDetails = cn + '<br/>' + organizationString + '<br/>' + issuerString;
selectedIndex = 0;
selectedIndex.value = 0;
while (true) {
let buttons = [
this.getString("nssdialogs.ok.label"),
this.getString("clientAuthAsk.viewCert.label"),
this.getString("nssdialogs.cancel.label"),
];
let prompt = this.getPrompt(this.getString("clientAuthAsk.title"),
this.getString("clientAuthAsk.message1"),
[ this.getString("nssdialogs.ok.label"),
this.getString("clientAuthAsk.viewCert.label"),
this.getString("nssdialogs.cancel.label")
])
this.getString("clientAuthAsk.message1"),
buttons)
.addLabel({ id: "requestedDetails", label: serverRequestedDetails } )
.addMenulist({
id: "nicknames",
label: this.getString("clientAuthAsk.message2"),
values: certNickList, selected: selectedIndex
values: certNickList,
selected: selectedIndex.value,
}).addCheckbox({
id: "rememberBox",
label: this.getString("clientAuthAsk.remember.label"),
checked: rememberSetting
});
let response = this.showPrompt(prompt);
selectedIndex = response.nicknames;
if (response.button == 1) {
this.viewCertDetails(certDetailsList[selectedIndex]);
selectedIndex.value = response.nicknames;
if (response.button == 1 /* buttons[1] */) {
this.viewCertDetails(certDetailsList[selectedIndex.value]);
continue;
} else if (response.button == 0) {
canceled.value = false;
} else if (response.button == 0 /* buttons[0] */) {
if (response.rememberBox == true) {
aCtx.QueryInterface(Ci.nsIClientAuthUserDecision).rememberClientAuthCertificate = true;
let caud = ctx.QueryInterface(Ci.nsIClientAuthUserDecision);
if (caud) {
caud.rememberClientAuthCertificate = true;
}
}
return true;
}
canceled.value = true;
return false;
}
}

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

@ -19,8 +19,40 @@ clientAuthAsk.message1=This site has requested that you identify yourself with a
clientAuthAsk.message2=Choose a certificate to present as identification:
clientAuthAsk.message3=Details of selected certificate:
clientAuthAsk.remember.label=Remember this decision
# LOCALIZATION NOTE(clientAuthAsk.nickAndSerial): Represents a single cert when
# the user is choosing from a list of certificates.
# %1$S is the nickname of the cert.
# %2$S is the serial number of the cert in AA:BB:CC hex format.
clientAuthAsk.nickAndSerial=%1$S [%2$S]
# LOCALIZATION NOTE(clientAuthAsk.organization): %S is the Organization of the
# server cert.
clientAuthAsk.organization=Organization: "%S"
# LOCALIZATION NOTE(clientAuthAsk.issuer): %S is the Organization of the
# issuer cert of the server cert.
clientAuthAsk.issuer=Issued Under: "%S"
# LOCALIZATION NOTE(clientAuthAsk.issuedTo): %1$S is the Distinguished Name of
# the currently selected client cert, such as "CN=John Doe,OU=Example" (without
# quotes).
clientAuthAsk.issuedTo=Issued to: %1$S
# LOCALIZATION NOTE(clientAuthAsk.serial): %1$S is the serial number of the
# selected cert in AA:BB:CC hex format.
clientAuthAsk.serial=Serial number: %1$S
# LOCALIZATION NOTE(clientAuthAsk.validityPeriod):
# %1$S is the already localized notBefore date of the selected cert.
# %2$S is the already localized notAfter date of the selected cert.
clientAuthAsk.validityPeriod=Valid from %1$S to %2$S
# LOCALIZATION NOTE(clientAuthAsk.keyUsages): %1$S is a comma separated list of
# already localized key usages the selected cert is valid for.
clientAuthAsk.keyUsages=Key Usages: %1$S
# LOCALIZATION NOTE(clientAuthAsk.emailAddresses): %1$S is a comma separated
# list of e-mail addresses the selected cert is valid for.
clientAuthAsk.emailAddresses=Email addresses: %1$S
# LOCALIZATION NOTE(clientAuthAsk.issuedBy): %1$S is the Distinguished Name of
# the cert which issued the selected cert.
clientAuthAsk.issuedBy=Issued by: %1$S
# LOCALIZATION NOTE(clientAuthAsk.storedOn): %1$S is the name of the PKCS #11
# token the selected cert is stored on.
clientAuthAsk.storedOn=Stored on: %1$S
clientAuthAsk.viewCert.label=View
certmgr.title=Certificate Details

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

@ -1412,7 +1412,7 @@ pref("network.http.referer.XOriginPolicy", 0);
// By default this is enabled for compatibility (see bug 141641)
pref("network.http.sendSecureXSiteReferrer", true);
// Controls whether referrer attributes in <a>, <img>, <area>, and <iframe> are honoured
// Controls whether referrer attributes in <a>, <img>, <area>, <iframe>, and <link> are honoured
pref("network.http.enablePerElementReferrer", true);
// Maximum number of consecutive redirects before aborting.

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

@ -341,6 +341,14 @@ LoadInfo::Clone() const
return copy.forget();
}
already_AddRefed<nsILoadInfo>
LoadInfo::CloneWithNewSecFlags(nsSecurityFlags aSecurityFlags) const
{
RefPtr<LoadInfo> copy(new LoadInfo(*this));
copy->mSecurityFlags = aSecurityFlags;
return copy.forget();
}
already_AddRefed<nsILoadInfo>
LoadInfo::CloneForNewRequest() const
{

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

@ -64,6 +64,11 @@ public:
// create an exact copy of the loadinfo
already_AddRefed<nsILoadInfo> Clone() const;
// hands off!!! don't use CloneWithNewSecFlags unless you know
// exactly what you are doing - it should only be used within
// nsBaseChannel::Redirect()
already_AddRefed<nsILoadInfo>
CloneWithNewSecFlags(nsSecurityFlags aSecurityFlags) const;
// creates a copy of the loadinfo which is appropriate to use for a
// separate request. I.e. not for a redirect or an inner channel, but
// when a separate request is made with the same security properties.

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

@ -84,8 +84,10 @@ nsBaseChannel::Redirect(nsIChannel *newChannel, uint32_t redirectFlags,
// make a copy of the loadinfo, append to the redirectchain
// and set it on the new channel
if (mLoadInfo) {
nsSecurityFlags secFlags = mLoadInfo->GetSecurityFlags() ^
nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL;
nsCOMPtr<nsILoadInfo> newLoadInfo =
static_cast<mozilla::LoadInfo*>(mLoadInfo.get())->Clone();
static_cast<mozilla::LoadInfo*>(mLoadInfo.get())->CloneWithNewSecFlags(secFlags);
nsCOMPtr<nsIPrincipal> uriPrincipal;
nsIScriptSecurityManager *sm = nsContentUtils::GetSecurityManager();

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

@ -52,8 +52,41 @@ certNotVerified_AlgorithmDisabled=Could not verify this certificate because it w
certNotVerified_Unknown=Could not verify this certificate for unknown reasons.
#Client auth
clientAuthRemember=Remember this decision
# LOCALIZATION NOTE(clientAuthNickAndSerial): Represents a single cert when the
# user is choosing from a list of certificates.
# %1$S is the nickname of the cert.
# %2$S is the serial number of the cert in AA:BB:CC hex format.
clientAuthNickAndSerial=%1$S [%2$S]
# LOCALIZATION NOTE(clientAuthMessage1): %S is the Organization of the server
# cert.
clientAuthMessage1=Organization: “%S”
# LOCALIZATION NOTE(clientAuthMessage2): %S is the Organization of the issuer
# cert of the server cert.
clientAuthMessage2=Issued Under: “%S”
# LOCALIZATION NOTE(clientAuthIssuedTo): %1$S is the Distinguished Name of the
# currently selected client cert, such as "CN=John Doe,OU=Example" (without
# quotes).
clientAuthIssuedTo=Issued to: %1$S
# LOCALIZATION NOTE(clientAuthSerial): %1$S is the serial number of the selected
# cert in AA:BB:CC hex format.
clientAuthSerial=Serial number: %1$S
# LOCALIZATION NOTE(clientAuthValidityPeriod):
# %1$S is the already localized notBefore date of the selected cert.
# %2$S is the already localized notAfter date of the selected cert.
clientAuthValidityPeriod=Valid from %1$S to %2$S
# LOCALIZATION NOTE(clientAuthKeyUsages): %1$S is a comma separated list of
# already localized key usages the selected cert is valid for.
clientAuthKeyUsages=Key Usages: %1$S
# LOCALIZATION NOTE(clientAuthEmailAddresses): %1$S is a comma separated list of
# e-mail addresses the selected cert is valid for.
clientAuthEmailAddresses=Email addresses: %1$S
# LOCALIZATION NOTE(clientAuthIssuedBy): %1$S is the Distinguished Name of the
# cert which issued the selected cert.
clientAuthIssuedBy=Issued by: %1$S
# LOCALIZATION NOTE(clientAuthStoredOn): %1$S is the name of the PKCS #11 token
# the selected cert is stored on.
clientAuthStoredOn=Stored on: %1$S
#Page Info
pageInfo_NoEncryption=Connection Not Encrypted

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

@ -8,8 +8,9 @@
* Dialog services for PIP.
*/
#include "mozIDOMWindow.h"
#include "mozilla/Assertions.h"
#include "mozilla/Casting.h"
#include "nsArray.h"
#include "nsCOMPtr.h"
#include "nsDateTimeFormatCID.h"
#include "nsEmbedCID.h"
#include "nsIComponentManager.h"
@ -21,7 +22,6 @@
#include "nsIPromptService.h"
#include "nsIProtectedAuthThread.h"
#include "nsIServiceManager.h"
#include "nsIStringBundle.h"
#include "nsIWindowWatcher.h"
#include "nsIX509CertDB.h"
#include "nsIX509Cert.h"
@ -31,7 +31,6 @@
#include "nsPromiseFlatString.h"
#include "nsReadableUtils.h"
#include "nsString.h"
#include "nsXPIDLString.h"
#define PIPSTRING_BUNDLE_URL "chrome://pippki/locale/pippki.properties"
@ -158,57 +157,70 @@ nsNSSDialogs::ConfirmDownloadCACert(nsIInterfaceRequestor *ctx,
}
NS_IMETHODIMP
nsNSSDialogs::ChooseCertificate(nsIInterfaceRequestor* ctx, const char16_t* cn,
const char16_t* organization,
const char16_t* issuer,
const char16_t** certNickList,
const char16_t** certDetailsList, uint32_t count,
int32_t* selectedIndex, bool* canceled)
nsNSSDialogs::ChooseCertificate(nsIInterfaceRequestor* ctx,
const nsAString& cnAndPort,
const nsAString& organization,
const nsAString& issuerOrg,
nsIArray* certList,
/*out*/ uint32_t* selectedIndex,
/*out*/ bool* certificateChosen)
{
nsresult rv;
uint32_t i;
NS_ENSURE_ARG_POINTER(ctx);
NS_ENSURE_ARG_POINTER(certList);
NS_ENSURE_ARG_POINTER(selectedIndex);
NS_ENSURE_ARG_POINTER(certificateChosen);
*canceled = false;
// Get the parent window for the dialog
nsCOMPtr<nsIDOMWindow> parent = do_GetInterface(ctx);
*certificateChosen = false;
nsCOMPtr<nsIDialogParamBlock> block =
do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID);
if (!block) return NS_ERROR_FAILURE;
block->SetNumberStrings(4+count*2);
rv = block->SetString(0, cn);
if (NS_FAILED(rv)) return rv;
rv = block->SetString(1, organization);
if (NS_FAILED(rv)) return rv;
rv = block->SetString(2, issuer);
if (NS_FAILED(rv)) return rv;
for (i = 0; i < count; i++) {
rv = block->SetString(i+3, certNickList[i]);
if (NS_FAILED(rv)) return rv;
do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID);
if (!block) {
return NS_ERROR_FAILURE;
}
for (i = 0; i < count; i++) {
rv = block->SetString(i+count+3, certDetailsList[i]);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIMutableArray> paramBlockArray = nsArrayBase::Create();
if (!paramBlockArray) {
return NS_ERROR_FAILURE;
}
nsresult rv = paramBlockArray->AppendElement(certList, false);
if (NS_FAILED(rv)) {
return rv;
}
rv = block->SetObjects(paramBlockArray);
if (NS_FAILED(rv)) {
return rv;
}
rv = block->SetInt(0, count);
if (NS_FAILED(rv)) return rv;
rv = block->SetNumberStrings(3);
if (NS_FAILED(rv)) {
return rv;
}
rv = block->SetString(0, PromiseFlatString(cnAndPort).get());
if (NS_FAILED(rv)) {
return rv;
}
rv = block->SetString(1, PromiseFlatString(organization).get());
if (NS_FAILED(rv)) {
return rv;
}
rv = block->SetString(2, PromiseFlatString(issuerOrg).get());
if (NS_FAILED(rv)) {
return rv;
}
rv = nsNSSDialogHelper::openDialog(nullptr,
"chrome://pippki/content/clientauthask.xul",
block);
if (NS_FAILED(rv)) return rv;
"chrome://pippki/content/clientauthask.xul",
block);
if (NS_FAILED(rv)) {
return rv;
}
int32_t status;
rv = block->GetInt(0, &status);
if (NS_FAILED(rv)) return rv;
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsIClientAuthUserDecision> extraResult = do_QueryInterface(ctx);
if (extraResult) {
@ -219,12 +231,23 @@ nsNSSDialogs::ChooseCertificate(nsIInterfaceRequestor* ctx, const char16_t* cn,
}
}
*canceled = (status == 0)?true:false;
if (!*canceled) {
// retrieve the nickname
rv = block->GetInt(1, selectedIndex);
*certificateChosen = (status != 0);
if (*certificateChosen) {
int32_t index = 0;
rv = block->GetInt(1, &index);
if (NS_FAILED(rv)) {
return rv;
}
if (index < 0) {
MOZ_ASSERT_UNREACHABLE("Selected index should never be negative");
return NS_ERROR_FAILURE;
}
*selectedIndex = mozilla::AssertedCast<uint32_t>(index);
}
return rv;
return NS_OK;
}

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

@ -6,81 +6,109 @@
/* import-globals-from pippki.js */
"use strict";
const nsIDialogParamBlock = Components.interfaces.nsIDialogParamBlock;
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
/**
* The pippki <stringbundle> element.
* @type <stringbundle>
*/
var bundle;
/**
* The array of certs the user can choose from.
* @type nsIArray<nsIX509Cert>
*/
var certArray;
/**
* The param block to get params from and set results on.
* @type nsIDialogParamBlock
*/
var dialogParams;
var itemCount = 0;
/**
* The checkbox storing whether the user wants to remember the selected cert.
* @type nsIDOMXULCheckboxElement
*/
var rememberBox;
function onLoad()
{
var cn;
var org;
var issuer;
function onLoad() {
dialogParams = window.arguments[0].QueryInterface(Ci.nsIDialogParamBlock);
dialogParams = window.arguments[0].QueryInterface(nsIDialogParamBlock);
cn = dialogParams.GetString(0);
org = dialogParams.GetString(1);
issuer = dialogParams.GetString(2);
bundle = document.getElementById("pippki_bundle");
let rememberSetting =
Services.prefs.getBoolPref("security.remember_cert_checkbox_default_setting");
// added with bug 431819. reuse string from caps in order to avoid string changes
var capsBundle = document.getElementById("caps_bundle");
var rememberString = capsBundle.getString("CheckMessage");
var rememberSetting = true;
rememberBox = document.getElementById("rememberBox");
rememberBox.label = bundle.getString("clientAuthRemember");
rememberBox.checked = rememberSetting;
var pref = Components.classes['@mozilla.org/preferences-service;1']
.getService(Components.interfaces.nsIPrefService);
if (pref) {
pref = pref.getBranch(null);
try {
rememberSetting =
pref.getBoolPref("security.remember_cert_checkbox_default_setting");
} catch (e) {
// pref is missing
}
let cnAndPort = dialogParams.GetString(0);
let org = dialogParams.GetString(1);
let issuerOrg = dialogParams.GetString(2);
let formattedOrg = bundle.getFormattedString("clientAuthMessage1", [org]);
let formattedIssuerOrg = bundle.getFormattedString("clientAuthMessage2",
[issuerOrg]);
setText("hostname", cnAndPort);
setText("organization", formattedOrg);
setText("issuer", formattedIssuerOrg);
let selectElement = document.getElementById("nicknames");
certArray = dialogParams.objects.queryElementAt(0, Ci.nsIArray);
for (let i = 0; i < certArray.length; i++) {
let menuItemNode = document.createElement("menuitem");
let cert = certArray.queryElementAt(i, Ci.nsIX509Cert);
let nickAndSerial =
bundle.getFormattedString("clientAuthNickAndSerial",
[cert.nickname, cert.serialNumber]);
menuItemNode.setAttribute("value", i);
menuItemNode.setAttribute("label", nickAndSerial); // This is displayed.
selectElement.firstChild.appendChild(menuItemNode);
if (i == 0) {
selectElement.selectedItem = menuItemNode;
}
}
rememberBox = document.getElementById("rememberBox");
rememberBox.label = rememberString;
rememberBox.checked = rememberSetting;
var bundle = document.getElementById("pippki_bundle");
var message1 = bundle.getFormattedString("clientAuthMessage1", [org]);
var message2 = bundle.getFormattedString("clientAuthMessage2", [issuer]);
setText("hostname", cn);
setText("organization", message1);
setText("issuer", message2);
var selectElement = document.getElementById("nicknames");
itemCount = dialogParams.GetInt(0);
for (let i = 0; i < itemCount; i++) {
var menuItemNode = document.createElement("menuitem");
let nick = dialogParams.GetString(i + 3);
menuItemNode.setAttribute("value", i);
menuItemNode.setAttribute("label", nick); // this is displayed
selectElement.firstChild.appendChild(menuItemNode);
if (i == 0) {
selectElement.selectedItem = menuItemNode;
}
}
setDetails();
}
function setDetails()
{
let index = parseInt(document.getElementById("nicknames").value);
let details = dialogParams.GetString(index + itemCount + 3);
document.getElementById("details").value = details;
}
function onCertSelected()
{
setDetails();
}
function doOK()
{
/**
* Populates the details section with information concerning the selected cert.
*/
function setDetails() {
let index = parseInt(document.getElementById("nicknames").value);
let cert = certArray.queryElementAt(index, Ci.nsIX509Cert);
let detailLines = [
bundle.getFormattedString("clientAuthIssuedTo", [cert.subjectName]),
bundle.getFormattedString("clientAuthSerial", [cert.serialNumber]),
bundle.getFormattedString("clientAuthValidityPeriod",
[cert.validity.notBeforeLocalTime,
cert.validity.notAfterLocalTime]),
];
let keyUsages = cert.keyUsages;
if (keyUsages) {
detailLines.push(bundle.getFormattedString("clientAuthKeyUsages",
[keyUsages]));
}
let emailAddresses = cert.getEmailAddresses({});
if (emailAddresses.length > 0) {
let joinedAddresses = emailAddresses.join(", ");
detailLines.push(bundle.getFormattedString("clientAuthEmailAddresses",
[joinedAddresses]));
}
detailLines.push(bundle.getFormattedString("clientAuthIssuedBy",
[cert.issuerName]));
detailLines.push(bundle.getFormattedString("clientAuthStoredOn",
[cert.tokenName]));
document.getElementById("details").value = detailLines.join("\n");
}
function onCertSelected() {
setDetails();
}
function doOK() {
// Signal that the user accepted.
dialogParams.SetInt(0, 1);
let index = parseInt(document.getElementById("nicknames").value);
@ -92,12 +120,9 @@ function doOK()
return true;
}
function doCancel()
{
function doCancel() {
// Signal that the user cancelled.
dialogParams.SetInt(0, 0);
// Signal some invalid index value since a cert hasn't actually been chosen.
dialogParams.SetInt(1, -1); // invalid value
// Signal whether the user wanted to remember the "selection".
dialogParams.SetInt(2, rememberBox.checked);
return true;

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

@ -20,7 +20,6 @@
<stringbundleset id="stringbundleset">
<stringbundle id="pippki_bundle" src="chrome://pippki/locale/pippki.properties"/>
<stringbundle id="caps_bundle" src="chrome://global/locale/security/caps.properties"/>
</stringbundleset>
<script type="application/javascript" src="chrome://pippki/content/pippki.js"/>

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

@ -4,28 +4,34 @@
#include "nsISupports.idl"
interface nsIArray;
interface nsIInterfaceRequestor;
/**
* nsIClientAuthDialog
* Provides UI for SSL client-auth dialogs.
*/
[scriptable, uuid(fa4c7520-1433-11d5-ba24-00108303b117)]
interface nsIClientAuthDialogs : nsISupports
{
/**
* display
* UI shown when a user is asked to do SSL client auth.
* Called when a user is asked to choose a certificate for client auth.
*
* @param ctx Context that allows at least nsIClientAuthUserDecision to be
* queried.
* @param cnAndPort Common Name of the server cert and the port of the server.
* @param organization Organization field of the server cert.
* @param issuerOrg Organization field of the issuer cert of the server cert.
* @param certList List of certificates the user can choose from.
* @param selectedIndex Index of the cert in |certList| that the user chose.
* Ignored if the return value is false.
* @return true if a certificate was chosen. false if the user canceled.
*/
void ChooseCertificate(in nsIInterfaceRequestor ctx,
in wstring cn,
in wstring organization,
in wstring issuer,
[array, size_is(count)] in wstring certNickList,
[array, size_is(count)] in wstring certDetailsList,
in unsigned long count,
out long selectedIndex,
out boolean canceled);
boolean chooseCertificate(in nsIInterfaceRequestor ctx,
in AString cnAndPort,
in AString organization,
in AString issuerOrg,
in nsIArray certList,
out unsigned long selectedIndex);
};
[scriptable, uuid(95c4373e-bdd4-4a63-b431-f5b000367721)]

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

@ -182,24 +182,6 @@ interface nsIX509Cert : nsISupports {
const unsigned long USAGE_NOT_ALLOWED = 1 << 7;
const unsigned long SIGNATURE_ALGORITHM_DISABLED = 1 << 8;
/**
* Constants that describe the certified usages of a certificate.
*
* Deprecated and unused
*/
const unsigned long CERT_USAGE_SSLClient = 0;
const unsigned long CERT_USAGE_SSLServer = 1;
const unsigned long CERT_USAGE_SSLServerWithStepUp = 2;
const unsigned long CERT_USAGE_SSLCA = 3;
const unsigned long CERT_USAGE_EmailSigner = 4;
const unsigned long CERT_USAGE_EmailRecipient = 5;
const unsigned long CERT_USAGE_ObjectSigner = 6;
const unsigned long CERT_USAGE_UserCertImport = 7;
const unsigned long CERT_USAGE_VerifyCA = 8;
const unsigned long CERT_USAGE_ProtectedObjectSigner = 9;
const unsigned long CERT_USAGE_StatusResponder = 10;
const unsigned long CERT_USAGE_AnyCA = 11;
/**
* Constants for specifying the chain mode when exporting a certificate
*/
@ -250,6 +232,13 @@ interface nsIX509Cert : nsISupports {
*/
void getUsagesString(in boolean localOnly, out uint32_t verified, out AString usages);
/**
* A comma separated list of localized strings representing the contents of
* the certificate's key usage extension, if present. The empty string if the
* certificate doesn't have the key usage extension, or has an empty extension.
*/
readonly attribute AString keyUsages;
/**
* This is the attribute which describes the ASN1 layout
* of the certificate. This can be used when doing a

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

@ -11,6 +11,7 @@
#include "certdb.h"
#include "mozilla/Base64.h"
#include "mozilla/Casting.h"
#include "mozilla/NotNull.h"
#include "mozilla/unused.h"
#include "nsArray.h"
#include "nsCOMPtr.h"
@ -70,6 +71,8 @@ NS_IMPL_ISUPPORTS(nsNSSCertificate,
nsISerializable,
nsIClassInfo)
static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
/*static*/ nsNSSCertificate*
nsNSSCertificate::Create(CERTCertificate* cert, SECOidTag* evOidPolicy)
{
@ -256,90 +259,84 @@ nsNSSCertificate::MarkForPermDeletion()
return NS_OK;
}
nsresult
GetKeyUsagesString(CERTCertificate* cert, nsINSSComponent* nssComponent,
nsString& text)
/**
* Appends a pipnss bundle string to the given string.
*
* @param nssComponent For accessing the string bundle.
* @param bundleKey Key for the string to append.
* @param currentText The text to append to, using commas as separators.
*/
template<size_t N>
void
AppendBundleString(const NotNull<nsCOMPtr<nsINSSComponent>>& nssComponent,
const char (&bundleKey)[N],
/*in/out*/ nsAString& currentText)
{
nsAutoString bundleString;
nsresult rv = nssComponent->GetPIPNSSBundleString(bundleKey, bundleString);
if (NS_FAILED(rv)) {
return;
}
if (!currentText.IsEmpty()) {
currentText.Append(',');
}
currentText.Append(bundleString);
}
NS_IMETHODIMP
nsNSSCertificate::GetKeyUsages(nsAString& text)
{
text.Truncate();
SECItem keyUsageItem;
keyUsageItem.data = nullptr;
keyUsageItem.len = 0;
SECStatus srv;
// There is no extension, v1 or v2 certificate
if (!cert->extensions)
return NS_OK;
srv = CERT_FindKeyUsageExtension(cert, &keyUsageItem);
if (srv == SECFailure) {
if (PORT_GetError () == SEC_ERROR_EXTENSION_NOT_FOUND)
return NS_OK;
else
return NS_ERROR_FAILURE;
nsCOMPtr<nsINSSComponent> nssComponent = do_GetService(kNSSComponentCID);
if (!nssComponent) {
return NS_ERROR_FAILURE;
}
if (!mCert) {
return NS_ERROR_FAILURE;
}
if (!mCert->extensions) {
return NS_OK;
}
ScopedAutoSECItem keyUsageItem;
if (CERT_FindKeyUsageExtension(mCert.get(), &keyUsageItem) != SECSuccess) {
return PORT_GetError() == SEC_ERROR_EXTENSION_NOT_FOUND ? NS_OK
: NS_ERROR_FAILURE;
}
unsigned char keyUsage = 0;
if (keyUsageItem.len) {
keyUsage = keyUsageItem.data[0];
}
nsAutoString local;
nsresult rv;
const char16_t comma = ',';
NotNull<nsCOMPtr<nsINSSComponent>> wrappedNSSComponent =
WrapNotNull(nssComponent);
if (keyUsage & KU_DIGITAL_SIGNATURE) {
rv = nssComponent->GetPIPNSSBundleString("CertDumpKUSign", local);
if (NS_SUCCEEDED(rv)) {
if (!text.IsEmpty()) text.Append(comma);
text.Append(local.get());
}
AppendBundleString(wrappedNSSComponent, "CertDumpKUSign", text);
}
if (keyUsage & KU_NON_REPUDIATION) {
rv = nssComponent->GetPIPNSSBundleString("CertDumpKUNonRep", local);
if (NS_SUCCEEDED(rv)) {
if (!text.IsEmpty()) text.Append(comma);
text.Append(local.get());
}
AppendBundleString(wrappedNSSComponent, "CertDumpKUNonRep", text);
}
if (keyUsage & KU_KEY_ENCIPHERMENT) {
rv = nssComponent->GetPIPNSSBundleString("CertDumpKUEnc", local);
if (NS_SUCCEEDED(rv)) {
if (!text.IsEmpty()) text.Append(comma);
text.Append(local.get());
}
AppendBundleString(wrappedNSSComponent, "CertDumpKUEnc", text);
}
if (keyUsage & KU_DATA_ENCIPHERMENT) {
rv = nssComponent->GetPIPNSSBundleString("CertDumpKUDEnc", local);
if (NS_SUCCEEDED(rv)) {
if (!text.IsEmpty()) text.Append(comma);
text.Append(local.get());
}
AppendBundleString(wrappedNSSComponent, "CertDumpKUDEnc", text);
}
if (keyUsage & KU_KEY_AGREEMENT) {
rv = nssComponent->GetPIPNSSBundleString("CertDumpKUKA", local);
if (NS_SUCCEEDED(rv)) {
if (!text.IsEmpty()) text.Append(comma);
text.Append(local.get());
}
AppendBundleString(wrappedNSSComponent, "CertDumpKUKA", text);
}
if (keyUsage & KU_KEY_CERT_SIGN) {
rv = nssComponent->GetPIPNSSBundleString("CertDumpKUCertSign", local);
if (NS_SUCCEEDED(rv)) {
if (!text.IsEmpty()) text.Append(comma);
text.Append(local.get());
}
AppendBundleString(wrappedNSSComponent, "CertDumpKUCertSign", text);
}
if (keyUsage & KU_CRL_SIGN) {
rv = nssComponent->GetPIPNSSBundleString("CertDumpKUCRLSign", local);
if (NS_SUCCEEDED(rv)) {
if (!text.IsEmpty()) text.Append(comma);
text.Append(local.get());
}
AppendBundleString(wrappedNSSComponent, "CertDumpKUCRLSign", text);
}
PORT_Free (keyUsageItem.data);
return NS_OK;
}
@ -348,8 +345,6 @@ nsNSSCertificate::FormatUIStrings(const nsAutoString& nickname,
nsAutoString& nickWithSerial,
nsAutoString& details)
{
static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
if (!NS_IsMainThread()) {
NS_ERROR("nsNSSCertificate::FormatUIStrings called off the main thread");
return NS_ERROR_NOT_SAME_THREAD;
@ -421,8 +416,7 @@ nsNSSCertificate::FormatUIStrings(const nsAutoString& nickname,
details.Append(char16_t('\n'));
}
if (NS_SUCCEEDED(GetKeyUsagesString(mCert.get(), nssComponent, temp1)) &&
!temp1.IsEmpty()) {
if (NS_SUCCEEDED(GetKeyUsages(temp1)) && !temp1.IsEmpty()) {
details.AppendLiteral(" ");
if (NS_SUCCEEDED(nssComponent->GetPIPNSSBundleString("CertDumpKeyUsage", info))) {
details.Append(info);
@ -585,8 +579,6 @@ nsNSSCertificate::GetWindowTitle(nsAString& aWindowTitle)
NS_IMETHODIMP
nsNSSCertificate::GetNickname(nsAString& aNickname)
{
static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
@ -607,8 +599,6 @@ nsNSSCertificate::GetNickname(nsAString& aNickname)
NS_IMETHODIMP
nsNSSCertificate::GetEmailAddress(nsAString& aEmailAddress)
{
static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;
@ -1054,8 +1044,6 @@ nsNSSCertificate::GetSha1Fingerprint(nsAString& _sha1Fingerprint)
NS_IMETHODIMP
nsNSSCertificate::GetTokenName(nsAString& aTokenName)
{
static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown())
return NS_ERROR_NOT_AVAILABLE;

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

@ -5,13 +5,13 @@
#include "nsNSSCertificateFakeTransport.h"
#include "mozilla/Assertions.h"
#include "nsIClassInfoImpl.h"
#include "nsIObjectInputStream.h"
#include "nsIObjectOutputStream.h"
#include "nsISupportsPrimitives.h"
#include "nsNSSCertificate.h"
#include "nsString.h"
#include "nsXPIDLString.h"
NS_IMPL_ISUPPORTS(nsNSSCertificateFakeTransport,
nsIX509Cert,
@ -199,6 +199,13 @@ nsNSSCertificateFakeTransport::GetUsagesString(bool, uint32_t*, nsAString&)
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsNSSCertificateFakeTransport::GetKeyUsages(nsAString&)
{
MOZ_ASSERT_UNREACHABLE("Unimplemented on content process");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsNSSCertificateFakeTransport::GetASN1Structure(nsIASN1Object**)
{

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

@ -21,6 +21,7 @@
#include "mozilla/Move.h"
#include "mozilla/Preferences.h"
#include "mozilla/Telemetry.h"
#include "nsArrayUtils.h"
#include "nsCharSeparatedTokenizer.h"
#include "nsClientAuthRemember.h"
#include "nsContentUtils.h"
@ -2099,11 +2100,6 @@ ClientAuthDataRunnable::RunOnTargetThread()
char** caNameStrings;
UniqueCERTCertificate cert;
UniqueSECKEYPrivateKey privKey;
UniqueCERTCertList certList;
CERTCertListNode* node;
UniqueCERTCertNicknames nicknames;
int keyError = 0; // used for private key retrieval error
int32_t NumberOfCerts = 0;
void* wincx = mSocketInfo;
nsresult rv;
@ -2152,30 +2148,31 @@ ClientAuthDataRunnable::RunOnTargetThread()
// automatically find the right cert
// find all user certs that are valid and for SSL
certList.reset(CERT_FindUserCertsByUsage(CERT_GetDefaultCertDB(),
certUsageSSLClient, false, true,
wincx));
UniqueCERTCertList certList(
CERT_FindUserCertsByUsage(CERT_GetDefaultCertDB(), certUsageSSLClient,
false, true, wincx));
if (!certList) {
goto noCert;
goto loser;
}
// filter the list to those issued by CAs supported by the server
mRV = CERT_FilterCertListByCANames(certList.get(), mCANames->nnames,
caNameStrings, certUsageSSLClient);
if (mRV != SECSuccess) {
goto noCert;
goto loser;
}
// make sure the list is not empty
node = CERT_LIST_HEAD(certList);
if (CERT_LIST_END(node, certList)) {
goto noCert;
if (CERT_LIST_END(CERT_LIST_HEAD(certList), certList)) {
goto loser;
}
UniqueCERTCertificate lowPrioNonrepCert;
// loop through the list until we find a cert with a key
while (!CERT_LIST_END(node, certList)) {
for (CERTCertListNode* node = CERT_LIST_HEAD(certList);
!CERT_LIST_END(node, certList);
node = CERT_LIST_NEXT(node)) {
// if the certificate has restriction and we do not satisfy it we do not
// use it
privKey.reset(PK11_FindKeyByAnyCert(node->cert, wincx));
@ -2192,13 +2189,10 @@ ClientAuthDataRunnable::RunOnTargetThread()
break;
}
}
keyError = PR_GetError();
if (keyError == SEC_ERROR_BAD_PASSWORD) {
if (PR_GetError() == SEC_ERROR_BAD_PASSWORD) {
// problem with password: bail
goto loser;
}
node = CERT_LIST_NEXT(node);
}
if (!cert && lowPrioNonrepCert) {
@ -2207,7 +2201,7 @@ ClientAuthDataRunnable::RunOnTargetThread()
}
if (!cert) {
goto noCert;
goto loser;
}
} else { // Not Auto => ask
// Get the SSL Certificate
@ -2229,30 +2223,22 @@ ClientAuthDataRunnable::RunOnTargetThread()
}
}
bool canceled = false;
if (hasRemembered) {
if (rememberedDBKey.IsEmpty()) {
canceled = true;
} else {
nsCOMPtr<nsIX509CertDB> certdb;
certdb = do_GetService(NS_X509CERTDB_CONTRACTID);
if (certdb) {
nsCOMPtr<nsIX509Cert> found_cert;
nsresult find_rv =
certdb->FindCertByDBKey(rememberedDBKey.get(),
getter_AddRefs(found_cert));
if (NS_SUCCEEDED(find_rv) && found_cert) {
nsNSSCertificate* obj_cert =
BitwiseCast<nsNSSCertificate*, nsIX509Cert*>(found_cert.get());
if (obj_cert) {
cert.reset(obj_cert->GetCert());
}
if (hasRemembered && !rememberedDBKey.IsEmpty()) {
nsCOMPtr<nsIX509CertDB> certdb = do_GetService(NS_X509CERTDB_CONTRACTID);
if (certdb) {
nsCOMPtr<nsIX509Cert> foundCert;
rv = certdb->FindCertByDBKey(rememberedDBKey.get(),
getter_AddRefs(foundCert));
if (NS_SUCCEEDED(rv) && foundCert) {
nsNSSCertificate* objCert =
BitwiseCast<nsNSSCertificate*, nsIX509Cert*>(foundCert.get());
if (objCert) {
cert.reset(objCert->GetCert());
}
}
if (!cert) {
hasRemembered = false;
}
if (!cert) {
hasRemembered = false;
}
}
}
@ -2260,17 +2246,14 @@ ClientAuthDataRunnable::RunOnTargetThread()
if (!hasRemembered) {
// user selects a cert to present
nsCOMPtr<nsIClientAuthDialogs> dialogs;
int32_t selectedIndex = -1;
char16_t** certNicknameList = nullptr;
char16_t** certDetailsList = nullptr;
// find all user certs that are for SSL
// note that we are allowing expired certs in this list
certList.reset(CERT_FindUserCertsByUsage(CERT_GetDefaultCertDB(),
certUsageSSLClient, false,
false, wincx));
UniqueCERTCertList certList(
CERT_FindUserCertsByUsage(CERT_GetDefaultCertDB(), certUsageSSLClient,
false, false, wincx));
if (!certList) {
goto noCert;
goto loser;
}
if (mCANames->nnames != 0) {
@ -2286,27 +2269,9 @@ ClientAuthDataRunnable::RunOnTargetThread()
if (CERT_LIST_END(CERT_LIST_HEAD(certList), certList)) {
// list is empty - no matching certs
goto noCert;
}
// filter it further for hostname restriction
node = CERT_LIST_HEAD(certList.get());
while (!CERT_LIST_END(node, certList.get())) {
++NumberOfCerts;
node = CERT_LIST_NEXT(node);
}
if (CERT_LIST_END(CERT_LIST_HEAD(certList.get()), certList.get())) {
goto noCert;
}
nicknames.reset(getNSSCertNicknamesFromCertList(certList));
if (!nicknames) {
goto loser;
}
NS_ASSERTION(nicknames->numnicknames == NumberOfCerts, "nicknames->numnicknames != NumberOfCerts");
// Get CN and O of the subject and O of the issuer
UniquePORTString ccn(CERT_GetCommonName(&mServerCert->subject));
NS_ConvertUTF8toUTF16 cn(ccn.get());
@ -2314,7 +2279,7 @@ ClientAuthDataRunnable::RunOnTargetThread()
int32_t port;
mSocketInfo->GetPort(&port);
nsString cn_host_port;
nsAutoString cn_host_port;
if (ccn && strcmp(ccn.get(), hostname) == 0) {
cn_host_port.Append(cn);
cn_host_port.Append(':');
@ -2333,91 +2298,61 @@ ClientAuthDataRunnable::RunOnTargetThread()
UniquePORTString cissuer(CERT_GetOrgName(&mServerCert->issuer));
NS_ConvertUTF8toUTF16 issuer(cissuer.get());
certNicknameList =
(char16_t**)moz_xmalloc(sizeof(char16_t*)* nicknames->numnicknames);
if (!certNicknameList)
goto loser;
certDetailsList =
(char16_t**)moz_xmalloc(sizeof(char16_t*)* nicknames->numnicknames);
if (!certDetailsList) {
free(certNicknameList);
nsCOMPtr<nsIMutableArray> certArray = nsArrayBase::Create();
if (!certArray) {
goto loser;
}
int32_t CertsToUse;
for (CertsToUse = 0, node = CERT_LIST_HEAD(certList);
!CERT_LIST_END(node, certList) && CertsToUse < nicknames->numnicknames;
node = CERT_LIST_NEXT(node)
) {
RefPtr<nsNSSCertificate> tempCert(nsNSSCertificate::Create(node->cert));
if (!tempCert)
continue;
NS_ConvertUTF8toUTF16 i_nickname(nicknames->nicknames[CertsToUse]);
nsAutoString nickWithSerial, details;
if (NS_FAILED(tempCert->FormatUIStrings(i_nickname, nickWithSerial, details)))
continue;
certNicknameList[CertsToUse] = ToNewUnicode(nickWithSerial);
if (!certNicknameList[CertsToUse])
continue;
certDetailsList[CertsToUse] = ToNewUnicode(details);
if (!certDetailsList[CertsToUse]) {
free(certNicknameList[CertsToUse]);
continue;
for (CERTCertListNode* node = CERT_LIST_HEAD(certList);
!CERT_LIST_END(node, certList);
node = CERT_LIST_NEXT(node)) {
nsCOMPtr<nsIX509Cert> tempCert = nsNSSCertificate::Create(node->cert);
if (!tempCert) {
goto loser;
}
++CertsToUse;
rv = certArray->AppendElement(tempCert, false);
if (NS_FAILED(rv)) {
goto loser;
}
}
// Throw up the client auth dialog and get back the index of the selected cert
nsresult rv = getNSSDialogs(getter_AddRefs(dialogs),
NS_GET_IID(nsIClientAuthDialogs),
NS_CLIENTAUTHDIALOGS_CONTRACTID);
rv = getNSSDialogs(getter_AddRefs(dialogs),
NS_GET_IID(nsIClientAuthDialogs),
NS_CLIENTAUTHDIALOGS_CONTRACTID);
if (NS_FAILED(rv)) {
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(CertsToUse, certNicknameList);
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(CertsToUse, certDetailsList);
goto loser;
}
rv = dialogs->ChooseCertificate(mSocketInfo, cn_host_port.get(),
org.get(), issuer.get(),
(const char16_t**)certNicknameList,
(const char16_t**)certDetailsList,
CertsToUse, &selectedIndex, &canceled);
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(CertsToUse, certNicknameList);
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(CertsToUse, certDetailsList);
if (NS_FAILED(rv)) goto loser;
uint32_t selectedIndex = 0;
bool certChosen = false;
rv = dialogs->ChooseCertificate(mSocketInfo, cn_host_port, org, issuer,
certArray, &selectedIndex, &certChosen);
if (NS_FAILED(rv)) {
goto loser;
}
// even if the user has canceled, we want to remember that, to avoid repeating prompts
bool wantRemember = false;
mSocketInfo->GetRememberClientAuthCertificate(&wantRemember);
int i;
if (!canceled)
for (i = 0, node = CERT_LIST_HEAD(certList);
!CERT_LIST_END(node, certList);
++i, node = CERT_LIST_NEXT(node)) {
if (i == selectedIndex) {
cert.reset(CERT_DupCertificate(node->cert));
break;
if (certChosen) {
nsCOMPtr<nsIX509Cert> selectedCert = do_QueryElementAt(certArray,
selectedIndex);
if (!selectedCert) {
goto loser;
}
cert.reset(selectedCert->GetCert());
}
if (cars && wantRemember) {
cars->RememberDecision(hostname, mServerCert,
canceled ? nullptr : cert.get());
certChosen ? cert.get() : nullptr);
}
}
if (canceled) { rv = NS_ERROR_NOT_AVAILABLE; goto loser; }
if (!cert) {
goto loser;
}
@ -2425,18 +2360,11 @@ ClientAuthDataRunnable::RunOnTargetThread()
// go get the private key
privKey.reset(PK11_FindKeyByAnyCert(cert.get(), wincx));
if (!privKey) {
keyError = PR_GetError();
if (keyError == SEC_ERROR_BAD_PASSWORD) {
// problem with password: bail
goto loser;
} else {
goto noCert;
}
goto loser;
}
}
goto done;
noCert:
loser:
if (mRV == SECSuccess) {
mRV = SECFailure;

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

@ -1817,7 +1817,8 @@ GeckoDriver.prototype.getElementProperty = function*(cmd, resp) {
break;
case Context.CONTENT:
return this.listener.getElementProperty(id, name);
resp.body.value = yield this.listener.getElementProperty(id, name);
break;
}
};

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

@ -137,7 +137,7 @@ class TestGetElementProperty(MarionetteTestCase):
self.assertIsInstance(prop, bool)
self.assertTrue(prop)
def test_missing_property_returns_false(self):
def test_missing_property_returns_default(self):
self.marionette.navigate(input)
el = self.marionette.find_element(By.TAG_NAME, "input")
prop = el.get_property("checked")

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

@ -1101,7 +1101,7 @@ function getElementAttribute(id, name) {
function getElementProperty(id, name) {
let el = seenEls.get(id, curContainer);
return el[name];
return typeof el[name] != "undefined" ? el[name] : null;
}
/**

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

@ -11,7 +11,7 @@ import utils
from mozlog import get_proxy_logger
# NOTE: we have a circular dependecy with output.py when we import results
# NOTE: we have a circular dependency with output.py when we import results
import results as TalosResults
LOG = get_proxy_logger()
@ -44,115 +44,6 @@ class Output(object):
"""
self.results = results
def __call__(self):
"""return list of results strings"""
raise NotImplementedError("Abstract base class")
def output(self, results, results_url, tbpl_output):
"""output to the results_url
- results_url : http:// or file:// URL
- results : list of results
"""
# parse the results url
results_url_split = utils.urlsplit(results_url)
results_scheme, results_server, results_path, _, _ = results_url_split
if results_scheme in ('http', 'https'):
self.post(results, results_server, results_path, results_scheme,
tbpl_output)
elif results_scheme == 'file':
with open(results_path, 'w') as f:
for result in results:
f.write("%s\n" % result)
else:
raise NotImplementedError(
"%s: %s - only http://, https://, and file:// supported"
% (self.__class__.__name__, results_url)
)
def post(self, results, server, path, scheme, tbpl_output):
raise NotImplementedError("Abstract base class")
@classmethod
def shortName(cls, name):
"""short name for counters"""
names = {"Working Set": "memset",
"% Processor Time": "%cpu",
"Private Bytes": "pbytes",
"RSS": "rss",
"XRes": "xres",
"Modified Page List Bytes": "modlistbytes",
"Main_RSS": "main_rss"}
return names.get(name, name)
@classmethod
def isMemoryMetric(cls, resultName):
"""returns if the result is a memory metric"""
memory_metric = ['memset', 'rss', 'pbytes', 'xres', 'modlistbytes',
'main_rss', 'content_rss'] # measured in bytes
return bool([i for i in memory_metric if i in resultName])
@classmethod
def v8_Metric(cls, val_list):
results = [i for i, j in val_list]
score = 100 * filter.geometric_mean(results)
return score
@classmethod
def JS_Metric(cls, val_list):
"""v8 benchmark score"""
results = [i for i, j in val_list]
LOG.info("javascript benchmark")
return sum(results)
@classmethod
def CanvasMark_Metric(cls, val_list):
"""CanvasMark benchmark score (NOTE: this is identical to JS_Metric)"""
results = [i for i, j in val_list]
LOG.info("CanvasMark benchmark")
return sum(results)
class PerfherderOutput(Output):
def __init__(self, results):
Output.__init__(self, results)
def output(self, results, results_url, tbpl_output):
"""output to the a file if results_url starts with file://
- results : json instance
- results_url : file:// URL
"""
# parse the results url
results_url_split = utils.urlsplit(results_url)
results_scheme, results_server, results_path, _, _ = results_url_split
# This is the output that treeherder expects to find when parsing the
# log file
LOG.info("PERFHERDER_DATA: %s" % json.dumps(results))
if results_scheme in ('file'):
json.dump(results, file(results_path, 'w'), indent=2,
sort_keys=True)
def post(self, results, server, path, scheme, tbpl_output):
"""conform to current code- not needed for perfherder"""
pass
def construct_results(self, vals, testname):
if 'responsiveness' in testname:
return filter.responsiveness_Metric([val for (val, page) in vals])
elif testname.startswith('v8_7'):
return self.v8_Metric(vals)
elif testname.startswith('kraken'):
return self.JS_Metric(vals)
elif testname.startswith('tcanvasmark'):
return self.CanvasMark_Metric(vals)
elif len(vals) > 1:
return filter.geometric_mean([i for i, j in vals])
else:
return filter.mean([i for i, j in vals])
def __call__(self):
suites = []
test_results = {
@ -278,5 +169,88 @@ class PerfherderOutput(Output):
'subtests': counter_subtests})
return test_results
# available output formats
formats = {'output_urls': PerfherderOutput}
def output(self, results, results_url, tbpl_output):
"""output to the a file if results_url starts with file://
- results : json instance
- results_url : file:// URL
"""
# parse the results url
results_url_split = utils.urlsplit(results_url)
results_scheme, results_server, results_path, _, _ = results_url_split
if results_scheme in ('http', 'https'):
self.post(results, results_server, results_path, results_scheme,
tbpl_output)
elif results_scheme == 'file':
with open(results_path, 'w') as f:
for result in results:
f.write("%s\n" % result)
else:
raise NotImplementedError(
"%s: %s - only http://, https://, and file:// supported"
% (self.__class__.__name__, results_url)
)
# This is the output that treeherder expects to find when parsing the
# log file
LOG.info("PERFHERDER_DATA: %s" % json.dumps(results))
if results_scheme in ('file'):
json.dump(results, file(results_path, 'w'), indent=2,
sort_keys=True)
def post(self, results, server, path, scheme, tbpl_output):
raise NotImplementedError("Abstract base class")
@classmethod
def shortName(cls, name):
"""short name for counters"""
names = {"Working Set": "memset",
"% Processor Time": "%cpu",
"Private Bytes": "pbytes",
"RSS": "rss",
"XRes": "xres",
"Modified Page List Bytes": "modlistbytes",
"Main_RSS": "main_rss"}
return names.get(name, name)
@classmethod
def isMemoryMetric(cls, resultName):
"""returns if the result is a memory metric"""
memory_metric = ['memset', 'rss', 'pbytes', 'xres', 'modlistbytes',
'main_rss', 'content_rss'] # measured in bytes
return bool([i for i in memory_metric if i in resultName])
@classmethod
def v8_Metric(cls, val_list):
results = [i for i, j in val_list]
score = 100 * filter.geometric_mean(results)
return score
@classmethod
def JS_Metric(cls, val_list):
"""v8 benchmark score"""
results = [i for i, j in val_list]
LOG.info("javascript benchmark")
return sum(results)
@classmethod
def CanvasMark_Metric(cls, val_list):
"""CanvasMark benchmark score (NOTE: this is identical to JS_Metric)"""
results = [i for i, j in val_list]
LOG.info("CanvasMark benchmark")
return sum(results)
def construct_results(self, vals, testname):
if 'responsiveness' in testname:
return filter.responsiveness_Metric([val for (val, page) in vals])
elif testname.startswith('v8_7'):
return self.v8_Metric(vals)
elif testname.startswith('kraken'):
return self.JS_Metric(vals)
elif testname.startswith('tcanvasmark'):
return self.CanvasMark_Metric(vals)
elif len(vals) > 1:
return filter.geometric_mean([i for i, j in vals])
else:
return filter.mean([i for i, j in vals])

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

@ -29,29 +29,6 @@ class TalosResults(object):
def add_extra_option(self, extra_option):
self.extra_options.append(extra_option)
def check_output_formats(self, output_formats):
"""check output formats"""
# ensure formats are available
formats = output_formats.keys()
missing = self.check_formats_exist(formats)
if missing:
raise utils.TalosError("Output format(s) unknown: %s"
% ','.join(missing))
# perform per-format check
for format, urls in output_formats.items():
cls = output.formats[format]
cls.check(urls)
@classmethod
def check_formats_exist(cls, formats):
"""
ensure that all formats are registered
return missing formats
"""
return [i for i in formats if i not in output.formats]
def output(self, output_formats):
"""
output all results to appropriate URLs
@ -62,7 +39,7 @@ class TalosResults(object):
try:
for key, urls in output_formats.items():
_output = output.formats[key](self)
_output = output.Output(self)
results = _output()
for url in urls:
_output.output(results, url, tbpl_output)

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

@ -178,7 +178,6 @@ def run_tests(config, browser_config):
else:
# local mode, output to files
results_urls = dict(output_urls=[os.path.abspath('local.json')])
talos_results.check_output_formats(results_urls)
httpd = setup_webserver(browser_config['webserver'])
httpd.start()

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

@ -11,7 +11,7 @@
<script>
test(function () {
var elements = ["iframe", "img", "a", "area"];
var elements = ["iframe", "img", "a", "area", "link"];
for (var i = 0; i < elements.length; i++) {
var elem = document.createElement(elements[i]);
elem.referrerPolicy = "unsafe-url";

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

@ -73,9 +73,13 @@ function checkPromptState(promptState, expectedState) {
is(promptState.butt1Disabled, false, "Checking cancel-button isn't disabled");
}
is(promptState.defButton0, expectedState.defButton == "button0", "checking button0 default");
is(promptState.defButton1, expectedState.defButton == "button1", "checking button1 default");
is(promptState.defButton2, expectedState.defButton == "button2", "checking button2 default");
if (isLinux && !promptState.focused) {
todo(false, "Checking button default fails if focus is not correct."); // bug 1278418
} else {
is(promptState.defButton0, expectedState.defButton == "button0", "checking button0 default");
is(promptState.defButton1, expectedState.defButton == "button1", "checking button1 default");
is(promptState.defButton2, expectedState.defButton == "button2", "checking button2 default");
}
if (isLinux && (!promptState.focused || isE10S)) {
todo(false, "Focus seems missing or wrong on Linux"); // bug 1265077

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

@ -109,9 +109,17 @@ nsPrefetchNode::OpenChannel()
}
nsCOMPtr<nsILoadGroup> loadGroup = source->OwnerDoc()->GetDocumentLoadGroup();
CORSMode corsMode = CORS_NONE;
net::ReferrerPolicy referrerPolicy = net::RP_Unset;
if (source->IsHTMLElement(nsGkAtoms::link)) {
corsMode = static_cast<dom::HTMLLinkElement*>(source.get())->GetCORSMode();
dom::HTMLLinkElement* link = static_cast<dom::HTMLLinkElement*>(source.get());
corsMode = link->GetCORSMode();
referrerPolicy = link->GetLinkReferrerPolicy();
}
if (referrerPolicy == net::RP_Unset) {
referrerPolicy = source->OwnerDoc()->GetReferrerPolicy();
}
uint32_t securityFlags;
if (corsMode == CORS_NONE) {
securityFlags = nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS;
@ -139,7 +147,7 @@ nsPrefetchNode::OpenChannel()
nsCOMPtr<nsIHttpChannel> httpChannel =
do_QueryInterface(mChannel);
if (httpChannel) {
httpChannel->SetReferrer(mReferrerURI);
httpChannel->SetReferrerWithPolicy(mReferrerURI, referrerPolicy);
httpChannel->SetRequestHeader(
NS_LITERAL_CSTRING("X-Moz"),
NS_LITERAL_CSTRING("prefetch"),