author | Coroiu Cristina <ccoroiu@mozilla.com> |
Tue, 24 Jul 2018 00:43:44 +0300 | |
changeset 427861 | fe48e26ca88c7919f0c075dc01d5f9fdccdb1260 |
parent 427819 | 07414f000aa1977db52c9baeb75080b155906f59 (current diff) |
parent 427860 | b82a9d1bfaf8d7d9bd21c7cfea159299871f7fc8 (diff) |
child 427862 | c47bdc24522ff63a7142d98f6db7949613efe3d4 |
child 427946 | cb74f2db6d826553874874992ae3c631b5cabd5e |
push id | 66737 |
push user | ccoroiu@mozilla.com |
push date | Mon, 23 Jul 2018 21:45:57 +0000 |
treeherder | autoland@c47bdc24522f [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | merge |
milestone | 63.0a1 |
first release with | nightly linux32
fe48e26ca88c
/
63.0a1
/
20180723220051
/
files
nightly linux64
fe48e26ca88c
/
63.0a1
/
20180723220051
/
files
nightly mac
fe48e26ca88c
/
63.0a1
/
20180723220051
/
files
nightly win32
fe48e26ca88c
/
63.0a1
/
20180723220051
/
files
nightly win64
fe48e26ca88c
/
63.0a1
/
20180723220051
/
files
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly linux32
63.0a1
/
20180723220051
/
pushlog to previous
nightly linux64
63.0a1
/
20180723220051
/
pushlog to previous
nightly mac
63.0a1
/
20180723220051
/
pushlog to previous
nightly win32
63.0a1
/
20180723220051
/
pushlog to previous
nightly win64
63.0a1
/
20180723220051
/
pushlog to previous
|
browser/modules/LightweightThemeChildListener.jsm | file | annotate | diff | comparison | revisions | |
dom/security/test/csp/file_child_worker.js | file | annotate | diff | comparison | revisions | |
dom/security/test/csp/file_child_worker.js^headers^ | file | annotate | diff | comparison | revisions | |
dom/security/test/csp/file_main_worker.js | file | annotate | diff | comparison | revisions | |
dom/security/test/csp/file_main_worker.js^headers^ | file | annotate | diff | comparison | revisions | |
testing/web-platform/meta/clipboard-apis/async-navigator-clipboard-basics.https.html.ini | file | annotate | diff | comparison | revisions |
--- a/accessible/aom/AccessibleNode.cpp +++ b/accessible/aom/AccessibleNode.cpp @@ -38,16 +38,19 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION( NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_END NS_IMPL_CYCLE_COLLECTING_ADDREF(AccessibleNode) NS_IMPL_CYCLE_COLLECTING_RELEASE(AccessibleNode) AccessibleNode::AccessibleNode(nsINode* aNode) : + mDoubleProperties(3), + mIntProperties(3), + mUIntProperties(6), mBooleanProperties(0), mDOMNode(aNode) { nsAccessibilityService* accService = GetOrCreateAccService(); if (!accService) { return; }
--- a/accessible/aom/AccessibleNode.h +++ b/accessible/aom/AccessibleNode.h @@ -2,16 +2,17 @@ /* vim: set ts=2 et sw=2 tw=40: */ /* 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 A11Y_AOM_ACCESSIBLENODE_H #define A11Y_AOM_ACCESSIBLENODE_H +#include "nsDataHashtable.h" #include "nsWrapperCache.h" #include "mozilla/ErrorResult.h" #include "mozilla/dom/BindingDeclarations.h" #include "mozilla/dom/Nullable.h" class nsINode; namespace mozilla { @@ -40,16 +41,38 @@ struct ParentObject; } \ #define ANODE_PROPS(typeName, type, ...) \ enum class AOM##typeName##Property { \ MOZ_FOR_EACH(ANODE_ENUM, (), (__VA_ARGS__)) \ }; \ MOZ_FOR_EACH(ANODE_FUNC, (typeName, type,), (__VA_ARGS__)) \ +#define ANODE_ACCESSOR_MUTATOR(typeName, type, defVal) \ + nsDataHashtable<nsUint32HashKey, type> m##typeName##Properties; \ + \ + dom::Nullable<type> GetProperty(AOM##typeName##Property aProperty) \ + { \ + type value = defVal; \ + if (m##typeName##Properties.Get(static_cast<int>(aProperty), &value)) { \ + return dom::Nullable<type>(value); \ + } \ + return dom::Nullable<type>(); \ + } \ + \ + void SetProperty(AOM##typeName##Property aProperty, \ + const dom::Nullable<type>& aValue) \ + { \ + if (aValue.IsNull()) { \ + m##typeName##Properties.Remove(static_cast<int>(aProperty)); \ + } else { \ + m##typeName##Properties.Put(static_cast<int>(aProperty), aValue.Value()); \ + } \ + } \ + class AccessibleNode : public nsISupports, public nsWrapperCache { public: explicit AccessibleNode(nsINode* aNode); NS_DECL_CYCLE_COLLECTING_ISUPPORTS; NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(AccessibleNode); @@ -79,16 +102,37 @@ public: Modal, Multiline, Multiselectable, ReadOnly, Required, Selected ) + ANODE_PROPS(UInt, uint32_t, + ColIndex, + ColSpan, + Level, + PosInSet, + RowIndex, + RowSpan + ) + + ANODE_PROPS(Int, int32_t, + ColCount, + RowCount, + SetSize + ) + + ANODE_PROPS(Double, double, + ValueMax, + ValueMin, + ValueNow + ) + protected: AccessibleNode(const AccessibleNode& aCopy) = delete; AccessibleNode& operator=(const AccessibleNode& aCopy) = delete; virtual ~AccessibleNode(); dom::Nullable<bool> GetProperty(AOMBooleanProperty aProperty) { int num = static_cast<int>(aProperty); @@ -107,16 +151,20 @@ protected: mBooleanProperties &= ~(1U << (2 * num)); } else { mBooleanProperties |= (1U << (2 * num)); mBooleanProperties = (aValue.Value() ? mBooleanProperties | (1U << (2 * num + 1)) : mBooleanProperties & ~(1U << (2 * num + 1))); } } + ANODE_ACCESSOR_MUTATOR(Double, double, 0.0) + ANODE_ACCESSOR_MUTATOR(Int, int32_t, 0) + ANODE_ACCESSOR_MUTATOR(UInt, uint32_t, 0) + // The 2k'th bit indicates whether the k'th boolean property is used(1) or not(0) // and 2k+1'th bit contains the property's value(1:true, 0:false) uint32_t mBooleanProperties; RefPtr<a11y::Accessible> mIntl; RefPtr<nsINode> mDOMNode; RefPtr<dom::DOMStringList> mStates; };
--- a/accessible/jsat/AccessFu.jsm +++ b/accessible/jsat/AccessFu.jsm @@ -403,22 +403,19 @@ var Input = { mm.sendAsyncMessage("AccessFu:SetSelection", aDetails); }, clipboard: function clipboard(aDetails) { const mm = Utils.getMessageManager(); mm.sendAsyncMessage("AccessFu:Clipboard", aDetails); }, - activateCurrent: function activateCurrent(aData, aActivateIfKey = false) { + activateCurrent: function activateCurrent(aData) { let mm = Utils.getMessageManager(); - let offset = 0; - - mm.sendAsyncMessage("AccessFu:Activate", - {offset, activateIfKey: aActivateIfKey}); + mm.sendAsyncMessage("AccessFu:Activate", { offset: 0 }); }, // XXX: This is here for backwards compatability with screen reader simulator // it should be removed when the extension is updated on amo. scroll: function scroll(aPage, aHorizontal) { this.sendScrollMessage(aPage, aHorizontal); },
--- a/accessible/jsat/ContentControl.jsm +++ b/accessible/jsat/ContentControl.jsm @@ -181,26 +181,16 @@ this.ContentControl.prototype = { this.autoMove(null, aMessage.json); }, handleActivate: function cc_handleActivate(aMessage) { let activateAccessible = (aAccessible) => { Logger.debug(() => { return ["activateAccessible", Logger.accessibleToString(aAccessible)]; }); - try { - if (aMessage.json.activateIfKey && - !Utils.isActivatableOnFingerUp(aAccessible)) { - // Only activate keys, don't do anything on other objects. - return; - } - } catch (e) { - // accessible is invalid. Silently fail. - return; - } if (aAccessible.actionCount > 0) { aAccessible.doAction(0); } else { let control = Utils.getEmbeddedControl(aAccessible); if (control && control.actionCount > 0) { control.doAction(0); } @@ -224,18 +214,19 @@ this.ContentControl.prototype = { for (let eventType of ["mousedown", "mouseup"]) { let evt = this.document.createEvent("MouseEvents"); evt.initMouseEvent(eventType, true, true, this.window, x, y, 0, 0, 0, false, false, false, false, 0, null); node.dispatchEvent(evt); } } - if (!Utils.isActivatableOnFingerUp(aAccessible)) { - // Keys will typically have a sound of their own. + // Action invoked will be presented on checked/selected state change. + if (!Utils.getState(aAccessible).contains(States.CHECKABLE) && + !Utils.getState(aAccessible).contains(States.SELECTABLE)) { this._contentScope.get().sendAsyncMessage("AccessFu:Present", Presentation.actionInvoked(aAccessible, "click")); } }; let focusedAcc = Utils.AccService.getAccessibleFor( this.document.activeElement); if (focusedAcc && this.vc.position === focusedAcc
--- a/accessible/jsat/EventManager.jsm +++ b/accessible/jsat/EventManager.jsm @@ -145,48 +145,35 @@ this.EventManager.prototype = { const position = event.newAccessible; // We pass control to the vc in the embedded frame. if (position && position.role == Roles.INTERNAL_FRAME) { break; } // Blur to document if new position is not explicitly focused. - if (!Utils.getState(position).contains(States.FOCUSED)) { + if (!position || !Utils.getState(position).contains(States.FOCUSED)) { aEvent.accessibleDocument.takeFocus(); } this.present( Presentation.pivotChanged(position, event.oldAccessible, event.newStartOffset, event.newEndOffset, event.reason, event.boundaryType)); break; } case Events.STATE_CHANGE: { - let event = aEvent.QueryInterface(Ci.nsIAccessibleStateChangeEvent); - let state = Utils.getState(event); + const event = aEvent.QueryInterface(Ci.nsIAccessibleStateChangeEvent); + const state = Utils.getState(event); if (state.contains(States.CHECKED)) { - if (aEvent.accessible.role === Roles.SWITCH) { - this.present( - Presentation. - actionInvoked(aEvent.accessible, - event.isEnabled ? "on" : "off")); - } else { - this.present( - Presentation. - actionInvoked(aEvent.accessible, - event.isEnabled ? "check" : "uncheck")); - } + this.present(Presentation.checked(aEvent.accessible)); } else if (state.contains(States.SELECTED)) { - this.present( - Presentation. - actionInvoked(aEvent.accessible, - event.isEnabled ? "select" : "unselect")); + this.present(Presentation.selected(aEvent.accessible)); } break; } case Events.NAME_CHANGE: { let acc = aEvent.accessible; if (acc === this.contentControl.vc.position) { this.present(Presentation.nameChanged(acc));
--- a/accessible/jsat/OutputGenerator.jsm +++ b/accessible/jsat/OutputGenerator.jsm @@ -765,42 +765,30 @@ var UtteranceGenerator = { // jshint ig _addRole: function _addRole(aOutput, aAccessible, aRoleStr) { if (this.mathmlRolesSet.has(aAccessible.role)) { this._addMathRoles(aOutput, aAccessible, aRoleStr); } else { aOutput.push({string: this._getOutputName(aRoleStr)}); } }, + /** + * Add localized state information to output data. + * Note: We do not expose checked and selected states, we let TalkBack do it for us + * there. This is because we expose the checked information on the node info itself. + */ _addState: function _addState(aOutput, aState, aRoleStr) { - if (aState.contains(States.UNAVAILABLE)) { aOutput.push({string: "stateUnavailable"}); } if (aState.contains(States.READONLY)) { aOutput.push({string: "stateReadonly"}); } - // Don't utter this in Jelly Bean, we let TalkBack do it for us there. - // This is because we expose the checked information on the node itself. - // XXX: this means the checked state is always appended to the end, - // regardless of the utterance ordering preference. - if ((Utils.AndroidSdkVersion < 16 || Utils.MozBuildApp === "browser") && - aState.contains(States.CHECKABLE)) { - let checked = aState.contains(States.CHECKED); - let statetr; - if (aRoleStr === "switch") { - statetr = checked ? "stateOn" : "stateOff"; - } else { - statetr = checked ? "stateChecked" : "stateNotChecked"; - } - aOutput.push({string: statetr}); - } - if (aState.contains(States.PRESSED)) { aOutput.push({string: "statePressed"}); } if (aState.contains(States.EXPANDABLE)) { let statetr = aState.contains(States.EXPANDED) ? "stateExpanded" : "stateCollapsed"; aOutput.push({string: statetr}); @@ -812,20 +800,16 @@ var UtteranceGenerator = { // jshint ig if (aState.contains(States.TRAVERSED)) { aOutput.push({string: "stateTraversed"}); } if (aState.contains(States.HASPOPUP)) { aOutput.push({string: "stateHasPopup"}); } - - if (aState.contains(States.SELECTED)) { - aOutput.push({string: "stateSelected"}); - } }, _getListUtterance: function _getListUtterance(aAccessible, aRoleStr, aFlags, aItemCount) { let utterance = []; this._addRole(utterance, aAccessible, aRoleStr); utterance.push({ string: this._getOutputName("listItemsCount"),
--- a/accessible/jsat/Presentation.jsm +++ b/accessible/jsat/Presentation.jsm @@ -93,35 +93,48 @@ class AndroidPresentor { focused(aObject) { let info = this._infoFromContext( new PivotContext(aObject, null, -1, -1, true, false)); return [{ eventType: AndroidEvents.VIEW_FOCUSED, ...info }]; } /** + * An object's check action has been invoked. + * Note: Checkable objects use TalkBack's text derived from the event state, so we don't + * populate the text here. + * @param {nsIAccessible} aAccessible the object that has been invoked. + */ + checked(aAccessible) { + return [{ + eventType: AndroidEvents.VIEW_CLICKED, + checked: Utils.getState(aAccessible).contains(States.CHECKED) + }]; + } + + /** + * An object's select action has been invoked. + * @param {nsIAccessible} aAccessible the object that has been invoked. + */ + selected(aAccessible) { + return [{ + eventType: AndroidEvents.VIEW_CLICKED, + selected: Utils.getState(aAccessible).contains(States.SELECTED) + }]; + } + + /** * An object's action has been invoked. - * @param {nsIAccessible} aObject the object that has been invoked. + * @param {nsIAccessible} aAccessible the object that has been invoked. * @param {string} aActionName the name of the action. */ - actionInvoked(aObject, aActionName) { - let state = Utils.getState(aObject); - - // Checkable objects use TalkBack's text derived from the event state, - // so we don't populate the text here. - let text = null; - if (!state.contains(States.CHECKABLE)) { - text = Utils.localize(UtteranceGenerator.genForAction(aObject, - aActionName)); - } - + actionInvoked(aAccessible, aActionName) { return [{ eventType: AndroidEvents.VIEW_CLICKED, - text, - checked: state.contains(States.CHECKED) + text: Utils.localize(UtteranceGenerator.genForAction(aAccessible, aActionName)) }]; } /** * Text has changed, either by the user or by the system. TODO. */ textChanged(aAccessible, aIsInserted, aStart, aLength, aText, aModifiedText) { let androidEvent = { @@ -287,16 +300,17 @@ class AndroidPresentor { const info = { bounds: aContext.bounds, focusable: state.contains(States.FOCUSABLE), focused: state.contains(States.FOCUSED), clickable: aContext.accessible.actionCount > 0, checkable: state.contains(States.CHECKABLE), checked: state.contains(States.CHECKED), editable: state.contains(States.EDITABLE), + selected: state.contains(States.SELECTED) }; if (EDIT_TEXT_ROLES.has(aContext.accessible.role)) { let textAcc = aContext.accessible.QueryInterface(Ci.nsIAccessibleText); return { ...info, className: "android.widget.EditText", hint: aContext.accessible.name,
--- a/accessible/jsat/Utils.jsm +++ b/accessible/jsat/Utils.jsm @@ -380,24 +380,16 @@ var Utils = { // jshint ignore:line aExcludeOrdered) { let parent = aStaticText.parent; if (aExcludeOrdered && parent.parent.DOMNode.nodeName === "OL") { return false; } return parent.role === Roles.LISTITEM && parent.childCount > 1 && aStaticText.indexInParent === 0; - }, - - isActivatableOnFingerUp: function isActivatableOnFingerUp(aAccessible) { - if (aAccessible.role === Roles.KEY) { - return true; - } - let quick_activate = this.getAttributes(aAccessible)["moz-quick-activate"]; - return quick_activate && JSON.parse(quick_activate); } }; /** * State object used internally to process accessible's states. * @param {Number} aBase Base state. * @param {Number} aExtended Extended state. */
--- a/accessible/tests/mochitest/aom/test_general.html +++ b/accessible/tests/mochitest/aom/test_general.html @@ -46,16 +46,40 @@ anode[prop] = true; is(anode[prop], true, `anode.${prop} was assigned true`); anode[prop] = false; is(anode[prop], false, `anode.${prop} was assigned false`); anode[prop] = null; is(anode[prop], null, `anode.${prop} was assigned null`); } + function testDoubleProp(anode, prop) { + is(anode[prop], null, `anode.${prop} should be null`); + anode[prop] = Number.MAX_VALUE; + is(anode[prop], Number.MAX_VALUE, `anode.${prop} was assigned ${Number.MAX_VALUE}`); + anode[prop] = null; + is(anode[prop], null, `anode.${prop} was assigned null`); + } + + function testIntProp(anode, prop) { + is(anode[prop], null, `anode.${prop} should be null`); + anode[prop] = -1; + is(anode[prop], -1, `anode.${prop} was assigned -1`); + anode[prop] = null; + is(anode[prop], null, `anode.${prop} was assigned null`); + } + + function testUIntProp(anode, prop) { + is(anode[prop], null, `anode.${prop} should be null`); + anode[prop] = 4294967295; + is(anode[prop], 4294967295, `anode.${prop} was assigned 4294967295`); + anode[prop] = null; + is(anode[prop], null, `anode.${prop} was assigned null`); + } + // Check that the WebIDL is as expected. function checkImplementation(ifrDoc) { let anode = ifrDoc.accessibleNode; ok(anode, "DOM document has accessible node"); is(anode.role, "document", "correct role of a document accessible node"); is(anode.DOMNode, ifrDoc, "correct DOM Node of a document accessible node"); @@ -113,16 +137,34 @@ const boolProps = ["atomic", "busy", "disabled", "expanded", "hidden", "modal", "multiline", "multiselectable", "readOnly", "required", "selected"]; for (const boolProp of boolProps) { testBoolProp(anode, boolProp); } + const doubleProps = ["valueMax", "valueMin", "valueNow"]; + + for (const doubleProp of doubleProps) { + testDoubleProp(anode, doubleProp); + } + + const intProps = ["colCount", "rowCount", "setSize"]; + + for (const intProp of intProps) { + testIntProp(anode, intProp); + } + + const uintProps = ["colIndex", "colSpan", "level", "posInSet", "rowIndex", "rowSpan"]; + + for (const uintProp of uintProps) { + testUIntProp(anode, uintProp); + } + // Check if an AccessibleNode is properly cached. let node = ifrDoc.createElement("div"); anode = node.accessibleNode; is(anode, node.accessibleNode, "an AccessibleNode is properly cached"); // Adopting node to another document doesn't change .accessibleNode let anotherDoc = document.implementation.createDocument("", "", null); let adopted_node = anotherDoc.adoptNode(node);
--- a/accessible/tests/mochitest/jsat/jsatcommon.js +++ b/accessible/tests/mochitest/jsat/jsatcommon.js @@ -363,16 +363,23 @@ class AccessFuContentTestRunner { } eventTextMatches(aEvent, aExpected) { isDeeply(aEvent.text, aExpected, "Event text matches. " + `Got ${JSON.stringify(aEvent.text)}, expected ${JSON.stringify(aExpected)}.`); } + eventInfoMatches(aEvent, aExpected) { + for (let key in aExpected) { + is(aEvent[key], aExpected[key], `Event info matches for ${key}. ` + + `Got ${aEvent[key]}, expected ${aExpected[key]}.`); + } + } + androidScrollForward() { this.sendMessage({ name: "AccessFu:AndroidScroll", data: { origin: "top", direction: "forward" } }); } androidScrollBackward() {
--- a/accessible/tests/mochitest/jsat/test_content_integration.html +++ b/accessible/tests/mochitest/jsat/test_content_integration.html @@ -39,22 +39,22 @@ evt = await runner.moveNext("Simple", AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED); runner.eventTextMatches(evt, ["such app", "wow", "heading level 1"]); runner.isFocused("iframe"); evt = await runner.moveNext("Simple", AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED); - runner.eventTextMatches(evt, ["many option", "not checked", "check button", "First item", "list", "1 item"]); + runner.eventInfoMatches(evt, { checked: false }); + runner.eventTextMatches(evt, ["many option", "check button", "First item", "list", "1 item"]); evt = await runner.activateCurrent(0, - AndroidEvents.VIEW_CLICKED, AndroidEvents.VIEW_CLICKED); - is(evt[1].checked, true, "checkbox is checked"); + is(evt.checked, true, "checkbox is checked"); evt = await runner.moveNext("Simple", AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED); runner.eventTextMatches(evt, ["many option"]); evt = await runner.moveNext("Simple", AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED); runner.eventTextMatches(evt, ["much range", "label"]); @@ -72,35 +72,35 @@ runner.eventTextMatches(evt, ["Home", "button"]); evt = await runner.moveNext("Simple", AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED); runner.eventTextMatches(evt, ["apple", "button"]); evt = await runner.moveNext("Simple", AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED); - runner.eventTextMatches(evt, ["Light", "off", "switch"]); + runner.eventInfoMatches(evt, { checked: false }); + runner.eventTextMatches(evt, ["Light", "switch"]); evt = await runner.activateCurrent(0, - AndroidEvents.VIEW_CLICKED, AndroidEvents.VIEW_CLICKED); - is(evt[1].checked, true, "checkbox is checked"); + is(evt.checked, true, "checkbox is checked"); evt = await runner.moveNext("Simple", AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED); runner.eventTextMatches(evt, ["slider", "0", "slider", "live"]); evt = await runner.movePrevious("Simple", AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED); - runner.eventTextMatches(evt, ["Light", "on", "switch"]); + runner.eventInfoMatches(evt, { checked: true }); + runner.eventTextMatches(evt, ["Light", "switch"]); evt = await runner.activateCurrent(0, - AndroidEvents.VIEW_CLICKED, AndroidEvents.VIEW_CLICKED); - is(evt[1].checked, false, "checkbox is checked"); + is(evt.checked, false, "checkbox is checked"); evt = await runner.movePrevious("Simple", AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED); runner.eventTextMatches(evt, ["apple", "button"]); evt = await runner.movePrevious("Simple", AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED); runner.eventTextMatches(evt, ["Home", "button"]); @@ -122,22 +122,22 @@ runner.eventTextMatches(evt, ["much range", "label"]); evt = await runner.movePrevious("Simple", AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED); runner.eventTextMatches(evt, ["many option", "label", "First item", "list", "1 item"]); evt = await runner.movePrevious("Simple", AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED); - runner.eventTextMatches(evt, ["many option", "checked", "check button"]); + runner.eventInfoMatches(evt, { checked: true }); + runner.eventTextMatches(evt, ["many option", "check button"]); evt = await runner.activateCurrent(0, - AndroidEvents.VIEW_CLICKED, AndroidEvents.VIEW_CLICKED); - is(evt[1].checked, false, "checkbox is checked"); + is(evt.checked, false, "checkbox is checked"); evt = await runner.movePrevious("Simple", AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED); runner.eventTextMatches(evt, ["wow", "heading level 1"]); evt = await runner.movePrevious("Simple", AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED); runner.eventTextMatches(evt, ["Back", "button"]); @@ -175,29 +175,31 @@ runner.eventTextMatches(evt, ["Traversal Rule test document", "Phone status bar"]); evt = await runner.moveNext("Simple", AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED); runner.eventTextMatches(evt, ["Back", "button"]); evt = await runner.moveNext("FormElement", AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED); - runner.eventTextMatches(evt, ["such app", "many option", "not checked", "check button", "First item", "list", "1 item"]); + runner.eventInfoMatches(evt, { checked: false }); + runner.eventTextMatches(evt, ["such app", "many option", "check button", "First item", "list", "1 item"]); evt = await runner.moveNext("FormElement", AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED); runner.eventTextMatches(evt, ["much range", "4", "slider"]); evt = await runner.movePrevious("Simple", AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED); runner.eventTextMatches(evt, ["much range", "label"]); evt = await runner.movePrevious("FormElement", AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED); - runner.eventTextMatches(evt, ["many option", "not checked", "check button", "First item", "list", "1 item"]); + runner.eventInfoMatches(evt, { checked: false }); + runner.eventTextMatches(evt, ["many option", "check button", "First item", "list", "1 item"]); evt = await runner.movePrevious("FormElement", AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED); runner.eventTextMatches(evt, ["Back", "button"]); await runner.clearCursor(); @@ -209,17 +211,18 @@ evt = await runner.moveNext("Simple", AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED); runner.eventTextMatches(evt, ["Back", "button"]); evt = await runner.moveNext("Simple", AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED); runner.eventTextMatches(evt, ["such app", "wow", "heading level 1"]); evt = await runner.moveNext("Simple", AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED); - runner.eventTextMatches(evt, ["many option", "not checked", "check button", "First item", "list", "1 item"]); + runner.eventInfoMatches(evt, { checked: false }); + runner.eventTextMatches(evt, ["many option", "check button", "First item", "list", "1 item"]); evt = await runner.moveFirst("Simple", AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED); todo_is(evt.text[0], "Phone status bar"); await runner.clearCursor(); evt = await runner.moveNext("Simple", @@ -410,17 +413,18 @@ runner.eventTextMatches(evt, ["Traversal Rule test document", "Home", "button"]); evt = await runner.moveNext("Simple", AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED); runner.eventTextMatches(evt, ["banana", "button"]); evt = await runner.moveNext("Simple", AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED); - runner.eventTextMatches(evt, ["Light", "off", "switch"]); + runner.eventInfoMatches(evt, { checked: false }); + runner.eventTextMatches(evt, ["Light", "switch"]); evt = await runner.moveNext("Simple", AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED); runner.eventTextMatches(evt, ["mover", "medium", "slider", "live"]); evt = await runner.moveNext("Simple", AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED); is(evt.exitView, "moveNext", "Reached end of content");
--- a/accessible/tests/mochitest/jsat/test_output.html +++ b/accessible/tests/mochitest/jsat/test_output.html @@ -248,21 +248,20 @@ https://bugzilla.mozilla.org/show_bug.cg expectedUtterance: [[{"string": "stateHasPopup"}, {"string": "buttonmenu"}, "I have a popup"], ["I have a popup", {"string": "stateHasPopup"}, {"string": "buttonmenu"}]], expectedBraille: [[{"string": "buttonmenuAbbr"}, "I have a popup"], ["I have a popup", {"string": "buttonmenuAbbr"}]] }, { // Test selected tab accOrElmOrID: "tab1", - expectedUtterance: [[{"string": "pagetablist"}, - {"string": "stateSelected"}, {"string": "pagetab"}, + expectedUtterance: [[{"string": "pagetablist"}, {"string": "pagetab"}, {"string": "objItemOfN", "args": [1, 2]}, "Account"], ["Account", - {"string": "stateSelected"}, {"string": "pagetab"}, - {"string": "objItemOfN", "args": [1, 2]}, {"string": "pagetablist"}] + {"string": "pagetab"}, {"string": "objItemOfN", "args": [1, 2]}, + {"string": "pagetablist"}] ], expectedBraille: [[{"string": "pagetabAbbr"}, {"string": "objItemOfN", "args": [1, 2]}, "Account"], ["Account", {"string": "pagetabAbbr"}, {"string": "objItemOfN", "args": [1, 2]}]] }, { // Test unselected tab accOrElmOrID: "tab2", @@ -272,60 +271,48 @@ https://bugzilla.mozilla.org/show_bug.cg {"string": "pagetablist"}]], expectedBraille: [[{"string": "pagetabAbbr"}, {"string": "objItemOfN", "args": [2, 2]}, "Advanced"], ["Advanced", {"string": "pagetabAbbr"}, {"string": "objItemOfN", "args": [2, 2]}]] }, { // Landing on this label should mimic landing on the checkbox. accOrElmOrID: "label1", - expectedUtterance: [[{"string": "stateNotChecked"}, - {"string": "checkbutton"}, "Orange"], ["Orange", - {"string": "stateNotChecked"}, {"string": "checkbutton"}]], - expectedBraille: [[{"string": "stateUncheckedAbbr"}, "Orange"], - ["Orange", {"string": "stateUncheckedAbbr"}]] + expectedUtterance: [[{"string": "checkbutton"}, "Orange"], ["Orange", + {"string": "checkbutton"}]], + expectedBraille: [["Orange"], ["Orange"]] }, { // Here we get a top-level view of the form. accOrElmOrID: "form1", - expectedUtterance: [[{"string": "label"}, - {"string": "stateNotChecked"}, {"string": "checkbutton"}, "Orange", - "Orange", {"string": "stateNotChecked"}, {"string": "checkbutton"}, - "Blue", {"string": "label"}, "Blue"], ["Orange", - {"string": "stateNotChecked"}, {"string": "checkbutton"}, "Orange", - {"string": "label"}, "Blue", {"string": "stateNotChecked"}, + expectedUtterance: [[{"string": "label"}, {"string": "checkbutton"}, "Orange", + "Orange", {"string": "checkbutton"}, "Blue", {"string": "label"}, "Blue"], + ["Orange", {"string": "checkbutton"}, "Orange", {"string": "label"}, "Blue", {"string": "checkbutton"}, "Blue", {"string": "label"}]], - expectedBraille: [[{"string": "labelAbbr"}, - {"string": "stateUncheckedAbbr"}, "Orange", "Orange", - {"string": "stateUncheckedAbbr"}, "Blue", {"string": "labelAbbr"}, - "Blue"], ["Orange", {"string": "stateUncheckedAbbr"}, "Orange", - {"string": "labelAbbr"}, "Blue", {"string": "stateUncheckedAbbr"}, - "Blue", {"string": "labelAbbr"}]] + expectedBraille: [[{"string": "labelAbbr"}, "Orange", "Orange", "Blue", + {"string": "labelAbbr"}, "Blue"], ["Orange", "Orange", + {"string": "labelAbbr"}, "Blue", "Blue", {"string": "labelAbbr"}]] }, { // This is a non-nesting label. accOrElmOrID: "label2", expectedUtterance: [[{"string": "label"}, "Blue"], ["Blue", {"string": "label"}]], expectedBraille: [[{"string": "labelAbbr"}, "Blue"], ["Blue", {"string": "labelAbbr"}]] }, { // This is a distinct control. accOrElmOrID: "input2", - expectedUtterance: [[{"string": "stateNotChecked"}, - {"string": "checkbutton"}, "Blue"], ["Blue", - {"string": "stateNotChecked"}, {"string": "checkbutton"}]], - expectedBraille: [[{"string": "stateUncheckedAbbr"}, "Blue"], ["Blue", - {"string": "stateUncheckedAbbr"}]] + expectedUtterance: [[ {"string": "checkbutton"}, "Blue"], + ["Blue", {"string": "checkbutton"}]], + expectedBraille: [["Blue"], ["Blue"]] }, { // This is a nested control. accOrElmOrID: "input1", - expectedUtterance: [[{"string": "stateNotChecked"}, - {"string": "checkbutton"}, "Orange"], ["Orange", - {"string": "stateNotChecked"}, {"string": "checkbutton"}]], - expectedBraille: [[{"string": "stateUncheckedAbbr"}, "Orange"], - ["Orange", {"string": "stateUncheckedAbbr"}]] + expectedUtterance: [[ {"string": "checkbutton"}, "Orange"], ["Orange", + {"string": "checkbutton"}]], + expectedBraille: [["Orange"], ["Orange"]] }, { // Landing on this label should mimic landing on the entry. accOrElmOrID: "label3", expectedUtterance: [[{"string": "entry"}, "Joe", "First name:"], ["First name:", "Joe", {"string": "entry"}]], expectedBraille: [[{"string": "entryAbbr"}, "Joe", "First name:"], ["First name:", "Joe", {"string": "entryAbbr"}]] }, { @@ -345,40 +332,30 @@ https://bugzilla.mozilla.org/show_bug.cg }, { accOrElmOrID: "password", expectedUtterance: [[{"string": "passwordtext"}, "Secret Password"], ["Secret Password", {"string": "passwordtext"}]], expectedBraille: [[{"string": "passwordtextAbbr"}, "Secret Password"], ["Secret Password", {"string": "passwordtextAbbr"}]] }, { accOrElmOrID: "input5", - expectedUtterance: [[{"string": "stateChecked"}, - {"string": "checkbutton"}, "Boring label"], ["Boring label", - {"string": "stateChecked"}, {"string": "checkbutton"}]], - expectedBraille: [[{"string": "stateCheckedAbbr"}, "Boring label"], - ["Boring label", {"string": "stateCheckedAbbr"}]] + expectedUtterance: [[{"string": "checkbutton"}, "Boring label"], + ["Boring label", {"string": "checkbutton"}]], + expectedBraille: [["Boring label"], ["Boring label"]] }, { accOrElmOrID: "radio_unselected", - expectedUtterance: [[{"string": "stateNotChecked"}, - {"string": "radiobutton"}, "any old radio button"], - ["any old radio button", {"string": "stateNotChecked"}, - {"string": "radiobutton"}] + expectedUtterance: [[{"string": "radiobutton"}, "any old radio button"], + ["any old radio button", {"string": "radiobutton"}] ], - expectedBraille: [ - [{"string": "stateUncheckedAbbr"}, "any old radio button"], - ["any old radio button", {"string": "stateUncheckedAbbr"}]] + expectedBraille: [["any old radio button"], ["any old radio button"]] }, { accOrElmOrID: "radio_selected", - expectedUtterance: [[{"string": "stateChecked"}, - {"string": "radiobutton"}, "a unique radio button"], - ["a unique radio button", {"string": "stateChecked"}, - {"string": "radiobutton"}]], - expectedBraille: [ - [{"string": "stateCheckedAbbr"}, "a unique radio button"], - ["a unique radio button", {"string": "stateCheckedAbbr"}]] + expectedUtterance: [[{"string": "radiobutton"}, "a unique radio button"], + ["a unique radio button", {"string": "radiobutton"}]], + expectedBraille: [["a unique radio button"], ["a unique radio button"]] }, { accOrElmOrID: "togglebutton_notpressed", expectedUtterance: [[{"string": "togglebutton"}, "I am not pressed"], ["I am not pressed", {"string": "togglebutton"}]], expectedBraille: [ [{"string": "stateUnpressedAbbr"}, "I am not pressed"], ["I am not pressed", {"string": "stateUnpressedAbbr"}]] }, { @@ -432,33 +409,31 @@ https://bugzilla.mozilla.org/show_bug.cg }, { accOrElmOrID: "gridcell2", oldAccOrElmOrID: "grid", expectedUtterance: [["4", "7"], ["4", "7"]], expectedBraille: [["4", "7"], ["4", "7"]] }, { accOrElmOrID: "gridcell3", oldAccOrElmOrID: "grid", - expectedUtterance: [[{"string": "stateSelected"}, "5"], - ["5", {"string": "stateSelected"}]], + expectedUtterance: [["5"], ["5"]], expectedBraille: [["5"], ["5"]], }, { accOrElmOrID: "frequency", expectedUtterance: [[{"string": "stateCollapsed"}, {"string": "stateHasPopup"}, {"string": "combobox"}, "15 min"], [ "15 min", {"string": "stateCollapsed"}, {"string": "stateHasPopup"}, {"string": "combobox"}]], expectedBraille: [[{"string": "comboboxAbbr"}, "15 min"], ["15 min", {"string": "comboboxAbbr"}]] }, { accOrElmOrID: "selected-combobox-option", oldAccOrElmOrID: "frequency", - expectedUtterance: [[{"string": "stateSelected"}, - {"string": "comboboxoption"}, "15 min"], ["15 min", - {"string": "stateSelected"}, {"string": "comboboxoption"}]], + expectedUtterance: [[{"string": "comboboxoption"}, "15 min"], + ["15 min", {"string": "comboboxoption"}]], expectedBraille: [[{"string": "comboboxoptionAbbr"}, "15 min"], [ "15 min", {"string": "comboboxoptionAbbr"}]] }, { accOrElmOrID: "combobox-option", oldAccOrElmOrID: "frequency", expectedUtterance: [[{"string": "comboboxoption"}, "30 min"], [ "30 min", {"string": "comboboxoption"}]], expectedBraille: [[{"string": "comboboxoptionAbbr"}, "30 min"], [ @@ -479,29 +454,24 @@ https://bugzilla.mozilla.org/show_bug.cg ["Last sync:", "2 days ago"]] }, { accOrElmOrID: "statusbar-2", expectedUtterance: [["Last sync: 30min ago"], ["Last sync: 30min ago"]], expectedBraille: [["Last sync: 30min ago"], ["Last sync: 30min ago"]] }, { accOrElmOrID: "switch-1", - expectedUtterance: [[{"string": "stateOn"}, {"string": "switch"}, - "Simple switch"], ["Simple switch", {"string": "stateOn"}, - {"string": "switch"}]], - expectedBraille: [[{"string": "stateCheckedAbbr"}, "Simple switch"], - ["Simple switch", {"string": "stateCheckedAbbr"}]] + expectedUtterance: [[{"string": "switch"}, "Simple switch"], + ["Simple switch", {"string": "switch"}]], + expectedBraille: [["Simple switch"], ["Simple switch"]] }, { accOrElmOrID: "switch-2", - expectedUtterance: [[{"string": "stateOff"}, - {"string": "switch"}, "Another switch"], ["Another switch", - {"string": "stateOff"}, {"string": "switch"}]], - expectedBraille: [ - [{"string": "stateUncheckedAbbr"}, "Another switch"], - ["Another switch", {"string": "stateUncheckedAbbr"}]] + expectedUtterance: [[{"string": "switch"}, "Another switch"], + ["Another switch", {"string": "switch"}]], + expectedBraille: [["Another switch"], ["Another switch"]] }]; // Test all possible utterance order preference values. function testOutputOrder(aOutputOrder) { return function() { SpecialPowers.pushPrefEnv({ "set": [[PREF_UTTERANCE_ORDER, aOutputOrder]] }, function() {
--- a/browser/app/winlauncher/LauncherProcessWin.cpp +++ b/browser/app/winlauncher/LauncherProcessWin.cpp @@ -76,42 +76,16 @@ ShowError(DWORD aError = ::GetLastError( if (!result) { return; } ::MessageBoxW(nullptr, rawMsgBuf, L"Firefox", MB_OK | MB_ICONERROR); ::LocalFree(rawMsgBuf); } -static bool -SetArgv0ToFullBinaryPath(wchar_t* aArgv[]) -{ - DWORD bufLen = MAX_PATH; - mozilla::UniquePtr<wchar_t[]> buf; - - while (true) { - buf = mozilla::MakeUnique<wchar_t[]>(bufLen); - DWORD retLen = ::GetModuleFileNameW(nullptr, buf.get(), bufLen); - if (!retLen) { - return false; - } - - if (retLen == bufLen && ::GetLastError() == ERROR_INSUFFICIENT_BUFFER) { - bufLen *= 2; - continue; - } - - break; - } - - // We intentionally leak buf into argv[0] - aArgv[0] = buf.release(); - return true; -} - namespace mozilla { // Eventually we want to be able to set a build config flag such that, when set, // this function will always return true. bool RunAsLauncherProcess(int& argc, wchar_t** argv) { return CheckArg(argc, argv, L"launcher",
--- a/browser/base/content/test/static/browser_all_files_referenced.js +++ b/browser/base/content/test/static/browser_all_files_referenced.js @@ -127,17 +127,16 @@ var whitelist = [ {file: "chrome://global/skin/tree/sort-asc-classic.png", platforms: ["linux"]}, {file: "chrome://global/skin/tree/sort-asc.png", platforms: ["linux"]}, {file: "chrome://global/skin/tree/sort-dsc-classic.png", platforms: ["linux"]}, {file: "chrome://global/skin/tree/sort-dsc.png", platforms: ["linux"]}, // Bug 1344267 {file: "chrome://marionette/content/test_anonymous_content.xul"}, {file: "chrome://marionette/content/test_dialog.properties"}, {file: "chrome://marionette/content/test_dialog.xul"}, - {file: "chrome://marionette/content/PerTestCoverageUtils.jsm"}, // Bug 1348533 {file: "chrome://mozapps/skin/downloads/buttons.png", platforms: ["macosx"]}, {file: "chrome://mozapps/skin/downloads/downloadButtons.png", platforms: ["linux", "win"]}, // Bug 1348558 {file: "chrome://mozapps/skin/update/downloadButtons.png", platforms: ["linux"]}, // Bug 1348559 {file: "chrome://pippki/content/resetpassword.xul"}, @@ -198,16 +197,20 @@ if (!isDevtools) { for (let module of ["addons.js", "bookmarks.js", "forms.js", "history.js", "passwords.js", "prefs.js", "tabs.js", "extension-storage.js"]) { whitelist.add("resource://services-sync/engines/" + module); } } +if (AppConstants.MOZ_CODE_COVERAGE) { + whitelist.add("chrome://marionette/content/PerTestCoverageUtils.jsm"); +} + const gInterestingCategories = new Set([ "agent-style-sheets", "addon-provider-module", "webextension-modules", "webextension-scripts", "webextension-schemas", "webextension-scripts-addon", "webextension-scripts-content", "webextension-scripts-devtools" ]); var gChromeReg = Cc["@mozilla.org/chrome/chrome-registry;1"] .getService(Ci.nsIChromeRegistry);
--- a/browser/base/content/test/static/browser_parsable_css.js +++ b/browser/base/content/test/static/browser_parsable_css.js @@ -62,16 +62,25 @@ let whitelist = [ errorMessage: /Property contained reference to invalid variable.*background/i, isFromDevTools: true}, {sourceName: /devtools\/skin\/animationinspector\.css$/i, intermittent: true, errorMessage: /Property contained reference to invalid variable.*color/i, isFromDevTools: true}, ]; +if (!Services.prefs.getBoolPref("layout.css.xul-box-display-values.content.enabled")) { + // These are UA sheets which use non-content-exposed `display` values. + whitelist.push({ + sourceName: /(skin\/shared\/Heartbeat|((?:res|gre-resources)\/(ua|html)))\.css$/i, + errorMessage: /Error in parsing value for .*\bdisplay\b/i, + isFromDevTools: false + }); +} + if (!Services.prefs.getBoolPref("full-screen-api.unprefix.enabled")) { whitelist.push({ sourceName: /(?:res|gre-resources)\/(ua|html)\.css$/i, errorMessage: /Unknown pseudo-class .*\bfullscreen\b/i, isFromDevTools: false }, { // PDFjs is futureproofing its pseudoselectors, and those rules are dropped. sourceName: /web\/viewer\.css$/i,
--- a/browser/components/preferences/languages.xul +++ b/browser/components/preferences/languages.xul @@ -44,17 +44,17 @@ onsynctopreference="return gLanguagesDialog.writeSpoofEnglish();"/> <grid flex="1"> <columns> <column flex="1"/> <column/> </columns> <rows> <row flex="1"> - <richlistbox id="activeLanguages" flex="1" height="200" + <richlistbox id="activeLanguages" flex="1" seltype="multiple" onselect="gLanguagesDialog.onLanguageSelect();"/> <vbox> <button id="up" class="up" oncommand="gLanguagesDialog.moveUp();" disabled="true" data-l10n-id="languages-customize-moveup" preference="pref.browser.language.disable_button.up"/> <button id="down" class="down" oncommand="gLanguagesDialog.moveDown();" disabled="true" data-l10n-id="languages-customize-movedown"
--- a/browser/themes/shared/incontentprefs/preferences.inc.css +++ b/browser/themes/shared/incontentprefs/preferences.inc.css @@ -204,16 +204,20 @@ button > hbox > label { width: 30px; margin-inline-start: 5px; } #getStarted { font-size: 90%; } +#activeLanguages { + height: 16em; +} + #activeLanguages > richlistitem { padding: 0.3em; } #downloadFolder { margin-inline-start: 0; padding-inline-start: 30px; background-repeat: no-repeat;
--- a/dom/media/MediaData.h +++ b/dom/media/MediaData.h @@ -657,17 +657,17 @@ public: private: friend class MediaRawData; explicit MediaRawDataWriter(MediaRawData* aMediaRawData); MOZ_MUST_USE bool EnsureSize(size_t aSize); MediaRawData* mTarget; }; -class MediaRawData : public MediaData +class MediaRawData final : public MediaData { public: MediaRawData(); MediaRawData(const uint8_t* aData, size_t aSize); MediaRawData(const uint8_t* aData, size_t aSize, const uint8_t* aAlphaData, size_t aAlphaSize); // Pointer to data or null if not-yet allocated @@ -695,21 +695,21 @@ public: // Indicate to the audio decoder that mDiscardPadding frames should be // trimmed. uint32_t mDiscardPadding = 0; RefPtr<TrackInfoSharedPtr> mTrackInfo; // Return a deep copy or nullptr if out of memory. - virtual already_AddRefed<MediaRawData> Clone() const; + already_AddRefed<MediaRawData> Clone() const; // Create a MediaRawDataWriter for this MediaRawData. The writer is not // thread-safe. - virtual UniquePtr<MediaRawDataWriter> CreateWriter(); - virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const; + UniquePtr<MediaRawDataWriter> CreateWriter(); + size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const; protected: ~MediaRawData(); private: friend class MediaRawDataWriter; AlignedByteBuffer mBuffer; AlignedByteBuffer mAlphaBuffer;
--- a/dom/media/VideoUtils.cpp +++ b/dom/media/VideoUtils.cpp @@ -710,16 +710,22 @@ IsVP9CodecString(const nsAString& aCodec uint8_t level = 0; uint8_t bitDepth = 0; return aCodec.EqualsLiteral("vp9") || aCodec.EqualsLiteral("vp9.0") || (StartsWith(NS_ConvertUTF16toUTF8(aCodec), "vp09") && ExtractVPXCodecDetails(aCodec, profile, level, bitDepth)); } +bool +IsAV1CodecString(const nsAString& aCodec) +{ + return aCodec.EqualsLiteral("av1"); // AV1 +} + UniquePtr<TrackInfo> CreateTrackInfoWithMIMEType(const nsACString& aCodecMIMEType) { UniquePtr<TrackInfo> trackInfo; if (StartsWith(aCodecMIMEType, "audio/")) { trackInfo.reset(new AudioInfo()); trackInfo->mMimeType = aCodecMIMEType; } else if (StartsWith(aCodecMIMEType, "video/")) {
--- a/dom/media/VideoUtils.h +++ b/dom/media/VideoUtils.h @@ -356,16 +356,19 @@ bool IsAACCodecString(const nsAString& aCodec); bool IsVP8CodecString(const nsAString& aCodec); bool IsVP9CodecString(const nsAString& aCodec); +bool +IsAV1CodecString(const nsAString& aCodec); + // Try and create a TrackInfo with a given codec MIME type. UniquePtr<TrackInfo> CreateTrackInfoWithMIMEType(const nsACString& aCodecMIMEType); // Try and create a TrackInfo with a given codec MIME type, and optional extra // parameters from a container type (its MIME type and codecs are ignored). UniquePtr<TrackInfo> CreateTrackInfoWithMIMETypeAndContainerTypeExtraParameters(
--- a/dom/media/mediasource/MediaSource.cpp +++ b/dom/media/mediasource/MediaSource.cpp @@ -1,19 +1,16 @@ /* -*- 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 "MediaSource.h" -#if MOZ_AV1 -#include "AOMDecoder.h" -#endif #include "AsyncEventRunner.h" #include "DecoderTraits.h" #include "Benchmark.h" #include "DecoderDoctorDiagnostics.h" #include "MediaContainerType.h" #include "MediaResult.h" #include "MediaSourceDemuxer.h" #include "MediaSourceUtils.h" @@ -130,19 +127,19 @@ MediaSource::IsTypeSupported(const nsASt return NS_OK; } if (mimeType == MEDIAMIMETYPE("video/webm")) { if (!(Preferences::GetBool("media.mediasource.webm.enabled", false) || StaticPrefs::MediaCapabilitiesEnabled() || containerType->ExtendedType().Codecs().Contains( NS_LITERAL_STRING("vp8")) || #ifdef MOZ_AV1 - // FIXME: Temporary comparison with the full codecs attribute. - // See bug 1377015. - AOMDecoder::IsSupportedCodec(containerType->ExtendedType().Codecs().AsString()) || + (StaticPrefs::MediaAv1Enabled() && + IsAV1CodecString( + containerType->ExtendedType().Codecs().AsString())) || #endif IsWebMForced(aDiagnostics))) { return NS_ERROR_DOM_NOT_SUPPORTED_ERR; } return NS_OK; } if (mimeType == MEDIAMIMETYPE("audio/webm")) { if (!(Preferences::GetBool("media.mediasource.webm.enabled", false) ||
--- a/dom/media/platforms/agnostic/AOMDecoder.cpp +++ b/dom/media/platforms/agnostic/AOMDecoder.cpp @@ -337,23 +337,16 @@ AOMDecoder::Drain() bool AOMDecoder::IsAV1(const nsACString& aMimeType) { return aMimeType.EqualsLiteral("video/av1"); } /* static */ bool -AOMDecoder::IsSupportedCodec(const nsAString& aCodecType) -{ - return aCodecType.EqualsLiteral("av1"); -} - -/* static */ -bool AOMDecoder::IsKeyframe(Span<const uint8_t> aBuffer) { aom_codec_stream_info_t info; PodZero(&info); auto res = aom_codec_peek_stream_info(aom_codec_av1_dx(), aBuffer.Elements(), aBuffer.Length(), &info);
--- a/dom/media/platforms/agnostic/AOMDecoder.h +++ b/dom/media/platforms/agnostic/AOMDecoder.h @@ -32,19 +32,16 @@ public: { return NS_LITERAL_CSTRING("av1 libaom video decoder"); } // Return true if aMimeType is a one of the strings used // by our demuxers to identify AV1 streams. static bool IsAV1(const nsACString& aMimeType); - // Return true if aCodecType is a supported codec description. - static bool IsSupportedCodec(const nsAString& aCodecType); - // Return true if a sample is a keyframe. static bool IsKeyframe(Span<const uint8_t> aBuffer); // Return the frame dimensions for a sample. static gfx::IntSize GetFrameSize(Span<const uint8_t> aBuffer); private: ~AOMDecoder();
--- a/dom/media/test/can_play_type_webm.js +++ b/dom/media/test/can_play_type_webm.js @@ -1,11 +1,11 @@ -function check_webm(v, enabled) { +async function check_webm(v, enabled) { function check(type, expected) { - is(v.canPlayType(type), enabled ? expected : "", type); + is(v.canPlayType(type), enabled ? expected : "", type + "='" + expected + "'"); } // WebM types check("video/webm", "maybe"); check("audio/webm", "maybe"); var video = ['vp8', 'vp8.0', 'vp9', 'vp9.0']; var audio = ['vorbis', 'opus']; @@ -21,9 +21,36 @@ function check_webm(v, enabled) { check("video/webm; codecs=\"" + acodec + ", " + vcodec + "\"", "probably"); }); }); // Unsupported WebM codecs check("video/webm; codecs=xyz", ""); check("video/webm; codecs=xyz,vorbis", ""); check("video/webm; codecs=vorbis,xyz", ""); + + function getPref(name) { + var pref = false; + try { + pref = SpecialPowers.getBoolPref(name); + } catch(ex) { } + return pref; + } + + function isWindows32() { + return navigator.userAgent.includes("Windows") && + !navigator.userAgent.includes("Win64"); + } + + function isAndroid() { + return navigator.userAgent.includes("Android"); + } + + const haveAv1 = getPref("media.av1.enabled"); + check("video/webm; codecs=\"av1\"", haveAv1 ? "probably" : ""); + + await SpecialPowers.pushPrefEnv({"set": [["media.av1.enabled", true]]}); + // AV1 is disabled on Windows 32 bits (bug 1475564) and Android (bug 1368843) + check("video/webm; codecs=\"av1\"", (isWindows32() || isAndroid()) ? "" : "probably"); + + await SpecialPowers.pushPrefEnv({"set": [["media.av1.enabled", false]]}); + check("video/webm; codecs=\"av1\"", ""); }
--- a/dom/media/test/test_can_play_type_mpeg.html +++ b/dom/media/test/test_can_play_type_mpeg.html @@ -91,16 +91,19 @@ function check_mp4(v, enabled) { [ "video/mp4; codecs=vp9", "video/mp4; codecs=\"vp9\"", "video/mp4; codecs=\"vp9.0\"" ].forEach((codec) => { // canPlayType should support VP9 in MP4... check(codec, "probably"); ok(MediaSource.isTypeSupported(codec), "VP9 in MP4 should be supported in MSE"); }); + + // AV1 (disabled until bug 1417050 is fixed) + check("video/mp4; codecs=\"av1\"", ""); } function check_mp3(v, enabled) { function check(type, expected) { var ex = enabled ? expected : ""; is(v.canPlayType(type), ex, type + "='" + ex + "'"); }
--- a/dom/media/test/test_can_play_type_webm.html +++ b/dom/media/test/test_can_play_type_webm.html @@ -16,14 +16,24 @@ a Bug 566245</a> <div id="content" style="display: none"> </div> <video id="v"></video> <pre id="test"> <script src="can_play_type_webm.js"></script> <script> -check_webm(document.getElementById('v'), true); -mediaTestCleanup(); + async function runTest() { + try { + await check_webm(document.getElementById('v'), true); + mediaTestCleanup(); + } catch (e) { + info("Exception " + e.message); + ok(false, "Threw exception " + e.message); + } + SimpleTest.finish(); + } + SimpleTest.waitForExplicitFinish(); + addLoadEvent(runTest); </script> </pre> </body> </html>
--- a/dom/media/webm/WebMDecoder.cpp +++ b/dom/media/webm/WebMDecoder.cpp @@ -60,17 +60,17 @@ WebMDecoder::GetTracksInfo(const MediaCo if (ExtractVPXCodecDetails(codec, profile, level, bitDepth)) { trackInfo->GetAsVideoInfo()->mBitDepth = bitDepth; } tracks.AppendElement(std::move(trackInfo)); continue; } } #ifdef MOZ_AV1 - if (AOMDecoder::IsSupportedCodec(codec)) { + if (StaticPrefs::MediaAv1Enabled() && IsAV1CodecString(codec)) { tracks.AppendElement( CreateTrackInfoWithMIMETypeAndContainerTypeExtraParameters( NS_LITERAL_CSTRING("video/av1"), aType)); continue; } #endif // Unknown codec aError =
deleted file mode 100644 --- a/dom/security/test/csp/file_child_worker.js +++ /dev/null @@ -1,39 +0,0 @@ -function doXHR(uri) { - try { - var xhr = new XMLHttpRequest(); - xhr.open("GET", uri); - xhr.send(); - } catch(ex) {} -} - -var sameBase = "http://mochi.test:8888/tests/dom/security/test/csp/file_CSP.sjs?testid="; -var crossBase = "http://example.com/tests/dom/security/test/csp/file_CSP.sjs?testid="; - -onmessage = (e) => { - for (base of [sameBase, crossBase]) { - var prefix; - var suffix; - if (e.data.inherited == "parent") { - //Worker inherits CSP from parent worker - prefix = base + "worker_child_inherited_parent_"; - suffix = base == sameBase ? "_good" : "_bad"; - } else if (e.data.inherited == "document") { - //Worker inherits CSP from owner document -> parent worker -> subworker - prefix = base + "worker_child_inherited_document_"; - suffix = base == sameBase ? "_good" : "_bad"; - } else { - // Worker delivers CSP from HTTP header - prefix = base + "worker_child_"; - suffix = base == sameBase ? "_same_bad" : "_cross_bad"; - } - - doXHR(prefix + "xhr" + suffix); - // Fetch is likely failed in subworker - // See Bug 1273070 - Failed to fetch in subworker - // Enable fetch test after the bug is fixed - // fetch(prefix + "xhr" + suffix); - try { - importScripts(prefix + "script" + suffix); - } catch(ex) {} - } -}
deleted file mode 100644 --- a/dom/security/test/csp/file_child_worker.js^headers^ +++ /dev/null @@ -1,1 +0,0 @@ -Content-Security-Policy: default-src 'none'
--- a/dom/security/test/csp/file_main.js +++ b/dom/security/test/csp/file_main.js @@ -1,51 +1,14 @@ -function doXHR(uri, callback) { +function doXHR(uri) { try { var xhr = new XMLHttpRequest(); xhr.open("GET", uri); - xhr.responseType = "blob"; xhr.send(); - xhr.onload = function () { - if (callback) callback(xhr.response); - } } catch(ex) {} } doXHR("http://mochi.test:8888/tests/dom/security/test/csp/file_CSP.sjs?testid=xhr_good"); doXHR("http://example.com/tests/dom/security/test/csp/file_CSP.sjs?testid=xhr_bad"); fetch("http://mochi.test:8888/tests/dom/security/test/csp/file_CSP.sjs?testid=fetch_good"); fetch("http://example.com/tests/dom/security/test/csp/file_CSP.sjs?testid=fetch_bad"); navigator.sendBeacon("http://mochi.test:8888/tests/dom/security/test/csp/file_CSP.sjs?testid=beacon_good"); navigator.sendBeacon("http://example.com/tests/dom/security/test/csp/file_CSP.sjs?testid=beacon_bad"); - -var topWorkerBlob; -var nestedWorkerBlob; - -doXHR("file_main_worker.js", function (topResponse) { - topWorkerBlob = URL.createObjectURL(topResponse); - doXHR("file_child_worker.js", function (response) { - nestedWorkerBlob = URL.createObjectURL(response); - runWorker(); - }); -}); - -function runWorker() { - // Top level worker, no subworker - // Worker does not inherit CSP from owner document - new Worker("file_main_worker.js").postMessage({inherited : "none"}); - - // Top level worker, no subworker - // Worker inherits CSP from owner document - new Worker(topWorkerBlob).postMessage({inherited : "document"}); - - // Subworker - // Worker does not inherit CSP from parent worker - new Worker("file_main_worker.js").postMessage({inherited : "none", nested : nestedWorkerBlob}); - - // Subworker - // Worker inherits CSP from parent worker - new Worker("file_main_worker.js").postMessage({inherited : "parent", nested : nestedWorkerBlob}); - - // Subworker - // Worker inherits CSP from owner document -> parent worker -> subworker - new Worker(topWorkerBlob).postMessage({inherited : "document", nested : nestedWorkerBlob}); -}
deleted file mode 100644 --- a/dom/security/test/csp/file_main_worker.js +++ /dev/null @@ -1,48 +0,0 @@ -function doXHR(uri) { - try { - var xhr = new XMLHttpRequest(); - xhr.open("GET", uri); - xhr.send(); - } catch(ex) {} -} - -var sameBase = "http://mochi.test:8888/tests/dom/security/test/csp/file_CSP.sjs?testid="; -var crossBase = "http://example.com/tests/dom/security/test/csp/file_CSP.sjs?testid="; - -onmessage = (e) => { - // Tests of nested worker - if (e.data.nested) { - if (e.data.inherited != "none") { - // Worker inherits CSP - new Worker(e.data.nested).postMessage({inherited : e.data.inherited}); - } - else { - // Worker does not inherit CSP - new Worker("file_child_worker.js").postMessage({inherited : e.data.inherited}); - } - return; - } - - //Tests of top level worker - for (base of [sameBase, crossBase]) { - var prefix; - var suffix; - if (e.data.inherited != "none") { - // Top worker inherits CSP from owner document - prefix = base + "worker_inherited_"; - suffix = base == sameBase ? "_good" : "_bad"; - } - else { - // Top worker delivers CSP from HTTP header - prefix = base + "worker_"; - suffix = base == sameBase ? "_same_bad" : "_cross_good"; - } - - doXHR(prefix + "xhr" + suffix); - fetch(prefix + "fetch" + suffix); - try { - if (e.data.inherited == "none") suffix = base == sameBase ? "_same_good" : "_cross_bad"; - importScripts(prefix + "script" + suffix); - } catch(ex) {} - } -}
deleted file mode 100644 --- a/dom/security/test/csp/file_main_worker.js^headers^ +++ /dev/null @@ -1,1 +0,0 @@ -Content-Security-Policy: default-src 'self' blob: ; connect-src http://example.com
new file mode 100644 --- /dev/null +++ b/dom/security/test/csp/main_csp_worker.html @@ -0,0 +1,439 @@ +<!DOCTYPE HTML> +<html> + <head> + <title>Bug 1475849: Test CSP worker inheritance</title> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="worker_helper.js"></script> + + </head> + <body> + <script type="application/javascript"> + const SJS = "worker.sjs"; + const SAME_BASE = "http://mochi.test:8888/tests/dom/security/test/csp/file_CSP.sjs"; + const CROSS_BASE = "http://example.com/tests/dom/security/test/csp/file_CSP.sjs"; + + SimpleTest.waitForExplicitFinish(); + /* test data format : + { + id: test id, short description of test, + base: URL of the request in worker, + action: type of request in worker (fetch, xhr, importscript) + type: how do we create the worker, from URL or Blob, + csp: csp of worker, + child: how do we create the child worker, from URL or Blob, + childCsp: csp of child worker + expectedBlock: result when CSP policy, true or false + } + */ + + // Document's CSP is defined in main_csp_worker.html^headers^ + // Content-Security-Policy: default-src 'self' blob: 'unsafe-inline' + var tests = [ + // create new Worker(url), worker's csp should be deliveried from header. + // csp should be: default-src 'self' blob: ; connect-src CROSS_BASE + { + id: "worker_url_fetch_same_bad", + base: SAME_BASE, + action: "fetch", + type: "url", + csp: "default-src 'self' blob: ; connect-src http://example.com", + expectBlocked: true + }, + { + id: "worker_url_importScripts_same_good", + base: SAME_BASE, + action: "importScripts", + type: "url", + csp: "default-src 'self' blob: ; connect-src http://example.com", + expectBlocked: false + }, + { + id: "worker_url_xhr_same_bad", + base: SAME_BASE, + action: "xhr", + type: "url", + csp: "default-src 'self' blob: ; connect-src http://example.com", + expectBlocked: true + }, + { + id: "worker_url_fetch_cross_good", + base: CROSS_BASE, + action: "fetch", + type: "url", + csp: "default-src 'self' blob: ; connect-src http://example.com", + expectBlocked: false + }, + { + id: "worker_url_importScripts_cross_bad", + base: CROSS_BASE, + action: "importScripts", + type: "url", + csp: "default-src 'self' blob: ; connect-src http://example.com", + expectBlocked: true + }, + { + id: "worker_url_xhr_cross_good", + base: CROSS_BASE, + action: "xhr", + type: "url", + csp: "default-src 'self' blob: ; connect-src http://example.com", + expectBlocked: false + }, + + // create new Worker(blob:), worker's csp should be inherited from + // document. + // csp should be : default-src 'self' blob: 'unsafe-inline' + { + id: "worker_blob_fetch_same_good", + base: SAME_BASE, + action: "fetch", + type: "blob", + csp: "default-src 'self' blob: ; connect-src http://example.com", + expectBlocked: false + }, + { + id: "worker_blob_xhr_same_good", + base: SAME_BASE, + action: "xhr", + type: "blob", + csp: "default-src 'self' blob: ; connect-src http://example.com", + expectBlocked: false + }, + { + id: "worker_blob_importScripts_same_good", + base: SAME_BASE, + action: "importScripts", + type: "blob", + csp: "default-src 'self' blob: ; connect-src http://example.com", + expectBlocked: false + }, + { + id: "worker_blob_fetch_cross_bad", + base: CROSS_BASE, + action: "fetch", + type: "blob", + csp: "default-src 'self' blob: ; connect-src http://example.com", + expectBlocked: true + }, + { + id: "worker_blob_xhr_cross_bad", + base: CROSS_BASE, + action: "xhr", + type: "blob", + csp: "default-src 'self' blob: ; connect-src http://example.com", + expectBlocked: true + }, + { + id: "worker_blob_importScripts_cross_bad", + base: CROSS_BASE, + action: "importScripts", + type: "blob", + csp: "default-src 'self' blob: ; connect-src http://example.com", + expectBlocked: true + }, + + // create parent worker from url, child worker from blob, + // Parent delivery csp then propagate to child + // csp should be: "default-src 'self' blob: ; connect-src 'self' http://example.com", + { + id: "worker_url_child_blob_fetch_same_good", + base: SAME_BASE, + action: "fetch", + child: "blob", + childCsp: "default-src 'none'", + type: "url", + csp: "default-src 'self' blob: ; connect-src 'self' http://example.com", + expectBlocked: false + }, + { + id: "worker_url_child_blob_importScripts_same_good", + base: SAME_BASE, + action: "importScripts", + child: "blob", + childCsp: "default-src 'none'", + type: "url", + csp: "default-src 'self' blob: ; connect-src 'self' http://example.com", + expectBlocked: false + }, + { + id: "worker_url_child_blob_xhr_same_good", + base: SAME_BASE, + child: "blob", + childCsp: "default-src 'none'", + action: "xhr", + type: "url", + csp: "default-src 'self' blob: ; connect-src 'self' http://example.com", + expectBlocked: false + }, + { + id: "worker_url_child_blob_fetch_cross_good", + base: CROSS_BASE, + action: "fetch", + child: "blob", + childCsp: "default-src 'none'", + type: "url", + csp: "default-src 'self' blob: ; connect-src 'self' http://example.com", + expectBlocked: false + }, + { + id: "worker_url_child_blob_importScripts_cross_bad", + base: CROSS_BASE, + action: "importScripts", + child: "blob", + childCsp: "default-src 'none'", + type: "url", + csp: "default-src 'self' blob: ; connect-src 'self' http://example.com", + expectBlocked: true + }, + { + id: "worker_url_child_blob_xhr_cross_godd", + base: CROSS_BASE, + child: "blob", + childCsp: "default-src 'none'", + action: "xhr", + type: "url", + csp: "default-src 'self' blob: ; connect-src 'self' http://example.com", + expectBlocked: false + }, + + + // create parent worker from blob, child worker from blob, + // Csp: document->parent->child + // csp should be : default-src 'self' blob: 'unsafe-inline' + { + id: "worker_blob_child_blob_fetch_same_good", + base: SAME_BASE, + child: "blob", + childCsp: "default-src 'none'", + action: "fetch", + type: "blob", + csp: "default-src 'self' blob:", + expectBlocked: false + }, + { + id: "worker_blob_child_blob_xhr_same_good", + base: SAME_BASE, + child: "blob", + childCsp: "default-src 'none'", + action: "xhr", + type: "blob", + csp: "default-src 'self' blob:", + expectBlocked: false + }, + { + id: "worker_blob_child_blob_importScripts_same_good", + base: SAME_BASE, + action: "importScripts", + child: "blob", + childCsp: "default-src 'none'", + type: "blob", + csp: "default-src 'self' blob:", + expectBlocked: false + }, + { + id: "worker_blob_child_blob_fetch_cross_bad", + base: CROSS_BASE, + child: "blob", + childCsp: "default-src 'none'", + action: "fetch", + type: "blob", + csp: "default-src 'self' blob:", + expectBlocked: true + }, + { + id: "worker_blob_child_blob_xhr_cross_bad", + base: CROSS_BASE, + child: "blob", + childCsp: "default-src 'none'", + action: "xhr", + type: "blob", + csp: "default-src 'self' blob:", + expectBlocked: true + }, + { + id: "worker_blob_child_blob_importScripts_cross_bad", + base: CROSS_BASE, + action: "importScripts", + child: "blob", + childCsp: "default-src 'none'", + type: "blob", + csp: "default-src 'self' blob:", + expectBlocked: true + }, + + // create parent worker from url, child worker from url, + // child delivery csp from header + // csp should be : default-src 'none' + { + id: "worker_url_child_url_fetch_cross_bad", + base: CROSS_BASE, + action: "fetch", + child: "url", + childCsp: "default-src 'none'", + type: "url", + csp: "default-src 'self' blob:", + expectBlocked: true + }, + { + id: "worker_url_child_url_xhr_cross_bad", + base: CROSS_BASE, + child: "url", + childCsp: "default-src 'none'", + action: "xhr", + type: "url", + csp: "default-src 'self' blob:", + expectBlocked: true + }, + { + id: "worker_url_child_url_importScripts_cross_bad", + base: CROSS_BASE, + action: "importScripts", + child: "url", + childCsp: "default-src 'none'", + type: "url", + csp: "default-src 'self' blob:", + expectBlocked: true + }, + { + id: "worker_url_child_url_fetch_same_bad", + base: SAME_BASE, + action: "fetch", + child: "url", + childCsp: "default-src 'none'", + type: "url", + csp: "default-src 'self' blob:", + expectBlocked: true + }, + { + id: "worker_url_child_url_xhr_same_bad", + base: SAME_BASE, + child: "url", + childCsp: "default-src 'none'", + action: "xhr", + type: "url", + csp: "default-src 'self' blob:", + expectBlocked: true + }, + { + id: "worker_url_child_url_importScripts_same_bad", + base: SAME_BASE, + action: "importScripts", + child: "url", + childCsp: "default-src 'none'", + type: "url", + csp: "default-src 'self' blob:", + expectBlocked: true + }, + + // create parent worker from blob, child worker from url, + // child delivery csp from header + // csp should be : default-src 'none' + { + id: "worker_blob_child_url_fetch_cross_bad", + base: CROSS_BASE, + child: "url", + childCsp: "default-src 'none'", + action: "fetch", + type: "blob", + csp: "default-src 'self' blob:", + expectBlocked: true + }, + { + id: "worker_blob_child_url_xhr_cross_bad", + base: CROSS_BASE, + child: "url", + childCsp: "default-src 'none'", + action: "xhr", + type: "blob", + csp: "default-src 'self' blob:", + expectBlocked: true + }, + { + id: "worker_blob_child_url_importScripts_cross_bad", + base: CROSS_BASE, + action: "importScripts", + child: "url", + childCsp: "default-src 'none'", + type: "blob", + csp: "default-src 'self' blob:", + expectBlocked: true + }, + { + id: "worker_blob_child_url_fetch_same_bad", + base: SAME_BASE, + child: "url", + childCsp: "default-src 'none'", + action: "fetch", + type: "blob", + csp: "default-src 'self' blob:", + expectBlocked: true + }, + { + id: "worker_blob_child_url_xhr_same_bad", + base: SAME_BASE, + child: "url", + childCsp: "default-src 'none'", + action: "xhr", + type: "blob", + csp: "default-src 'self' blob:", + expectBlocked: true + }, + { + id: "worker_blob_child_url_importScripts_same_bad", + base: SAME_BASE, + action: "importScripts", + child: "url", + childCsp: "default-src 'none'", + type: "blob", + csp: "default-src 'self' blob:", + expectBlocked: true + }, + + + ]; + + async function runWorkerTest(data) { + let src = SJS; + src += "?base=" + escape(data.base); + src += "&action=" + escape(data.action); + src += "&csp=" + escape(data.csp); + src += "&id=" + escape(data.id); + + if (data.child) { + src += "&child=" + escape(data.child); + } + + if (data.childCsp) { + src += "&childCsp=" + escape(data.childCsp); + } + + switch (data.type) { + case "url": + new Worker(src); + break; + + case "blob": + new Worker(URL.createObjectURL(await doXHRGetBlob(src))); + break; + + default: + throw "Unsupport type"; + } + + let checkUri = data.base + "?id=" + data.id; + await assertCSPBlock(checkUri, data.expectBlocked); + runNextTest(); + }; + + tests.forEach(function(test) { + addAsyncTest(async function() { + runWorkerTest(test); + }); + }); + + runNextTest(); + </script> + + </body> +</html>
new file mode 100644 --- /dev/null +++ b/dom/security/test/csp/main_csp_worker.html^headers^ @@ -0,0 +1,1 @@ +Content-Security-Policy: default-src 'self' blob: 'unsafe-inline'
--- a/dom/security/test/csp/mochitest.ini +++ b/dom/security/test/csp/mochitest.ini @@ -42,20 +42,16 @@ support-files = file_inlinestyle_main.html file_inlinestyle_main.html^headers^ file_inlinestyle_main_allowed.html file_inlinestyle_main_allowed.html^headers^ file_invalid_source_expression.html file_main.html file_main.html^headers^ file_main.js - file_main_worker.js - file_main_worker.js^headers^ - file_child_worker.js - file_child_worker.js^headers^ file_web_manifest.html file_web_manifest_remote.html file_web_manifest_https.html file_web_manifest.json file_web_manifest.json^headers^ file_web_manifest_https.json file_web_manifest_mixed_content.html file_bug836922_npolicies.html @@ -358,8 +354,14 @@ support-files = file_spawn_service_worker.js [test_frame_src.html] support-files = file_frame_src_frame_governs.html file_frame_src_child_governs.html file_frame_src.js file_frame_src_inner.html [test_security_policy_violation_event.html] +[test_csp_worker_inheritance.html] +support-files = + worker.sjs + worker_helper.js + main_csp_worker.html + main_csp_worker.html^headers^
--- a/dom/security/test/csp/test_CSP.html +++ b/dom/security/test/csp/test_CSP.html @@ -24,40 +24,16 @@ window.tests = { script_good: -1, script_bad: -1, xhr_good: -1, xhr_bad: -1, fetch_good: -1, fetch_bad: -1, beacon_good: -1, beacon_bad: -1, - worker_xhr_same_bad: -1, - worker_xhr_cross_good: -1, - worker_fetch_same_bad: -1, - worker_fetch_cross_good: -1, - worker_script_same_good: -1, - worker_script_cross_bad: -1, - worker_inherited_xhr_good: -1, - worker_inherited_xhr_bad: -1, - worker_inherited_fetch_good: -1, - worker_inherited_fetch_bad: -1, - worker_inherited_script_good: -1, - worker_inherited_script_bad: -1, - worker_child_xhr_same_bad: -1, - worker_child_xhr_cross_bad: -1, - worker_child_script_same_bad: -1, - worker_child_script_cross_bad: -1, - worker_child_inherited_parent_xhr_bad: -1, - worker_child_inherited_parent_xhr_good: -1, - worker_child_inherited_parent_script_good: -1, - worker_child_inherited_parent_script_bad: -1, - worker_child_inherited_document_xhr_good: -1, - worker_child_inherited_document_xhr_bad: -1, - worker_child_inherited_document_script_good: -1, - worker_child_inherited_document_script_bad: -1, media_good: -1, media_bad: -1, font_good: -1, font_bad: -1, object_good: -1, object_bad: -1, };
new file mode 100644 --- /dev/null +++ b/dom/security/test/csp/test_csp_worker_inheritance.html @@ -0,0 +1,20 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +<html> + <head> + <title>Test for Bug 1475849</title> + </head> + <body> + <p id="display"></p> + <div id="content" style="display: none"> + </div> + <iframe style="width:200px;height:200px;" id='cspframe'></iframe> + <script class="testbody" type="text/javascript"> + document.getElementById('cspframe').src = 'main_csp_worker.html'; + </script> + + </body> +</html>
new file mode 100644 --- /dev/null +++ b/dom/security/test/csp/worker.sjs @@ -0,0 +1,116 @@ +Components.utils.importGlobalProperties(["URLSearchParams"]); + +const SJS = "http://mochi.test:8888/tests/dom/security/test/csp/worker.sjs"; + +function createFetchWorker(url) +{ + return `fetch("${url}");`; +} + +function createXHRWorker(url) +{ + return ` + try { + var xhr = new XMLHttpRequest(); + xhr.open("GET", "${url}"); + xhr.send(); + } catch(ex) {} + `; +} + +function createImportScriptsWorker(url) +{ + return ` + try { + importScripts("${url}"); + } catch(ex) {} + `; +} + +function createChildWorkerURL(params) +{ + let url = SJS + "?" + params.toString(); + return `new Worker("${url}");`; +} + +function createChildWorkerBlob(params) +{ + let url = SJS + "?" + params.toString(); + return ` + try { + var xhr = new XMLHttpRequest(); + xhr.open("GET", "${url}"); + xhr.responseType = "blob"; + xhr.send(); + xhr.onload = () => { + new Worker(URL.createObjectURL(xhr.response));}; + } catch(ex) {} + `; +} + +function handleRequest(request, response) +{ + let params = new URLSearchParams(request.queryString); + + let id = params.get("id"); + let base = unescape(params.get("base")); + let child = params.has("child") ? params.get("child") : ""; + + //avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "application/javascript"); + + // Deliver the CSP policy encoded in the URL + if(params.has("csp")) { + response.setHeader("Content-Security-Policy", unescape(params.get("csp")), false); + } + + if (child) { + let childCsp = params.has("childCsp") ? params.get("childCsp") : ""; + params.delete("csp"); + params.delete("child"); + params.delete("childCsp"); + params.append("csp", childCsp); + + switch (child) { + case "blob": + response.write(createChildWorkerBlob(params)); + break; + + case "url": + response.write(createChildWorkerURL(params)); + break; + + default: + response.setStatusLine(request.httpVersion, 400, "Bad request"); + break; + } + + return; + } + + if (params.has("action")) { + switch (params.get("action")) { + case "fetch": + response.write(createFetchWorker(base + "?id=" + id)); + break; + + case "xhr": + response.write(createXHRWorker(base + "?id=" + id)); + break; + + case "importScripts": + response.write(createImportScriptsWorker(base + "?id=" + id)); + break; + + default: + response.setStatusLine(request.httpVersion, 400, "Bad request"); + break; + } + + return; + } + + response.write("I don't know action "); + return; +}
new file mode 100644 --- /dev/null +++ b/dom/security/test/csp/worker_helper.js @@ -0,0 +1,81 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +var _tests = []; +function addTest(test) { + _tests.push(test); +} + +function addAsyncTest(fn) { + _tests.push(() => (fn)().catch(ok.bind(null, false))); +} + +function runNextTest() { + if (_tests.length == 0) { + SimpleTest.finish(); + return; + } + const fn = _tests.shift(); + try { + fn(); + } catch (ex) { + info("Test function " + (fn.name ? "'" + fn.name + "' " : "") + + "threw an exception: " + ex); + } +} + +/** + * Helper to perform an XHR then blob response to create worker + */ +function doXHRGetBlob(uri) { + return new Promise(resolve => { + const xhr = new XMLHttpRequest(); + xhr.open("GET", uri); + xhr.responseType = "blob"; + xhr.addEventListener("load", function() { + is(xhr.status, 200, "doXHRGetBlob load uri='" + uri + "' status=" + xhr.status); + resolve(xhr.response); + }); + xhr.send(); + }); +} + +function removeObserver(observer) { + SpecialPowers.removeObserver(observer, "specialpowers-http-notify-request"); + SpecialPowers.removeObserver(observer, "csp-on-violate-policy"); +} + +/** + * Helper to perform an assert to check if the request should be blocked or + * allowed by CSP + */ +function assertCSPBlock(url, shouldBlock) { + return new Promise((resolve, reject) => { + let observer = { + observe(subject, topic, data) { + if (topic === "specialpowers-http-notify-request") { + if (data == url) { + is(shouldBlock, false, "Should allow request uri='" + url); + removeObserver(observer); + resolve(); + } + } + + if (topic === "csp-on-violate-policy") { + let asciiSpec = SpecialPowers.getPrivilegedProps( + SpecialPowers.do_QueryInterface(subject, "nsIURI"), "asciiSpec"); + if (asciiSpec == url) { + is(shouldBlock, true, "Should block request uri='" + url); + removeObserver(observer); + resolve(); + } + } + }, + }; + + SpecialPowers.addObserver(observer, "csp-on-violate-policy"); + SpecialPowers.addObserver(observer, "specialpowers-http-notify-request"); + }); +}
--- a/dom/svg/test/mochitest.ini +++ b/dom/svg/test/mochitest.ini @@ -40,16 +40,17 @@ support-files = [test_bug872812.html] [test_getBBox-method.html] [test_dataTypes.html] [test_dataTypesModEvents.html] [test_fragments.html] [test_getCTM.html] [test_getElementById.xhtml] [test_getSubStringLength.xhtml] +[test_getTotalLength.xhtml] [test_lang.xhtml] skip-if = true # disabled-for-intermittent-failures--bug-701060 [test_length.xhtml] [test_lengthParsing.html] [test_markerOrient.xhtml] [test_nonAnimStrings.xhtml] [test_non-scaling-stroke.html] [test_object-delayed-intrinsic-size.html]
new file mode 100644 --- /dev/null +++ b/dom/svg/test/test_getTotalLength.xhtml @@ -0,0 +1,42 @@ +<!DOCTYPE html> +<html xmlns="http://www.w3.org/1999/xhtml"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1474284 +--> +<head> + <title>Test for Bug 1474284</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1474284">Mozilla Bug 1474284</a> +<p id="display"></p> + +<svg xmlns="http://www.w3.org/2000/svg"> + <path id="path1" stroke="#000" fill="none" + d="M 50,40 + C 50,40 0,60 30,20"/> +</svg> + +<pre id="test"> +<script class="testbody" type="application/javascript"> +SimpleTest.waitForExplicitFinish(); + +function expectValue(id, expected) +{ + isfuzzy(document.getElementById(id).getTotalLength(), + expected, expected * 0.02, + `getTotalLength() on element id="${id}" returned the wrong value`); +} + +function run() +{ + expectValue("path1", 55.19); + SimpleTest.finish(); +} + +window.addEventListener("load", run, false); +</script> +</pre> +</body> +</html>
--- a/dom/webidl/AccessibleNode.webidl +++ b/dom/webidl/AccessibleNode.webidl @@ -20,18 +20,34 @@ interface AccessibleNode { // Accessible properties attribute boolean? modal; attribute boolean? multiline; attribute boolean? multiselectable; attribute boolean? readOnly; attribute boolean? required; + // Range values + attribute double? valueMax; + attribute double? valueMin; + attribute double? valueNow; + // Accessible states attribute boolean? disabled; attribute boolean? expanded; attribute boolean? hidden; attribute boolean? selected; // Live regions attribute boolean? atomic; attribute boolean? busy; + + // Collections. + attribute long? colCount; + attribute unsigned long? colIndex; + attribute unsigned long? colSpan; + attribute unsigned long? level; + attribute unsigned long? posInSet; + attribute long? rowCount; + attribute unsigned long? rowIndex; + attribute unsigned long? rowSpan; + attribute long? setSize; };
--- a/gfx/2d/Path.cpp +++ b/gfx/2d/Path.cpp @@ -301,16 +301,20 @@ FindInflectionApproximationRange(BezierC double aTolerance) { SplitBezier(aControlPoints, nullptr, &aControlPoints, aT); PointD cp21 = aControlPoints.mCP2 - aControlPoints.mCP1; PointD cp41 = aControlPoints.mCP4 - aControlPoints.mCP1; if (cp21.x == 0. && cp21.y == 0.) { + cp21 = aControlPoints.mCP3 - aControlPoints.mCP1; + } + + if (cp21.x == 0. && cp21.y == 0.) { // In this case s3 becomes lim[n->0] (cp41.x * n) / n - (cp41.y * n) / n = cp41.x - cp41.y. // Use the absolute value so that Min and Max will correspond with the // minimum and maximum of the range. *aMin = aT - CubicRoot(std::abs(aTolerance / (cp41.x - cp41.y))); *aMax = aT + CubicRoot(std::abs(aTolerance / (cp41.x - cp41.y))); return; }
--- a/js/src/ds/LifoAlloc.h +++ b/js/src/ds/LifoAlloc.h @@ -219,17 +219,17 @@ class BumpChunk : public SingleLinkedLis uint8_t* const capacity_; #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED // Magic number used to check against poisoned values. const uintptr_t magic_ : 24; static constexpr uintptr_t magicNumber = uintptr_t(0x4c6966); #endif -#if defined(DEBUG) || defined(MOZ_DIAGNOSTIC_ASSERT_ENABLED) +#if defined(DEBUG) || defined(MOZ_ASAN) # define LIFO_CHUNK_PROTECT 1 #endif #ifdef LIFO_CHUNK_PROTECT // Constant used to know if the current chunk should be protected. This is // mainly use to prevent dead-lock in the MemoryProtectionExceptionHandler // methods. const uintptr_t protect_ : 1;
--- a/layout/generic/crashtests/crashtests.list +++ b/layout/generic/crashtests/crashtests.list @@ -647,18 +647,18 @@ load text-overflow-bug713610.html load text-overflow-form-elements.html load text-overflow-iframe.html asserts(1-4) load 1225005.html # bug 682647 and bug 448083 load 1233191.html load 1233607.html load 1234701-1.html load 1234701-2.html load 1271765.html -asserts(2) asserts-if(Android,1) load 1272983-1.html # bug 586628 -asserts(2) asserts-if(Android,1) load 1272983-2.html # bug 586628 +pref(layout.css.xul-box-display-values.content.enabled,true) asserts(2) asserts-if(Android,1) load 1272983-1.html # bug 586628 +pref(layout.css.xul-box-display-values.content.enabled,true) asserts(2) asserts-if(Android,1) load 1272983-2.html # bug 586628 load 1275059.html load 1278007.html load 1278080.html load 1279814.html skip-if(webrender) load large-border-radius-dashed.html # see bug 1409243, not handled by webrender skip-if(webrender) load large-border-radius-dashed2.html # see bug 1409243, not handled by webrender skip-if(webrender) load large-border-radius-dotted.html # see bug 1409243, not handled by webrender skip-if(webrender) load large-border-radius-dotted2.html # see bug 1409243, not handled by webrender
--- a/layout/reftests/box-ordinal/reftest.list +++ b/layout/reftests/box-ordinal/reftest.list @@ -1,7 +1,7 @@ -== box-ordinal-with-out-of-flow-1.html box-ordinal-with-out-of-flow-1-ref.html +pref(layout.css.xul-box-display-values.content.enabled,true) == box-ordinal-with-out-of-flow-1.html box-ordinal-with-out-of-flow-1-ref.html == dynamic-1-remove-to-none-grouped.xul dynamic-1-ref.xul == dynamic-1-add-to-one-grouped.xul dynamic-1-ref.xul == dynamic-1-remove-to-one-grouped-1.xul dynamic-1-ref.xul fails == dynamic-1-remove-to-one-grouped-2.xul dynamic-1-ref.xul # bug 575500 == dynamic-1-add-to-two-grouped-1.xul dynamic-1-ref.xul == dynamic-1-add-to-two-grouped-2.xul dynamic-1-ref.xul
--- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -412,17 +412,17 @@ fuzzy-if(Android,2,18) == 315920-17.html == 320979-1.html 320979-1-ref.html != 321402-1.html about:blank != 321402-2.html about:blank fuzzy-if(webrender&&winWidget,35-35,1-1) == 321402-3.xul 321402-3-ref.xul == 321402-4.xul 321402-4-ref.xul == 321402-5.xul 321402-5-ref.xul == 321402-6.xul 321402-6-ref.xul == 321738-1.html 321738-1-ref.html -== 322436-1.html 322436-1-ref.html +pref(layout.css.xul-box-display-values.content.enabled,true) == 322436-1.html 322436-1-ref.html == 322461-1.xml 322461-1-ref.html == 323656-1.html 323656-1-ref.html == 323656-2.html 323656-2-ref.html == 323656-3.html 323656-3-ref.html == 323656-4.html 323656-4-ref.html == 323656-5.svg 323656-5-ref.svg == 323656-6.html 323656-6-ref.html fuzzy-if(Android,2,140) == 325292-1.html 325292-1-ref.html @@ -951,17 +951,17 @@ fails == 411585-3.html 411585-3-ref.html == 411792-1.html 411792-1-ref.html == 412093-1.html 412093-1-ref.html == 412352-1.html 412352-1-ref.html == 412352-2.html 412352-2-ref.html == 412607-1a.html 412607-1-ref.html == 412607-1b.html 412607-1-ref.html random-if(Android) == 412679-1.html 412679-1-ref.html fuzzy-if(skiaContent,1,17) == 412679-2.html 412679-2-ref.html -== 413027-1.html 413027-1-ref.html +pref(layout.css.xul-box-display-values.content.enabled,true) == 413027-1.html 413027-1-ref.html fails == 413027-2.html 413027-2-ref.html fails == 413027-3.html 413027-3-ref.html == 413286-1a.html 413286-1-ref.html == 413286-1b.html 413286-1-ref.html == 413286-1c.html 413286-1-ref.html == 413286-2a.html 413286-2-ref.html == 413286-2b.html 413286-2-ref.html == 413286-2c.html 413286-2-ref.html @@ -1404,17 +1404,17 @@ fuzzy-if(Android,5,2800) == 506481-1.htm == 507187-1.html 507187-1-ref.html == 507487-1.html 507487-1-ref.html == 507487-2.xhtml 507487-2-ref.xhtml == 507762-1.html 507762-1-ref.html == 507762-2.html 507762-2-ref.html == 507762-3.html 507762-1-ref.html == 507762-4.html 507762-2-ref.html random == 508816-1.xul 508816-1-ref.xul # Bug 1375012 -== 508816-2.html 508816-2-ref.html +pref(layout.css.xul-box-display-values.content.enabled,true) == 508816-2.html 508816-2-ref.html skip-if(isDebugBuild) == 508908-1.xul 508908-1-ref.xul == 508919-1.xhtml 508919-1-ref.xhtml == 509155-1.xhtml 509155-1-ref.xhtml fuzzy-if(Android,5,1656) fuzzy-if(skiaContent,1,1200) == 512410.html 512410-ref.html == 512631-1.html 512631-1-ref.html == 513153-1a.html 513153-1-ref.html == 513153-1b.html 513153-1-ref.html == 513153-2a.html 513153-2-ref.html @@ -1444,17 +1444,17 @@ fuzzy-if(skiaContent,5,50) == 526463-1.h == 528038-1b.html 528038-1-ref.html == 528038-1c.html 528038-1-ref.html == 528038-1d.html 528038-1-ref.html == 528038-1e.html 528038-1-ref.html == 528038-1f.html 528038-1-ref.html == 528038-2.html 528038-2-ref.html == 528096-1.html 528096-1-ref.html == 530686-1.html 530686-1-ref.html -== 531098-1.html 531098-1-ref.html +pref(layout.css.xul-box-display-values.content.enabled,true) == 531098-1.html 531098-1-ref.html fuzzy-if(Android,2,48) == 531200-1.html 531200-1-ref.html == 531371-1.html 531371-1-ref.html == 534526-1a.html 534526-1-ref.html == 534526-1b.html 534526-1-ref.html == 534804-1.html 534804-1-ref.html == 534808-1.html 534808-1-ref.html == 534808-2.html 534808-2-ref.html == 534919-1.html 534919-1-ref.html @@ -1559,17 +1559,17 @@ fuzzy-if(Android,1,1) needs-focus == 568 == 574898-1.html 574898-ref.html # 574907 is a windows-only issue, result on other platforms depends on details of font support random-if(!winWidget) random-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)) == 574907-1.html 574907-1-ref.html # Bug 1258240 random-if(!winWidget) random-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)) == 574907-2.html 574907-2-ref.html # Bug 1258240 # 574907-3 only worked under directwrite, and even there it now depends on the rendering mode; marking as random for now random-if(!winWidget) fails-if(winWidget&&!dwrite) random-if(winWidget&&dwrite) != 574907-3.html 574907-3-notref.html == 577838-1.html 577838-1-ref.html == 577838-2.html 577838-2-ref.html -== 579323-1.html 579323-1-ref.html +pref(layout.css.xul-box-display-values.content.enabled,true) == 579323-1.html 579323-1-ref.html == 579349-1.html 579349-1-ref.html == 579655-1.html 579655-1-ref.html skip-if(!haveTestPlugin) fails-if(Android) HTTP == 579808-1.html 579808-1-ref.html fails-if(Android) random-if(layersGPUAccelerated) fuzzy-if(skiaContent,1,10000) == 579985-1.html 579985-1-ref.html # this bug was only for a regression in BasicLayers anyway skip-if(Android) == 580160-1.html 580160-1-ref.html # bug 920927 for Android; issues without the test-plugin fuzzy-if(asyncPan&&!layersGPUAccelerated,255,141) == 580863-1.html 580863-1-ref.html fails-if(Android) random-if(layersGPUAccelerated) fuzzy-if(skiaContent,1,6436) == 581317-1.html 581317-1-ref.html == 581579-1.html 581579-1-ref.html
--- a/layout/reftests/text-overflow/reftest.list +++ b/layout/reftests/text-overflow/reftest.list @@ -17,17 +17,17 @@ fuzzy-if(skiaContent,1,4200) fuzzy-if(we fuzzy-if(webrender,5,509) == marker-shadow.html marker-shadow-ref.html fuzzy-if(webrender,3,25) == aligned-baseline.html aligned-baseline-ref.html skip-if(Android) fuzzy-if(skiaContent,1,5) == clipped-elements.html clipped-elements-ref.html == theme-overflow.html theme-overflow-ref.html == table-cell.html table-cell-ref.html fuzzy-if(gtkWidget,10,32) fuzzy-if(webrender,47,18) == two-value-syntax.html two-value-syntax-ref.html == single-value.html single-value-ref.html fuzzy-if(gtkWidget,10,2) == atomic-under-marker.html atomic-under-marker-ref.html -fuzzy(1,2616) skip-if(Android) fuzzy-if(asyncPan&&!layersGPUAccelerated,102,12352) fails-if(gtkWidget) == xulscroll.html xulscroll-ref.html # gtkWidget:bug 1309107, bug 1328771 +pref(layout.css.xul-box-display-values.content.enabled,true) fuzzy(1,2616) skip-if(Android) fuzzy-if(asyncPan&&!layersGPUAccelerated,102,12352) fails-if(gtkWidget) == xulscroll.html xulscroll-ref.html # gtkWidget:bug 1309107, bug 1328771 == combobox-zoom.html combobox-zoom-ref.html == dynamic-change-1.html dynamic-change-1-ref.html == float-edges-1.html float-edges-1-ref.html # The vertical-text pref setting can be removed after bug 1138384 lands == vertical-decorations-1.html vertical-decorations-1-ref.html == vertical-decorations-2.html vertical-decorations-2-ref.html != vertical-decorations-1.html vertical-decorations-1-2-notref.html
--- a/layout/style/test/test_flexbox_child_display_values.xhtml +++ b/layout/style/test/test_flexbox_child_display_values.xhtml @@ -134,18 +134,16 @@ function main() { testDisplayValue("table"); testDisplayValue("inline-table", "table"); // These values all compute to "block" in a flex container. Do them in a // loop, so that I don't have to type "block" a zillion times. var dispValsThatComputeToBlockInAFlexContainer = [ "inline", "inline-block", - "-moz-box", - "-moz-inline-box", ]; dispValsThatComputeToBlockInAFlexContainer.forEach( function(aSpecifiedDisplay) { testDisplayValue(aSpecifiedDisplay, "block"); }); // Table-parts are special. When they're a child of a flex container,
--- a/layout/style/test/test_layout_css_xul_display_values_content_enabled.html +++ b/layout/style/test/test_layout_css_xul_display_values_content_enabled.html @@ -13,17 +13,20 @@ const VALUES = [ "-moz-inline-stack", "-moz-deck", "-moz-popup", "-moz-groupbox", ]; SimpleTest.waitForExplicitFinish(); SpecialPowers.pushPrefEnv( - {"set": [["layout.css.xul-display-values.content.enabled", true]]} + {"set": [ + ["layout.css.xul-display-values.content.enabled", true], + ["layout.css.xul-box-display-values.content.enabled", true], + ]} ).then(runTest); function runTest() { const div = document.querySelector("div"); for (const value of VALUES) { div.style.display = value; is(div.style.display, value); is(getComputedStyle(div).display, value);
--- a/layout/style/test/test_non_content_accessible_values.html +++ b/layout/style/test/test_non_content_accessible_values.html @@ -1,19 +1,18 @@ <!doctype html> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <style id="sheet"></style> <div></div> <script> const NON_CONTENT_ACCESSIBLE_VALUES = { "display": [ - // FIXME(emilio, bug TBD): Remove from content these two too. - // "-moz-box", - // "-moz-inline-box", + "-moz-box", + "-moz-inline-box", "-moz-grid", "-moz-inline-grid", "-moz-grid-group", "-moz-grid-line", "-moz-stack", "-moz-inline-stack", "-moz-deck", "-moz-popup",
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/AccessibilityTest.kt +++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/AccessibilityTest.kt @@ -57,16 +57,17 @@ class AccessibilityTest : BaseSessionTes return getVirtualDescendantId(getSourceIdMethod.invoke(event) as Long) } catch (ex: Exception) { return 0 } } private interface EventDelegate { fun onAccessibilityFocused(event: AccessibilityEvent) { } + fun onClicked(event: AccessibilityEvent) { } fun onFocused(event: AccessibilityEvent) { } fun onTextSelectionChanged(event: AccessibilityEvent) { } fun onTextChanged(event: AccessibilityEvent) { } fun onTextTraversal(event: AccessibilityEvent) { } } @Before fun setup() { // We initialize a view with a parent and grandparent so that the @@ -82,16 +83,17 @@ class AccessibilityTest : BaseSessionTes // Set up an external delegate that will intercept accessibility events. sessionRule.addExternalDelegateUntilTestEnd( EventDelegate::class, { newDelegate -> (view.parent as View).setAccessibilityDelegate(object : View.AccessibilityDelegate() { override fun onRequestSendAccessibilityEvent(host: ViewGroup, child: View, event: AccessibilityEvent): Boolean { when (event.eventType) { AccessibilityEvent.TYPE_VIEW_FOCUSED -> newDelegate.onFocused(event) + AccessibilityEvent.TYPE_VIEW_CLICKED -> newDelegate.onClicked(event) AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED -> newDelegate.onAccessibilityFocused(event) AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED -> newDelegate.onTextSelectionChanged(event) AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED -> newDelegate.onTextChanged(event) AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY -> newDelegate.onTextTraversal(event) else -> {} } return false } @@ -190,16 +192,35 @@ class AccessibilityTest : BaseSessionTes @AssertCalled(count = 1) override fun onTextTraversal(event: AccessibilityEvent) { assertThat("fromIndex matches", event.fromIndex, equalTo(fromIndex)) assertThat("toIndex matches", event.toIndex, equalTo(toIndex)) } }) } + private fun waitUntilClick(checked: Boolean? = null, selected: Boolean? = null) { + sessionRule.waitUntilCalled(object : EventDelegate { + @AssertCalled(count = 1) + override fun onClicked(event: AccessibilityEvent) { + var nodeId = getSourceId(event) + var node = provider.createAccessibilityNodeInfo(nodeId) + + if (checked != null) { + assertThat("Event's checked state matches", event.isChecked, equalTo(checked)) + assertThat("Checkbox node has correct checked state", node.isChecked, equalTo(checked)) + } + + if (selected != null) { + assertThat("Selectable node has correct selected state", node.isSelected, equalTo(selected)) + } + } + }) + } + private fun setSelectionArguments(start: Int, end: Int): Bundle { val arguments = Bundle(2) arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, start) arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, end) return arguments } private fun moveByGranularityArguments(granularity: Int, extendSelection: Boolean = false): Bundle { @@ -353,9 +374,63 @@ class AccessibilityTest : BaseSessionTes moveByGranularityArguments(AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE)) waitUntilTextTraversed(18, 28) // "sit amet, " provider.performAction(nodeId, AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY, moveByGranularityArguments(AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE)) waitUntilTextTraversed(0, 18) // "Lorem ipsum dolor " } + + @Test fun testCheckbox() { + var nodeId = AccessibilityNodeProvider.HOST_VIEW_ID; + sessionRule.session.loadString("<label><input id='checkbox' type='checkbox'>many option</label>", "text/html") + sessionRule.waitForPageStop() + + mainSession.evaluateJS("$('#checkbox').focus()") + sessionRule.waitUntilCalled(object : EventDelegate { + @AssertCalled(count = 1) + override fun onAccessibilityFocused(event: AccessibilityEvent) { + nodeId = getSourceId(event) + var node = provider.createAccessibilityNodeInfo(nodeId) + assertThat("Checkbox node is checkable", node.isCheckable, equalTo(true)) + assertThat("Checkbox node is clickable", node.isClickable, equalTo(true)) + assertThat("Checkbox node is focusable", node.isFocusable, equalTo(true)) + assertThat("Checkbox node is not checked", node.isChecked, equalTo(false)) + assertThat("Checkbox node has correct role", node.text.toString(), equalTo("many option check button")) + } + }) + + provider.performAction(nodeId, AccessibilityNodeInfo.ACTION_CLICK, null) + waitUntilClick(checked = true) + + provider.performAction(nodeId, AccessibilityNodeInfo.ACTION_CLICK, null) + waitUntilClick(checked = false) + } + + @Test fun testSelectable() { + var nodeId = View.NO_ID + sessionRule.session.loadString( + """<ul style="list-style-type: none;" role="listbox"> + <li id="li" role="option" onclick="this.setAttribute('aria-selected', + this.getAttribute('aria-selected') == 'true' ? 'false' : 'true')">1</li> + </ul>""","text/html") + sessionRule.waitForPageStop() + + provider.performAction(nodeId, AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null) + sessionRule.waitUntilCalled(object : EventDelegate { + @AssertCalled(count = 1) + override fun onAccessibilityFocused(event: AccessibilityEvent) { + nodeId = getSourceId(event) + var node = provider.createAccessibilityNodeInfo(nodeId) + assertThat("Selectable node is clickable", node.isClickable, equalTo(true)) + assertThat("Selectable node is not selected", node.isSelected, equalTo(false)) + assertThat("Selectable node has correct role", node.text.toString(), equalTo("1 option list box")) + } + }) + + provider.performAction(nodeId, AccessibilityNodeInfo.ACTION_CLICK, null) + waitUntilClick(selected = true) + + provider.performAction(nodeId, AccessibilityNodeInfo.ACTION_CLICK, null) + waitUntilClick(selected = false) + } }
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/SessionAccessibility.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/SessionAccessibility.java @@ -374,16 +374,17 @@ public class SessionAccessibility { private void populateNodeInfoFromJSON(AccessibilityNodeInfo node, final GeckoBundle message) { node.setEnabled(message.getBoolean("enabled", true)); node.setCheckable(message.getBoolean("checkable")); node.setChecked(message.getBoolean("checked")); node.setPassword(message.getBoolean("password")); node.setFocusable(message.getBoolean("focusable")); node.setFocused(message.getBoolean("focused")); + node.setSelected(message.getBoolean("selected")); node.setClassName(message.getString("className", "android.view.View")); final String[] textArray = message.getStringArray("text"); StringBuilder sb = new StringBuilder(); if (textArray != null && textArray.length > 0) { sb.append(textArray[0] != null ? textArray[0] : ""); for (int i = 1; i < textArray.length; i++) { @@ -426,16 +427,25 @@ public class SessionAccessibility { final float[] origin = new float[2]; mSession.getClientToScreenMatrix(matrix); matrix.mapPoints(origin); screenBounds.offset((int) -origin[0], (int) -origin[1]); node.setBoundsInParent(screenBounds); } + private void updateState(final AccessibilityNodeInfo node, final GeckoBundle message) { + if (message.containsKey("checked")) { + node.setChecked(message.getBoolean("checked")); + } + if (message.containsKey("selected")) { + node.setSelected(message.getBoolean("selected")); + } + } + private void sendAccessibilityEvent(final GeckoBundle message) { if (mView == null || !Settings.isEnabled()) return; final int eventType = message.getInt("eventType", -1); if (eventType < 0) { Log.e(LOGTAG, "No accessibility event type provided"); return; @@ -467,16 +477,21 @@ public class SessionAccessibility { } mVirtualContentNode = AccessibilityNodeInfo.obtain(mView, eventSource); populateNodeInfoFromJSON(mVirtualContentNode, message); } if (mVirtualContentNode != null) { // Bounds for the virtual content can be updated from any event. updateBounds(mVirtualContentNode, message); + + // State for the virtual content can be updated when view is clicked. + if (eventType == AccessibilityEvent.TYPE_VIEW_CLICKED) { + updateState(mVirtualContentNode, message); + } } final AccessibilityEvent accessibilityEvent = obtainEvent(eventType, eventSource); populateEventFromJSON(accessibilityEvent, message); ((ViewParent) mView).requestSendAccessibilityEvent(mView, accessibilityEvent); } public boolean onMotionEvent(final MotionEvent event) {
--- a/modules/libpref/init/StaticPrefList.h +++ b/modules/libpref/init/StaticPrefList.h @@ -356,16 +356,30 @@ VARCACHE_PREF( #undef PREF_VALUE VARCACHE_PREF( "layout.css.xul-display-values.content.enabled", layout_css_xul_display_values_content_enabled, bool, false ) +// Pref to control whether display: -moz-box and display: -moz-inline-box are +// parsed in content pages. +#ifdef EARLY_BETA_OR_EARLIER +#define PREF_VALUE false +#else +#define PREF_VALUE true +#endif +VARCACHE_PREF( + "layout.css.xul-box-display-values.content.enabled", + layout_css_xul_box_display_values_content_enabled, + bool, PREF_VALUE +) +#undef PREF_VALUE + // Is support for CSS "grid-template-{columns,rows}: subgrid X" enabled? VARCACHE_PREF( "layout.css.grid-template-subgrid-value.enabled", layout_css_grid_template_subgrid_value_enabled, bool, false ) // Is support for variation fonts enabled?
--- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -601,16 +601,20 @@ pref("media.cubeb.logging_level", ""); pref("media.cubeb.sandbox", true); pref("media.audioipc.pool_size", 2); // 64 * 4 kB stack per pool thread. pref("media.audioipc.stack_size", 262144); #else pref("media.cubeb.sandbox", false); #endif +#ifdef MOZ_AV1 +pref("media.av1.enabled", false); +#endif + pref("media.webaudio.audiocontextoptions-samplerate.enabled", true); // setSinkId expected to be unconditionally enabled in 63. Till then the // implementation will remain hidden behind this pref (Bug 1152401, Bug 934425). pref("media.setsinkid.enabled", false); // Weather we allow AMD switchable graphics pref("layers.amd-switchable-gfx.enabled", true);
--- a/mozglue/tests/interceptor/TestDllInterceptor.cpp +++ b/mozglue/tests/interceptor/TestDllInterceptor.cpp @@ -394,17 +394,18 @@ bool ShouldTestTipTsf() if (!LoadLibraryW(fullPath)) { return false; } // Leak the module so that it's loaded for the interceptor test return true; } -int main() +extern "C" +int wmain(int argc, wchar_t* argv[]) { LARGE_INTEGER start; QueryPerformanceCounter(&start); // We disable this part of the test because the code coverage instrumentation // injects code in rotatePayload in a way that WindowsDllInterceptor doesn't // understand. #ifndef MOZ_CODE_COVERAGE
--- a/mozglue/tests/interceptor/TestDllInterceptorCrossProcess.cpp +++ b/mozglue/tests/interceptor/TestDllInterceptorCrossProcess.cpp @@ -1,14 +1,17 @@ /* -*- 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 https://mozilla.org/MPL/2.0/. */ +#include "mozilla/Attributes.h" +#include "mozilla/ArrayUtils.h" +#include "mozilla/CmdLineAndEnvUtils.h" #include "nsWindowsDllInterceptor.h" #include "nsWindowsHelpers.h" #include <string> using std::wstring; extern "C" __declspec(dllexport) int @@ -25,43 +28,51 @@ ReturnResultHook() { if (gOrigReturnResult() != 2) { return 3; } return 0; } -int ParentMain() +int ParentMain(int argc, wchar_t* argv[]) { + mozilla::SetArgv0ToFullBinaryPath(argv); + // We'll add the child process to a job so that, in the event of a failure in // this parent process, the child process will be automatically terminated. nsAutoHandle job(::CreateJobObject(nullptr, nullptr)); if (!job) { printf("TEST-UNEXPECTED-FAIL | DllInterceptorCrossProcess | Job creation failed\n"); return 1; } - JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobInfo{}; + JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobInfo = {}; jobInfo.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; if (!::SetInformationJobObject(job.get(), JobObjectExtendedLimitInformation, &jobInfo, sizeof(jobInfo))) { printf("TEST-UNEXPECTED-FAIL | DllInterceptorCrossProcess | Job config failed\n"); return 1; } - wstring cmdLine(::GetCommandLineW()); - cmdLine += L" -child"; + wchar_t childArgv_1[] = L"-child"; + + wchar_t* childArgv[] = { + argv[0], + childArgv_1 + }; + + mozilla::UniquePtr<wchar_t[]> + cmdLine(mozilla::MakeCommandLine(mozilla::ArrayLength(childArgv), childArgv)); STARTUPINFOW si = { sizeof(si) }; PROCESS_INFORMATION pi; - if (!::CreateProcessW(nullptr, const_cast<LPWSTR>(cmdLine.c_str()), nullptr, - nullptr, FALSE, CREATE_SUSPENDED, nullptr, nullptr, &si, - &pi)) { + if (!::CreateProcessW(argv[0], cmdLine.get(), nullptr, nullptr, FALSE, + CREATE_SUSPENDED, nullptr, nullptr, &si, &pi)) { printf("TEST-UNEXPECTED-FAIL | DllInterceptorCrossProcess | Failed to spawn child process\n"); return 1; } nsAutoHandle childProcess(pi.hProcess); nsAutoHandle childMainThread(pi.hThread); if (!::AssignProcessToJobObject(job.get(), childProcess.get())) { @@ -109,17 +120,23 @@ int ParentMain() printf("TEST-UNEXPECTED-FAIL | DllInterceptorCrossProcess | Child process exit code is %lu instead of 0\n", childExitCode); return 1; } printf("TEST-PASS | DllInterceptorCrossProcess | Child process exit code is zero\n"); return 0; } -int main(int argc, char* argv[]) +extern "C" +int wmain(int argc, wchar_t* argv[]) { if (argc > 1) { - return ReturnResult(); + // clang keeps inlining this call despite every attempt to force it to do + // otherwise. We'll use GetProcAddress and call its function pointer instead. + auto pReturnResult = + reinterpret_cast<decltype(&ReturnResult)>( + ::GetProcAddress(::GetModuleHandleW(nullptr), "ReturnResult")); + return pReturnResult(); } - return ParentMain(); + return ParentMain(argc, argv); }
--- a/mozglue/tests/interceptor/moz.build +++ b/mozglue/tests/interceptor/moz.build @@ -10,8 +10,14 @@ GeckoCppUnitTests( 'TestDllInterceptorCrossProcess', ], linkage=None ) OS_LIBS += [ 'ole32', ] + +if CONFIG['OS_TARGET'] == 'WINNT' and CONFIG['CC_TYPE'] == 'gcc': + # This allows us to use wmain as the entry point on mingw + LDFLAGS += [ + '-municode', + ]
--- a/nsprpub/config/prdepend.h +++ b/nsprpub/config/prdepend.h @@ -5,9 +5,8 @@ /* * A dummy header file that is a dependency for all the object files. * Used to force a full recompilation of NSPR in Mozilla's Tinderbox * depend builds. See comments in rules.mk. */ #error "Do not include this header file." -
--- a/nsprpub/configure +++ b/nsprpub/configure @@ -2483,17 +2483,17 @@ case $target_os in *\ *) target_os=`echo # The aliases save the names the user supplied, while $host etc. # will get canonicalized. test -n "$target_alias" && test "$program_prefix$program_suffix$program_transform_name" = \ NONENONEs,x,x, && program_prefix=${target_alias}- MOD_MAJOR_VERSION=4 -MOD_MINOR_VERSION=19 +MOD_MINOR_VERSION=20 MOD_PATCH_VERSION=0 NSPR_MODNAME=nspr20 _HAVE_PTHREADS= USE_PTHREADS= USE_USER_PTHREADS= USE_NSPR_THREADS= USE_N32= USE_X32=
--- a/nsprpub/configure.in +++ b/nsprpub/configure.in @@ -10,17 +10,17 @@ AC_CONFIG_SRCDIR([pr/include/nspr.h]) AC_CONFIG_AUX_DIR(${srcdir}/build/autoconf) AC_CANONICAL_TARGET dnl ======================================================== dnl = Defaults dnl ======================================================== MOD_MAJOR_VERSION=4 -MOD_MINOR_VERSION=19 +MOD_MINOR_VERSION=20 MOD_PATCH_VERSION=0 NSPR_MODNAME=nspr20 _HAVE_PTHREADS= USE_PTHREADS= USE_USER_PTHREADS= USE_NSPR_THREADS= USE_N32= USE_X32=
--- a/nsprpub/pr/include/md/_linux.cfg +++ b/nsprpub/pr/include/md/_linux.cfg @@ -1015,16 +1015,108 @@ #define PR_ALIGN_OF_FLOAT 4 #define PR_ALIGN_OF_DOUBLE 4 #define PR_ALIGN_OF_POINTER 4 #define PR_ALIGN_OF_WORD 4 #define PR_BYTES_PER_WORD_LOG2 2 #define PR_BYTES_PER_DWORD_LOG2 3 +#elif defined(__riscv) && (__riscv_xlen == 32) + +#undef IS_BIG_ENDIAN +#define IS_LITTLE_ENDIAN 1 +#undef IS_64 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 4 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 4 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 32 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 32 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 5 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 5 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 4 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 4 +#define PR_ALIGN_OF_WORD 4 + +#define PR_BYTES_PER_WORD_LOG2 2 +#define PR_BYTES_PER_DWORD_LOG2 3 + +#elif defined(__riscv) && (__riscv_xlen == 64) + +#undef IS_BIG_ENDIAN +#define IS_LITTLE_ENDIAN 1 +#define IS_64 + +#define PR_BYTES_PER_BYTE 1 +#define PR_BYTES_PER_SHORT 2 +#define PR_BYTES_PER_INT 4 +#define PR_BYTES_PER_INT64 8 +#define PR_BYTES_PER_LONG 8 +#define PR_BYTES_PER_FLOAT 4 +#define PR_BYTES_PER_DOUBLE 8 +#define PR_BYTES_PER_WORD 8 +#define PR_BYTES_PER_DWORD 8 + +#define PR_BITS_PER_BYTE 8 +#define PR_BITS_PER_SHORT 16 +#define PR_BITS_PER_INT 32 +#define PR_BITS_PER_INT64 64 +#define PR_BITS_PER_LONG 64 +#define PR_BITS_PER_FLOAT 32 +#define PR_BITS_PER_DOUBLE 64 +#define PR_BITS_PER_WORD 64 + +#define PR_BITS_PER_BYTE_LOG2 3 +#define PR_BITS_PER_SHORT_LOG2 4 +#define PR_BITS_PER_INT_LOG2 5 +#define PR_BITS_PER_INT64_LOG2 6 +#define PR_BITS_PER_LONG_LOG2 6 +#define PR_BITS_PER_FLOAT_LOG2 5 +#define PR_BITS_PER_DOUBLE_LOG2 6 +#define PR_BITS_PER_WORD_LOG2 6 + +#define PR_ALIGN_OF_SHORT 2 +#define PR_ALIGN_OF_INT 4 +#define PR_ALIGN_OF_LONG 8 +#define PR_ALIGN_OF_INT64 8 +#define PR_ALIGN_OF_FLOAT 4 +#define PR_ALIGN_OF_DOUBLE 8 +#define PR_ALIGN_OF_POINTER 8 +#define PR_ALIGN_OF_WORD 8 + +#define PR_BYTES_PER_WORD_LOG2 3 +#define PR_BYTES_PER_DWORD_LOG2 3 + #else #error "Unknown CPU architecture" #endif #ifndef HAVE_LONG_LONG #define HAVE_LONG_LONG
--- a/nsprpub/pr/include/md/_linux.h +++ b/nsprpub/pr/include/md/_linux.h @@ -52,16 +52,20 @@ #elif defined(__sh__) #define _PR_SI_ARCHITECTURE "sh" #elif defined(__avr32__) #define _PR_SI_ARCHITECTURE "avr32" #elif defined(__m32r__) #define _PR_SI_ARCHITECTURE "m32r" #elif defined(__or1k__) #define _PR_SI_ARCHITECTURE "or1k" +#elif defined(__riscv) && (__riscv_xlen == 32) +#define _PR_SI_ARCHITECTURE "riscv32" +#elif defined(__riscv) && (__riscv_xlen == 64) +#define _PR_SI_ARCHITECTURE "riscv64" #else #error "Unknown CPU architecture" #endif #define PR_DLL_SUFFIX ".so" #define _PR_VMBASE 0x30000000 #define _PR_STACK_VMBASE 0x50000000 #define _MD_DEFAULT_STACK_SIZE 65536L
--- a/nsprpub/pr/include/prinit.h +++ b/nsprpub/pr/include/prinit.h @@ -26,21 +26,21 @@ PR_BEGIN_EXTERN_C /* ** NSPR's version is used to determine the likelihood that the version you ** used to build your component is anywhere close to being compatible with ** what is in the underlying library. ** ** The format of the version string is ** "<major version>.<minor version>[.<patch level>] [<Beta>]" */ -#define PR_VERSION "4.19" +#define PR_VERSION "4.20 Beta" #define PR_VMAJOR 4 -#define PR_VMINOR 19 +#define PR_VMINOR 20 #define PR_VPATCH 0 -#define PR_BETA PR_FALSE +#define PR_BETA PR_TRUE /* ** PRVersionCheck ** ** The basic signature of the function that is called to provide version ** checking. The result will be a boolean that indicates the likelihood ** that the underling library will perform as the caller expects. **
--- a/nsprpub/pr/src/misc/prnetdb.c +++ b/nsprpub/pr/src/misc/prnetdb.c @@ -2,16 +2,20 @@ /* 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 "primpl.h" #include <string.h> +#if defined(LINUX) +#include <sys/un.h> +#endif + /* * On Unix, the error code for gethostbyname() and gethostbyaddr() * is returned in the global variable h_errno, instead of the usual * errno. */ #if defined(XP_UNIX) #if defined(_PR_NEED_H_ERRNO) extern int h_errno; @@ -1361,17 +1365,27 @@ PRUintn _PR_NetAddrSize(const PRNetAddr* else if (PR_AF_INET6 == addr->raw.family) #if defined(_PR_INET6) addrsize = sizeof(struct sockaddr_in6); #else addrsize = sizeof(addr->ipv6); #endif #if defined(XP_UNIX) || defined(XP_OS2) else if (AF_UNIX == addr->raw.family) - addrsize = sizeof(addr->local); + { +#if defined(LINUX) + if (addr->local.path[0] == 0) + /* abstract socket address is supported on Linux only */ + addrsize = strnlen(addr->local.path + 1, + sizeof(addr->local.path)) + + offsetof(struct sockaddr_un, sun_path) + 1; + else +#endif + addrsize = sizeof(addr->local); + } #endif else addrsize = 0; return addrsize; } /* _PR_NetAddrSize */ PR_IMPLEMENT(PRIntn) PR_EnumerateHostEnt( PRIntn enumIndex, const PRHostEnt *hostEnt, PRUint16 port, PRNetAddr *address)
--- a/nsprpub/pr/src/pthreads/ptio.c +++ b/nsprpub/pr/src/pthreads/ptio.c @@ -1745,17 +1745,22 @@ static PRStatus pt_Bind(PRFileDesc *fd, #endif if (pt_TestAbort()) return PR_FAILURE; PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE); if (addr->raw.family == AF_UNIX) { /* Disallow relative pathnames */ - if (addr->local.path[0] != '/') + if (addr->local.path[0] != '/' +#if defined(LINUX) + /* Linux has abstract socket address support */ + && addr->local.path[0] != 0 +#endif + ) { PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); return PR_FAILURE; } } #ifdef _PR_INET6 if (addr->raw.family == PR_AF_INET6) {
--- a/nsprpub/pr/src/pthreads/ptsynch.c +++ b/nsprpub/pr/src/pthreads/ptsynch.c @@ -906,17 +906,18 @@ PR_IMPLEMENT(PRStatus) PR_DeleteSemaphor #include <fcntl.h> #include <sys/sem.h> /* * From the semctl(2) man page in glibc 2.0 */ #if (defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)) \ - || defined(FREEBSD) || defined(OPENBSD) || defined(BSDI) \ + || (defined(FREEBSD) && __FreeBSD_version < 1200059) \ + || defined(OPENBSD) || defined(BSDI) \ || defined(DARWIN) || defined(SYMBIAN) /* union semun is defined by including <sys/sem.h> */ #else /* according to X/OPEN we have to define it ourselves */ union semun { int val; struct semid_ds *buf; unsigned short *array;
--- a/nsprpub/pr/tests/Makefile.in +++ b/nsprpub/pr/tests/Makefile.in @@ -13,16 +13,17 @@ VPATH = @srcdir@ include $(MOD_DEPTH)/config/autoconf.mk include $(topsrcdir)/config/config.mk DIRS = dll CSRCS = \ + abstract.c \ accept.c \ acceptread.c \ acceptreademu.c \ addrstr.c \ affinity.c \ alarm.c \ anonfm.c \ append.c \
new file mode 100755 --- /dev/null +++ b/nsprpub/pr/tests/abstract.c @@ -0,0 +1,157 @@ +/* -*- Mode: C++; tab-width: 4; 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/. */ + +#include <stdio.h> + +#if defined(LINUX) + +#include <string.h> +#include "nspr.h" + +static const char abstractSocketName[] = "\0testsocket"; + +static void +ClientThread(void* aArg) +{ + PRFileDesc* socket; + PRNetAddr addr; + PRUint8 buf[1024]; + PRInt32 len; + PRInt32 total; + + addr.local.family = PR_AF_LOCAL; + memcpy(addr.local.path, abstractSocketName, sizeof(abstractSocketName)); + + socket = PR_OpenTCPSocket(addr.raw.family); + if (!socket) { + fprintf(stderr, "PR_OpenTCPSokcet failed\n"); + exit(1); + } + + if (PR_Connect(socket, &addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) { + fprintf(stderr, "PR_Connect failed\n"); + exit(1); + } + + total = 0; + while (total < sizeof(buf)) { + len = PR_Recv(socket, buf + total, sizeof(buf) - total, 0, + PR_INTERVAL_NO_TIMEOUT); + if (len < 1) { + fprintf(stderr, "PR_Recv failed\n"); + exit(1); + } + total += len; + } + + total = 0; + while (total < sizeof(buf)) { + len = PR_Send(socket, buf + total, sizeof(buf) - total, 0, + PR_INTERVAL_NO_TIMEOUT); + if (len < 1) { + fprintf(stderr, "PR_Send failed\n"); + exit(1); + } + total += len; + } + + if (PR_Close(socket) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } +} + +int +main() +{ + PRFileDesc* socket; + PRFileDesc* acceptSocket; + PRThread* thread; + PRNetAddr addr; + PRUint8 buf[1024]; + PRInt32 len; + PRInt32 total; + + addr.local.family = PR_AF_LOCAL; + memcpy(addr.local.path, abstractSocketName, sizeof(abstractSocketName)); + + socket = PR_OpenTCPSocket(addr.raw.family); + if (!socket) { + fprintf(stderr, "PR_OpenTCPSocket failed\n"); + exit(1); + } + if (PR_Bind(socket, &addr) == PR_FAILURE) { + fprintf(stderr, "PR_Bind failed\n"); + exit(1); + } + + if (PR_Listen(socket, 5) == PR_FAILURE) { + fprintf(stderr, "PR_Listen failed\n"); + exit(1); + } + + thread = PR_CreateThread(PR_USER_THREAD, ClientThread, 0, PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); + if (!thread) { + fprintf(stderr, "PR_CreateThread failed"); + exit(1); + } + + acceptSocket = PR_Accept(socket, NULL, PR_INTERVAL_NO_TIMEOUT); + if (!acceptSocket) { + fprintf(stderr, "PR_Accept failed\n"); + exit(1); + } + + memset(buf, 'A', sizeof(buf)); + + total = 0; + while (total < sizeof(buf)) { + len = PR_Send(acceptSocket, buf + total, sizeof(buf) - total, 0, + PR_INTERVAL_NO_TIMEOUT); + if (len < 1) { + fprintf(stderr, "PR_Send failed\n"); + exit(1); + } + total += len; + } + + total = 0; + while (total < sizeof(buf)) { + len = PR_Recv(acceptSocket, buf + total, sizeof(buf) - total, 0, + PR_INTERVAL_NO_TIMEOUT); + if (len < 1) { + fprintf(stderr, "PR_Recv failed\n"); + exit(1); + } + total += len; + } + + if (PR_Close(acceptSocket) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + + if (PR_JoinThread(thread) == PR_FAILURE) { + fprintf(stderr, "PR_JoinThread failed\n"); + exit(1); + } + + if (PR_Close(socket) == PR_FAILURE) { + fprintf(stderr, "PR_Close failed\n"); + exit(1); + } + printf("PASS\n"); + return 0; +} + +#else +int +main() +{ + prinf("PASS\n"); + return 0; +} +#endif
--- a/nsprpub/pr/tests/runtests.pl +++ b/nsprpub/pr/tests/runtests.pl @@ -236,16 +236,17 @@ sub win_test_prog { # There is no signal, no core on Windows print_end($prog, $status, 0, 0); return $status } # MAIN --------------- @progs = ( +"abstract", "accept", "acceptread", "acceptreademu", "affinity", "alarm", "anonfm", "atomic", "attach",
--- a/nsprpub/pr/tests/runtests.sh +++ b/nsprpub/pr/tests/runtests.sh @@ -66,16 +66,17 @@ fi LOGFILE=${NSPR_TEST_LOGFILE:-$NULL_DEVICE} # # Tests run on all platforms # TESTS=" +abstract accept acceptread acceptreademu affinity alarm anonfm atomic attach
--- a/nsprpub/pr/tests/vercheck.c +++ b/nsprpub/pr/tests/vercheck.c @@ -35,34 +35,34 @@ static char *compatible_version[] = { "4.7.6", "4.8", "4.8.1", "4.8.2", "4.8.3", "4.8.4", "4.8.5", "4.8.6", "4.8.7", "4.8.8", "4.8.9", "4.9", "4.9.1", "4.9.2", "4.9.3", "4.9.4", "4.9.5", "4.9.6", "4.10", "4.10.1", "4.10.2", "4.10.3", "4.10.4", "4.10.5", "4.10.6", "4.10.7", "4.10.8", "4.10.9", "4.10.10", "4.11", "4.12", "4.13", "4.14", "4.15", - "4.16", "4.17", "4.18", + "4.16", "4.17", "4.18", "4.19", PR_VERSION }; /* * This release is not backward compatible with the old * NSPR 2.1 and 3.x releases. * * Any release is incompatible with future releases and * patches. */ static char *incompatible_version[] = { "2.1 19980529", "3.0", "3.0.1", "3.1", "3.1.1", "3.1.2", "3.1.3", "3.5", "3.5.1", - "4.19.1", - "4.20", "4.20.1", + "4.20.1", + "4.21", "4.21.1", "10.0", "11.1", "12.14.20" }; int main(int argc, char **argv) { int idx; int num_compatible = sizeof(compatible_version) / sizeof(char *); int num_incompatible = sizeof(incompatible_version) / sizeof(char *);
--- a/servo/components/style/values/specified/box.rs +++ b/servo/components/style/values/specified/box.rs @@ -25,16 +25,27 @@ fn moz_display_values_enabled(context: & use stylesheets::Origin; context.stylesheet_origin == Origin::UserAgent || context.chrome_rules_enabled() || unsafe { structs::StaticPrefs_sVarCache_layout_css_xul_display_values_content_enabled } } +#[cfg(feature = "gecko")] +fn moz_box_display_values_enabled(context: &ParserContext) -> bool { + use gecko_bindings::structs; + use stylesheets::Origin; + context.stylesheet_origin == Origin::UserAgent || + context.chrome_rules_enabled() || + unsafe { + structs::StaticPrefs_sVarCache_layout_css_xul_box_display_values_content_enabled + } +} + #[allow(missing_docs)] #[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)] #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] /// Defines an element’s display type, which consists of /// the two basic qualities of how an element generates boxes /// <https://drafts.csswg.org/css-display/#propdef-display> pub enum Display { @@ -75,18 +86,20 @@ pub enum Display { Contents, #[cfg(feature = "gecko")] FlowRoot, #[cfg(feature = "gecko")] WebkitBox, #[cfg(feature = "gecko")] WebkitInlineBox, #[cfg(feature = "gecko")] + #[parse(condition = "moz_box_display_values_enabled")] MozBox, #[cfg(feature = "gecko")] + #[parse(condition = "moz_box_display_values_enabled")] MozInlineBox, #[cfg(feature = "gecko")] #[parse(condition = "moz_display_values_enabled")] MozGrid, #[cfg(feature = "gecko")] #[parse(condition = "moz_display_values_enabled")] MozInlineGrid, #[cfg(feature = "gecko")]
--- a/testing/marionette/jar.mn +++ b/testing/marionette/jar.mn @@ -41,10 +41,12 @@ marionette.jar: #ifdef ENABLE_TESTS content/test2.xul (chrome/test2.xul) content/test_anonymous_content.xul (chrome/test_anonymous_content.xul) content/test_dialog.dtd (chrome/test_dialog.dtd) content/test_dialog.properties (chrome/test_dialog.properties) content/test_dialog.xul (chrome/test_dialog.xul) content/test_nested_iframe.xul (chrome/test_nested_iframe.xul) content/test.xul (chrome/test.xul) +#ifdef MOZ_CODE_COVERAGE content/PerTestCoverageUtils.jsm (../../tools/code-coverage/PerTestCoverageUtils.jsm) #endif +#endif
--- a/testing/mozharness/scripts/merge_day/gecko_migration.py +++ b/testing/mozharness/scripts/merge_day/gecko_migration.py @@ -42,16 +42,23 @@ class GeckoMigration(MercurialScript, Ba config_options = [ [['--hg-user', ], { "action": "store", "dest": "hg_user", "type": "string", "default": "ffxbld <release@mozilla.com>", "help": "Specify what user to use to commit to hg.", }], + [['--ssh-user', ], { + "action": "store", + "dest": "ssh_user", + "type": "string", + "default": None, + "help": "The user to push to hg.mozilla.org as.", + }], [['--balrog-api-root', ], { "action": "store", "dest": "balrog_api_root", "type": "string", "help": "Specify Balrog API root URL.", }], [['--balrog-username', ], { "action": "store", @@ -186,17 +193,22 @@ class GeckoMigration(MercurialScript, Ba self.config['migration_behavior'] == 'beta_to_release': return ['--new-branch', '-r', '.'] else: return ['-r', '.'] def set_push_to_ssh(self): for cwd in self.query_push_dirs(): repo_url = self.read_repo_hg_rc(cwd).get('paths', 'default') - push_dest = repo_url.replace('https://', 'ssh://') + username = self.config.get('ssh_user', '') + # Add a trailing @ to the username if it exists, otherwise it gets + # mushed up with the hostname. + if username: + username += '@' + push_dest = repo_url.replace('https://', 'ssh://' + username) if not push_dest.startswith('ssh://'): raise Exception('Warning: path "{}" is not supported. Protocol must be ssh') self.edit_repo_hg_rc(cwd, 'paths', 'default-push', push_dest) def query_from_revision(self): """ Shortcut to get the revision for the from repo
--- a/toolkit/components/prompts/content/selectDialog.xul +++ b/toolkit/components/prompts/content/selectDialog.xul @@ -11,12 +11,12 @@ onload="dialogOnLoad()" ondialogaccept="return dialogOK();"> <script type="application/javascript" src="chrome://global/content/selectDialog.js" /> <keyset id="dialogKeys"/> <vbox style="width: 24em;margin: 5px;"> <label id="info.txt"/> <vbox> - <richlistbox id="list" class="theme-listbox" height="80"/> + <richlistbox id="list" class="theme-listbox" style="height: 8em;"/> </vbox> </vbox> </dialog>
--- a/toolkit/content/widgets.css +++ b/toolkit/content/widgets.css @@ -5,18 +5,20 @@ /* ===== widgets.css ===================================================== == Styles ported from XBL <resources>, loaded by "global.css". ======================================================================= */ @import url("chrome://global/content/autocomplete.css"); @import url("chrome://global/skin/autocomplete.css"); @import url("chrome://formautofill-shared/skin/autocomplete-item.css"); @import url("chrome://formautofill/skin/autocomplete-item.css"); +@import url("chrome://global/skin/dialog.css"); @import url("chrome://global/skin/dropmarker.css"); @import url("chrome://global/skin/groupbox.css"); @import url("chrome://global/skin/menu.css"); @import url("chrome://global/skin/menulist.css"); @import url("chrome://global/skin/notification.css"); @import url("chrome://global/skin/popup.css"); +@import url("chrome://global/skin/progressmeter.css"); @import url("chrome://global/skin/richlistbox.css"); @import url("chrome://global/skin/splitter.css"); @import url("chrome://global/skin/toolbar.css"); @import url("chrome://global/skin/wizard.css");
--- a/toolkit/content/widgets/dialog.xml +++ b/toolkit/content/widgets/dialog.xml @@ -9,19 +9,16 @@ ]> <bindings id="dialogBindings" xmlns="http://www.mozilla.org/xbl" xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:xbl="http://www.mozilla.org/xbl"> <binding id="dialog"> - <resources> - <stylesheet src="chrome://global/skin/dialog.css"/> - </resources> <content> <xul:vbox class="box-inherit dialog-content-box" flex="1"> <children/> </xul:vbox> <xul:hbox class="dialog-button-box" anonid="buttons" xbl:inherits="pack=buttonpack,align=buttonalign,dir=buttondir,orient=buttonorient" #ifdef XP_UNIX
--- a/toolkit/content/widgets/progressmeter.xml +++ b/toolkit/content/widgets/progressmeter.xml @@ -5,20 +5,16 @@ <bindings id="progressmeterBindings" xmlns="http://www.mozilla.org/xbl" xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:xbl="http://www.mozilla.org/xbl"> <binding id="progressmeter"> - <resources> - <stylesheet src="chrome://global/skin/progressmeter.css"/> - </resources> - <content> <xul:spacer class="progress-bar" xbl:inherits="mode"/> <xul:spacer class="progress-remainder" xbl:inherits="mode"/> </content> <implementation> <property name="mode" onset="if (this.mode != val) this.setAttribute('mode', val); return val;" onget="return this.getAttribute('mode');"/>
--- a/toolkit/modules/AppConstants.jsm +++ b/toolkit/modules/AppConstants.jsm @@ -314,9 +314,16 @@ this.AppConstants = Object.freeze({ #endif HAVE_SHELL_SERVICE: #ifdef HAVE_SHELL_SERVICE true, #else false, #endif + + MOZ_CODE_COVERAGE: +#ifdef MOZ_CODE_COVERAGE + true, +#else + false, +#endif });
--- a/toolkit/profile/content/profileSelection.js +++ b/toolkit/profile/content/profileSelection.js @@ -132,17 +132,17 @@ function onProfilesKey(aEvent) { break; case KeyEvent.DOM_VK_F2: RenameProfile(); break; } } function onProfilesDblClick(aEvent) { - if (aEvent.target.localName == "listitem") + if (aEvent.target.closest("richlistitem")) document.documentElement.acceptDialog(); } // invoke the createProfile Wizard function CreateProfileWizard() { window.openDialog("chrome://mozapps/content/profile/createProfileWizard.xul", "", "centerscreen,chrome,modal,titlebar", gProfileService); }
--- a/toolkit/profile/content/profileSelection.xul +++ b/toolkit/profile/content/profileSelection.xul @@ -52,17 +52,17 @@ accesskey="&renameButton.accesskey;" oncommand="RenameProfile();"/> <button id="delbutton" label="&deleteButton.label;" accesskey="&deleteButton.accesskey;" oncommand="ConfirmDelete();"/> </vbox> <separator flex="1"/> <vbox flex="1"> - <richlistbox id="profiles" class="theme-listbox" height="100" seltype="single" + <richlistbox id="profiles" class="theme-listbox" seltype="single" ondblclick="onProfilesDblClick(event)" onkeypress="onProfilesKey(event);"> </richlistbox> <!-- Bug 257777 --> <checkbox id="offlineState" label="&offlineState.label;" accesskey="&offlineState.accesskey;"/> <checkbox id="autoSelectLastProfile" label="&useSelected.label;"
--- a/toolkit/themes/osx/mozapps/profile/profileSelection.css +++ b/toolkit/themes/osx/mozapps/profile/profileSelection.css @@ -9,8 +9,12 @@ box#managebuttons > button { min-width: 8em; } #managebuttons { padding-top: 1em; } + +#profiles { + height: 12em; +}
--- a/toolkit/themes/windows/mozapps/profile/profileSelection.css +++ b/toolkit/themes/windows/mozapps/profile/profileSelection.css @@ -9,8 +9,12 @@ box#managebuttons > button { min-width: 8em; } #managebuttons { padding-top: 1em; } + +#profiles { + height: 12em; +}
--- a/toolkit/xre/CmdLineAndEnvUtils.h +++ b/toolkit/xre/CmdLineAndEnvUtils.h @@ -18,18 +18,20 @@ #endif #if defined(XP_WIN) #include "mozilla/Move.h" #include "mozilla/UniquePtr.h" #include "mozilla/Vector.h" #include <wchar.h> +#include <windows.h> #endif // defined(XP_WIN) +#include "mozilla/MemoryChecking.h" #include "mozilla/TypedEnumBits.h" #include <ctype.h> #include <stdint.h> // Undo X11/X.h's definition of None #undef None @@ -342,16 +344,58 @@ MakeCommandLine(int argc, wchar_t **argv } } *c = '\0'; return std::move(s); } +inline bool +SetArgv0ToFullBinaryPath(wchar_t* aArgv[]) +{ + if (!aArgv) { + return false; + } + + DWORD bufLen = MAX_PATH; + mozilla::UniquePtr<wchar_t[]> buf; + DWORD retLen; + + while (true) { + buf = mozilla::MakeUnique<wchar_t[]>(bufLen); + retLen = ::GetModuleFileNameW(nullptr, buf.get(), bufLen); + if (!retLen) { + return false; + } + + if (retLen == bufLen && ::GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + bufLen *= 2; + continue; + } + + break; + } + + // Upon success, retLen *excludes* the null character + ++retLen; + + // Since we're likely to have a bunch of unused space in buf, let's reallocate + // a string to the actual size of the file name. + auto newArgv_0 = mozilla::MakeUnique<wchar_t[]>(retLen); + if (wcscpy_s(newArgv_0.get(), retLen, buf.get())) { + return false; + } + + // We intentionally leak newArgv_0 into argv[0] + aArgv[0] = newArgv_0.release(); + MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(aArgv[0]); + return true; +} + #endif // defined(XP_WIN) // Save literal putenv string to environment variable. inline void SaveToEnv(const char *aEnvString) { #if defined(MOZILLA_INTERNAL_API) char *expr = strdup(aEnvString);
--- a/xpcom/ds/PLDHashTable.cpp +++ b/xpcom/ds/PLDHashTable.cpp @@ -496,21 +496,21 @@ PLDHashTable::ChangeTable(int32_t aDelta mEntryStore.Set(newEntryStore, &mGeneration); PLDHashMoveEntry moveEntry = mOps->moveEntry; // Copy only live entries, leaving removed ones behind. uint32_t oldCapacity = 1u << oldLog2; for (uint32_t i = 0; i < oldCapacity; ++i) { PLDHashEntryHdr* oldEntry = (PLDHashEntryHdr*)oldEntryAddr; if (EntryIsLive(oldEntry)) { - oldEntry->mKeyHash &= ~kCollisionFlag; - PLDHashEntryHdr* newEntry = FindFreeEntry(oldEntry->mKeyHash); + const PLDHashNumber key = oldEntry->mKeyHash & ~kCollisionFlag; + PLDHashEntryHdr* newEntry = FindFreeEntry(key); NS_ASSERTION(EntryIsFree(newEntry), "EntryIsFree(newEntry)"); moveEntry(this, oldEntry, newEntry); - newEntry->mKeyHash = oldEntry->mKeyHash; + newEntry->mKeyHash = key; } oldEntryAddr += mEntrySize; } free(oldEntryStore); return true; }