diff --git a/accessible/aom/AccessibleNode.cpp b/accessible/aom/AccessibleNode.cpp index 2fb7583c8925..90d8b69341c0 100644 --- a/accessible/aom/AccessibleNode.cpp +++ b/accessible/aom/AccessibleNode.cpp @@ -30,8 +30,12 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(AccessibleNode) AccessibleNode::AccessibleNode(nsINode* aNode) : mDOMNode(aNode) { - DocAccessible* doc = - GetOrCreateAccService()->GetDocAccessible(mDOMNode->OwnerDoc()); + nsAccessibilityService* accService = GetOrCreateAccService(); + if (!accService) { + return; + } + + DocAccessible* doc = accService->GetDocAccessible(mDOMNode->OwnerDoc()); if (doc) { mIntl = doc->GetAccessible(mDOMNode); } @@ -57,8 +61,11 @@ void AccessibleNode::GetRole(nsAString& aRole) { if (mIntl) { - GetOrCreateAccService()->GetStringRole(mIntl->Role(), aRole); - return; + nsAccessibilityService* accService = GetOrCreateAccService(); + if (accService) { + accService->GetStringRole(mIntl->Role(), aRole); + return; + } } aRole.AssignLiteral("unknown"); @@ -67,15 +74,19 @@ AccessibleNode::GetRole(nsAString& aRole) void AccessibleNode::GetStates(nsTArray& aStates) { - if (mIntl) { - if (!mStates) { - mStates = GetOrCreateAccService()->GetStringStates(mIntl->State()); - } + nsAccessibilityService* accService = GetOrCreateAccService(); + if (!mIntl || !accService) { + aStates.AppendElement(NS_LITERAL_STRING("defunct")); + return; + } + + if (mStates) { aStates = mStates->StringArray(); return; } - aStates.AppendElement(NS_LITERAL_STRING("defunct")); + mStates = accService->GetStringStates(mIntl->State()); + aStates = mStates->StringArray(); } void @@ -106,7 +117,8 @@ AccessibleNode::GetAttributes(nsTArray& aAttributes) bool AccessibleNode::Is(const Sequence& aFlavors) { - if (!mIntl) { + nsAccessibilityService* accService = GetOrCreateAccService(); + if (!mIntl || !accService) { for (const auto& flavor : aFlavors) { if (!flavor.EqualsLiteral("unknown") && !flavor.EqualsLiteral("defunct")) { return false; @@ -116,10 +128,10 @@ AccessibleNode::Is(const Sequence& aFlavors) } nsAutoString role; - GetOrCreateAccService()->GetStringRole(mIntl->Role(), role); + accService->GetStringRole(mIntl->Role(), role); if (!mStates) { - mStates = GetOrCreateAccService()->GetStringStates(mIntl->State()); + mStates = accService->GetStringStates(mIntl->State()); } for (const auto& flavor : aFlavors) { diff --git a/accessible/base/nsAccessibilityService.cpp b/accessible/base/nsAccessibilityService.cpp index 1cf33f196744..97dc6e7fa341 100644 --- a/accessible/base/nsAccessibilityService.cpp +++ b/accessible/base/nsAccessibilityService.cpp @@ -1904,6 +1904,11 @@ nsAccessibilityService::NotifyOfConsumersChange() nsAccessibilityService* GetOrCreateAccService(uint32_t aNewConsumer) { + // Do not initialize accessibility if it is force disabled. + if (PlatformDisabledState() == ePlatformIsDisabled) { + return nullptr; + } + if (!nsAccessibilityService::gAccessibilityService) { RefPtr service = new nsAccessibilityService(); if (!service->Init()) { diff --git a/accessible/xpcom/xpcAccessibilityService.cpp b/accessible/xpcom/xpcAccessibilityService.cpp index 2606d4b366cb..35fee520c685 100644 --- a/accessible/xpcom/xpcAccessibilityService.cpp +++ b/accessible/xpcom/xpcAccessibilityService.cpp @@ -46,7 +46,7 @@ xpcAccessibilityService::AddRef(void) // We want refcount to be > 1 because one reference is added in the XPCOM // accessibility service getter. - if (mRefCnt > 1 && PlatformDisabledState() != ePlatformIsDisabled) { + if (mRefCnt > 1) { GetOrCreateAccService(nsAccessibilityService::eXPCOM); } @@ -280,13 +280,10 @@ NS_GetAccessibilityService(nsIAccessibilityService** aResult) NS_ENSURE_TRUE(aResult, NS_ERROR_NULL_POINTER); *aResult = nullptr; - // Do not initialize accessibility if it is force disabled. - if (PlatformDisabledState() == ePlatformIsDisabled) { + if (!GetOrCreateAccService(nsAccessibilityService::eXPCOM)) { return NS_ERROR_SERVICE_NOT_AVAILABLE; } - GetOrCreateAccService(nsAccessibilityService::eXPCOM); - xpcAccessibilityService* service = new xpcAccessibilityService(); NS_ENSURE_TRUE(service, NS_ERROR_OUT_OF_MEMORY); xpcAccessibilityService::gXPCAccessibilityService = service; diff --git a/browser/components/preferences/in-content/tests/browser_subdialogs.js b/browser/components/preferences/in-content/tests/browser_subdialogs.js index a5994fa3d175..5aa0d2ba400a 100644 --- a/browser/components/preferences/in-content/tests/browser_subdialogs.js +++ b/browser/components/preferences/in-content/tests/browser_subdialogs.js @@ -297,7 +297,9 @@ add_task(async function wrapped_text_in_dialog_should_have_expected_scrollHeight Assert.ok(docEl.scrollHeight > contentOldHeight, "Content height increased (from " + contentOldHeight + " to " + docEl.scrollHeight + ")."); Assert.equal(frame.style.height, docEl.scrollHeight + "px", - "Height on the frame should be higher now"); + "Height on the frame should be higher now. " + + "This test may fail on certain screen resoluition. " + + "See bug 1420576 and bug 1205717."); }); await close_subdialog_and_test_generic_end_state(tab.linkedBrowser, diff --git a/browser/modules/test/browser/browser_urlBar_zoom.js b/browser/modules/test/browser/browser_urlBar_zoom.js index e9118e24fa30..050ab5f7d8e1 100644 --- a/browser/modules/test/browser/browser_urlBar_zoom.js +++ b/browser/modules/test/browser/browser_urlBar_zoom.js @@ -8,6 +8,8 @@ var initialPageZoom = ZoomManager.zoom; const kTimeoutInMS = 20000; async function testZoomButtonAppearsAndDisappearsBasedOnZoomChanges(zoomEventType) { + let tab = await BrowserTestUtils.openNewForegroundTab({ gBrowser, waitForStateStop: true }); + info("Running this test with " + zoomEventType.substring(0, 9)); info("Confirm whether the browser zoom is set to the default level"); is(initialPageZoom, 1, "Page zoom is set to default (100%)"); @@ -32,6 +34,8 @@ async function testZoomButtonAppearsAndDisappearsBasedOnZoomChanges(zoomEventTyp expectedZoomLevel = 100; is(pageZoomLevel, expectedZoomLevel, "Clicking zoom button successfully resets browser zoom to 100%"); is(zoomResetButton.hidden, true, "Zoom reset button returns to being hidden"); + + await BrowserTestUtils.removeTab(tab); } add_task(async function() { diff --git a/devtools/client/debugger/test/mochitest/browser_dbg_parser-03.js b/devtools/client/debugger/test/mochitest/browser_dbg_parser-03.js index 439df705b4eb..76c3bfc9ebc2 100644 --- a/devtools/client/debugger/test/mochitest/browser_dbg_parser-03.js +++ b/devtools/client/debugger/test/mochitest/browser_dbg_parser-03.js @@ -19,7 +19,7 @@ function test() { "", - "", "" @@ -44,14 +44,14 @@ function test() { "The first script was located correctly."); is(parsed.getScriptInfo(source.indexOf("let b")).toSource(), "({start:85, length:13, index:1})", "The second script was located correctly."); - is(parsed.getScriptInfo(source.indexOf("let c")).toSource(), "({start:151, length:13, index:2})", + is(parsed.getScriptInfo(source.indexOf("let c")).toSource(), "({start:139, length:13, index:2})", "The third script was located correctly."); is(parsed.getScriptInfo(source.indexOf("let a") - 1).toSource(), "({start:31, length:13, index:0})", "The left edge of the first script was interpreted correctly."); is(parsed.getScriptInfo(source.indexOf("let b") - 1).toSource(), "({start:85, length:13, index:1})", "The left edge of the second script was interpreted correctly."); - is(parsed.getScriptInfo(source.indexOf("let c") - 1).toSource(), "({start:151, length:13, index:2})", + is(parsed.getScriptInfo(source.indexOf("let c") - 1).toSource(), "({start:139, length:13, index:2})", "The left edge of the third script was interpreted correctly."); is(parsed.getScriptInfo(source.indexOf("let a") - 2).toSource(), "({start:-1, length:-1, index:-1})", @@ -65,7 +65,7 @@ function test() { "The right edge of the first script was interpreted correctly."); is(parsed.getScriptInfo(source.indexOf("let b") + 12).toSource(), "({start:85, length:13, index:1})", "The right edge of the second script was interpreted correctly."); - is(parsed.getScriptInfo(source.indexOf("let c") + 12).toSource(), "({start:151, length:13, index:2})", + is(parsed.getScriptInfo(source.indexOf("let c") + 12).toSource(), "({start:139, length:13, index:2})", "The right edge of the third script was interpreted correctly."); is(parsed.getScriptInfo(source.indexOf("let a") + 13).toSource(), "({start:-1, length:-1, index:-1})", diff --git a/devtools/client/debugger/test/mochitest/browser_dbg_parser-05.js b/devtools/client/debugger/test/mochitest/browser_dbg_parser-05.js index b34d3952a0de..e8937450beff 100644 --- a/devtools/client/debugger/test/mochitest/browser_dbg_parser-05.js +++ b/devtools/client/debugger/test/mochitest/browser_dbg_parser-05.js @@ -19,7 +19,7 @@ function test() { "a.push('');", - "a.push('');" ].join("\n"); @@ -34,11 +34,11 @@ function test() { is(parsed.scriptCount, 1, "There should be 1 script parsed in the parent source."); - is(parsed.getScriptInfo(source.indexOf("let a")).toSource(), "({start:0, length:261, index:0})", + is(parsed.getScriptInfo(source.indexOf("let a")).toSource(), "({start:0, length:249, index:0})", "The script location is correct (1)."); - is(parsed.getScriptInfo(source.indexOf("")).toSource(), "({start:0, length:261, index:0})", + is(parsed.getScriptInfo(source.indexOf("")).toSource(), "({start:0, length:249, index:0})", "The script location is correct (3)."); finish(); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg_parser-11.js b/devtools/client/debugger/test/mochitest/browser_dbg_parser-11.js index ee2b4c89d32c..660f93700ebf 100644 --- a/devtools/client/debugger/test/mochitest/browser_dbg_parser-11.js +++ b/devtools/client/debugger/test/mochitest/browser_dbg_parser-11.js @@ -12,7 +12,7 @@ function test() { let source = [ '', @@ -34,7 +34,7 @@ function test() { is(parsed.getScriptInfo(source.indexOf("hello third!")).toSource(), "({start:-1, length:-1, index:-1})", "Inline script on self-closing tag not considered a script"); - is(parsed.getScriptInfo(source.indexOf("hello fourth")).toSource(), "({start:267, length:14, index:4})", + is(parsed.getScriptInfo(source.indexOf("hello fourth")).toSource(), "({start:255, length:14, index:4})", "The fourth script was located correctly."); finish(); diff --git a/devtools/client/webconsole/new-console-output/test/mochitest/test-bug-632347-iterators-generators.html b/devtools/client/webconsole/new-console-output/test/mochitest/test-bug-632347-iterators-generators.html index 2209e519dffe..b9c4a54c2531 100644 --- a/devtools/client/webconsole/new-console-output/test/mochitest/test-bug-632347-iterators-generators.html +++ b/devtools/client/webconsole/new-console-output/test/mochitest/test-bug-632347-iterators-generators.html @@ -5,7 +5,7 @@ Web Console test for bug 632347 - generators - + + + + + + +

W3C Web Authentication - Authenticator Selection Criteria

+ Mozilla Bug 1406462 + + + + + diff --git a/dom/webauthn/u2f-hid-rs/Cargo.toml b/dom/webauthn/u2f-hid-rs/Cargo.toml index 5d52318e7a2b..6f05213d7dfb 100644 --- a/dom/webauthn/u2f-hid-rs/Cargo.toml +++ b/dom/webauthn/u2f-hid-rs/Cargo.toml @@ -19,6 +19,7 @@ env_logger = "0.4.1" libc = "^0.2" boxfnonce = "0.0.3" runloop = "0.1.0" +bitflags = "1.0" [dev-dependencies] rust-crypto = "^0.2" diff --git a/dom/webauthn/u2f-hid-rs/examples/main.rs b/dom/webauthn/u2f-hid-rs/examples/main.rs index c6ab61bb68f5..2210d04ad95e 100644 --- a/dom/webauthn/u2f-hid-rs/examples/main.rs +++ b/dom/webauthn/u2f-hid-rs/examples/main.rs @@ -9,7 +9,7 @@ use crypto::digest::Digest; use crypto::sha2::Sha256; use std::io; use std::sync::mpsc::channel; -use u2fhid::U2FManager; +use u2fhid::{RegisterFlags, U2FManager}; extern crate log; extern crate env_logger; @@ -49,10 +49,12 @@ fn main() { application.result(&mut app_bytes); let manager = U2FManager::new().unwrap(); + let flags = RegisterFlags::empty(); let (tx, rx) = channel(); manager .register( + flags, 15_000, chall_bytes.clone(), app_bytes.clone(), diff --git a/dom/webauthn/u2f-hid-rs/src/capi.rs b/dom/webauthn/u2f-hid-rs/src/capi.rs index 2e5a72df2873..69b0c2d9c349 100644 --- a/dom/webauthn/u2f-hid-rs/src/capi.rs +++ b/dom/webauthn/u2f-hid-rs/src/capi.rs @@ -109,6 +109,7 @@ pub unsafe extern "C" fn rust_u2f_res_free(res: *mut U2FResult) { #[no_mangle] pub unsafe extern "C" fn rust_u2f_mgr_register( mgr: *mut U2FManager, + flags: u64, timeout: u64, callback: U2FCallback, challenge_ptr: *const u8, @@ -126,20 +127,28 @@ pub unsafe extern "C" fn rust_u2f_mgr_register( return 0; } + let flags = ::RegisterFlags::from_bits_truncate(flags); let challenge = from_raw(challenge_ptr, challenge_len); let application = from_raw(application_ptr, application_len); let key_handles = (*khs).clone(); let tid = new_tid(); - let res = (*mgr).register(timeout, challenge, application, key_handles, move |rv| { - if let Ok(registration) = rv { - let mut result = U2FResult::new(); - result.insert(RESBUF_ID_REGISTRATION, registration); - callback(tid, Box::into_raw(Box::new(result))); - } else { - callback(tid, ptr::null_mut()); - }; - }); + let res = (*mgr).register( + flags, + timeout, + challenge, + application, + key_handles, + move |rv| { + if let Ok(registration) = rv { + let mut result = U2FResult::new(); + result.insert(RESBUF_ID_REGISTRATION, registration); + callback(tid, Box::into_raw(Box::new(result))); + } else { + callback(tid, ptr::null_mut()); + }; + }, + ); if res.is_ok() { tid } else { 0 } } diff --git a/dom/webauthn/u2f-hid-rs/src/lib.rs b/dom/webauthn/u2f-hid-rs/src/lib.rs index 4b607bde2125..db3234fcd304 100644 --- a/dom/webauthn/u2f-hid-rs/src/lib.rs +++ b/dom/webauthn/u2f-hid-rs/src/lib.rs @@ -34,6 +34,9 @@ extern crate libc; extern crate boxfnonce; extern crate runloop; +#[macro_use] +extern crate bitflags; + mod consts; mod statemachine; mod u2ftypes; @@ -45,6 +48,15 @@ pub use manager::U2FManager; mod capi; pub use capi::*; +// Keep this in sync with the constants in u2fhid-capi.h. +bitflags! { + pub struct RegisterFlags: u64 { + const REQUIRE_RESIDENT_KEY = 1; + const REQUIRE_USER_VERIFICATION = 2; + const REQUIRE_PLATFORM_ATTACHMENT = 4; + } +} + #[cfg(fuzzing)] pub use u2fprotocol::*; #[cfg(fuzzing)] diff --git a/dom/webauthn/u2f-hid-rs/src/manager.rs b/dom/webauthn/u2f-hid-rs/src/manager.rs index b0cc27e3802f..502364fd8439 100644 --- a/dom/webauthn/u2f-hid-rs/src/manager.rs +++ b/dom/webauthn/u2f-hid-rs/src/manager.rs @@ -11,8 +11,9 @@ use statemachine::StateMachine; use runloop::RunLoop; use util::{to_io_err, OnceCallback}; -pub enum QueueAction { +enum QueueAction { Register { + flags: ::RegisterFlags, timeout: u64, challenge: Vec, application: Vec, @@ -45,6 +46,7 @@ impl U2FManager { while alive() { match rx.recv_timeout(Duration::from_millis(50)) { Ok(QueueAction::Register { + flags, timeout, challenge, application, @@ -52,7 +54,14 @@ impl U2FManager { callback, }) => { // This must not block, otherwise we can't cancel. - sm.register(timeout, challenge, application, key_handles, callback); + sm.register( + flags, + timeout, + challenge, + application, + key_handles, + callback, + ); } Ok(QueueAction::Sign { timeout, @@ -88,6 +97,7 @@ impl U2FManager { pub fn register( &self, + flags: ::RegisterFlags, timeout: u64, challenge: Vec, application: Vec, @@ -116,6 +126,7 @@ impl U2FManager { let callback = OnceCallback::new(callback); let action = QueueAction::Register { + flags, timeout, challenge, application, diff --git a/dom/webauthn/u2f-hid-rs/src/statemachine.rs b/dom/webauthn/u2f-hid-rs/src/statemachine.rs index 008e4be07e92..5e1b7be27d04 100644 --- a/dom/webauthn/u2f-hid-rs/src/statemachine.rs +++ b/dom/webauthn/u2f-hid-rs/src/statemachine.rs @@ -22,6 +22,7 @@ impl StateMachine { pub fn register( &mut self, + flags: ::RegisterFlags, timeout: u64, challenge: Vec, application: Vec, @@ -45,6 +46,17 @@ impl StateMachine { return; } + // We currently support none of the authenticator selection + // criteria because we can't ask tokens whether they do support + // those features. If flags are set, ignore all tokens for now. + // + // Technically, this is a ConstraintError because we shouldn't talk + // to this authenticator in the first place. But the result is the + // same anyway. + if !flags.is_empty() { + return; + } + // Iterate the exclude list and see if there are any matches. // Abort the state machine if we found a valid key handle. if key_handles.iter().any(|key_handle| { diff --git a/dom/webauthn/u2f-hid-rs/src/u2fhid-capi.h b/dom/webauthn/u2f-hid-rs/src/u2fhid-capi.h index 2277135c6314..a27f7fc1b5be 100644 --- a/dom/webauthn/u2f-hid-rs/src/u2fhid-capi.h +++ b/dom/webauthn/u2f-hid-rs/src/u2fhid-capi.h @@ -15,6 +15,10 @@ const uint8_t U2F_RESBUF_ID_REGISTRATION = 0; const uint8_t U2F_RESBUF_ID_KEYHANDLE = 1; const uint8_t U2F_RESBUF_ID_SIGNATURE = 2; +const uint64_t U2F_FLAG_REQUIRE_RESIDENT_KEY = 1; +const uint64_t U2F_FLAG_REQUIRE_USER_VERIFICATION = 2; +const uint64_t U2F_FLAG_REQUIRE_PLATFORM_ATTACHMENT = 4; + // NOTE: Preconditions // * All rust_u2f_mgr* pointers must refer to pointers which are returned // by rust_u2f_mgr_new, and must be freed with rust_u2f_mgr_free. @@ -42,6 +46,7 @@ rust_u2f_manager* rust_u2f_mgr_new(); /* unsafe */ void rust_u2f_mgr_free(rust_u2f_manager* mgr); uint64_t rust_u2f_mgr_register(rust_u2f_manager* mgr, + uint64_t flags, uint64_t timeout, rust_u2f_callback, const uint8_t* challenge_ptr, diff --git a/dom/webidl/WebAuthentication.webidl b/dom/webidl/WebAuthentication.webidl index 267b1c997a4b..0f6f6c9b4319 100644 --- a/dom/webidl/WebAuthentication.webidl +++ b/dom/webidl/WebAuthentication.webidl @@ -75,7 +75,7 @@ dictionary PublicKeyCredentialUserEntity : PublicKeyCredentialEntity { dictionary AuthenticatorSelectionCriteria { AuthenticatorAttachment authenticatorAttachment; boolean requireResidentKey = false; - boolean requireUserVerification = false; + UserVerificationRequirement userVerification = "preferred"; }; enum AuthenticatorAttachment { @@ -83,6 +83,12 @@ enum AuthenticatorAttachment { "cross-platform" // Cross-platform attachment }; +enum UserVerificationRequirement { + "required", + "preferred", + "discouraged" +}; + dictionary PublicKeyCredentialRequestOptions { required BufferSource challenge; unsigned long timeout; diff --git a/dom/websocket/tests/iframe_webSocket_sandbox.html b/dom/websocket/tests/iframe_webSocket_sandbox.html index f0004d85c17e..0e6d1d97bfa7 100644 --- a/dom/websocket/tests/iframe_webSocket_sandbox.html +++ b/dom/websocket/tests/iframe_webSocket_sandbox.html @@ -1,6 +1,6 @@ -