Merge mozilla-central to autoland. a=merge CLOSED TREE

This commit is contained in:
Margareta Eliza Balazs 2018-08-27 12:44:17 +03:00
commit a629c5e84f
17 changed files with 406 additions and 132 deletions

View File

@ -42,6 +42,7 @@ const SEC_ERROR_OCSP_INVALID_SIGNING_CERT = SEC_ERROR_BASE + 144;
const SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED = SEC_ERROR_BASE + 176;
const MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE = MOZILLA_PKIX_ERROR_BASE + 5;
const MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE = MOZILLA_PKIX_ERROR_BASE + 6;
const MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED = MOZILLA_PKIX_ERROR_BASE + 13;
const MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT = MOZILLA_PKIX_ERROR_BASE + 14;
const MOZILLA_PKIX_ERROR_MITM_DETECTED = MOZILLA_PKIX_ERROR_BASE + 15;
@ -146,6 +147,11 @@ class NetErrorChild extends ActorChild {
case MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT:
msg1 += gPipNSSBundle.GetStringFromName("certErrorTrust_SelfSigned") + "\n";
break;
// This error code currently only exists for the Symantec distrust, we may need to adjust
// it to fit other distrusts later.
case MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED:
msg1 += gPipNSSBundle.formatStringFromName("certErrorTrust_Symantec", [hostString], 1) + "\n";
break;
default:
msg1 += gPipNSSBundle.GetStringFromName("certErrorTrust_Untrusted") + "\n";
}
@ -365,6 +371,26 @@ class NetErrorChild extends ActorChild {
updateContainerPosition();
break;
// This error code currently only exists for the Symantec distrust
// in Firefox 63, so we add copy explaining that to the user.
// In case of future distrusts of that scale we might need to add
// additional parameters that allow us to identify the affected party
// without replicating the complex logic from certverifier code.
case MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED:
let description = gPipNSSBundle.formatStringFromName(
"certErrorSymantecDistrustDescription", [doc.location.hostname], 1);
let descriptionContainer = doc.getElementById("errorShortDescText2");
descriptionContainer.textContent = description;
let adminDescription = doc.createElement("p");
adminDescription.textContent =
gPipNSSBundle.GetStringFromName("certErrorSymantecDistrustAdministrator");
descriptionContainer.append(adminDescription);
learnMoreLink.href = baseURL + "symantec-warning";
updateContainerPosition();
break;
case MOZILLA_PKIX_ERROR_MITM_DETECTED:
case MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT:
learnMoreLink.href = baseURL + "security-error";

View File

@ -114,6 +114,11 @@
<div id="errorShortDesc">
<p id="errorShortDescText" />
</div>
<div id="errorShortDesc2">
<p id="errorShortDescText2" />
</div>
<p id="badStsCertExplanation" hidden="true">&certerror.whatShouldIDo.badStsCertExplanation;</p>
<div id="wrongSystemTimePanel">

View File

@ -702,11 +702,13 @@ ElementEditor.prototype = {
if (Services.prefs.getBoolPref("devtools.inspector.flexboxHighlighter.enabled") &&
(target.dataset.display === "flex" || target.dataset.display === "inline-flex")) {
this._displayBadge.classList.add("active");
this.highlighters.toggleFlexboxHighlighter(this.inspector.selection.nodeFront,
"markup");
}
if (target.dataset.display === "grid" || target.dataset.display === "inline-grid") {
this._displayBadge.classList.add("active");
this.highlighters.toggleGridHighlighter(this.inspector.selection.nodeFront,
"markup");
}

View File

@ -4,10 +4,13 @@
:root {
--markup-badge-active-background-color: var(--blue-50);
--markup-badge-background-color: var(--grey-20);
--markup-badge-active-border-color: #FFFFFFB3;
--markup-badge-background-color: white;
--markup-badge-border-color: #CACAD1;
--markup-badge-color: var(--grey-90);
--markup-badge-color: var(--grey-60);
--markup-badge-hover-background-color: #DFDFE8;
--markup-badge-interactive-background-color: var(--grey-20);
--markup-badge-interactive-color: var(--grey-90);
--markup-hidden-attr-name-color: #BA89B8;
--markup-hidden-attr-value-color: #5C6D87;
--markup-hidden-punctuation-color: #909090;
@ -17,10 +20,13 @@
.theme-dark:root {
--markup-badge-active-background-color: var(--blue-60);
--markup-badge-background-color: var(--grey-70);
--markup-badge-active-border-color: #FFF6;
--markup-badge-background-color: var(--grey-80);
--markup-badge-border-color: var(--grey-50);
--markup-badge-color: var(--grey-30);
--markup-badge-color: var(--grey-40);
--markup-badge-hover-background-color: var(--grey-80);
--markup-badge-interactive-background-color: var(--grey-70);
--markup-badge-interactive-color: var(--grey-30);
--markup-hidden-attr-name-color: #B07EB3;
--markup-hidden-attr-value-color: #9893A3;
--markup-hidden-punctuation-color: #909090;
@ -229,18 +235,21 @@ ul.children + .tag-line::before {
.expandable.collapsed .close::before {
/* Display an ellipsis character in collapsed nodes that can be expanded. */
content: "\2026";
content: "";
background-color: var(--markup-badge-interactive-background-color);
background-image: url(chrome://devtools/skin/images/more.svg);
background-repeat: no-repeat;
background-position: center;
border: 1px solid var(--markup-badge-border-color);
fill: var(--markup-badge-interactive-color);
vertical-align: middle;
display: inline-block;
width: 12px;
height: 8px;
margin: 0 2px;
line-height: 3px;
color: var(--theme-body-color-inactive);
border-radius: 3px;
border-style: solid;
border-width: 1px;
text-align: center;
vertical-align: middle;
-moz-context-properties: fill;
}
/* Hide HTML void elements (img, hr, br, ) closing tag when the element is not
@ -413,30 +422,33 @@ ul.children + .tag-line::before {
}
}
.markup-badge.active {
background-color: var(--markup-badge-active-background-color);
border-color: var(--theme-selection-color);
color: var(--theme-selection-color);
}
/* Markup badges that are interactive/clickable */
.markup-badge[data-custom],
.markup-badge[data-display="flex"].interactive,
.markup-badge[data-display="grid"],
.markup-badge[data-display="inline-flex"],
.markup-badge[data-display="inline-grid"],
.markup-badge[data-event] {
background-color: var(--markup-badge-interactive-background-color);
color: var(--markup-badge-interactive-color);
cursor: pointer;
}
.markup-badge[data-display="flex"].interactive:focus,
.markup-badge[data-display="flex"].interactive:hover,
.markup-badge[data-display="grid"]:focus,
.markup-badge[data-display="grid"]:hover,
.markup-badge[data-display="inline-flex"].interactive:focus,
.markup-badge[data-display="inline-flex"].interactive:hover,
.markup-badge[data-display="inline-grid"]:focus,
.markup-badge[data-display="inline-grid"]:hover,
.markup-badge[data-display="flex"]:not(.active).interactive:focus,
.markup-badge[data-display="flex"]:not(.active).interactive:hover,
.markup-badge[data-display="grid"]:not(.active):focus,
.markup-badge[data-display="grid"]:not(.active):hover,
.markup-badge[data-display="inline-flex"]:not(.active).interactive:focus,
.markup-badge[data-display="inline-flex"]:not(.active).interactive:hover,
.markup-badge[data-display="inline-grid"]:not(.active):focus,
.markup-badge[data-display="inline-grid"]:not(.active):hover,
.markup-badge[data-event]:focus,
.markup-badge[data-event]:hover {
background-color: var(--markup-badge-hover-background-color);
}
.markup-badge.active {
background-color: var(--markup-badge-active-background-color);
border-color: var(--markup-badge-active-border-color);
color: var(--theme-selection-color);
}

View File

@ -65,8 +65,8 @@ var PromisesActor = protocol.ActorClassWithSpec(promisesSpec, {
this._newPromises = [];
this._promisesSettled = [];
this.dbg.findScripts().forEach(s => {
this.parentActor.sources.createSourceActors(s.source);
this.dbg.findSources().forEach(source => {
this.parentActor.sources.createSourceActors(source);
});
this.dbg.onNewScript = s => {

View File

@ -170,11 +170,23 @@ ReplayDebugger.prototype = {
/////////////////////////////////////////////////////////
_getSource(id) {
if (!this._scriptSources[id]) {
const data = this._sendRequest({ type: "getSource", id });
this._scriptSources[id] = new ReplayDebuggerScriptSource(this, data);
const source = this._scriptSources[id];
if (source) {
return source;
}
return this._scriptSources[id];
return this._addSource(this._sendRequest({ type: "getSource", id }));
},
_addSource(data) {
if (!this._scriptSources[data.id]) {
this._scriptSources[data.id] = new ReplayDebuggerScriptSource(this, data);
}
return this._scriptSources[data.id];
},
findSources() {
const data = this._sendRequest({ type: "findSources" });
return data.map(source => this._addSource(source));
},
/////////////////////////////////////////////////////////

View File

@ -465,6 +465,22 @@ function getScriptData(id) {
};
}
function getSourceData(id) {
const source = gScriptSources.getObject(id);
const introductionScript = gScripts.getId(source.introductionScript);
return {
id: id,
text: source.text,
url: source.url,
displayURL: source.displayURL,
elementAttributeName: source.elementAttributeName,
introductionScript,
introductionOffset: introductionScript ? source.introductionOffset : undefined,
introductionType: source.introductionType,
sourceMapURL: source.sourceMapURL,
};
}
function forwardToScript(name) {
return request => gScripts.getObject(request.id)[name](request.value);
}
@ -495,20 +511,16 @@ const gRequestHandlers = {
return RecordReplayControl.getContent(request.url);
},
findSources(request) {
const sources = [];
gScriptSources.forEach((id) => {
sources.push(getSourceData(id));
});
return sources;
},
getSource(request) {
const source = gScriptSources.getObject(request.id);
const introductionScript = gScripts.getId(source.introductionScript);
return {
id: request.id,
text: source.text,
url: source.url,
displayURL: source.displayURL,
elementAttributeName: source.elementAttributeName,
introductionScript,
introductionOffset: introductionScript ? source.introductionOffset : undefined,
introductionType: source.introductionType,
sourceMapURL: source.sourceMapURL,
};
return getSourceData(request.id);
},
getObject(request) {

View File

@ -1111,22 +1111,12 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
},
/**
* Get the script and source lists from the debugger.
* Get the source lists from the debugger.
*/
_discoverSources: function() {
// Only get one script per Debugger.Source.
const sourcesToScripts = new Map();
const scripts = this.dbg.findScripts();
for (let i = 0, len = scripts.length; i < len; i++) {
const s = scripts[i];
if (s.source) {
sourcesToScripts.set(s.source, s);
}
}
return Promise.all([...sourcesToScripts.values()].map(script => {
return this.sources.createSourceActors(script.source);
const sources = this.dbg.findSources();
return Promise.all(sources.map(source => {
return this.sources.createSourceActors(source);
}));
},

View File

@ -357,26 +357,10 @@ other kinds of objects.
[visible frame][vf] currently on the calling thread's stack, or `null`
if there are no visible frames on the stack.
<code>findSources([<i>query</i>]) <i>(not yet implemented)</i></code>
: Return an array of all [`Debugger.Source`][source] instances matching
<i>query</i>. Each source appears only once in the array. <i>Query</i>
is an object whose properties restrict which sources are returned; a
source must meet all the criteria given by <i>query</i> to be returned.
If <i>query</i> is omitted, we return all sources of all debuggee
<code>findSources()</code>
: Return an array of all [`Debugger.Source`][source] instances of all debuggee
scripts.
<i>Query</i> may have the following properties:
`url`
: The source's `url` property must be equal to this value.
`global`
: The source must have been evaluated in the scope of the given global
object. If this property's value is a [`Debugger.Object`][object] instance
belonging to this `Debugger` instance, then its referent is used. If the
object is not a global object, then the global in whose scope it was
allocated is used.
Note that the result may include sources that can no longer ever be
used by the debuggee: say, eval code that has finished running, or
source for unreachable functions. Whether such sources appear can be

View File

@ -0,0 +1,4 @@
// In a debugger with no debuggees, findSources should return no scripts.
const dbg = new Debugger;
assertEq(dbg.findSources().length, 0);

View File

@ -0,0 +1,15 @@
// In a debugger with scripts, findSources finds the script source.
const g = newGlobal();
// Declare a function in order to keep the script source alive across GC.
g.evaluate(`function fa() {}`, { fileName: "a.js" });
g.evaluate(`function fb() {}`, { fileName: "b.js" });
g.evaluate(`function fc() {}`, { fileName: "c.js" });
const dbg = new Debugger();
const gw = dbg.addDebuggee(g);
const sources = dbg.findSources();
assertEq(sources.filter(s => s.url == "a.js").length, 1);
assertEq(sources.filter(s => s.url == "b.js").length, 1);
assertEq(sources.filter(s => s.url == "c.js").length, 1);

View File

@ -0,0 +1,19 @@
// In a debugger with multiple debuggees, findSources finds script sources across all debuggees.
const g1 = newGlobal();
const g2 = newGlobal();
// Declare a function in order to keep the script source alive across GC.
g1.evaluate(`function fa() {}`, { fileName: "a.js" });
g1.evaluate(`function fb() {}`, { fileName: "b.js" });
g2.evaluate(`function fc() {}`, { fileName: "c.js" });
g2.evaluate(`function fd() {}`, { fileName: "d.js" });
const dbg = new Debugger();
const g1w = dbg.addDebuggee(g1);
const g2w = dbg.addDebuggee(g2);
const sources = dbg.findSources();
assertEq(dbg.findSources().filter(s => s.url == "a.js").length, 1);
assertEq(dbg.findSources().filter(s => s.url == "b.js").length, 1);
assertEq(dbg.findSources().filter(s => s.url == "c.js").length, 1);
assertEq(dbg.findSources().filter(s => s.url == "d.js").length, 1);

View File

@ -4188,19 +4188,73 @@ Debugger::removeDebuggeeGlobal(FreeOp* fop, GlobalObject* global,
static inline DebuggerSourceReferent GetSourceReferent(JSObject* obj);
class MOZ_STACK_CLASS Debugger::QueryBase
{
protected:
QueryBase(JSContext* cx, Debugger* dbg)
: cx(cx),
debugger(dbg),
iterMarker(&cx->runtime()->gc),
realms(cx->zone()),
oom(false)
{}
// The context in which we should do our work.
JSContext* cx;
// The debugger for which we conduct queries.
Debugger* debugger;
// Require the set of realms to stay fixed while this query is alive.
gc::AutoEnterIteration iterMarker;
using RealmSet = HashSet<Realm*, DefaultHasher<Realm*>, ZoneAllocPolicy>;
// A script must be in one of these realms to match the query.
RealmSet realms;
// Indicates whether OOM has occurred while matching.
bool oom;
bool addRealm(Realm* realm) {
return realms.put(realm);
}
// Arrange for this query to match only scripts that run in |global|.
bool matchSingleGlobal(GlobalObject* global) {
MOZ_ASSERT(realms.count() == 0);
if (!addRealm(global->realm())) {
ReportOutOfMemory(cx);
return false;
}
return true;
}
// Arrange for this ScriptQuery to match all scripts running in debuggee
// globals.
bool matchAllDebuggeeGlobals() {
MOZ_ASSERT(realms.count() == 0);
// Build our realm set from the debugger's set of debuggee globals.
for (WeakGlobalObjectSet::Range r = debugger->debuggees.all(); !r.empty(); r.popFront()) {
if (!addRealm(r.front()->realm())) {
ReportOutOfMemory(cx);
return false;
}
}
return true;
}
};
/*
* A class for parsing 'findScripts' query arguments and searching for
* scripts that match the criteria they represent.
*/
class MOZ_STACK_CLASS Debugger::ScriptQuery
class MOZ_STACK_CLASS Debugger::ScriptQuery : public Debugger::QueryBase
{
public:
/* Construct a ScriptQuery to use matching scripts for |dbg|. */
ScriptQuery(JSContext* cx, Debugger* dbg):
cx(cx),
debugger(dbg),
iterMarker(&cx->runtime()->gc),
realms(cx->zone()),
ScriptQuery(JSContext* cx, Debugger* dbg)
: QueryBase(cx, dbg),
url(cx),
displayURLString(cx),
hasSource(false),
@ -4211,8 +4265,7 @@ class MOZ_STACK_CLASS Debugger::ScriptQuery
innermostForRealm(cx->zone()),
scriptVector(cx, ScriptVector(cx)),
lazyScriptVector(cx, LazyScriptVector(cx)),
wasmInstanceVector(cx, WasmInstanceObjectVector(cx)),
oom(false)
wasmInstanceVector(cx, WasmInstanceObjectVector(cx))
{}
/*
@ -4436,20 +4489,6 @@ class MOZ_STACK_CLASS Debugger::ScriptQuery
}
private:
/* The context in which we should do our work. */
JSContext* cx;
/* The debugger for which we conduct queries. */
Debugger* debugger;
/* Require the set of realms to stay fixed while the ScriptQuery is alive. */
gc::AutoEnterIteration iterMarker;
using RealmSet = HashSet<Realm*, DefaultHasher<Realm*>, ZoneAllocPolicy>;
/* A script must be in one of these realms to match the query. */
RealmSet realms;
/* If this is a string, matching scripts have urls equal to it. */
RootedValue url;
@ -4499,39 +4538,6 @@ class MOZ_STACK_CLASS Debugger::ScriptQuery
*/
Rooted<WasmInstanceObjectVector> wasmInstanceVector;
/* Indicates whether OOM has occurred while matching. */
bool oom;
bool addRealm(Realm* realm) {
return realms.put(realm);
}
/* Arrange for this ScriptQuery to match only scripts that run in |global|. */
bool matchSingleGlobal(GlobalObject* global) {
MOZ_ASSERT(realms.count() == 0);
if (!addRealm(global->realm())) {
ReportOutOfMemory(cx);
return false;
}
return true;
}
/*
* Arrange for this ScriptQuery to match all scripts running in debuggee
* globals.
*/
bool matchAllDebuggeeGlobals() {
MOZ_ASSERT(realms.count() == 0);
// Build our realm set from the debugger's set of debuggee globals.
for (WeakGlobalObjectSet::Range r = debugger->debuggees.all(); !r.empty(); r.popFront()) {
if (!addRealm(r.front()->realm())) {
ReportOutOfMemory(cx);
return false;
}
}
return true;
}
/*
* Given that parseQuery or omittedQuery has been called, prepare to match
* scripts. Set urlCString and displayURLChars as appropriate.
@ -4765,6 +4771,160 @@ Debugger::findScripts(JSContext* cx, unsigned argc, Value* vp)
return true;
}
/*
* A class for searching sources for 'findSources'.
*/
class MOZ_STACK_CLASS Debugger::SourceQuery : public Debugger::QueryBase
{
public:
using SourceSet = JS::GCHashSet<JSObject*,
js::MovableCellHasher<JSObject*>,
ZoneAllocPolicy>;
SourceQuery(JSContext* cx, Debugger* dbg)
: QueryBase(cx, dbg),
sources(cx, SourceSet(cx->zone()))
{}
bool findSources() {
if (!matchAllDebuggeeGlobals())
return false;
Realm* singletonRealm = nullptr;
if (realms.count() == 1)
singletonRealm = realms.all().front();
// Search each realm for debuggee scripts.
MOZ_ASSERT(sources.empty());
oom = false;
IterateScripts(cx, singletonRealm, this, considerScript);
IterateLazyScripts(cx, singletonRealm, this, considerLazyScript);
if (oom) {
ReportOutOfMemory(cx);
return false;
}
// TODO: Until such time that wasm modules are real ES6 modules,
// unconditionally consider all wasm toplevel instance scripts.
for (WeakGlobalObjectSet::Range r = debugger->allDebuggees(); !r.empty(); r.popFront()) {
for (wasm::Instance* instance : r.front()->realm()->wasm.instances()) {
consider(instance->object());
if (oom) {
ReportOutOfMemory(cx);
return false;
}
}
}
return true;
}
Handle<SourceSet> foundSources() const {
return sources;
}
private:
Rooted<SourceSet> sources;
static void considerScript(JSRuntime* rt, void* data, JSScript* script,
const JS::AutoRequireNoGC& nogc) {
SourceQuery* self = static_cast<SourceQuery*>(data);
self->consider(script, nogc);
}
static void considerLazyScript(JSRuntime* rt, void* data, LazyScript* lazyScript,
const JS::AutoRequireNoGC& nogc) {
SourceQuery* self = static_cast<SourceQuery*>(data);
self->consider(lazyScript, nogc);
}
void consider(JSScript* script, const JS::AutoRequireNoGC& nogc) {
if (oom || script->selfHosted())
return;
Realm* realm = script->realm();
if (!realms.has(realm))
return;
if (!script->sourceObject())
return;
ScriptSourceObject* source =
&UncheckedUnwrap(script->sourceObject())->as<ScriptSourceObject>();
if (!sources.put(source))
oom = true;
}
void consider(LazyScript* lazyScript, const JS::AutoRequireNoGC& nogc) {
if (oom)
return;
Realm* realm = lazyScript->realm();
if (!realms.has(realm))
return;
// If the script is already delazified, it should already be handled.
if (lazyScript->maybeScript())
return;
ScriptSourceObject* source = &lazyScript->sourceObject();
if (!sources.put(source))
oom = true;
}
void consider(WasmInstanceObject* instanceObject) {
if (oom)
return;
if (!sources.put(instanceObject))
oom = true;
}
};
static inline DebuggerSourceReferent
AsSourceReferent(JSObject* obj)
{
if (obj->is<ScriptSourceObject>()) {
return AsVariant(&obj->as<ScriptSourceObject>());
}
return AsVariant(&obj->as<WasmInstanceObject>());
}
/* static */ bool
Debugger::findSources(JSContext* cx, unsigned argc, Value* vp)
{
THIS_DEBUGGER(cx, argc, vp, "findSources", args, dbg);
if (gc::GCRuntime::temporaryAbortIfWasmGc(cx)) {
JS_ReportErrorASCII(cx, "API temporarily unavailable under wasm gc");
return false;
}
SourceQuery query(cx, dbg);
if (!query.findSources())
return false;
Handle<SourceQuery::SourceSet> sources(query.foundSources());
size_t resultLength = sources.count();
RootedArrayObject result(cx, NewDenseFullyAllocatedArray(cx, resultLength));
if (!result)
return false;
result->ensureDenseInitializedLength(cx, 0, resultLength);
size_t i = 0;
for (auto iter = sources.get().iter(); !iter.done(); iter.next()) {
Rooted<DebuggerSourceReferent> sourceReferent(cx, AsSourceReferent(iter.get()));
RootedObject sourceObject(cx, dbg->wrapVariantReferent(cx, sourceReferent));
if (!sourceObject)
return false;
result->setDenseElement(i, ObjectValue(*sourceObject));
i++;
}
args.rval().setObject(*result);
return true;
}
/*
* A class for parsing 'findObjects' query arguments and searching for objects
* that match the criteria they represent.
@ -5181,6 +5341,7 @@ const JSFunctionSpec Debugger::methods[] = {
JS_FN("getNewestFrame", Debugger::getNewestFrame, 0, 0),
JS_FN("clearAllBreakpoints", Debugger::clearAllBreakpoints, 0, 0),
JS_FN("findScripts", Debugger::findScripts, 1, 0),
JS_FN("findSources", Debugger::findSources, 1, 0),
JS_FN("findObjects", Debugger::findObjects, 1, 0),
JS_FN("findAllGlobals", Debugger::findAllGlobals, 0, 0),
JS_FN("makeGlobalObjectReference", Debugger::makeGlobalObjectReference, 1, 0),

View File

@ -566,7 +566,9 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
uint32_t traceLoggerScriptedCallsLastDrainedSize;
uint32_t traceLoggerScriptedCallsLastDrainedIteration;
class QueryBase;
class ScriptQuery;
class SourceQuery;
class ObjectQuery;
MOZ_MUST_USE bool addDebuggeeGlobal(JSContext* cx, Handle<GlobalObject*> obj);
@ -718,6 +720,7 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
static bool getNewestFrame(JSContext* cx, unsigned argc, Value* vp);
static bool clearAllBreakpoints(JSContext* cx, unsigned argc, Value* vp);
static bool findScripts(JSContext* cx, unsigned argc, Value* vp);
static bool findSources(JSContext* cx, unsigned argc, Value* vp);
static bool findObjects(JSContext* cx, unsigned argc, Value* vp);
static bool findAllGlobals(JSContext* cx, unsigned argc, Value* vp);
static bool makeGlobalObjectReference(JSContext* cx, unsigned argc, Value* vp);

View File

@ -116,8 +116,8 @@
<div id="whatShouldIDoContent">
<h2>&certerror.whatShouldIDo.heading;</h2>
<div id="whatShouldIDoContentText">
<p>&certerror.whatShouldIDo.content;</p>
<div>
<p id="whatShouldIDoContentText">&certerror.whatShouldIDo.content;</p>
<button id="getMeOutOfHereButton">&certerror.getMeOutOfHere.label;</button>
</div>
</div>

View File

@ -91,6 +91,7 @@ const SEC_ERROR_REUSED_ISSUER_AND_SERIAL = SEC_ERROR_BASE + 138;
const SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED = SEC_ERROR_BASE + 176;
const MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE = MOZILLA_PKIX_ERROR_BASE + 5;
const MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE = MOZILLA_PKIX_ERROR_BASE + 6;
const MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED = MOZILLA_PKIX_ERROR_BASE + 13;
const SSL_ERROR_BASE = Ci.nsINSSErrorsService.NSS_SSL_ERROR_BASE;
@ -203,6 +204,11 @@ var AboutCertErrorListener = {
case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
msg += gPipNSSBundle.GetStringFromName("certErrorTrust_ExpiredIssuer") + "\n";
break;
// This error code currently only exists for the Symantec distrust, we may need to adjust
// it to fit other distrusts later.
case MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED:
msg += gPipNSSBundle.formatStringFromName("certErrorTrust_Symantec", [hostString], 1) + "\n";
break;
case SEC_ERROR_UNTRUSTED_CERT:
default:
msg += gPipNSSBundle.GetStringFromName("certErrorTrust_Untrusted") + "\n";
@ -234,6 +240,23 @@ var AboutCertErrorListener = {
hostString += ":" + uri.port;
}
// This error code currently only exists for the Symantec distrust
// in Firefox 63, so we add copy explaining that to the user.
// In case of future distrusts of that scale we might need to add
// additional parameters that allow us to identify the affected party
// without replicating the complex logic from certverifier code.
if (securityInfo.errorCode == MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED) {
let introContent = doc.getElementById("introContent");
let description = doc.createElement("p");
description.textContent = gPipNSSBundle.formatStringFromName(
"certErrorSymantecDistrustDescription", [hostString], 1);
introContent.append(description);
// The regular "what should I do" message does not make sense in this case.
doc.getElementById("whatShouldIDoContentText").textContent =
gPipNSSBundle.GetStringFromName("certErrorSymantecDistrustAdministrator");
}
this._setTechDetailsMsgPart1(hostString, sslStatus, securityInfo, technicalInfo, doc);
if (sslStatus.isDomainMismatch) {

View File

@ -287,6 +287,8 @@ certErrorTrust_SignatureAlgorithmDisabled=The certificate is not trusted because
certErrorTrust_ExpiredIssuer=The certificate is not trusted because the issuer certificate has expired.
certErrorTrust_Untrusted=The certificate does not come from a trusted source.
certErrorTrust_MitM=Your connection is being intercepted by a TLS proxy. Uninstall it if possible or configure your device to trust its root certificate.
# LOCALIZATION NOTE (certErrorTrust_Symantec): %S is replaced by the domain for which the certificate is valid
certErrorTrust_Symantec=The security certificate for %S is not trustworthy because the issuing organization failed to follow security practices. Certificates issued by Symantec, including the Thawte, GeoTrust, and RapidSSL brands, are not considered safe.
certErrorMismatch=The certificate is not valid for the name %S.
# LOCALIZATION NOTE (certErrorMismatch1, certErrorMismatchSinglePrefix1, certErrorMismatchMultiple1): %1$S is replaced by the brand name, %2$S is replaced by host name.
@ -306,6 +308,10 @@ certErrorExpiredNow1=Websites prove their identity via security certificates, wh
certErrorNotYetValidNow=The certificate will not be valid until %1$S. The current time is %2$S.
certErrorNotYetValidNow1=Websites prove their identity via security certificates, which are valid for a set time period. The security certificate for %S appears to be not yet valid.
# LOCALIZATION NOTE (certErrorSymantecDistrustDescription): %S will be replaced by the domain for which the certificate is valid.
certErrorSymantecDistrustDescription=Websites prove their identity via certificates, which are issued by certificate authorities. Most browsers will no longer trust Symantec, the certificate authority for %S.
certErrorSymantecDistrustAdministrator=You may notify the websites administrator about this problem.
# LOCALIZATION NOTE (certErrorCodePrefix3): %S is replaced by the error code.
certErrorCodePrefix3=Error code: %S