зеркало из https://github.com/mozilla/gecko-dev.git
Merge autoland to mozilla-central. a=merge
This commit is contained in:
Коммит
8b42ade55d
|
@ -135,18 +135,6 @@ option(env='OLD_CONFIGURE', nargs=1, help='Path to the old configure script')
|
|||
|
||||
option(env='MOZCONFIG', nargs=1, help='Mozconfig location')
|
||||
|
||||
option('--with-external-source-dir', env='EXTERNAL_SOURCE_DIR', nargs=1,
|
||||
help='External directory containing additional build files')
|
||||
|
||||
|
||||
@depends('--with-external-source-dir')
|
||||
def external_source_dir(value):
|
||||
if value:
|
||||
return value[0]
|
||||
|
||||
|
||||
set_config('EXTERNAL_SOURCE_DIR', external_source_dir)
|
||||
add_old_configure_assignment('EXTERNAL_SOURCE_DIR', external_source_dir)
|
||||
|
||||
# Read user mozconfig
|
||||
# ==============================================================
|
||||
|
@ -155,13 +143,11 @@ add_old_configure_assignment('EXTERNAL_SOURCE_DIR', external_source_dir)
|
|||
# be called when --help is passed, and the mozconfig wouldn't be read.
|
||||
|
||||
|
||||
@depends('MOZCONFIG', 'OLD_CONFIGURE',
|
||||
check_build_environment, '--with-external-source-dir',
|
||||
@depends('MOZCONFIG', 'OLD_CONFIGURE', check_build_environment,
|
||||
'--help')
|
||||
@imports(_from='mozbuild.mozconfig', _import='MozconfigLoader')
|
||||
@imports(_from='mozboot.mozconfig', _import='find_mozconfig')
|
||||
def mozconfig(mozconfig, old_configure, build_env,
|
||||
external_source_dir, help):
|
||||
def mozconfig(mozconfig, old_configure, build_env, help):
|
||||
if not old_configure and not help:
|
||||
die('The OLD_CONFIGURE environment variable must be set')
|
||||
|
||||
|
@ -185,8 +171,6 @@ def mozconfig(mozconfig, old_configure, build_env,
|
|||
return {'path': None}
|
||||
|
||||
topsrcdir = build_env.topsrcdir
|
||||
if external_source_dir:
|
||||
topsrcdir = external_source_dir[0]
|
||||
loader = MozconfigLoader(topsrcdir)
|
||||
mozconfig = mozconfig[0] if mozconfig else None
|
||||
mozconfig = find_mozconfig(topsrcdir, env={'MOZCONFIG': mozconfig})
|
||||
|
@ -1100,17 +1084,13 @@ def target_is_sparc(target):
|
|||
set_define('SPARC64', target_is_sparc)
|
||||
|
||||
|
||||
@depends('--enable-project', '--with-external-source-dir',
|
||||
check_build_environment, '--help')
|
||||
@depends('--enable-project', check_build_environment, '--help')
|
||||
@imports(_from='os.path', _import='exists')
|
||||
def include_project_configure(project, external_source_dir, build_env, help):
|
||||
def include_project_configure(project, build_env, help):
|
||||
if not project:
|
||||
die('--enable-project is required.')
|
||||
|
||||
base_dir = build_env.topsrcdir
|
||||
if external_source_dir:
|
||||
base_dir = os.path.join(base_dir, external_source_dir[0])
|
||||
|
||||
path = os.path.join(base_dir, project[0], 'moz.configure')
|
||||
if not exists(path):
|
||||
die('Cannot find project %s', project[0])
|
||||
|
|
|
@ -273,6 +273,11 @@ class DebuggerPanel {
|
|||
}
|
||||
|
||||
destroy() {
|
||||
const resourceWatcher = this.toolbox.resourceWatcher;
|
||||
resourceWatcher.unwatchResources([resourceWatcher.TYPES.ERROR_MESSAGE], {
|
||||
onAvailable: this._actions.addExceptionFromResources,
|
||||
});
|
||||
|
||||
this.panelWin.Debugger.destroy();
|
||||
this.emit("destroyed");
|
||||
}
|
||||
|
|
|
@ -783,9 +783,10 @@ Toolbox.prototype = {
|
|||
// there is always at least one listener existing for network events across
|
||||
// the lifetime of the various panels, so stopping the resource watcher from
|
||||
// clearing out its cache of network event resources.
|
||||
this.noopNetworkEventListener = () => {};
|
||||
await this.resourceWatcher.watchResources(
|
||||
[this.resourceWatcher.TYPES.NETWORK_EVENT],
|
||||
{ onAvailable: () => {}, onUpdated: () => {} }
|
||||
{ onAvailable: this.noopNetworkEventListener }
|
||||
);
|
||||
|
||||
await domReady;
|
||||
|
@ -3642,6 +3643,10 @@ Toolbox.prototype = {
|
|||
this._onTargetAvailable,
|
||||
this._onTargetDestroyed
|
||||
);
|
||||
this.resourceWatcher.unwatchResources(
|
||||
[this.resourceWatcher.TYPES.NETWORK_EVENT],
|
||||
{ onAvailable: this.noopNetworkEventListener }
|
||||
);
|
||||
|
||||
this.targetList.destroy();
|
||||
|
||||
|
|
|
@ -1671,11 +1671,16 @@ Inspector.prototype = {
|
|||
this.styleChangeTracker.destroy();
|
||||
this.searchboxShortcuts.destroy();
|
||||
|
||||
this.toolbox.targetList.unwatchTargets(
|
||||
[this.toolbox.targetList.TYPES.FRAME],
|
||||
const { targetList, resourceWatcher } = this.toolbox;
|
||||
targetList.unwatchTargets(
|
||||
[targetList.TYPES.FRAME],
|
||||
this._onTargetAvailable,
|
||||
this._onTargetDestroyed
|
||||
);
|
||||
resourceWatcher.unwatchResources(
|
||||
[resourceWatcher.TYPES.ROOT_NODE, resourceWatcher.TYPES.CSS_CHANGE],
|
||||
{ onAvailable: this.onResourceAvailable }
|
||||
);
|
||||
|
||||
this._is3PaneModeChromeEnabled = null;
|
||||
this._is3PaneModeEnabled = null;
|
||||
|
|
|
@ -116,9 +116,12 @@ async function navigateIframeTo(inspector, url) {
|
|||
const { resourceWatcher, targetList } = inspector.toolbox;
|
||||
const onTargetProcessed = waitForTargetProcessed(targetList, url);
|
||||
|
||||
const onNewRoot = waitForResourceOnce(
|
||||
const onNewRoot = waitForNextResource(
|
||||
resourceWatcher,
|
||||
resourceWatcher.TYPES.ROOT_NODE
|
||||
resourceWatcher.TYPES.ROOT_NODE,
|
||||
{
|
||||
ignoreExistingResources: true,
|
||||
}
|
||||
);
|
||||
|
||||
info("Update the src attribute of the iframe tag");
|
||||
|
|
|
@ -90,7 +90,7 @@ PerformancePanel.prototype = {
|
|||
this._checkRecordingStatus
|
||||
);
|
||||
|
||||
await this.toolbox.targetList.unwatchTargets(
|
||||
this.toolbox.targetList.unwatchTargets(
|
||||
[this.toolbox.targetList.TYPES.FRAME],
|
||||
this._onTargetAvailable
|
||||
);
|
||||
|
|
|
@ -1181,18 +1181,34 @@ function getCurrentTestFilePath() {
|
|||
* The ResourceWatcher instance that should emit the expected resource.
|
||||
* @param {String} resourceType
|
||||
* One of ResourceWatcher.TYPES, type of the expected resource.
|
||||
* @param {Object} additional options
|
||||
* - {Boolean} ignoreExistingResources: ignore existing resources or not.
|
||||
* - {Function} predicate: if provided, will wait until a resource makes
|
||||
* predicate(resource) return true.
|
||||
* @return {Object}
|
||||
* - resource {Object} the resource itself
|
||||
* - targetFront {TargetFront} the target which owns the resource
|
||||
*/
|
||||
function waitForResourceOnce(resourceWatcher, resourceType) {
|
||||
function waitForNextResource(
|
||||
resourceWatcher,
|
||||
resourceType,
|
||||
{ ignoreExistingResources = false, predicate } = {}
|
||||
) {
|
||||
// If no predicate was provided, convert to boolean to avoid resolving for
|
||||
// empty `resources` arrays.
|
||||
predicate = predicate || (resource => !!resource);
|
||||
|
||||
return new Promise(resolve => {
|
||||
const onAvailable = resources => {
|
||||
resolve(resources[0]);
|
||||
resourceWatcher.unwatchResources([resourceType], { onAvailable });
|
||||
const matchingResource = resources.find(resource => predicate(resource));
|
||||
if (matchingResource) {
|
||||
resolve(matchingResource);
|
||||
resourceWatcher.unwatchResources([resourceType], { onAvailable });
|
||||
}
|
||||
};
|
||||
|
||||
resourceWatcher.watchResources([resourceType], {
|
||||
ignoreExistingResources: true,
|
||||
ignoreExistingResources,
|
||||
onAvailable,
|
||||
});
|
||||
});
|
||||
|
|
|
@ -210,6 +210,7 @@ class WebConsoleUI {
|
|||
resourceWatcher.TYPES.ERROR_MESSAGE,
|
||||
resourceWatcher.TYPES.PLATFORM_MESSAGE,
|
||||
resourceWatcher.TYPES.NETWORK_EVENT,
|
||||
resourceWatcher.TYPES.NETWORK_EVENT_STACKTRACE,
|
||||
],
|
||||
{
|
||||
onAvailable: this._onResourceAvailable,
|
||||
|
|
|
@ -36,7 +36,6 @@ exports.ANIMATION_TYPE_FOR_LONGHANDS = [
|
|||
"-moz-box-orient",
|
||||
"-moz-box-pack",
|
||||
"box-sizing",
|
||||
"-moz-button-appearance",
|
||||
"caption-side",
|
||||
"clear",
|
||||
"clip-rule",
|
||||
|
|
|
@ -100,6 +100,12 @@ class Actor extends Pool {
|
|||
console.error(error.stack);
|
||||
}
|
||||
|
||||
// Do not try to send the error if the actor is destroyed
|
||||
// as the connection is probably also destroyed and may throw.
|
||||
if (this.isDestroyed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.conn.send({
|
||||
from: this.actorID,
|
||||
// error.error -> errors created using the throwError() helper
|
||||
|
@ -170,6 +176,13 @@ var generateRequestHandlers = function(actorSpec, actorProto) {
|
|||
// No need to send a response.
|
||||
return;
|
||||
}
|
||||
if (this.isDestroyed()) {
|
||||
console.error(
|
||||
`Tried to send a '${spec.name}' method reply on an already destroyed actor` +
|
||||
` '${this.typeName}'`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
let response;
|
||||
try {
|
||||
|
|
|
@ -171,23 +171,22 @@ class ResourceWatcher {
|
|||
* It will only listen for types which are defined by `TargetList.startListening`.
|
||||
*/
|
||||
async _watchAllTargets() {
|
||||
if (this._isWatchingTargets) {
|
||||
return;
|
||||
if (!this._watchTargetsPromise) {
|
||||
this._watchTargetsPromise = this.targetList.watchTargets(
|
||||
this.targetList.ALL_TYPES,
|
||||
this._onTargetAvailable,
|
||||
this._onTargetDestroyed
|
||||
);
|
||||
}
|
||||
this._isWatchingTargets = true;
|
||||
await this.targetList.watchTargets(
|
||||
this.targetList.ALL_TYPES,
|
||||
this._onTargetAvailable,
|
||||
this._onTargetDestroyed
|
||||
);
|
||||
return this._watchTargetsPromise;
|
||||
}
|
||||
|
||||
async _unwatchAllTargets() {
|
||||
if (!this._isWatchingTargets) {
|
||||
_unwatchAllTargets() {
|
||||
if (!this._watchTargetsPromise) {
|
||||
return;
|
||||
}
|
||||
this._isWatchingTargets = false;
|
||||
await this.targetList.unwatchTargets(
|
||||
this._watchTargetsPromise = null;
|
||||
this.targetList.unwatchTargets(
|
||||
this.targetList.ALL_TYPES,
|
||||
this._onTargetAvailable,
|
||||
this._onTargetDestroyed
|
||||
|
|
|
@ -466,7 +466,7 @@ class TargetList extends EventEmitter {
|
|||
* Stop listening for the creation and/or destruction of a given type of target fronts.
|
||||
* See `watchTargets()` for documentation of the arguments.
|
||||
*/
|
||||
async unwatchTargets(types, onAvailable, onDestroy) {
|
||||
unwatchTargets(types, onAvailable, onDestroy) {
|
||||
if (typeof onAvailable != "function") {
|
||||
throw new Error(
|
||||
"TargetList.unwatchTargets expects a function as second argument"
|
||||
|
|
|
@ -35,6 +35,7 @@ skip-if = os == "linux" #Bug 1655183
|
|||
[browser_resources_several_resources.js]
|
||||
[browser_resources_stylesheets.js]
|
||||
[browser_resources_target_destroy.js]
|
||||
[browser_resources_target_resources_race.js]
|
||||
[browser_resources_websocket.js]
|
||||
[browser_target_list_browser_workers.js]
|
||||
[browser_target_list_frames.js]
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {
|
||||
ResourceWatcher,
|
||||
} = require("devtools/shared/resources/resource-watcher");
|
||||
|
||||
/**
|
||||
* Test initial target resources are correctly retrieved even when several calls
|
||||
* to watchResources are made simultaneously.
|
||||
*
|
||||
* This checks a race condition which occurred when calling watchResources
|
||||
* simultaneously. This made the "second" call to watchResources miss existing
|
||||
* resources (in case those are emitted from the target instead of the watcher).
|
||||
* See Bug 1663896.
|
||||
*/
|
||||
add_task(async function() {
|
||||
// Disable the preloaded process as it creates processes intermittently
|
||||
// which forces the emission of RDP requests we aren't correctly waiting for.
|
||||
await pushPref("dom.ipc.processPrelaunch.enabled", false);
|
||||
|
||||
const {
|
||||
client,
|
||||
resourceWatcher,
|
||||
targetList,
|
||||
} = await initResourceWatcherAndTarget();
|
||||
|
||||
const expectedPlatformMessage = "expectedMessage";
|
||||
|
||||
info("Log a message *before* calling ResourceWatcher.watchResources");
|
||||
Services.console.logStringMessage(expectedPlatformMessage);
|
||||
|
||||
info("Call watchResources from 2 separate call sites consecutively");
|
||||
|
||||
// Empty onAvailable callback for CSS MESSAGES, we only want to check that
|
||||
// the second resource we watch correctly provides existing resources.
|
||||
const onCssMessageAvailable = resources => {};
|
||||
|
||||
// First call to watchResources.
|
||||
// We do not await on `watchPromise1` here, in order to simulate simultaneous
|
||||
// calls to watchResources (which could come from 2 separate modules in a real
|
||||
// scenario).
|
||||
const initialWatchPromise = resourceWatcher.watchResources(
|
||||
[ResourceWatcher.TYPES.CSS_MESSAGE],
|
||||
{
|
||||
onAvailable: onCssMessageAvailable,
|
||||
}
|
||||
);
|
||||
|
||||
// `waitForNextResource` will trigger another call to `watchResources`.
|
||||
const onMessageReceived = waitForNextResource(
|
||||
resourceWatcher,
|
||||
ResourceWatcher.TYPES.PLATFORM_MESSAGE,
|
||||
{
|
||||
ignoreExistingResources: false,
|
||||
predicate: r => r.message === expectedPlatformMessage,
|
||||
}
|
||||
);
|
||||
|
||||
info("Waiting for the expected message to be received");
|
||||
await onMessageReceived;
|
||||
ok(true, "All the expected messages were received");
|
||||
|
||||
info("Wait for the other watchResources promise to finish");
|
||||
await initialWatchPromise;
|
||||
|
||||
// Unwatch all resources.
|
||||
resourceWatcher.unwatchResources([ResourceWatcher.TYPES.CSS_MESSAGE], {
|
||||
onAvailable: onCssMessageAvailable,
|
||||
});
|
||||
|
||||
Services.console.reset();
|
||||
targetList.destroy();
|
||||
await client.close();
|
||||
});
|
|
@ -179,7 +179,7 @@ async function testProcesses(targetList, target) {
|
|||
"The destroyed target is the one that has been reported as created"
|
||||
);
|
||||
|
||||
await targetList.unwatchTargets(
|
||||
targetList.unwatchTargets(
|
||||
[TargetList.TYPES.PROCESS],
|
||||
onAvailable,
|
||||
onDestroyed
|
||||
|
|
|
@ -163,7 +163,7 @@ async function testWatchTargets(mainRoot) {
|
|||
"The destroyed target is the one that has been reported as created"
|
||||
);
|
||||
|
||||
await targetList.unwatchTargets(
|
||||
targetList.unwatchTargets(
|
||||
[TargetList.TYPES.PROCESS],
|
||||
onAvailable,
|
||||
onDestroyed
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
Capturing a minidump
|
||||
====================
|
||||
|
||||
*Minidumps* are files created by various Windows tools which record the
|
||||
complete state of a program as it's running, or as it was at the moment
|
||||
of a crash. Small minidumps are created by the Breakpad :ref:`crash
|
||||
reporting <Crash Reporter>` tool, but sometimes that's not
|
||||
sufficient to diagnose a problem. For example, if the application is
|
||||
hanging (not responding to input, but hasn't crashed) then Breakpad is
|
||||
not triggered, and it can be difficult to determine where the problem
|
||||
lies. Sometimes a more complete form of minidump is needed to see
|
||||
additional details about a crash, in which case manual capture of a
|
||||
minidump is desired.
|
||||
|
||||
This page describes how to capture these minidumps on Windows, to permit
|
||||
better debugging.
|
||||
|
||||
|
||||
Privacy and minidumps
|
||||
---------------------
|
||||
|
||||
.. warning::
|
||||
|
||||
**Warning!** Unlike the minidumps submitted by Breakpad, these
|
||||
minidumps contain the **complete** contents of program memory. They
|
||||
are therefore much more likely to contain private information, if
|
||||
there is any in the browser. For this reason, you may prefer to
|
||||
generate minidumps against a `clean
|
||||
profile <http://support.mozilla.com/en-US/kb/Managing%20profiles>`__
|
||||
where possible.
|
||||
|
||||
|
||||
Capturing a minidump: application crash
|
||||
---------------------------------------
|
||||
|
||||
To capture a full minidump for an application crash, you can use a tool
|
||||
called windbg.
|
||||
|
||||
|
||||
Install debugging tools for Windows
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Microsoft distributes the Debugging Tools for Windows for free, those
|
||||
include WinDbg which you will need here. Download it from `Install
|
||||
Debugging Tools for
|
||||
Windows <http://msdn.microsoft.com/en-us/windows/hardware/gg463009.aspx>`__.
|
||||
(*You'll want the 32-bit version of WinDbg only if you are using a
|
||||
32*-bit version of Firefox) Then install it, the standard settings in
|
||||
the installation process are fine.
|
||||
|
||||
|
||||
Capture a minidump
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
#. Connect Firefox to the debugger.
|
||||
|
||||
a. If Firefox is not already running, then open WinDbg from the Start
|
||||
menu (Start->All Programs->Debugging Tools for Windows->WinDbg).
|
||||
Next, open the **"File"** menu and choose **"Open
|
||||
Executable..."**. In the file chooser window that appears, open
|
||||
the firefox.exe executable in your Firefox program folder
|
||||
(C:\Program Files\Mozilla Firefox).
|
||||
|
||||
b. If Firefox is already running, open WinDbg from the Start menu
|
||||
(Start->All Programs->Debugging Tools for Windows->WinDbg). Next,
|
||||
open the **"File"** menu and choose **"Attach to a Process..."**.
|
||||
In the file chooser window that appears, find the firefox.exe
|
||||
executable process with the lowest PID.
|
||||
|
||||
#. You should now see a "Command" text window with debug output at the
|
||||
top and an input box at the bottom. From the menu, select
|
||||
``Debug → Go``, and Firefox should start. If the debugger spits out
|
||||
some text right away and Firefox doesn't come up, select
|
||||
``Debug → Go`` again.
|
||||
|
||||
#. When the program is about to crash, WinDbg will spit out more data,
|
||||
and the prompt at the bottom will change from saying "``*BUSY*``" to
|
||||
having a number in it. At this point, you should type
|
||||
"``.dump /ma c:\temp\firefoxcrash.dmp``" -- without the quotes, but
|
||||
don't forget the dot at the beginning. Once it completes, which can
|
||||
take a fair while, you will have a very large file at
|
||||
``c:\temp\firefoxcrash.dmp`` that can be used to help debug your
|
||||
problem. File size will depend on this size of Firefox running in
|
||||
your environment, which could several GB.
|
||||
|
||||
#. Ask in the relevant bug or thread how best to share this very large
|
||||
file!
|
||||
|
||||
|
||||
Capturing a minidump: application hang
|
||||
--------------------------------------
|
||||
|
||||
On Windows Vista and Windows 7, you can follow `these
|
||||
instructions <http://support.microsoft.com/kb/931673>`__ to capture a
|
||||
dump file and locate it after it's been saved.
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 75 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 34 KiB |
|
@ -0,0 +1,69 @@
|
|||
How to get a process dump with Windows Task Manager
|
||||
===================================================
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
When tracking down the causes of process hangs, it is often helpful to
|
||||
obtain a process dump while the process is experiencing a hang. This
|
||||
article describes how to get a process dump with Task Manager on
|
||||
Windows. (To get a process dump for Thunderbird or some other product,
|
||||
substitute the product name where ever you see Firefox in these
|
||||
instructions.)
|
||||
|
||||
|
||||
Caution
|
||||
-------
|
||||
|
||||
The memory dump that will be created through this process is a complete
|
||||
snapshot of the state of Firefox when you create the file, so it
|
||||
contains URLs of active tabs, history information, and possibly even
|
||||
passwords depending on what you are doing when the snapshot is taken. It
|
||||
is advisable to create a new, blank profile to use when reproducing the
|
||||
hang and capturing the memory dump. Please ask for help doing this!
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
Windows
|
||||
To get a process dump, you need to be using Windows Vista or above.
|
||||
A Firefox nightly or release
|
||||
You need a Firefox version for which symbols are available from the
|
||||
:ref:`symbol server <Using The Mozilla Symbol Server>`. You
|
||||
can use any `official nightly
|
||||
build <https://ftp.mozilla.org/pub/firefox/nightly/>`__ or released
|
||||
version of Firefox from Mozilla. You can find the latest trunk
|
||||
nightly builds under
|
||||
`http://ftp.mozilla.org/pub/mozilla.o.../latest-trunk/ <http://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/latest-trunk/>`__.
|
||||
|
||||
|
||||
Creating the Dump File
|
||||
----------------------
|
||||
|
||||
Ensure that Firefox is not already running.
|
||||
|
||||
|
||||
Run Firefox, reproduce the hang
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Start Firefox and perform whatever steps are necessary to cause Firefox
|
||||
to hang. Once the browser hangs, continue with the steps below.
|
||||
|
||||
|
||||
After the hang
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
#. Open Windows Task Manager (CTRL+SHIFT+ESC).
|
||||
#. Find Firefox.exe among the list of processes.
|
||||
#. Right-click Firefox.exe and select "Create dump file". Task manager
|
||||
should indicate where the dump file was written to.
|
||||
|
||||
|
||||
See also
|
||||
--------
|
||||
|
||||
- :ref:`How to get a stacktrace for a bug report <How to get a stacktrace for a bug report>`
|
||||
- `How to create a user-mode process dump file in Windows Vista and in
|
||||
Windows 7
|
||||
(MSDN) <https://docs.microsoft.com/en-us/windows/client-management/generate-kernel-or-complete-crash-dump#manually-generate-a-memory-dump-file>`__
|
|
@ -0,0 +1,152 @@
|
|||
How to get a stacktrace for a bug report
|
||||
========================================
|
||||
|
||||
If you file a bug report in Bugzilla about a crash you should include a
|
||||
stacktrace (call stack) in your report. A stacktrace will tell Mozilla
|
||||
developers what crashed and provide a starting point for investigating
|
||||
its cause. This article describes how to use the Mozilla Crash Reporter
|
||||
(Breakpad) to get a crash ID, which our engineers can use to get a
|
||||
stacktrace, and alternative ways to get a stacktrace if you can't get a
|
||||
crash ID.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
You need a binary build of Firefox from
|
||||
`Mozilla.org <https://www.mozilla.org/firefox/>`__. SeaMonkey and
|
||||
Thunderbird also support crash reporting.
|
||||
|
||||
Mozilla's crash report server currently only has debug information for
|
||||
Mozilla builds and thus the crash reporter cannot work if you use a
|
||||
build from a Linux distribution or if you compile from source code. In
|
||||
these cases you will need to use one of the :ref:`alternative
|
||||
methods <Alternative ways to get a stacktrace>` listed below.
|
||||
|
||||
.. note::
|
||||
|
||||
**Note:** When filing a crash report, it is important to know whether
|
||||
the crash occurs with `Firefox safe
|
||||
mode <http://support.mozilla.com/kb/Safe+Mode>`__. This helps
|
||||
engineers determine whether a particular
|
||||
`extension <http://support.mozilla.com/kb/Troubleshooting+extensions+and+themes>`__
|
||||
or
|
||||
`plugin <http://support.mozilla.com/kb/Troubleshooting+plugins>`__
|
||||
is the cause of the crash.
|
||||
|
||||
|
||||
How to get a crash ID with the Mozilla Crash Reporter
|
||||
-----------------------------------------------------
|
||||
|
||||
1 - Crash and submit a report to the system.
|
||||
|
||||
.. image:: img/reporter.jpg
|
||||
|
||||
The Mozilla Crash Reporter window should automatically come up after Firefox crashes.
|
||||
If you have any additional information about the crash, such as additional detail on
|
||||
what you were doing at the time that may have triggered the crash, please enter it
|
||||
into the comments box. Be sure that you **check the "Tell Mozilla about this crash"**
|
||||
checkbox and click the restart button. The crash reporter should now submit the
|
||||
crash report and Firefox should open again.
|
||||
|
||||
.. note::
|
||||
|
||||
The "Details" button gives additional data about the incident,
|
||||
however this is not useful in a bug report.
|
||||
|
||||
|
||||
2 - Tell us the ID of the report you submitted.
|
||||
|
||||
.. image:: img/crashlist.jpg
|
||||
|
||||
To access all of your submitted reports type "about:crashes" into the Firefox address bar
|
||||
and press enter. Firefox should open a list of IDs for your submitted crash reports.
|
||||
Copy two or three of the IDs for the appropriate crashes and paste them into your
|
||||
Bugzilla report. Please check the listed times to avoid copying the ID of an unrelated
|
||||
crash report.
|
||||
|
||||
.. note::
|
||||
|
||||
You can prefix a "bp-" to the beginning of an ID to make Bugzilla turn it
|
||||
into a link: bp-a70759c6-1295-4160-aa30-bc4772090918
|
||||
|
||||
|
||||
How to get the crash ID if Firefox crashes on startup
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If Firefox crashes on startup you can still access your submitted crash
|
||||
reports. Crash reports are accessible from all Firefox profiles, so if a
|
||||
`new
|
||||
profile <https://support.mozilla.org/kb/profile-manager-create-remove-switch-firefox-profiles>`__
|
||||
does not crash you can use it to access them through "about:crashes" as above.
|
||||
|
||||
|
||||
Accessing crash report IDs outside of Firefox
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If you cannot load Firefox at all you can find the crash report files at
|
||||
this location depending on your operating system:
|
||||
|
||||
* Windows : ``%APPDATA%\Mozilla\Firefox\Crash Reports\submitted\``
|
||||
* OS X : ``~/Library/Application Support/Firefox/Crash Reports/submitted/``
|
||||
* Linux : ``~/.mozilla/firefox/Crash Reports/submitted/``
|
||||
|
||||
Each file in this folder contains one submitted crash report ID. You can
|
||||
check the modified or creation time for each file to discern which crash
|
||||
reports are relevant to your bug report.
|
||||
|
||||
|
||||
Alternative ways to get a stacktrace
|
||||
------------------------------------
|
||||
|
||||
If the Mozilla crash reporter doesn't come up or isn't available you
|
||||
will need to obtain a stacktrace manually:
|
||||
|
||||
|
||||
Windows
|
||||
~~~~~~~
|
||||
|
||||
See the article :ref:`Create a stacktrace with Windbg` for information
|
||||
on how to do this.
|
||||
|
||||
For a full process dump, see :ref:`How to get a process dump with Windows
|
||||
Task Manager`.
|
||||
|
||||
|
||||
OS X
|
||||
~~~~
|
||||
|
||||
Run /Applications/Utilities/Console.app. Expand "~/Library/Logs" and
|
||||
"CrashReporter", then look for logs for "firefox-bin".
|
||||
|
||||
|
||||
Linux
|
||||
~~~~~
|
||||
|
||||
Note that for most distros, the package you need to get symbols for will
|
||||
be something like "xulrunner", not "firefox".
|
||||
|
||||
|
||||
Crash reports files on your computer
|
||||
------------------------------------
|
||||
|
||||
When Breakpad initially catches a crash it first writes crash report
|
||||
files (e.g. .dump and .extra files) into the 'pending' subdirectory of
|
||||
its 'Crash Reports' directory.
|
||||
|
||||
If Breakpad successfully sends the crash report to the reporting server
|
||||
then, by default, the files added to the 'pending' subdirectory for the
|
||||
crash are removed, and a .txt file is placed in the 'submitted'
|
||||
directory containing the crash ID created by the reporting server.
|
||||
|
||||
If you want Breakpad to leave the .dump and .extra files on your
|
||||
computer so that you can examine them locally, then set the
|
||||
MOZ_CRASHREPORTER_NO_DELETE_DUMP environment variable to 1.
|
||||
|
||||
- Ubuntu: `Instructions from the Ubuntu
|
||||
Team <https://wiki.ubuntu.com/MozillaTeam/Bugs#Obtain%20a%20backtrace%20from%20an%20apport%20crash%20report%20(using%20gdb)>`__
|
||||
- openSUSE: `General instructions from
|
||||
openSUSE <https://en.opensuse.org/openSUSE:Bugreport_application_crashed>`__
|
||||
- Fedora: `Capturing Stack
|
||||
Traces <https://fedoraproject.org/wiki/StackTraces>`__
|
||||
- Gentoo: `Debugging using
|
||||
GDB <https://wiki.gentoo.org/wiki/Debugging_with_GDB>`__
|
|
@ -0,0 +1,232 @@
|
|||
How to get a stacktrace with WinDbg
|
||||
===================================
|
||||
|
||||
+--------------------------------------------------------------------+
|
||||
| This page is an import from MDN and the contents might be outdated |
|
||||
+--------------------------------------------------------------------+
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
Sometimes you need to get a stacktrace (call stack) for a crash or hang
|
||||
but `Breakpad <http://kb.mozillazine.org/Breakpad>`__ fails because it's
|
||||
a special crash or a hang. This article describes how to get a
|
||||
stacktrace in those cases with WinDbg on Windows. (To get a stacktrace
|
||||
for Thunderbird or some other product, substitute the product name where
|
||||
ever you see Firefox in this instructions.)
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
To get such a stacktrace you need to install the following software:
|
||||
|
||||
Debugging Tools for Windows
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Microsoft distributes the Debugging Tools for Windows for free, those
|
||||
include WinDbg which you will need here. Download it from `Install
|
||||
Debugging Tools for
|
||||
Windows <https://docs.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk>`__.
|
||||
(*You'll want the 32-bit version*, even if you are using a 64-bit
|
||||
version of Windows) Then install it, the standard settings in the
|
||||
installation process are fine.
|
||||
|
||||
A Firefox nightly or release
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You need a Firefox version for which symbols are availables from the
|
||||
:ref:`symbol server <Using The Mozilla Symbol Server>` to use
|
||||
with WinDbg. You can use any `official nightly
|
||||
build <https://ftp.mozilla.org/pub/firefox/nightly/>`__ or released
|
||||
version of Firefox from Mozilla. You can find the latest trunk nightly
|
||||
builds under
|
||||
`http://ftp.mozilla.org/pub/mozilla.o.../latest-trunk/ <https://ftp.mozilla.org/pub/firefox/nightly/latest-mozilla-central/>`__.
|
||||
|
||||
|
||||
Debugging
|
||||
---------
|
||||
|
||||
To begin debugging, ensure that Firefox is not already running and open
|
||||
WinDbg from the Start menu. (Start->All Programs->Debugging Tools for
|
||||
Windows->WinDbg) Next, open the **"File"** menu and choose **"Open
|
||||
Executable..."**. In the file chooser window that appears, open the
|
||||
firefox.exe executable in your Firefox program folder (C:\Program
|
||||
Files\Mozilla Firefox).
|
||||
|
||||
You should now see a "Command" text window with debug output at the top
|
||||
and an input box at the bottom. Before debugging can start, several
|
||||
commands must be entered into the one-line input box at the bottom of
|
||||
the Command window.
|
||||
|
||||
.. note::
|
||||
|
||||
Tip: All commands must be entered exactly as written, one line at a
|
||||
time, into the bottom of the Command box.
|
||||
|
||||
- Copying and pasting each line is the easiest method to avoid
|
||||
mistakes
|
||||
- Some commands start with a period (.) or a pipe character (|),
|
||||
which is required. (The keystroke for a pipe character on US
|
||||
keyboards is SHIFT+\)
|
||||
- Submit the log file on a bug or via the support site, even if
|
||||
nothing seems to happen during the debug process
|
||||
|
||||
|
||||
Start debugging
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Now that Firefox is opened in the debugger, you need to configure your
|
||||
WinDbg to download symbols from the Mozilla symbol server. To load the
|
||||
symbols, enter the three commands below, pressing enter after each one.
|
||||
(More details are available at :ref:`symbol server <Using The Mozilla Symbol Server>`.)
|
||||
|
||||
::
|
||||
|
||||
.sympath SRV*c:\symbols*http://symbols.mozilla.org/firefox;SRV*c:\symbols*http://msdl.microsoft.com/download/symbols
|
||||
.symfix+ c:\symbols
|
||||
.reload /f
|
||||
|
||||
Now wait for the symbols to download. This may take some time depending
|
||||
on your connection speed; the total size of the Mozilla and Microsoft
|
||||
symbols download is around 1.4GB. WinDbg will show "Busy" at the bottom
|
||||
of the application window until the download is complete.
|
||||
|
||||
Once the download is complete, you need to configure WinDbg to examine
|
||||
child processes, ignore a specific event caused by Flash Player, and
|
||||
record a log of loaded modules. You will also want to open a log file to
|
||||
save data you collect. To do this, enter these four commands, pressing
|
||||
enter after each one.
|
||||
|
||||
::
|
||||
|
||||
.logopen /t c:\temp\firefox-debug.log
|
||||
.childdbg 1
|
||||
.tlist
|
||||
sxn gp
|
||||
lm
|
||||
|
||||
If you see firefox.exe listed in the output from .tlist more than once,
|
||||
then you are already running the application and need to close the
|
||||
running instance first before you start debugging, otherwise you won't
|
||||
get useful results.
|
||||
|
||||
Now run Firefox by opening the **Debug** menu and clicking **Go**.
|
||||
**While Firefox is running, you will not be able to type any commands
|
||||
into the debugger.** After it starts, try to reproduce the crash or
|
||||
hanging issue that you are seeing.
|
||||
|
||||
.. note::
|
||||
|
||||
If Firefox fails to start, and you see lines of text followed by a
|
||||
command prompt in the debugger, a "breakpoint" may have been
|
||||
triggered. If you are prompted for a command but don't see an error
|
||||
about a crash, go back to the **Debug** menu and press **Go**.
|
||||
|
||||
Once the browser crashes, you will see an error (such as "Access
|
||||
violation") in the WinDbg Command window. If Firefox hangs and there is
|
||||
no command prompt available in the debugger, open the **Debug** menu and
|
||||
choose **Break.** Once the browser has crashed or been stopped, continue
|
||||
with the steps below.
|
||||
|
||||
|
||||
After the crash or hang
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You need to capture the debug information to include in a bug comment or
|
||||
support request. Enter these three commands, one at a time, to get the
|
||||
stacktrace, crash/hang analysis and log of loaded modules. (Again, press
|
||||
Enter after each command.)
|
||||
|
||||
::
|
||||
|
||||
~* kp
|
||||
!analyze -v -f
|
||||
lm
|
||||
|
||||
After these steps are completed, find the file
|
||||
**c:\temp\firefox-debug-(Today's Date).txt** on your hard drive. To
|
||||
provide the information to the development community, submit this file
|
||||
with a `support request <https://support.mozilla.com/>`__ or attach it
|
||||
to a related bug on `Bugzilla <https://bugzilla.mozilla.org/>`__.
|
||||
|
||||
|
||||
Producing a minidump
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Sometimes the stacktrace alone is not enough information for a developer
|
||||
to figure out what went wrong. A developer may ask you for a "minidump"
|
||||
or a "full memory dump", which are files containing more information
|
||||
about the process. :ref:`You can easily produce minidumps from WinDBG and
|
||||
provide them to developers <Capturing a minidump>`.
|
||||
|
||||
FAQ
|
||||
|
||||
Q: I am running Windows 7 (32-bit or 64-bit) and I see an exception in
|
||||
the WinDbg command window that says 'ntdll32!LdrpDoDebuggerBreak+0x2c'
|
||||
or 'ntdll32!LdrpDoDebuggerBreak+0x30'. What do I do now?
|
||||
|
||||
A: If you see 'int 3' after either of those exceptions, you will need to
|
||||
execute the following commands in WinDbg.
|
||||
|
||||
::
|
||||
|
||||
bp ntdll!LdrpDoDebuggerBreak+0x30
|
||||
bp ntdll!LdrpDoDebuggerBreak+0x2c
|
||||
eb ntdll!LdrpDoDebuggerBreak+0x30 0x90
|
||||
eb ntdll!LdrpDoDebuggerBreak+0x2c 0x90
|
||||
|
||||
| Make sure you enter them one at a time and press enter after each one.
|
||||
If you use the 64-bit version of Windows, you need to replace "ntdll"
|
||||
in these commands with "ntdll32".
|
||||
| Q: The first four frames of my stack trace look like this:
|
||||
|
||||
::
|
||||
|
||||
0012fe20 7c90e89a ntdll!KiFastSystemCallRet
|
||||
0012fe24 7c81cd96 ntdll!ZwTerminateProcess+0xc
|
||||
0012ff20 7c81cdee kernel32!_ExitProcess+0x62
|
||||
|
||||
0012ff34 6000179e kernel32!ExitProcess+0x14
|
||||
|
||||
This looks wrong to me?!
|
||||
|
||||
A: You ran the application without the "Debug child processes also"
|
||||
check box being checked. You need to detach the debugger and open the
|
||||
application again, this time with the check box being checked.
|
||||
|
||||
Q: WinDbg tells me that it is unable to verify checksum for firefox.exe.
|
||||
Is this normal?
|
||||
|
||||
A: Yes, this is normal and can be ignored.
|
||||
|
||||
Q: Should I click yes or no when WinDbg asks me to "Save information for
|
||||
workspace?"
|
||||
|
||||
A: Click yes and WinDbg will save you from having to enter in the symbol
|
||||
location for Firefox.exe in the future. Click no if you'd rather not
|
||||
having WinDbg save this information.
|
||||
|
||||
Q: I'm seeing "wow64" on top of each thread, is that ok ?
|
||||
|
||||
A: No, you are running a 64 bit version of Windbg and trying to debug a
|
||||
32 bit version of the mozilla software. Redownload and install the 32
|
||||
bit version of windbg.
|
||||
|
||||
|
||||
Troubleshooting: Symbols will not download
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If symbols will not download no matter what you do, the problem may be
|
||||
that Internet Explorer has been set to the **Work Offline** mode. You
|
||||
will not receive any warnings of this in Windbg, Visual C++ or Visual
|
||||
Studio. Even using the command line with symchk.exe to download symbols
|
||||
will fail. This is because Microsoft uses Internet Explorer's internet &
|
||||
proxy settings to download the symbol files. Check the File menu of
|
||||
Internet Explorer to ensure "Work Offline" is unchecked.
|
||||
|
||||
|
||||
See also
|
||||
--------
|
||||
|
||||
- :ref:`symbol server <Using The Mozilla Symbol Server>` Maps addresses to human readable strings.
|
||||
- :ref:`source server <Using The Mozilla Source Server>` Maps addresses to source code lines
|
|
@ -141,3 +141,9 @@ HTTPSOnlyFailedRequest = Upgrading insecure request “%1$S” failed. (%2$S)
|
|||
|
||||
# LOCALIZATION NOTE: %S is the URL of the blocked request;
|
||||
IframeSandboxBlockedDownload = Download of “%S” was blocked because the triggering iframe has the sandbox flag set.
|
||||
|
||||
# Sanitizer API
|
||||
# LOCALIZATION NOTE: Please do not localize "DocumentFragment". It's the name of an API.
|
||||
SanitizerRcvdNoInput = Received empty or no input. Returning an empty DocumentFragment.
|
||||
# LOCALIZATION NOTE: "Sanitizer" is the name of the API. Please do not localize.
|
||||
SanitizerOptionsDiscarded = Options for the Sanitizer constructor are not yet supported. Please note this is experimental behavior.
|
||||
|
|
|
@ -9,7 +9,7 @@ with Files('*'):
|
|||
|
||||
TEST_DIRS += ['test']
|
||||
|
||||
DIRS += [ 'featurepolicy' ]
|
||||
DIRS += [ 'featurepolicy', 'sanitizer' ]
|
||||
|
||||
EXPORTS.mozilla.dom += [
|
||||
'CSPEvalChecker.h',
|
||||
|
|
|
@ -0,0 +1,203 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
#include "BindingDeclarations.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/DocumentFragment.h"
|
||||
#include "mozilla/dom/SanitizerBinding.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsTreeSanitizer.h"
|
||||
#include "Sanitizer.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Sanitizer, mGlobal)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(Sanitizer)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(Sanitizer)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Sanitizer)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
JSObject* Sanitizer::WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) {
|
||||
return Sanitizer_Binding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<Sanitizer> Sanitizer::Constructor(
|
||||
const GlobalObject& aGlobal, const SanitizerOptions& aOptions,
|
||||
ErrorResult& aRv) {
|
||||
// Note: Later, aOptions will be interpreted and stored as a member.
|
||||
// We'll just ignore it for now.
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
RefPtr<Sanitizer> sanitizer = new Sanitizer(global);
|
||||
AutoTArray<nsString, 1> params = {};
|
||||
sanitizer->LogLocalizedString("SanitizerOptionsDiscarded", params,
|
||||
nsIScriptError::infoFlag);
|
||||
return sanitizer.forget();
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<DocumentFragment> Sanitizer::InputToNewFragment(
|
||||
const Optional<mozilla::dom::StringOrDocumentFragmentOrDocument>& aInput,
|
||||
ErrorResult& aRv) {
|
||||
// turns an StringOrDocumentFragmentOrDocument into a DocumentFragment for
|
||||
// internal use with nsTreeSanitizer
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(mGlobal);
|
||||
if (!window || !window->GetDoc()) {
|
||||
// FIXME: Should we throw another exception?
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
if (!aInput.WasPassed()) {
|
||||
AutoTArray<nsString, 1> params = {};
|
||||
LogLocalizedString("SanitizerRcvdNoInput", params,
|
||||
nsIScriptError::warningFlag);
|
||||
|
||||
RefPtr<DocumentFragment> emptyFragment =
|
||||
window->GetDoc()->CreateDocumentFragment();
|
||||
return emptyFragment.forget();
|
||||
}
|
||||
// We need to create a new docfragment based on the input
|
||||
// and can't use a live document (possibly with mutation observershandlers)
|
||||
nsAutoString innerHTML;
|
||||
if (aInput.Value().IsDocumentFragment()) {
|
||||
RefPtr<DocumentFragment> inFragment =
|
||||
&aInput.Value().GetAsDocumentFragment();
|
||||
inFragment->GetInnerHTML(innerHTML);
|
||||
} else if (aInput.Value().IsString()) {
|
||||
innerHTML.Assign(aInput.Value().GetAsString());
|
||||
} else if (aInput.Value().IsDocument()) {
|
||||
RefPtr<Document> doc = &aInput.Value().GetAsDocument();
|
||||
nsCOMPtr<Element> docElement = doc->GetDocumentElement();
|
||||
|
||||
docElement->GetInnerHTML(innerHTML, IgnoreErrors());
|
||||
}
|
||||
if (innerHTML.IsEmpty()) {
|
||||
AutoTArray<nsString, 1> params = {};
|
||||
LogLocalizedString("SanitizerRcvdNoInput", params,
|
||||
nsIScriptError::warningFlag);
|
||||
|
||||
RefPtr<DocumentFragment> emptyFragment =
|
||||
window->GetDoc()->CreateDocumentFragment();
|
||||
return emptyFragment.forget();
|
||||
}
|
||||
// We don't have a context element yet. let's create a mock HTML body element
|
||||
RefPtr<mozilla::dom::NodeInfo> info =
|
||||
window->GetDoc()->NodeInfoManager()->GetNodeInfo(
|
||||
nsGkAtoms::body, nullptr, kNameSpaceID_XHTML, nsINode::ELEMENT_NODE);
|
||||
|
||||
nsCOMPtr<nsINode> context = NS_NewHTMLBodyElement(
|
||||
info.forget(), mozilla::dom::FromParser::FROM_PARSER_FRAGMENT);
|
||||
RefPtr<DocumentFragment> fragment = nsContentUtils::CreateContextualFragment(
|
||||
context, innerHTML, true /* aPreventScriptExecution */, aRv);
|
||||
if (aRv.Failed()) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
return fragment.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DocumentFragment> Sanitizer::Sanitize(
|
||||
const Optional<mozilla::dom::StringOrDocumentFragmentOrDocument>& aInput,
|
||||
ErrorResult& aRv) {
|
||||
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(mGlobal);
|
||||
if (!window || !window->GetDoc()) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
if (!aInput.WasPassed()) {
|
||||
AutoTArray<nsString, 1> params = {};
|
||||
LogLocalizedString("SanitizerRcvdNoInput", params,
|
||||
nsIScriptError::warningFlag);
|
||||
RefPtr<DocumentFragment> fragment =
|
||||
window->GetDoc()->CreateDocumentFragment();
|
||||
return fragment.forget();
|
||||
}
|
||||
ErrorResult error;
|
||||
RefPtr<DocumentFragment> fragment =
|
||||
Sanitizer::InputToNewFragment(aInput, error);
|
||||
if (error.Failed()) {
|
||||
return fragment.forget();
|
||||
}
|
||||
nsTreeSanitizer treeSanitizer(mSanitizationFlags);
|
||||
|
||||
treeSanitizer.Sanitize(fragment);
|
||||
return fragment.forget();
|
||||
}
|
||||
|
||||
void Sanitizer::SanitizeToString(
|
||||
const Optional<StringOrDocumentFragmentOrDocument>& aInput,
|
||||
nsAString& outSanitized, ErrorResult& aRv) {
|
||||
outSanitized = EmptyString();
|
||||
if (!aInput.WasPassed()) {
|
||||
AutoTArray<nsString, 1> params = {};
|
||||
LogLocalizedString("SanitizerRcvdNoInput", params,
|
||||
nsIScriptError::warningFlag);
|
||||
return;
|
||||
}
|
||||
ErrorResult error;
|
||||
RefPtr<DocumentFragment> fragment =
|
||||
Sanitizer::InputToNewFragment(aInput, error);
|
||||
if (error.Failed()) {
|
||||
return;
|
||||
}
|
||||
nsTreeSanitizer treeSanitizer(mSanitizationFlags);
|
||||
|
||||
treeSanitizer.Sanitize(fragment);
|
||||
fragment->GetInnerHTML(outSanitized);
|
||||
}
|
||||
|
||||
/* ------ Logging ------ */
|
||||
|
||||
void Sanitizer::LogLocalizedString(const char* aName,
|
||||
const nsTArray<nsString>& aParams,
|
||||
uint32_t aFlags) {
|
||||
uint64_t innerWindowID = 0;
|
||||
bool isPrivateBrowsing = true;
|
||||
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(mGlobal);
|
||||
if (window && window->GetDoc()) {
|
||||
auto* doc = window->GetDoc();
|
||||
innerWindowID = doc->InnerWindowID();
|
||||
isPrivateBrowsing = nsContentUtils::IsInPrivateBrowsing(doc);
|
||||
}
|
||||
nsAutoString logMsg;
|
||||
nsContentUtils::FormatLocalizedString(nsContentUtils::eSECURITY_PROPERTIES,
|
||||
aName, aParams, logMsg);
|
||||
LogMessage(logMsg, aFlags, innerWindowID, isPrivateBrowsing);
|
||||
}
|
||||
|
||||
/* static */
|
||||
void Sanitizer::LogMessage(const nsAString& aMessage, uint32_t aFlags,
|
||||
uint64_t aInnerWindowID, bool aFromPrivateWindow) {
|
||||
// Prepending 'Sanitizer' to the outgoing console message
|
||||
nsString message;
|
||||
message.AppendLiteral(u"Sanitizer: ");
|
||||
message.Append(aMessage);
|
||||
|
||||
// Allow for easy distinction in devtools code.
|
||||
nsCString category("Sanitizer");
|
||||
|
||||
if (aInnerWindowID > 0) {
|
||||
// Send to content console
|
||||
nsContentUtils::ReportToConsoleByWindowID(message, aFlags, category,
|
||||
aInnerWindowID);
|
||||
} else {
|
||||
// Send to browser console
|
||||
nsContentUtils::LogSimpleConsoleError(
|
||||
message, category.get(), aFromPrivateWindow,
|
||||
true /* from chrome context */, aFlags);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,101 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef mozilla_dom_Sanitizer_h
|
||||
#define mozilla_dom_Sanitizer_h
|
||||
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "mozilla/dom/DocumentFragment.h"
|
||||
#include "mozilla/dom/SanitizerBinding.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIParserUtils.h"
|
||||
#include "nsTreeSanitizer.h"
|
||||
|
||||
class nsISupports;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class ErrorResult;
|
||||
|
||||
namespace dom {
|
||||
|
||||
class GlobalObject;
|
||||
|
||||
class Sanitizer final : public nsISupports, public nsWrapperCache {
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Sanitizer)
|
||||
|
||||
explicit Sanitizer(nsIGlobalObject* aGlobal) : mGlobal(aGlobal) {
|
||||
MOZ_ASSERT(aGlobal);
|
||||
// FIXME(freddyb): Waiting for wicg-draft to evolve. Bug 1658564.
|
||||
mSanitizationFlags = nsIParserUtils::SanitizerAllowStyle |
|
||||
nsIParserUtils::SanitizerAllowComments;
|
||||
}
|
||||
|
||||
nsIGlobalObject* GetParentObject() const { return mGlobal; }
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
/**
|
||||
* Sanitizer() WebIDL constructor
|
||||
* @return a new Sanitizer object, with methods as below
|
||||
*/
|
||||
static already_AddRefed<Sanitizer> Constructor(
|
||||
const GlobalObject& aGlobal, const SanitizerOptions& aOptions,
|
||||
ErrorResult& aRv);
|
||||
|
||||
/**
|
||||
* sanitize WebIDL method.
|
||||
* @param aInput "bad" HTML that needs to be sanitized
|
||||
* @return DocumentFragment of the sanitized HTML
|
||||
*/
|
||||
already_AddRefed<DocumentFragment> Sanitize(
|
||||
const Optional<mozilla::dom::StringOrDocumentFragmentOrDocument>& aInput,
|
||||
ErrorResult& aRv);
|
||||
|
||||
/**
|
||||
* sanitizeToString WebIDL method.
|
||||
* @param aInput "bad" HTML that needs to be sanitized
|
||||
* @param outSanitized out-param for the string of sanitized HTML
|
||||
*/
|
||||
void SanitizeToString(
|
||||
const Optional<StringOrDocumentFragmentOrDocument>& aInput,
|
||||
nsAString& outSanitized, ErrorResult& aRv);
|
||||
|
||||
/**
|
||||
* Logs localized message to either content console or browser console
|
||||
* @param aName Localization key
|
||||
* @param aParams Localization parameters
|
||||
* @param aFlags Logging Flag (see nsIScriptError)
|
||||
*/
|
||||
void LogLocalizedString(const char* aName, const nsTArray<nsString>& aParams,
|
||||
uint32_t aFlags);
|
||||
|
||||
private:
|
||||
~Sanitizer() = default;
|
||||
already_AddRefed<DocumentFragment> InputToNewFragment(
|
||||
const Optional<mozilla::dom::StringOrDocumentFragmentOrDocument>& aInput,
|
||||
ErrorResult& aRv);
|
||||
/**
|
||||
* Logs localized message to either content console or browser console
|
||||
* @param aMessage Message to log
|
||||
* @param aFlags Logging Flag (see nsIScriptError)
|
||||
* @param aInnerWindowID Inner Window ID (Logged on browser console if 0)
|
||||
* @param aFromPrivateWindow If from private window
|
||||
*/
|
||||
static void LogMessage(const nsAString& aMessage, uint32_t aFlags,
|
||||
uint64_t aInnerWindowID, bool aFromPrivateWindow);
|
||||
|
||||
SanitizerOptions mOptions;
|
||||
uint32_t mSanitizationFlags;
|
||||
nsCOMPtr<nsIGlobalObject> mGlobal;
|
||||
};
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // ifndef mozilla_dom_Sanitizer_h
|
|
@ -0,0 +1,37 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
with Files("**"):
|
||||
BUG_COMPONENT = ('Core', 'DOM: Security')
|
||||
|
||||
#TEST_DIRS += [ 'tests' ]
|
||||
|
||||
MOCHITEST_MANIFESTS += ['tests/mochitest/mochitest.ini']
|
||||
|
||||
|
||||
EXPORTS.mozilla.dom += [
|
||||
'Sanitizer.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'Sanitizer.cpp',
|
||||
]
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'/dom/base',
|
||||
'/dom/bindings',
|
||||
'/dom/html',
|
||||
]
|
||||
|
||||
#include('/ipc/chromium/chromium-config.mozbuild')
|
||||
#include('/tools/fuzzing/libfuzzer-config.mozbuild')
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
#if CONFIG['FUZZING_INTERFACES']:
|
||||
# TEST_DIRS += [
|
||||
# 'fuzztest'
|
||||
# ]
|
|
@ -0,0 +1,5 @@
|
|||
[DEFAULT]
|
||||
prefs =
|
||||
dom.security.sanitizer.enabled=true
|
||||
scheme=https
|
||||
[test_sanitizer_api.html]
|
|
@ -0,0 +1,75 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Test sanitizer api</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="div"></div>
|
||||
<script type="text/javascript">
|
||||
"use strict";
|
||||
/* global Sanitizer */
|
||||
// we're not done after "onload"
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
var oldVal = SpecialPowers.getBoolPref("dom.security.sanitizer.enabled");
|
||||
SpecialPowers.setBoolPref("dom.security.sanitizer.enabled", true);
|
||||
|
||||
|
||||
function* possibleInputTypes(inputStr) {
|
||||
/* This generator function, given a string, yields all possible input objects
|
||||
for our sanitizer API (string, docfragment, document).
|
||||
*/
|
||||
|
||||
// 1) as string
|
||||
yield ({testInput: inputStr, testType: "String" });
|
||||
// 2) as DocumentFragment
|
||||
let temp = document.createElement('template');
|
||||
// asking eslint to skip this: innerHTML is safe for template elements.
|
||||
// eslint-disable-next-line no-unsanitized/property
|
||||
temp.innerHTML = inputStr;
|
||||
yield ({testInput: temp.content, testType: "DocumentFragment" });
|
||||
// 3) as HTMLDocument
|
||||
const parser = new DOMParser;
|
||||
yield ({testInput: parser.parseFromString(inputStr, "text/html"), testType: "Document" });
|
||||
}
|
||||
// basic interface smoke test
|
||||
ok(Sanitizer, "Sanitizer is truthy");
|
||||
const mySanitizer = new Sanitizer();
|
||||
ok(mySanitizer, "Sanitizer constructor works");
|
||||
ok(mySanitizer.sanitize, "sanitize function exists");
|
||||
|
||||
// testing sanitizer results
|
||||
const testCases = [
|
||||
{testString: "<p>hello</p>", testExpected: "<p>hello</p>" },
|
||||
// script element encoded to not confuse the HTML parser and end execution here
|
||||
{ testString: "<p>second test</p><script>alert(1)\x3C/script>", testExpected: "<p>second test</p>"},
|
||||
];
|
||||
|
||||
|
||||
const div = document.getElementById("div");
|
||||
for (let test of testCases) {
|
||||
const {testString, testExpected} = test;
|
||||
|
||||
for (let testInputAndType of possibleInputTypes(testString)) {
|
||||
const {testInput, testType} = testInputAndType;
|
||||
|
||||
// test documentfragment API
|
||||
div.innerHTML = "";
|
||||
const docFragment = mySanitizer.sanitize(testInput);
|
||||
div.append(docFragment);
|
||||
is(div.innerHTML, testExpected, `Sanitizer.sanitize() should turn (${testType}) '${testInput}' into '${testExpected}'`);
|
||||
|
||||
// test string api, doesnt work yet
|
||||
/*is(mySanitizer.sanitizeToString(testInput), testExpected,
|
||||
`Sanitizer.sanitizeToString() should turn (${testType}) '${testInput}' into '${testExpected}'`);*/
|
||||
}
|
||||
}
|
||||
|
||||
SpecialPowers.setBoolPref("dom.security.sanitizer.enabled", oldVal);
|
||||
SimpleTest.finish();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1003,6 +1003,8 @@ var interfaceNamesInGlobalScope = [
|
|||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "RTCTrackEvent", insecureContext: true },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "Sanitizer" },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "Screen", insecureContext: true },
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
{ name: "ScreenOrientation", insecureContext: true },
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/.
|
||||
*
|
||||
* The origin of this IDL file is
|
||||
* https://wicg.github.io/purification/
|
||||
*
|
||||
* * Copyright © 2020 the Contributors to the HTML Sanitizer API Specification,
|
||||
* published by the Web Platform Incubator Community Group under the W3C Community Contributor License Agreement (CLA).
|
||||
*/
|
||||
|
||||
|
||||
typedef (DOMString or DocumentFragment or Document) SanitizerInput;
|
||||
|
||||
// unimplemented during prototyping
|
||||
dictionary SanitizerOptions {
|
||||
sequence<DOMString> allowed;
|
||||
sequence<DOMString> removed;
|
||||
};
|
||||
|
||||
[Exposed=Window, SecureContext]
|
||||
interface Sanitizer {
|
||||
[Pref="dom.security.sanitizer.enabled", Throws]
|
||||
constructor(optional SanitizerOptions options = {}); // optionality still discussed in spec
|
||||
[Throws]
|
||||
DocumentFragment sanitize(optional SanitizerInput input);
|
||||
[Throws]
|
||||
DOMString sanitizeToString(optional SanitizerInput input);
|
||||
};
|
|
@ -277,6 +277,9 @@ with Files("RTC*"):
|
|||
with Files("SVG*"):
|
||||
BUG_COMPONENT = ("Core", "SVG")
|
||||
|
||||
with Files("Sanitizer.webidl"):
|
||||
BUG_COMPONENT = ("Core", "DOM: Security")
|
||||
|
||||
with Files("ScriptProcessorNode.webidl"):
|
||||
BUG_COMPONENT = ("Core", "Web Audio")
|
||||
|
||||
|
@ -781,6 +784,7 @@ WEBIDL_FILES = [
|
|||
'Request.webidl',
|
||||
'ResizeObserver.webidl',
|
||||
'Response.webidl',
|
||||
'Sanitizer.webidl',
|
||||
'Screen.webidl',
|
||||
'ScreenOrientation.webidl',
|
||||
'ScriptProcessorNode.webidl',
|
||||
|
|
|
@ -4,9 +4,9 @@ Building SpiderMonkey
|
|||
**Before you begin, make sure you have the right build tools for your
|
||||
computer:**
|
||||
|
||||
* :ref:`linux-build-documentation`
|
||||
* `Windows <https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Build_Instructions/Windows_Prerequisites>`__
|
||||
* `Mac <https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Build_Instructions/Mac_OS_X_Prerequisites>`__
|
||||
* :ref:`Building Firefox On Linux`
|
||||
* :ref:`Building Firefox On Windows`
|
||||
* :ref:`Building Firefox On MacOS`
|
||||
* `Others <https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Build_Instructions>`__
|
||||
|
||||
This guide shows you how to build SpiderMonkey using ``mach``, which is Mozilla's multipurpose build tool.
|
||||
|
@ -118,6 +118,118 @@ looks like this:
|
|||
# switching between optimized and debug builds while developing.
|
||||
mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-opt-@CONFIG_GUESS@
|
||||
|
||||
SpiderMonkey on Android aarch64
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Building SpiderMonkey on Android
|
||||
--------------------------------
|
||||
|
||||
- First, run `mach bootstrap` and answer `GeckoView/Firefox for Android` when
|
||||
asked which project you want to build. This will download a recent Android
|
||||
NDK, make sure all the build dependencies required to compile on Android are
|
||||
present, etc.
|
||||
- Make sure that `$MOZBUILD_DIR/android-sdk-linux/platform-tools` is present in
|
||||
your `PATH` environment. You can do this by running the following line in a
|
||||
shell, or adding it to a shell profile init file:
|
||||
|
||||
.. code::
|
||||
|
||||
$ export PATH="$PATH:~/.mozbuild/android-sdk-linux/platform-tools"
|
||||
|
||||
- Create a typical `mozconfig` file for compiling SpiderMonkey, as outlined in
|
||||
the :ref:`Setting up a MOZCONFIG` documentation, and include the following
|
||||
line:
|
||||
|
||||
.. code::
|
||||
|
||||
ac_add_options --target=aarch64-linux-android
|
||||
|
||||
- Then compile as usual with `mach compile` with this `MOZCONFIG` file.
|
||||
|
||||
Running jit-tests on Android
|
||||
----------------------------
|
||||
|
||||
- Plug your Android device to the machine which compiled the shell for aarch64
|
||||
as described above, or make sure it is on the same subnetwork as the host. It
|
||||
should appear in the list of devices seen by `adb`:
|
||||
|
||||
.. code::
|
||||
|
||||
adb devices
|
||||
|
||||
This command should show you a device ID with the name of the device. If it
|
||||
doesn't, make sure that you have enabled Developer options on your device, as
|
||||
well as `enabled USB debugging on the device <https://developer.android.com/studio/debug/dev-options>`_.
|
||||
|
||||
- Run `mach jit-test --remote {JIT_TEST_ARGS}` with the android-aarch64
|
||||
`MOZCONFIG` file. This will upload the JS shell and its dependencies to the
|
||||
Android device, in a temporary directory (`/data/local/tmp/test_root/bin` as
|
||||
of 2020-09-02). Then it will start running the jit-test suite.
|
||||
|
||||
Debugging jit-tests on Android
|
||||
------------------------------
|
||||
|
||||
Debugging on Android uses the GDB remote debugging protocol, so we'll set up a
|
||||
GDB server on the Android device, that is going to be controlled remotely by
|
||||
the host machine.
|
||||
|
||||
- Upload the `gdbserver` precompiled binary from the NDK from the host machine
|
||||
to the Android device, using this command on the host:
|
||||
|
||||
.. code::
|
||||
|
||||
adb push \
|
||||
~/.mozbuild/android-ndk-r20/prebuilt/android-arm64/gdbserver/gdbserver \
|
||||
/data/local/tmp/test_root/bin
|
||||
|
||||
- Make sure that the `ncurses5` library is installed on the host. On
|
||||
Debian-like distros, this can be done with `sudo apt install -y libncurses5`.
|
||||
|
||||
- Set up port forwarding for the GDB port, from the Android device to the host,
|
||||
so we can connect to a local port from the host, without needing to find what
|
||||
the IP address of the Android device is:
|
||||
|
||||
.. code::
|
||||
|
||||
adb forward tcp:5039 tcp:5039
|
||||
|
||||
- Start `gdbserver` on the phone, passing the JS shell command line arguments
|
||||
to gdbserver:
|
||||
|
||||
.. code::
|
||||
|
||||
adb shell export LD_LIBRARY_PATH=/data/local/tmp/test_root/bin '&&' /data/local/tmp/test_root/bin/gdbserver :5039 /data/local/tmp/test_root/bin/js /path/to/test.js
|
||||
|
||||
.. note::
|
||||
|
||||
Note this will make the gdbserver listen on the 5039 port on all the
|
||||
network interfaces. In particular, the gdbserver will be reachable from
|
||||
every other devices on the same networks as your phone. Since the gdbserver
|
||||
protocol is unsafe, it is strongly recommended to double-check that the
|
||||
gdbserver process has properly terminated when exiting the shell, and to
|
||||
not run it more than needed.
|
||||
|
||||
.. note::
|
||||
|
||||
You can find the full command line that the `jit_test.py` script is
|
||||
using by giving it the `-s` parameter, and copy/paste it as the final
|
||||
argument to the gdbserver invocation above.
|
||||
|
||||
- On the host, start the precompiled NDK version of GDB that matches your host
|
||||
architecture, passing it the path to the shell compiled with `mach` above:
|
||||
|
||||
.. code::
|
||||
|
||||
~/.mozbuild/android-ndk-r20/prebuilt/linux-x86_64/bin/gdb /path/to/objdir-aarch64-linux-android/dist/bin/js
|
||||
|
||||
- Then connect remotely to the GDB server that's listening on the Android
|
||||
device:
|
||||
|
||||
.. code::
|
||||
|
||||
(gdb) target remote :5039
|
||||
(gdb) continue
|
||||
|
||||
Cross-Compiling
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -52,6 +52,16 @@ static int membarrier(int cmd, int flags) {
|
|||
return syscall(__NR_membarrier, cmd, flags);
|
||||
}
|
||||
|
||||
// These definitions come from the Linux kernel source, for kernels before 4.16
|
||||
// which didn't have access to these membarrier commands.
|
||||
# ifndef MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE
|
||||
# define MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE (1 << 5)
|
||||
# endif
|
||||
|
||||
# ifndef MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE
|
||||
# define MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE (1 << 6)
|
||||
# endif
|
||||
|
||||
#endif // __aarch64__
|
||||
|
||||
namespace vixl {
|
||||
|
|
|
@ -1151,6 +1151,10 @@ static JSString* FuncTypeToString(JSContext* cx, const FuncType& funcType) {
|
|||
}
|
||||
|
||||
UniqueChars argStr = ToString(arg);
|
||||
if (!argStr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!buf.append(argStr.get(), strlen(argStr.get()))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -1169,6 +1173,10 @@ static JSString* FuncTypeToString(JSContext* cx, const FuncType& funcType) {
|
|||
}
|
||||
|
||||
UniqueChars resultStr = ToString(result);
|
||||
if (!resultStr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!buf.append(resultStr.get(), strlen(resultStr.get()))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -570,7 +570,15 @@ inline bool OpIter<Policy>::checkIsSubtypeOf(ValType actual, ValType expected) {
|
|||
}
|
||||
|
||||
UniqueChars actualText = ToString(actual);
|
||||
if (!actualText) {
|
||||
return false;
|
||||
}
|
||||
|
||||
UniqueChars expectedText = ToString(expected);
|
||||
if (!expectedText) {
|
||||
return false;
|
||||
}
|
||||
|
||||
UniqueChars error(
|
||||
JS_smprintf("type mismatch: expression has type %s but expected %s",
|
||||
actualText.get(), expectedText.get()));
|
||||
|
@ -691,6 +699,10 @@ inline bool OpIter<Policy>::popWithRefType(Value* value) {
|
|||
}
|
||||
|
||||
UniqueChars actualText = ToString(stackType.valType());
|
||||
if (!actualText) {
|
||||
return false;
|
||||
}
|
||||
|
||||
UniqueChars error(JS_smprintf(
|
||||
"type mismatch: expression has type %s but expected a reference type",
|
||||
actualText.get()));
|
||||
|
|
|
@ -140,6 +140,7 @@ use std::ptr;
|
|||
|
||||
use crate::bindings::{CompiledFunc, FuncCompileInput, ModuleEnvironment, StaticEnvironment};
|
||||
use crate::compile::BatchCompiler;
|
||||
use cranelift_codegen::CodegenError;
|
||||
|
||||
/// Initializes all the process-wide Cranelift state. It must be called at least once, before any
|
||||
/// other use of this crate. It is not an issue if it is called more than once; subsequent calls
|
||||
|
@ -218,9 +219,21 @@ pub unsafe extern "C" fn cranelift_compile_function(
|
|||
};
|
||||
|
||||
if let Err(e) = compiler.compile(data.stackmaps()) {
|
||||
error!("Cranelift compilation error: {}\n", e);
|
||||
info!("Compiled function: {}", compiler);
|
||||
return false;
|
||||
// Make sure to panic on verifier errors, so that fuzzers see those. Other errors are about
|
||||
// unsupported features or implementation limits, so just report them as a user-facing
|
||||
// error.
|
||||
match e {
|
||||
CodegenError::Verifier(verifier_error) => {
|
||||
panic!("Cranelift verifier error: {}", verifier_error);
|
||||
}
|
||||
CodegenError::ImplLimitExceeded
|
||||
| CodegenError::CodeTooLarge
|
||||
| CodegenError::Unsupported(_) => {
|
||||
error!("Cranelift compilation error: {}\n", e);
|
||||
info!("Compiled function: {}", compiler);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// TODO(bbouvier) if destroy is called while one of these objects is alive, you're going to
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html><head>
|
||||
<meta charset="utf-8">
|
||||
<title>Reference for bug 1246836</title>
|
||||
<style type="text/css">
|
||||
html,body {
|
||||
color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0;
|
||||
}
|
||||
|
||||
select {
|
||||
-moz-appearance: none;
|
||||
border: 1px solid black;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<select><option>ABC</select>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,27 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html><head>
|
||||
<meta charset="utf-8">
|
||||
<title>Testcase for bug 1246836</title>
|
||||
<style type="text/css">
|
||||
html,body {
|
||||
color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0;
|
||||
}
|
||||
|
||||
select {
|
||||
-moz-appearance: button;
|
||||
border: 1px solid black;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<select><option>ABC</select>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -12,7 +12,6 @@ needs-focus == focusring-3.html focusring-3-ref.html
|
|||
== dynamic-text-indent-1.html dynamic-text-indent-1-ref.html
|
||||
== dynamic-text-overflow-1.html dynamic-text-overflow-1-ref.html
|
||||
== listbox-zero-row-initial.html listbox-zero-row-initial-ref.html
|
||||
== 1246836.html 1246836-ref.html
|
||||
skip-if(Android) == select-option-display-none-inline-size.html select-option-display-none-inline-size-ref.html
|
||||
|
||||
# Android and Windows actually use the anonymous select > button (rather than
|
||||
|
|
|
@ -580,7 +580,6 @@ cbindgen-types = [
|
|||
{ gecko = "StyleSVGLength", servo = "crate::values::computed::svg::SVGLength" },
|
||||
{ gecko = "StyleFontSizeKeyword", servo = "crate::values::specified::font::FontSizeKeyword" },
|
||||
{ gecko = "StyleDefaultFontSizes", servo = "crate::gecko::wrapper::DefaultFontSizes" },
|
||||
{ gecko = "StyleButtonAppearance", servo = "crate::values::specified::ButtonAppearance" },
|
||||
]
|
||||
|
||||
mapped-generic-types = [
|
||||
|
|
|
@ -2165,7 +2165,6 @@ nsStyleDisplay::nsStyleDisplay(const Document& aDocument)
|
|||
mContain(StyleContain::NONE),
|
||||
mAppearance(StyleAppearance::None),
|
||||
mDefaultAppearance(StyleAppearance::None),
|
||||
mButtonAppearance(StyleButtonAppearance::Allow),
|
||||
mPosition(StylePositionProperty::Static),
|
||||
mFloat(StyleFloat::None),
|
||||
mBreakType(StyleClear::None),
|
||||
|
@ -2236,7 +2235,6 @@ nsStyleDisplay::nsStyleDisplay(const nsStyleDisplay& aSource)
|
|||
mContain(aSource.mContain),
|
||||
mAppearance(aSource.mAppearance),
|
||||
mDefaultAppearance(aSource.mDefaultAppearance),
|
||||
mButtonAppearance(aSource.mButtonAppearance),
|
||||
mPosition(aSource.mPosition),
|
||||
mFloat(aSource.mFloat),
|
||||
mBreakType(aSource.mBreakType),
|
||||
|
@ -2504,7 +2502,6 @@ nsChangeHint nsStyleDisplay::CalcDifference(
|
|||
mBreakAfter != aNewData.mBreakAfter ||
|
||||
mAppearance != aNewData.mAppearance ||
|
||||
mDefaultAppearance != aNewData.mDefaultAppearance ||
|
||||
mButtonAppearance != aNewData.mButtonAppearance ||
|
||||
mOrient != aNewData.mOrient ||
|
||||
mOverflowClipBoxBlock != aNewData.mOverflowClipBoxBlock ||
|
||||
mOverflowClipBoxInline != aNewData.mOverflowClipBoxInline) {
|
||||
|
|
|
@ -1224,7 +1224,6 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay {
|
|||
|
||||
public:
|
||||
mozilla::StyleAppearance mDefaultAppearance;
|
||||
mozilla::StyleButtonAppearance mButtonAppearance;
|
||||
mozilla::StylePositionProperty mPosition;
|
||||
|
||||
mozilla::StyleFloat mFloat;
|
||||
|
@ -1334,6 +1333,7 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay {
|
|||
mozilla::StyleAppearance EffectiveAppearance() const {
|
||||
switch (mAppearance) {
|
||||
case mozilla::StyleAppearance::Auto:
|
||||
case mozilla::StyleAppearance::Button:
|
||||
case mozilla::StyleAppearance::Searchfield:
|
||||
case mozilla::StyleAppearance::Textarea:
|
||||
case mozilla::StyleAppearance::Checkbox:
|
||||
|
@ -1366,14 +1366,6 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay {
|
|||
// difference between menulist and menulist-button handling, we don't
|
||||
// bother.
|
||||
return mDefaultAppearance;
|
||||
case mozilla::StyleAppearance::Button:
|
||||
// `appearance: button` should behave like `auto` for a specific list
|
||||
// of widget elements, and we encode that using the internal
|
||||
// -moz-button-appearance property.
|
||||
if (mButtonAppearance == mozilla::StyleButtonAppearance::Disallow) {
|
||||
return mDefaultAppearance;
|
||||
}
|
||||
return mAppearance;
|
||||
default:
|
||||
return mAppearance;
|
||||
}
|
||||
|
|
|
@ -86,7 +86,6 @@ input {
|
|||
display: inline-block;
|
||||
appearance: auto;
|
||||
-moz-default-appearance: textfield;
|
||||
-moz-button-appearance: disallow;
|
||||
/* The sum of border and padding on block-start and block-end
|
||||
must be the same here, for buttons, and for <select> (including its
|
||||
internal padding magic) */
|
||||
|
@ -110,7 +109,6 @@ input::placeholder {
|
|||
textarea {
|
||||
appearance: auto;
|
||||
-moz-default-appearance: textarea;
|
||||
-moz-button-appearance: disallow;
|
||||
margin-block: 1px;
|
||||
border: 2px inset ThreeDLightShadow;
|
||||
/* The 1px inline padding is for parity with Win/IE */
|
||||
|
@ -242,7 +240,6 @@ select {
|
|||
padding-block: 0;
|
||||
appearance: auto;
|
||||
-moz-default-appearance: menulist;
|
||||
-moz-button-appearance: allow;
|
||||
}
|
||||
|
||||
select:-moz-select-list-box {
|
||||
|
@ -253,7 +250,6 @@ select:-moz-select-list-box {
|
|||
padding-block: 1px;
|
||||
appearance: auto;
|
||||
-moz-default-appearance: listbox;
|
||||
-moz-button-appearance: disallow;
|
||||
}
|
||||
|
||||
select > button {
|
||||
|
@ -754,7 +750,6 @@ output:-moz-ui-invalid {
|
|||
progress {
|
||||
appearance: auto;
|
||||
-moz-default-appearance: progress-bar;
|
||||
-moz-button-appearance: disallow;
|
||||
display: inline-block;
|
||||
vertical-align: -0.2em;
|
||||
|
||||
|
@ -767,8 +762,11 @@ progress {
|
|||
}
|
||||
|
||||
::-moz-progress-bar {
|
||||
display: inline-block;
|
||||
|
||||
/* Prevent styling that would change the type of frame we construct. */
|
||||
display: inline-block !important;
|
||||
float: none !important;
|
||||
position: static !important;
|
||||
overflow: visible !important;
|
||||
box-sizing: border-box !important;
|
||||
|
||||
appearance: auto;
|
||||
|
@ -783,14 +781,17 @@ progress {
|
|||
meter {
|
||||
appearance: auto;
|
||||
-moz-default-appearance: meter;
|
||||
-moz-button-appearance: disallow;
|
||||
display: inline-block;
|
||||
vertical-align: -0.2em;
|
||||
background: linear-gradient(#e6e6e6, #e6e6e6, #eeeeee 20%, #cccccc 45%, #cccccc 55%);
|
||||
}
|
||||
|
||||
::-moz-meter-bar {
|
||||
display: inline-block;
|
||||
/* Block styles that would change the type of frame we construct. */
|
||||
display: inline-block !important;
|
||||
float: none !important;
|
||||
position: static !important;
|
||||
overflow: visible !important;
|
||||
|
||||
appearance: auto;
|
||||
-moz-default-appearance: meterchunk;
|
||||
|
@ -833,7 +834,12 @@ input[type=range] {
|
|||
* set the width/height of this pseudo-element.
|
||||
*/
|
||||
input[type=range]::-moz-range-track {
|
||||
display: block;
|
||||
/* Prevent styling that would change the type of frame we construct. */
|
||||
display: block !important;
|
||||
float: none !important;
|
||||
position: static !important;
|
||||
writing-mode: unset !important;
|
||||
direction: unset !important;
|
||||
block-size: 0.2em; /* same as inline-size below */
|
||||
/* Prevent nsIFrame::HandlePress setting mouse capture to this element. */
|
||||
user-select: none !important;
|
||||
|
@ -853,7 +859,12 @@ input[type=range][orient=vertical]::-moz-range-track {
|
|||
* is ignored.
|
||||
*/
|
||||
input[type=range]::-moz-range-progress {
|
||||
display: block;
|
||||
/* Prevent styling that would change the type of frame we construct. */
|
||||
display: block !important;
|
||||
float: none !important;
|
||||
position: static !important;
|
||||
writing-mode: unset !important;
|
||||
direction: unset !important;
|
||||
/* Since one of width/height will be ignored, this just sets the "other"
|
||||
dimension.
|
||||
*/
|
||||
|
@ -875,7 +886,12 @@ input[type=range]::-moz-range-thumb {
|
|||
*/
|
||||
appearance: auto !important;
|
||||
-moz-default-appearance: range-thumb !important;
|
||||
display: block;
|
||||
/* Prevent styling that would change the type of frame we construct. */
|
||||
display: block !important;
|
||||
float: none !important;
|
||||
position: static !important;
|
||||
writing-mode: unset !important;
|
||||
direction: unset !important;
|
||||
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
|
@ -892,7 +908,10 @@ input[type="number"] {
|
|||
}
|
||||
|
||||
input:is([type=number], [type=search])::-moz-complex-control-wrapper {
|
||||
/* Prevent styling that would change the type of frame we construct. */
|
||||
display: flex;
|
||||
float: none !important;
|
||||
position: static !important;
|
||||
block-size: 100%;
|
||||
/* The align-self: center bit below allows the editor to be potentially
|
||||
* bigger than us. Clip it to match other text fields. */
|
||||
|
|
|
@ -90,7 +90,6 @@ const char* gInaccessibleProperties[] = {
|
|||
"-x-lang",
|
||||
"-x-span",
|
||||
"-x-text-zoom",
|
||||
"-moz-button-appearance",
|
||||
"-moz-context-properties",
|
||||
"-moz-control-character-visibility",
|
||||
"-moz-default-appearance",
|
||||
|
|
|
@ -2649,6 +2649,12 @@
|
|||
value: true
|
||||
mirror: always
|
||||
|
||||
# pref controls `Sanitizer` API being exposed
|
||||
- name: dom.security.sanitizer.enabled
|
||||
type: bool
|
||||
value: false
|
||||
mirror: always
|
||||
|
||||
# Is support for selection event APIs enabled?
|
||||
- name: dom.select_events.enabled
|
||||
type: bool
|
||||
|
|
|
@ -1655,8 +1655,6 @@ fi
|
|||
|
||||
if test -f "${_topsrcdir}/$REAL_BRANDING_DIRECTORY/configure.sh"; then
|
||||
. "${_topsrcdir}/$REAL_BRANDING_DIRECTORY/configure.sh"
|
||||
elif test -f "${EXTERNAL_SOURCE_DIR}/$REAL_BRANDING_DIRECTORY/configure.sh"; then
|
||||
. "${EXTERNAL_SOURCE_DIR}/$REAL_BRANDING_DIRECTORY/configure.sh"
|
||||
fi
|
||||
|
||||
AC_SUBST(MOZ_BRANDING_DIRECTORY)
|
||||
|
|
|
@ -16,7 +16,7 @@ static HINSTANCE gHInst;
|
|||
|
||||
// ***** Section: ScopeExit
|
||||
// Derived from mfbt mozilla::ScopeExit, I have removed the use of
|
||||
// GuardObjectNotifier and annotations MOZ_STACK_CLASS and MOZ_MUST_USE.
|
||||
// GuardObjectNotifier and the MOZ_* annotations.
|
||||
template <typename ExitFunction>
|
||||
class ScopeExit {
|
||||
ExitFunction mExitFunction;
|
||||
|
@ -314,4 +314,4 @@ BOOL APIENTRY DllMain(HINSTANCE instance, DWORD reason, LPVOID) {
|
|||
InitializeCriticalSection(&gStartBitsThread.cs);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -183,14 +183,6 @@ class ConfigEnvironment(object):
|
|||
|
||||
self.substs = ReadOnlyDict(self.substs)
|
||||
|
||||
self.external_source_dir = None
|
||||
external = self.substs.get('EXTERNAL_SOURCE_DIR', '')
|
||||
if external:
|
||||
external = mozpath.normpath(external)
|
||||
if not os.path.isabs(external):
|
||||
external = mozpath.join(self.topsrcdir, external)
|
||||
self.external_source_dir = mozpath.normpath(external)
|
||||
|
||||
@property
|
||||
def is_artifact_build(self):
|
||||
return self.substs.get('MOZ_ARTIFACT_BUILDS', False)
|
||||
|
|
|
@ -769,11 +769,6 @@ class SourcePath(Path):
|
|||
|
||||
if value.startswith('/'):
|
||||
path = None
|
||||
# If the path starts with a '/' and is actually relative to an
|
||||
# external source dir, use that as base instead of topsrcdir.
|
||||
if context.config.external_source_dir:
|
||||
path = mozpath.join(context.config.external_source_dir,
|
||||
value[1:])
|
||||
if not path or not os.path.exists(path):
|
||||
path = mozpath.join(context.config.topsrcdir,
|
||||
value[1:])
|
||||
|
|
|
@ -118,7 +118,6 @@ class EmptyConfig(object):
|
|||
|
||||
self.substs = self.PopulateOnGetDict(EmptyValue, substs or self.default_substs)
|
||||
self.defines = self.substs
|
||||
self.external_source_dir = None
|
||||
self.error_is_fatal = False
|
||||
|
||||
|
||||
|
@ -141,12 +140,6 @@ def is_read_allowed(path, config):
|
|||
if mozpath.basedir(path, [topsrcdir]):
|
||||
return True
|
||||
|
||||
if config.external_source_dir:
|
||||
external_dir = os.path.normcase(config.external_source_dir)
|
||||
norm_path = os.path.normcase(path)
|
||||
if mozpath.basedir(norm_path, [external_dir]):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
|
@ -1098,14 +1091,6 @@ class BuildReader(object):
|
|||
|
||||
topobjdir = config.topobjdir
|
||||
|
||||
if not mozpath.basedir(path, [config.topsrcdir]):
|
||||
external = config.external_source_dir
|
||||
if external and mozpath.basedir(path, [external]):
|
||||
config = ConfigEnvironment.from_config_status(
|
||||
mozpath.join(topobjdir, 'config.status'))
|
||||
config.topsrcdir = external
|
||||
config.external_source_dir = None
|
||||
|
||||
relpath = mozpath.relpath(path, config.topsrcdir)
|
||||
reldir = mozpath.dirname(relpath)
|
||||
|
||||
|
@ -1114,7 +1099,6 @@ class BuildReader(object):
|
|||
config = ConfigEnvironment.from_config_status(
|
||||
mozpath.join(topobjdir, reldir, 'config.status'))
|
||||
config.topobjdir = topobjdir
|
||||
config.external_source_dir = None
|
||||
|
||||
context = Context(VARIABLES, config, self.finder)
|
||||
sandbox = MozbuildSandbox(context, metadata=metadata,
|
||||
|
|
|
@ -61,7 +61,6 @@ class MockConfig(object):
|
|||
|
||||
self.defines = self.substs
|
||||
|
||||
self.external_source_dir = None
|
||||
self.lib_prefix = 'lib'
|
||||
self.rust_lib_prefix = 'lib'
|
||||
self.lib_suffix = '.a'
|
||||
|
|
|
@ -286,7 +286,6 @@ class TestPaths(unittest.TestCase):
|
|||
cls.config = config = Config()
|
||||
config.topsrcdir = mozpath.abspath(os.curdir)
|
||||
config.topobjdir = mozpath.abspath('obj')
|
||||
config.external_source_dir = None
|
||||
|
||||
def test_path(self):
|
||||
config = self.config
|
||||
|
|
|
@ -212,8 +212,8 @@ static void InstallSigSysHandler(void) {
|
|||
* @see SandboxInfo
|
||||
* @see BroadcastSetThreadSandbox
|
||||
*/
|
||||
static bool MOZ_MUST_USE InstallSyscallFilter(const sock_fprog* aProg,
|
||||
bool aUseTSync) {
|
||||
[[nodiscard]] static bool InstallSyscallFilter(const sock_fprog* aProg,
|
||||
bool aUseTSync) {
|
||||
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
|
||||
if (!aUseTSync && errno == ETXTBSY) {
|
||||
return false;
|
||||
|
|
|
@ -334,7 +334,6 @@ class Longhand(object):
|
|||
"BackgroundRepeat",
|
||||
"BorderImageRepeat",
|
||||
"BorderStyle",
|
||||
"ButtonAppearance",
|
||||
"Clear",
|
||||
"ColumnCount",
|
||||
"Contain",
|
||||
|
|
|
@ -639,25 +639,6 @@ ${helpers.predefined_type(
|
|||
gecko_ffi_name="mDefaultAppearance",
|
||||
)}
|
||||
|
||||
// A UA-sheet only property that controls the effect of `appearance: button`
|
||||
// on the element: `-moz-button-appearance: allow` means the element is rendered
|
||||
// with button appearance, and `-moz-button-appearance: disallow` is treated
|
||||
// like `appearance: auto`.
|
||||
//
|
||||
// https://github.com/w3c/csswg-drafts/issues/5174 proposes to simplify `button`
|
||||
// to mean `auto` unconditionally, at which point this property can be removed.
|
||||
${helpers.predefined_type(
|
||||
"-moz-button-appearance",
|
||||
"ButtonAppearance",
|
||||
"computed::ButtonAppearance::Allow",
|
||||
engines="gecko",
|
||||
animation_value_type="none",
|
||||
needs_context=False,
|
||||
spec="Internal (not web-exposed)",
|
||||
enabled_in="ua",
|
||||
gecko_ffi_name="mButtonAppearance",
|
||||
)}
|
||||
|
||||
${helpers.single_keyword(
|
||||
"-moz-orient",
|
||||
"inline block horizontal vertical",
|
||||
|
|
|
@ -12,7 +12,7 @@ use crate::values::generics::box_::VerticalAlign as GenericVerticalAlign;
|
|||
use crate::values::specified::box_ as specified;
|
||||
|
||||
pub use crate::values::specified::box_::{AnimationName, Appearance, BreakBetween, BreakWithin};
|
||||
pub use crate::values::specified::box_::{ButtonAppearance, Clear as SpecifiedClear};
|
||||
pub use crate::values::specified::box_::{Clear as SpecifiedClear};
|
||||
pub use crate::values::specified::box_::{Float as SpecifiedFloat, Contain, Display, Overflow};
|
||||
pub use crate::values::specified::box_::{OverflowAnchor, OverflowClipBox, OverscrollBehavior};
|
||||
pub use crate::values::specified::box_::{
|
||||
|
|
|
@ -42,7 +42,7 @@ pub use self::border::{BorderCornerRadius, BorderRadius, BorderSpacing};
|
|||
pub use self::border::{BorderImageRepeat, BorderImageSideWidth};
|
||||
pub use self::border::{BorderImageSlice, BorderImageWidth};
|
||||
pub use self::box_::{AnimationIterationCount, AnimationName, Contain};
|
||||
pub use self::box_::{Appearance, BreakBetween, BreakWithin, ButtonAppearance, Clear, Float};
|
||||
pub use self::box_::{Appearance, BreakBetween, BreakWithin, Clear, Float};
|
||||
pub use self::box_::{Display, Overflow, OverflowAnchor, TransitionProperty};
|
||||
pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective, Resize};
|
||||
pub use self::box_::{ScrollSnapAlign, ScrollSnapAxis, ScrollSnapStrictness, ScrollSnapType};
|
||||
|
|
|
@ -1845,31 +1845,6 @@ pub enum Appearance {
|
|||
Count,
|
||||
}
|
||||
|
||||
/// The effect of `appearance: button` on an element.
|
||||
#[derive(
|
||||
Clone,
|
||||
Copy,
|
||||
Debug,
|
||||
Eq,
|
||||
Hash,
|
||||
MallocSizeOf,
|
||||
Parse,
|
||||
PartialEq,
|
||||
SpecifiedValueInfo,
|
||||
ToCss,
|
||||
ToComputedValue,
|
||||
ToResolvedValue,
|
||||
ToShmem,
|
||||
)]
|
||||
#[repr(u8)]
|
||||
pub enum ButtonAppearance {
|
||||
/// `appearance: button` means the element is rendered with button
|
||||
/// appearance.
|
||||
Allow,
|
||||
/// `appearance: button` is treated like `appearance: auto`.
|
||||
Disallow,
|
||||
}
|
||||
|
||||
/// A kind of break between two boxes.
|
||||
///
|
||||
/// https://drafts.csswg.org/css-break/#break-between
|
||||
|
|
|
@ -37,7 +37,7 @@ pub use self::border::{BorderCornerRadius, BorderImageSlice, BorderImageWidth};
|
|||
pub use self::border::{BorderImageRepeat, BorderImageSideWidth};
|
||||
pub use self::border::{BorderRadius, BorderSideWidth, BorderSpacing, BorderStyle};
|
||||
pub use self::box_::{AnimationIterationCount, AnimationName, Contain, Display};
|
||||
pub use self::box_::{Appearance, BreakBetween, BreakWithin, ButtonAppearance};
|
||||
pub use self::box_::{Appearance, BreakBetween, BreakWithin};
|
||||
pub use self::box_::{Clear, Float, Overflow, OverflowAnchor};
|
||||
pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective, Resize};
|
||||
pub use self::box_::{ScrollSnapAlign, ScrollSnapAxis, ScrollSnapStrictness, ScrollSnapType};
|
||||
|
|
|
@ -221,7 +221,6 @@ include = [
|
|||
"FontSizeKeyword",
|
||||
"AspectRatio",
|
||||
"DefaultFontSizes",
|
||||
"ButtonAppearance",
|
||||
"RuleChangeKind",
|
||||
]
|
||||
item_types = ["enums", "structs", "unions", "typedefs", "functions", "constants"]
|
||||
|
|
|
@ -21,8 +21,6 @@ job-defaults:
|
|||
- 'build/clang-plugin/moz.build'
|
||||
- 'build/clang-plugin/Makefile.in'
|
||||
- 'build/build-clang/build-clang.py'
|
||||
run-on-projects:
|
||||
- trunk
|
||||
fetches:
|
||||
fetch:
|
||||
- clang-10
|
||||
|
@ -38,6 +36,8 @@ linux64-clang-tidy:
|
|||
- 'build/build-clang/clang-tidy-linux64.json'
|
||||
resources:
|
||||
- 'build/build-clang/clang-tidy-linux64.json'
|
||||
run-on-projects:
|
||||
- trunk
|
||||
fetches:
|
||||
toolchain:
|
||||
- linux64-binutils
|
||||
|
@ -61,6 +61,8 @@ macosx64-clang-tidy:
|
|||
resources:
|
||||
- 'build/build-clang/clang-tidy-macosx64.json'
|
||||
- 'taskcluster/scripts/misc/tooltool-download.sh'
|
||||
run-on-projects:
|
||||
- trunk
|
||||
fetches:
|
||||
toolchain:
|
||||
- linux64-binutils
|
||||
|
@ -88,12 +90,16 @@ win64-clang-tidy:
|
|||
resources:
|
||||
- 'build/build-clang/clang-tidy-win64.json'
|
||||
tooltool-downloads: internal
|
||||
run-on-projects:
|
||||
- trunk
|
||||
fetches:
|
||||
fetch:
|
||||
- cmake
|
||||
- ninja
|
||||
|
||||
linux64-civet-tidy:
|
||||
attributes:
|
||||
local-toolchain: false
|
||||
index:
|
||||
job-name: linux64-civet-tidy
|
||||
treeherder:
|
||||
|
@ -110,6 +116,7 @@ linux64-civet-tidy:
|
|||
- 'build/build-clang/civet-tidy-linux64.json'
|
||||
resources:
|
||||
- 'build/build-clang/civet-tidy-linux64.json'
|
||||
run-on-projects: []
|
||||
fetches:
|
||||
fetch:
|
||||
- civet-source
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Reference: appearance: button</title>
|
||||
<select><option>select</option></select>
|
|
@ -1,16 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Basic User Interface Test: appearance: button</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-ui-4/#appearance-switching">
|
||||
<meta name="assert" content="Drop-down select elements with appearance: button are rendered differently from appearance: auto.">
|
||||
<link rel="mismatch" href="appearance-button-002.tentative-ref.html">
|
||||
<style>
|
||||
select { appearance: none; appearance: button; }
|
||||
</style>
|
||||
<!--
|
||||
Test marked as tentative since although css-ui says "The element is rendered
|
||||
with the look and feel of a push button, similar to the appearance: auto
|
||||
rendering of the [HTML] button element.", there is no requirement that the
|
||||
look and feel of a push button is different from that of a drop-down select.
|
||||
-->
|
||||
<select><option>select</option></select>
|
|
@ -1,16 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Basic User Interface Test: -webkit-appearance: button</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-ui-4/#appearance-switching">
|
||||
<meta name="assert" content="Drop-down select elements with appearance: button are rendered differently from appearance: auto.">
|
||||
<link rel="mismatch" href="appearance-button-002.tentative-ref.html">
|
||||
<style>
|
||||
select { -webkit-appearance: none; -webkit-appearance: button; }
|
||||
</style>
|
||||
<!--
|
||||
Test marked as tentative since although css-ui says "The element is rendered
|
||||
with the look and feel of a push button, similar to the appearance: auto
|
||||
rendering of the [HTML] button element.", there is no requirement that the
|
||||
look and feel of a push button is different from that of a drop-down select.
|
||||
-->
|
||||
<select><option>select</option></select>
|
|
@ -1,22 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="data:text/css,
|
||||
vbox { height: 50px; }
|
||||
button {
|
||||
color: transparent;
|
||||
margin: 0;
|
||||
}
|
||||
" type="text/css"?>
|
||||
|
||||
<window title="Buttons with mini, small and regular control font"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<vbox style="font-size: 9px">
|
||||
<hbox><button label="Mini"/></hbox>
|
||||
</vbox>
|
||||
<vbox style="font: message-box">
|
||||
<hbox><button label="Small"/></hbox>
|
||||
</vbox>
|
||||
<vbox style="font: -moz-dialog">
|
||||
<hbox><button label="Regular"/></hbox>
|
||||
</vbox>
|
||||
</window>
|
|
@ -1,6 +1,5 @@
|
|||
# This folder is registered in the chrome manifest at layout/tools/reftest/jar.mn.
|
||||
|
||||
skip-if(!cocoaWidget) == chrome://reftest/content/osx-theme/482681.xhtml chrome://reftest/content/osx-theme/482681-ref.xhtml
|
||||
skip-if(!cocoaWidget) == chrome://reftest/content/osx-theme/radiosize.xhtml chrome://reftest/content/osx-theme/radiosize-ref.xhtml
|
||||
skip-if(!cocoaWidget) == chrome://reftest/content/osx-theme/checkboxsize.xhtml chrome://reftest/content/osx-theme/checkboxsize-ref.xhtml
|
||||
# This failure is caused by bug 1586055 in WebRender
|
||||
|
|
|
@ -20,3 +20,9 @@ to the firefox source docs.
|
|||
4. Verify the rst syntax using `./mach lint -l rst`_
|
||||
|
||||
.. _./mach lint -l rst: /tools/lint/linters/rstlinter.html
|
||||
|
||||
5. If relevant, remove unbreakable spaces (rendered with a "!" on Phabricator)
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ sed -i -e 's/\xc2\xa0/ /g' doc.rst
|
||||
|
|
Загрузка…
Ссылка в новой задаче