From 9ebde3021572b9951e5cdc92f08b3d84e98f96f4 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 20 Mar 2017 00:28:46 -0700 Subject: [PATCH 01/46] servo: Merge #16016 - Add separate specified value for keyword font sizes (from Manishearth:graft-font-size); r=upsuper In Gecko, these keywords compute to different values depending on the font. See https://bugzilla.mozilla.org/show_bug.cgi?id=1341775 Source-Repo: https://github.com/servo/servo Source-Revision: 50fd39f068fe5a4a018bb4e7a602f50f10590524 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : bce6512a67ff1bb441554ece8b0e3cf9db07e80e --- servo/components/script/dom/element.rs | 5 +- .../components/script/dom/htmlfontelement.rs | 30 ++-- .../style/properties/longhand/font.mako.rs | 163 +++++++++++++++--- .../style/values/specified/length.rs | 42 ----- servo/ports/geckolib/glue.rs | 4 +- 5 files changed, 162 insertions(+), 82 deletions(-) diff --git a/servo/components/script/dom/element.rs b/servo/components/script/dom/element.rs index 3a73bbce97ed..f9e23bd50e08 100644 --- a/servo/components/script/dom/element.rs +++ b/servo/components/script/dom/element.rs @@ -478,7 +478,10 @@ impl LayoutElementHelpers for LayoutJS { if let Some(font_size) = font_size { hints.push(from_declaration( shared_lock, - PropertyDeclaration::FontSize(font_size::SpecifiedValue(font_size.into())))) + PropertyDeclaration::FontSize( + font_size::SpecifiedValue::from_html_size(font_size as u8) + ) + )) } let cellspacing = if let Some(this) = self.downcast::() { diff --git a/servo/components/script/dom/htmlfontelement.rs b/servo/components/script/dom/htmlfontelement.rs index 8644544cdfe5..4e6b96a9c7e7 100644 --- a/servo/components/script/dom/htmlfontelement.rs +++ b/servo/components/script/dom/htmlfontelement.rs @@ -18,7 +18,6 @@ use html5ever_atoms::LocalName; use servo_atoms::Atom; use style::attr::AttrValue; use style::str::{HTML_SPACE_CHARACTERS, read_numbers}; -use style::values::specified; #[dom_struct] pub struct HTMLFontElement { @@ -62,8 +61,7 @@ impl HTMLFontElementMethods for HTMLFontElement { // https://html.spec.whatwg.org/multipage/#dom-font-size fn SetSize(&self, value: DOMString) { let element = self.upcast::(); - let length = parse_length(&value); - element.set_attribute(&local_name!("size"), AttrValue::Length(value.into(), length)); + element.set_attribute(&local_name!("size"), parse_size(&value)); } } @@ -76,10 +74,7 @@ impl VirtualMethods for HTMLFontElement { match name { &local_name!("face") => AttrValue::from_atomic(value.into()), &local_name!("color") => AttrValue::from_legacy_color(value.into()), - &local_name!("size") => { - let length = parse_length(&value); - AttrValue::Length(value.into(), length) - }, + &local_name!("size") => parse_size(&value), _ => self.super_type().unwrap().parse_plain_attribute(name, value), } } @@ -88,7 +83,7 @@ impl VirtualMethods for HTMLFontElement { pub trait HTMLFontElementLayoutHelpers { fn get_color(&self) -> Option; fn get_face(&self) -> Option; - fn get_size(&self) -> Option; + fn get_size(&self) -> Option; } impl HTMLFontElementLayoutHelpers for LayoutJS { @@ -113,18 +108,21 @@ impl HTMLFontElementLayoutHelpers for LayoutJS { } #[allow(unsafe_code)] - fn get_size(&self) -> Option { - unsafe { + fn get_size(&self) -> Option { + let size = unsafe { (*self.upcast::().unsafe_get()) .get_attr_for_layout(&ns!(), &local_name!("size")) - .and_then(AttrValue::as_length) - .cloned() + }; + match size { + Some(&AttrValue::UInt(_, s)) => Some(s), + _ => None, } } } /// https://html.spec.whatwg.org/multipage/#rules-for-parsing-a-legacy-font-size -fn parse_length(mut input: &str) -> Option { +fn parse_size(mut input: &str) -> AttrValue { + let original_input = input; // Steps 1 & 2 are not relevant // Step 3 @@ -138,7 +136,7 @@ fn parse_length(mut input: &str) -> Option { let mut input_chars = input.chars().peekable(); let parse_mode = match input_chars.peek() { // Step 4 - None => return None, + None => return AttrValue::String(original_input.into()), // Step 5 Some(&'+') => { @@ -155,7 +153,7 @@ fn parse_length(mut input: &str) -> Option { // Steps 6, 7, 8 let mut value = match read_numbers(input_chars) { (Some(v), _) if v >= 0 => v, - _ => return None, + _ => return AttrValue::String(original_input.into()), }; // Step 9 @@ -166,5 +164,5 @@ fn parse_length(mut input: &str) -> Option { } // Steps 10, 11, 12 - Some(specified::Length::from_font_size_int(value as u8)) + AttrValue::UInt(original_input.into(), value as u32) } diff --git a/servo/components/style/properties/longhand/font.mako.rs b/servo/components/style/properties/longhand/font.mako.rs index a62da4290650..49b3557c8cb1 100644 --- a/servo/components/style/properties/longhand/font.mako.rs +++ b/servo/components/style/properties/longhand/font.mako.rs @@ -400,24 +400,129 @@ ${helpers.single_keyword("font-variant-caps", impl ToCss for SpecifiedValue { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - self.0.to_css(dest) + match *self { + SpecifiedValue::Length(ref lop) => lop.to_css(dest), + SpecifiedValue::Keyword(kw) => kw.to_css(dest), + SpecifiedValue::Smaller => dest.write_str("smaller"), + SpecifiedValue::Larger => dest.write_str("larger"), + } } } impl HasViewportPercentage for SpecifiedValue { fn has_viewport_percentage(&self) -> bool { - return self.0.has_viewport_percentage() + match *self { + SpecifiedValue::Length(ref lop) => lop.has_viewport_percentage(), + _ => false + } } } #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] - pub struct SpecifiedValue(pub specified::LengthOrPercentage); + pub enum SpecifiedValue { + Length(specified::LengthOrPercentage), + Keyword(KeywordSize), + Smaller, + Larger, + } + pub mod computed_value { use app_units::Au; pub type T = Au; } + /// CSS font keywords + #[derive(Debug, Copy, Clone, PartialEq)] + #[cfg_attr(feature = "servo", derive(HeapSizeOf))] + pub enum KeywordSize { + XXSmall = 0, + XSmall = 1, + Small = 2, + Medium = 3, + Large = 4, + XLarge = 5, + XXLarge = 6, + // This is not a real font keyword and will not parse + // HTML font-size 7 corresponds to this value + XXXLarge = 7, + } + + pub use self::KeywordSize::*; + + impl KeywordSize { + pub fn parse(input: &mut Parser) -> Result { + Ok(match_ignore_ascii_case! {&*input.expect_ident()?, + "xx-small" => XXSmall, + "x-small" => XSmall, + "small" => Small, + "medium" => Medium, + "large" => Large, + "x-large" => XLarge, + "xx-large" => XXLarge, + _ => return Err(()) + }) + } + } + + impl ToCss for KeywordSize { + fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { + dest.write_str(match *self { + XXSmall => "xx-small", + XSmall => "x-small", + Small => "small", + Medium => "medium", + Large => "large", + XLarge => "x-large", + XXLarge => "xx-large", + XXXLarge => unreachable!("We should never serialize \ + specified values set via + HTML presentation attributes"), + }) + } + } + + impl ToComputedValue for KeywordSize { + type ComputedValue = Au; + #[inline] + fn to_computed_value(&self, _: &Context) -> computed_value::T { + // https://drafts.csswg.org/css-fonts-3/#font-size-prop + use values::FONT_MEDIUM_PX; + match *self { + XXSmall => Au::from_px(FONT_MEDIUM_PX) * 3 / 5, + XSmall => Au::from_px(FONT_MEDIUM_PX) * 3 / 4, + Small => Au::from_px(FONT_MEDIUM_PX) * 8 / 9, + Medium => Au::from_px(FONT_MEDIUM_PX), + Large => Au::from_px(FONT_MEDIUM_PX) * 6 / 5, + XLarge => Au::from_px(FONT_MEDIUM_PX) * 3 / 2, + XXLarge => Au::from_px(FONT_MEDIUM_PX) * 2, + XXXLarge => Au::from_px(FONT_MEDIUM_PX) * 3, + } + } + + #[inline] + fn from_computed_value(_: &computed_value::T) -> Self { + unreachable!() + } + } + + impl SpecifiedValue { + /// https://html.spec.whatwg.org/multipage/#rules-for-parsing-a-legacy-font-size + pub fn from_html_size(size: u8) -> Self { + SpecifiedValue::Keyword(match size { + // If value is less than 1, let it be 1. + 0 | 1 => XSmall, + 2 => Small, + 3 => Medium, + 4 => Large, + 5 => XLarge, + 6 => XXLarge, + // If value is greater than 7, let it be 7. + _ => XXXLarge, + }) + } + } + #[inline] #[allow(missing_docs)] pub fn get_initial_value() -> computed_value::T { @@ -426,7 +531,7 @@ ${helpers.single_keyword("font-variant-caps", #[inline] pub fn get_initial_specified_value() -> SpecifiedValue { - SpecifiedValue(specified::LengthOrPercentage::Length(NoCalcLength::medium())) + SpecifiedValue::Keyword(Medium) } impl ToComputedValue for SpecifiedValue { @@ -434,45 +539,61 @@ ${helpers.single_keyword("font-variant-caps", #[inline] fn to_computed_value(&self, context: &Context) -> computed_value::T { - match self.0 { - LengthOrPercentage::Length(NoCalcLength::FontRelative(value)) => { + use values::specified::length::FontRelativeLength; + match *self { + SpecifiedValue::Length(LengthOrPercentage::Length( + NoCalcLength::FontRelative(value))) => { value.to_computed_value(context, /* use inherited */ true) } - LengthOrPercentage::Length(NoCalcLength::ServoCharacterWidth(value)) => { + SpecifiedValue::Length(LengthOrPercentage::Length( + NoCalcLength::ServoCharacterWidth(value))) => { value.to_computed_value(context.inherited_style().get_font().clone_font_size()) } - LengthOrPercentage::Length(ref l) => { + SpecifiedValue::Length(LengthOrPercentage::Length(ref l)) => { l.to_computed_value(context) } - LengthOrPercentage::Percentage(Percentage(value)) => { + SpecifiedValue::Length(LengthOrPercentage::Percentage(Percentage(value))) => { context.inherited_style().get_font().clone_font_size().scale_by(value) } - LengthOrPercentage::Calc(ref calc) => { + SpecifiedValue::Length(LengthOrPercentage::Calc(ref calc)) => { let calc = calc.to_computed_value(context); calc.length() + context.inherited_style().get_font().clone_font_size() .scale_by(calc.percentage()) } + SpecifiedValue::Keyword(ref key) => { + key.to_computed_value(context) + } + SpecifiedValue::Smaller => { + FontRelativeLength::Em(0.85).to_computed_value(context, + /* use_inherited */ true) + } + SpecifiedValue::Larger => { + FontRelativeLength::Em(1.2).to_computed_value(context, + /* use_inherited */ true) + } } } #[inline] fn from_computed_value(computed: &computed_value::T) -> Self { - SpecifiedValue(LengthOrPercentage::Length( + SpecifiedValue::Length(LengthOrPercentage::Length( ToComputedValue::from_computed_value(computed) )) } } /// | | | - pub fn parse(_context: &ParserContext, input: &mut Parser) -> Result { - use values::specified::{Length, LengthOrPercentage}; - - input.try(specified::LengthOrPercentage::parse_non_negative) - .or_else(|()| { - let ident = try!(input.expect_ident()); - NoCalcLength::from_str(&ident as &str) - .ok_or(()) - .map(specified::LengthOrPercentage::Length) - }).map(SpecifiedValue) + pub fn parse(_: &ParserContext, input: &mut Parser) -> Result { + if let Ok(lop) = input.try(specified::LengthOrPercentage::parse_non_negative) { + Ok(SpecifiedValue::Length(lop)) + } else if let Ok(kw) = input.try(KeywordSize::parse) { + Ok(SpecifiedValue::Keyword(kw)) + } else { + match_ignore_ascii_case! {&*input.expect_ident()?, + "smaller" => Ok(SpecifiedValue::Smaller), + "larger" => Ok(SpecifiedValue::Larger), + _ => Err(()) + } + } } diff --git a/servo/components/style/values/specified/length.rs b/servo/components/style/values/specified/length.rs index d530680660a1..bffae92c4ff4 100644 --- a/servo/components/style/values/specified/length.rs +++ b/servo/components/style/values/specified/length.rs @@ -276,38 +276,6 @@ impl Mul for NoCalcLength { } impl NoCalcLength { - /// https://drafts.csswg.org/css-fonts-3/#font-size-prop - pub fn from_str(s: &str) -> Option { - Some(match_ignore_ascii_case! { s, - "xx-small" => NoCalcLength::Absolute(Au::from_px(FONT_MEDIUM_PX) * 3 / 5), - "x-small" => NoCalcLength::Absolute(Au::from_px(FONT_MEDIUM_PX) * 3 / 4), - "small" => NoCalcLength::Absolute(Au::from_px(FONT_MEDIUM_PX) * 8 / 9), - "medium" => NoCalcLength::Absolute(Au::from_px(FONT_MEDIUM_PX)), - "large" => NoCalcLength::Absolute(Au::from_px(FONT_MEDIUM_PX) * 6 / 5), - "x-large" => NoCalcLength::Absolute(Au::from_px(FONT_MEDIUM_PX) * 3 / 2), - "xx-large" => NoCalcLength::Absolute(Au::from_px(FONT_MEDIUM_PX) * 2), - - // https://github.com/servo/servo/issues/3423#issuecomment-56321664 - "smaller" => NoCalcLength::FontRelative(FontRelativeLength::Em(0.85)), - "larger" => NoCalcLength::FontRelative(FontRelativeLength::Em(1.2)), - _ => return None - }) - } - - /// https://drafts.csswg.org/css-fonts-3/#font-size-prop - pub fn from_font_size_int(i: u8) -> Self { - let au = match i { - 0 | 1 => Au::from_px(FONT_MEDIUM_PX) * 3 / 4, - 2 => Au::from_px(FONT_MEDIUM_PX) * 8 / 9, - 3 => Au::from_px(FONT_MEDIUM_PX), - 4 => Au::from_px(FONT_MEDIUM_PX) * 6 / 5, - 5 => Au::from_px(FONT_MEDIUM_PX) * 3 / 2, - 6 => Au::from_px(FONT_MEDIUM_PX) * 2, - _ => Au::from_px(FONT_MEDIUM_PX) * 3, - }; - NoCalcLength::Absolute(au) - } - /// Parse a given absolute or relative dimension. pub fn parse_dimension(value: CSSFloat, unit: &str) -> Result { match_ignore_ascii_case! { unit, @@ -444,21 +412,11 @@ impl Length { Length::NoCalc(NoCalcLength::zero()) } - /// https://drafts.csswg.org/css-fonts-3/#font-size-prop - pub fn from_str(s: &str) -> Option { - NoCalcLength::from_str(s).map(Length::NoCalc) - } - /// Parse a given absolute or relative dimension. pub fn parse_dimension(value: CSSFloat, unit: &str) -> Result { NoCalcLength::parse_dimension(value, unit).map(Length::NoCalc) } - /// https://drafts.csswg.org/css-fonts-3/#font-size-prop - pub fn from_font_size_int(i: u8) -> Self { - Length::NoCalc(NoCalcLength::from_font_size_int(i)) - } - #[inline] fn parse_internal(input: &mut Parser, context: AllowedNumericType) -> Result { match try!(input.next()) { diff --git a/servo/ports/geckolib/glue.rs b/servo/ports/geckolib/glue.rs index 177a6c076e8f..253e724a3635 100644 --- a/servo/ports/geckolib/glue.rs +++ b/servo/ports/geckolib/glue.rs @@ -1111,7 +1111,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetKeywordValue(declarations: value: i32) { use style::properties::{PropertyDeclaration, LonghandId}; use style::properties::longhands; - use style::values::specified::{BorderStyle, NoCalcLength}; + use style::values::specified::BorderStyle; let declarations = Locked::::as_arc(&declarations); let long = get_longhand_from_id!(property); @@ -1127,7 +1127,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetKeywordValue(declarations: Clear => longhands::clear::SpecifiedValue::from_gecko_keyword(value), FontSize => { // We rely on Gecko passing in font-size values (0...7) here. - longhands::font_size::SpecifiedValue(NoCalcLength::from_font_size_int(value as u8).into()) + longhands::font_size::SpecifiedValue::from_html_size(value as u8) }, ListStyleType => longhands::list_style_type::SpecifiedValue::from_gecko_keyword(value), WhiteSpace => longhands::white_space::SpecifiedValue::from_gecko_keyword(value), From c6fa23934dff3dbfc2a4d77c6ad631b465e2ab37 Mon Sep 17 00:00:00 2001 From: Henry Chang Date: Sun, 19 Mar 2017 15:52:25 +0800 Subject: [PATCH 02/46] Bug 1348626 - Retry when isPinged() failed to avoid false alarm. r=francois MozReview-Commit-ID: BOdJZReICxZ --HG-- extra : rebase_source : 16e0b0b1a65d0bc1249ff0583947acd39defb5d9 --- .../tests/mochitest/test_classify_ping.html | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/toolkit/components/url-classifier/tests/mochitest/test_classify_ping.html b/toolkit/components/url-classifier/tests/mochitest/test_classify_ping.html index 4919ff9ceeee..63318dbae89b 100644 --- a/toolkit/components/url-classifier/tests/mochitest/test_classify_ping.html +++ b/toolkit/components/url-classifier/tests/mochitest/test_classify_ping.html @@ -21,6 +21,7 @@ const host_track = "http://trackertest.org/"; const path_ping = "tests/toolkit/components/url-classifier/tests/mochitest/ping.sjs"; const TP_ENABLE_PREF = "privacy.trackingprotection.enabled"; + const RETRY_TIMEOUT_MS = 200; var testData = [ { url: "trackertest.org/", @@ -37,9 +38,8 @@ ping(id, host_nottrack); return new Promise(function(resolve, reject) { - setTimeout(function() { - isPinged(id, expectPing, msg, resolve); - }, timeout); + // Retry at most 30 seconds. + isPingedWithRetry(id, expectPing, msg, resolve, 30 * 1000 / RETRY_TIMEOUT_MS); }); } @@ -85,19 +85,30 @@ document.body.removeChild(elm); } - function isPinged(id, expected, msg, callback) { + function isPingedWithRetry(id, expected, msg, callback, retryCnt) { var url = "http://mochi.test:8888/" + path_ping; var xhr = new XMLHttpRequest(); xhr.open('GET', url + "?id=" + id); xhr.onload = function() { var isPinged = xhr.response === "ping"; - is(expected, isPinged, msg); - - callback(); + let success = isPinged === expected; + if (success || 0 === retryCnt) { + is(expected, isPinged, msg); + callback(); + return; + } + // Retry on failure. + setTimeout(() => { + isPingedWithRetry(id, expected, msg, callback, retryCnt - 1); + }, RETRY_TIMEOUT_MS); }; xhr.send(); } + function isPinged(id, expected, msg, callback) { + isPingedWithRetry(id, expected, msg, callback, 0); + } + function cleanup() { SpecialPowers.clearUserPref(TP_ENABLE_PREF); } From 106b6939c6d4c4843ce81beef2bbdd1b4117a3d2 Mon Sep 17 00:00:00 2001 From: John Lin Date: Fri, 17 Mar 2017 14:21:27 +0800 Subject: [PATCH 03/46] Bug 1346235 - part 1: translate native error to Java exception. r=jchen MozReview-Commit-ID: BcpfJLSzTvk --HG-- extra : rebase_source : 53d6e9efa064b4a5ab32676d349a5c0cadb78ea7 --- .../java/org/mozilla/gecko/mozglue/SharedMemory.java | 7 ++++++- mozglue/android/SharedMemNatives.cpp | 10 +++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/mobile/android/base/java/org/mozilla/gecko/mozglue/SharedMemory.java b/mobile/android/base/java/org/mozilla/gecko/mozglue/SharedMemory.java index bc43a275545e..00b80f4a127b 100644 --- a/mobile/android/base/java/org/mozilla/gecko/mozglue/SharedMemory.java +++ b/mobile/android/base/java/org/mozilla/gecko/mozglue/SharedMemory.java @@ -133,7 +133,12 @@ public class SharedMemory implements Parcelable { } if (!mIsMapped) { - mHandle = map(getFD(), mSize); + try { + mHandle = map(getFD(), mSize); + } catch (NullPointerException e) { + Log.e(LOGTAG, "SharedMemory#" + mId + " error.", e); + throw e; + } if (mHandle != 0) { mIsMapped = true; } diff --git a/mozglue/android/SharedMemNatives.cpp b/mozglue/android/SharedMemNatives.cpp index d186d6e21e9e..04ceac6a57f2 100644 --- a/mozglue/android/SharedMemNatives.cpp +++ b/mozglue/android/SharedMemNatives.cpp @@ -3,7 +3,9 @@ * 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 #include +#include #include #include @@ -52,6 +54,12 @@ jlong JNICALL Java_org_mozilla_gecko_mozglue_SharedMemory_map(JNIEnv *env, jobject jobj, jint fd, jint length) { void* address = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (address == MAP_FAILED) { + char msg[128]; + snprintf(msg, sizeof(msg), "mmap failed. errno=%d", errno); + env->ThrowNew(env->FindClass("java/lang/NullPointerException"), msg); + return 0; + } return jlong(address); } @@ -62,4 +70,4 @@ Java_org_mozilla_gecko_mozglue_SharedMemory_unmap(JNIEnv *env, jobject jobj, jlo munmap((void*)address, (size_t)size); } -} \ No newline at end of file +} From bbbc27bc084726737b2e5eab40fb2c6d296723e3 Mon Sep 17 00:00:00 2001 From: John Lin Date: Fri, 17 Mar 2017 15:04:26 +0800 Subject: [PATCH 04/46] Bug 1346235 - part 2: translate memory error to I/O failure. r=jchen MozReview-Commit-ID: F2ca0q2JQp --HG-- extra : rebase_source : 9c23a461dbd2ebe3c61ee08e066af51d3b6fe249 --- .../org/mozilla/gecko/mozglue/SharedMemBuffer.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/mobile/android/base/java/org/mozilla/gecko/mozglue/SharedMemBuffer.java b/mobile/android/base/java/org/mozilla/gecko/mozglue/SharedMemBuffer.java index cf22685c2cde..d9455dc5df89 100644 --- a/mobile/android/base/java/org/mozilla/gecko/mozglue/SharedMemBuffer.java +++ b/mobile/android/base/java/org/mozilla/gecko/mozglue/SharedMemBuffer.java @@ -54,7 +54,11 @@ public final class SharedMemBuffer implements Sample.Buffer { if (!src.isDirect()) { throw new IOException("SharedMemBuffer only support reading from direct byte buffer."); } - nativeReadFromDirectBuffer(src, mSharedMem.getPointer(), offset, size); + try { + nativeReadFromDirectBuffer(src, mSharedMem.getPointer(), offset, size); + } catch (NullPointerException e) { + throw new IOException(e); + } } private native static void nativeReadFromDirectBuffer(ByteBuffer src, long dest, int offset, int size); @@ -64,7 +68,11 @@ public final class SharedMemBuffer implements Sample.Buffer { if (!dest.isDirect()) { throw new IOException("SharedMemBuffer only support writing to direct byte buffer."); } - nativeWriteToDirectBuffer(mSharedMem.getPointer(), dest, offset, size); + try { + nativeWriteToDirectBuffer(mSharedMem.getPointer(), dest, offset, size); + } catch (NullPointerException e) { + throw new IOException(e); + } } private native static void nativeWriteToDirectBuffer(long src, ByteBuffer dest, int offset, int size); From f737b4804b67ee1b71ba8d67b40dbad4713d6968 Mon Sep 17 00:00:00 2001 From: John Lin Date: Fri, 17 Mar 2017 15:17:16 +0800 Subject: [PATCH 05/46] Bug 1346235 - part 3: forward shared memory allocation error to peer process. r=jchen MozReview-Commit-ID: KDIMylv9tVt --HG-- extra : rebase_source : fa4326ce1ca97a46ed9f3cb639a17dfa9950fe4e --- .../base/java/org/mozilla/gecko/media/Codec.java | 11 ++++++++--- .../base/java/org/mozilla/gecko/media/SamplePool.java | 10 ++++------ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/mobile/android/base/java/org/mozilla/gecko/media/Codec.java b/mobile/android/base/java/org/mozilla/gecko/media/Codec.java index 877cbc7ab69e..58deb8ebfb7b 100644 --- a/mobile/android/base/java/org/mozilla/gecko/media/Codec.java +++ b/mobile/android/base/java/org/mozilla/gecko/media/Codec.java @@ -196,8 +196,8 @@ import java.util.concurrent.ConcurrentLinkedQueue; return; } - Sample output = obtainOutputSample(index, info); try { + Sample output = obtainOutputSample(index, info); mSentIndices.add(index); mSentOutputs.add(output); mCallbacks.onOutput(output); @@ -471,8 +471,13 @@ import java.util.concurrent.ConcurrentLinkedQueue; } @Override - public synchronized Sample dequeueInput(int size) { - return mInputProcessor.onAllocate(size); + public synchronized Sample dequeueInput(int size) throws RemoteException { + try { + return mInputProcessor.onAllocate(size); + } catch (Exception e) { + // Translate allocation error to remote exception. + throw new RemoteException(e.getMessage()); + } } @Override diff --git a/mobile/android/base/java/org/mozilla/gecko/media/SamplePool.java b/mobile/android/base/java/org/mozilla/gecko/media/SamplePool.java index f484c7f2a909..f802166f29e5 100644 --- a/mobile/android/base/java/org/mozilla/gecko/media/SamplePool.java +++ b/mobile/android/base/java/org/mozilla/gecko/media/SamplePool.java @@ -32,7 +32,7 @@ final class SamplePool { mDefaultBufferSize = size; } - private synchronized Sample obtain(int size) { + private synchronized Sample obtain(int size) { if (!mRecycledSamples.isEmpty()) { return mRecycledSamples.remove(0); } @@ -48,13 +48,11 @@ final class SamplePool { SharedMemory shm = null; try { shm = new SharedMemory(mNextId++, Math.max(size, mDefaultBufferSize)); - } catch (NoSuchMethodException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); + } catch (NoSuchMethodException | IOException e) { + throw new UnsupportedOperationException(e); } - return shm != null ? Sample.create(shm) : Sample.create(); + return Sample.create(shm); } private synchronized void recycle(Sample recycled) { From d65535053dadd02412c3ec1cb46bc66bdb1a76ac Mon Sep 17 00:00:00 2001 From: John Lin Date: Fri, 17 Mar 2017 15:06:39 +0800 Subject: [PATCH 06/46] Bug 1346235 - part 4: recycle unpopulated input samples. r=jchen MozReview-Commit-ID: Lr0aSQ0OfRg --HG-- extra : rebase_source : 71f37d29c5d3a08e63171956fa5a02e716bcec0a --- .../java/org/mozilla/gecko/media/Codec.java | 22 +++++++--- .../org/mozilla/gecko/media/CodecProxy.java | 44 +++++++++++-------- 2 files changed, 40 insertions(+), 26 deletions(-) diff --git a/mobile/android/base/java/org/mozilla/gecko/media/Codec.java b/mobile/android/base/java/org/mozilla/gecko/media/Codec.java index 58deb8ebfb7b..fa9b8ecaa3b2 100644 --- a/mobile/android/base/java/org/mozilla/gecko/media/Codec.java +++ b/mobile/android/base/java/org/mozilla/gecko/media/Codec.java @@ -66,18 +66,26 @@ import java.util.concurrent.ConcurrentLinkedQueue; private synchronized void onSample(Sample sample) { if (sample == null) { - Log.w(LOGTAG, "WARN: null input sample"); + // Ignore empty input. + mSamplePool.recycleInput(mDequeuedSamples.remove()); + Log.w(LOGTAG, "WARN: empty input sample"); return; } - if (!sample.isEOS()) { - Sample temp = sample; - sample = mDequeuedSamples.remove(); - sample.info = temp.info; - sample.cryptoInfo = temp.cryptoInfo; - temp.dispose(); + if (sample.isEOS()) { + queueSample(sample); + return; } + Sample dequeued = mDequeuedSamples.remove(); + dequeued.info = sample.info; + dequeued.cryptoInfo = sample.cryptoInfo; + queueSample(dequeued); + + sample.dispose(); + } + + private void queueSample(Sample sample) { if (!mInputSamples.offer(sample)) { reportError(Error.FATAL, new Exception("FAIL: input sample queue is full")); return; diff --git a/mobile/android/base/java/org/mozilla/gecko/media/CodecProxy.java b/mobile/android/base/java/org/mozilla/gecko/media/CodecProxy.java index b3d95015725d..765689325d17 100644 --- a/mobile/android/base/java/org/mozilla/gecko/media/CodecProxy.java +++ b/mobile/android/base/java/org/mozilla/gecko/media/CodecProxy.java @@ -170,34 +170,40 @@ public final class CodecProxy { Log.e(LOGTAG, "cannot send input to an ended codec"); return false; } + + boolean eos = info.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM; + mCallbacks.setEndOfInput(eos); + + if (eos) { + return sendInput(Sample.EOS); + } + + try { + return sendInput(mRemote.dequeueInput(info.size).set(bytes, info, cryptoInfo)); + } catch (RemoteException e) { + Log.e(LOGTAG, "fail to dequeue input buffer", e); + return false; + } catch (IOException e) { + Log.e(LOGTAG, "fail to copy input data.", e); + // Balance dequeue/queue. + return sendInput(null); + } + } + + private boolean sendInput(Sample sample) { try { - Sample sample = processInput(bytes, info, cryptoInfo); - if (sample == null) { - return false; - } mRemote.queueInput(sample); - sample.dispose(); + if (sample != null) { + sample.dispose(); + } } catch (Exception e) { - Log.e(LOGTAG, "fail to input sample: size=" + info.size + - ", pts=" + info.presentationTimeUs + - ", flags=" + Integer.toHexString(info.flags), e); + Log.e(LOGTAG, "fail to queue input:" + sample, e); return false; } return true; } - private Sample processInput(ByteBuffer bytes, BufferInfo info, CryptoInfo cryptoInfo) - throws RemoteException, IOException { - if (info.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM) { - mCallbacks.setEndOfInput(true); - return Sample.EOS; - } else { - mCallbacks.setEndOfInput(false); - return mRemote.dequeueInput(info.size).set(bytes, info, cryptoInfo); - } - } - @WrapForJNI public synchronized boolean flush() { if (mRemote == null) { From 390a075c262c4ff1e050339b2635d36f6933638d Mon Sep 17 00:00:00 2001 From: Frederik Braun Date: Mon, 30 Jan 2017 14:09:37 +0100 Subject: [PATCH 07/46] Bug 1073952: inherit CSP into iframe sandbox srcdoc r=ckerschb,Tomcat MozReview-Commit-ID: 3fhWCGwgG4A --HG-- extra : rebase_source : 7e84fafe0ef69b7f6695de825fc254ee0e4209ba --- caps/BasePrincipal.cpp | 15 +++++++++++++++ caps/BasePrincipal.h | 1 + caps/nsIPrincipal.idl | 5 +++-- caps/nsNullPrincipal.cpp | 14 ++++++++++++++ caps/nsNullPrincipal.h | 1 + caps/nsScriptSecurityManager.cpp | 26 +++++++++++++++++++++++++- caps/nsSystemPrincipal.cpp | 11 ++++++++++- caps/nsSystemPrincipal.h | 1 + 8 files changed, 70 insertions(+), 4 deletions(-) diff --git a/caps/BasePrincipal.cpp b/caps/BasePrincipal.cpp index b00ce460c26b..466e4994cd0b 100644 --- a/caps/BasePrincipal.cpp +++ b/caps/BasePrincipal.cpp @@ -442,6 +442,21 @@ BasePrincipal::GetCsp(nsIContentSecurityPolicy** aCsp) return NS_OK; } +NS_IMETHODIMP +BasePrincipal::SetCsp(nsIContentSecurityPolicy* aCsp) +{ + // Never destroy an existing CSP on the principal. + // This method should only be called in rare cases. + + MOZ_ASSERT(!mCSP, "do not destroy an existing CSP"); + if (mCSP) { + return NS_ERROR_ALREADY_INITIALIZED; + } + + mCSP = aCsp; + return NS_OK; +} + NS_IMETHODIMP BasePrincipal::EnsureCSP(nsIDOMDocument* aDocument, nsIContentSecurityPolicy** aCSP) diff --git a/caps/BasePrincipal.h b/caps/BasePrincipal.h index 7391e8b468bf..537b1a8e51e9 100644 --- a/caps/BasePrincipal.h +++ b/caps/BasePrincipal.h @@ -222,6 +222,7 @@ public: NS_IMETHOD SubsumesConsideringDomainIgnoringFPD(nsIPrincipal* other, bool* _retval) final; NS_IMETHOD CheckMayLoad(nsIURI* uri, bool report, bool allowIfInheritsPrincipal) final; NS_IMETHOD GetCsp(nsIContentSecurityPolicy** aCsp) override; + NS_IMETHOD SetCsp(nsIContentSecurityPolicy* aCsp) override; NS_IMETHOD EnsureCSP(nsIDOMDocument* aDocument, nsIContentSecurityPolicy** aCSP) override; NS_IMETHOD GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP) override; NS_IMETHOD EnsurePreloadCSP(nsIDOMDocument* aDocument, nsIContentSecurityPolicy** aCSP) override; diff --git a/caps/nsIPrincipal.idl b/caps/nsIPrincipal.idl index 16aceafeff7d..870792527813 100644 --- a/caps/nsIPrincipal.idl +++ b/caps/nsIPrincipal.idl @@ -151,10 +151,11 @@ interface nsIPrincipal : nsISerializable /** * A Content Security Policy associated with this principal. - * * Use this function to query the associated CSP with this principal. + * Please *only* use this function to *set* a CSP when you know exactly what you are doing. + * Most likely you want to call ensureCSP instead of setCSP. */ - [noscript] readonly attribute nsIContentSecurityPolicy csp; + [noscript] attribute nsIContentSecurityPolicy csp; /* * Use this function to query a CSP associated with this principal. diff --git a/caps/nsNullPrincipal.cpp b/caps/nsNullPrincipal.cpp index 8ab0bd27c91a..fe846ac25b0c 100644 --- a/caps/nsNullPrincipal.cpp +++ b/caps/nsNullPrincipal.cpp @@ -108,6 +108,20 @@ nsNullPrincipal::GetHashValue(uint32_t *aResult) return NS_OK; } +NS_IMETHODIMP +nsNullPrincipal::SetCsp(nsIContentSecurityPolicy* aCsp) { + // Never destroy an existing CSP on the principal. + // This method should only be called in rare cases. + + MOZ_ASSERT(!mCSP, "do not destroy an existing CSP"); + if (mCSP) { + return NS_ERROR_ALREADY_INITIALIZED; + } + + mCSP = aCsp; + return NS_OK; +} + NS_IMETHODIMP nsNullPrincipal::GetURI(nsIURI** aURI) { diff --git a/caps/nsNullPrincipal.h b/caps/nsNullPrincipal.h index ad3345d74741..653029258f4b 100644 --- a/caps/nsNullPrincipal.h +++ b/caps/nsNullPrincipal.h @@ -45,6 +45,7 @@ public: NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override; NS_IMETHOD GetHashValue(uint32_t* aHashValue) override; + NS_IMETHOD SetCsp(nsIContentSecurityPolicy* aCsp) override; NS_IMETHOD GetURI(nsIURI** aURI) override; NS_IMETHOD GetDomain(nsIURI** aDomain) override; NS_IMETHOD SetDomain(nsIURI* aDomain) override; diff --git a/caps/nsScriptSecurityManager.cpp b/caps/nsScriptSecurityManager.cpp index 2135af2da087..d6176f9e32b6 100644 --- a/caps/nsScriptSecurityManager.cpp +++ b/caps/nsScriptSecurityManager.cpp @@ -294,6 +294,30 @@ nsScriptSecurityManager::GetChannelResultPrincipal(nsIChannel* aChannel, if (!aIgnoreSandboxing && loadInfo->GetLoadingSandboxed()) { MOZ_ALWAYS_TRUE(NS_SUCCEEDED(loadInfo->GetSandboxedLoadingPrincipal(aPrincipal))); MOZ_ASSERT(*aPrincipal); + // if the new NullPrincipal (above) loads an iframe[srcdoc], we + // need to inherit an existing CSP to avoid bypasses (bug 1073952). + // We continue inheriting for nested frames with e.g., data: URLs. + if (loadInfo->GetExternalContentPolicyType() == nsIContentPolicy::TYPE_SUBDOCUMENT) { + nsCOMPtr uri; + aChannel->GetURI(getter_AddRefs(uri)); + nsAutoCString URISpec; + uri->GetSpec(URISpec); + bool isData = (NS_SUCCEEDED(uri->SchemeIs("data", &isData)) && isData); + if (URISpec.EqualsLiteral("about:srcdoc") || isData) { + nsCOMPtr principalToInherit = loadInfo->PrincipalToInherit(); + if (!principalToInherit) { + principalToInherit = loadInfo->TriggeringPrincipal(); + } + nsCOMPtr originalCsp; + principalToInherit->GetCsp(getter_AddRefs(originalCsp)); + // if the principalToInherit had a CSP, + // add it to the newly created NullPrincipal. + if (originalCsp) { + nsresult rv = (*aPrincipal)->SetCsp(originalCsp); + NS_ENSURE_SUCCESS(rv, rv); + } + } + } return NS_OK; } @@ -325,7 +349,7 @@ nsScriptSecurityManager::GetChannelResultPrincipal(nsIChannel* aChannel, nsCOMPtr uri; nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri)); - NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr principalToInherit = loadInfo->PrincipalToInherit(); if (!principalToInherit) { principalToInherit = loadInfo->TriggeringPrincipal(); diff --git a/caps/nsSystemPrincipal.cpp b/caps/nsSystemPrincipal.cpp index 94cbeecc29a5..b1c33553ac8d 100644 --- a/caps/nsSystemPrincipal.cpp +++ b/caps/nsSystemPrincipal.cpp @@ -57,7 +57,7 @@ nsSystemPrincipal::GetHashValue(uint32_t *result) return NS_OK; } -NS_IMETHODIMP +NS_IMETHODIMP nsSystemPrincipal::GetURI(nsIURI** aURI) { *aURI = nullptr; @@ -78,6 +78,15 @@ nsSystemPrincipal::GetCsp(nsIContentSecurityPolicy** aCsp) return NS_OK; } +NS_IMETHODIMP +nsSystemPrincipal::SetCsp(nsIContentSecurityPolicy* aCsp) +{ + // Never destroy an existing CSP on the principal. + // This method should only be called in rare cases. + + return NS_ERROR_FAILURE; +} + NS_IMETHODIMP nsSystemPrincipal::EnsureCSP(nsIDOMDocument* aDocument, nsIContentSecurityPolicy** aCSP) diff --git a/caps/nsSystemPrincipal.h b/caps/nsSystemPrincipal.h index 2dd6a0f58ef1..0e67ce45e490 100644 --- a/caps/nsSystemPrincipal.h +++ b/caps/nsSystemPrincipal.h @@ -37,6 +37,7 @@ public: NS_IMETHOD GetDomain(nsIURI** aDomain) override; NS_IMETHOD SetDomain(nsIURI* aDomain) override; NS_IMETHOD GetCsp(nsIContentSecurityPolicy** aCsp) override; + NS_IMETHOD SetCsp(nsIContentSecurityPolicy* aCsp) override; NS_IMETHOD EnsureCSP(nsIDOMDocument* aDocument, nsIContentSecurityPolicy** aCSP) override; NS_IMETHOD GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP) override; NS_IMETHOD EnsurePreloadCSP(nsIDOMDocument* aDocument, nsIContentSecurityPolicy** aCSP) override; From 56207a1b8b410c71ab236363ec16b22eae7e078a Mon Sep 17 00:00:00 2001 From: Frederik Braun Date: Mon, 30 Jan 2017 14:12:15 +0100 Subject: [PATCH 08/46] Bug 1073952: tests for iframe sandbox srcdoc and data URIs with CSP r=ckerschb,Tomcat MozReview-Commit-ID: 5Q8XIJPrRPk --HG-- extra : rebase_source : 391431d3585173d096ab58747a854542dfd3adca --- .../test/csp/file_iframe_sandbox_srcdoc.html | 11 ++ .../file_iframe_sandbox_srcdoc.html^headers^ | 1 + dom/security/test/csp/file_iframe_srcdoc.sjs | 79 ++++++++++ dom/security/test/csp/mochitest.ini | 5 + .../test/csp/test_iframe_sandbox_srcdoc.html | 62 ++++++++ dom/security/test/csp/test_iframe_srcdoc.html | 140 ++++++++++++++++++ 6 files changed, 298 insertions(+) create mode 100644 dom/security/test/csp/file_iframe_sandbox_srcdoc.html create mode 100644 dom/security/test/csp/file_iframe_sandbox_srcdoc.html^headers^ create mode 100644 dom/security/test/csp/file_iframe_srcdoc.sjs create mode 100644 dom/security/test/csp/test_iframe_sandbox_srcdoc.html create mode 100644 dom/security/test/csp/test_iframe_srcdoc.html diff --git a/dom/security/test/csp/file_iframe_sandbox_srcdoc.html b/dom/security/test/csp/file_iframe_sandbox_srcdoc.html new file mode 100644 index 000000000000..bc700ed68fb3 --- /dev/null +++ b/dom/security/test/csp/file_iframe_sandbox_srcdoc.html @@ -0,0 +1,11 @@ + + + + + Bug 1073952 - CSP should restrict scripts in srcdoc iframe even if sandboxed + + + + + diff --git a/dom/security/test/csp/file_iframe_sandbox_srcdoc.html^headers^ b/dom/security/test/csp/file_iframe_sandbox_srcdoc.html^headers^ new file mode 100644 index 000000000000..cf869e07d402 --- /dev/null +++ b/dom/security/test/csp/file_iframe_sandbox_srcdoc.html^headers^ @@ -0,0 +1 @@ +content-security-policy: default-src *; diff --git a/dom/security/test/csp/file_iframe_srcdoc.sjs b/dom/security/test/csp/file_iframe_srcdoc.sjs new file mode 100644 index 000000000000..6de8a029ef1b --- /dev/null +++ b/dom/security/test/csp/file_iframe_srcdoc.sjs @@ -0,0 +1,79 @@ +// Custom *.sjs file specifically for the needs of +// https://bugzilla.mozilla.org/show_bug.cgi?id=1073952 + +"use strict"; +Components.utils.importGlobalProperties(["URLSearchParams"]); + +const SCRIPT = ` + `; + +const SIMPLE_IFRAME_SRCDOC = ` + + + + + + + `; + +const INNER_SRCDOC_IFRAME = ` + `; + +const NESTED_IFRAME_SRCDOC = ` + + + + + + + `; + + +const INNER_DATAURI_IFRAME = ` + `; + +const NESTED_IFRAME_SRCDOC_DATAURI = ` + + + + + + + `; + +function handleRequest(request, response) { + const query = new URLSearchParams(request.queryString); + + response.setHeader("Cache-Control", "no-cache", false); + if (typeof query.get("csp") === "string") { + response.setHeader("Content-Security-Policy", query.get("csp"), false); + } + response.setHeader("Content-Type", "text/html", false); + + if (query.get("action") === "simple_iframe_srcdoc") { + response.write(SIMPLE_IFRAME_SRCDOC); + return; + } + + if (query.get("action") === "nested_iframe_srcdoc") { + response.write(NESTED_IFRAME_SRCDOC); + return; + } + + if (query.get("action") === "nested_iframe_srcdoc_datauri") { + response.write(NESTED_IFRAME_SRCDOC_DATAURI); + return; + } + + // we should never get here, but just in case + // return something unexpected + response.write("do'h"); +} diff --git a/dom/security/test/csp/mochitest.ini b/dom/security/test/csp/mochitest.ini index 58ac777ea5d7..4d3e02b67cd8 100644 --- a/dom/security/test/csp/mochitest.ini +++ b/dom/security/test/csp/mochitest.ini @@ -205,6 +205,9 @@ support-files = file_upgrade_insecure_navigation.sjs file_punycode_host_src.sjs file_punycode_host_src.js + file_iframe_srcdoc.sjs + file_iframe_sandbox_srcdoc.html + file_iframe_sandbox_srcdoc.html^headers^ [test_base-uri.html] [test_blob_data_schemes.html] @@ -293,3 +296,5 @@ tags = mcb [test_strict_dynamic_default_src.html] [test_upgrade_insecure_navigation.html] [test_punycode_host_src.html] +[test_iframe_sandbox_srcdoc.html] +[test_iframe_srcdoc.html] diff --git a/dom/security/test/csp/test_iframe_sandbox_srcdoc.html b/dom/security/test/csp/test_iframe_sandbox_srcdoc.html new file mode 100644 index 000000000000..53beafcacd9c --- /dev/null +++ b/dom/security/test/csp/test_iframe_sandbox_srcdoc.html @@ -0,0 +1,62 @@ + + + + + Bug 1073952 - CSP should restrict scripts in srcdoc iframe even if sandboxed + + + + +

Bug 1073952

+ + + + diff --git a/dom/security/test/csp/test_iframe_srcdoc.html b/dom/security/test/csp/test_iframe_srcdoc.html new file mode 100644 index 000000000000..95b924a5e387 --- /dev/null +++ b/dom/security/test/csp/test_iframe_srcdoc.html @@ -0,0 +1,140 @@ + + + + Bug 1073952 - Test CSP enforcement within iframe srcdoc + + + + + + + + + + From 622080220c2b15ff323e9b1e0b1f79807f09d0ba Mon Sep 17 00:00:00 2001 From: Frederik Braun Date: Mon, 30 Jan 2017 14:13:13 +0100 Subject: [PATCH 09/46] Bug 1073952: proper indentation for nsScriptSecurityManager::GetChannelResultPrincipal r=Tomcat MozReview-Commit-ID: 84qywpARPwI --HG-- extra : rebase_source : fd0bc97039e95d93ba0eb7688ef3e1571ef1bba3 --- caps/nsScriptSecurityManager.cpp | 126 +++++++++++++++---------------- 1 file changed, 63 insertions(+), 63 deletions(-) diff --git a/caps/nsScriptSecurityManager.cpp b/caps/nsScriptSecurityManager.cpp index d6176f9e32b6..a3874ab22ce0 100644 --- a/caps/nsScriptSecurityManager.cpp +++ b/caps/nsScriptSecurityManager.cpp @@ -269,28 +269,28 @@ nsScriptSecurityManager::GetChannelResultPrincipal(nsIChannel* aChannel, nsIPrincipal** aPrincipal, bool aIgnoreSandboxing) { - NS_PRECONDITION(aChannel, "Must have channel!"); - // Check whether we have an nsILoadInfo that says what we should do. - nsCOMPtr loadInfo = aChannel->GetLoadInfo(); - if (loadInfo && loadInfo->GetForceInheritPrincipalOverruleOwner()) { - nsCOMPtr principalToInherit = loadInfo->PrincipalToInherit(); - if (!principalToInherit) { - principalToInherit = loadInfo->TriggeringPrincipal(); - } - principalToInherit.forget(aPrincipal); + NS_PRECONDITION(aChannel, "Must have channel!"); + // Check whether we have an nsILoadInfo that says what we should do. + nsCOMPtr loadInfo = aChannel->GetLoadInfo(); + if (loadInfo && loadInfo->GetForceInheritPrincipalOverruleOwner()) { + nsCOMPtr principalToInherit = loadInfo->PrincipalToInherit(); + if (!principalToInherit) { + principalToInherit = loadInfo->TriggeringPrincipal(); + } + principalToInherit.forget(aPrincipal); + return NS_OK; + } + + nsCOMPtr owner; + aChannel->GetOwner(getter_AddRefs(owner)); + if (owner) { + CallQueryInterface(owner, aPrincipal); + if (*aPrincipal) { return NS_OK; } + } - nsCOMPtr owner; - aChannel->GetOwner(getter_AddRefs(owner)); - if (owner) { - CallQueryInterface(owner, aPrincipal); - if (*aPrincipal) { - return NS_OK; - } - } - - if (loadInfo) { + if (loadInfo) { if (!aIgnoreSandboxing && loadInfo->GetLoadingSandboxed()) { MOZ_ALWAYS_TRUE(NS_SUCCEEDED(loadInfo->GetSandboxedLoadingPrincipal(aPrincipal))); MOZ_ASSERT(*aPrincipal); @@ -321,51 +321,51 @@ nsScriptSecurityManager::GetChannelResultPrincipal(nsIChannel* aChannel, return NS_OK; } - bool forceInherit = loadInfo->GetForceInheritPrincipal(); - if (aIgnoreSandboxing && !forceInherit) { - // Check if SEC_FORCE_INHERIT_PRINCIPAL was dropped because of - // sandboxing: - if (loadInfo->GetLoadingSandboxed() && - loadInfo->GetForceInheritPrincipalDropped()) { - forceInherit = true; - } - } - if (forceInherit) { - nsCOMPtr principalToInherit = loadInfo->PrincipalToInherit(); - if (!principalToInherit) { - principalToInherit = loadInfo->TriggeringPrincipal(); - } - principalToInherit.forget(aPrincipal); - return NS_OK; - } - - nsSecurityFlags securityFlags = loadInfo->GetSecurityMode(); - // The data: inheritance flags should only apply to the initial load, - // not to loads that it might have redirected to. - if (loadInfo->RedirectChain().IsEmpty() && - (securityFlags == nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS || - securityFlags == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS || - securityFlags == nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS)) { - - nsCOMPtr uri; - nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri)); - NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr principalToInherit = loadInfo->PrincipalToInherit(); - if (!principalToInherit) { - principalToInherit = loadInfo->TriggeringPrincipal(); - } - bool inheritForAboutBlank = loadInfo->GetAboutBlankInherits(); - - if (nsContentUtils::ChannelShouldInheritPrincipal(principalToInherit, - uri, - inheritForAboutBlank, - false)) { - principalToInherit.forget(aPrincipal); - return NS_OK; - } - } + bool forceInherit = loadInfo->GetForceInheritPrincipal(); + if (aIgnoreSandboxing && !forceInherit) { + // Check if SEC_FORCE_INHERIT_PRINCIPAL was dropped because of + // sandboxing: + if (loadInfo->GetLoadingSandboxed() && + loadInfo->GetForceInheritPrincipalDropped()) { + forceInherit = true; + } } - return GetChannelURIPrincipal(aChannel, aPrincipal); + if (forceInherit) { + nsCOMPtr principalToInherit = loadInfo->PrincipalToInherit(); + if (!principalToInherit) { + principalToInherit = loadInfo->TriggeringPrincipal(); + } + principalToInherit.forget(aPrincipal); + return NS_OK; + } + + nsSecurityFlags securityFlags = loadInfo->GetSecurityMode(); + // The data: inheritance flags should only apply to the initial load, + // not to loads that it might have redirected to. + if (loadInfo->RedirectChain().IsEmpty() && + (securityFlags == nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS || + securityFlags == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS || + securityFlags == nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS)) { + + nsCOMPtr uri; + nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri)); + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr principalToInherit = loadInfo->PrincipalToInherit(); + if (!principalToInherit) { + principalToInherit = loadInfo->TriggeringPrincipal(); + } + bool inheritForAboutBlank = loadInfo->GetAboutBlankInherits(); + + if (nsContentUtils::ChannelShouldInheritPrincipal(principalToInherit, + uri, + inheritForAboutBlank, + false)) { + principalToInherit.forget(aPrincipal); + return NS_OK; + } + } + } + return GetChannelURIPrincipal(aChannel, aPrincipal); } /* The principal of the URI that this channel is loading. This is never From 7e5ea646a59889f7546343f8ec51d057246d6b81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 20 Mar 2017 03:43:26 -0700 Subject: [PATCH 10/46] servo: Merge #16035 - stylo: Sequentialize binding generation if logging is enabled (from emilio:parallel-log-no-fun); r=upsuper Otherwise the log is useless, and it's even slower than in parallel mode due to the high lock contention. Source-Repo: https://github.com/servo/servo Source-Revision: 9fdebf0934bd4fa97414756b9690a88ae63a991c --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 3fd4179805755770bf77025d697e7ddb7227d32c --- servo/components/style/build_gecko.rs | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/servo/components/style/build_gecko.rs b/servo/components/style/build_gecko.rs index a217c6fe0332..15a9d06dc023 100644 --- a/servo/components/style/build_gecko.rs +++ b/servo/components/style/build_gecko.rs @@ -772,17 +772,22 @@ mod bindings { pub fn generate() { use self::common::*; - use std::fs; - use std::thread; + use std::{env, fs, thread}; println!("cargo:rerun-if-changed=build_gecko.rs"); fs::create_dir_all(&*OUTDIR_PATH).unwrap(); bindings::setup_logging(); - let threads = vec![ - thread::spawn(|| bindings::generate_structs(BuildType::Debug)), - thread::spawn(|| bindings::generate_structs(BuildType::Release)), - thread::spawn(|| bindings::generate_bindings()), - ]; - for t in threads.into_iter() { - t.join().unwrap(); + if env::var("STYLO_BUILD_LOG").is_ok() { + bindings::generate_structs(BuildType::Debug); + bindings::generate_structs(BuildType::Release); + bindings::generate_bindings(); + } else { + let threads = vec![ + thread::spawn(|| bindings::generate_structs(BuildType::Debug)), + thread::spawn(|| bindings::generate_structs(BuildType::Release)), + thread::spawn(|| bindings::generate_bindings()), + ]; + for t in threads.into_iter() { + t.join().unwrap(); + } } } From 405f2f52de7de5a3d9e2771c0d8a2ee937c4fe81 Mon Sep 17 00:00:00 2001 From: Thomas Nguyen Date: Mon, 20 Mar 2017 14:43:08 +0800 Subject: [PATCH 11/46] Bug 1345569 - Get blocked info from content when clicking report false deceiptive site from xul browser. r=francois MozReview-Commit-ID: GXkbjfOrnHX --HG-- extra : rebase_source : 7130d656b0dfd2f0cbc64227657347efdce54036 --- browser/base/content/browser.js | 29 +++++++++++ browser/base/content/content.js | 50 +++++++++++-------- .../base/content/report-phishing-overlay.xul | 2 +- .../safebrowsing/safebrowsing.properties | 6 +++ browser/locales/jar.mn | 1 + .../url-classifier/SafeBrowsing.jsm | 4 +- 6 files changed, 70 insertions(+), 22 deletions(-) create mode 100644 browser/locales/en-US/chrome/browser/safebrowsing/safebrowsing.properties diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 5ceca60efb10..60434b687b15 100755 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -6680,6 +6680,35 @@ function BrowserOpenSyncTabs() { gSyncUI.openSyncedTabsPanel(); } +function ReportFalseDeceptiveSite() { + let docURI = gBrowser.selectedBrowser.documentURI; + let isPhishingPage = + docURI && docURI.spec.startsWith("about:blocked?e=deceptiveBlocked"); + + if (isPhishingPage) { + let mm = gBrowser.selectedBrowser.messageManager; + let onMessage = (message) => { + mm.removeMessageListener("DeceptiveBlockedDetails:Result", onMessage); + let reportUrl = gSafeBrowsing.getReportURL("PhishMistake", message.data.blockedInfo); + if (reportUrl) { + openUILinkIn(reportUrl, "tab"); + } else { + let promptService = Cc["@mozilla.org/embedcomp/prompt-service;1"]. + getService(Ci.nsIPromptService); + let bundle = + Services.strings.createBundle("chrome://browser/locale/safebrowsing/safebrowsing.properties"); + promptService.alert(window, + bundle.GetStringFromName("errorReportFalseDeceptiveTitle"), + bundle.formatStringFromName("errorReportFalseDeceptiveMessage", + [message.data.blockedInfo.provider], 1)); + } + } + mm.addMessageListener("DeceptiveBlockedDetails:Result", onMessage); + + mm.sendAsyncMessage("DeceptiveBlockedDetails"); + } +} + /** * Format a URL * eg: diff --git a/browser/base/content/content.js b/browser/base/content/content.js index 1be217b95de6..f34d11f9a323 100644 --- a/browser/base/content/content.js +++ b/browser/base/content/content.js @@ -262,6 +262,35 @@ function getSerializedSecurityInfo(docShell) { return serhelper.serializeToString(securityInfo); } +function getSiteBlockedErrorDetails(docShell) { + let blockedInfo = {}; + if (docShell.failedChannel) { + let classifiedChannel = docShell.failedChannel. + QueryInterface(Ci.nsIClassifiedChannel); + if (classifiedChannel) { + let httpChannel = docShell.failedChannel.QueryInterface(Ci.nsIHttpChannel); + + let reportUri = httpChannel.URI.clone(); + + // Remove the query to avoid leaking sensitive data + if (reportUri instanceof Ci.nsIURL) { + reportUri.query = ""; + } + + blockedInfo = { list: classifiedChannel.matchedList, + provider: classifiedChannel.matchedProvider, + uri: reportUri.asciiSpec }; + } + } + return blockedInfo; +} + +addMessageListener("DeceptiveBlockedDetails", (message) => { + sendAsyncMessage("DeceptiveBlockedDetails:Result", { + blockedInfo: getSiteBlockedErrorDetails(docShell), + }); +}); + var AboutNetAndCertErrorListener = { init(chromeGlobal) { addMessageListener("CertErrorDetails", this); @@ -583,32 +612,13 @@ var ClickEventHandler = { let docShell = ownerDoc.defaultView.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIWebNavigation) .QueryInterface(Ci.nsIDocShell); - let blockedInfo = {}; - if (docShell.failedChannel) { - let classifiedChannel = docShell.failedChannel. - QueryInterface(Ci.nsIClassifiedChannel); - if (classifiedChannel) { - let httpChannel = docShell.failedChannel.QueryInterface(Ci.nsIHttpChannel); - - let reportUri = httpChannel.URI.clone(); - - // Remove the query to avoid leaking sensitive data - if (reportUri instanceof Ci.nsIURL) { - reportUri.query = ""; - } - - blockedInfo = { list: classifiedChannel.matchedList, - provider: classifiedChannel.matchedProvider, - uri: reportUri.asciiSpec }; - } - } sendAsyncMessage("Browser:SiteBlockedError", { location: ownerDoc.location.href, reason, elementId: targetElement.getAttribute("id"), isTopFrame: (ownerDoc.defaultView.parent === ownerDoc.defaultView), - blockedInfo + blockedInfo: getSiteBlockedErrorDetails(docShell), }); }, diff --git a/browser/base/content/report-phishing-overlay.xul b/browser/base/content/report-phishing-overlay.xul index 712079f82479..112bf75a0d88 100644 --- a/browser/base/content/report-phishing-overlay.xul +++ b/browser/base/content/report-phishing-overlay.xul @@ -29,7 +29,7 @@ accesskey="&safeb.palm.notdeceptive.accesskey;" insertbefore="aboutSeparator" observes="reportPhishingErrorBroadcaster" - oncommand="openUILinkIn(gSafeBrowsing.getReportURL('PhishMistake'), 'tab');" + oncommand="ReportFalseDeceptiveSite();" onclick="checkForMiddleClick(this, event);"/> diff --git a/browser/locales/en-US/chrome/browser/safebrowsing/safebrowsing.properties b/browser/locales/en-US/chrome/browser/safebrowsing/safebrowsing.properties new file mode 100644 index 000000000000..aa72ddbffd14 --- /dev/null +++ b/browser/locales/en-US/chrome/browser/safebrowsing/safebrowsing.properties @@ -0,0 +1,6 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +errorReportFalseDeceptiveTitle=This isn’t a deceptive site +errorReportFalseDeceptiveMessage=It’s not possible to report this error at this time. diff --git a/browser/locales/jar.mn b/browser/locales/jar.mn index 35fc613f4536..b1edf111714f 100644 --- a/browser/locales/jar.mn +++ b/browser/locales/jar.mn @@ -54,6 +54,7 @@ locale/browser/places/moveBookmarks.dtd (%chrome/browser/places/moveBookmarks.dtd) locale/browser/safebrowsing/phishing-afterload-warning-message.dtd (%chrome/browser/safebrowsing/phishing-afterload-warning-message.dtd) locale/browser/safebrowsing/report-phishing.dtd (%chrome/browser/safebrowsing/report-phishing.dtd) + locale/browser/safebrowsing/safebrowsing.properties (%chrome/browser/safebrowsing/safebrowsing.properties) locale/browser/feeds/subscribe.dtd (%chrome/browser/feeds/subscribe.dtd) locale/browser/feeds/subscribe.properties (%chrome/browser/feeds/subscribe.properties) locale/browser/migration/migration.dtd (%chrome/browser/migration/migration.dtd) diff --git a/toolkit/components/url-classifier/SafeBrowsing.jsm b/toolkit/components/url-classifier/SafeBrowsing.jsm index 988aab73865f..8e7bd549dc9d 100644 --- a/toolkit/components/url-classifier/SafeBrowsing.jsm +++ b/toolkit/components/url-classifier/SafeBrowsing.jsm @@ -155,7 +155,9 @@ this.SafeBrowsing = { throw err; } - if (!info.list || !info.uri) { + // The "Phish" reports are about submitting new phishing URLs to Google so + // they don't have an associated list URL + if (kind != "Phish" && (!info.list || !info.uri)) { return null; } From f37b8c7128b8b9dc3ab82c0bd8386c5628fffbe8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A3o=20Gottwald?= Date: Sat, 18 Mar 2017 08:40:19 +0100 Subject: [PATCH 12/46] Bug 1348495 - Stop setting padding for .button-box on Linux. r=karlt MozReview-Commit-ID: 7nh452uE5qc --HG-- extra : rebase_source : 51d5baea48a10930d2cb066b535a31bd6f4ab460 --- toolkit/themes/linux/global/button.css | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/toolkit/themes/linux/global/button.css b/toolkit/themes/linux/global/button.css index 6ed09c94ca0b..d7c1399bd0ec 100644 --- a/toolkit/themes/linux/global/button.css +++ b/toolkit/themes/linux/global/button.css @@ -20,10 +20,6 @@ button { .button-box { -moz-appearance: button-focus; - padding-top: 1px; - padding-bottom: 2px; - padding-inline-start: 3px; - padding-inline-end: 4px; } .button-icon { @@ -49,15 +45,6 @@ button[checked="true"] { color: ButtonText; } -button:hover:active > .button-box, -button[open="true"] > .button-box, -button[checked="true"] > .button-box { - padding-top: 2px; - padding-bottom: 1px; - padding-inline-start: 4px; - padding-inline-end: 3px; -} - /* .......... disabled state .......... */ button[disabled="true"], @@ -65,13 +52,6 @@ button[disabled="true"]:hover:active { color: GrayText; } -button[disabled="true"] > .button-box { - padding-top: 1px !important; - padding-bottom: 2px !important; - padding-inline-start: 3px !important; - padding-inline-end: 4px !important; -} - /* ::::: menu/menu-button buttons ::::: */ button[type="menu-button"] { From e612827768aa3a2547a5eb1d5341c0d451d6fe46 Mon Sep 17 00:00:00 2001 From: "Panashe M. Fundira" Date: Mon, 20 Mar 2017 04:23:28 -0700 Subject: [PATCH 13/46] servo: Merge #15918 - PropertyDeclaration with CSSWideKeyword is parsed (from munyari:whitespace); r=emilio Addresses #15401 Source-Repo: https://github.com/servo/servo Source-Revision: 4a63581fadd41f9a1901498e47672c59d44b5fb0 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 96b764da3b2d4dcefbb9d76d2b4715117443c0e0 --- .../style/properties/properties.mako.rs | 4 +++- .../unit/style/properties/serialization.rs | 21 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/servo/components/style/properties/properties.mako.rs b/servo/components/style/properties/properties.mako.rs index f9c2cac07b64..b2a84529f1a6 100644 --- a/servo/components/style/properties/properties.mako.rs +++ b/servo/components/style/properties/properties.mako.rs @@ -1175,7 +1175,9 @@ impl PropertyDeclaration { pub fn value_is_unparsed(&self) -> bool { match *self { PropertyDeclaration::WithVariables(..) => true, - PropertyDeclaration::Custom(..) => true, + PropertyDeclaration::Custom(_, ref value) => { + !matches!(value.borrow(), DeclaredValue::CSSWideKeyword(..)) + } _ => false, } } diff --git a/servo/tests/unit/style/properties/serialization.rs b/servo/tests/unit/style/properties/serialization.rs index 962db4f63d57..218691073703 100644 --- a/servo/tests/unit/style/properties/serialization.rs +++ b/servo/tests/unit/style/properties/serialization.rs @@ -1130,4 +1130,25 @@ mod shorthand_serialization { assert_eq!(serialization, block_text); } } + + mod keywords { + pub use super::*; + #[test] + fn css_wide_keywords_should_be_parsed() { + let block_text = "--a:inherit;"; + let block = parse_declaration_block(block_text); + + let serialization = block.to_css_string(); + assert_eq!(serialization, "--a: inherit;"); + } + + #[test] + fn non_keyword_custom_property_should_be_unparsed() { + let block_text = "--main-color: #06c;"; + let block = parse_declaration_block(block_text); + + let serialization = block.to_css_string(); + assert_eq!(serialization, block_text); + } + } } From 765b21da4d89785a23bd990e7fd57fcbbe08331c Mon Sep 17 00:00:00 2001 From: Ravi Shankar Date: Mon, 20 Mar 2017 05:28:12 -0700 Subject: [PATCH 14/46] servo: Merge #16040 - Cleanup tidy (from Wafflespeanut:tidy); r=Manishearth fixes #16039 Source-Repo: https://github.com/servo/servo Source-Revision: e8b364793416465f6b4877414623dac2c52f2e6a --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : c7241dfee8e223852f59d05b75c88fb20775963f --- servo/python/servo/lints/wpt_lint.py | 6 +++-- servo/python/tidy/servo_tidy/tidy.py | 39 ++++++++++++++-------------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/servo/python/servo/lints/wpt_lint.py b/servo/python/servo/lints/wpt_lint.py index 2160e6d557d4..75c4b72f226b 100644 --- a/servo/python/servo/lints/wpt_lint.py +++ b/servo/python/servo/lints/wpt_lint.py @@ -8,7 +8,7 @@ # except according to those terms. import os -import site +import sys from servo_tidy.tidy import LintRunner, filter_file @@ -28,11 +28,13 @@ class Lint(LintRunner): def run(self): if self.stylo: return + wpt_working_dir = os.path.abspath(os.path.join(WPT_PATH, "web-platform-tests")) for suite in SUITES: files = self._get_wpt_files(suite) - site.addsitedir(wpt_working_dir) + sys.path.insert(0, wpt_working_dir) from tools.lint import lint + sys.path.remove(wpt_working_dir) file_dir = os.path.abspath(os.path.join(WPT_PATH, suite)) returncode = lint.lint(file_dir, files, output_json=False, css_mode=False) if returncode: diff --git a/servo/python/tidy/servo_tidy/tidy.py b/servo/python/tidy/servo_tidy/tidy.py index fff707a736a6..36679cf9b1f1 100644 --- a/servo/python/tidy/servo_tidy/tidy.py +++ b/servo/python/tidy/servo_tidy/tidy.py @@ -111,11 +111,11 @@ def progress_wrapper(iterator): class FileList(object): - def __init__(self, directory, only_changed_files=False, exclude_dirs=[], progress=True, stylo=False): + def __init__(self, directory, only_changed_files=False, exclude_dirs=[], progress=True): self.directory = directory self.excluded = exclude_dirs iterator = self._filter_excluded() if exclude_dirs else self._default_walk() - if only_changed_files and not stylo: + if only_changed_files: try: # Fall back if git doesn't work newiter = self._git_changed_files() @@ -168,10 +168,9 @@ def filter_file(file_name): return True -def filter_files(start_dir, only_changed_files, progress, stylo): +def filter_files(start_dir, only_changed_files, progress): file_iter = FileList(start_dir, only_changed_files=only_changed_files, - exclude_dirs=config["ignore"]["directories"], progress=progress, - stylo=stylo) + exclude_dirs=config["ignore"]["directories"], progress=progress) for file_name in file_iter: base_name = os.path.basename(file_name) if not any(fnmatch.fnmatch(base_name, pattern) for pattern in FILE_PATTERNS_TO_CHECK): @@ -1018,20 +1017,22 @@ class LintRunner(object): dir_name, filename = os.path.split(self.path) sys.path.append(dir_name) module = imp.load_source(filename[:-3], self.path) - if hasattr(module, 'Lint'): - if issubclass(module.Lint, LintRunner): - lint = module.Lint(self.path, self.only_changed_files, - self.exclude_dirs, self.progress, stylo=self.stylo) - for error in lint.run(): - if not hasattr(error, '__iter__'): - yield (self.path, 1, "errors should be a tuple of (path, line, reason)") - return - yield error - else: - yield (self.path, 1, "class 'Lint' should inherit from 'LintRunner'") - else: - yield (self.path, 1, "script should contain a class named 'Lint'") sys.path.remove(dir_name) + if not hasattr(module, 'Lint'): + yield (self.path, 1, "script should contain a class named 'Lint'") + return + + if not issubclass(module.Lint, LintRunner): + yield (self.path, 1, "class 'Lint' should inherit from 'LintRunner'") + return + + lint = module.Lint(self.path, self.only_changed_files, + self.exclude_dirs, self.progress, stylo=self.stylo) + for error in lint.run(): + if type(error) is not tuple or (type(error) is tuple and len(error) != 3): + yield (self.path, 1, "errors should be a tuple of (path, line, reason)") + return + yield error def get_files(self, path, **kwargs): args = ['only_changed_files', 'exclude_dirs', 'progress'] @@ -1071,7 +1072,7 @@ def scan(only_changed_files=False, progress=True, stylo=False): # check directories contain expected files directory_errors = check_directory_files(config['check_ext']) # standard checks - files_to_check = filter_files('.', only_changed_files, progress, stylo) + files_to_check = filter_files('.', only_changed_files and not stylo, progress) checking_functions = (check_flake8, check_lock, check_webidl_spec, check_json, check_yaml) line_checking_functions = (check_license, check_by_line, check_toml, check_shell, check_rust, check_spec, check_modeline) From ef288ed482fbd0bbb4556306798a9042c03362d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 20 Mar 2017 14:27:57 +0100 Subject: [PATCH 15/46] Bug 1341102: Adjust expectations for new passes caused by servo/servo#15918. r=me MozReview-Commit-ID: EY3AMreVcVG --- layout/style/test/stylo-failures.md | 1 - 1 file changed, 1 deletion(-) diff --git a/layout/style/test/stylo-failures.md b/layout/style/test/stylo-failures.md index 604116f8abaa..2f84fe6b7528 100644 --- a/layout/style/test/stylo-failures.md +++ b/layout/style/test/stylo-failures.md @@ -378,7 +378,6 @@ to mochitest command. * background-position invalid 3-value form **issue to be filed** * test_shorthand_property_getters.html `should serialize to 4-value` [2] * test_variables.html `--weird`: name of custom property is not escaped properly servo/servo#15399 [1] - * ... `got "--`: CSS-wide keywords in custom properties servo/servo#15401 [3] * image-layer values should omit some of its parts when they are initial servo/servo#15951 * test_shorthand_property_getters.html `background` [2] * counter-{reset,increment} doesn't serialize none servo/servo#15977 From 4f8d16041f6c50094666e66cc76815cedfca6a88 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Tue, 14 Mar 2017 13:01:10 -0400 Subject: [PATCH 16/46] Bug 1342320 - Use PlacesUtils and not PlacesSyncUtils in sync bookmark decline/undecline test r=markh MozReview-Commit-ID: DgbCeKgSxoE --HG-- extra : rebase_source : d7a73f871436a3c557e3ea921439da3e6f55e13c --- .../sync/tests/unit/test_bookmark_decline_undecline.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/services/sync/tests/unit/test_bookmark_decline_undecline.js b/services/sync/tests/unit/test_bookmark_decline_undecline.js index bcce158d8fce..b503eeee54c4 100644 --- a/services/sync/tests/unit/test_bookmark_decline_undecline.js +++ b/services/sync/tests/unit/test_bookmark_decline_undecline.js @@ -70,13 +70,11 @@ add_task(async function test_decline_undecline() { await SyncTestingInfrastructure(server); try { - let bzGuid = "999999999999"; - await PlacesSyncUtils.bookmarks.insert({ - kind: PlacesSyncUtils.bookmarks.KINDS.BOOKMARK, - syncId: bzGuid, - parentSyncId: "menu", + let { guid: bzGuid } = await PlacesUtils.bookmarks.insert({ + parentGuid: PlacesUtils.bookmarks.menuGuid, url: "https://bugzilla.mozilla.org", - + index: PlacesUtils.bookmarks.DEFAULT_INDEX, + title: "bugzilla", }); ok(!getBookmarkWBO(server, bzGuid), "Shouldn't have been uploaded yet"); From bd2ab930f4a9c586b3dcd0615c40a5710dbce6ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 20 Mar 2017 06:26:38 -0700 Subject: [PATCH 17/46] servo: Merge #15890 - selectors: Check the bloom filter at most once per complex selector (from emilio:bloom); r=heycam Fixes https://github.com/servo/rust-selectors/issues/107 Source-Repo: https://github.com/servo/servo Source-Revision: 4fa40c77036c0635abb6a567146a101d11521cb0 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 409937020b288d2b6b26e988093a03987720231e --- servo/components/selectors/matching.rs | 157 ++++++++++++------------- 1 file changed, 73 insertions(+), 84 deletions(-) diff --git a/servo/components/selectors/matching.rs b/servo/components/selectors/matching.rs index f567b2bc7cac..e100a6f3357b 100644 --- a/servo/components/selectors/matching.rs +++ b/servo/components/selectors/matching.rs @@ -112,12 +112,56 @@ pub fn matches(selector_list: &[Selector], }) } +fn may_match(mut selector: &ComplexSelector, + bf: &BloomFilter) + -> bool + where E: Element, +{ + // See if the bloom filter can exclude any of the descendant selectors, and + // reject if we can. + loop { + match selector.next { + None => break, + Some((ref cs, Combinator::Descendant)) => selector = &**cs, + Some((ref cs, _)) => { + selector = &**cs; + continue; + } + }; + + for ss in selector.compound_selector.iter() { + match *ss { + SimpleSelector::LocalName(LocalName { ref name, ref lower_name }) => { + if !bf.might_contain(name) && + !bf.might_contain(lower_name) { + return false + } + }, + SimpleSelector::Namespace(ref namespace) => { + if !bf.might_contain(&namespace.url) { + return false + } + }, + SimpleSelector::ID(ref id) => { + if !bf.might_contain(id) { + return false + } + }, + SimpleSelector::Class(ref class) => { + if !bf.might_contain(class) { + return false + } + }, + _ => {}, + } + } + } + + // If we haven't proven otherwise, it may match. + true +} + /// Determines whether the given element matches the given complex selector. -/// -/// NB: If you add support for any new kinds of selectors to this routine, be sure to set -/// `shareable` to false unless you are willing to update the style sharing logic. Otherwise things -/// will almost certainly break as elements will start mistakenly sharing styles. (See -/// `can_share_style_with` in `servo/components/style/matching.rs`.) pub fn matches_complex_selector(selector: &ComplexSelector, element: &E, parent_bf: Option<&BloomFilter>, @@ -126,7 +170,13 @@ pub fn matches_complex_selector(selector: &ComplexSelector, -> bool where E: Element { - match matches_complex_selector_internal(selector, element, parent_bf, relations, flags) { + if let Some(filter) = parent_bf { + if !may_match::(selector, filter) { + return false; + } + } + + match matches_complex_selector_internal(selector, element, relations, flags) { SelectorMatchingResult::Matched => { match selector.next { Some((_, Combinator::NextSibling)) | @@ -190,81 +240,19 @@ enum SelectorMatchingResult { NotMatchedGlobally, } -/// Quickly figures out whether or not the complex selector is worth doing more -/// work on. If the simple selectors don't match, or there's a child selector -/// that does not appear in the bloom parent bloom filter, we can exit early. -fn can_fast_reject(mut selector: &ComplexSelector, - element: &E, - parent_bf: Option<&BloomFilter>, - relations: &mut StyleRelations, - flags: &mut ElementSelectorFlags) - -> Option - where E: Element -{ - if !selector.compound_selector.iter().all(|simple_selector| { - matches_simple_selector(simple_selector, element, parent_bf, relations, flags) }) { - return Some(SelectorMatchingResult::NotMatchedAndRestartFromClosestLaterSibling); - } - - let bf: &BloomFilter = match parent_bf { - None => return None, - Some(ref bf) => bf, - }; - - // See if the bloom filter can exclude any of the descendant selectors, and - // reject if we can. - loop { - match selector.next { - None => break, - Some((ref cs, Combinator::Descendant)) => selector = &**cs, - Some((ref cs, _)) => { - selector = &**cs; - continue; - } - }; - - for ss in selector.compound_selector.iter() { - match *ss { - SimpleSelector::LocalName(LocalName { ref name, ref lower_name }) => { - if !bf.might_contain(name) && - !bf.might_contain(lower_name) { - return Some(SelectorMatchingResult::NotMatchedGlobally); - } - }, - SimpleSelector::Namespace(ref namespace) => { - if !bf.might_contain(&namespace.url) { - return Some(SelectorMatchingResult::NotMatchedGlobally); - } - }, - SimpleSelector::ID(ref id) => { - if !bf.might_contain(id) { - return Some(SelectorMatchingResult::NotMatchedGlobally); - } - }, - SimpleSelector::Class(ref class) => { - if !bf.might_contain(class) { - return Some(SelectorMatchingResult::NotMatchedGlobally); - } - }, - _ => {}, - } - } - } - - // Can't fast reject. - None -} - fn matches_complex_selector_internal(selector: &ComplexSelector, - element: &E, - parent_bf: Option<&BloomFilter>, - relations: &mut StyleRelations, - flags: &mut ElementSelectorFlags) - -> SelectorMatchingResult + element: &E, + relations: &mut StyleRelations, + flags: &mut ElementSelectorFlags) + -> SelectorMatchingResult where E: Element { - if let Some(result) = can_fast_reject(selector, element, parent_bf, relations, flags) { - return result; + let matches_all_simple_selectors = selector.compound_selector.iter().all(|simple| { + matches_simple_selector(simple, element, relations, flags) + }); + + if !matches_all_simple_selectors { + return SelectorMatchingResult::NotMatchedAndRestartFromClosestLaterSibling; } match selector.next { @@ -287,10 +275,9 @@ fn matches_complex_selector_internal(selector: &ComplexSelector, Some(next_element) => next_element, }; let result = matches_complex_selector_internal(&**next_selector, - &element, - parent_bf, - relations, - flags); + &element, + relations, + flags); match (result, combinator) { // Return the status immediately. (SelectorMatchingResult::Matched, _) => return result, @@ -332,7 +319,6 @@ fn matches_complex_selector_internal(selector: &ComplexSelector, fn matches_simple_selector( selector: &SimpleSelector, element: &E, - parent_bf: Option<&BloomFilter>, relations: &mut StyleRelations, flags: &mut ElementSelectorFlags) -> bool @@ -466,7 +452,10 @@ fn matches_simple_selector( } SimpleSelector::Negation(ref negated) => { !negated.iter().all(|s| { - matches_complex_selector(s, element, parent_bf, relations, flags) + match matches_complex_selector_internal(s, element, relations, flags) { + SelectorMatchingResult::Matched => true, + _ => false, + } }) } } From f0c29bc5fc916fe61069f653dad3950a7cbb122f Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Thu, 9 Mar 2017 17:33:50 +0800 Subject: [PATCH 18/46] Bug 1338446 Part 1 - Label dispatching ShortTermURISpecCache by using SystemGroup. r=heycam In ErrorReporter::~ErrorReporter(), we dispatch sSpecCache to clear itself. It's not related to content, so label it by using SystemGroup. Use another runnable pointer to keep sSpecCache alive. MozReview-Commit-ID: JN1qrS2jxFs --HG-- extra : rebase_source : ffdd72816e7864cefeabde85f692e837c5fe1bc5 --- layout/style/ErrorReporter.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/layout/style/ErrorReporter.cpp b/layout/style/ErrorReporter.cpp index b57814eb7479..4775a68ef324 100644 --- a/layout/style/ErrorReporter.cpp +++ b/layout/style/ErrorReporter.cpp @@ -11,6 +11,7 @@ #include "mozilla/css/Loader.h" #include "mozilla/Preferences.h" #include "mozilla/Services.h" +#include "mozilla/SystemGroup.h" #include "nsCSSScanner.h" #include "nsIConsoleService.h" #include "nsIDocument.h" @@ -153,7 +154,11 @@ ErrorReporter::~ErrorReporter() // balance between performance and memory usage, so we only allow // short-term caching. if (sSpecCache && sSpecCache->IsInUse() && !sSpecCache->IsPending()) { - if (NS_FAILED(NS_DispatchToCurrentThread(sSpecCache))) { + nsCOMPtr runnable(sSpecCache); + nsresult rv = + SystemGroup::Dispatch("ShortTermURISpecCache", TaskCategory::Other, + runnable.forget()); + if (NS_FAILED(rv)) { // Peform the "deferred" cleanup immediately if the dispatch fails. sSpecCache->Run(); } else { From bef3641333b1d07f8933611006c56b11ae4c854a Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Thu, 9 Mar 2017 18:02:01 +0800 Subject: [PATCH 19/46] Bug 1338446 Part 2 - Label FontFaceSet::CheckLoadingFinishedAfterDelay. r=heycam mDocument is always valid because we get mDocument from the argument of FontFaceSet's constructor, and FontFaceSet is always created in nsIDocument's methods. Delay giving checkTask a name until we dispatch it. No need to name it twice. MozReview-Commit-ID: 6nKYRcRqvQ0 --HG-- extra : rebase_source : 5d7be9c1bcf41ce6fae9ba37a4013144c23fa832 --- layout/style/FontFaceSet.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/layout/style/FontFaceSet.cpp b/layout/style/FontFaceSet.cpp index a35556c8587b..b126e88b66f8 100644 --- a/layout/style/FontFaceSet.cpp +++ b/layout/style/FontFaceSet.cpp @@ -104,6 +104,8 @@ FontFaceSet::FontFaceSet(nsPIDOMWindowInner* aWindow, nsIDocument* aDocument) , mHasLoadingFontFacesIsDirty(false) , mDelayedLoadCheck(false) { + MOZ_ASSERT(mDocument, "We should get a valid document from the caller!"); + nsCOMPtr global = do_QueryInterface(aWindow); // If the pref is not set, don't create the Promise (which the page wouldn't @@ -1473,9 +1475,9 @@ FontFaceSet::OnFontFaceStatusChanged(FontFace* aFontFace) if (!mDelayedLoadCheck) { mDelayedLoadCheck = true; nsCOMPtr checkTask = - NewRunnableMethod("FontFaceSet::CheckLoadingFinishedAfterDelay", - this, &FontFaceSet::CheckLoadingFinishedAfterDelay); - NS_DispatchToMainThread(checkTask); + NewRunnableMethod(this, &FontFaceSet::CheckLoadingFinishedAfterDelay); + mDocument->Dispatch("FontFaceSet::CheckLoadingFinishedAfterDelay", + TaskCategory::Other, checkTask.forget()); } } } From f087300185b874eecd04538f7e7eeae5e992c9fa Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Mon, 13 Mar 2017 17:00:57 +0800 Subject: [PATCH 20/46] Bug 1338446 Part 3 - Label SheetLoadData in Loader::PostLoadEvent. r=heycam When constructing a Loader without passing a document, we added a DocGroup parameter so that we could still use it to dispatch events to the DocGroup. Delete NS_ENSURE_TRUE because new() is infallable. Use another runnable pointer for calling dispatching because forget() will nuke the pointer and we need to use evt afterwards. MozReview-Commit-ID: Ce2K6j4pUhA --HG-- extra : rebase_source : 2bacf1f856e0700f36b2fefe4d2424719cad77a7 --- dom/base/nsDocument.cpp | 3 ++- layout/base/nsDocumentViewer.cpp | 4 ++-- layout/base/nsStyleSheetService.cpp | 2 +- layout/style/CSSStyleSheet.cpp | 2 +- layout/style/Loader.cpp | 23 +++++++++++++++++++---- layout/style/Loader.h | 9 ++++++++- layout/style/PreloadedStyleSheet.cpp | 2 +- layout/style/nsLayoutStylesheetCache.cpp | 2 +- 8 files changed, 35 insertions(+), 12 deletions(-) diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 9df11a64b3b3..d21325719650 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -4406,7 +4406,8 @@ nsDocument::LoadAdditionalStyleSheet(additionalSheetType aType, return NS_ERROR_INVALID_ARG; // Loading the sheet sync. - RefPtr loader = new css::Loader(GetStyleBackendType()); + RefPtr loader = + new css::Loader(GetStyleBackendType(), GetDocGroup()); css::SheetParsingMode parsingMode; switch (aType) { diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index 18b2e7daa91d..5b363899116d 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -2294,8 +2294,8 @@ nsDocumentViewer::CreateStyleSet(nsIDocument* aDocument) nsAutoString sheets; elt->GetAttribute(NS_LITERAL_STRING("usechromesheets"), sheets); if (!sheets.IsEmpty() && baseURI) { - RefPtr cssLoader = - new mozilla::css::Loader(backendType); + RefPtr cssLoader = + new css::Loader(backendType, aDocument->GetDocGroup()); char *str = ToNewCString(sheets); char *newStr = str; diff --git a/layout/base/nsStyleSheetService.cpp b/layout/base/nsStyleSheetService.cpp index d75c330069e0..dc6548ed8ce0 100644 --- a/layout/base/nsStyleSheetService.cpp +++ b/layout/base/nsStyleSheetService.cpp @@ -218,7 +218,7 @@ LoadSheet(nsIURI* aURI, StyleBackendType aType, RefPtr* aResult) { - RefPtr loader = new css::Loader(aType); + RefPtr loader = new css::Loader(aType, nullptr); return loader->LoadSheetSync(aURI, aParsingMode, true, aResult); } diff --git a/layout/style/CSSStyleSheet.cpp b/layout/style/CSSStyleSheet.cpp index afb8e7081e04..84d0f7c9f476 100644 --- a/layout/style/CSSStyleSheet.cpp +++ b/layout/style/CSSStyleSheet.cpp @@ -988,7 +988,7 @@ CSSStyleSheet::ReparseSheet(const nsAString& aInput) loader = mDocument->CSSLoader(); NS_ASSERTION(loader, "Document with no CSS loader!"); } else { - loader = new css::Loader(StyleBackendType::Gecko); + loader = new css::Loader(StyleBackendType::Gecko, nullptr); } mozAutoDocUpdate updateBatch(mDocument, UPDATE_STYLE, true); diff --git a/layout/style/Loader.cpp b/layout/style/Loader.cpp index f6e1f34368a6..10cf9af0acd5 100644 --- a/layout/style/Loader.cpp +++ b/layout/style/Loader.cpp @@ -19,11 +19,12 @@ #include "mozilla/css/Loader.h" #include "mozilla/ArrayUtils.h" +#include "mozilla/dom/DocGroup.h" #include "mozilla/IntegerPrintfMacros.h" #include "mozilla/LoadInfo.h" #include "mozilla/MemoryReporting.h" - #include "mozilla/StyleSheetInlines.h" +#include "mozilla/SystemGroup.h" #include "nsIRunnable.h" #include "nsIUnicharStreamLoader.h" #include "nsSyncLoadService.h" @@ -519,8 +520,9 @@ LoaderReusableStyleSheets::FindReusableStyleSheet(nsIURI* aURL, * Loader Implementation * *************************/ -Loader::Loader(StyleBackendType aType) +Loader::Loader(StyleBackendType aType, DocGroup* aDocGroup) : mDocument(nullptr) + , mDocGroup(aDocGroup) , mDatasToNotifyOn(0) , mCompatMode(eCompatibility_FullStandards) , mStyleBackendType(Some(aType)) @@ -542,6 +544,8 @@ Loader::Loader(nsIDocument* aDocument) , mSyncCallback(false) #endif { + MOZ_ASSERT(mDocument, "We should get a valid document from the caller!"); + // We can just use the preferred set, since there are no sheets in the // document yet (if there are, how did they get there? _we_ load the sheets!) // and hence the selected set makes no sense at this time. @@ -2471,13 +2475,24 @@ Loader::PostLoadEvent(nsIURI* aURI, aObserver, nullptr, mDocument); - NS_ENSURE_TRUE(evt, NS_ERROR_OUT_OF_MEMORY); if (!mPostedEvents.AppendElement(evt)) { return NS_ERROR_OUT_OF_MEMORY; } - nsresult rv = NS_DispatchToCurrentThread(evt); + nsresult rv; + RefPtr runnable(evt); + if (mDocument) { + rv = mDocument->Dispatch("SheetLoadData", TaskCategory::Other, + runnable.forget()); + } else if (mDocGroup) { + rv = mDocGroup->Dispatch("SheetLoadData", TaskCategory::Other, + runnable.forget()); + } else { + rv = SystemGroup::Dispatch("SheetLoadData", TaskCategory::Other, + runnable.forget()); + } + if (NS_FAILED(rv)) { NS_WARNING("failed to dispatch stylesheet load event"); mPostedEvents.RemoveElement(evt); diff --git a/layout/style/Loader.h b/layout/style/Loader.h index 9059e8e6f886..dbeb5e610324 100644 --- a/layout/style/Loader.h +++ b/layout/style/Loader.h @@ -36,6 +36,7 @@ class nsIStyleSheetLinkingElement; namespace mozilla { namespace dom { +class DocGroup; class Element; } // namespace dom } // namespace mozilla @@ -191,7 +192,11 @@ class Loader final { typedef mozilla::net::ReferrerPolicy ReferrerPolicy; public: - explicit Loader(StyleBackendType aType); + // aDocGroup is used for dispatching SheetLoadData in PostLoadEvent(). It + // can be null if you want to use this constructor, and there's no + // document when the Loader is constructed. + Loader(StyleBackendType aType, mozilla::dom::DocGroup* aDocGroup); + explicit Loader(nsIDocument*); private: @@ -574,6 +579,8 @@ private: // DropDocumentReference(). nsIDocument* MOZ_NON_OWNING_REF mDocument; // the document we live for + // For dispatching events via DocGroup::Dispatch() when mDocument is nullptr. + RefPtr mDocGroup; // Number of datas still waiting to be notified on if we're notifying on a // whole bunch at once (e.g. in one of the stop methods). This is used to diff --git a/layout/style/PreloadedStyleSheet.cpp b/layout/style/PreloadedStyleSheet.cpp index e39057fd59ab..276112e7cbd1 100644 --- a/layout/style/PreloadedStyleSheet.cpp +++ b/layout/style/PreloadedStyleSheet.cpp @@ -71,7 +71,7 @@ PreloadedStyleSheet::GetSheet(StyleBackendType aType, StyleSheet** aResult) aType == StyleBackendType::Gecko ? mGecko : mServo; if (!sheet) { - RefPtr loader = new css::Loader(aType); + RefPtr loader = new css::Loader(aType, nullptr); nsresult rv = loader->LoadSheetSync(mURI, mParsingMode, true, &sheet); NS_ENSURE_SUCCESS(rv, rv); MOZ_ASSERT(sheet); diff --git a/layout/style/nsLayoutStylesheetCache.cpp b/layout/style/nsLayoutStylesheetCache.cpp index a28d943410a5..1cfed5e77a7e 100644 --- a/layout/style/nsLayoutStylesheetCache.cpp +++ b/layout/style/nsLayoutStylesheetCache.cpp @@ -773,7 +773,7 @@ nsLayoutStylesheetCache::LoadSheet(nsIURI* aURI, gCSSLoader_Servo; if (!loader) { - loader = new mozilla::css::Loader(mBackendType); + loader = new Loader(mBackendType, nullptr); if (!loader) { ErrorLoadingSheet(aURI, "no Loader", eCrash); return; From dd4484225fa464b89f5316530bd7dc55cb16135f Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Tue, 14 Mar 2017 21:29:55 +0800 Subject: [PATCH 21/46] Bug 1338446 Part 4 - Label StyleImageRequestCleanupTask. r=heycam If nsStyleImageRequest::Resolve() has been called, we cache the DocGroup and use it for dispatching events for the clean up task. Otherwise, it's safe to do clean up task on non-main thread. MozReview-Commit-ID: BXalEkc6dBm --HG-- extra : rebase_source : ccc7c43a385f3149b53763030419561fc64efbfa --- layout/style/nsCSSValue.cpp | 4 +++- layout/style/nsStyleStruct.cpp | 25 ++++++++++++++++++++----- layout/style/nsStyleStruct.h | 3 +++ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/layout/style/nsCSSValue.cpp b/layout/style/nsCSSValue.cpp index 16a5432f93db..bc1b6bc1f181 100644 --- a/layout/style/nsCSSValue.cpp +++ b/layout/style/nsCSSValue.cpp @@ -3057,7 +3057,9 @@ css::ImageValue::Initialize(nsIDocument* aDocument) css::ImageValue::~ImageValue() { - MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(NS_IsMainThread() || mRequests.Count() == 0, + "Destructor should run on main thread, or on non-main thread " + "when mRequest is empty!"); for (auto iter = mRequests.Iter(); !iter.Done(); iter.Next()) { nsIDocument* doc = iter.Key(); diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index 007df3cdfbbe..5bb6d7564940 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -33,6 +33,7 @@ #include "CounterStyleManager.h" #include "mozilla/dom/AnimationEffectReadOnlyBinding.h" // for PlaybackDirection +#include "mozilla/dom/DocGroup.h" #include "mozilla/dom/ImageTracker.h" #include "mozilla/Likely.h" #include "nsIURI.h" @@ -1890,7 +1891,7 @@ nsStyleGradient::HasCalc() /** * Runnable to release the nsStyleImageRequest's mRequestProxy, - * mImageValue and mImageValue on the main thread, and to perform + * mImageValue and mImageTracker on the main thread, and to perform * any necessary unlocking and untracking of the image. */ class StyleImageRequestCleanupTask : public mozilla::Runnable @@ -1911,7 +1912,8 @@ public: NS_IMETHOD Run() final { - MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(!mRequestProxy || NS_IsMainThread(), + "If mRequestProxy is non-null, we need to run on main thread!"); if (!mRequestProxy) { return NS_OK; @@ -1932,7 +1934,15 @@ public: } protected: - virtual ~StyleImageRequestCleanupTask() { MOZ_ASSERT(NS_IsMainThread()); } + virtual ~StyleImageRequestCleanupTask() + { + MOZ_ASSERT(mImageValue->mRequests.Count() == 0 || NS_IsMainThread(), + "If mImageValue has any mRequests, we need to run on main " + "thread to release ImageValues!"); + MOZ_ASSERT((!mRequestProxy && !mImageTracker) || NS_IsMainThread(), + "mRequestProxy and mImageTracker's destructor need to run " + "on the main thread!"); + } private: Mode mModeFlags; @@ -1986,10 +1996,13 @@ nsStyleImageRequest::~nsStyleImageRequest() mRequestProxy.forget(), mImageValue.forget(), mImageTracker.forget()); - if (NS_IsMainThread()) { + if (NS_IsMainThread() || !IsResolved()) { task->Run(); } else { - NS_DispatchToMainThread(task.forget()); + MOZ_ASSERT(IsResolved() == bool(mDocGroup), + "We forgot to cache mDocGroup in Resolve()?"); + mDocGroup->Dispatch("StyleImageRequestCleanupTask", + TaskCategory::Other, task.forget()); } } @@ -2003,8 +2016,10 @@ nsStyleImageRequest::Resolve(nsPresContext* aPresContext) { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(!IsResolved(), "already resolved"); + MOZ_ASSERT(aPresContext); mResolved = true; + mDocGroup = aPresContext->Document()->GetDocGroup(); // For now, just have unique nsCSSValue/ImageValue objects. We should // really store the ImageValue on the Servo specified value, so that we can diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index 500e7cdfc111..1f856654b271 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -385,6 +385,9 @@ private: RefPtr mImageValue; RefPtr mImageTracker; + // Cache DocGroup for dispatching events in the destructor. + RefPtr mDocGroup; + Mode mModeFlags; bool mResolved; }; From e27cc69d635d4290f311a6497b0df86e7050306c Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Tue, 14 Mar 2017 21:34:57 +0800 Subject: [PATCH 22/46] Bug 1338446 Part 5 - Label runnable in Gecko_DropElementSnapshot by using SystemGroup. r=heycam This runnable is to delete object only, so using system group should be fine. MozReview-Commit-ID: 8uMxMO3yERG --HG-- extra : rebase_source : 75ae4953d4c91fa0ab9a0c598a1989fa122f8f5a --- layout/style/ServoBindings.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/layout/style/ServoBindings.cpp b/layout/style/ServoBindings.cpp index 9461a75110bd..1aa3e1563d67 100644 --- a/layout/style/ServoBindings.cpp +++ b/layout/style/ServoBindings.cpp @@ -41,6 +41,7 @@ #include "mozilla/ServoElementSnapshot.h" #include "mozilla/ServoRestyleManager.h" #include "mozilla/StyleAnimationValue.h" +#include "mozilla/SystemGroup.h" #include "mozilla/DeclarationBlockInlines.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/ElementInlines.h" @@ -344,7 +345,8 @@ Gecko_DropElementSnapshot(ServoElementSnapshotOwned aSnapshot) // descendants of a new display:none root). if (MOZ_UNLIKELY(!NS_IsMainThread())) { nsCOMPtr task = NS_NewRunnableFunction([=]() { delete aSnapshot; }); - NS_DispatchToMainThread(task.forget()); + SystemGroup::Dispatch("Gecko_DropElementSnapshot", TaskCategory::Other, + task.forget()); } else { delete aSnapshot; } From 44a41925d33e4a9ff4fe1a78882caf866358eccd Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Tue, 14 Mar 2017 21:57:34 +0800 Subject: [PATCH 23/46] Bug 1338446 Part 6 - Label LoadTimer in nsFontFaceLoader::StartedLoading. r=heycam Delete #include "mozilla/Logging.h" because it has been included. Add FontFaceSet::Document() to get valid document for nsFontFaceLoader. MozReview-Commit-ID: IAXM9UgvjOE --HG-- extra : rebase_source : e5aa8aadea5e2f9f2e5d73cc718318cf97471d3f --- layout/style/FontFaceSet.h | 2 ++ layout/style/nsFontFaceLoader.cpp | 15 +++++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/layout/style/FontFaceSet.h b/layout/style/FontFaceSet.h index d08fbaf8c8cf..a1473dad61db 100644 --- a/layout/style/FontFaceSet.h +++ b/layout/style/FontFaceSet.h @@ -162,6 +162,8 @@ public: return set ? set->GetPresContext() : nullptr; } + nsIDocument* Document() const { return mDocument; } + // -- Web IDL -------------------------------------------------------------- IMPL_EVENT_HANDLER(loading) diff --git a/layout/style/nsFontFaceLoader.cpp b/layout/style/nsFontFaceLoader.cpp index 2f0ccd634e88..d8bdee0dd063 100644 --- a/layout/style/nsFontFaceLoader.cpp +++ b/layout/style/nsFontFaceLoader.cpp @@ -11,8 +11,6 @@ #include "nsFontFaceLoader.h" -#include "mozilla/Logging.h" - #include "nsError.h" #include "nsContentUtils.h" #include "mozilla/Preferences.h" @@ -55,6 +53,8 @@ nsFontFaceLoader::nsFontFaceLoader(gfxUserFontEntry* aUserFontEntry, mFontFaceSet(aFontFaceSet), mChannel(aChannel) { + MOZ_ASSERT(mFontFaceSet, + "We should get a valid FontFaceSet from the caller!"); mStartTime = TimeStamp::Now(); } @@ -87,10 +87,13 @@ nsFontFaceLoader::StartedLoading(nsIStreamLoader* aStreamLoader) if (loadTimeout > 0) { mLoadTimer = do_CreateInstance("@mozilla.org/timer;1"); if (mLoadTimer) { - mLoadTimer->InitWithFuncCallback(LoadTimerCallback, - static_cast(this), - loadTimeout, - nsITimer::TYPE_ONE_SHOT); + mLoadTimer->SetTarget( + mFontFaceSet->Document()->EventTargetFor(TaskCategory::Other)); + mLoadTimer->InitWithNamedFuncCallback(LoadTimerCallback, + static_cast(this), + loadTimeout, + nsITimer::TYPE_ONE_SHOT, + "LoadTimerCallback"); } } else { mUserFontEntry->mFontDataLoadingState = gfxUserFontEntry::LOADING_SLOWLY; From 8a533e93cf5c7337eb0298e69acde95402bc657c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Sat, 18 Mar 2017 19:41:39 +0300 Subject: [PATCH 24/46] Bug 1341642 - Stylo: Add support for -moz-* pseudo-classes for alt text r=manishearth MozReview-Commit-ID: 1t42xaTtUmb --HG-- extra : rebase_source : 58072c6ea9df8a931671450f31e345e872ef6e53 --- dom/events/EventStates.h | 54 ++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/dom/events/EventStates.h b/dom/events/EventStates.h index b1b9654ef198..ddab2cdf8beb 100644 --- a/dom/events/EventStates.h +++ b/dom/events/EventStates.h @@ -12,7 +12,7 @@ namespace mozilla { -#define NS_EVENT_STATE_HIGHEST_SERVO_BIT 12 +#define NS_EVENT_STATE_HIGHEST_SERVO_BIT 19 /** * EventStates is the class used to represent the event states of nsIContent @@ -223,6 +223,21 @@ private: #define NS_EVENT_STATE_INVALID NS_DEFINE_EVENT_STATE_MACRO(11) // UI friendly version of :valid pseudo-class. #define NS_EVENT_STATE_MOZ_UI_VALID NS_DEFINE_EVENT_STATE_MACRO(12) +// Content could not be rendered (image/object/etc). +#define NS_EVENT_STATE_BROKEN NS_DEFINE_EVENT_STATE_MACRO(13) +// Content disabled by the user (images turned off, say). +#define NS_EVENT_STATE_USERDISABLED NS_DEFINE_EVENT_STATE_MACRO(14) +// Content suppressed by the user (ad blocking, etc). +#define NS_EVENT_STATE_SUPPRESSED NS_DEFINE_EVENT_STATE_MACRO(15) +// Content is still loading such that there is nothing to show the +// user (eg an image which hasn't started coming in yet). +#define NS_EVENT_STATE_LOADING NS_DEFINE_EVENT_STATE_MACRO(16) +// Handler for the content has been blocked. +#define NS_EVENT_STATE_HANDLER_BLOCKED NS_DEFINE_EVENT_STATE_MACRO(17) +// Handler for the content has been disabled. +#define NS_EVENT_STATE_HANDLER_DISABLED NS_DEFINE_EVENT_STATE_MACRO(18) +// Handler for the content has crashed +#define NS_EVENT_STATE_HANDLER_CRASHED NS_DEFINE_EVENT_STATE_MACRO(19) /* * Bits below here do not have Servo-related ordering constraints. @@ -232,42 +247,27 @@ private: */ // Drag is hovering over content. -#define NS_EVENT_STATE_DRAGOVER NS_DEFINE_EVENT_STATE_MACRO(13) +#define NS_EVENT_STATE_DRAGOVER NS_DEFINE_EVENT_STATE_MACRO(20) // Content is required. -#define NS_EVENT_STATE_REQUIRED NS_DEFINE_EVENT_STATE_MACRO(14) +#define NS_EVENT_STATE_REQUIRED NS_DEFINE_EVENT_STATE_MACRO(21) // Content is optional (and can be required). -#define NS_EVENT_STATE_OPTIONAL NS_DEFINE_EVENT_STATE_MACRO(15) +#define NS_EVENT_STATE_OPTIONAL NS_DEFINE_EVENT_STATE_MACRO(22) // Link has been visited. -#define NS_EVENT_STATE_VISITED NS_DEFINE_EVENT_STATE_MACRO(16) +#define NS_EVENT_STATE_VISITED NS_DEFINE_EVENT_STATE_MACRO(23) // Link hasn't been visited. -#define NS_EVENT_STATE_UNVISITED NS_DEFINE_EVENT_STATE_MACRO(17) +#define NS_EVENT_STATE_UNVISITED NS_DEFINE_EVENT_STATE_MACRO(24) // Content value is in-range (and can be out-of-range). -#define NS_EVENT_STATE_INRANGE NS_DEFINE_EVENT_STATE_MACRO(18) +#define NS_EVENT_STATE_INRANGE NS_DEFINE_EVENT_STATE_MACRO(25) // Content value is out-of-range. -#define NS_EVENT_STATE_OUTOFRANGE NS_DEFINE_EVENT_STATE_MACRO(19) +#define NS_EVENT_STATE_OUTOFRANGE NS_DEFINE_EVENT_STATE_MACRO(26) // These two are temporary (see bug 302188) // Content is read-only. -#define NS_EVENT_STATE_MOZ_READONLY NS_DEFINE_EVENT_STATE_MACRO(20) +#define NS_EVENT_STATE_MOZ_READONLY NS_DEFINE_EVENT_STATE_MACRO(27) // Content is editable. -#define NS_EVENT_STATE_MOZ_READWRITE NS_DEFINE_EVENT_STATE_MACRO(21) +#define NS_EVENT_STATE_MOZ_READWRITE NS_DEFINE_EVENT_STATE_MACRO(28) // Content is the default one (meaning depends of the context). -#define NS_EVENT_STATE_DEFAULT NS_DEFINE_EVENT_STATE_MACRO(22) -// Content could not be rendered (image/object/etc). -#define NS_EVENT_STATE_BROKEN NS_DEFINE_EVENT_STATE_MACRO(23) -// Content disabled by the user (images turned off, say). -#define NS_EVENT_STATE_USERDISABLED NS_DEFINE_EVENT_STATE_MACRO(24) -// Content suppressed by the user (ad blocking, etc). -#define NS_EVENT_STATE_SUPPRESSED NS_DEFINE_EVENT_STATE_MACRO(25) -// Content is still loading such that there is nothing to show the -// user (eg an image which hasn't started coming in yet). -#define NS_EVENT_STATE_LOADING NS_DEFINE_EVENT_STATE_MACRO(26) -#define NS_EVENT_STATE_INCREMENT_SCRIPT_LEVEL NS_DEFINE_EVENT_STATE_MACRO(27) -// Handler for the content has been blocked. -#define NS_EVENT_STATE_HANDLER_BLOCKED NS_DEFINE_EVENT_STATE_MACRO(28) -// Handler for the content has been disabled. -#define NS_EVENT_STATE_HANDLER_DISABLED NS_DEFINE_EVENT_STATE_MACRO(29) -// Handler for the content has crashed -#define NS_EVENT_STATE_HANDLER_CRASHED NS_DEFINE_EVENT_STATE_MACRO(30) +#define NS_EVENT_STATE_DEFAULT NS_DEFINE_EVENT_STATE_MACRO(29) +#define NS_EVENT_STATE_INCREMENT_SCRIPT_LEVEL NS_DEFINE_EVENT_STATE_MACRO(30) // Content has focus and should show a ring. #define NS_EVENT_STATE_FOCUSRING NS_DEFINE_EVENT_STATE_MACRO(31) // Content is a submit control and the form isn't valid. From 6d7bb2e928c71132991409c63ead2c21288baacc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Mon, 20 Mar 2017 17:47:59 +0300 Subject: [PATCH 25/46] Bug 1341642 - Add a reftest for :-moz-broken r=emilio MozReview-Commit-ID: FiWwxDq47W1 --HG-- extra : rebase_source : fae032d6a4d060cacb2c8b2069cfa4368dc59b07 --- layout/reftests/image/moz-broken-matching-1-ref.html | 7 +++++++ layout/reftests/image/moz-broken-matching-1.html | 7 +++++++ layout/reftests/image/reftest.list | 2 ++ 3 files changed, 16 insertions(+) create mode 100644 layout/reftests/image/moz-broken-matching-1-ref.html create mode 100644 layout/reftests/image/moz-broken-matching-1.html diff --git a/layout/reftests/image/moz-broken-matching-1-ref.html b/layout/reftests/image/moz-broken-matching-1-ref.html new file mode 100644 index 000000000000..94bb5e4962b7 --- /dev/null +++ b/layout/reftests/image/moz-broken-matching-1-ref.html @@ -0,0 +1,7 @@ + + + diff --git a/layout/reftests/image/moz-broken-matching-1.html b/layout/reftests/image/moz-broken-matching-1.html new file mode 100644 index 000000000000..eb63194e140b --- /dev/null +++ b/layout/reftests/image/moz-broken-matching-1.html @@ -0,0 +1,7 @@ + + + diff --git a/layout/reftests/image/reftest.list b/layout/reftests/image/reftest.list index 588034fb0a4b..e4e4d7b2f266 100644 --- a/layout/reftests/image/reftest.list +++ b/layout/reftests/image/reftest.list @@ -126,3 +126,5 @@ fuzzy(1,1) == image-orientation-background.html?90&flip image-orientation-r == image-resize-percent-height.html image-resize-ref.html == image-resize-percent-width.html image-resize-ref.html + +== moz-broken-matching-1.html moz-broken-matching-1-ref.html From 4f6cfa8bc70f48afaa639be7b4b8f4b9fcd3b634 Mon Sep 17 00:00:00 2001 From: Shawn Huang Date: Mon, 20 Mar 2017 18:34:15 +0800 Subject: [PATCH 26/46] Bug 1348214 - Clear storage per origin when loading storage test cases, r=jgraham MozReview-Commit-ID: ndsajg7Glb --HG-- extra : rebase_source : 847950b2eaf7f9e1cf779ed5d3c707bc745dd11c --- .../wptrunner/executors/executormarionette.py | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/testing/web-platform/harness/wptrunner/executors/executormarionette.py b/testing/web-platform/harness/wptrunner/executors/executormarionette.py index 128828e60bd8..174f64b671da 100644 --- a/testing/web-platform/harness/wptrunner/executors/executormarionette.py +++ b/testing/web-platform/harness/wptrunner/executors/executormarionette.py @@ -264,6 +264,23 @@ class MarionetteProtocol(Protocol): with self.marionette.using_context(self.marionette.CONTEXT_CHROME): self.marionette.execute_script(script) + def clear_origin(self, url): + self.logger.info("Clearing origin %s" % (url)) + script = """ + let url = '%s'; + let uri = Components.classes["@mozilla.org/network/io-service;1"] + .getService(Ci.nsIIOService) + .newURI(url); + let ssm = Components.classes["@mozilla.org/scriptsecuritymanager;1"] + .getService(Ci.nsIScriptSecurityManager); + let principal = ssm.createCodebasePrincipal(uri, {}); + let qms = Components.classes["@mozilla.org/dom/quota-manager-service;1"] + .getService(Components.interfaces.nsIQuotaManagerService); + qms.clearStoragesForPrincipal(principal, "default", true); + """ % url + with self.marionette.using_context(self.marionette.CONTEXT_CHROME): + self.marionette.execute_script(script) + class RemoteMarionetteProtocol(Protocol): def __init__(self, executor, browser): @@ -325,6 +342,11 @@ class ExecuteAsyncScriptRun(object): self.result_flag = threading.Event() def run(self): + index = self.url.rfind("/storage/"); + if index != -1: + # Clear storage + self.protocol.clear_origin(self.url) + timeout = self.timeout try: From 14f92d0eed183e64ef1ac7b8d9737bc59bcceed5 Mon Sep 17 00:00:00 2001 From: Patrick Brosset Date: Mon, 20 Mar 2017 14:05:21 +0100 Subject: [PATCH 27/46] Bug 1301015 - Re-enable some devtools tests on e10s-multi; r=krizsa Some devtools tests had been forced to run in e10s with just 1 content process in bug 1301340 and bug 1303113 because they were failing. Now there seems to have been enough e10s messaging fixes that these tests work again. It seems safe to re-enable multi-content-processes for them now. MozReview-Commit-ID: ENfDdIXvIAI --HG-- extra : rebase_source : 9f29d7f58088b3a99a3512b9f7e73525cb9a6e7e --- devtools/client/aboutdebugging/test/browser_tabs.js | 6 ------ .../test/browser_animation_spacebar_toggles_animations.js | 6 ------ .../test/browser/browser_toolbox_swap_browsers.js | 6 ------ .../browser_webconsole_show_subresource_security_errors.js | 6 ------ devtools/client/webconsole/test/browser_webconsole_split.js | 4 ---- .../tests/browser/browser_animation_getMultipleStates.js | 6 ------ 6 files changed, 34 deletions(-) diff --git a/devtools/client/aboutdebugging/test/browser_tabs.js b/devtools/client/aboutdebugging/test/browser_tabs.js index e82090607fa5..99e76be5d969 100644 --- a/devtools/client/aboutdebugging/test/browser_tabs.js +++ b/devtools/client/aboutdebugging/test/browser_tabs.js @@ -5,12 +5,6 @@ const TAB_URL = "data:text/html,foo"; -add_task(function* setup() { - yield SpecialPowers.pushPrefEnv({ - set: [["dom.ipc.processCount", 1]] - }); -}); - add_task(function* () { let { tab, document } = yield openAboutDebugging("tabs"); diff --git a/devtools/client/animationinspector/test/browser_animation_spacebar_toggles_animations.js b/devtools/client/animationinspector/test/browser_animation_spacebar_toggles_animations.js index 799ecc28db78..593dbe685c21 100644 --- a/devtools/client/animationinspector/test/browser_animation_spacebar_toggles_animations.js +++ b/devtools/client/animationinspector/test/browser_animation_spacebar_toggles_animations.js @@ -4,12 +4,6 @@ "use strict"; -add_task(function* setup() { - yield SpecialPowers.pushPrefEnv({ - set: [["dom.ipc.processCount", 1]] - }); -}); - // Test that the spacebar key press toggles the toggleAll button state // when a node with no animation is selected. // This test doesn't need to test if animations actually pause/resume diff --git a/devtools/client/responsive.html/test/browser/browser_toolbox_swap_browsers.js b/devtools/client/responsive.html/test/browser/browser_toolbox_swap_browsers.js index 8f7afaf010c2..26bc4d1ee714 100644 --- a/devtools/client/responsive.html/test/browser/browser_toolbox_swap_browsers.js +++ b/devtools/client/responsive.html/test/browser/browser_toolbox_swap_browsers.js @@ -30,12 +30,6 @@ let checkToolbox = Task.async(function* (tab, location) { ok(!!gDevTools.getToolbox(target), `Toolbox exists ${location}`); }); -add_task(function* setup() { - yield SpecialPowers.pushPrefEnv({ - set: [["dom.ipc.processCount", 1]] - }); -}); - add_task(function* () { let tab = yield addTab(TEST_URL); diff --git a/devtools/client/webconsole/test/browser_webconsole_show_subresource_security_errors.js b/devtools/client/webconsole/test/browser_webconsole_show_subresource_security_errors.js index 43cb96bdc487..2f2238d1fbbb 100644 --- a/devtools/client/webconsole/test/browser_webconsole_show_subresource_security_errors.js +++ b/devtools/client/webconsole/test/browser_webconsole_show_subresource_security_errors.js @@ -13,12 +13,6 @@ const TEST_DOC = "https://example.com/browser/devtools/client/webconsole/" + "test/test_bug1092055_shouldwarn.html"; const SAMPLE_MSG = "specified a header that could not be parsed successfully."; -add_task(function* setup() { - yield SpecialPowers.pushPrefEnv({ - set: [["dom.ipc.processCount", 1]] - }); -}); - add_task(function* () { let { browser } = yield loadTab(TEST_URI); diff --git a/devtools/client/webconsole/test/browser_webconsole_split.js b/devtools/client/webconsole/test/browser_webconsole_split.js index a855a246922c..bb858d1c192a 100644 --- a/devtools/client/webconsole/test/browser_webconsole_split.js +++ b/devtools/client/webconsole/test/browser_webconsole_split.js @@ -9,10 +9,6 @@ const TEST_URI = "data:text/html;charset=utf-8,Web Console test for splitting"; function test() { waitForExplicitFinish(); - SpecialPowers.pushPrefEnv({"set": [["dom.ipc.processCount", 1]]}, runTest); -} - -function runTest() { // Test is slow on Linux EC2 instances - Bug 962931 requestLongerTimeout(2); diff --git a/devtools/server/tests/browser/browser_animation_getMultipleStates.js b/devtools/server/tests/browser/browser_animation_getMultipleStates.js index 4436695b0124..2e78aceb61f5 100644 --- a/devtools/server/tests/browser/browser_animation_getMultipleStates.js +++ b/devtools/server/tests/browser/browser_animation_getMultipleStates.js @@ -4,12 +4,6 @@ "use strict"; -add_task(function* setup() { - yield SpecialPowers.pushPrefEnv({ - set: [["dom.ipc.processCount", 1]] - }); -}); - // Check that the duration, iterationCount and delay are retrieved correctly for // multiple animations. From 6896b92768175cd5575c50d0adf81dec2071d7ee Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Mon, 20 Mar 2017 08:31:25 -0700 Subject: [PATCH 28/46] servo: Merge #16045 - Bug 1348487 - stylo: Don't allow combinators in :-moz-any (from mbrubeck:any); r=emilio https://bugzilla.mozilla.org/show_bug.cgi?id=1348487 Source-Repo: https://github.com/servo/servo Source-Revision: 17098ddc8ffde03945387f98f52d1856ff1a8cd8 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 274906c936cbfbaa2cbc04414723e62c56fe348a --- servo/components/style/gecko/selector_parser.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/servo/components/style/gecko/selector_parser.rs b/servo/components/style/gecko/selector_parser.rs index 8b3b019dc772..25785beee023 100644 --- a/servo/components/style/gecko/selector_parser.rs +++ b/servo/components/style/gecko/selector_parser.rs @@ -341,6 +341,10 @@ impl<'a> ::selectors::Parser for SelectorParser<'a> { let selectors = parser.parse_comma_separated(|input| { ComplexSelector::parse(self, input) })?; + // Selectors inside `:-moz-any` may not include combinators. + if selectors.iter().any(|s| s.next.is_some()) { + return Err(()) + } NonTSPseudoClass::MozAny(selectors) } _ => return Err(()) From 459dc06e8acf9def2625abb2a9b0c271390d350b Mon Sep 17 00:00:00 2001 From: Kirk Steuber Date: Fri, 10 Mar 2017 14:06:49 -0800 Subject: [PATCH 29/46] Bug 1346405 - Update build/pgo/certs/README so instructions are current and applicable cross-platform r=ted MozReview-Commit-ID: LfhNX9WH0zZ --HG-- extra : rebase_source : cf04c0d266fc378b0ae2278426a0a2c908c9930b --- build/pgo/certs/README | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build/pgo/certs/README b/build/pgo/certs/README index ba2b346f9ad9..a005ec95ebd2 100644 --- a/build/pgo/certs/README +++ b/build/pgo/certs/README @@ -1,9 +1,9 @@ The certificate authority and server certificates here are generated by $topsrcdir/build/pgo/genpgocert.py. You can generate a new CA cert by running: -$objdir/_virtualenv/bin/python $topsrcdir/build/pgo/genpgocert.py --gen-ca +./mach python build/pgo/genpgocert.py --gen-ca You can generate new server certificates by running: -$objdir/_virtualenv/bin/python $topsrcdir/build/pgo/genpgocert.py --gen-server +./mach python build/pgo/genpgocert.py --gen-server -These will place the new files in this directory where you can commit them. +These commands will modify cert8.db and key3.db. The changes to these should be committed. From 7b64f6d5456599fbf20e58e764d5de149a46dbe6 Mon Sep 17 00:00:00 2001 From: Gabriele Svelto Date: Tue, 14 Mar 2017 14:37:26 +0100 Subject: [PATCH 30/46] Bug 1319071 - Make crash minidumps use the same format for filenames on Linux as on other platforms; r=ted This patch forks the breakpad files used for GUID generation and replaces them with copies living together with the rest of the forked sources. Since other files in the breakpad sources rely on the original files being present they haven't been removed but we deliberately define their inclusion definitions in the build system to prevent them from contributing to the build. This ensures that we always use our own version of the GUID generator while not touching the non-forked sources. MozReview-Commit-ID: 5kW74yAPUDW --HG-- rename : toolkit/crashreporter/google-breakpad/src/common/linux/guid_creator.cc => toolkit/crashreporter/breakpad-client/linux/handler/guid_generator.cc rename : toolkit/crashreporter/google-breakpad/src/common/linux/guid_creator.h => toolkit/crashreporter/breakpad-client/linux/handler/guid_generator.h extra : rebase_source : 60eb027258833996777469d2a13142077486bee9 --- .../crash_generation_server.cc | 2 +- .../linux/handler/guid_generator.cc | 108 ++++++++++++++++++ .../linux/handler/guid_generator.h | 48 ++++++++ .../linux/handler/minidump_descriptor.cc | 3 +- .../breakpad-client/linux/moz.build | 5 + .../src/common/linux/moz.build | 2 - tools/profiler/moz.build | 1 - 7 files changed, 163 insertions(+), 6 deletions(-) create mode 100644 toolkit/crashreporter/breakpad-client/linux/handler/guid_generator.cc create mode 100644 toolkit/crashreporter/breakpad-client/linux/handler/guid_generator.h diff --git a/toolkit/crashreporter/breakpad-client/linux/crash_generation/crash_generation_server.cc b/toolkit/crashreporter/breakpad-client/linux/crash_generation/crash_generation_server.cc index de1bfeb56a03..cb15941746d5 100644 --- a/toolkit/crashreporter/breakpad-client/linux/crash_generation/crash_generation_server.cc +++ b/toolkit/crashreporter/breakpad-client/linux/crash_generation/crash_generation_server.cc @@ -44,9 +44,9 @@ #include "linux/crash_generation/crash_generation_server.h" #include "linux/crash_generation/client_info.h" #include "linux/handler/exception_handler.h" +#include "linux/handler/guid_generator.h" #include "linux/minidump_writer/minidump_writer.h" #include "common/linux/eintr_wrapper.h" -#include "common/linux/guid_creator.h" #include "common/linux/safe_readlink.h" static const char kCommandQuit = 'x'; diff --git a/toolkit/crashreporter/breakpad-client/linux/handler/guid_generator.cc b/toolkit/crashreporter/breakpad-client/linux/handler/guid_generator.cc new file mode 100644 index 000000000000..b0ef05bd9d0e --- /dev/null +++ b/toolkit/crashreporter/breakpad-client/linux/handler/guid_generator.cc @@ -0,0 +1,108 @@ +// Copyright (c) 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "linux/handler/guid_generator.h" + +#include +#include +#include +#include +#include +#include + +// +// GUIDGenerator +// +// This class is used to generate random GUID. +// Currently use random number to generate a GUID since Linux has +// no native GUID generator. This should be OK since we don't expect +// crash to happen very offen. +// +class GUIDGenerator { + public: + static uint16_t BytesToUInt16(const uint8_t bytes[]) { + return ((uint16_t) bytes[1] << 8) | ((uint16_t) bytes[0]); + } + + // The last field in a GUID is 48 bits long so we're converting only 6 bytes + static uint64_t BytesToUInt48(const uint8_t bytes[]) { + return ((uint64_t) bytes[0] << 40) | ((uint64_t) bytes[1] << 32) | + ((uint64_t) bytes[2] << 24) | ((uint64_t) bytes[3] << 16) | + ((uint64_t) bytes[4] << 8) | (uint64_t) bytes[5]; + } + + static void UInt32ToBytes(uint8_t bytes[], uint32_t n) { + bytes[0] = n & 0xff; + bytes[1] = (n >> 8) & 0xff; + bytes[2] = (n >> 16) & 0xff; + bytes[3] = (n >> 24) & 0xff; + } + + static bool CreateGUID(GUID *guid) { + InitOnce(); + guid->data1 = random(); + guid->data2 = (uint16_t)(random()); + guid->data3 = (uint16_t)(random()); + UInt32ToBytes(&guid->data4[0], random()); + UInt32ToBytes(&guid->data4[4], random()); + return true; + } + + private: + static void InitOnce() { + pthread_once(&once_control, &InitOnceImpl); + } + + static void InitOnceImpl() { + srandom(time(NULL)); + } + + static pthread_once_t once_control; +}; + +pthread_once_t GUIDGenerator::once_control = PTHREAD_ONCE_INIT; + +bool CreateGUID(GUID *guid) { + return GUIDGenerator::CreateGUID(guid); +} + +// Parse guid to string. +bool GUIDToString(const GUID *guid, char *buf, size_t buf_len) { + // Should allow more space the the max length of GUID. + assert(buf_len > kGUIDStringLength); + int num = snprintf(buf, buf_len, kGUIDFormatString, + guid->data1, guid->data2, guid->data3, + GUIDGenerator::BytesToUInt16(&(guid->data4[0])), + GUIDGenerator::BytesToUInt48(&(guid->data4[2]))); + if (num != kGUIDStringLength) + return false; + + buf[num] = '\0'; + return true; +} diff --git a/toolkit/crashreporter/breakpad-client/linux/handler/guid_generator.h b/toolkit/crashreporter/breakpad-client/linux/handler/guid_generator.h new file mode 100644 index 000000000000..de97eda1cbdc --- /dev/null +++ b/toolkit/crashreporter/breakpad-client/linux/handler/guid_generator.h @@ -0,0 +1,48 @@ +// Copyright (c) 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef LINUX_HANDLER_GUID_GENERATOR_H__ +#define LINUX_HANDLER_GUID_GENERATOR_H__ + +#include "google_breakpad/common/minidump_format.h" + +typedef MDGUID GUID; + +// Format string for parsing GUID. +const char kGUIDFormatString[] = "%08x-%04x-%04x-%04x-%012" PRIx64; +// Length of GUID string. Don't count the ending '\0'. +const size_t kGUIDStringLength = 36; + +// Create a guid. +bool CreateGUID(GUID *guid); + +// Get the string from guid. +bool GUIDToString(const GUID *guid, char *buf, size_t buf_len); + +#endif diff --git a/toolkit/crashreporter/breakpad-client/linux/handler/minidump_descriptor.cc b/toolkit/crashreporter/breakpad-client/linux/handler/minidump_descriptor.cc index 4d4bd162805d..f61db98d5a39 100644 --- a/toolkit/crashreporter/breakpad-client/linux/handler/minidump_descriptor.cc +++ b/toolkit/crashreporter/breakpad-client/linux/handler/minidump_descriptor.cc @@ -29,10 +29,9 @@ #include +#include "linux/handler/guid_generator.h" #include "linux/handler/minidump_descriptor.h" -#include "common/linux/guid_creator.h" - namespace google_breakpad { //static diff --git a/toolkit/crashreporter/breakpad-client/linux/moz.build b/toolkit/crashreporter/breakpad-client/linux/moz.build index 71a4389406d2..73a08eb16e62 100644 --- a/toolkit/crashreporter/breakpad-client/linux/moz.build +++ b/toolkit/crashreporter/breakpad-client/linux/moz.build @@ -10,6 +10,7 @@ UNIFIED_SOURCES += [ 'dump_writer_common/thread_info.cc', 'dump_writer_common/ucontext_reader.cc', 'handler/exception_handler.cc', + 'handler/guid_generator.cc', 'handler/minidump_descriptor.cc', 'log/log.cc', 'microdump_writer/microdump_writer.cc', @@ -18,6 +19,10 @@ UNIFIED_SOURCES += [ 'minidump_writer/minidump_writer.cc', ] +# On Linux we override the guid_creator.h header and use our own instead +if CONFIG['OS_TARGET'] == 'Linux' or CONFIG['OS_TARGET'] == 'Android': + DEFINES['COMMON_LINUX_GUID_CREATOR_H__'] = 1 + if CONFIG['OS_TARGET'] == 'Android': LOCAL_INCLUDES += [ '/toolkit/crashreporter/google-breakpad/src/common/android/include', diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/moz.build b/toolkit/crashreporter/google-breakpad/src/common/linux/moz.build index 7450f6ba3f29..75e1ea2df162 100644 --- a/toolkit/crashreporter/google-breakpad/src/common/linux/moz.build +++ b/toolkit/crashreporter/google-breakpad/src/common/linux/moz.build @@ -6,7 +6,6 @@ UNIFIED_SOURCES += [ 'elfutils.cc', - 'guid_creator.cc', 'linux_libc_support.cc', 'memory_mapped_file.cc', 'safe_readlink.cc', @@ -29,7 +28,6 @@ HOST_SOURCES += [ 'elf_symbols_to_module.cc', 'elfutils.cc', 'file_id.cc', - 'guid_creator.cc', 'linux_libc_support.cc', 'memory_mapped_file.cc', ] diff --git a/tools/profiler/moz.build b/tools/profiler/moz.build index bd58736fd17f..da4daed82837 100644 --- a/tools/profiler/moz.build +++ b/tools/profiler/moz.build @@ -60,7 +60,6 @@ if CONFIG['MOZ_GECKO_PROFILER']: SOURCES += [ '/toolkit/crashreporter/google-breakpad/src/common/linux/elfutils.cc', '/toolkit/crashreporter/google-breakpad/src/common/linux/file_id.cc', - '/toolkit/crashreporter/google-breakpad/src/common/linux/guid_creator.cc', '/toolkit/crashreporter/google-breakpad/src/common/linux/linux_libc_support.cc', '/toolkit/crashreporter/google-breakpad/src/common/linux/memory_mapped_file.cc', ] From 9b71d631d4fc63eb2aa4441232b6600aeb000d08 Mon Sep 17 00:00:00 2001 From: Federico Padua Date: Sat, 18 Mar 2017 21:18:27 +0100 Subject: [PATCH 31/46] Bug 1344833 - Enable flake8 rule E128: "continuation line under-indented for visual indent". r=Dexter This patch enables flake8 rule E128: "continuation line under-indented for visual indent" in toolkit/components/telemetry by removing the relative E128 entry from toolkit/components/telemetry/.flake8 and fixing the files for which the E128 error was reported. Precisely 10 errors violating E128 rule were found and solved. MozReview-Commit-ID: 4sNXIxGFJQN --HG-- extra : rebase_source : bc2ef3bf1cc4bbe5b0450458226af07a83c30f30 --- toolkit/components/telemetry/.flake8 | 2 +- .../telemetry/gen-histogram-data.py | 20 +++++++++---------- .../components/telemetry/histogram_tools.py | 8 ++++---- toolkit/components/telemetry/parse_scalars.py | 10 +++++----- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/toolkit/components/telemetry/.flake8 b/toolkit/components/telemetry/.flake8 index 4559a3d82bd5..cfed80d4d151 100644 --- a/toolkit/components/telemetry/.flake8 +++ b/toolkit/components/telemetry/.flake8 @@ -1,5 +1,5 @@ [flake8] # See http://pep8.readthedocs.io/en/latest/intro.html#configuration -ignore = E121, E123, E126, E129, E133, E226, E241, E242, E704, W503, E402, E128, E501, E202, W602, E127, W601 +ignore = E121, E123, E126, E129, E133, E226, E241, E242, E704, W503, E402, E501, E202, W602, E127, W601 max-line-length = 99 filename = *.py, +.lint diff --git a/toolkit/components/telemetry/gen-histogram-data.py b/toolkit/components/telemetry/gen-histogram-data.py index 1c6813bb2426..151c536f25e3 100644 --- a/toolkit/components/telemetry/gen-histogram-data.py +++ b/toolkit/components/telemetry/gen-histogram-data.py @@ -21,16 +21,16 @@ def print_array_entry(output, histogram, name_index, exp_index, label_index, lab if cpp_guard: print("#if defined(%s)" % cpp_guard, file=output) print(" { %s, %s, %s, %s, %d, %d, %s, %d, %d, %s }," - % (histogram.low(), - histogram.high(), - histogram.n_buckets(), - histogram.nsITelemetry_kind(), - name_index, - exp_index, - histogram.dataset(), - label_index, - label_count, - "true" if histogram.keyed() else "false"), file=output) + % (histogram.low(), + histogram.high(), + histogram.n_buckets(), + histogram.nsITelemetry_kind(), + name_index, + exp_index, + histogram.dataset(), + label_index, + label_count, + "true" if histogram.keyed() else "false"), file=output) if cpp_guard: print("#endif", file=output) diff --git a/toolkit/components/telemetry/histogram_tools.py b/toolkit/components/telemetry/histogram_tools.py index a745af236dbd..ce13627330b7 100644 --- a/toolkit/components/telemetry/histogram_tools.py +++ b/toolkit/components/telemetry/histogram_tools.py @@ -371,14 +371,14 @@ associated with the histogram. Returns None if no guarding is necessary.""" continue if not isinstance(definition[key], key_type): raise ValueError, ('value for key "{0}" in Histogram "{1}" ' - 'should be {2}').format(key, name, nice_type_name(key_type)) + 'should be {2}').format(key, name, nice_type_name(key_type)) for key, key_type in type_checked_list_fields.iteritems(): if key not in definition: continue if not all(isinstance(x, key_type) for x in definition[key]): raise ValueError, ('all values for list "{0}" in Histogram "{1}" ' - 'should be {2}').format(key, name, nice_type_name(key_type)) + 'should be {2}').format(key, name, nice_type_name(key_type)) @staticmethod def check_keys(name, definition, allowed_keys): @@ -393,8 +393,8 @@ associated with the histogram. Returns None if no guarding is necessary.""" if whitelists is not None and self._n_buckets > 100 and type(self._n_buckets) is int: if self._name not in whitelists['n_buckets']: raise KeyError, ('New histogram "%s" is not permitted to have more than 100 buckets. ' - 'Histograms with large numbers of buckets use disproportionately high amounts of resources. ' - 'Contact the Telemetry team (e.g. in #telemetry) if you think an exception ought to be made.' % self._name) + 'Histograms with large numbers of buckets use disproportionately high amounts of resources. ' + 'Contact the Telemetry team (e.g. in #telemetry) if you think an exception ought to be made.' % self._name) @staticmethod def boolean_flag_bucket_parameters(definition): diff --git a/toolkit/components/telemetry/parse_scalars.py b/toolkit/components/telemetry/parse_scalars.py index b6c6d240c0a0..4a3713047fab 100644 --- a/toolkit/components/telemetry/parse_scalars.py +++ b/toolkit/components/telemetry/parse_scalars.py @@ -49,7 +49,7 @@ class ScalarType: for n in [group_name, probe_name]: if len(n) > MAX_NAME_LENGTH: raise ValueError("Name '{}' exceeds maximum name length of {} characters." - .format(n, MAX_NAME_LENGTH)) + .format(n, MAX_NAME_LENGTH)) def check_name(name, error_msg_prefix, allowed_char_regexp): # Check if we only have the allowed characters. @@ -60,8 +60,8 @@ class ScalarType: # Don't allow leading/trailing digits, '.' or '_'. if re.search(r'(^[\d\._])|([\d\._])$', name): raise ValueError(error_msg_prefix + - " name must not have a leading/trailing digit, a dot or underscore. Got: '{}'" - .format(name)) + " name must not have a leading/trailing digit, a dot or underscore. Got: '{}'" + .format(name)) check_name(group_name, 'Group', r'\.') check_name(probe_name, 'Probe', r'_') @@ -115,7 +115,7 @@ class ScalarType: # Checks the type for all the fields. wrong_type_names = ['{} must be {}'.format(f, ALL_FIELDS[f].__name__) - for f in definition.keys() if not isinstance(definition[f], ALL_FIELDS[f])] + for f in definition.keys() if not isinstance(definition[f], ALL_FIELDS[f])] if len(wrong_type_names) > 0: raise TypeError(self._name + ' - ' + ', '.join(wrong_type_names)) @@ -237,7 +237,7 @@ class ScalarType: release_channel_collection = \ self._definition.get('release_channel_collection', 'opt-in') return 'nsITelemetry::' + ('DATASET_RELEASE_CHANNEL_OPTOUT' - if release_channel_collection == 'opt-out' else 'DATASET_RELEASE_CHANNEL_OPTIN') + if release_channel_collection == 'opt-out' else 'DATASET_RELEASE_CHANNEL_OPTIN') @property def cpp_guard(self): From d7e6cc08c3797ce2112f41f2bc24005b08a0c14a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A3o=20Gottwald?= Date: Thu, 16 Mar 2017 15:11:05 +0100 Subject: [PATCH 32/46] Bug 1347928 - Remove legacy information-*.png icons. r=jaws MozReview-Commit-ID: 47FAxEjg4KG --HG-- extra : rebase_source : 6b67778d0129752867b4f1d5933e016464a398c9 --- .../migration/content/aboutWelcomeBack.xhtml | 2 +- browser/themes/shared/aboutProviderDirectory.css | 2 +- .../shared/components/notification-box.css | 3 ++- .../test_autofill_default_behavior.js | 10 +++++----- .../places/tests/unit/test_bookmarks_html.js | 2 +- toolkit/themes/osx/global/global.css | 2 +- .../themes/osx/global/icons/information-16.png | Bin 818 -> 0 bytes .../themes/osx/global/icons/information-24.png | Bin 1289 -> 0 bytes .../themes/osx/global/icons/information-32.png | Bin 1773 -> 0 bytes .../themes/osx/global/icons/information-64.png | Bin 3687 -> 0 bytes .../osx/global/icons/information-large.png | Bin 2592 -> 0 bytes toolkit/themes/osx/global/jar.mn | 5 ----- toolkit/themes/shared/non-mac.jar.inc.mn | 3 --- toolkit/themes/windows/global/global.css | 2 +- .../windows/global/icons/information-24.png | Bin 1477 -> 0 bytes .../windows/global/icons/information-32.png | Bin 2080 -> 0 bytes toolkit/themes/windows/global/jar.mn | 1 + 17 files changed, 13 insertions(+), 19 deletions(-) delete mode 100644 toolkit/themes/osx/global/icons/information-16.png delete mode 100644 toolkit/themes/osx/global/icons/information-24.png delete mode 100644 toolkit/themes/osx/global/icons/information-32.png delete mode 100644 toolkit/themes/osx/global/icons/information-64.png delete mode 100644 toolkit/themes/osx/global/icons/information-large.png delete mode 100644 toolkit/themes/windows/global/icons/information-24.png delete mode 100644 toolkit/themes/windows/global/icons/information-32.png diff --git a/browser/components/migration/content/aboutWelcomeBack.xhtml b/browser/components/migration/content/aboutWelcomeBack.xhtml index 058a329755f4..d4e4b120d7ef 100644 --- a/browser/components/migration/content/aboutWelcomeBack.xhtml +++ b/browser/components/migration/content/aboutWelcomeBack.xhtml @@ -20,7 +20,7 @@ &welcomeback2.tabtitle; - + + + + + + + +
+

+
+ + diff --git a/gfx/layers/apz/test/mochitest/mochitest.ini b/gfx/layers/apz/test/mochitest/mochitest.ini index 5f7807fb510e..0696805561e2 100644 --- a/gfx/layers/apz/test/mochitest/mochitest.ini +++ b/gfx/layers/apz/test/mochitest/mochitest.ini @@ -10,6 +10,7 @@ helper_bug1280013.html helper_bug1285070.html helper_bug1299195.html + helper_bug1346632.html helper_click.html helper_div_pan.html helper_drag_click.html diff --git a/gfx/layers/apz/test/mochitest/test_group_mouseevents.html b/gfx/layers/apz/test/mochitest/test_group_mouseevents.html index dcf71f0cc023..afe89d4d4490 100644 --- a/gfx/layers/apz/test/mochitest/test_group_mouseevents.html +++ b/gfx/layers/apz/test/mochitest/test_group_mouseevents.html @@ -17,7 +17,9 @@ var subtests = [ // Sanity test for click but with some mouse movement between the down and up {'file': 'helper_drag_click.html'}, // Test for dragging on a fake-scrollbar element that scrolls the page - {'file': 'helper_drag_scroll.html'} + {'file': 'helper_drag_scroll.html'}, + // Test for dragging the scrollbar with a fixed-pos element overlaying it + {'file': 'helper_bug1346632.html'} ]; if (isApzEnabled()) { From d6adf366f63717393c1043e06a7015878458793f Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Fri, 17 Mar 2017 13:33:56 -0700 Subject: [PATCH 37/46] Bug 1344393 - Add StageParameters for Oculus r=daoshengmu MozReview-Commit-ID: 9OkleewwS2b --HG-- extra : rebase_source : 75bffc843ba9a3d869700334c41ceb910707e5f4 --- gfx/vr/gfxVROculus.cpp | 54 +++++++++++++++++++++++++++++++++++++++ gfx/vr/gfxVROculus.h | 4 ++- gfx/vr/ovr_capi_dynamic.h | 19 +++++++++++--- 3 files changed, 72 insertions(+), 5 deletions(-) diff --git a/gfx/vr/gfxVROculus.cpp b/gfx/vr/gfxVROculus.cpp index a72b9d736daa..b9d1bd4972c8 100644 --- a/gfx/vr/gfxVROculus.cpp +++ b/gfx/vr/gfxVROculus.cpp @@ -98,6 +98,7 @@ static pfn_ovr_GetFloatArray ovr_GetFloatArray = nullptr; static pfn_ovr_SetFloatArray ovr_SetFloatArray = nullptr; static pfn_ovr_GetString ovr_GetString = nullptr; static pfn_ovr_SetString ovr_SetString = nullptr; +static pfn_ovr_GetBoundaryDimensions ovr_GetBoundaryDimensions = nullptr; #ifdef XP_WIN static pfn_ovr_CreateTextureSwapChainDX ovr_CreateTextureSwapChainDX = nullptr; @@ -286,6 +287,7 @@ InitializeOculusCAPI() REQUIRE_FUNCTION(ovr_SetFloatArray); REQUIRE_FUNCTION(ovr_GetString); REQUIRE_FUNCTION(ovr_SetString); + REQUIRE_FUNCTION(ovr_GetBoundaryDimensions); #ifdef XP_WIN @@ -356,6 +358,7 @@ VRDisplayOculus::VRDisplayOculus(ovrSession aSession) , mVertexBuffer(nullptr) , mInputLayout(nullptr) , mIsPresenting(false) + , mEyeHeight(OVR_DEFAULT_EYE_HEIGHT) { MOZ_COUNT_CTOR_INHERITED(VRDisplayOculus, VRDisplayHost); @@ -373,6 +376,7 @@ VRDisplayOculus::VRDisplayOculus(ovrSession aSession) if (mDesc.AvailableTrackingCaps & ovrTrackingCap_Position) { mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_Position; mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_LinearAcceleration; + mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_StageParameters; } mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_External; mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_MountDetection; @@ -401,6 +405,8 @@ VRDisplayOculus::VRDisplayOculus(ovrSession aSession) // take the max of both for eye resolution mDisplayInfo.mEyeResolution.width = std::max(texSize[VRDisplayInfo::Eye_Left].w, texSize[VRDisplayInfo::Eye_Right].w); mDisplayInfo.mEyeResolution.height = std::max(texSize[VRDisplayInfo::Eye_Left].h, texSize[VRDisplayInfo::Eye_Right].h); + + UpdateStageParameters(); } VRDisplayOculus::~VRDisplayOculus() { @@ -418,10 +424,49 @@ VRDisplayOculus::Destroy() } } +void +VRDisplayOculus::UpdateStageParameters() +{ + ovrVector3f playArea; + ovrResult res = ovr_GetBoundaryDimensions(mSession, ovrBoundary_PlayArea, &playArea); + if (res == ovrSuccess) { + mDisplayInfo.mStageSize.width = playArea.x; + mDisplayInfo.mStageSize.height = playArea.z; + } else { + // If we fail, fall back to reasonable defaults. + // 1m x 1m space + mDisplayInfo.mStageSize.width = 1.0f; + mDisplayInfo.mStageSize.height = 1.0f; + } + + mEyeHeight = ovr_GetFloat(mSession, OVR_KEY_EYE_HEIGHT, OVR_DEFAULT_EYE_HEIGHT); + + mDisplayInfo.mSittingToStandingTransform._11 = 1.0f; + mDisplayInfo.mSittingToStandingTransform._12 = 0.0f; + mDisplayInfo.mSittingToStandingTransform._13 = 0.0f; + mDisplayInfo.mSittingToStandingTransform._14 = 0.0f; + + mDisplayInfo.mSittingToStandingTransform._21 = 0.0f; + mDisplayInfo.mSittingToStandingTransform._22 = 1.0f; + mDisplayInfo.mSittingToStandingTransform._23 = 0.0f; + mDisplayInfo.mSittingToStandingTransform._24 = 0.0f; + + mDisplayInfo.mSittingToStandingTransform._31 = 0.0f; + mDisplayInfo.mSittingToStandingTransform._32 = 0.0f; + mDisplayInfo.mSittingToStandingTransform._33 = 1.0f; + mDisplayInfo.mSittingToStandingTransform._34 = 0.0f; + + mDisplayInfo.mSittingToStandingTransform._41 = 0.0f; + mDisplayInfo.mSittingToStandingTransform._42 = mEyeHeight; + mDisplayInfo.mSittingToStandingTransform._43 = 0.0f; + mDisplayInfo.mSittingToStandingTransform._44 = 1.0f; +} + void VRDisplayOculus::ZeroSensor() { ovr_RecenterTrackingOrigin(mSession); + UpdateStageParameters(); } VRHMDSensorState @@ -440,6 +485,7 @@ VRDisplayOculus::GetSensorState() result = GetSensorState(frameDelta); result.inputFrameID = mInputFrameID; mLastSensorState[result.inputFrameID % kMaxLatencyFrames] = result; + result.position[1] -= mEyeHeight; return result; } @@ -988,6 +1034,11 @@ VRSystemManagerOculus::GetHMDs(nsTArray>& aHMDResult) ovrResult orv = ovr_Create(&session, &luid); if (orv == ovrSuccess) { mSession = session; + orv = ovr_SetTrackingOriginType(session, ovrTrackingOrigin_FloorLevel); + if (orv != ovrSuccess) { + NS_WARNING("ovr_SetTrackingOriginType failed.\n"); + } + mHMDInfo = new VRDisplayOculus(session); } } @@ -1099,6 +1150,9 @@ VRSystemManagerOculus::HandleInput() poseState.linearAcceleration[0] = pose.LinearAcceleration.x; poseState.linearAcceleration[1] = pose.LinearAcceleration.y; poseState.linearAcceleration[2] = pose.LinearAcceleration.z; + + float eyeHeight = ovr_GetFloat(mSession, OVR_KEY_EYE_HEIGHT, OVR_DEFAULT_EYE_HEIGHT); + poseState.position[1] -= eyeHeight; } HandlePoseTracking(i, poseState, controller); } diff --git a/gfx/vr/gfxVROculus.h b/gfx/vr/gfxVROculus.h index 7a233925773d..3d99138f5a93 100644 --- a/gfx/vr/gfxVROculus.h +++ b/gfx/vr/gfxVROculus.h @@ -48,6 +48,7 @@ protected: const VRHMDSensorState& aSensorState, const gfx::Rect& aLeftEyeRect, const gfx::Rect& aRightEyeRect) override; + void UpdateStageParameters(); public: explicit VRDisplayOculus(ovrSession aSession); @@ -82,7 +83,8 @@ protected: RefPtr mInputLayout; bool mIsPresenting; - + float mEyeHeight; + bool UpdateConstantBuffers(); struct Vertex diff --git a/gfx/vr/ovr_capi_dynamic.h b/gfx/vr/ovr_capi_dynamic.h index edf2b78a3d94..9a4ae06ba056 100644 --- a/gfx/vr/ovr_capi_dynamic.h +++ b/gfx/vr/ovr_capi_dynamic.h @@ -567,8 +567,15 @@ typedef enum { ovrDebugHudStereo_EnumSize = 0x7fffffff } ovrDebugHudStereoMode; +typedef enum { + // Outer boundary - closely represents user setup walls + ovrBoundary_Outer = 0x0001, + // Play area - safe rectangular area inside outer boundary which can optionally be used to restrict user interactions and motion. + ovrBoundary_PlayArea = 0x0100, +} ovrBoundaryType; + typedef ovrBool(OVR_PFN* pfn_ovr_GetBool)(ovrSession session, const char* propertyName, ovrBool defaultVal); -typedef ovrBool(OVR_PFN* pfn_ovr_SetBool)(ovrSession session, const char* propertyName, ovrBool value); +typedef ovrBool(OVR_PFN* pfn_ovr_SetBool)(ovrSession session, const char* propertyName, ovrBool value); typedef int (OVR_PFN* pfn_ovr_GetInt)(ovrSession session, const char* propertyName, int defaultVal); typedef ovrBool (OVR_PFN* pfn_ovr_SetInt)(ovrSession session, const char* propertyName, int value); typedef float (OVR_PFN* pfn_ovr_GetFloat)(ovrSession session, const char* propertyName, float defaultVal); @@ -581,8 +588,9 @@ typedef const char* (OVR_PFN* pfn_ovr_GetString)(ovrSession session, const char* const char* defaultVal); typedef ovrBool (OVR_PFN* pfn_ovr_SetString)(ovrSession session, const char* propertyName, const char* value); - - +typedef ovrResult (OVR_PFN* pfn_ovr_GetBoundaryDimensions)(ovrSession session, + ovrBoundaryType boundaryType, + ovrVector3f* outDimensions); typedef enum { ovrError_MemoryAllocationFailure = -1000, @@ -714,7 +722,10 @@ typedef ovrResult (OVR_PFN* pfn_ovr_GetMirrorTextureBufferGL)(ovrSession session ovrMirrorTexture mirrorTexture, unsigned int* out_TexId); -#ifdef __cplusplus +#define OVR_KEY_EYE_HEIGHT "EyeHeight" // float meters +#define OVR_DEFAULT_EYE_HEIGHT 1.675f + +#ifdef __cplusplus } #endif From 4e410934afcc4eba93e414dc4200e179b8c3213c Mon Sep 17 00:00:00 2001 From: Kearwood Gilbert Date: Wed, 15 Mar 2017 16:40:57 -0700 Subject: [PATCH 38/46] Bug 1346923 - Remove PVRManager::GetDisplays sync IPC r=daoshengmu,kanru - PVRManager::GetDisplays was a sync IPC that was part of an optimization for a use case that has been eliminated by changes to the WebVR spec. - This was an optimization for Navigator.activeVRDisplays that would allow enumeration of displays active in any content process without powering on any additional VR hardware. This will no longer be necessary as the activeVRDisplays has been restricted to returning only the displays active in the current javascript context. MozReview-Commit-ID: F6sOtM9nups --HG-- extra : rebase_source : bd8967fab9677206d998eea922c8d1640551de1c --- gfx/vr/ipc/PVRManager.ipdl | 4 ---- gfx/vr/ipc/VRManagerChild.cpp | 10 ---------- gfx/vr/ipc/VRManagerParent.cpp | 8 -------- gfx/vr/ipc/VRManagerParent.h | 1 - ipc/ipdl/sync-messages.ini | 2 -- 5 files changed, 25 deletions(-) diff --git a/gfx/vr/ipc/PVRManager.ipdl b/gfx/vr/ipc/PVRManager.ipdl index 61e1bff271a6..2920a352560c 100644 --- a/gfx/vr/ipc/PVRManager.ipdl +++ b/gfx/vr/ipc/PVRManager.ipdl @@ -45,10 +45,6 @@ parent: // asynchronously to children via UpdateDisplayInfo. async RefreshDisplays(); - // GetDisplays synchronously returns the VR displays that have already been - // enumerated by RefreshDisplays() but does not enumerate new ones. - sync GetDisplays() returns(VRDisplayInfo[] aDisplayInfo); - // Reset the sensor of the display identified by aDisplayID so that the current // sensor state is the "Zero" position. async ResetSensor(uint32_t aDisplayID); diff --git a/gfx/vr/ipc/VRManagerChild.cpp b/gfx/vr/ipc/VRManagerChild.cpp index 5ee0b9af4207..d33951cb4d77 100644 --- a/gfx/vr/ipc/VRManagerChild.cpp +++ b/gfx/vr/ipc/VRManagerChild.cpp @@ -293,16 +293,6 @@ VRManagerChild::RecvUpdateDisplayInfo(nsTArray&& aDisplayUpdates) bool VRManagerChild::GetVRDisplays(nsTArray>& aDisplays) { - if (!mDisplaysInitialized) { - /** - * If we haven't received any asynchronous callback after requesting - * display enumeration with RefreshDisplays, get the existing displays - * that have already been enumerated by other VRManagerChild instances. - */ - nsTArray displays; - Unused << SendGetDisplays(&displays); - UpdateDisplayInfo(displays); - } aDisplays = mDisplays; return true; } diff --git a/gfx/vr/ipc/VRManagerParent.cpp b/gfx/vr/ipc/VRManagerParent.cpp index e413f24d8b4d..af72b18a7253 100644 --- a/gfx/vr/ipc/VRManagerParent.cpp +++ b/gfx/vr/ipc/VRManagerParent.cpp @@ -241,14 +241,6 @@ VRManagerParent::RecvRefreshDisplays() return IPC_OK(); } -mozilla::ipc::IPCResult -VRManagerParent::RecvGetDisplays(nsTArray *aDisplays) -{ - VRManager* vm = VRManager::Get(); - vm->GetVRDisplayInfo(*aDisplays); - return IPC_OK(); -} - mozilla::ipc::IPCResult VRManagerParent::RecvResetSensor(const uint32_t& aDisplayID) { diff --git a/gfx/vr/ipc/VRManagerParent.h b/gfx/vr/ipc/VRManagerParent.h index 28d12d5a2200..0eaa18669729 100644 --- a/gfx/vr/ipc/VRManagerParent.h +++ b/gfx/vr/ipc/VRManagerParent.h @@ -86,7 +86,6 @@ protected: void OnChannelConnected(int32_t pid) override; virtual mozilla::ipc::IPCResult RecvRefreshDisplays() override; - virtual mozilla::ipc::IPCResult RecvGetDisplays(nsTArray *aDisplays) override; virtual mozilla::ipc::IPCResult RecvResetSensor(const uint32_t& aDisplayID) override; virtual mozilla::ipc::IPCResult RecvGetSensorState(const uint32_t& aDisplayID, VRHMDSensorState* aState) override; virtual mozilla::ipc::IPCResult RecvSetHaveEventListener(const bool& aHaveEventListener) override; diff --git a/ipc/ipdl/sync-messages.ini b/ipc/ipdl/sync-messages.ini index 22682b2489bc..be20e076a070 100644 --- a/ipc/ipdl/sync-messages.ini +++ b/ipc/ipdl/sync-messages.ini @@ -949,8 +949,6 @@ description = description = [PWebRenderBridge::DPGetSnapshot] description = -[PVRManager::GetDisplays] -description = [PVRManager::GetSensorState] description = [PVRManager::SetHaveEventListener] From c6610ae7fd976426cae1ce07488451bf9f5ab35e Mon Sep 17 00:00:00 2001 From: Blake Kaplan Date: Wed, 15 Mar 2017 14:53:12 -0700 Subject: [PATCH 39/46] Bug 1333472 - Try to fix intermittent failures in browser_windowactivation.js. r=Felipe MozReview-Commit-ID: E1jG1vLznvk --HG-- extra : rebase_source : 31417c4ab76f822462e4e7367ae37bbfe7a4d411 --- .../test/general/browser_windowactivation.js | 66 ++++++++----------- 1 file changed, 26 insertions(+), 40 deletions(-) diff --git a/browser/base/content/test/general/browser_windowactivation.js b/browser/base/content/test/general/browser_windowactivation.js index 73e972a45592..0102c7e958be 100644 --- a/browser/base/content/test/general/browser_windowactivation.js +++ b/browser/base/content/test/general/browser_windowactivation.js @@ -4,39 +4,31 @@ /* eslint-env mozilla/frame-script */ -var testPage = "data:text/html,
"; +var testPage = "data:text/html;charset=utf-8,
"; var colorChangeNotifications = 0; var otherWindow; var browser1, browser2; -function test() { - waitForExplicitFinish(); - waitForFocus(reallyRunTests); -} +add_task(function* reallyRunTests() { -function reallyRunTests() { + let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, testPage); + browser1 = tab1.linkedBrowser; - let tab1 = gBrowser.addTab(); - let tab2 = gBrowser.addTab(); - browser1 = gBrowser.getBrowserForTab(tab1); - browser2 = gBrowser.getBrowserForTab(tab2); + // This can't use openNewForegroundTab because if we focus tab2 now, we + // won't send a focus event during test 6, further down in this file. + let tab2 = gBrowser.addTab(testPage); + browser2 = tab2.linkedBrowser; + yield BrowserTestUtils.browserLoaded(browser2); + + browser1.messageManager.loadFrameScript("data:,(" + childFunction.toString() + ")();", true); + browser2.messageManager.loadFrameScript("data:,(" + childFunction.toString() + ")();", true); gURLBar.focus(); - var loadCount = 0; - function check() { - // wait for both tabs to load - if (++loadCount != 2) { - return; - } - - browser1.removeEventListener("load", check, true); - browser2.removeEventListener("load", check, true); - - sendGetBackgroundRequest(true); - } + let testFinished = {}; + testFinished.promise = new Promise(resolve => testFinished.resolve = resolve); // The test performs four checks, using -moz-window-inactive on two child tabs. // First, the initial state should be transparent. The second check is done @@ -74,7 +66,7 @@ function reallyRunTests() { break; case 8: is(message.data.color, "rgba(0, 0, 0, 0)", "second window after tab switch"); - finishTest(); + testFinished.resolve(); break; case 9: ok(false, "too many color change notifications"); @@ -97,16 +89,17 @@ function reallyRunTests() { ok(message.data.ok, "Test:DeactivateEvent"); }); - browser1.addEventListener("load", check, true); - browser2.addEventListener("load", check, true); - browser1.contentWindow.location = testPage; - browser2.contentWindow.location = testPage; - - browser1.messageManager.loadFrameScript("data:,(" + childFunction.toString() + ")();", true); - browser2.messageManager.loadFrameScript("data:,(" + childFunction.toString() + ")();", true); - gBrowser.selectedTab = tab1; -} + + // Start the test. + sendGetBackgroundRequest(true); + + yield testFinished.promise; + + yield BrowserTestUtils.removeTab(tab1); + yield BrowserTestUtils.removeTab(tab2); + otherWindow = null; +}); function sendGetBackgroundRequest(ifChanged) { browser1.messageManager.sendAsyncMessage("Test:GetBackgroundColor", { ifChanged }); @@ -114,19 +107,12 @@ function sendGetBackgroundRequest(ifChanged) { } function runOtherWindowTests() { - otherWindow = window.open("data:text/html,Hi", "", "chrome"); + otherWindow = window.open("data:text/html;charset=utf-8,Hi", "", "chrome"); waitForFocus(function() { sendGetBackgroundRequest(true); }, otherWindow); } -function finishTest() { - gBrowser.removeCurrentTab(); - gBrowser.removeCurrentTab(); - otherWindow = null; - finish(); -} - function childFunction() { let oldColor = null; From d6c9b04db10bfb20002bfcda12945011b51ff9a3 Mon Sep 17 00:00:00 2001 From: David Teller Date: Mon, 20 Mar 2017 16:57:14 +0100 Subject: [PATCH 40/46] Bug 1348883 - Clarifying histogram DOM_SCRIPT_SRC_ENCODING;r=francois MozReview-Commit-ID: KT2zgsuoeAT --HG-- extra : rebase_source : 9757e8d6a6d6beb85392582aa4f75f4ac88498c7 --- toolkit/components/telemetry/Histograms.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index d76c44cfef3f..4d9231a7528a 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -10462,11 +10462,11 @@ }, "DOM_SCRIPT_SRC_ENCODING": { "alert_emails": ["dteller@mozilla.com"], - "expires_in_version": "never", + "expires_in_version": "61", "kind": "count", "keyed": true, "bug_numbers": [1344152], - "description": "Encoding used in a