зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to fx-team, a=merge
This commit is contained in:
Коммит
bf02c9e2f4
|
@ -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"),
|
||||
|
|
Загрузка…
Ссылка в новой задаче