From 0da735fe740b0a7e396db354771a50a0ac6212a0 Mon Sep 17 00:00:00 2001 From: Tobias Schneider Date: Tue, 21 Feb 2017 03:13:39 -0800 Subject: [PATCH 001/234] Bug 1337936 - (intersection-observer) Revise lifetime management. r=smaug MozReview-Commit-ID: AvdDJaRELXm --HG-- extra : rebase_source : a3e8705822545fd4c1cee688939c617a419d3936 --- dom/base/DOMIntersectionObserver.cpp | 16 ++++++++-------- dom/base/DOMIntersectionObserver.h | 3 ++- dom/base/Element.cpp | 8 ++++---- dom/base/Element.h | 3 ++- dom/base/FragmentOrElement.cpp | 6 ++++++ dom/base/FragmentOrElement.h | 3 ++- dom/base/nsDocument.cpp | 20 +++++++++++--------- dom/base/nsDocument.h | 3 ++- 8 files changed, 37 insertions(+), 25 deletions(-) diff --git a/dom/base/DOMIntersectionObserver.cpp b/dom/base/DOMIntersectionObserver.cpp index 4c5658923553..a0072763d664 100644 --- a/dom/base/DOMIntersectionObserver.cpp +++ b/dom/base/DOMIntersectionObserver.cpp @@ -43,15 +43,17 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMIntersectionObserver) NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER + tmp->Disconnect(); NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwner) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument) NS_IMPL_CYCLE_COLLECTION_UNLINK(mCallback) NS_IMPL_CYCLE_COLLECTION_UNLINK(mRoot) NS_IMPL_CYCLE_COLLECTION_UNLINK(mQueuedEntries) - tmp->Disconnect(); NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMIntersectionObserver) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCallback) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRoot) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mQueuedEntries) @@ -189,8 +191,9 @@ DOMIntersectionObserver::Connect() } mConnected = true; - nsIDocument* document = mOwner->GetExtantDoc(); - document->AddIntersectionObserver(this); + if (mDocument) { + mDocument->AddIntersectionObserver(this); + } } void @@ -206,11 +209,8 @@ DOMIntersectionObserver::Disconnect() target->UnregisterIntersectionObserver(this); } mObservationTargets.Clear(); - if (mOwner) { - nsIDocument* document = mOwner->GetExtantDoc(); - if (document) { - document->RemoveIntersectionObserver(this); - } + if (mDocument) { + mDocument->RemoveIntersectionObserver(this); } } diff --git a/dom/base/DOMIntersectionObserver.h b/dom/base/DOMIntersectionObserver.h index b4ff12cf1921..843143f418eb 100644 --- a/dom/base/DOMIntersectionObserver.h +++ b/dom/base/DOMIntersectionObserver.h @@ -108,7 +108,7 @@ class DOMIntersectionObserver final : public nsISupports, public: DOMIntersectionObserver(already_AddRefed&& aOwner, mozilla::dom::IntersectionCallback& aCb) - : mOwner(aOwner), mCallback(&aCb), mConnected(false) + : mOwner(aOwner), mDocument(mOwner->GetExtantDoc()), mCallback(&aCb), mConnected(false) { } NS_DECL_CYCLE_COLLECTING_ISUPPORTS @@ -166,6 +166,7 @@ protected: double aIntersectionRatio); nsCOMPtr mOwner; + RefPtr mDocument; RefPtr mCallback; RefPtr mRoot; nsCSSRect mRootMargin; diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index ee9f881f76cf..845315be50c6 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -3851,7 +3851,7 @@ Element::ClearDataset() slots->mDataset = nullptr; } -nsDataHashtable, int32_t>* +nsDataHashtable, int32_t>* Element::RegisteredIntersectionObservers() { nsDOMSlots* slots = DOMSlots(); @@ -3861,7 +3861,7 @@ Element::RegisteredIntersectionObservers() void Element::RegisterIntersectionObserver(DOMIntersectionObserver* aObserver) { - nsDataHashtable, int32_t>* observers = + nsDataHashtable, int32_t>* observers = RegisteredIntersectionObservers(); if (observers->Contains(aObserver)) { return; @@ -3872,7 +3872,7 @@ Element::RegisterIntersectionObserver(DOMIntersectionObserver* aObserver) void Element::UnregisterIntersectionObserver(DOMIntersectionObserver* aObserver) { - nsDataHashtable, int32_t>* observers = + nsDataHashtable, int32_t>* observers = RegisteredIntersectionObservers(); observers->Remove(aObserver); } @@ -3880,7 +3880,7 @@ Element::UnregisterIntersectionObserver(DOMIntersectionObserver* aObserver) bool Element::UpdateIntersectionObservation(DOMIntersectionObserver* aObserver, int32_t aThreshold) { - nsDataHashtable, int32_t>* observers = + nsDataHashtable, int32_t>* observers = RegisteredIntersectionObservers(); if (!observers->Contains(aObserver)) { return false; diff --git a/dom/base/Element.h b/dom/base/Element.h index 15f903f5dfc4..5e464be95c37 100644 --- a/dom/base/Element.h +++ b/dom/base/Element.h @@ -1466,7 +1466,8 @@ protected: nsDOMTokenList* GetTokenList(nsIAtom* aAtom, const DOMTokenListSupportedTokenArray aSupportedTokens = nullptr); - nsDataHashtable, int32_t>* RegisteredIntersectionObservers(); + nsDataHashtable, int32_t>* + RegisteredIntersectionObservers(); private: /** diff --git a/dom/base/FragmentOrElement.cpp b/dom/base/FragmentOrElement.cpp index 3e79f93d5d9f..0e1c17a7acfc 100644 --- a/dom/base/FragmentOrElement.cpp +++ b/dom/base/FragmentOrElement.cpp @@ -626,6 +626,12 @@ FragmentOrElement::nsDOMSlots::Traverse(nsCycleCollectionTraversalCallback &cb, mCustomElementData->mCallbackQueue[i]->Traverse(cb); } } + + for (auto iter = mRegisteredIntersectionObservers.Iter(); !iter.Done(); iter.Next()) { + RefPtr observer = iter.Key(); + NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mRegisteredIntersectionObservers[i]"); + cb.NoteXPCOMChild(observer.get()); + } } void diff --git a/dom/base/FragmentOrElement.h b/dom/base/FragmentOrElement.h index f3a6a01306a1..6d04159f030f 100644 --- a/dom/base/FragmentOrElement.h +++ b/dom/base/FragmentOrElement.h @@ -348,7 +348,8 @@ public: /** * Registered Intersection Observers on the element. */ - nsDataHashtable, int32_t> mRegisteredIntersectionObservers; + nsDataHashtable, int32_t> + mRegisteredIntersectionObservers; }; protected: diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 8a48240183f5..19f8771e6906 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -1832,8 +1832,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDocument) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOnDemandBuiltInUASheets) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPreloadingImages) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIntersectionObservers) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSubImportLinks) for (uint32_t i = 0; i < tmp->mFrameRequestCallbacks.Length(); ++i) { @@ -12594,15 +12592,15 @@ nsDocument::ReportUseCounters(UseCounterReportKind aKind) void nsDocument::AddIntersectionObserver(DOMIntersectionObserver* aObserver) { - NS_ASSERTION(mIntersectionObservers.IndexOf(aObserver) == nsTArray::NoIndex, - "Intersection observer already in the list"); - mIntersectionObservers.AppendElement(aObserver); + MOZ_ASSERT(!mIntersectionObservers.Contains(aObserver), + "Intersection observer already in the list"); + mIntersectionObservers.PutEntry(aObserver); } void nsDocument::RemoveIntersectionObserver(DOMIntersectionObserver* aObserver) { - mIntersectionObservers.RemoveElement(aObserver); + mIntersectionObservers.RemoveEntry(aObserver); } void @@ -12619,7 +12617,8 @@ nsDocument::UpdateIntersectionObservations() time = perf->Now(); } } - for (const auto& observer : mIntersectionObservers) { + for (auto iter = mIntersectionObservers.Iter(); !iter.Done(); iter.Next()) { + DOMIntersectionObserver* observer = iter.Get()->GetKey(); observer->Update(this, time); } } @@ -12630,7 +12629,6 @@ nsDocument::ScheduleIntersectionObserverNotification() if (mIntersectionObservers.IsEmpty()) { return; } - MOZ_RELEASE_ASSERT(NS_IsMainThread()); nsCOMPtr notification = NewRunnableMethod(this, &nsDocument::NotifyIntersectionObservers); @@ -12641,7 +12639,11 @@ nsDocument::ScheduleIntersectionObserverNotification() void nsDocument::NotifyIntersectionObservers() { - nsTArray> observers(mIntersectionObservers); + nsTArray> observers(mIntersectionObservers.Count()); + for (auto iter = mIntersectionObservers.Iter(); !iter.Done(); iter.Next()) { + DOMIntersectionObserver* observer = iter.Get()->GetKey(); + observers.AppendElement(observer); + } for (const auto& observer : observers) { observer->Notify(); } diff --git a/dom/base/nsDocument.h b/dom/base/nsDocument.h index 814d7c144ac5..82e0221089c5 100644 --- a/dom/base/nsDocument.h +++ b/dom/base/nsDocument.h @@ -1359,7 +1359,8 @@ protected: nsTObserverArray mObservers; // Array of intersection observers - nsTArray> mIntersectionObservers; + nsTHashtable> + mIntersectionObservers; // Tracker for animations that are waiting to start. // nullptr until GetOrCreatePendingAnimationTracker is called. From 3ea1b8cd85c5ac4665afde56b5be938382b63bb0 Mon Sep 17 00:00:00 2001 From: "Fischer.json" Date: Mon, 20 Feb 2017 11:57:13 +0800 Subject: [PATCH 002/234] Bug 1340618 - Don't hardcode Firefox in strings for space disk warning in Preferences r=jaws MozReview-Commit-ID: KyEba2v30rC --HG-- extra : rebase_source : 871a2a57614725e1157325ab8228775dd785dccf --- browser/base/content/browser.js | 9 +++++---- .../browser/preferences/preferences.properties | 12 ++++++++---- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index c0db31a894d0..5f8eb2af5c08 100755 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -460,6 +460,7 @@ const gStoragePressureObserver = { let buttons = []; let usage = parseInt(data); let prefStrBundle = document.getElementById("bundle_preferences"); + let brandShortName = document.getElementById("bundle_brand").getString("brandShortName"); let notificationBox = document.getElementById("high-priority-global-notificationbox"); buttons.push({ label: prefStrBundle.getString("spaceAlert.learnMoreButton.label"), @@ -474,7 +475,7 @@ const gStoragePressureObserver = { // This is because this usage is small and not the main cause for space issue. // In order to avoid the bad and wrong impression among users that // firefox eats disk space a lot, indicate users to clean up other disk space. - msg = prefStrBundle.getString("spaceAlert.under5GB.description"); + msg = prefStrBundle.getFormattedString("spaceAlert.under5GB.message", [brandShortName]); buttons.push({ label: prefStrBundle.getString("spaceAlert.under5GB.okButton.label"), accessKey: prefStrBundle.getString("spaceAlert.under5GB.okButton.accesskey"), @@ -483,15 +484,15 @@ const gStoragePressureObserver = { } else { // The firefox-used space >= 5GB, then guide users to about:preferences // to clear some data stored on firefox by websites. - let descriptionStringID = "spaceAlert.over5GB.description"; + let descriptionStringID = "spaceAlert.over5GB.message"; let prefButtonLabelStringID = "spaceAlert.over5GB.prefButton.label"; let prefButtonAccesskeyStringID = "spaceAlert.over5GB.prefButton.accesskey"; if (AppConstants.platform == "win") { - descriptionStringID = "spaceAlert.over5GB.descriptionWin"; + descriptionStringID = "spaceAlert.over5GB.messageWin"; prefButtonLabelStringID = "spaceAlert.over5GB.prefButtonWin.label"; prefButtonAccesskeyStringID = "spaceAlert.over5GB.prefButtonWin.accesskey"; } - msg = prefStrBundle.getString(descriptionStringID); + msg = prefStrBundle.getFormattedString(descriptionStringID, [brandShortName]); buttons.push({ label: prefStrBundle.getString(prefButtonLabelStringID), accessKey: prefStrBundle.getString(prefButtonAccesskeyStringID), diff --git a/browser/locales/en-US/chrome/browser/preferences/preferences.properties b/browser/locales/en-US/chrome/browser/preferences/preferences.properties index 1c7b78e3fa3f..2f2e1ab34929 100644 --- a/browser/locales/en-US/chrome/browser/preferences/preferences.properties +++ b/browser/locales/en-US/chrome/browser/preferences/preferences.properties @@ -207,12 +207,16 @@ spaceAlert.over5GB.prefButton.accesskey=O # LOCALIZATION NOTE (spaceAlert.over5GB.prefButtonWin.label): On Windows Preferences is called Options spaceAlert.over5GB.prefButtonWin.label=Open Options spaceAlert.over5GB.prefButtonWin.accesskey=O -spaceAlert.over5GB.description=Firefox is running out of disk space. Website contents may not display properly. You can clear stored site data in Preferences > Advanced > Site Data. -# LOCALIZATION NOTE (spaceAlert.over5GB.descriptionWin): On Windows Preferences is called Options -spaceAlert.over5GB.descriptionWin=Firefox is running out of disk space. Website contents may not display properly. You can clear stored site data in Options > Advanced > Site Data. +# LOCALIZATION NOTE (spaceAlert.over5GB.message): %S = brandShortName +spaceAlert.over5GB.message=%S is running out of disk space. Website contents may not display properly. You can clear stored site data in Preferences > Advanced > Site Data. +# LOCALIZATION NOTE (spaceAlert.over5GB.messageWin): +# - On Windows Preferences is called Options +# - %S = brandShortName +spaceAlert.over5GB.messageWin=%S is running out of disk space. Website contents may not display properly. You can clear stored site data in Options > Advanced > Site Data. spaceAlert.under5GB.okButton.label=OK, Got it spaceAlert.under5GB.okButton.accesskey=K -spaceAlert.under5GB.description=Firefox is running out of disk space. Website contents may not display properly. Visit “Learn More” to optimize your disk usage for better browsing experience. +# LOCALIZATION NOTE (spaceAlert.under5GB.message): %S = brandShortName +spaceAlert.under5GB.message=%S is running out of disk space. Website contents may not display properly. Visit “Learn More” to optimize your disk usage for better browsing experience. # LOCALIZATION NOTE (featureEnableRequiresRestart, featureDisableRequiresRestart, restartTitle): %S = brandShortName featureEnableRequiresRestart=%S must restart to enable this feature. From 40f095b3eb14df2377f5a369c7472acfffa0da35 Mon Sep 17 00:00:00 2001 From: Sean Maltby Date: Sat, 21 Jan 2017 19:03:02 -0500 Subject: [PATCH 003/234] Bug 1317643 - Resolved issue where the avatar icon resets to default. r=maliu When debug mode is toggled, hardRefresh() is called, removing and adding all preferences. However, profileAvatarTarget wasn't being updated with the new instance of profilePreference. This was resolved by moving the creation of profileAvatarTarget to refresh(), which is called in hardRefresh(). MozReview-Commit-ID: 8raarHbmR23 --HG-- extra : rebase_source : cf0bf90ca67b4e5dd322af25ed16ac43116fafd1 --- .../gecko/fxa/activities/FxAccountStatusFragment.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/activities/FxAccountStatusFragment.java b/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/activities/FxAccountStatusFragment.java index a30b92e5f363..734b5596ad51 100644 --- a/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/activities/FxAccountStatusFragment.java +++ b/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/activities/FxAccountStatusFragment.java @@ -471,10 +471,6 @@ public class FxAccountStatusFragment accountProfileInformationReceiver = new FxAccountProfileInformationReceiver(); LocalBroadcastManager.getInstance(getActivity()).registerReceiver(accountProfileInformationReceiver, intentFilter); - // profilePreference is set during onCreate, so it's definitely not null here. - final float cornerRadius = getResources().getDimension(R.dimen.fxaccount_profile_image_width) / 2; - profileAvatarTarget = new PicassoPreferenceIconTarget(getResources(), profilePreference, cornerRadius); - refresh(); } @@ -518,6 +514,10 @@ public class FxAccountStatusFragment throw new IllegalArgumentException("fxAccount must not be null"); } + // profilePreference is set during onCreate, so it's definitely not null here. + final float cornerRadius = getResources().getDimension(R.dimen.fxaccount_profile_image_width) / 2; + profileAvatarTarget = new PicassoPreferenceIconTarget(getResources(), profilePreference, cornerRadius); + updateProfileInformation(); updateAuthServerPreference(); updateSyncServerPreference(); From 13bc7a75b4c835aa191ea7ca1a7e8c5bad360944 Mon Sep 17 00:00:00 2001 From: Scott Wu Date: Thu, 16 Feb 2017 15:57:54 +0800 Subject: [PATCH 004/234] Bug 1337319 - Order month and year spinners based on locale datetime format r=mconley MozReview-Commit-ID: AmAVjybJZ6A --HG-- extra : rebase_source : 009b64009817ae468c0d47b473d4cbdcf72246c0 --- toolkit/content/widgets/datepicker.js | 11 +++++++++++ toolkit/content/widgets/spinner.js | 5 ++++- toolkit/themes/shared/datetimeinputpickers.css | 10 ++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/toolkit/content/widgets/datepicker.js b/toolkit/content/widgets/datepicker.js index 0eea684e7a04..56148e857932 100644 --- a/toolkit/content/widgets/datepicker.js +++ b/toolkit/content/widgets/datepicker.js @@ -62,6 +62,8 @@ function DatePicker(context) { isYearSet: false, isMonthSet: false, isDateSet: false, + datetimeOrders: new Intl.DateTimeFormat(locale) + .formatToParts(new Date(0)).map(part => part.type), getDayString: new Intl.NumberFormat(locale).format, getWeekHeaderString: weekday => weekdayStrings[weekday], getMonthString: month => monthStrings[month], @@ -110,6 +112,7 @@ function DatePicker(context) { setYear: this.state.setYear, setMonth: this.state.setMonth, getMonthString: this.state.getMonthString, + datetimeOrders: this.state.datetimeOrders, locale: this.state.locale }, { monthYear: this.context.monthYear, @@ -287,6 +290,7 @@ function DatePicker(context) { * {Function} setYear * {Function} setMonth * {Function} getMonthString + * {Array} datetimeOrders * } * @param {DOMElement} context */ @@ -294,12 +298,18 @@ function DatePicker(context) { const spinnerSize = 5; const yearFormat = new Intl.DateTimeFormat(options.locale, { year: "numeric" }).format; const dateFormat = new Intl.DateTimeFormat(options.locale, { year: "numeric", month: "long" }).format; + const spinnerOrder = + options.datetimeOrders.indexOf("month") < options.datetimeOrders.indexOf("year") ? + "order-month-year" : "order-year-month"; + + context.monthYearView.classList.add(spinnerOrder); this.context = context; this.state = { dateFormat }; this.props = {}; this.components = { month: new Spinner({ + id: "spinner-month", setValue: month => { this.state.isMonthSet = true; options.setMonth(month); @@ -308,6 +318,7 @@ function DatePicker(context) { viewportSize: spinnerSize }, context.monthYearView), year: new Spinner({ + id: "spinner-year", setValue: year => { this.state.isYearSet = true; options.setYear(year); diff --git a/toolkit/content/widgets/spinner.js b/toolkit/content/widgets/spinner.js index 759b6ffdc5e8..20bd8c4c9666 100644 --- a/toolkit/content/widgets/spinner.js +++ b/toolkit/content/widgets/spinner.js @@ -42,7 +42,7 @@ function Spinner(props, context) { * } */ _init(props) { - const { setValue, getDisplayString, hideButtons, rootFontSize = 10 } = props; + const { id, setValue, getDisplayString, hideButtons, rootFontSize = 10 } = props; const spinnerTemplate = document.getElementById("spinner-template"); const spinnerElement = document.importNode(spinnerTemplate.content, true); @@ -72,6 +72,9 @@ function Spinner(props, context) { this.elements.spinner.style.height = (ITEM_HEIGHT * viewportSize) + "rem"; + if (id) { + this.elements.container.id = id; + } if (hideButtons) { this.elements.container.classList.add("hide-buttons"); } diff --git a/toolkit/themes/shared/datetimeinputpickers.css b/toolkit/themes/shared/datetimeinputpickers.css index bed7be578f3d..55eea5b5a162 100644 --- a/toolkit/themes/shared/datetimeinputpickers.css +++ b/toolkit/themes/shared/datetimeinputpickers.css @@ -171,6 +171,16 @@ button.month-year.active::after { transition: none; } +.order-month-year > #spinner-month, +.order-year-month > #spinner-year { + order: 1; +} + +.order-month-year > #spinner-year, +.order-year-month > #spinner-month { + order: 2; +} + .calendar-container { cursor: default; display: flex; From 795cdad162ae4f7625b09382e466f77fbfb1b71e Mon Sep 17 00:00:00 2001 From: Sean Lee Date: Thu, 16 Feb 2017 23:05:35 +0800 Subject: [PATCH 005/234] Bug 1340104 - Hide the result without primary label in ProfileAutoCompleteResult.; r=MattN MozReview-Commit-ID: FSqU2fnKjeB --HG-- extra : rebase_source : e96941b752c9c101ad6b90db0ef944c488d155d0 --- .../ProfileAutoCompleteResult.jsm | 9 ++-- .../unit/test_profileAutocompleteResult.js | 43 ++++++++++++++++--- 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/browser/extensions/formautofill/ProfileAutoCompleteResult.jsm b/browser/extensions/formautofill/ProfileAutoCompleteResult.jsm index fd06e196b750..46bc8a581600 100644 --- a/browser/extensions/formautofill/ProfileAutoCompleteResult.jsm +++ b/browser/extensions/formautofill/ProfileAutoCompleteResult.jsm @@ -69,11 +69,11 @@ ProfileAutoCompleteResult.prototype = { * @returns {number} The number of results */ get matchCount() { - return this._matchingProfiles.length; + return this._popupLabels.length; }, _checkIndexBounds(index) { - if (index < 0 || index >= this._matchingProfiles.length) { + if (index < 0 || index >= this._popupLabels.length) { throw Components.Exception("Index out of range.", Cr.NS_ERROR_ILLEGAL_VALUE); } }, @@ -123,7 +123,10 @@ ProfileAutoCompleteResult.prototype = { }, _generateLabels(focusedFieldName, allFieldNames, profiles) { - return profiles.map(profile => { + // Skip results without a primary label. + return profiles.filter(profile => { + return !!profile[focusedFieldName]; + }).map(profile => { return { primary: profile[focusedFieldName], secondary: this._getSecondaryLabel(focusedFieldName, diff --git a/browser/extensions/formautofill/test/unit/test_profileAutocompleteResult.js b/browser/extensions/formautofill/test/unit/test_profileAutocompleteResult.js index 8cfc83ec34b3..486ccb8a8a97 100644 --- a/browser/extensions/formautofill/test/unit/test_profileAutocompleteResult.js +++ b/browser/extensions/formautofill/test/unit/test_profileAutocompleteResult.js @@ -12,11 +12,17 @@ let matchingProfiles = [{ organization: "Mozilla", "street-address": "331 E. Evelyn Avenue", tel: "1-650-903-0800", +}, { + guid: "test-guid-3", + organization: "", + "street-address": "321, No Name St.", + tel: "1-000-000-0000", }]; let allFieldNames = ["street-address", "organization", "tel"]; let testCases = [{ + description: "Focus on an `organization` field", options: {}, matchingProfiles, allFieldNames, @@ -46,6 +52,7 @@ let testCases = [{ }], }, }, { + description: "Focus on an `tel` field", options: {}, matchingProfiles, allFieldNames, @@ -72,9 +79,19 @@ let testCases = [{ secondary: "331 E. Evelyn Avenue", }), image: "", + }, { + value: "1-000-000-0000", + style: "autofill-profile", + comment: JSON.stringify(matchingProfiles[2]), + label: JSON.stringify({ + primary: "1-000-000-0000", + secondary: "321, No Name St.", + }), + image: "", }], }, }, { + description: "Focus on an `street-address` field", options: {}, matchingProfiles, allFieldNames, @@ -101,9 +118,19 @@ let testCases = [{ secondary: "Mozilla", }), image: "", + }, { + value: "321, No Name St.", + style: "autofill-profile", + comment: JSON.stringify(matchingProfiles[2]), + label: JSON.stringify({ + primary: "321, No Name St.", + secondary: "1-000-000-0000", + }), + image: "", }], }, }, { + description: "No matching profiles", options: {}, matchingProfiles: [], allFieldNames, @@ -115,6 +142,7 @@ let testCases = [{ items: [], }, }, { + description: "Search with failure", options: {resultCode: Ci.nsIAutoCompleteResult.RESULT_FAILURE}, matchingProfiles: [], allFieldNames, @@ -128,13 +156,14 @@ let testCases = [{ }]; add_task(function* test_all_patterns() { - testCases.forEach(pattern => { - let actual = new ProfileAutoCompleteResult(pattern.searchString, - pattern.fieldName, - pattern.allFieldNames, - pattern.matchingProfiles, - pattern.options); - let expectedValue = pattern.expected; + testCases.forEach(testCase => { + do_print("Starting testcase: " + testCase.description); + let actual = new ProfileAutoCompleteResult(testCase.searchString, + testCase.fieldName, + testCase.allFieldNames, + testCase.matchingProfiles, + testCase.options); + let expectedValue = testCase.expected; equal(actual.searchResult, expectedValue.searchResult); equal(actual.defaultIndex, expectedValue.defaultIndex); equal(actual.matchCount, expectedValue.items.length); From b70e5069a91fa8a2412f740cf2223e5a99229d36 Mon Sep 17 00:00:00 2001 From: Martin Stransky Date: Wed, 22 Feb 2017 09:49:54 +0100 Subject: [PATCH 006/234] Bug 1341296 - Move mozcontainer.c to cpp file, r=karlt MozReview-Commit-ID: 2n18VlOMQod --HG-- rename : widget/gtk/mozcontainer.c => widget/gtk/mozcontainer.cpp extra : rebase_source : c463aff90a88c37c1fe5ba52b2b0c2a588df8f92 --- widget/gtk/moz.build | 2 +- widget/gtk/{mozcontainer.c => mozcontainer.cpp} | 12 ++++++------ widget/gtk/mozcontainer.h | 8 -------- 3 files changed, 7 insertions(+), 15 deletions(-) rename widget/gtk/{mozcontainer.c => mozcontainer.cpp} (97%) diff --git a/widget/gtk/moz.build b/widget/gtk/moz.build index baccb6ccd900..fcac41c320ea 100644 --- a/widget/gtk/moz.build +++ b/widget/gtk/moz.build @@ -19,7 +19,7 @@ EXPORTS.mozilla += [ UNIFIED_SOURCES += [ 'IMContextWrapper.cpp', - 'mozcontainer.c', + 'mozcontainer.cpp', 'NativeKeyBindings.cpp', 'nsAppShell.cpp', 'nsBidiKeyboard.cpp', diff --git a/widget/gtk/mozcontainer.c b/widget/gtk/mozcontainer.cpp similarity index 97% rename from widget/gtk/mozcontainer.c rename to widget/gtk/mozcontainer.cpp index 9b596e4fb84c..84c10205537b 100644 --- a/widget/gtk/mozcontainer.c +++ b/widget/gtk/mozcontainer.cpp @@ -71,7 +71,8 @@ moz_container_get_type(void) moz_container_type = g_type_register_static (GTK_TYPE_CONTAINER, "MozContainer", - &moz_container_info, 0); + &moz_container_info, + static_cast(0)); #ifdef ACCESSIBILITY /* Set a factory to return accessible object with ROLE_REDUNDANT for * MozContainer, so that gail won't send focus notification for it */ @@ -89,7 +90,7 @@ moz_container_new (void) { MozContainer *container; - container = g_object_new (MOZ_CONTAINER_TYPE, NULL); + container = static_cast(g_object_new (MOZ_CONTAINER_TYPE, nullptr)); return GTK_WIDGET(container); } @@ -290,7 +291,7 @@ moz_container_size_allocate (GtkWidget *widget, tmp_list = container->children; while (tmp_list) { - MozContainerChild *child = tmp_list->data; + MozContainerChild *child = static_cast(tmp_list->data); moz_container_allocate_child (container, child); @@ -372,7 +373,7 @@ moz_container_forall (GtkContainer *container, gboolean include_internals, tmp_list = moz_container->children; while (tmp_list) { MozContainerChild *child; - child = tmp_list->data; + child = static_cast(tmp_list->data); tmp_list = tmp_list->next; (* callback) (child->widget, callback_data); } @@ -400,7 +401,7 @@ moz_container_get_child (MozContainer *container, GtkWidget *child_widget) while (tmp_list) { MozContainerChild *child; - child = tmp_list->data; + child = static_cast(tmp_list->data); tmp_list = tmp_list->next; if (child->widget == child_widget) @@ -415,4 +416,3 @@ moz_container_add(GtkContainer *container, GtkWidget *widget) { moz_container_put(MOZ_CONTAINER(container), widget, 0, 0); } - diff --git a/widget/gtk/mozcontainer.h b/widget/gtk/mozcontainer.h index 23e17f7b39c8..51c76bb6a607 100644 --- a/widget/gtk/mozcontainer.h +++ b/widget/gtk/mozcontainer.h @@ -10,10 +10,6 @@ #include -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - /* * MozContainer * @@ -79,8 +75,4 @@ void moz_container_move (MozContainer *container, gint width, gint height); -#ifdef __cplusplus -} -#endif /* __cplusplus */ - #endif /* __MOZ_CONTAINER_H__ */ From ab2a0b9de52af7a71a2fc4fda98de9441182d912 Mon Sep 17 00:00:00 2001 From: steveck-chung Date: Wed, 15 Feb 2017 18:33:52 +0800 Subject: [PATCH 007/234] Bug 1339007 - Replace async getEnabledStatus with initialProcessData for content process init, r=MattN MozReview-Commit-ID: Eg0ulHpjpSL --HG-- extra : rebase_source : 03ee969174f88c1834cbe3c8bede369d72b3e19d --- .../formautofill/FormAutofillContent.jsm | 7 ++-- .../formautofill/FormAutofillParent.jsm | 28 ++++++++----- .../test/unit/test_enabledStatus.js | 40 ++++++++++++++----- 3 files changed, 50 insertions(+), 25 deletions(-) diff --git a/browser/extensions/formautofill/FormAutofillContent.jsm b/browser/extensions/formautofill/FormAutofillContent.jsm index cb2d631a34d0..f871123b7178 100644 --- a/browser/extensions/formautofill/FormAutofillContent.jsm +++ b/browser/extensions/formautofill/FormAutofillContent.jsm @@ -271,9 +271,10 @@ var FormAutofillContent = { ProfileAutocomplete.ensureUnregistered(); } }); - Services.cpmm.sendAsyncMessage("FormAutofill:getEnabledStatus"); - // TODO: use initialProcessData: - // Services.cpmm.initialProcessData.autofillEnabled + + if (Services.cpmm.initialProcessData.autofillEnabled) { + ProfileAutocomplete.ensureRegistered(); + } }, /** diff --git a/browser/extensions/formautofill/FormAutofillParent.jsm b/browser/extensions/formautofill/FormAutofillParent.jsm index a8830be3c1f7..da90796234b8 100644 --- a/browser/extensions/formautofill/FormAutofillParent.jsm +++ b/browser/extensions/formautofill/FormAutofillParent.jsm @@ -80,11 +80,10 @@ FormAutofillParent.prototype = { // Observing the pref and storage changes Services.prefs.addObserver(ENABLED_PREF, this, false); Services.obs.addObserver(this, "formautofill-storage-changed", false); - this._enabled = this._getStatus(); + // Force to trigger the onStatusChanged function for setting listeners properly // while initizlization - this._onStatusChanged(); - Services.ppmm.addMessageListener("FormAutofill:getEnabledStatus", this); + this._setStatus(this._getStatus()); }, observe(subject, topic, data) { @@ -104,8 +103,7 @@ FormAutofillParent.prototype = { // Observe pref changes and update _enabled cache if status is changed. let currentStatus = this._getStatus(); if (currentStatus !== this._enabled) { - this._enabled = currentStatus; - this._onStatusChanged(); + this._setStatus(currentStatus); } break; } @@ -118,8 +116,7 @@ FormAutofillParent.prototype = { let currentStatus = this._getStatus(); if (currentStatus !== this._enabled) { - this._enabled = currentStatus; - this._onStatusChanged(); + this._setStatus(currentStatus); } break; } @@ -143,6 +140,9 @@ FormAutofillParent.prototype = { } Services.ppmm.broadcastAsyncMessage("FormAutofill:enabledStatus", this._enabled); + // Sync process data autofillEnabled to make sure the value up to date + // no matter when the new content process is initialized. + Services.ppmm.initialProcessData.autofillEnabled = this._enabled; }, /** @@ -159,6 +159,16 @@ FormAutofillParent.prototype = { return this._profileStore.getAll().length > 0; }, + /** + * Set status and trigger _onStatusChanged. + * + * @param {boolean} newStatus The latest status we want to set for _enabled + */ + _setStatus(newStatus) { + this._enabled = newStatus; + this._onStatusChanged(); + }, + /** * Handles the message coming from FormAutofillContent. * @@ -171,10 +181,6 @@ FormAutofillParent.prototype = { case "FormAutofill:GetProfiles": this._getProfiles(data, target); break; - case "FormAutofill:getEnabledStatus": - Services.ppmm.broadcastAsyncMessage("FormAutofill:enabledStatus", - this._enabled); - break; } }, diff --git a/browser/extensions/formautofill/test/unit/test_enabledStatus.js b/browser/extensions/formautofill/test/unit/test_enabledStatus.js index 31ccdf20299f..92582c3c21c3 100644 --- a/browser/extensions/formautofill/test/unit/test_enabledStatus.js +++ b/browser/extensions/formautofill/test/unit/test_enabledStatus.js @@ -8,13 +8,15 @@ Cu.import("resource://formautofill/FormAutofillParent.jsm"); add_task(function* test_enabledStatus_init() { let formAutofillParent = new FormAutofillParent(); - sinon.spy(formAutofillParent, "_onStatusChanged"); + sinon.spy(formAutofillParent, "_setStatus"); // Default status is false before initialization do_check_eq(formAutofillParent._enabled, false); + do_check_eq(Services.ppmm.initialProcessData.autofillEnabled, undefined); formAutofillParent.init(); - do_check_eq(formAutofillParent._onStatusChanged.called, true); + do_check_eq(formAutofillParent._setStatus.called, true); + do_check_eq(Services.ppmm.initialProcessData.autofillEnabled, false); formAutofillParent._uninit(); }); @@ -22,36 +24,36 @@ add_task(function* test_enabledStatus_init() { add_task(function* test_enabledStatus_observe() { let formAutofillParent = new FormAutofillParent(); sinon.stub(formAutofillParent, "_getStatus"); - sinon.spy(formAutofillParent, "_onStatusChanged"); + sinon.spy(formAutofillParent, "_setStatus"); // _enabled = _getStatus() => No need to trigger onStatusChanged formAutofillParent._enabled = true; formAutofillParent._getStatus.returns(true); formAutofillParent.observe(null, "nsPref:changed", "browser.formautofill.enabled"); - do_check_eq(formAutofillParent._onStatusChanged.called, false); + do_check_eq(formAutofillParent._setStatus.called, false); // _enabled != _getStatus() => Need to trigger onStatusChanged formAutofillParent._getStatus.returns(false); formAutofillParent.observe(null, "nsPref:changed", "browser.formautofill.enabled"); - do_check_eq(formAutofillParent._onStatusChanged.called, true); + do_check_eq(formAutofillParent._setStatus.called, true); // profile added => Need to trigger onStatusChanged formAutofillParent._getStatus.returns(!formAutofillParent._enabled); - formAutofillParent._onStatusChanged.reset(); + formAutofillParent._setStatus.reset(); formAutofillParent.observe(null, "formautofill-storage-changed", "add"); - do_check_eq(formAutofillParent._onStatusChanged.called, true); + do_check_eq(formAutofillParent._setStatus.called, true); // profile removed => Need to trigger onStatusChanged formAutofillParent._getStatus.returns(!formAutofillParent._enabled); - formAutofillParent._onStatusChanged.reset(); + formAutofillParent._setStatus.reset(); formAutofillParent.observe(null, "formautofill-storage-changed", "remove"); - do_check_eq(formAutofillParent._onStatusChanged.called, true); + do_check_eq(formAutofillParent._setStatus.called, true); // profile updated => no need to trigger onStatusChanged formAutofillParent._getStatus.returns(!formAutofillParent._enabled); - formAutofillParent._onStatusChanged.reset(); + formAutofillParent._setStatus.reset(); formAutofillParent.observe(null, "formautofill-storage-changed", "update"); - do_check_eq(formAutofillParent._onStatusChanged.called, false); + do_check_eq(formAutofillParent._setStatus.called, false); }); add_task(function* test_enabledStatus_getStatus() { @@ -82,3 +84,19 @@ add_task(function* test_enabledStatus_getStatus() { Services.prefs.setBoolPref("browser.formautofill.enabled", false); do_check_eq(formAutofillParent._getStatus(), false); }); + +add_task(function* test_enabledStatus_setStatus() { + let formAutofillParent = new FormAutofillParent(); + sinon.spy(formAutofillParent, "_onStatusChanged"); + + formAutofillParent._setStatus(true); + do_check_eq(formAutofillParent._enabled, true); + do_check_eq(Services.ppmm.initialProcessData.autofillEnabled, true); + do_check_eq(formAutofillParent._onStatusChanged.called, true); + + formAutofillParent._onStatusChanged.reset(); + formAutofillParent._setStatus(false); + do_check_eq(formAutofillParent._enabled, false); + do_check_eq(Services.ppmm.initialProcessData.autofillEnabled, false); + do_check_eq(formAutofillParent._onStatusChanged.called, true); +}); From 30ad7317630c42d9dbca87499a91dc20c69a8b9f Mon Sep 17 00:00:00 2001 From: Mark Banner Date: Wed, 22 Feb 2017 10:33:20 +0000 Subject: [PATCH 008/234] Bug 1341571 - 'ex' is not defined in TelemetryModules.jsm. r=Dexter MozReview-Commit-ID: 1rlDGjm9k0W --HG-- extra : rebase_source : ca849a93c8d470858f946da6db9255dc45c46fd5 --- toolkit/components/telemetry/TelemetryModules.jsm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/toolkit/components/telemetry/TelemetryModules.jsm b/toolkit/components/telemetry/TelemetryModules.jsm index 0964ab3998f5..561710bffc3b 100644 --- a/toolkit/components/telemetry/TelemetryModules.jsm +++ b/toolkit/components/telemetry/TelemetryModules.jsm @@ -89,11 +89,10 @@ this.TelemetryModules = Object.freeze({ } ); }, - err => this._log.error("notify - promise failed", ex) + err => this._log.error("notify - promise failed", err) ); } catch (ex) { this._log.error("notify - caught exception", ex); } }, }); - From d7f752c059fd980d12511ae23e43d06428d0f88f Mon Sep 17 00:00:00 2001 From: Julian Descottes Date: Wed, 22 Feb 2017 11:05:05 +0100 Subject: [PATCH 009/234] Bug 1338300 - part1: add color to the css grid highlighter options;r=gl MozReview-Commit-ID: KnAdz2MCeDZ --HG-- extra : rebase_source : e4a1ee401650266e71f59deaf6cc95fa94429ccd --- .../server/actors/highlighters/css-grid.js | 37 +++++++++++++++---- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/devtools/server/actors/highlighters/css-grid.js b/devtools/server/actors/highlighters/css-grid.js index 170b179e9208..0e5b189a2e1e 100644 --- a/devtools/server/actors/highlighters/css-grid.js +++ b/devtools/server/actors/highlighters/css-grid.js @@ -21,20 +21,22 @@ const { const { stringifyGridFragments } = require("devtools/server/actors/utils/css-grid-utils"); const CSS_GRID_ENABLED_PREF = "layout.css.grid.enabled"; +const DEFAULT_GRID_COLOR = "#4B0082"; const ROWS = "rows"; const COLUMNS = "cols"; + const GRID_LINES_PROPERTIES = { "edge": { lineDash: [0, 0], - strokeStyle: "#4B0082" + alpha: 1, }, "explicit": { lineDash: [5, 3], - strokeStyle: "#8A2BE2" + alpha: 0.75, }, "implicit": { lineDash: [2, 2], - strokeStyle: "#9370DB" + alpha: 0.5, } }; @@ -42,7 +44,7 @@ const GRID_LINES_PROPERTIES = { const GRID_GAP_PATTERN_WIDTH = 14; const GRID_GAP_PATTERN_HEIGHT = 14; const GRID_GAP_PATTERN_LINE_DASH = [5, 3]; -const GRID_GAP_PATTERN_STROKE_STYLE = "#9370DB"; +const GRID_GAP_ALPHA = 0.5; /** * Cached used by `CssGridHighlighter.getGridGapPattern`. @@ -64,6 +66,9 @@ const COLUMN_KEY = {}; * h.destroy(); * * Available Options: + * - color(colorValue) + * @param {String} colorValue + * The color that should be used to draw the highlighter for this grid. * - showGridArea(areaName) * @param {String} areaName * Shows the grid area highlight for the given area name. @@ -251,6 +256,10 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, { return this.getElement("canvas"); }, + get color() { + return this.options.color || DEFAULT_GRID_COLOR; + }, + /** * Gets the grid gap pattern used to render the gap regions. * @@ -270,6 +279,7 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, { canvas.height = GRID_GAP_PATTERN_HEIGHT; let ctx = canvas.getContext("2d"); + ctx.save(); ctx.setLineDash(GRID_GAP_PATTERN_LINE_DASH); ctx.beginPath(); ctx.translate(.5, .5); @@ -282,8 +292,10 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, { ctx.lineTo(0, GRID_GAP_PATTERN_HEIGHT); } - ctx.strokeStyle = GRID_GAP_PATTERN_STROKE_STYLE; + ctx.strokeStyle = this.color; + ctx.globalAlpha = GRID_GAP_ALPHA; ctx.stroke(); + ctx.restore(); let pattern = ctx.createPattern(canvas, "repeat"); gCachedGridPattern.set(dimension, pattern); @@ -295,8 +307,7 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, { * using DeadWrapper objects as gap patterns the next time. */ onNavigate() { - gCachedGridPattern.delete(ROW_KEY); - gCachedGridPattern.delete(COLUMN_KEY); + this._clearCache(); }, onWillNavigate({ isTopLevel }) { @@ -311,9 +322,17 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, { return false; } + // The grid pattern cache should be cleared in case the color changed. + this._clearCache(); + return this._update(); }, + _clearCache() { + gCachedGridPattern.delete(ROW_KEY); + gCachedGridPattern.delete(COLUMN_KEY); + }, + /** * Shows the grid area highlight for the given area name. * @@ -610,7 +629,9 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, { this.ctx.lineTo(endPos, linePos); } - this.ctx.strokeStyle = GRID_LINES_PROPERTIES[lineType].strokeStyle; + this.ctx.strokeStyle = this.color; + this.ctx.globalAlpha = GRID_LINES_PROPERTIES[lineType].alpha; + this.ctx.stroke(); this.ctx.restore(); }, From 2b9ac413d6cdaeaf001d9cf029aa83cf915d0d81 Mon Sep 17 00:00:00 2001 From: Julian Descottes Date: Tue, 21 Feb 2017 20:24:40 +0100 Subject: [PATCH 010/234] Bug 1338300 - part2: extract layoutview GridItem to dedicated component;r=gl MozReview-Commit-ID: AKWvRoGu6CZ --HG-- extra : rebase_source : a116abf52a1c0b77b6ad5a06bde9aafe53d2b10c --- .../inspector/layout/components/GridItem.js | 69 +++++++++++++++++++ .../inspector/layout/components/GridList.js | 53 +++----------- .../inspector/layout/components/moz.build | 1 + .../client/inspector/layout/reducers/grids.js | 14 ++-- 4 files changed, 82 insertions(+), 55 deletions(-) create mode 100644 devtools/client/inspector/layout/components/GridItem.js diff --git a/devtools/client/inspector/layout/components/GridItem.js b/devtools/client/inspector/layout/components/GridItem.js new file mode 100644 index 000000000000..d57ed09b0693 --- /dev/null +++ b/devtools/client/inspector/layout/components/GridItem.js @@ -0,0 +1,69 @@ +/* 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/. */ + +"use strict"; + +const { addons, createClass, DOM: dom, PropTypes } = + require("devtools/client/shared/vendor/react"); + +const Types = require("../types"); + +module.exports = createClass({ + + displayName: "GridItem", + + propTypes: { + grid: PropTypes.shape(Types.grid).isRequired, + onSetGridOverlayColor: PropTypes.func.isRequired, + onToggleGridHighlighter: PropTypes.func.isRequired, + }, + + mixins: [ addons.PureRenderMixin ], + + onGridCheckboxClick() { + let { + grid, + onToggleGridHighlighter, + } = this.props; + + onToggleGridHighlighter(grid.nodeFront); + }, + + render() { + let { grid } = this.props; + let { nodeFront } = grid; + let { displayName, attributes } = nodeFront; + + let gridName = displayName; + + let idIndex = attributes.findIndex(({ name }) => name === "id"); + if (idIndex > -1 && attributes[idIndex].value) { + gridName += "#" + attributes[idIndex].value; + } + + let classIndex = attributes.findIndex(({name}) => name === "class"); + if (classIndex > -1 && attributes[classIndex].value) { + gridName += "." + attributes[classIndex].value.split(" ").join("."); + } + + return dom.li( + { + key: grid.id, + }, + dom.label( + {}, + dom.input( + { + type: "checkbox", + value: grid.id, + checked: grid.highlighted, + onChange: this.onGridCheckboxClick, + } + ), + gridName + ) + ); + }, + +}); diff --git a/devtools/client/inspector/layout/components/GridList.js b/devtools/client/inspector/layout/components/GridList.js index fd3d038a13a7..72101dc8ba1a 100644 --- a/devtools/client/inspector/layout/components/GridList.js +++ b/devtools/client/inspector/layout/components/GridList.js @@ -4,9 +4,11 @@ "use strict"; -const { addons, createClass, DOM: dom, PropTypes } = +const { addons, createClass, createFactory, DOM: dom, PropTypes } = require("devtools/client/shared/vendor/react"); +const GridItem = createFactory(require("./GridItem")); + const Types = require("../types"); const { getStr } = require("../utils/l10n"); @@ -21,18 +23,10 @@ module.exports = createClass({ mixins: [ addons.PureRenderMixin ], - onGridCheckboxClick({ target }) { - let { - grids, - onToggleGridHighlighter, - } = this.props; - - onToggleGridHighlighter(grids[target.value].nodeFront); - }, - render() { let { grids, + onToggleGridHighlighter, } = this.props; return dom.div( @@ -45,43 +39,12 @@ module.exports = createClass({ ), dom.ul( {}, - grids.map(grid => { - let { nodeFront } = grid; - let { displayName, attributes } = nodeFront; - - let gridName = displayName; - - let idIndex = attributes.findIndex(({ name }) => name === "id"); - if (idIndex > -1 && attributes[idIndex].value) { - gridName += "#" + attributes[idIndex].value; - } - - let classIndex = attributes.findIndex(({name}) => name === "class"); - if (classIndex > -1 && attributes[classIndex].value) { - gridName += "." + attributes[classIndex].value.split(" ").join("."); - } - - return dom.li( - { - key: grid.id, - }, - dom.label( - {}, - dom.input( - { - type: "checkbox", - value: grid.id, - checked: grid.highlighted, - onChange: this.onGridCheckboxClick, - } - ), - gridName - ) - ); - }) + grids.map(grid => GridItem({ + grid, + onToggleGridHighlighter, + })) ) ); }, }); - diff --git a/devtools/client/inspector/layout/components/moz.build b/devtools/client/inspector/layout/components/moz.build index 35bb87a6d180..7ad90ba4572b 100644 --- a/devtools/client/inspector/layout/components/moz.build +++ b/devtools/client/inspector/layout/components/moz.build @@ -16,5 +16,6 @@ DevToolsModules( 'ComputedProperty.js', 'Grid.js', 'GridDisplaySettings.js', + 'GridItem.js', 'GridList.js', ) diff --git a/devtools/client/inspector/layout/reducers/grids.js b/devtools/client/inspector/layout/reducers/grids.js index e39dc82dd612..472b21a5fa68 100644 --- a/devtools/client/inspector/layout/reducers/grids.js +++ b/devtools/client/inspector/layout/reducers/grids.js @@ -14,17 +14,11 @@ const INITIAL_GRIDS = []; let reducers = { [UPDATE_GRID_HIGHLIGHTED](grids, { nodeFront, highlighted }) { - let newGrids = grids.map(g => { - if (g.nodeFront == nodeFront) { - g.highlighted = highlighted; - } else { - g.highlighted = false; - } - - return g; + return grids.map(g => { + return Object.assign({}, g, { + highlighted: g.nodeFront === nodeFront ? highlighted : false + }); }); - - return newGrids; }, [UPDATE_GRIDS](_, { grids }) { From 5551adf76ee2f7c6918b7da3df77b4504f491dd1 Mon Sep 17 00:00:00 2001 From: Julian Descottes Date: Wed, 22 Feb 2017 12:39:04 +0100 Subject: [PATCH 011/234] Bug 1338300 - part3: add colorpicker to update grid overlay color;r=gl MozReview-Commit-ID: 5wgZCgx8J3u --HG-- extra : rebase_source : 88ffb25a7737d4ea44911a7d6101454298387824 --- .../client/inspector/layout/actions/grids.js | 19 +++- .../client/inspector/layout/actions/index.js | 3 + .../client/inspector/layout/components/App.js | 4 +- .../inspector/layout/components/Grid.js | 6 + .../inspector/layout/components/GridItem.js | 53 ++++++++- .../inspector/layout/components/GridList.js | 6 + devtools/client/inspector/layout/layout.js | 107 +++++++++++++++++- .../client/inspector/layout/reducers/grids.js | 13 +++ devtools/client/inspector/layout/types.js | 3 + devtools/client/themes/layout.css | 26 +++++ 10 files changed, 231 insertions(+), 9 deletions(-) diff --git a/devtools/client/inspector/layout/actions/grids.js b/devtools/client/inspector/layout/actions/grids.js index a1744b70046d..0f69ef62f025 100644 --- a/devtools/client/inspector/layout/actions/grids.js +++ b/devtools/client/inspector/layout/actions/grids.js @@ -5,12 +5,29 @@ "use strict"; const { + UPDATE_GRID_COLOR, UPDATE_GRID_HIGHLIGHTED, UPDATE_GRIDS, } = require("./index"); module.exports = { + /** + * Update the color used for the grid's highlighter. + * + * @param {NodeFront} nodeFront + * The NodeFront of the DOM node to toggle the grid highlighter. + * @param {String} color + * The color to use for thie nodeFront's grid highlighter. + */ + updateGridColor(nodeFront, color) { + return { + type: UPDATE_GRID_COLOR, + color, + nodeFront, + }; + }, + /** * Update the grid highlighted state. * @@ -22,8 +39,8 @@ module.exports = { updateGridHighlighted(nodeFront, highlighted) { return { type: UPDATE_GRID_HIGHLIGHTED, - nodeFront, highlighted, + nodeFront, }; }, diff --git a/devtools/client/inspector/layout/actions/index.js b/devtools/client/inspector/layout/actions/index.js index d2b3383877db..d694e37400a2 100644 --- a/devtools/client/inspector/layout/actions/index.js +++ b/devtools/client/inspector/layout/actions/index.js @@ -8,6 +8,9 @@ const { createEnum } = require("devtools/client/shared/enum"); createEnum([ + // Update the color used for the overlay of a grid. + "UPDATE_GRID_COLOR", + // Update the grid highlighted state. "UPDATE_GRID_HIGHLIGHTED", diff --git a/devtools/client/inspector/layout/components/App.js b/devtools/client/inspector/layout/components/App.js index 403eccdf9101..d8dd19582d0c 100644 --- a/devtools/client/inspector/layout/components/App.js +++ b/devtools/client/inspector/layout/components/App.js @@ -26,11 +26,13 @@ const App = createClass({ propTypes: { boxModel: PropTypes.shape(Types.boxModel).isRequired, + getSwatchColorPickerTooltip: PropTypes.func.isRequired, grids: PropTypes.arrayOf(PropTypes.shape(Types.grid)).isRequired, highlighterSettings: PropTypes.shape(Types.highlighterSettings).isRequired, showBoxModelProperties: PropTypes.bool.isRequired, - onShowBoxModelEditor: PropTypes.func.isRequired, onHideBoxModelHighlighter: PropTypes.func.isRequired, + onSetGridOverlayColor: PropTypes.func.isRequired, + onShowBoxModelEditor: PropTypes.func.isRequired, onShowBoxModelHighlighter: PropTypes.func.isRequired, onToggleGridHighlighter: PropTypes.func.isRequired, onToggleShowGridLineNumbers: PropTypes.func.isRequired, diff --git a/devtools/client/inspector/layout/components/Grid.js b/devtools/client/inspector/layout/components/Grid.js index 2e1e63cc9f0f..68a88ee26646 100644 --- a/devtools/client/inspector/layout/components/Grid.js +++ b/devtools/client/inspector/layout/components/Grid.js @@ -18,8 +18,10 @@ module.exports = createClass({ displayName: "Grid", propTypes: { + getSwatchColorPickerTooltip: PropTypes.func.isRequired, grids: PropTypes.arrayOf(PropTypes.shape(Types.grid)).isRequired, highlighterSettings: PropTypes.shape(Types.highlighterSettings).isRequired, + onSetGridOverlayColor: PropTypes.func.isRequired, onToggleGridHighlighter: PropTypes.func.isRequired, onToggleShowGridLineNumbers: PropTypes.func.isRequired, onToggleShowInfiniteLines: PropTypes.func.isRequired, @@ -29,8 +31,10 @@ module.exports = createClass({ render() { let { + getSwatchColorPickerTooltip, grids, highlighterSettings, + onSetGridOverlayColor, onToggleGridHighlighter, onToggleShowGridLineNumbers, onToggleShowInfiniteLines, @@ -42,7 +46,9 @@ module.exports = createClass({ id: "layout-grid-container", }, GridList({ + getSwatchColorPickerTooltip, grids, + onSetGridOverlayColor, onToggleGridHighlighter, }), GridDisplaySettings({ diff --git a/devtools/client/inspector/layout/components/GridItem.js b/devtools/client/inspector/layout/components/GridItem.js index d57ed09b0693..1dbf62be8ebf 100644 --- a/devtools/client/inspector/layout/components/GridItem.js +++ b/devtools/client/inspector/layout/components/GridItem.js @@ -4,8 +4,8 @@ "use strict"; -const { addons, createClass, DOM: dom, PropTypes } = - require("devtools/client/shared/vendor/react"); +const { addons, createClass, DOM: dom, PropTypes } = require("devtools/client/shared/vendor/react"); +const { findDOMNode } = require("devtools/client/shared/vendor/react-dom"); const Types = require("../types"); @@ -14,6 +14,7 @@ module.exports = createClass({ displayName: "GridItem", propTypes: { + getSwatchColorPickerTooltip: PropTypes.func.isRequired, grid: PropTypes.shape(Types.grid).isRequired, onSetGridOverlayColor: PropTypes.func.isRequired, onToggleGridHighlighter: PropTypes.func.isRequired, @@ -21,6 +22,34 @@ module.exports = createClass({ mixins: [ addons.PureRenderMixin ], + componentDidMount() { + let tooltip = this.props.getSwatchColorPickerTooltip(); + let swatchEl = findDOMNode(this).querySelector(".grid-color-swatch"); + + let previousColor; + tooltip.addSwatch(swatchEl, { + onCommit: this.setGridColor, + onPreview: this.setGridColor, + onRevert: () => { + this.props.onSetGridOverlayColor(this.props.grid.nodeFront, previousColor); + }, + onShow: () => { + previousColor = this.props.grid.color; + }, + }); + }, + + componentWillUnmount() { + let tooltip = this.props.getSwatchColorPickerTooltip(); + let swatchEl = findDOMNode(this).querySelector(".grid-color-swatch"); + tooltip.removeSwatch(swatchEl); + }, + + setGridColor() { + let color = findDOMNode(this).querySelector(".grid-color-value").textContent; + this.props.onSetGridOverlayColor(this.props.grid.nodeFront, color); + }, + onGridCheckboxClick() { let { grid, @@ -50,6 +79,7 @@ module.exports = createClass({ return dom.li( { key: grid.id, + className: "grid-item", }, dom.label( {}, @@ -62,6 +92,25 @@ module.exports = createClass({ } ), gridName + ), + dom.div( + { + className: "grid-color-swatch", + style: { + backgroundColor: grid.color, + }, + title: grid.color, + } + ), + // The SwatchColorPicker relies on the nextSibling of the swatch element to apply + // the selected color. This is why we use a span in display: none for now. + // Ideally we should modify the SwatchColorPickerTooltip to bypass this requirement. + // See https://bugzilla.mozilla.org/show_bug.cgi?id=1341578 + dom.span( + { + className: "grid-color-value" + }, + grid.color ) ); }, diff --git a/devtools/client/inspector/layout/components/GridList.js b/devtools/client/inspector/layout/components/GridList.js index 72101dc8ba1a..4898a8358490 100644 --- a/devtools/client/inspector/layout/components/GridList.js +++ b/devtools/client/inspector/layout/components/GridList.js @@ -17,7 +17,9 @@ module.exports = createClass({ displayName: "GridList", propTypes: { + getSwatchColorPickerTooltip: PropTypes.func.isRequired, grids: PropTypes.arrayOf(PropTypes.shape(Types.grid)).isRequired, + onSetGridOverlayColor: PropTypes.func.isRequired, onToggleGridHighlighter: PropTypes.func.isRequired, }, @@ -25,7 +27,9 @@ module.exports = createClass({ render() { let { + getSwatchColorPickerTooltip, grids, + onSetGridOverlayColor, onToggleGridHighlighter, } = this.props; @@ -40,7 +44,9 @@ module.exports = createClass({ dom.ul( {}, grids.map(grid => GridItem({ + getSwatchColorPickerTooltip, grid, + onSetGridOverlayColor, onToggleGridHighlighter, })) ) diff --git a/devtools/client/inspector/layout/layout.js b/devtools/client/inspector/layout/layout.js index fa2e96087c24..8ca1e09dc972 100644 --- a/devtools/client/inspector/layout/layout.js +++ b/devtools/client/inspector/layout/layout.js @@ -13,10 +13,13 @@ const { InplaceEditor } = require("devtools/client/shared/inplace-editor"); const { createFactory, createElement } = require("devtools/client/shared/vendor/react"); const { Provider } = require("devtools/client/shared/vendor/react-redux"); +const SwatchColorPickerTooltip = require("devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip"); + const { updateLayout, } = require("./actions/box-model"); const { + updateGridColor, updateGridHighlighted, updateGrids, } = require("./actions/grids"); @@ -37,6 +40,18 @@ const NUMERIC = /^-?[\d\.]+$/; const SHOW_GRID_LINE_NUMBERS = "devtools.gridinspector.showGridLineNumbers"; const SHOW_INFINITE_LINES_PREF = "devtools.gridinspector.showInfiniteLines"; +// Default grid colors. +const GRID_COLORS = [ + "#05E4EE", + "#BB9DFF", + "#FFB53B", + "#71F362", + "#FF90FF", + "#FF90FF", + "#1B80FF", + "#FF2647" +]; + function LayoutView(inspector, window) { this.document = window.document; this.highlighters = inspector.highlighters; @@ -74,7 +89,23 @@ LayoutView.prototype = { this.loadHighlighterSettings(); + // Create a shared SwatchColorPicker instance to be reused by all GridItem components. + this.swatchColorPickerTooltip = new SwatchColorPickerTooltip( + this.inspector.toolbox.doc, + this.inspector, + { + supportsCssColor4ColorFunction: () => false + } + ); + let app = App({ + /** + * Retrieve the shared SwatchColorPicker instance. + */ + getSwatchColorPickerTooltip: () => { + return this.swatchColorPickerTooltip; + }, + /** * Shows the box model properties under the box model if true, otherwise, hidden by * default. @@ -89,6 +120,29 @@ LayoutView.prototype = { toolbox.highlighterUtils.unhighlight(); }, + /** + * Handler for a change in the grid overlay color picker for a grid container. + * + * @param {NodeFront} node + * The NodeFront of the grid container element for which the grid color is + * being updated. + * @param {String} color + * A hex string representing the color to use. + */ + onSetGridOverlayColor: (node, color) => { + this.store.dispatch(updateGridColor(node, color)); + let { grids } = this.store.getState(); + + // If the grid for which the color was updated currently has a highlighter, update + // the color. + for (let grid of grids) { + if (grid.nodeFront === node && grid.highlighted) { + let highlighterSettings = this.getGridHighlighterSettings(node); + this.highlighters.showGridHighlighter(node, highlighterSettings); + } + } + }, + /** * Shows the inplace editor when a box model editable value is clicked on the * box model panel. @@ -180,13 +234,13 @@ LayoutView.prototype = { * highlighter is toggled on/off for. */ onToggleGridHighlighter: node => { - let { highlighterSettings } = this.store.getState(); + let highlighterSettings = this.getGridHighlighterSettings(node); this.highlighters.toggleGridHighlighter(node, highlighterSettings); }, /** * Handler for a change in the show grid line numbers checkbox in the - * GridDisplaySettings component. TOggles on/off the option to show the grid line + * GridDisplaySettings component. Toggles on/off the option to show the grid line * numbers in the grid highlighter. Refreshes the shown grid highlighter for the * grids currently highlighted. * @@ -197,10 +251,11 @@ LayoutView.prototype = { this.store.dispatch(updateShowGridLineNumbers(enabled)); Services.prefs.setBoolPref(SHOW_GRID_LINE_NUMBERS, enabled); - let { grids, highlighterSettings } = this.store.getState(); + let { grids } = this.store.getState(); for (let grid of grids) { if (grid.highlighted) { + let highlighterSettings = this.getGridHighlighterSettings(grid.nodeFront); this.highlighters.showGridHighlighter(grid.nodeFront, highlighterSettings); } } @@ -219,14 +274,15 @@ LayoutView.prototype = { this.store.dispatch(updateShowInfiniteLines(enabled)); Services.prefs.setBoolPref(SHOW_INFINITE_LINES_PREF, enabled); - let { grids, highlighterSettings } = this.store.getState(); + let { grids } = this.store.getState(); for (let grid of grids) { if (grid.highlighted) { + let highlighterSettings = this.getGridHighlighterSettings(grid.nodeFront); this.highlighters.showGridHighlighter(grid.nodeFront, highlighterSettings); } } - }, + } }); let provider = createElement(Provider, { @@ -270,6 +326,43 @@ LayoutView.prototype = { this.walker = null; }, + /** + * Returns the color set for the grid highlighter associated with the provided + * nodeFront. + * + * @param {NodeFront} nodeFront + * The NodeFront for which we need the color. + */ + getGridColorForNodeFront(nodeFront) { + let { grids } = this.store.getState(); + + for (let grid of grids) { + if (grid.nodeFront === nodeFront) { + return grid.color; + } + } + + return null; + }, + + /** + * Create a highlighter settings object for the provided nodeFront. + * + * @param {NodeFront} nodeFront + * The NodeFront for which we need highlighter settings. + */ + getGridHighlighterSettings(nodeFront) { + let { highlighterSettings } = this.store.getState(); + + // Get the grid color for the provided nodeFront. + let color = this.getGridColorForNodeFront(nodeFront); + + // Merge the grid color to the generic highlighter settings. + return Object.assign({}, highlighterSettings, { + color + }); + }, + /** * Returns true if the layout panel is visible, and false otherwise. */ @@ -391,8 +484,12 @@ LayoutView.prototype = { let grid = gridFronts[i]; let nodeFront = yield this.walker.getNodeFromActor(grid.actorID, ["containerEl"]); + let fallbackColor = GRID_COLORS[i % GRID_COLORS.length]; + let color = this.getGridColorForNodeFront(nodeFront) || fallbackColor; + grids.push({ id: i, + color, gridFragments: grid.gridFragments, highlighted: nodeFront == this.highlighters.gridHighlighterShown, nodeFront, diff --git a/devtools/client/inspector/layout/reducers/grids.js b/devtools/client/inspector/layout/reducers/grids.js index 472b21a5fa68..f3843bf5edea 100644 --- a/devtools/client/inspector/layout/reducers/grids.js +++ b/devtools/client/inspector/layout/reducers/grids.js @@ -5,6 +5,7 @@ "use strict"; const { + UPDATE_GRID_COLOR, UPDATE_GRID_HIGHLIGHTED, UPDATE_GRIDS, } = require("../actions/index"); @@ -13,6 +14,18 @@ const INITIAL_GRIDS = []; let reducers = { + [UPDATE_GRID_COLOR](grids, { nodeFront, color }) { + let newGrids = grids.map(g => { + if (g.nodeFront == nodeFront) { + g.color = color; + } + + return g; + }); + + return newGrids; + }, + [UPDATE_GRID_HIGHLIGHTED](grids, { nodeFront, highlighted }) { return grids.map(g => { return Object.assign({}, g, { diff --git a/devtools/client/inspector/layout/types.js b/devtools/client/inspector/layout/types.js index 478f145b1cae..b9c286200ca0 100644 --- a/devtools/client/inspector/layout/types.js +++ b/devtools/client/inspector/layout/types.js @@ -24,6 +24,9 @@ exports.grid = { // The id of the grid id: PropTypes.number, + // The color for the grid overlay highlighter + color: PropTypes.string, + // The grid fragment object of the grid container gridFragments: PropTypes.array, diff --git a/devtools/client/themes/layout.css b/devtools/client/themes/layout.css index 3d106e01a898..d2848ba14e0d 100644 --- a/devtools/client/themes/layout.css +++ b/devtools/client/themes/layout.css @@ -52,3 +52,29 @@ text-align: center; padding: 0.5em; } + +/** + * Grid Item + */ + +.grid-item { + display: flex; + align-items: center; +} + +.grid-item input { + margin: 0 5px; +} + +.grid-color-swatch { + width: 12px; + height: 12px; + margin-left: 5px; + border: 1px solid var(--theme-highlight-gray); + border-radius: 50%; + cursor: pointer; +} + +.grid-color-value { + display: none; +} From bda562a499f096a6144048e21f42b380c246cbe2 Mon Sep 17 00:00:00 2001 From: cku Date: Wed, 22 Feb 2017 15:56:53 +0800 Subject: [PATCH 012/234] Bug 1340257 - Part 1. Remove Assertion failure: mightHaveNoneSVGMask. r=heycam After fighting with this assertion several months, I decided to remove it for two reasons: This assertion allows PreEffectBBoxProperty not being cached only under specific condition. But the condition is wider then we expect. 1. PreEffectsBBoxProperty is cached by nsIFrame::FinishAndStoreOverflow(this function calls ComputeEffectsRect which cache this property actually) and it is called from nsXXXFrame::Reflow on demand. Yes, *on demand*, not always. And this is the fist reason that why I think we should just remove this assertion. For example, nsBlockFrame::Reflow calls FinishAndStoreOverflow to store this property. But like BRFrame, it does not call FinishAndStoreOverflow at all. In anohter word, if you apply any SVG effect to a BRFrame, you will always hit this assertion. Here is an example:
So, if we still want to keep this assertion, we may need to create a list which list all frame types that cache PreEffectsBBoxProperty, and do this check only if the type of aFrame is listed. This is error prone since we may introduce a new frame type at any time and forget to update this table. 2. So, I think it's better just removing this assertion. The assertion that we really need is the next one(2nd one): MOZ_ASSERT(!preTransformOverflows, "GetVisualOverflowRect() won't return the pre-effects rect!"); Since hitting that assertion, the 2nd one, means caller will retrieve wrong effect region. Hitting the first assertion only means we do not cache PreEffectsBBoxProperty, it's pretty normal and not hurt anything. This is the second reason that I think we should remvoe this assertion. MozReview-Commit-ID: JfiYTiP2laG --HG-- extra : rebase_source : b0225e36cd7e33a23516cfbe5a40c731d92f8825 --- layout/svg/nsSVGIntegrationUtils.cpp | 68 +++++----------------------- 1 file changed, 11 insertions(+), 57 deletions(-) diff --git a/layout/svg/nsSVGIntegrationUtils.cpp b/layout/svg/nsSVGIntegrationUtils.cpp index f5f07b6f6642..7f0156adad53 100644 --- a/layout/svg/nsSVGIntegrationUtils.cpp +++ b/layout/svg/nsSVGIntegrationUtils.cpp @@ -85,66 +85,20 @@ private: if (r) { return *r; } - // Despite the fact that we're invoked for frames with SVG effects applied, - // we can actually get here. All continuations and IB split siblings of a - // frame with SVG effects applied will have the PreEffectsBBoxProperty - // property set on them. Therefore, the frames that are passed to us will - // always have that property set...well, with one exception. If the frames - // for an element with SVG effects applied have been subject to an "IB - // split", then the block frame(s) that caused the split will have been - // wrapped in anonymous, inline-block, nsBlockFrames of pseudo-type - // nsCSSAnonBoxes::mozAnonymousBlock. These "IB split sibling" anonymous - // blocks will have the PreEffectsBBoxProperty property set on them, but - // they will never be passed to us. Instead, we'll be passed the block - // children that they wrap, which don't have the PreEffectsBBoxProperty - // property set on them. This is actually okay. What we care about is - // collecting the _pre_ effects visual overflow rects of the frames to - // which the SVG effects have been applied. Since the IB split results in - // any overflow rect adjustments for transforms, effects, etc. taking - // place on the anonymous block wrappers, the wrapped children are left - // with their overflow rects unaffected. In other words, calling - // GetVisualOverflowRect() on the children will return their pre-effects - // visual overflow rects, just as we need. - // - // A couple of tests that demonstrate the IB split and cause us to get here - // are: - // - // * reftests/svg/svg-integration/clipPath-html-06.xhtml - // * reftests/svg/svg-integration/clipPath-html-06-extref.xhtml - // - // If we ever got passed a frame with the PreTransformOverflowAreasProperty - // property set, that would be bad, since then our GetVisualOverflowRect() - // call would give us the post-effects, and post-transform, overflow rect. - // - // There is one more exceptions, in - // nsStyleImageLayers::Layer::CalcDifference, we do not add - // nsChangeHint_UpdateOverflow hint when image mask(not SVG mask) property - // value changed, since replace image mask does not cause layout change. - // So even if we apply a new mask image to this frame, - // PreEffectsBBoxProperty might still left empty. + #ifdef DEBUG - if (aCheckPropCache) { - nsIFrame* firstFrame = - nsLayoutUtils::FirstContinuationOrIBSplitSibling(aFrame); - bool mightHaveNoneSVGMask = - nsSVGEffects::GetEffectProperties(firstFrame).MightHaveNoneSVGMask(); + // Having PreTransformOverflowAreasProperty cached means + // GetVisualOverflowRect() will return post-effect rect, which is not what + // we want. This function intentional reports pre-effect rect. But it does + // not matter if there is no SVG effect on this frame, since no effect + // means post-effect rect matches pre-effect rect. + if (nsSVGIntegrationUtils::UsingEffectsForFrame(aFrame)) { + nsOverflowAreas* preTransformOverflows = + aFrame->Properties().Get(aFrame->PreTransformOverflowAreasProperty()); - NS_ASSERTION(mightHaveNoneSVGMask || - aFrame->GetParent()->StyleContext()->GetPseudo() == - nsCSSAnonBoxes::mozAnonymousBlock, - "How did we getting here, then?"); + MOZ_ASSERT(!preTransformOverflows, + "GetVisualOverflowRect() won't return the pre-effects rect!"); } - - bool hasEffect = nsSVGIntegrationUtils::UsingEffectsForFrame(aFrame); - nsOverflowAreas* preTransformOverflows = - aFrame->Properties().Get(aFrame->PreTransformOverflowAreasProperty()); - // Having PreTransformOverflowAreasProperty means GetVisualOverflowRect() - // will return post-effect rect, which is not what we want, this function - // intentional reports pre-effect rect. But it does not matter if there is - // no SVG effect on this frame, since no effect means post-effect rect - // matches pre-effect rect. - MOZ_ASSERT(!hasEffect || !preTransformOverflows, - "GetVisualOverflowRect() won't return the pre-effects rect!"); #endif return aFrame->GetVisualOverflowRect(); } From 2f1f711b2d1c2ce4f18b0a53acbc11c4f10b2552 Mon Sep 17 00:00:00 2001 From: cku Date: Wed, 22 Feb 2017 16:27:40 +0800 Subject: [PATCH 013/234] Bug 1340257 - Part 2. Revert the change in bug 842114. r=cjku MozReview-Commit-ID: Kqyt4AHwpJL --HG-- extra : rebase_source : 2e4ddbe50895b79433ddbe1e392b1a0be83d142c --- layout/svg/nsSVGIntegrationUtils.cpp | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/layout/svg/nsSVGIntegrationUtils.cpp b/layout/svg/nsSVGIntegrationUtils.cpp index 7f0156adad53..7fb8719c3ade 100644 --- a/layout/svg/nsSVGIntegrationUtils.cpp +++ b/layout/svg/nsSVGIntegrationUtils.cpp @@ -55,12 +55,10 @@ public: */ PreEffectsVisualOverflowCollector(nsIFrame* aFirstContinuation, nsIFrame* aCurrentFrame, - const nsRect& aCurrentFrameOverflowArea, - bool aCheckPreEffectsBBoxPropCache) + const nsRect& aCurrentFrameOverflowArea) : mFirstContinuation(aFirstContinuation) , mCurrentFrame(aCurrentFrame) , mCurrentFrameOverflowArea(aCurrentFrameOverflowArea) - , mCheckPreEffectsBBoxPropCache(aCheckPreEffectsBBoxPropCache) { NS_ASSERTION(!mFirstContinuation->GetPrevContinuation(), "We want the first continuation here"); @@ -69,7 +67,7 @@ public: virtual void AddBox(nsIFrame* aFrame) override { nsRect overflow = (aFrame == mCurrentFrame) ? mCurrentFrameOverflowArea - : GetPreEffectsVisualOverflowRect(aFrame, mCheckPreEffectsBBoxPropCache); + : GetPreEffectsVisualOverflowRect(aFrame); mResult.UnionRect(mResult, overflow + aFrame->GetOffsetTo(mFirstContinuation)); } @@ -79,8 +77,7 @@ public: private: - static nsRect GetPreEffectsVisualOverflowRect(nsIFrame* aFrame, - bool aCheckPropCache) { + static nsRect GetPreEffectsVisualOverflowRect(nsIFrame* aFrame) { nsRect* r = aFrame->Properties().Get(nsIFrame::PreEffectsBBoxProperty()); if (r) { return *r; @@ -107,7 +104,6 @@ private: nsIFrame* mCurrentFrame; const nsRect& mCurrentFrameOverflowArea; nsRect mResult; - bool mCheckPreEffectsBBoxPropCache; }; /** @@ -118,15 +114,13 @@ static nsRect GetPreEffectsVisualOverflowUnion(nsIFrame* aFirstContinuation, nsIFrame* aCurrentFrame, const nsRect& aCurrentFramePreEffectsOverflow, - const nsPoint& aFirstContinuationToUserSpace, - bool aCheckPreEffectsBBoxPropCache) + const nsPoint& aFirstContinuationToUserSpace) { NS_ASSERTION(!aFirstContinuation->GetPrevContinuation(), "Need first continuation here"); PreEffectsVisualOverflowCollector collector(aFirstContinuation, aCurrentFrame, - aCurrentFramePreEffectsOverflow, - aCheckPreEffectsBBoxPropCache); + aCurrentFramePreEffectsOverflow); // Compute union of all overflow areas relative to aFirstContinuation: nsLayoutUtils::GetAllInFlowBoxes(aFirstContinuation, &collector); // Return the result in user space: @@ -204,8 +198,7 @@ nsSVGIntegrationUtils::GetSVGBBoxForNonSVGFrame(nsIFrame* aNonSVGFrame) nsLayoutUtils::FirstContinuationOrIBSplitSibling(aNonSVGFrame); // 'r' is in "user space": nsRect r = GetPreEffectsVisualOverflowUnion(firstFrame, nullptr, nsRect(), - GetOffsetToBoundingBox(firstFrame), - true); + GetOffsetToBoundingBox(firstFrame)); return nsLayoutUtils::RectToGfxRect(r, aNonSVGFrame->PresContext()->AppUnitsPerCSSPixel()); } @@ -267,11 +260,7 @@ nsRect nsLayoutUtils::RectToGfxRect( GetPreEffectsVisualOverflowUnion(firstFrame, aFrame, aPreEffectsOverflowRect, - firstFrameToBoundingBox, - false /* See the beginning of the - comment above this function to - know why we skip this - checking. */), + firstFrameToBoundingBox), aFrame->PresContext()->AppUnitsPerCSSPixel()); overrideBBox.RoundOut(); From ae051c91a0caca3e2621872aaee76bb6eb73c9e2 Mon Sep 17 00:00:00 2001 From: Sebastian Hengst Date: Wed, 22 Feb 2017 14:06:26 +0100 Subject: [PATCH 014/234] Backed out changeset 5f93d62d9229 (bug 1337936) for asserting in crashtest 869038.html. r=backout --- dom/base/DOMIntersectionObserver.cpp | 16 ++++++++-------- dom/base/DOMIntersectionObserver.h | 3 +-- dom/base/Element.cpp | 8 ++++---- dom/base/Element.h | 3 +-- dom/base/FragmentOrElement.cpp | 6 ------ dom/base/FragmentOrElement.h | 3 +-- dom/base/nsDocument.cpp | 20 +++++++++----------- dom/base/nsDocument.h | 3 +-- 8 files changed, 25 insertions(+), 37 deletions(-) diff --git a/dom/base/DOMIntersectionObserver.cpp b/dom/base/DOMIntersectionObserver.cpp index a0072763d664..4c5658923553 100644 --- a/dom/base/DOMIntersectionObserver.cpp +++ b/dom/base/DOMIntersectionObserver.cpp @@ -43,17 +43,15 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMIntersectionObserver) NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER - tmp->Disconnect(); NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwner) - NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument) NS_IMPL_CYCLE_COLLECTION_UNLINK(mCallback) NS_IMPL_CYCLE_COLLECTION_UNLINK(mRoot) NS_IMPL_CYCLE_COLLECTION_UNLINK(mQueuedEntries) + tmp->Disconnect(); NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMIntersectionObserver) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCallback) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRoot) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mQueuedEntries) @@ -191,9 +189,8 @@ DOMIntersectionObserver::Connect() } mConnected = true; - if (mDocument) { - mDocument->AddIntersectionObserver(this); - } + nsIDocument* document = mOwner->GetExtantDoc(); + document->AddIntersectionObserver(this); } void @@ -209,8 +206,11 @@ DOMIntersectionObserver::Disconnect() target->UnregisterIntersectionObserver(this); } mObservationTargets.Clear(); - if (mDocument) { - mDocument->RemoveIntersectionObserver(this); + if (mOwner) { + nsIDocument* document = mOwner->GetExtantDoc(); + if (document) { + document->RemoveIntersectionObserver(this); + } } } diff --git a/dom/base/DOMIntersectionObserver.h b/dom/base/DOMIntersectionObserver.h index 843143f418eb..b4ff12cf1921 100644 --- a/dom/base/DOMIntersectionObserver.h +++ b/dom/base/DOMIntersectionObserver.h @@ -108,7 +108,7 @@ class DOMIntersectionObserver final : public nsISupports, public: DOMIntersectionObserver(already_AddRefed&& aOwner, mozilla::dom::IntersectionCallback& aCb) - : mOwner(aOwner), mDocument(mOwner->GetExtantDoc()), mCallback(&aCb), mConnected(false) + : mOwner(aOwner), mCallback(&aCb), mConnected(false) { } NS_DECL_CYCLE_COLLECTING_ISUPPORTS @@ -166,7 +166,6 @@ protected: double aIntersectionRatio); nsCOMPtr mOwner; - RefPtr mDocument; RefPtr mCallback; RefPtr mRoot; nsCSSRect mRootMargin; diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index 845315be50c6..ee9f881f76cf 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -3851,7 +3851,7 @@ Element::ClearDataset() slots->mDataset = nullptr; } -nsDataHashtable, int32_t>* +nsDataHashtable, int32_t>* Element::RegisteredIntersectionObservers() { nsDOMSlots* slots = DOMSlots(); @@ -3861,7 +3861,7 @@ Element::RegisteredIntersectionObservers() void Element::RegisterIntersectionObserver(DOMIntersectionObserver* aObserver) { - nsDataHashtable, int32_t>* observers = + nsDataHashtable, int32_t>* observers = RegisteredIntersectionObservers(); if (observers->Contains(aObserver)) { return; @@ -3872,7 +3872,7 @@ Element::RegisterIntersectionObserver(DOMIntersectionObserver* aObserver) void Element::UnregisterIntersectionObserver(DOMIntersectionObserver* aObserver) { - nsDataHashtable, int32_t>* observers = + nsDataHashtable, int32_t>* observers = RegisteredIntersectionObservers(); observers->Remove(aObserver); } @@ -3880,7 +3880,7 @@ Element::UnregisterIntersectionObserver(DOMIntersectionObserver* aObserver) bool Element::UpdateIntersectionObservation(DOMIntersectionObserver* aObserver, int32_t aThreshold) { - nsDataHashtable, int32_t>* observers = + nsDataHashtable, int32_t>* observers = RegisteredIntersectionObservers(); if (!observers->Contains(aObserver)) { return false; diff --git a/dom/base/Element.h b/dom/base/Element.h index 5e464be95c37..15f903f5dfc4 100644 --- a/dom/base/Element.h +++ b/dom/base/Element.h @@ -1466,8 +1466,7 @@ protected: nsDOMTokenList* GetTokenList(nsIAtom* aAtom, const DOMTokenListSupportedTokenArray aSupportedTokens = nullptr); - nsDataHashtable, int32_t>* - RegisteredIntersectionObservers(); + nsDataHashtable, int32_t>* RegisteredIntersectionObservers(); private: /** diff --git a/dom/base/FragmentOrElement.cpp b/dom/base/FragmentOrElement.cpp index 0e1c17a7acfc..3e79f93d5d9f 100644 --- a/dom/base/FragmentOrElement.cpp +++ b/dom/base/FragmentOrElement.cpp @@ -626,12 +626,6 @@ FragmentOrElement::nsDOMSlots::Traverse(nsCycleCollectionTraversalCallback &cb, mCustomElementData->mCallbackQueue[i]->Traverse(cb); } } - - for (auto iter = mRegisteredIntersectionObservers.Iter(); !iter.Done(); iter.Next()) { - RefPtr observer = iter.Key(); - NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mSlots->mRegisteredIntersectionObservers[i]"); - cb.NoteXPCOMChild(observer.get()); - } } void diff --git a/dom/base/FragmentOrElement.h b/dom/base/FragmentOrElement.h index 6d04159f030f..f3a6a01306a1 100644 --- a/dom/base/FragmentOrElement.h +++ b/dom/base/FragmentOrElement.h @@ -348,8 +348,7 @@ public: /** * Registered Intersection Observers on the element. */ - nsDataHashtable, int32_t> - mRegisteredIntersectionObservers; + nsDataHashtable, int32_t> mRegisteredIntersectionObservers; }; protected: diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 19f8771e6906..8a48240183f5 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -1832,6 +1832,8 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDocument) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOnDemandBuiltInUASheets) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPreloadingImages) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIntersectionObservers) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSubImportLinks) for (uint32_t i = 0; i < tmp->mFrameRequestCallbacks.Length(); ++i) { @@ -12592,15 +12594,15 @@ nsDocument::ReportUseCounters(UseCounterReportKind aKind) void nsDocument::AddIntersectionObserver(DOMIntersectionObserver* aObserver) { - MOZ_ASSERT(!mIntersectionObservers.Contains(aObserver), - "Intersection observer already in the list"); - mIntersectionObservers.PutEntry(aObserver); + NS_ASSERTION(mIntersectionObservers.IndexOf(aObserver) == nsTArray::NoIndex, + "Intersection observer already in the list"); + mIntersectionObservers.AppendElement(aObserver); } void nsDocument::RemoveIntersectionObserver(DOMIntersectionObserver* aObserver) { - mIntersectionObservers.RemoveEntry(aObserver); + mIntersectionObservers.RemoveElement(aObserver); } void @@ -12617,8 +12619,7 @@ nsDocument::UpdateIntersectionObservations() time = perf->Now(); } } - for (auto iter = mIntersectionObservers.Iter(); !iter.Done(); iter.Next()) { - DOMIntersectionObserver* observer = iter.Get()->GetKey(); + for (const auto& observer : mIntersectionObservers) { observer->Update(this, time); } } @@ -12629,6 +12630,7 @@ nsDocument::ScheduleIntersectionObserverNotification() if (mIntersectionObservers.IsEmpty()) { return; } + MOZ_RELEASE_ASSERT(NS_IsMainThread()); nsCOMPtr notification = NewRunnableMethod(this, &nsDocument::NotifyIntersectionObservers); @@ -12639,11 +12641,7 @@ nsDocument::ScheduleIntersectionObserverNotification() void nsDocument::NotifyIntersectionObservers() { - nsTArray> observers(mIntersectionObservers.Count()); - for (auto iter = mIntersectionObservers.Iter(); !iter.Done(); iter.Next()) { - DOMIntersectionObserver* observer = iter.Get()->GetKey(); - observers.AppendElement(observer); - } + nsTArray> observers(mIntersectionObservers); for (const auto& observer : observers) { observer->Notify(); } diff --git a/dom/base/nsDocument.h b/dom/base/nsDocument.h index 82e0221089c5..814d7c144ac5 100644 --- a/dom/base/nsDocument.h +++ b/dom/base/nsDocument.h @@ -1359,8 +1359,7 @@ protected: nsTObserverArray mObservers; // Array of intersection observers - nsTHashtable> - mIntersectionObservers; + nsTArray> mIntersectionObservers; // Tracker for animations that are waiting to start. // nullptr until GetOrCreatePendingAnimationTracker is called. From 624bf0bbd2a1599cb7a4b59c0690d79cb7781926 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Tue, 21 Feb 2017 18:58:30 -0500 Subject: [PATCH 015/234] Bug 1341450 - Repair incorrect check for missing DMDReportAndDump function. r=jmaher MozReview-Commit-ID: 9lZEvxOYoR3 --HG-- extra : rebase_source : c2e61f6aebafe91269ea7a99bdf4b5cc5492ed21 --- testing/mochitest/tests/SimpleTest/MemoryStats.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testing/mochitest/tests/SimpleTest/MemoryStats.js b/testing/mochitest/tests/SimpleTest/MemoryStats.js index 2af971184c08..0c29d58071a0 100644 --- a/testing/mochitest/tests/SimpleTest/MemoryStats.js +++ b/testing/mochitest/tests/SimpleTest/MemoryStats.js @@ -104,7 +104,7 @@ MemoryStats.dump = function (testNumber, } // This is the old, deprecated function. - if (dumpDMD && typeof(DMDReportAndDump) != undefined) { + if (dumpDMD && typeof(DMDReportAndDump) != "undefined") { var basename = "dmd-" + testNumber + "-deprecated.txt"; var dumpfile = MemoryStats.constructPathname(dumpOutputDirectory, basename); @@ -112,7 +112,7 @@ MemoryStats.dump = function (testNumber, DMDReportAndDump(dumpfile); } - if (dumpDMD && typeof(DMDAnalyzeReports) != undefined) { + if (dumpDMD && typeof(DMDAnalyzeReports) != "undefined") { var basename = "dmd-" + testNumber + ".txt"; var dumpfile = MemoryStats.constructPathname(dumpOutputDirectory, basename); From cc2cd3e3ae5910c5954c42e8a6fca3898dbfa2df Mon Sep 17 00:00:00 2001 From: Rob Wood Date: Tue, 21 Feb 2017 17:07:02 -0500 Subject: [PATCH 016/234] Bug 1340785 - SETA: Add support for TC BBB tasks; r=jmaher MozReview-Commit-ID: 54UMq7OTrnR --HG-- extra : rebase_source : 733c341be127c79459f65f7504aa5fee9573f5c1 --- taskcluster/taskgraph/task/transform.py | 10 ++++++++- taskcluster/taskgraph/util/seta.py | 30 ++++++++++++++++++------- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/taskcluster/taskgraph/task/transform.py b/taskcluster/taskgraph/task/transform.py index f015f2a00346..fa810fae10bf 100644 --- a/taskcluster/taskgraph/task/transform.py +++ b/taskcluster/taskgraph/task/transform.py @@ -87,6 +87,8 @@ class TransformTask(base.Task): return [(label, name) for name, label in self.dependencies.items()] def optimize(self, params): + bbb_task = False + if self.index_paths: optimized, taskId = super(TransformTask, self).optimize(params) if optimized: @@ -100,12 +102,18 @@ class TransformTask(base.Task): self.label) return True, None + # for bbb tasks we need to send in the buildbot buildername + if self.task.get('provisionerId') == 'buildbot-bridge': + self.label = self.task.get('payload').get('buildername') + bbb_task = True + # we would like to return 'False, None' while it's high_value_task # and we wouldn't optimize it. Otherwise, it will return 'True, None' if is_low_value_task(self.label, params.get('project'), params.get('pushlog_id'), - params.get('pushdate')): + params.get('pushdate'), + bbb_task): # Always optimize away low-value tasks return True, None else: diff --git a/taskcluster/taskgraph/util/seta.py b/taskcluster/taskgraph/util/seta.py index ff27596686eb..b7b9a492c0ad 100644 --- a/taskcluster/taskgraph/util/seta.py +++ b/taskcluster/taskgraph/util/seta.py @@ -13,7 +13,7 @@ PROJECT_SCHEDULE_ALL_EVERY_PUSHES = {'mozilla-inbound': 5, 'autoland': 5} PROJECT_SCHEDULE_ALL_EVERY_MINUTES = {'mozilla-inbound': 60, 'autoland': 60} SETA_ENDPOINT = "https://treeherder.mozilla.org/api/project/%s/seta/" \ - "job-priorities/?build_system_type=taskcluster" + "job-priorities/?build_system_type=%s" PUSH_ENDPOINT = "https://hg.mozilla.org/integration/%s/json-pushes/?startID=%d&endID=%d" @@ -25,6 +25,7 @@ class SETA(object): def __init__(self): # cached low value tasks, by project self.low_value_tasks = {} + self.low_value_bb_tasks = {} # cached push dates by project self.push_dates = defaultdict(dict) # cached push_ids that failed to retrieve datetime for @@ -42,12 +43,18 @@ class SETA(object): return 'test-%s/%s-%s' % (task_tuple[0], task_tuple[1], task_tuple[2]) - def query_low_value_tasks(self, project): + def query_low_value_tasks(self, project, bbb=False): # Request the set of low value tasks from the SETA service. Low value tasks will be # optimized out of the task graph. low_value_tasks = [] - url = SETA_ENDPOINT % project + if not bbb: + # we want to get low priority tasklcuster jobs + url = SETA_ENDPOINT % (project, 'taskcluster') + else: + # we want low priority buildbot jobs + url = SETA_ENDPOINT % (project, 'buildbot&priority=5') + # Try to fetch the SETA data twice, falling back to an empty list of low value tasks. # There are 10 seconds between each try. try: @@ -162,7 +169,7 @@ class SETA(object): return min_between_pushes - def is_low_value_task(self, label, project, pushlog_id, push_date): + def is_low_value_task(self, label, project, pushlog_id, push_date, bbb_task=False): # marking a task as low_value means it will be optimized out by tc if project not in SETA_PROJECTS: return False @@ -180,10 +187,17 @@ class SETA(object): int(push_date)) >= PROJECT_SCHEDULE_ALL_EVERY_MINUTES.get(project, 60): return False - # cache the low value tasks per project to avoid repeated SETA server queries - if project not in self.low_value_tasks: - self.low_value_tasks[project] = self.query_low_value_tasks(project) - return label in self.low_value_tasks[project] + if not bbb_task: + # cache the low value tasks per project to avoid repeated SETA server queries + if project not in self.low_value_tasks: + self.low_value_tasks[project] = self.query_low_value_tasks(project) + return label in self.low_value_tasks[project] + + # gecko decision task requesting if a bbb task is a low value task, so use bb jobs + # in this case, the label param sent in will be the buildbot buildername already + if project not in self.low_value_bb_tasks: + self.low_value_bb_tasks[project] = self.query_low_value_tasks(project, bbb=True) + return label in self.low_value_bb_tasks[project] # create a single instance of this class, and expose its `is_low_value_task` # bound method as a module-level function From 728d8ad262b5ecce5298dd2c827ad05430d7186c Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Wed, 22 Feb 2017 05:03:39 -0800 Subject: [PATCH 017/234] servo: Merge #15686 - Use serde_json to persist cookies in the net crate (from nox:serde-cookies); r=Ms2ger Source-Repo: https://github.com/servo/servo Source-Revision: deabf9618438627edb04a76ebd086b612012fc75 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : a3c194f90e0efcf25351505e039bfd163507ee1b --- servo/Cargo.lock | 22 +++++++++++++--------- servo/components/net/Cargo.toml | 3 +++ servo/components/net/cookie.rs | 13 ++++++++++--- servo/components/net/cookie_storage.rs | 4 ++-- servo/components/net/hsts.rs | 10 +++++----- servo/components/net/lib.rs | 4 ++++ servo/components/net/resource_thread.rs | 16 ++++++++-------- 7 files changed, 45 insertions(+), 27 deletions(-) diff --git a/servo/Cargo.lock b/servo/Cargo.lock index 9ee6cb8a9890..7f2a649894e5 100644 --- a/servo/Cargo.lock +++ b/servo/Cargo.lock @@ -602,7 +602,7 @@ dependencies = [ "devtools_traits 0.0.1", "encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper_serde 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper_serde 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", @@ -620,7 +620,7 @@ dependencies = [ "heapsize 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper_serde 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper_serde 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", "serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1165,13 +1165,14 @@ dependencies = [ [[package]] name = "hyper_serde" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cookie 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1638,7 +1639,7 @@ dependencies = [ "devtools_traits 0.0.1", "flate2 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper_serde 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper_serde 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "immeta 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1652,6 +1653,9 @@ dependencies = [ "openssl-verify 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "profile_traits 0.0.1", "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", "servo_config 0.0.1", "servo_url 0.0.1", "threadpool 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1685,7 +1689,7 @@ dependencies = [ "devtools_traits 0.0.1", "flate2 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper_serde 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper_serde 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", "net 0.0.1", @@ -1706,7 +1710,7 @@ dependencies = [ "heapsize 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper_serde 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper_serde 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "image 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2209,7 +2213,7 @@ dependencies = [ "html5ever 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "html5ever-atoms 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper_serde 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper_serde 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "image 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "js 0.1.4 (git+https://github.com/servo/rust-mozjs)", @@ -2312,7 +2316,7 @@ dependencies = [ "heapsize 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper_serde 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper_serde 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)", "msg 0.0.1", @@ -3416,7 +3420,7 @@ dependencies = [ "checksum html5ever-atoms 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f9bd86e3b6a5a7933a272cc0a854f24e371f31576e585c0b41e8f857270c5134" "checksum httparse 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a6e7a63e511f9edffbab707141fbb8707d1a3098615fb2adbd5769cdfcc9b17d" "checksum hyper 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)" = "1b9bf64f730d6ee4b0528a5f0a316363da9d8104318731509d4ccc86248f82b3" -"checksum hyper_serde 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "19065fedb73b4d5c617482cedfb3cfb092fc379870a7e3aadd16fd491838129a" +"checksum hyper_serde 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d602a93073c250f49b2e2d931cc1755a5f447824154dc3c711716dee29bd7486" "checksum idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1053236e00ce4f668aeca4a769a09b3bf5a682d802abd6f3cb39374f6b162c11" "checksum image 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "979bad0502082fd60053a490282e87d6c89650942e3a270e0d4c83569c7f5899" "checksum immeta 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3e76ecb1d64979a91c7fc5b7c0495ef1467e3cbff759044f2b88878a5a845ef7" diff --git a/servo/components/net/Cargo.toml b/servo/components/net/Cargo.toml index da1db328a8f6..2252c7655415 100644 --- a/servo/components/net/Cargo.toml +++ b/servo/components/net/Cargo.toml @@ -30,6 +30,9 @@ openssl = "0.7.6" openssl-verify = "0.1" profile_traits = {path = "../profile_traits"} rustc-serialize = "0.3" +serde = "0.9" +serde_derive = "0.9" +serde_json = "0.9" servo_config = {path = "../config"} servo_url = {path = "../url"} threadpool = "1.0" diff --git a/servo/components/net/cookie.rs b/servo/components/net/cookie.rs index 42a49a4ac0a2..c40bf909e2a4 100644 --- a/servo/components/net/cookie.rs +++ b/servo/components/net/cookie.rs @@ -6,6 +6,7 @@ //! http://tools.ietf.org/html/rfc6265 use cookie_rs; +use hyper_serde::{self, Serde}; use net_traits::CookieSource; use net_traits::pub_domains::is_pub_domain; use servo_url::ServoUrl; @@ -16,14 +17,20 @@ use time::{Tm, now, at, Duration}; /// A stored cookie that wraps the definition in cookie-rs. This is used to implement /// various behaviours defined in the spec that rely on an associated request URL, /// which cookie-rs and hyper's header parsing do not support. -#[derive(Clone, Debug, RustcDecodable, RustcEncodable)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct Cookie { + #[serde(deserialize_with = "hyper_serde::deserialize", + serialize_with = "hyper_serde::serialize")] pub cookie: cookie_rs::Cookie, pub host_only: bool, pub persistent: bool, + #[serde(deserialize_with = "hyper_serde::deserialize", + serialize_with = "hyper_serde::serialize")] pub creation_time: Tm, + #[serde(deserialize_with = "hyper_serde::deserialize", + serialize_with = "hyper_serde::serialize")] pub last_access: Tm, - pub expiry_time: Option, + pub expiry_time: Option>, } impl Cookie { @@ -85,7 +92,7 @@ impl Cookie { persistent: persistent, creation_time: now(), last_access: now(), - expiry_time: expiry_time, + expiry_time: expiry_time.map(Serde), }) } diff --git a/servo/components/net/cookie_storage.rs b/servo/components/net/cookie_storage.rs index 8d39334263c8..7ea4eecd6856 100644 --- a/servo/components/net/cookie_storage.rs +++ b/servo/components/net/cookie_storage.rs @@ -16,7 +16,7 @@ use time::Tm; extern crate time; -#[derive(Clone, Debug, RustcDecodable, RustcEncodable)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct CookieStorage { version: u32, cookies_map: HashMap>, @@ -192,7 +192,7 @@ fn reg_host<'a>(url: &'a str) -> String { fn is_cookie_expired(cookie: &Cookie) -> bool { match cookie.expiry_time { - Some(t) => t.to_timespec() <= time::get_time(), + Some(ref t) => t.to_timespec() <= time::get_time(), None => false, } } diff --git a/servo/components/net/hsts.rs b/servo/components/net/hsts.rs index 3807a47085ae..f540955b05a6 100644 --- a/servo/components/net/hsts.rs +++ b/servo/components/net/hsts.rs @@ -4,7 +4,7 @@ use net_traits::IncludeSubdomains; use net_traits::pub_domains::reg_suffix; -use rustc_serialize::json::decode; +use serde_json; use servo_config::resource_files::read_resource_file; use std::collections::HashMap; use std::net::{Ipv4Addr, Ipv6Addr}; @@ -12,7 +12,7 @@ use std::str::from_utf8; use time; use url::Url; -#[derive(RustcDecodable, RustcEncodable, Clone)] +#[derive(Clone, Deserialize, Serialize)] pub struct HstsEntry { pub host: String, pub include_subdomains: bool, @@ -53,7 +53,7 @@ impl HstsEntry { } } -#[derive(RustcDecodable, RustcEncodable, Clone)] +#[derive(Clone, Deserialize, Serialize)] pub struct HstsList { pub entries_map: HashMap>, } @@ -65,14 +65,14 @@ impl HstsList { /// Create an `HstsList` from the bytes of a JSON preload file. pub fn from_preload(preload_content: &[u8]) -> Option { - #[derive(RustcDecodable)] + #[derive(Deserialize)] struct HstsEntries { entries: Vec, } let hsts_entries: Option = from_utf8(&preload_content) .ok() - .and_then(|c| decode(c).ok()); + .and_then(|c| serde_json::from_str(c).ok()); hsts_entries.map_or(None, |hsts_entries| { let mut hsts_list: HstsList = HstsList::new(); diff --git a/servo/components/net/lib.rs b/servo/components/net/lib.rs index d4edd3ec953c..d61de0b679d0 100644 --- a/servo/components/net/lib.rs +++ b/servo/components/net/lib.rs @@ -27,6 +27,10 @@ extern crate openssl; extern crate openssl_verify; extern crate profile_traits; extern crate rustc_serialize; +extern crate serde; +#[macro_use] +extern crate serde_derive; +extern crate serde_json; extern crate servo_config; extern crate servo_url; extern crate threadpool; diff --git a/servo/components/net/resource_thread.rs b/servo/components/net/resource_thread.rs index 925b5e19cdc0..7c109e3b252c 100644 --- a/servo/components/net/resource_thread.rs +++ b/servo/components/net/resource_thread.rs @@ -23,8 +23,8 @@ use net_traits::{ResourceThreads, WebSocketCommunicate, WebSocketConnectData}; use net_traits::request::{Request, RequestInit}; use net_traits::storage_thread::StorageThreadMsg; use profile_traits::time::ProfilerChan; -use rustc_serialize::{Decodable, Encodable}; -use rustc_serialize::json; +use serde::{Deserialize, Serialize}; +use serde_json; use servo_url::ServoUrl; use std::borrow::{Cow, ToOwned}; use std::collections::HashMap; @@ -211,7 +211,7 @@ impl ResourceChannelManager { } pub fn read_json_from_file(data: &mut T, config_dir: &Path, filename: &str) - where T: Decodable + where T: Deserialize { let path = config_dir.join(filename); let display = path.display(); @@ -233,17 +233,17 @@ pub fn read_json_from_file(data: &mut T, config_dir: &Path, filename: &str) Ok(_) => println!("successfully read from {}", display), } - match json::decode(&string_buffer) { + match serde_json::from_str(&string_buffer) { Ok(decoded_buffer) => *data = decoded_buffer, Err(why) => warn!("Could not decode buffer{}", why), } } pub fn write_json_to_file(data: &T, config_dir: &Path, filename: &str) - where T: Encodable + where T: Serialize { let json_encoded: String; - match json::encode(&data) { + match serde_json::to_string_pretty(&data) { Ok(d) => json_encoded = d, Err(_) => return, } @@ -266,7 +266,7 @@ pub fn write_json_to_file(data: &T, config_dir: &Path, filename: &str) } } -#[derive(RustcDecodable, RustcEncodable, Clone)] +#[derive(Clone, Deserialize, Serialize)] pub struct AuthCacheEntry { pub user_name: String, pub password: String, @@ -281,7 +281,7 @@ impl AuthCache { } } -#[derive(RustcDecodable, RustcEncodable, Clone)] +#[derive(Clone, Deserialize, Serialize)] pub struct AuthCache { pub version: u32, pub entries: HashMap, From 8e621b659c1f404bf8965d929abd78408810b71b Mon Sep 17 00:00:00 2001 From: Mathieu Leplatre Date: Sun, 11 Dec 2016 14:37:22 -1000 Subject: [PATCH 018/234] Bug 1224528 - Load initial JSON files for blocklist r=mgoodwin MozReview-Commit-ID: D53xoTa0PZu --HG-- extra : rebase_source : a4aa143c627df0f70c15fd3589cde7a49e30d80d --- browser/installer/package-manifest.in | 1 + services/blocklists/addons.json | 1 + services/blocklists/certificates.json | 1 + services/blocklists/gfx.json | 1 + services/blocklists/moz.build | 15 ++++ services/blocklists/pins.json | 1 + services/blocklists/plugins.json | 1 + services/blocklists/readme.md | 29 +++++++ services/common/blocklist-clients.js | 80 ++++++++++++++----- .../tests/unit/test_blocklist_certificates.js | 59 +++++++++++--- .../tests/unit/test_blocklist_clients.js | 42 +++++----- .../tests/unit/test_blocklist_signatures.js | 3 +- services/common/tests/unit/xpcshell.ini | 2 + services/moz.build | 5 +- tools/lint/eslint/modules.json | 2 +- 15 files changed, 186 insertions(+), 57 deletions(-) create mode 100644 services/blocklists/addons.json create mode 100644 services/blocklists/certificates.json create mode 100644 services/blocklists/gfx.json create mode 100644 services/blocklists/moz.build create mode 100644 services/blocklists/pins.json create mode 100644 services/blocklists/plugins.json create mode 100644 services/blocklists/readme.md diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in index fa6ca5b1b03c..71f558c777e1 100644 --- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -636,6 +636,7 @@ @RESPATH@/greprefs.js @RESPATH@/defaults/autoconfig/prefcalls.js @RESPATH@/browser/defaults/permissions +@RESPATH@/browser/defaults/blocklists ; Warning: changing the path to channel-prefs.js can cause bugs (Bug 756325) ; Technically this is an app pref file, but we are keeping it in the original diff --git a/services/blocklists/addons.json b/services/blocklists/addons.json new file mode 100644 index 000000000000..f0408b03cc5a --- /dev/null +++ b/services/blocklists/addons.json @@ -0,0 +1 @@ +{"data":[{"guid":"ext@alibonus.com","blockID":"i1524","enabled":true,"last_modified":1485301116629,"details":{"who":"All Firefox users who have these versions installed.","created":"2017-01-24T22:45:39Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1333471","name":"Alibonus 1.20.9 and lower","why":"Versions 1.20.9 and lower of this add-on contain critical security issues."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"1.20.9","severity":1}],"prefs":[],"id":"a015d5a4-9184-95db-0c74-9262af2332fa","schema":1485297431051},{"guid":"{a0d7ccb3-214d-498b-b4aa-0e8fda9a7bf7}","blockID":"i1523","enabled":true,"last_modified":1485297214072,"details":{"who":"All Firefox users who have these versions of the Web of Trust add-on installed.","created":"2017-01-24T22:01:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1314332","name":"Web of Trust 20170120 and lower","why":"Versions 20170120 and lower of the Web of Trust add-on send excessive user data to its service, which has been reportedly shared with third parties without sufficient sanitization. These versions are also affected by a vulnerability that could lead to unwanted remote code execution."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"20170120","severity":1}],"prefs":[],"id":"2224c139-9b98-0900-61c1-04031de11ad3","schema":1485295513652},{"guid":"/^(ciscowebexstart1@cisco\\.com|ciscowebexstart_test@cisco\\.com|ciscowebexstart@cisco\\.com|ciscowebexgpc@cisco\\.com)$/","blockID":"i1522","enabled":true,"last_modified":1485215014902,"details":{"who":"All Firefox users who have any Cisco WebEx add-ons installed.","created":"2017-01-23T22:55:58Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1333225","name":"Cisco WebEx add-ons","why":"A critical security vulnerability has been discovered in Cisco WebEx add-ons that enable malicious websites to execute code on the user's system."},"versionRange":[{"targetApplication":[],"minVersion":"1.0.0","maxVersion":"1.0.1","severity":1}],"prefs":[],"id":"30368779-1d3b-490a-0a34-253085af7754","schema":1485212610474},{"guid":"{de71f09a-3342-48c5-95c1-4b0f17567554}","blockID":"i1493","enabled":true,"last_modified":1484867614757,"details":{"who":"All users who have this add-on installed.","created":"2017-01-12T22:17:59Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1329654","name":"Search for Firefox Convertor (malware)","why":"This is a malicious add-on that is installed using a fake name. It changes search and homepage settings."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"1.3.9","severity":3}],"prefs":[],"id":"d6ec9f54-9945-088e-ba68-40117eaba24e","schema":1484335370642},{"guid":"googlotim@gmail.com","blockID":"i1492","enabled":true,"last_modified":1483646608603,"details":{"who":"All users who have Savogram version 1.3.2 installed. Version 1.3.1 doesn't have this problem and can be installed from the add-on page. Note that this is an older version, so affected users won't be automatically updated to it. New versions should correct this problem if they become available.","created":"2017-01-05T19:58:39Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1328594","name":"Savogram 1.3.2","why":"Version 1.3.2 of this add-on loads remote code and performs DOM injection in an unsafe manner."},"versionRange":[{"targetApplication":[],"minVersion":"1.3.2","maxVersion":"1.3.2","severity":1}],"prefs":[],"id":"0756ed76-7bc7-ec1e-aba5-3a9fac2107ba","schema":1483389810787},{"guid":"support@update-firefox.com","blockID":"i21","enabled":true,"last_modified":1483389809169,"details":{"who":"All users of the add-on in all Mozilla applications.","created":"2011-01-31T16:23:48Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=629717","name":"Browser Update (spyware)","why":"This add-on is adware/spyware masquerading as a Firefox update mechanism."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"dfb06be8-3594-28e4-d163-17e27119f15d","schema":1483387107003},{"guid":"{2224e955-00e9-4613-a844-ce69fccaae91}","blockID":"i7","enabled":true,"last_modified":1483389809147,"details":{"who":"All users of Internet Saving Optimizer for all Mozilla applications.","created":"2011-03-31T16:28:25Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=512406","name":"Internet Saving Optimizer (extension)","why":"This add-on causes a high volume of Firefox crashes and is considered malware."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"b9efb796-97c2-6434-d28f-acc83436f8e5","schema":1483387107003},{"guid":"supportaccessplugin@gmail.com","blockID":"i43","enabled":true,"last_modified":1483389809124,"details":{"who":"All users with Firefox Access Plugin installed","created":"2011-10-11T11:24:05Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=693673","name":"Firefox Access Plugin (spyware)","why":"This add-on is spyware that reports all visited websites to a third party with no user value."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"1ed230a4-e174-262a-55ab-0c33f93a2529","schema":1483387107003},{"guid":"{8CE11043-9A15-4207-A565-0C94C42D590D}","blockID":"i10","enabled":true,"last_modified":1483389809102,"details":{"who":"All users of this add-on in all Mozilla applications.","created":"2011-03-31T16:28:25Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=541302","name":"Internal security options editor (malware)","why":"This add-on secretly hijacks all search results in most major search engines and masks as a security add-on."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"e2e0ac09-6d68-75f5-2424-140f51904876","schema":1483387107003},{"guid":"youtube@youtube2.com","blockID":"i47","enabled":true,"last_modified":1483389809079,"details":{"who":"All users with any version of Free Cheesecake Factory installed on any Mozilla product.","created":"2011-12-22T13:11:36Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=713050","name":"Free Cheesecake Factory (malware)","why":"This add-on hijacks your Facebook account."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"85f5c1db-433b-bee3-2a3b-325165cacc6e","schema":1483387107003},{"guid":"admin@youtubespeedup.com","blockID":"i48","enabled":true,"last_modified":1483389809057,"details":{"who":"All users with any version of Youtube Speed UP! installed on any Mozilla product.","created":"2011-12-29T19:48:06Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=714221","name":"Youtube Speed UP! (malware)","why":"This add-on hijacks your Facebook account."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"a93922c4-8a8a-5230-8f76-76fecb0653b6","schema":1483387107003},{"guid":"{E8E88AB0-7182-11DF-904E-6045E0D72085}","blockID":"i13","enabled":true,"last_modified":1483389809035,"details":{"who":"All users of this add-on for all Mozilla applications.","created":"2011-03-31T16:28:25Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=578085","name":"Mozilla Sniffer (malware)","why":"This add-on intercepts website login credentials and is malware. For more information, please read our security announcement."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"ebbd6de9-fc8a-3e5b-2a07-232bee589c7c","schema":1483387107003},{"guid":"sigma@labs.mozilla","blockID":"i44","enabled":true,"last_modified":1483389809012,"details":{"who":"All users of Lab Kit in all versions of Firefox.","created":"2011-10-11T11:51:34Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=690819","name":"Mozilla Labs: Lab Kit","why":"The Lab Kit add-on has been retired due to compatibility issues with Firefox 7 and future Firefox browser releases. You can still install Mozilla Labs add-ons individually.\r\n\r\nFor more information, please read this announcement."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"d614e9cd-220f-3a19-287b-57e122f8c4b5","schema":1483387107003},{"guid":"/^(jid0-S9kkzfTvEmC985BVmf8ZOzA5nLM@jetpack|jid1-qps14pkDB6UDvA@jetpack|jid1-Tsr09YnAqIWL0Q@jetpack|shole@ats.ext|{38a64ef0-7181-11e3-981f-0800200c9a66}|eochoa@ualberta.ca)$/","blockID":"i1424","enabled":true,"last_modified":1483378113482,"details":{"who":"All users who have any of the affected versions installed.","created":"2016-12-21T17:22:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1325060","name":"Various vulnerable add-on versions","why":"A security vulnerability was discovered in old versions of the Add-ons SDK, which is exposed by certain old versions of add-ons. In the case of some add-ons that haven't been updated for a long time, all versions are being blocked."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"0699488d-2a19-6735-809e-f229849fe00b","schema":1483376308298},{"guid":"pink@rosaplugin.info","blockID":"i84","enabled":true,"last_modified":1482945810971,"details":{"who":"All Firefox users who have this add-on installed","created":"2012-04-09T10:13:51Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=743484","name":"Facebook Rosa (malware)","why":"Add-on acts like malware and performs user actions on Facebook without their consent."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"66ad8de9-311d-076c-7356-87fde6d30d8f","schema":1482945809444},{"guid":"videoplugin@player.com","blockID":"i90","enabled":true,"last_modified":1482945810949,"details":{"who":"All Firefox users who have installed this add-on.","created":"2012-05-07T08:58:30Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=752483","name":"FlashPlayer 11 (malware)","why":"This add-on is malware disguised as a Flash Player update. It can hijack Google searches and Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"d25943f1-39ef-b9ec-ab77-baeef3498365","schema":1482945809444},{"guid":"youtb3@youtb3.com","blockID":"i60","enabled":true,"last_modified":1482945810927,"details":{"who":"All Firefox users who have this extension installed.","created":"2012-02-02T16:38:41Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=723753","name":"Video extension (malware)","why":"Malicious extension installed under false pretenses."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"cae3093f-a7b3-5352-a264-01dbfbf347ce","schema":1482945809444},{"guid":"{8f42fb8b-b6f6-45de-81c0-d6d39f54f971}","blockID":"i82","enabled":true,"last_modified":1482945810904,"details":{"who":"All Firefox users who have installed this add-on.","created":"2012-04-09T10:04:28Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=743012","name":"Face Plus (malware)","why":"This add-on maliciously manipulates Facebook and is installed under false pretenses."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"09319ab3-55e7-fec1-44e0-84067d014b9b","schema":1482945809444},{"guid":"cloudmask@cloudmask.com","blockID":"i1233","enabled":true,"last_modified":1482945810881,"details":{"who":"Any user who has version 2.0.788, or earlier, installed.","created":"2016-06-17T14:31:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1280431","name":"CloudMask","why":"These versions of the add-on (before 2.0.788) execute code from a website in a privileged local browser context, potentially allowing dangerous, unreviewed, actions to affect the user's computer. This is fixed in later versions."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"2.0.788","severity":1}],"prefs":[],"id":"2a8b40c7-a1d2-29f4-b7d7-ccfc5066bae1","schema":1482945809444},{"guid":"{95ff02bc-ffc6-45f0-a5c8-619b8226a9de}","blockID":"i105","enabled":true,"last_modified":1482945810858,"details":{"who":"All Firefox users who have this add-on installed.","created":"2012-06-08T14:34:25Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=763065","name":"Eklenti D\u00fcnyas\u0131 (malware)","why":"This is a malicious add-on that inserts scripts into Facebook and hijacks the user's session.\r\n"},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"afbbc08d-2414-f51e-fdb8-74c0a2d90323","schema":1482945809444},{"guid":"{fa277cfc-1d75-4949-a1f9-4ac8e41b2dfd}","blockID":"i77","enabled":true,"last_modified":1482945810835,"details":{"who":"All Firefox users who have installed this add-on.","created":"2012-03-22T14:39:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=738419","name":"Adobe Flash (malware)","why":"This add-on is malware that is installed under false pretenses as an Adobe plugin."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"81753a93-382d-5f9d-a4ca-8a21b679ebb1","schema":1482945809444},{"guid":"youtube@youtube3.com","blockID":"i57","enabled":true,"last_modified":1482945810811,"details":{"who":"All Firefox users that have installed this add-on.","created":"2012-01-31T13:54:20Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=722823","name":"Divx 2012 Plugin (malware)","why":"Malware installed on false pretenses."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"4a93a0eb-a513-7272-6199-bc4d6228ff50","schema":1482945809444},{"guid":"{392e123b-b691-4a5e-b52f-c4c1027e749c}","blockID":"i109","enabled":true,"last_modified":1482945810788,"details":{"who":"All Firefox users who have this add-on installed.","created":"2012-06-29T13:20:22Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=769781","name":"Zaman Tuneline Hay\u0131r! (malware)","why":"This add-on pretends to be developed by Facebook and injects scripts that manipulate users' Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"b9a805aa-cae7-58d6-5a53-2af4442e4cf6","schema":1482945809444},{"guid":"msntoolbar@msn.com","blockID":"i18","enabled":true,"last_modified":1482945810764,"details":{"who":"Users of Bing Bar 6.0 and older for all versions of Firefox.","created":"2011-03-31T16:28:25Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=599971","name":"Bing Bar","why":"This add-on has security issues and was blocked at Microsoft's request. For more information, please see this article."},"versionRange":[{"targetApplication":[],"minVersion":" 0","maxVersion":"6.*","severity":1}],"prefs":[],"id":"9b2f2039-b997-8993-d6dc-d881bc1ca7a1","schema":1482945809444},{"guid":"yasd@youasdr3.com","blockID":"i104","enabled":true,"last_modified":1482945810740,"details":{"who":"All Firefox users who have this add-on installed.","created":"2012-06-08T14:33:31Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=763065","name":"Play Now (malware)","why":"This is a malicious add-on that inserts scripts into Facebook and hijacks the user's session.\r\n"},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"8a352dff-d09d-1e78-7feb-45dec7ace5a5","schema":1482945809444},{"guid":"fdm_ffext@freedownloadmanager.org","blockID":"i2","enabled":true,"last_modified":1482945810393,"details":{"who":"Users of Firefox 3 and later with versions 1.0 through 1.3.1 of Free Download Manager","created":"2011-03-31T16:28:25Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=408445","name":"Free Download Manager","why":"This add-on causes a high volume of crashes."},"versionRange":[{"targetApplication":[{"minVersion":"3.0a1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"}],"minVersion":"1.0","maxVersion":"1.3.1","severity":1}],"prefs":[],"id":"fc46f8e7-0489-b90f-a373-d93109479ca5","schema":1482945809444},{"guid":"flash@adobe.com","blockID":"i56","enabled":true,"last_modified":1482945810371,"details":{"who":"All Firefox users who have this add-on installed.","created":"2012-01-30T15:41:51Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=722526","name":"Adobe Flash Update (malware)","why":"This add-on poses as an Adobe Flash update and injects malicious scripts into web pages. It hides itself in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"696db959-fb0b-8aa4-928e-65f157cdd77a","schema":1482945809444},{"guid":"youtubeer@youtuber.com","blockID":"i66","enabled":true,"last_modified":1482945810348,"details":{"who":"All Firefox users who have installed this add-on.","created":"2012-02-13T15:44:20Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=726787","name":"Plug VDS (malware)","why":"Add-on behaves maliciously, and is installed under false pretenses."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"0878ce4e-b476-ffa3-0e06-21a65b7917a1","schema":1482945809444},{"guid":"{B13721C7-F507-4982-B2E5-502A71474FED}","blockID":"i8","enabled":true,"last_modified":1482945810326,"details":{"who":"Users of all versions of the original Skype Toolbar in all versions of Firefox.","created":"2011-03-31T16:28:25Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=627278","name":"Original Skype Toolbar","why":"This add-on causes a high volume of Firefox crashes and introduces severe performance issues. Please update to the latest version. For more information, please read our announcement."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"5a320611-59a3-0eee-bb30-9052be870e00","schema":1482945809444},{"guid":"yslow@yahoo-inc.com","blockID":"i11","enabled":true,"last_modified":1482945810303,"details":{"who":"Users of YSlow version 2.0.5 for Firefox 3.5.7 and later.","created":"2011-03-31T16:28:25Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=542686","name":"YSlow","why":"This add-on causes a high volume of Firefox crashes and other stability issues. Users should update to the latest version."},"versionRange":[{"targetApplication":[{"minVersion":"3.5.7","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"}],"minVersion":"2.0.5","maxVersion":"2.0.5","severity":1}],"prefs":[],"id":"a9b34e8f-45ce-9217-b791-98e094c26352","schema":1482945809444},{"guid":"youtube@youtuber.com","blockID":"i63","enabled":true,"last_modified":1482945810281,"details":{"who":"All Firefox users who have installed this add-on.","created":"2012-02-06T15:39:38Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=724691","name":"Mozilla Essentials (malware)","why":"Installs under false pretenses and delivers malware."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"18216e6f-9d70-816f-4d4c-63861f43ff3c","schema":1482945809444},{"guid":"flash@adobee.com","blockID":"i83","enabled":true,"last_modified":1482945810259,"details":{"who":"All Firefox users who have this add-on installed.","created":"2012-04-09T10:08:22Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=743497","name":"FlashPlayer 11 (malware)","why":"This add-on is malware installed under false pretenses."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"09bb4661-331c-f7ba-865b-9e085dc437af","schema":1482945809444},{"guid":"youtube@2youtube.com","blockID":"i71","enabled":true,"last_modified":1482945810236,"details":{"who":"All Firefox users who have installed this add-on.","created":"2012-02-27T10:23:23Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=730399","name":"YouTube extension (malware)","why":"Extension is malware, installed under false pretenses."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"5d389c1f-b3a0-b06f-6ffb-d1e8aa055e3c","schema":1482945809444},{"guid":"webmaster@buzzzzvideos.info","blockID":"i58","enabled":true,"last_modified":1482945810213,"details":{"who":"All Firefox users who have installed this add-on.","created":"2012-01-31T14:51:06Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=722844","name":"Buzz Video (malware)","why":"Malware add-on that is installed under false pretenses."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"f7aab105-e2c2-42f5-d9be-280eb9c0c8f7","schema":1482945809444},{"guid":"play5@vide04flash.com","blockID":"i92","enabled":true,"last_modified":1482945810191,"details":{"who":"All Firefox users who have this add-on installed.","created":"2012-05-15T13:27:22Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=755443","name":"Lastest Flash PLayer (malware)","why":"This add-on impersonates a Flash Player update (poorly), and inserts malicious scripts into Facebook."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"7190860e-fc1f-cd9f-5d25-778e1e9043b2","schema":1482945809444},{"guid":"support3_en@adobe122.com","blockID":"i97","enabled":true,"last_modified":1482945810168,"details":{"who":"All Firefox users who have installed this add-on.","created":"2012-05-28T13:42:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=759164","name":"FlashPlayer 11 (malware)","why":"This add-on is malware disguised as the Flash Player plugin."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"decf93a1-2bb0-148c-a1a6-10b3757b554b","schema":1482945809444},{"guid":"a1g0a9g219d@a1.com","blockID":"i73","enabled":true,"last_modified":1482945810146,"details":{"who":"All Firefox users who have installed this add-on.","created":"2012-03-15T15:03:04Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=736275","name":"Flash Player (malware)","why":"This add-on is malware disguised as Flash Player. It steals user cookies and sends them to a remote location."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"6dd66b43-897d-874a-2227-54e240b8520f","schema":1482945809444},{"guid":"ghostviewer@youtube2.com","blockID":"i59","enabled":true,"last_modified":1482945810123,"details":{"who":"All Firefox users who have installed this add-on.","created":"2012-02-02T16:32:15Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=723683","name":"Ghost Viewer (malware)","why":"Malicious add-on that automatically posts to Facebook."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"06dfe833-8c3d-90ee-3aa8-37c3c28f7c56","schema":1482945809444},{"guid":"{46551EC9-40F0-4e47-8E18-8E5CF550CFB8}","blockID":"i19","enabled":true,"last_modified":1482945810101,"details":{"who":"Users of Stylish version 1.1b1 for Firefox.","created":"2011-03-31T16:28:25Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=621660","name":"Stylish","why":"Version 1.1b1 of this add-on causes compatibility issues with Firefox. Users should update to the latest version."},"versionRange":[{"targetApplication":[],"minVersion":"1.1b1","maxVersion":"1.1b1","severity":1}],"prefs":[],"id":"aaea37e1-ff86-4565-8bd5-55a6bf942791","schema":1482945809444},{"guid":"kdrgun@gmail.com","blockID":"i103","enabled":true,"last_modified":1482945810078,"details":{"who":"All Firefox users who have this add-on installed.","created":"2012-06-08T14:32:51Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=763065","name":"Timeline Kapat (malware)","why":"This is a malicious add-on that inserts scripts into Facebook and hijacks the user's session."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"a9a46ab2-2f56-1046-201c-5faa3435e248","schema":1482945809444},{"guid":"youtube2@youtube2.com","blockID":"i67","enabled":true,"last_modified":1482945810055,"details":{"who":"All Firefox users who have installed this add-on.","created":"2012-02-18T09:10:30Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=728476","name":"Youtube Online (malware)","why":"This add-on is malware, installed under false pretenses."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"14650ece-295b-a667-f9bc-a3d973e2228c","schema":1482945809444},{"guid":"masterfiler@gmail.com","blockID":"i12","enabled":true,"last_modified":1482945810032,"details":{"who":"All users of this add-on for all Mozilla applications.","created":"2010-02-05T15:01:27Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=542081","name":"Master File (malware)","why":"This add-on is malware and attempts to install a Trojan on the user's computer."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"a256d79d-5af8-92e9-a29d-350adf822efe","schema":1482945809444},{"guid":"{847b3a00-7ab1-11d4-8f02-006008948af5}","blockID":"i9","enabled":true,"last_modified":1482945810003,"details":{"who":"Users of Enigmail versions older than 0.97a for Thunderbird 3 and later.","created":"2011-03-31T16:28:25Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=531047","name":"Enigmail","why":"This add-on causes a high volume of crashes and other stability issues. Users should update Enigmail."},"versionRange":[{"targetApplication":[{"minVersion":"3.0pre","guid":"{3550f703-e582-4d05-9a08-453d09bdfdc6}","maxVersion":"*"}],"minVersion":"0","maxVersion":"0.97a","severity":1}],"prefs":[],"id":"115f46b6-059d-202a-4373-2ca79b096347","schema":1482945809444},{"guid":"mozilla_cc@internetdownloadmanager.com","blockID":"i14","enabled":true,"last_modified":1482945809979,"details":{"who":"Users of Firefox 4 and later with Internet Download Manager version 6.9.8 and older.","created":"2011-03-31T16:28:25Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=578443","name":"Internet Download Manager","why":"This add-on causes a high volume of crashes and has other stability issues."},"versionRange":[{"targetApplication":[{"minVersion":"3.7a1pre","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"}],"minVersion":"0","maxVersion":"6.9.8","severity":1}],"prefs":[],"id":"773ffcfb-75d1-081d-7431-ebe3fa5dbb44","schema":1482945809444},{"guid":"admin@youtubeplayer.com","blockID":"i51","enabled":true,"last_modified":1482945809957,"details":{"who":"All Firefox users with this extension installed.","created":"2012-01-18T14:34:55Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=717165","name":"Youtube player (malware)","why":"This add-on is malware, doing nothing more than inserting advertisements into websites through iframes."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"16b2ce94-88db-0d79-33fc-a93070ceb509","schema":1482945809444},{"guid":"personas@christopher.beard","blockID":"i15","enabled":true,"last_modified":1482945809934,"details":{"who":"All users of Personas Plus 1.6 in all versions of Firefox.","created":"2011-03-31T16:28:25Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=590978","name":"Personas Plus","why":"This version of Personas Plus is incompatible with certain Firefox functionality and other add-ons. Users should upgrade to the latest version."},"versionRange":[{"targetApplication":[{"minVersion":"3.6","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"3.6.*"}],"minVersion":"1.6","maxVersion":"1.6","severity":1}],"prefs":[],"id":"e36479c6-ca00-48d4-4fd9-ec677fd032da","schema":1482945809444},{"guid":"youtubeee@youtuber3.com","blockID":"i96","enabled":true,"last_modified":1482945809912,"details":{"who":"All Firefox users who have installed this add-on.","created":"2012-05-25T09:26:47Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=758503","name":"Divx 2012 Plugins (malware)","why":"This is a malicious add-on that is disguised as a DivX plugin."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"f01be9cb-5cf2-774a-a4d7-e210a24db5b9","schema":1482945809444},{"guid":"{3252b9ae-c69a-4eaf-9502-dc9c1f6c009e}","blockID":"i17","enabled":true,"last_modified":1482945809886,"details":{"who":"Users of version 2.2 of this add-on in all versions of Firefox.","created":"2011-03-31T16:28:25Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=599971","name":"Default Manager (Microsoft)","why":"This add-on has security issues and was blocked at Microsoft's request. For more information, please see this article."},"versionRange":[{"targetApplication":[],"minVersion":"2.2","maxVersion":"2.2","severity":1}],"prefs":[],"id":"38be28ac-2e30-37fa-4332-852a55fafb43","schema":1482945809444},{"guid":"{68b8676b-99a5-46d1-b390-22411d8bcd61}","blockID":"i93","enabled":true,"last_modified":1482945809863,"details":{"who":"All Firefox users who have this add-on installed.","created":"2012-05-16T10:44:42Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=755635","name":"Zaman T\u00fcnelini Kald\u0131r! (malware)","why":"This is a malicious add-on that post content on Facebook accounts and steals user data."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"733aff15-9b1f-ec04-288f-b78a55165a1c","schema":1482945809444},{"guid":"applebeegifts@mozilla.doslash.org","blockID":"i54","enabled":true,"last_modified":1482945809840,"details":{"who":"All Firefox users that install this add-on.","created":"2012-01-26T16:17:49Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=721562","name":"Applebees Gift Card (malware)","why":"Add-on is malware installed under false pretenses."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"1372c8ab-5452-745a-461a-aa78e3e12c4b","schema":1482945809444},{"guid":"activity@facebook.com","blockID":"i65","enabled":true,"last_modified":1482945809437,"details":{"who":"All Firefox users who have installed this add-on.","created":"2012-02-13T15:41:02Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=726803","name":"Facebook extension (malware)","why":"Add-on behaves maliciously and poses as an official Facebook add-on."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"79ad1c9b-0828-7823-4574-dd1cdd46c3d6","schema":1482945112982},{"guid":"jid0-EcdqvFOgWLKHNJPuqAnawlykCGZ@jetpack","blockID":"i62","enabled":true,"last_modified":1482945809415,"details":{"who":"All Firefox users who have installed this add-on.","created":"2012-02-06T14:46:33Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=724650","name":"YouTube extension (malware)","why":"Add-on is installed under false pretenses and delivers malware."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"5ae1e642-b53c-54c0-19e7-5562cfdac3a3","schema":1482945112982},{"guid":"{B7082FAA-CB62-4872-9106-E42DD88EDE45}","blockID":"i25","enabled":true,"last_modified":1482945809393,"details":{"who":"Users of McAfee SiteAdvisor below version 3.3.1 for Firefox 4.\r\n\r\nUsers of McAfee SiteAdvisor 3.3.1 and below for Firefox 5 and higher.","created":"2011-03-14T15:53:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=637542","name":"McAfee SiteAdvisor","why":"This add-on causes a high volume of crashes and is incompatible with certain versions of Firefox."},"versionRange":[{"targetApplication":[{"minVersion":"3.7a1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"}],"minVersion":"0.1","maxVersion":"3.3.0.*","severity":1}],"prefs":[],"id":"c950501b-1f08-2ab2-d817-7c664c0d16fe","schema":1482945112982},{"guid":"{B7082FAA-CB62-4872-9106-E42DD88EDE45}","blockID":"i38","enabled":true,"last_modified":1482945809371,"details":{"who":"Users of McAfee SiteAdvisor below version 3.3.1 for Firefox 4.\r\n\r\nUsers of McAfee SiteAdvisor 3.3.1 and below for Firefox 5 and higher.","created":"2011-05-27T13:55:02Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=660111","name":"McAfee SiteAdvisor","why":"This add-on causes a high volume of crashes and is incompatible with certain versions of Firefox."},"versionRange":[{"targetApplication":[{"minVersion":"5.0a1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"}],"minVersion":"3.3.1","maxVersion":"*","severity":1}],"prefs":[],"id":"f11de388-4511-8d06-1414-95d3b2b122c5","schema":1482945112982},{"guid":"{3f963a5b-e555-4543-90e2-c3908898db71}","blockID":"i6","enabled":true,"last_modified":1482945809348,"details":{"who":"Users of AVG SafeSearch version 8.5 and older for all Mozilla applications.","created":"2009-06-17T13:12:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=527135","name":"AVG SafeSearch","why":"This add-on causes a high volume of crashes and causes other stability issues."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"8.5","severity":1}],"prefs":[],"id":"0d6f7d4c-bf5d-538f-1ded-ea4c6b775617","schema":1482945112982},{"guid":"langpack-vi-VN@firefox.mozilla.org","blockID":"i3","enabled":true,"last_modified":1482945809326,"details":{"who":"Users of Vietnamese Language Pack version 2.0 for all Mozilla applications.","created":"2011-03-31T16:28:25Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=432406","name":"Vietnamese Language Pack","why":"Corrupted files. For more information, please see this blog post."},"versionRange":[{"targetApplication":[],"minVersion":"2.0","maxVersion":"2.0","severity":1}],"prefs":[],"id":"51d4b581-d21c-20a1-6147-b17c3adc7867","schema":1482945112982},{"guid":"youtube@youtube7.com","blockID":"i55","enabled":true,"last_modified":1482945809304,"details":{"who":"All Firefox users with this add-on installed.","created":"2012-01-27T09:39:31Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=721646","name":"Plugin Video (malware)","why":"This is malware posing as video software."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"08ceedf5-c7c1-f54f-db0c-02f01f0e319a","schema":1482945112982},{"guid":"crossriderapp3924@crossrider.com","blockID":"i76","enabled":true,"last_modified":1482945809279,"details":{"who":"All Firefox users who have installed this add-on.","created":"2012-03-22T10:38:47Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=738282","name":"Fblixx (malware)","why":"This add-on compromises Facebook privacy and security and spams friends lists without user intervention."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"39d0a019-62fb-837b-1f1f-6831e56442b5","schema":1482945112982},{"guid":"{45147e67-4020-47e2-8f7a-55464fb535aa}","blockID":"i86","enabled":true,"last_modified":1482945809255,"details":{"who":"All Firefox users who have this add-on installed.","created":"2012-04-25T16:33:21Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=748993","name":"Mukemmel Face+","why":"This add-on injects scripts into Facebook and performs malicious activity."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"960443f9-cf48-0b71-1ff2-b8c34a3411ea","schema":1482945112982},{"guid":"{4B3803EA-5230-4DC3-A7FC-33638F3D3542}","blockID":"i4","enabled":true,"last_modified":1482945809232,"details":{"who":"Users of Firefox 3 and later with version 1.2 of Crawler Toolbar","created":"2008-07-08T10:23:31Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=441649","name":"Crawler Toolbar","why":"This add-on causes a high volume of crashes."},"versionRange":[{"targetApplication":[{"minVersion":"3.0a1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"}],"minVersion":"1.2","maxVersion":"1.2","severity":1}],"prefs":[],"id":"a9818d53-3a6a-8673-04dd-2a16f5644215","schema":1482945112982},{"guid":"flashupdate@adobe.com","blockID":"i68","enabled":true,"last_modified":1482945809208,"details":{"who":"All Firefox users who have this add-on installed.","created":"2012-02-21T13:55:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=722526","name":"Flash Update (malware)","why":"Add-on is malware, installed under false pretenses."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"1ba5b46e-790d-5af2-9580-a5f1e6e65522","schema":1482945112982},{"guid":"plugin@youtubeplayer.com","blockID":"i127","enabled":true,"last_modified":1482945809185,"details":{"who":"All users who have this add-on installed.","created":"2012-08-16T13:03:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=783356","name":"Youtube Facebook Player (malware)","why":"This add-on tries to pass as a YouTube player and runs malicious scripts on webpages."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"17a8bece-e2df-a55d-8a72-95faff028b83","schema":1482945112982},{"guid":"GifBlock@facebook.com","blockID":"i79","enabled":true,"last_modified":1482945809162,"details":{"who":"All Firefox users who have installed this extension.","created":"2012-03-27T10:53:33Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=739482","name":"Facebook Essentials (malware)","why":"This extension is malicious and is installed under false pretenses."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"728451e8-1273-d887-37e9-5712b1cc3bff","schema":1482945112982},{"guid":"ff-ext@youtube","blockID":"i52","enabled":true,"last_modified":1482945809138,"details":{"who":"All Firefox users that have this add-on installed.","created":"2012-01-19T08:26:35Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=719296","name":"Youtube player (malware)","why":"This add-on poses as a YouTube player while posting spam into Facebook account."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"cd2dd72a-dd52-6752-a0cd-a4b312fd0b65","schema":1482945112982},{"guid":"ShopperReports@ShopperReports.com","blockID":"i22","enabled":true,"last_modified":1482945809115,"details":{"who":"Users of Shopper Reports version 3.1.22.0 in Firefox 4 and later.","created":"2011-02-09T17:03:39Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=630191","name":"Shopper Reports","why":"This add-on causes a high volume of Firefox crashes."},"versionRange":[{"targetApplication":[],"minVersion":"3.1.22.0","maxVersion":"3.1.22.0","severity":1}],"prefs":[],"id":"f26b049c-d856-750f-f050-996e6bec7cbb","schema":1482945112982},{"guid":"{27182e60-b5f3-411c-b545-b44205977502}","blockID":"i16","enabled":true,"last_modified":1482945809092,"details":{"who":"Users of version 1.0 of this add-on in all versions of Firefox.","created":"2011-03-31T16:28:25Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=599971","name":"Search Helper Extension (Microsoft)","why":"This add-on has security issues and was blocked at Microsoft's request. For more information, please see this article."},"versionRange":[{"targetApplication":[],"minVersion":"1.0","maxVersion":"1.0","severity":1}],"prefs":[],"id":"2655f230-11f3-fe4c-7c3d-757d37d5f9a5","schema":1482945112982},{"guid":"{841468a1-d7f4-4bd3-84e6-bb0f13a06c64}","blockID":"i46","enabled":true,"last_modified":1482945809069,"details":{"who":"Users of all versions of Nectar Search Toolbar in Firefox 9.","created":"2011-12-20T11:38:17Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=712369","name":"Nectar Search Toolbar","why":"This add-on causes crashes and other stability issues in Firefox."},"versionRange":[{"targetApplication":[{"minVersion":"9.0a1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"9.0"}],"minVersion":"0.1","maxVersion":"*","severity":1}],"prefs":[],"id":"b660dabd-0dc0-a55c-4b86-416080b345d9","schema":1482945112982},{"guid":"support@daemon-tools.cc","blockID":"i5","enabled":true,"last_modified":1482945809045,"details":{"who":"Users of Daemon Tools Toolbar version 1.0.0.5 and older for all Mozilla applications.","created":"2009-02-13T18:39:01Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=459850","name":"Daemon Tools Toolbar","why":"This add-on causes a high volume of crashes."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"1.0.0.5","severity":1}],"prefs":[],"id":"8cabafd3-576a-b487-31c8-ab59e0349a0e","schema":1482945112982},{"guid":"{a3a5c777-f583-4fef-9380-ab4add1bc2a8}","blockID":"i53","enabled":true,"last_modified":1482945809021,"details":{"who":"All users of Firefox with this add-on installed.","created":"2012-01-19T15:58:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=719605","name":"Peliculas-FLV (malware)","why":"This add-on is being offered as an online movie viewer, when it reality it only inserts scripts and ads into known sites."},"versionRange":[{"targetApplication":[],"minVersion":"2.0.3","maxVersion":"2.0.3","severity":3}],"prefs":[],"id":"07bc0962-60da-087b-c3ab-f2a6ab84d81c","schema":1482945112982},{"guid":"royal@facebook.com","blockID":"i64","enabled":true,"last_modified":1482945808997,"details":{"who":"All Firefox users who have installed this add-on.","created":"2012-02-09T13:24:23Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=725777","name":"Facebook ! (malware)","why":"Malicious add-on posing as a Facebook tool."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"dd1d2623-0d15-c93e-8fbd-ba07b0299a44","schema":1482945112982},{"guid":"{28bfb930-7620-11e1-b0c4-0800200c9a66}","blockID":"i108","enabled":true,"last_modified":1482945808973,"details":{"who":"All Firefox user who have this add-on installed.","created":"2012-06-21T09:24:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=766852","name":"Aplicativo (malware)","why":"This is malware disguised as an Adobe product. It spams Facebook pages."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"908dc4fb-ebc9-cea1-438f-55e4507ba834","schema":1482945112982},{"guid":"socialnetworktools@mozilla.doslash.org","blockID":"i78","enabled":true,"last_modified":1482945808950,"details":{"who":"All Firefox users who have installed this add-on.","created":"2012-03-26T16:46:55Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=739441","name":"Social Network Tools (malware)","why":"This add-on hijacks the Facebook UI and adds scripts to track users."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"1064cd25-3b87-64bb-b0a6-2518ad281574","schema":1482945112982},{"guid":"youtubeeing@youtuberie.com","blockID":"i98","enabled":true,"last_modified":1482945808927,"details":{"who":"All Firefox users who have installed this add-on.","created":"2012-05-30T09:30:14Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=759663","name":"Youtube Video Player (malware)","why":"This add-on is malware disguised as a Youtube add-on."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"3484f860-56e1-28e8-5a70-cdcd5ab9d6ee","schema":1482945112982},{"guid":"{3a12052a-66ef-49db-8c39-e5b0bd5c83fa}","blockID":"i101","enabled":true,"last_modified":1482945808904,"details":{"who":"All Firefox users who have installed this add-on.","created":"2012-06-05T18:37:42Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=761874","name":"Timeline Remove (malware)","why":"This add-on is malware disguised as a Facebook timeline remover."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"b01b321b-6628-7166-bd15-52f21a04d8bd","schema":1482945112982},{"guid":"pfzPXmnzQRXX6@2iABkVe.com","blockID":"i99","enabled":true,"last_modified":1482945808881,"details":{"who":"All Firefox users who have this add-on installed.","created":"2012-05-30T17:10:18Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=759950","name":"Flash Player (malware)","why":"This add-on is malware disguised as a Flash Player update."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"29cc4abc-4f52-01f1-eb0b-cad84ba4db13","schema":1482945112982},{"guid":"/^(@pluginscribens_firefox|extension@vidscrab.com|firefox@jjj.ee|firefox@shop-reward.de|FxExtPasteNGoHtk@github.lostdj|himanshudotrai@gmail.com|jid0-bigoD0uivzAMmt07zrf3OHqa418@jetpack|jid0-iXbAR01tjT2BsbApyS6XWnjDhy8@jetpack)$/","blockID":"i1423","enabled":true,"last_modified":1482343886390,"details":{"who":"All users who have any of the affected versions installed.","created":"2016-12-21T17:21:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1325060","name":"Various vulnerable add-on versions","why":"A security vulnerability was discovered in old versions of the Add-ons SDK, which is exposed by certain old versions of add-ons. In the case of some add-ons that haven't been updated for a long time, all versions are being blocked."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"a58a2836-e4e7-74b5-c109-fa3d41e9ed56","schema":1482341309012},{"guid":"/^(pdftoword@addingapps.com|jid0-EYTXLS0GyfQME5irGbnD4HksnbQ@jetpack|jid1-ZjJ7t75BAcbGCX@jetpack)$/","blockID":"i1425","enabled":true,"last_modified":1482343886365,"details":{"who":"All users who have any of the affected versions installed.","created":"2016-12-21T17:23:14Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1325060","name":"Various vulnerable add-on versions","why":"A security vulnerability was discovered in old versions of the Add-ons SDK, which is exposed by certain old versions of add-ons. In the case of some add-ons that haven't been updated for a long time, all versions are being blocked."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"150e639f-c832-63d0-a775-59313b2e1bf9","schema":1482341309012},{"guid":"{cc8f597b-0765-404e-a575-82aefbd81daf}","blockID":"i380","enabled":true,"last_modified":1480349217152,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-06-19T13:03:00Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=866332","name":"Update My Browser (malware)","why":"This is a malicious add-on that hijacks Facebook accounts and performs unwanted actions on behalf of the user."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"4950d7aa-c602-15f5-a7a2-d844182d5cbd","schema":1480349193877},{"guid":"extension@FastFreeConverter.com","blockID":"i470","enabled":true,"last_modified":1480349217071,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-11-07T15:38:26Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=935779","name":"Installer bundle (malware)","why":"This add-on is part of a malicious Firefox installer bundle."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"649dd933-debf-69b7-020f-496c2c9f99c8","schema":1480349193877},{"guid":"59D317DB041748fdB89B47E6F96058F3@jetpack","blockID":"i694","enabled":true,"last_modified":1480349217005,"details":{"who":"All Firefox users who have this add-ons installed. Users who wish to continue using this add-on can enable it in the Add-ons Manager.","created":"2014-08-21T13:46:30Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1053540","name":"JsInjectExtension","why":"This is a suspicious add-on that appears to be installed without user consent, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"75692bd4-18e5-a9be-7ec3-9327e159ef68","schema":1480349193877},{"guid":"/^({bfec236d-e122-4102-864f-f5f19d897f5e}|{3f842035-47f4-4f10-846b-6199b07f09b8}|{92ed4bbd-83f2-4c70-bb4e-f8d3716143fe})$/","blockID":"i527","enabled":true,"last_modified":1480349216927,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-12-20T14:13:38Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=949566","name":"KeyBar add-on","why":"The installer that includes this add-on violates the Add-on Guidelines by making changes that can't be easily reverted and uses multiple IDs."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"6d68dd97-7965-0a84-8ca7-435aac3c8040","schema":1480349193877},{"guid":"support@vide1flash2.com","blockID":"i246","enabled":true,"last_modified":1480349216871,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-01-14T09:17:47Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=830159","name":"Lastest Adobe Flash Player (malware)","why":"This is an add-on that poses as the Adobe Flash Player and runs malicious code in the user's system."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"2004fba1-74bf-a072-2a59-6e0ba827b541","schema":1480349193877},{"guid":"extension21804@extension21804.com","blockID":"i312","enabled":true,"last_modified":1480349216827,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-03-06T14:14:05Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=835665","name":"Coupon Companion","why":"This add-on doesn't follow our Add-on Guidelines, bypassing our third party install opt-in screen. Users who wish to continue using this extension can enable it in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"b2cf1256-dadd-6501-1f4e-25902d408692","schema":1480349193877},{"guid":"toolbar@ask.com","blockID":"i602","enabled":true,"last_modified":1480349216765,"details":{"who":"All Firefox users who have these versions of the Ask Toolbar installed. Users who wish to continue using it can enable it in the Add-ons Manager.\r\n","created":"2014-06-12T14:18:05Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1024719","name":"Ask Toolbar (old Avira Security Toolbar bundle)","why":"Certain old versions of the Ask Toolbar are causing problems to users when trying to open new tabs. Using more recent versions of the Ask Toolbar should also fix this problem.\r\n"},"versionRange":[{"targetApplication":[],"minVersion":"3.15.8","maxVersion":"3.15.8.*","severity":1}],"prefs":[],"id":"b2b4236d-5d4d-82b2-99cd-00ff688badf1","schema":1480349193877},{"guid":"nosquint@urandom.ca","blockID":"i1232","enabled":true,"last_modified":1480349216711,"details":{"who":"Users on Firefox 47, and higher, using version 2.1.9.1, and earlier, of this add-on. If you wish to continue using it, you can enable it in the Add-ons Manager.","created":"2016-06-10T17:12:55Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1279561","name":"NoSquint","why":"The add-on is breaking the in-built zoom functionality on Firefox 47."},"versionRange":[{"targetApplication":[{"minVersion":"47","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"}],"minVersion":"0","maxVersion":"2.1.9.1-signed.1-signed","severity":1}],"prefs":[],"id":"30e0a35c-056a-054b-04f3-ade68b83985a","schema":1480349193877},{"guid":"{FE1DEEEA-DB6D-44b8-83F0-34FC0F9D1052}","blockID":"i364","enabled":true,"last_modified":1480349216652,"details":{"who":"All Firefox users who have this add-on installed. Users who want to enable the add-on again can do so in the Add-ons Manager.","created":"2013-06-10T16:14:41Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=867670","name":"IB Updater","why":"This add-on is side-installed with other software, and blocks setting reversions attempted by users who want to recover their settings after they are hijacked by other add-ons."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"a59b967c-66ca-7ad9-2dc6-d0ad37ded5fd","schema":1480349193877},{"guid":"vpyekkifgv@vpyekkifgv.org","blockID":"i352","enabled":true,"last_modified":1480349216614,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-05-14T13:42:04Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=872211","name":"SQLlite Addon (malware)","why":"Uses a deceptive name and injects ads into pages without user consent."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"8fd981ab-7ee0-e367-d804-0efe29d63178","schema":1480349193877},{"guid":"/^firefox@(albrechto|swiftbrowse|springsmart|storimbo|squirrelweb|betterbrowse|lizardlink|rolimno|browsebeyond|clingclang|weblayers|kasimos|higher-aurum|xaven|bomlabio)\\.(com?|net|org|info|biz)$/","blockID":"i549","enabled":true,"last_modified":1480349216570,"details":{"who":"All Firefox users who have one or more of these add-ons installed. If you wish to continue using any of these add-ons, they can be enabled in the Add-ons Manager.","created":"2014-01-30T15:08:04Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=937405","name":"Yontoo add-ons","why":"A large amount of add-ons developed by Yontoo are known to be silently installed and otherwise violate the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"3a124164-b177-805b-06f7-70a358b37e08","schema":1480349193877},{"guid":"thefoxonlybetter@quicksaver","blockID":"i702","enabled":true,"last_modified":1480349216512,"details":{"who":"All Firefox users who have any of these versions of the add-on installed.","created":"2014-08-27T10:05:31Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1053469","name":"The Fox, Only Better (malicious versions)","why":"Certain versions of The Fox, Only Better weren't developed by the original developer, and are likely malicious in nature. This violates the Add-on Guidelines for reusing an already existent ID."},"versionRange":[{"targetApplication":[],"minVersion":"1.10","maxVersion":"*","severity":3}],"prefs":[],"id":"60e54f6a-1b10-f889-837f-60a76a98fccc","schema":1480349193877},{"guid":"/@(ft|putlocker|clickmovie|m2k|sharerepo|smarter-?)downloader\\.com$/","blockID":"i396","enabled":true,"last_modified":1480349216487,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-06-25T12:48:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=881454","name":"PutLockerDownloader and related","why":"This group of add-ons is silently installed, bypassing our install opt-in screen. This violates our Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"e98ba6e3-f2dd-fdee-b106-3e0d2a03cda4","schema":1480349193877},{"guid":"my7thfakeid@gmail.com","blockID":"i1262","enabled":true,"last_modified":1480349216460,"details":{"who":"Anyone who has this add-on installed.","created":"2016-08-17T10:54:59Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1295616","name":"Remote Keylogger test 0 addon","why":"This add-on is a keylogger that sends the data to a remote server, and goes under the name Real_player.addon."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"81b380c0-8092-ea5e-11cd-54c7f563ff5a","schema":1480349193877},{"guid":"{f0e59437-6148-4a98-b0a6-60d557ef57f4}","blockID":"i304","enabled":true,"last_modified":1480349216402,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-02-27T13:10:18Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=845975","name":"WhiteSmoke B","why":"This add-on doesn't follow our installation guidelines and is dropped silently into user's profiles."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"0469e643-1a90-f9be-4aad-b347469adcbe","schema":1480349193877},{"guid":"firebug@software.joehewitt.com","blockID":"i75","enabled":true,"last_modified":1480349216375,"details":{"who":"All Firefox 9 users on Mac OS X or Linux who have Firebug 1.9.0 installed.","created":"2012-03-21T16:00:01Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=718831","name":"Firebug","why":"Firebug 1.9.0 creates stability problems on Firefox 9, on Mac OS X and Linux. Upgrading to Firefox 10 or later, or upgrading to Firebug 1.9.1 or later fixes this problem."},"versionRange":[{"targetApplication":[{"minVersion":"9.0a1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"9.*"}],"minVersion":"1.9.0","maxVersion":"1.9.0","severity":1}],"prefs":[],"os":"Darwin,Linux","id":"a1f9f055-ef34-1412-c39f-35605a70d031","schema":1480349193877},{"guid":"xz123@ya456.com","blockID":"i486","enabled":true,"last_modified":1480349215808,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-11-15T13:34:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=939254","name":"BetterSurf (malware)","why":"This add-on appears to be malware and is installed silently in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"b9825a25-a96c-407e-e656-46a7948e5745","schema":1480349193877},{"guid":"{C7AE725D-FA5C-4027-BB4C-787EF9F8248A}","blockID":"i424","enabled":true,"last_modified":1480349215779,"details":{"who":"Users of Firefox 23 or later who have RelevantKnowledge 1.0.0.2 or lower.","created":"2013-07-01T10:45:20Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=860641","name":"RelevantKnowledge 1.0.0.2 and lower","why":"Old versions of this add-on are causing startup crashes in Firefox 23, currently on the Beta channel. RelevantKnowledge users on Firefox 23 and above should update to version 1.0.0.3 of the add-on."},"versionRange":[{"targetApplication":[{"minVersion":"23.0a1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"}],"minVersion":"0","maxVersion":"1.0.0.2","severity":1}],"prefs":[],"id":"c888d167-7970-4b3f-240f-2d8e6f14ded4","schema":1480349193877},{"guid":"{5C655500-E712-41e7-9349-CE462F844B19}","blockID":"i966","enabled":true,"last_modified":1480349215743,"details":{"who":"All users who have this add-on installed.","created":"2015-07-17T13:42:28Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1175425","name":"Quick Translator","why":"This add-on is vulnerable to a cross-site scripting attack, putting users at risk when using it in arbitrary websites."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"1.0.1-signed","severity":1}],"prefs":[],"id":"f34b00a6-c783-7851-a441-0d80fb1d1031","schema":1480349193877},{"guid":"superlrcs@svenyor.net","blockID":"i545","enabled":true,"last_modified":1480349215672,"details":{"who":"All Firefox users who have this add-on installed. If you wish to continue using this add-on, you can enable it in the Add-ons Manager.","created":"2014-01-30T11:52:42Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=949596","name":"SuperLyrics","why":"This add-on is in violation of the Add-on Guidelines, using multiple add-on IDs and potentially doing other unwanted activities."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"002cd4fa-4c2b-e28b-9220-4a520f4d9ec6","schema":1480349193877},{"guid":"mbrsepone@facebook.com","blockID":"i479","enabled":true,"last_modified":1480349215645,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-11-11T15:42:30Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=937331","name":"Mozilla Lightweight Pack (malware)","why":"This add-on is malware that hijacks Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"0549645e-5f50-5089-1f24-6e7d3bfab8e0","schema":1480349193877},{"guid":"/^brasilescape.*\\@facebook\\.com$/","blockID":"i453","enabled":true,"last_modified":1480349215591,"details":{"who":"All Firefox users who have these add-ons installed.","created":"2013-09-20T09:54:04Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=918566","name":"Brasil Escape (malware)","why":"This is a group of malicious add-ons that use deceitful names like \"Facebook Video Pack\" or \"Mozilla Service Pack\" and hijack Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"8e6b1176-1794-2117-414e-f0821443f27b","schema":1480349193877},{"guid":"foxyproxy-basic@eric.h.jung","blockID":"i952","enabled":true,"last_modified":1480349215536,"details":{"who":"All users who have this add-on installed on Thunderbird 38 and above.","created":"2015-07-15T09:35:50Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1183890","name":"FoxyProxy Basic for Thunderbird","why":"This add-on is causing consistent startup crashes on Thunderbird 38 and above."},"versionRange":[{"targetApplication":[{"minVersion":"38.0a2","guid":"{3550f703-e582-4d05-9a08-453d09bdfdc6}","maxVersion":"*"},{"minVersion":"2.35","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"}],"minVersion":"0","maxVersion":"3.5.5","severity":1}],"prefs":[],"id":"81658491-feda-2ed3-3c6c-8e60c2b73aee","schema":1480349193877},{"guid":"mbroctone@facebook.com","blockID":"i476","enabled":true,"last_modified":1480349215504,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-11-08T15:32:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=936590","name":"Mozilla Storage Service (malware)","why":"This add-on is malware that hijacks the users' Facebook account."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"92198396-8756-8d09-7f18-a68d29894f71","schema":1480349193877},{"guid":"toolbar@ask.com","blockID":"i616","enabled":true,"last_modified":1480349215479,"details":{"who":"All Firefox users who have these versions of the Ask Toolbar installed. Users who wish to continue using it can enable it in the Add-ons Manager.\r\n","created":"2014-06-12T14:24:20Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1024719","name":"Ask Toolbar (old Avira Security Toolbar bundle)","why":"Certain old versions of the Ask Toolbar are causing problems to users when trying to open new tabs. Using more recent versions of the Ask Toolbar should also fix this problem.\r\n"},"versionRange":[{"targetApplication":[],"minVersion":"3.15.28","maxVersion":"3.15.28.*","severity":1}],"prefs":[],"id":"f11b485f-320e-233c-958b-a63377024fad","schema":1480349193877},{"guid":"/^({e9df9360-97f8-4690-afe6-996c80790da4}|{687578b9-7132-4a7a-80e4-30ee31099e03}|{46a3135d-3683-48cf-b94c-82655cbc0e8a}|{49c795c2-604a-4d18-aeb1-b3eba27e5ea2}|{7473b6bd-4691-4744-a82b-7854eb3d70b6}|{96f454ea-9d38-474f-b504-56193e00c1a5})$/","blockID":"i494","enabled":true,"last_modified":1480349215454,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-12-02T14:52:32Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=776404","name":"uTorrent and related","why":"This add-on changes search settings without user interaction, and fails to reset them after it is removed. It also uses multiple add-on IDs for no apparent reason. This violates our Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"485210d0-8e69-3436-536f-5d1deeea4167","schema":1480349193877},{"guid":"{EB7508CA-C7B2-46E0-8C04-3E94A035BD49}","blockID":"i162","enabled":true,"last_modified":1480349215428,"details":{"who":"All Firefox users who have installed any of these add-ons.","created":"2012-10-11T12:25:36Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=799266","name":"Mozilla Safe Browsing and others (Medfos malware)","why":"This block covers a number of malicious add-ons that deceive users, using names like \"Mozilla Safe Browsing\" and \"Translate This!\", and claiming they are developed by \"Mozilla Corp.\". They hijack searches and redirects users to pages they didn't intend to go to.\r\n\r\nNote: this block won't be active until bug 799266 is fixed."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"07566aa3-4ff9-ac4f-9de9-71c77454b4da","schema":1480349193877},{"guid":"toolbar@ask.com","blockID":"i614","enabled":true,"last_modified":1480349215399,"details":{"who":"All Firefox users who have these versions of the Ask Toolbar installed. Users who wish to continue using it can enable it in the Add-ons Manager.\r\n","created":"2014-06-12T14:23:39Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1024719","name":"Ask Toolbar (old Avira Security Toolbar bundle)","why":"Certain old versions of the Ask Toolbar are causing problems to users when trying to open new tabs. Using more recent versions of the Ask Toolbar should also fix this problem.\r\n"},"versionRange":[{"targetApplication":[],"minVersion":"3.15.26","maxVersion":"3.15.26.*","severity":1}],"prefs":[],"id":"ede541f3-1748-7b33-9bd6-80e2f948e14f","schema":1480349193877},{"guid":"/^({976cd962-e0ca-4337-aea7-d93fae63a79c}|{525ba996-1ce4-4677-91c5-9fc4ead2d245}|{91659dab-9117-42d1-a09f-13ec28037717}|{c1211069-1163-4ba8-b8b3-32fc724766be})$/","blockID":"i522","enabled":true,"last_modified":1480349215360,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-12-20T13:15:33Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=947485","name":"appbario7","why":"The installer that includes this add-on violates the Add-on Guidelines by being silently installed and using multiple add-on IDs."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"580aed26-dc3b-eef8-fa66-a0a402447b7b","schema":1480349193877},{"guid":"jid0-O6MIff3eO5dIGf5Tcv8RsJDKxrs@jetpack","blockID":"i552","enabled":true,"last_modified":1480349215327,"details":{"who":"All Firefox users who have this extension installed.","created":"2014-02-19T15:26:37Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=974041","name":"Extension_Protected (malware)","why":"This extension is malware that attempts to make it impossible for a second extension and itself to be disabled, and also forces the new tab page to have a specific URL."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"e53063b4-5702-5b66-c860-d368cba4ccb6","schema":1480349193877},{"guid":"toolbar@ask.com","blockID":"i604","enabled":true,"last_modified":1480349215302,"details":{"who":"All Firefox users who have these versions of the Ask Toolbar installed. Users who wish to continue using it can enable it in the Add-ons Manager.\r\n","created":"2014-06-12T14:18:58Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1024719","name":"Ask Toolbar (old Avira Security Toolbar bundle)","why":"Certain old versions of the Ask Toolbar are causing problems to users when trying to open new tabs. Using more recent versions of the Ask Toolbar should also fix this problem.\r\n"},"versionRange":[{"targetApplication":[],"minVersion":"3.15.10","maxVersion":"3.15.11.*","severity":1}],"prefs":[],"id":"b910f779-f36e-70e1-b17a-8afb75988c03","schema":1480349193877},{"guid":"brasilescapefive@facebook.com","blockID":"i483","enabled":true,"last_modified":1480349215276,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-11-14T09:37:06Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=938473","name":"Facebook Video Pack (malware)","why":"This add-on is malware that hijacks Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"85ee7840-f262-ad30-eb91-74b3248fd13d","schema":1480349193877},{"guid":"brasilescapeeight@facebook.com","blockID":"i482","enabled":true,"last_modified":1480349215249,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-11-14T09:36:55Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=938476","name":"Mozilla Security Pack (malware)","why":"This add-on is malware that hijacks Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"457a5722-be90-5a9f-5fa0-4c753e9f324c","schema":1480349193877},{"guid":"happylyrics@hpyproductions.net","blockID":"i370","enabled":true,"last_modified":1480349215225,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using this add-on can enable it in the Add-ons Manager.","created":"2013-06-11T15:42:24Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=881815","name":"Happy Lyrics","why":"This add-on is silently installed into Firefox without the users' consent, violating our Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"730e616d-94a7-df0c-d31a-98b7875d60c2","schema":1480349193877},{"guid":"search-snacks@search-snacks.com","blockID":"i872","enabled":true,"last_modified":1480349215198,"details":{"who":"All users who have this add-on installed. Users who wish to continue using the add-on can enable it in the Add-ons Manager.","created":"2015-03-04T14:37:33Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1082733","name":"Search Snacks","why":"This add-on is silently installed into users' systems, in violation of our Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"7567b06f-98fb-9400-8007-5d0357c345d9","schema":1480349193877},{"guid":"{ABDE892B-13A8-4d1b-88E6-365A6E755758}","blockID":"i107","enabled":true,"last_modified":1480349215173,"details":{"who":"All Firefox users on Windows who have the RealPlayer Browser Record extension installed.","created":"2012-06-14T13:54:27Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=764210","name":"RealPlayer Browser Record Plugin","why":"The RealPlayer Browser Record extension is causing significant problems on Flash video sites like YouTube. This block automatically disables the add-on, but users can re-enable it from the Add-ons Manager if necessary.\r\n\r\nThis block shouldn't disable any other RealPlayer plugins, so watching RealPlayer content on the web should be unaffected.\r\n\r\nIf you still have problems playing videos on YouTube or elsewhere, please visit our support site for help."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"15.0.5","severity":1}],"prefs":[],"os":"WINNT","id":"e3b89e55-b35f-8694-6f0e-f856e57a191d","schema":1480349193877},{"guid":"/(\\{7aeae561-714b-45f6-ace3-4a8aed6e227b\\})|(\\{01e86e69-a2f8-48a0-b068-83869bdba3d0\\})|(\\{77f5fe49-12e3-4cf5-abb4-d993a0164d9e\\})/","blockID":"i436","enabled":true,"last_modified":1480349215147,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-08-09T15:04:44Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=891606","name":"Visual Bee","why":"This add-on doesn't follow the Add-on Guidelines, changing Firefox default settings and not reverting them on uninstall. If you want to continue using this add-on, it can be enabled in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"ad6dc811-ab95-46fa-4bff-42186c149980","schema":1480349193877},{"guid":"amo-validator-bypass@example.com","blockID":"i1058","enabled":true,"last_modified":1480349214743,"details":{"who":"All users who install this add-on.","created":"2015-11-24T09:03:01Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1227605","name":" AMO Validator Bypass","why":"This add-on is a proof of concept of a malicious add-on that bypasses the code validator."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"86e38e3e-a729-b5a2-20a8-4738b376eea6","schema":1480349193877},{"guid":"6lIy@T.edu","blockID":"i852","enabled":true,"last_modified":1480349214613,"details":{"who":"All Firefox users who have this add-on installed.","created":"2015-02-09T15:30:27Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1128269","name":"unIsaless","why":"This add-on is silently installed and performs unwanted actions, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"39798bc2-9c75-f172-148b-13f3ca1dde9b","schema":1480349193877},{"guid":"{394DCBA4-1F92-4f8e-8EC9-8D2CB90CB69B}","blockID":"i100","enabled":true,"last_modified":1480349214568,"details":{"who":"All Firefox users who have Lightshot 2.5.0 installed.","created":"2012-06-05T09:24:51Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=761339","name":"Lightshot","why":"The Lightshot add-on, version 2.5.0, is causing widespread and frequent crashes in Firefox. Lightshot users are strongly recommended to update to version 2.6.0 as soon as possible."},"versionRange":[{"targetApplication":[],"minVersion":"2.5.0","maxVersion":"2.5.0","severity":1}],"prefs":[],"id":"57829ea2-5a95-1b6e-953c-7c4a7b3b21ac","schema":1480349193877},{"guid":"{a7f2cb14-0472-42a1-915a-8adca2280a2c}","blockID":"i686","enabled":true,"last_modified":1480349214537,"details":{"who":"All users who have this add-on installed. Users who wish to continue using this add-on can enable it in the Add-on Manager.","created":"2014-08-06T16:35:39Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1033809","name":"HomeTab","why":"This add-on is silently installed into users' systems, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":["browser.startup.homepage","browser.search.defaultenginename"],"id":"33a8f403-b2c8-cadf-e1ba-40b39edeaf18","schema":1480349193877},{"guid":"{CA8C84C6-3918-41b1-BE77-049B2BDD887C}","blockID":"i862","enabled":true,"last_modified":1480349214479,"details":{"who":"All users who have this add-on installed. Users who wish to continue using the add-on can enable it in the Add-ons Manager.","created":"2015-02-26T12:51:25Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1131230","name":"Ebay Shopping Assistant by Spigot","why":"This add-on is silently installed into users' systems, in violation of our Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":["browser.startup.homepage","browser.search.defaultenginename"],"id":"9a9d6da2-90a1-5b71-8b24-96492d57dfd1","schema":1480349193877},{"guid":"update@firefox.com","blockID":"i374","enabled":true,"last_modified":1480349214427,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-06-18T13:58:38Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=781088","name":"Premium Update (malware)","why":"This is a malicious extension that hijacks Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"bb388413-60ea-c9d6-9a3b-c90df950c319","schema":1480349193877},{"guid":"sqlmoz@facebook.com","blockID":"i350","enabled":true,"last_modified":1480349214360,"details":{"who":"All Firefox users who have this extension installed.","created":"2013-05-13T09:43:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=871610","name":"Mozilla Service Pack (malware)","why":"This extension is malware posing as Mozilla software. It hijacks Facebook accounts and spams other Facebook users."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"715082e8-7a30-b27b-51aa-186c38e078f6","schema":1480349193877},{"guid":"iobitapps@mybrowserbar.com","blockID":"i562","enabled":true,"last_modified":1480349214299,"details":{"who":"All Firefox users who have this add-on installed. If you wish to continue using it, it can be enabled in the Add-ons Manager.","created":"2014-02-27T10:00:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=948695","name":"IObit Apps Toolbar","why":"This add-on is installed silently and changes users settings without reverting them, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"be9a54f6-20c1-7dee-3aea-300b336b2ae5","schema":1480349193877},{"guid":"{9e09ac65-43c0-4b9d-970f-11e2e9616c55}","blockID":"i376","enabled":true,"last_modified":1480349214246,"details":{"who":"All Firefox users who have installed this add-on.","created":"2013-06-18T14:16:25Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=857847","name":"The Social Networks (malware)","why":"This add-on is malware that hijacks Facebook accounts and posts content on it."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"753638b4-65ca-6d71-f1f5-ce32ba2edf3b","schema":1480349193877},{"guid":"mozillahmpg@mozilla.org","blockID":"i140","enabled":true,"last_modified":1480349214216,"details":{"who":"All Firefox users who have installed this add-on.","created":"2012-09-17T16:04:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=791867","name":"Google YouTube HD Player (malware)","why":"This is a malicious add-on that tries to monetize on its users by embedding unauthorized affiliate codes on shopping websites, and sometimes redirecting users to alternate sites that could be malicious in nature."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"98150e2e-cb45-1fee-8458-28d3602ec2ec","schema":1480349193877},{"guid":"astrovia@facebook.com","blockID":"i489","enabled":true,"last_modified":1480349214157,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-11-25T12:40:30Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=942699","name":"Facebook Security Service (malware)","why":"This add-on is malware that hijacks Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"6f365ff4-e48f-8a06-d19d-55e19fba81f4","schema":1480349193877},{"guid":"{bbea93c6-64a3-4a5a-854a-9cc61c8d309e}","blockID":"i1126","enabled":true,"last_modified":1480349214066,"details":{"who":"All users who have this add-on installed.","created":"2016-02-29T21:58:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1251940","name":"Tab Extension (malware)","why":"This is a malicious add-on that disables various security checks in Firefox."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"5acb9dcc-59d4-46d1-2a11-1194c4948239","schema":1480349193877},{"guid":"ffxtlbr@iminent.com","blockID":"i628","enabled":true,"last_modified":1480349214036,"details":{"who":"All Firefox users who have any of these add-ons installed. Users who wish to continue using them can enable them in the Add-ons Manager.","created":"2014-06-26T15:47:15Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=866943","name":"Iminent Minibar","why":"These add-ons have been silently installed repeatedly, and change settings without user consent, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":["browser.startup.homepage","browser.search.defaultenginename"],"id":"4387ad94-8500-d74d-68e3-20564a9aac9e","schema":1480349193877},{"guid":"{28387537-e3f9-4ed7-860c-11e69af4a8a0}","blockID":"i40","enabled":true,"last_modified":1480349214002,"details":{"who":"Users of MediaBar versions 4.3.1.00 and below in all versions of Firefox.","created":"2011-07-19T10:19:41Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=665775","name":"MediaBar (2)","why":"This add-on causes a high volume of crashes and is incompatible with certain versions of Firefox."},"versionRange":[{"targetApplication":[],"minVersion":"0.1","maxVersion":"4.3.1.00","severity":1}],"prefs":[],"id":"ff95664b-93e4-aa73-ac20-5ffb7c87d8b7","schema":1480349193877},{"guid":"{41e5ef7a-171d-4ab5-8351-951c65a29908}","blockID":"i784","enabled":true,"last_modified":1480349213962,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-11-14T14:37:56Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1073810","name":"HelpSiteExpert","why":"This add-on is silently installed into users' systems. It uses very unsafe practices to load its code, and leaks information of all web browsing activity. These are all violations of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"0c05a0bb-30b4-979e-33a7-9f3955eba17d","schema":1480349193877},{"guid":"/^({2d7886a0-85bb-4bf2-b684-ba92b4b21d23}|{2fab2e94-d6f9-42de-8839-3510cef6424b}|{c02397f7-75b0-446e-a8fa-6ef70cfbf12b}|{8b337819-d1e8-48d3-8178-168ae8c99c36}|firefox@neurowise.info|firefox@allgenius.info)$/","blockID":"i762","enabled":true,"last_modified":1480349213913,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2014-10-17T16:58:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1082599","name":"SaveSense, neurowise, allgenius","why":"These add-ons are silently installed into users' systems, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"c5439f55-ace5-ad73-1270-017c0ba7b2ce","schema":1480349193877},{"guid":"{462be121-2b54-4218-bf00-b9bf8135b23f}","blockID":"i226","enabled":true,"last_modified":1480349213879,"details":{"who":"All Firefox users who have this add-on installed.","created":"2012-11-29T16:27:36Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=812303","name":"WhiteSmoke","why":"This add-on is silently side-installed by other software, and doesn't do much more than changing the users' settings, without reverting them on removal."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"994c6084-e864-0e4e-ac91-455083ee46c7","schema":1480349193877},{"guid":"firefox@browsefox.com","blockID":"i546","enabled":true,"last_modified":1480349213853,"details":{"who":"All Firefox users who have this add-on installed. If you want to continue using it, it can be enabled in the Add-ons Manager.","created":"2014-01-30T12:26:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=936244","name":"BrowseFox","why":"This add-on is silently installed, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"407d8c84-8939-cd28-b284-9b680e529bf6","schema":1480349193877},{"guid":"{6926c7f7-6006-42d1-b046-eba1b3010315}","blockID":"i382","enabled":true,"last_modified":1480349213825,"details":{"who":"All Firefox users who have this add-on installed. Those who wish to continue using it can enable it again in the Add-ons Manager.","created":"2013-06-25T12:05:34Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=844956","name":"appbario7","why":"This add-on is silently installed, bypassing the Firefox opt-in screen and violating our Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"2367bd94-2bdd-c615-de89-023ba071a443","schema":1480349193877},{"guid":"faststartff@gmail.com","blockID":"i866","enabled":true,"last_modified":1480349213799,"details":{"who":"All users who have this add-on installed. Users who wish to continue using the add-on can enable it in the Add-ons Manager.","created":"2015-02-26T13:12:47Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1131217","name":"Fast Start","why":"This add-on is silently installed into users' systems, in violation of our Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"9e730bca-c7d1-da82-64f6-c74de216cb7d","schema":1480349193877},{"guid":"05dd836e-2cbd-4204-9ff3-2f8a8665967d@a8876730-fb0c-4057-a2fc-f9c09d438e81.com","blockID":"i468","enabled":true,"last_modified":1480349213774,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-11-07T14:43:39Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=935135","name":"Trojan.DownLoader9.50268 (malware)","why":"This add-on appears to be part of a Trojan software package."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"2fd53d9b-7096-f1fb-fbcb-2b40a6193894","schema":1480349193877},{"guid":"jid1-0xtMKhXFEs4jIg@jetpack","blockID":"i586","enabled":true,"last_modified":1480349213717,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-06-03T15:50:19Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1011286","name":"ep (malware)","why":"This add-on appears to be malware installed without user consent."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"50ca2179-83ab-1817-163d-39ed2a9fbd28","schema":1480349193877},{"guid":"/^({16e193c8-1706-40bf-b6f3-91403a9a22be}|{284fed43-2e13-4afe-8aeb-50827d510e20}|{5e3cc5d8-ed11-4bed-bc47-35b4c4bc1033}|{7429e64a-1fd4-4112-a186-2b5630816b91}|{8c9980d7-0f09-4459-9197-99b3e559660c}|{8f1d9545-0bb9-4583-bb3c-5e1ac1e2920c})$/","blockID":"i517","enabled":true,"last_modified":1480349213344,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-12-20T12:54:33Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=947509","name":"Re-markit","why":"The installer that includes this add-on violates the Add-on Guidelines by silently installing the add-on, and using multiple add-on IDs."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"e88a28ab-5569-f06d-b0e2-15c51bb2a4b7","schema":1480349193877},{"guid":"safebrowse@safebrowse.co","blockID":"i782","enabled":true,"last_modified":1480349213319,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-11-12T14:20:44Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1097696","name":"SafeBrowse","why":"This add-on loads scripts with malicious code that appears intended to steal usernames, passwords, and other private information."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"edd81c91-383b-f041-d8f6-d0b9a90230bd","schema":1480349193877},{"guid":"{af95cc15-3b9b-45ae-8d9b-98d08eda3111}","blockID":"i492","enabled":true,"last_modified":1480349213294,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-12-02T12:45:06Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=945126","name":"Facebook (malware)","why":"This is a malicious Firefox extension that uses a deceptive name and hijacks users' Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"7064e9e2-fba4-7b57-86d7-6f4afbf6f560","schema":1480349193877},{"guid":"{84a93d51-b7a9-431e-8ff8-d60e5d7f5df1}","blockID":"i744","enabled":true,"last_modified":1480349213264,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2014-10-17T15:47:06Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1080817","name":"Spigot Shopping Assistant","why":"This add-on appears to be silently installed into users' systems, and changes settings without consent, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"dbc7ef8b-2c48-5dae-73a0-f87288c669f0","schema":1480349193877},{"guid":"{C3949AC2-4B17-43ee-B4F1-D26B9D42404D}","blockID":"i918","enabled":true,"last_modified":1480349213231,"details":{"who":"All Firefox users who have this add-on installed in Firefox 39 and above.\r\n","created":"2015-06-02T09:58:16Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1170633","name":"RealPlayer Browser Record Plugin","why":"Certain versions of this extension are causing startup crashes in Firefox 39 and above.\r\n"},"versionRange":[{"targetApplication":[{"minVersion":"39.0a1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"}],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"7f2a68f3-aa8a-ae41-1e48-d1f8f63d53c7","schema":1480349193877},{"guid":"831778-poidjao88DASfsAnindsd@jetpack","blockID":"i972","enabled":true,"last_modified":1480349213194,"details":{"who":"All users who have this add-on installed.","created":"2015-08-04T15:18:03Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1190962","name":"Video patch (malware)","why":"This is a malicious add-on that hijacks Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"39471221-6926-e11b-175a-b28424d49bf6","schema":1480349193877},{"guid":"lbmsrvfvxcblvpane@lpaezhjez.org","blockID":"i342","enabled":true,"last_modified":1480349213128,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-05-06T16:18:14Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=863385","name":"RapidFinda","why":"This add-on is silently installed, violating our Add-on Guidelines. It also appears to install itself both locally and globally, producing a confusing uninstall experience."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"98fb4536-07a4-d03a-f7c5-945acecc8203","schema":1480349193877},{"guid":"{babb9931-ad56-444c-b935-38bffe18ad26}","blockID":"i499","enabled":true,"last_modified":1480349213100,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-12-04T15:22:02Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=946086","name":"Facebook Credits (malware)","why":"This is a malicious Firefox extension that uses a deceptive name and hijacks users' Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"be1d19fa-1662-322a-13e6-5fa5474f33a7","schema":1480349193877},{"guid":"{18d5a8fe-5428-485b-968f-b97b05a92b54}","blockID":"i802","enabled":true,"last_modified":1480349213074,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-12-15T10:52:49Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1080839","name":"Astromenda Search Addon","why":"This add-on is silently installed and is considered malware, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":["browser.startup.homepage","browser.search.defaultenginename"],"id":"bc846147-cdc1-141f-5846-b705c48bd6ed","schema":1480349193877},{"guid":"{b6ef1336-69bb-45b6-8cba-e578fc0e4433}","blockID":"i780","enabled":true,"last_modified":1480349213024,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-11-12T14:00:47Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1073810","name":"Power-SW","why":"This add-on is silently installed into users' systems. It uses very unsafe practices to load its code, and leaks information of all web browsing activity. These are all violations of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"3b080157-2900-d071-60fe-52b0aa376cf0","schema":1480349193877},{"guid":"info@wxdownloadmanager.com","blockID":"i196","enabled":true,"last_modified":1480349212999,"details":{"who":"All Firefox users who have these add-ons installed.","created":"2012-11-05T09:24:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=806451","name":"Codec (malware)","why":"These are malicious add-ons that are distributed with a trojan and negatively affect web browsing."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"b62597d0-d2cb-d597-7358-5143a1d13658","schema":1480349193877},{"guid":"{C3949AC2-4B17-43ee-B4F1-D26B9D42404D}","blockID":"i111","enabled":true,"last_modified":1480349212971,"details":{"who":"All Firefox users on Windows who have the RealPlayer Browser Record extension installed.","created":"2012-07-10T15:28:16Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=771802","name":"RealPlayer Browser Record Plugin","why":"The RealPlayer Browser Record extension is causing significant problems on Flash video sites like YouTube. This block automatically disables the add-on, but users can re-enable it from the Add-ons Manager if necessary.\r\n\r\nThis block shouldn't disable any other RealPlayer plugins, so watching RealPlayer content on the web should be unaffected.\r\n\r\nIf you still have problems playing videos on YouTube or elsewhere, please visit our support site for help."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"15.0.5","severity":1}],"prefs":[],"os":"WINNT","id":"d3f96257-7635-555f-ef48-34d426322992","schema":1480349193877},{"guid":"l@AdLJ7uz.net","blockID":"i728","enabled":true,"last_modified":1480349212911,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2014-10-16T16:34:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1076771","name":"GGoSavee","why":"This add-on is silently installed and changes user settings without consent, in violation of the Add-on Guidelines"},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":["browser.startup.homepage"],"id":"e6bfa340-7d8a-1627-5cdf-40c0c4982e9d","schema":1480349193877},{"guid":"{6b2a75c8-6e2e-4267-b955-43e25b54e575}","blockID":"i698","enabled":true,"last_modified":1480349212871,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2014-08-21T15:46:31Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1052611","name":"BrowserShield","why":"This add-on is silently installed into users' systems, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"492e4e43-f89f-da58-9c09-d99528ee9ca9","schema":1480349193877},{"guid":"/^({65f9f6b7-2dae-46fc-bfaf-f88e4af1beca}|{9ed31f84-c8b3-4926-b950-dff74047ff79}|{0134af61-7a0c-4649-aeca-90d776060cb3}|{02edb56b-9b33-435b-b7df-b2843273a694}|{da51d4f6-3e7e-4ef8-b400-9198e0874606}|{b24577db-155e-4077-bb37-3fdd3c302bb5})$/","blockID":"i525","enabled":true,"last_modified":1480349212839,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-12-20T14:11:14Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=949566","name":"KeyBar add-on","why":"The installer that includes this add-on violates the Add-on Guidelines by making changes that can't be easily reverted and using multiple IDs."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"78562d79-9a64-c259-fb63-ce24e29bb141","schema":1480349193877},{"guid":"adsremoval@adsremoval.net","blockID":"i560","enabled":true,"last_modified":1480349212798,"details":{"who":"All Firefox users who have this add-on installed. If you wish to continue using this add-on, you can enable it in the Add-ons Manager.","created":"2014-02-27T09:57:31Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=962793","name":"Ad Removal","why":"This add-on is silently installed and changes various user settings, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"4d150ad4-dc22-9790-07a9-36e0a23f857f","schema":1480349193877},{"guid":"firefoxaddon@youtubeenhancer.com","blockID":"i445","enabled":true,"last_modified":1480349212747,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-09-04T16:53:37Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=911966","name":"YouTube Enhancer Plus (malware)","why":"This is a malicious add-on that imitates a popular video downloader extension, and attempts to hijack Facebook accounts. The add-on available in the add-ons site is safe to use."},"versionRange":[{"targetApplication":[],"minVersion":"208.7.0","maxVersion":"208.7.0","severity":3}],"prefs":[],"id":"41d75d3f-a57e-d5ad-b95b-22f5fa010b4e","schema":1480349193877},{"guid":"suchpony@suchpony.de","blockID":"i1264","enabled":true,"last_modified":1480349212719,"details":{"who":"All users who have version 1.6.7 or less of this add-on installed.","created":"2016-08-24T10:48:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1251911","name":"Suchpony (pre 1.6.8)","why":"Old versions of this add-on contained code from YouTube Unblocker, which was originally blocked due to malicious activity. Version 1.6.8 is now okay."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"1.6.7","severity":3}],"prefs":[],"id":"1bbf00f3-53b5-3777-43c7-0a0b11f9c433","schema":1480349193877},{"guid":"{336D0C35-8A85-403a-B9D2-65C292C39087}","blockID":"i224","enabled":true,"last_modified":1480349212655,"details":{"who":"All Firefox users who have this add-on installed.","created":"2012-11-29T16:22:49Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=812292","name":"IB Updater","why":"This add-on is side-installed with other software, and blocks setting reversions attempted by users who want to recover their settings after they are hijacked by other add-ons."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"c87666e6-ec9a-2f1e-ad03-a722d2fa2a25","schema":1480349193877},{"guid":"G4Ce4@w.net","blockID":"i718","enabled":true,"last_modified":1480349212277,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2014-10-02T12:21:22Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1076771","name":"YoutUbeAdBlaocke","why":"This add-on is silently installed into users' systems and changes settings without consent, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":["browser.startup.homepage"],"id":"3e1e9322-93e9-4ce1-41f5-46ad4ef1471b","schema":1480349193877},{"guid":"extension@Fast_Free_Converter.com","blockID":"i533","enabled":true,"last_modified":1480349212247,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-12-20T15:04:18Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=949597","name":"FastFreeConverter","why":"The installer that includes this add-on violates the Add-on Guidelines by silently installing it."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"726f5645-c0bf-66dc-a97a-d072b46e63e7","schema":1480349193877},{"guid":"@stopad","blockID":"i1266","enabled":true,"last_modified":1480349212214,"details":{"who":"Users who have version 0.0.4 and earlier of the add-on installed.","created":"2016-08-30T12:24:20Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1298780","name":"Stop Ads Addon","why":"Stop Ads sends each visited url to a third party server which is not necessary for the add-on to work or disclosed in a privacy policy or user opt-in. Versions 0.0.4 and earlier are affected."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"0.0.4","severity":1}],"prefs":[],"id":"3d1893dd-2092-d1f7-03f3-9629b7d7139e","schema":1480349193877},{"guid":"703db0db-5fe9-44b6-9f53-c6a91a0ad5bd@7314bc82-969e-4d2a-921b-e5edd0b02cf1.com","blockID":"i519","enabled":true,"last_modified":1480349212183,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-12-20T12:57:27Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=947509","name":"Re-markit","why":"The installer that includes this add-on violates the Add-on Guidelines by silently installing the add-on, and using multiple add-on IDs."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"a27d0f9f-7708-3d5f-82e1-e3f29e6098a0","schema":1480349193877},{"guid":"imbaty@taringamp3.com","blockID":"i662","enabled":true,"last_modified":1480349212157,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-07-10T15:39:44Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1036757","name":"Taringa MP3 / Adobe Flash","why":"This is a malicious add-on that attempts to hide itself by impersonating the Adobe Flash plugin."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"f43859d4-46b7-c028-4738-d40a73ddad7b","schema":1480349193877},{"guid":"{13c9f1f9-2322-4d5c-81df-6d4bf8476ba4}","blockID":"i348","enabled":true,"last_modified":1480349212102,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-05-08T15:55:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=867359","name":"mywebsearch","why":"This add-on is silently installed, violating our Add-on Guidelines. It also fails to revert settings changes on removal.\r\n\r\nUsers who wish to continue using this add-on can enable it in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"372cf3df-0810-85d8-b5d7-faffff309a11","schema":1480349193877},{"guid":"{a6e67e6f-8615-4fe0-a599-34a73fc3fba5}","blockID":"i346","enabled":true,"last_modified":1480349212077,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-05-06T17:06:06Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=867333","name":"Startnow","why":"This add-on is silently installed, violating our Add-on Guidelines. Also, it doesn't reset its settings changes on uninstall.\r\n\r\nUsers who wish to continue using this add-on can enable it in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"1caf911c-ff2f-b0f6-0d32-29ef74be81bb","schema":1480349193877},{"guid":"garg_sms@yahoo.in","blockID":"i652","enabled":true,"last_modified":1480349212044,"details":{"who":"All Firefox users who have this version of the add-on installed.","created":"2014-07-10T15:17:38Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1036757","name":"Save My YouTube Day!, version 67.9","why":"Certain versions of the Save My YouTube Day! extension weren't developed by the original developer, and are likely malicious in nature. This violates the Add-on Guidelines for reusing an already existent ID."},"versionRange":[{"targetApplication":[],"minVersion":"67.9","maxVersion":"67.9","severity":3}],"prefs":[],"id":"e50c0189-a7cd-774d-702b-62eade1bf18e","schema":1480349193877},{"guid":"9518042e-7ad6-4dac-b377-056e28d00c8f@f1cc0a13-4df1-4d66-938f-088db8838882.com","blockID":"i308","enabled":true,"last_modified":1480349212020,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using this add-on can enable it in the Add-ons Manager.","created":"2013-02-28T13:48:32Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=846455","name":"Solid Savings","why":"This add-on is silently installed, bypassing our third-party opt-in screen, in violation of our Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"df25ee07-74d4-ccd9-dbbe-7eb053015144","schema":1480349193877},{"guid":"jufa098j-LKooapd9jasJ9jliJsd@jetpack","blockID":"i1000","enabled":true,"last_modified":1480349211979,"details":{"who":"All users who have this add-on installed.","created":"2015-09-07T14:00:20Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1201163","name":"Secure Video (malware)","why":"This is a malicious add-on that hijacks Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"c3a98025-0f4e-3bb4-b475-97329e7b1426","schema":1480349193877},{"guid":"{46eddf51-a4f6-4476-8d6c-31c5187b2a2f}","blockID":"i750","enabled":true,"last_modified":1480349211953,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2014-10-17T16:17:47Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=963788","name":"Slick Savings","why":"This add-on is silently installed into users' systems, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"9b4ef650-e1ad-d55f-c420-4f26dbb4139c","schema":1480349193877},{"guid":"{DAC3F861-B30D-40dd-9166-F4E75327FAC7}","blockID":"i924","enabled":true,"last_modified":1480349211896,"details":{"who":"All Firefox users who have this add-on installed in Firefox 39 and above.\r\n","created":"2015-06-09T15:28:17Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1173154","name":"RealPlayer Browser Record Plugin","why":"Certain versions of this extension are causing startup crashes in Firefox 39 and above.\r\n"},"versionRange":[{"targetApplication":[{"minVersion":"39.0a1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"}],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"be57998b-9e4d-1040-e6bb-ed9de056338d","schema":1480349193877},{"guid":"JMLv@njMaHh.org","blockID":"i790","enabled":true,"last_modified":1480349211841,"details":{"who":"All users who have this add-on installed.","created":"2014-11-24T14:14:47Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1103516","name":"YouttubeAdBlocke","why":"This is a malicious add-on that hijacks Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"070d5747-137d-8500-8713-cfc6437558a3","schema":1480349193877},{"guid":"istart_ffnt@gmail.com","blockID":"i888","enabled":true,"last_modified":1480349211785,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using this add-on can enable it in the Add-on Manager.","created":"2015-04-10T16:27:47Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1152553","name":"Istart","why":"This add-on appears to be malware, being silently installed and hijacking user settings, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":["browser.startup.homepage","browser.search.defaultenginename"],"id":"32fad759-38d9-dad9-2295-e44cc6887040","schema":1480349193877},{"guid":"gystqfr@ylgga.com","blockID":"i449","enabled":true,"last_modified":1480349211748,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-09-13T16:19:39Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=912742","name":"Define Ext","why":"This add-on doesn't follow our Add-on Guidelines. It is installed bypassing the Firefox opt-in screen, and manipulates settings without reverting them on removal. Users who wish to continue using this add-on can enable it in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"8fe8f509-c530-777b-dccf-d10d58ae78cf","schema":1480349193877},{"guid":"e9d197d59f2f45f382b1aa5c14d82@8706aaed9b904554b5cb7984e9.com","blockID":"i844","enabled":true,"last_modified":1480349211713,"details":{"who":"All Firefox users who have this add-on installed.","created":"2015-02-06T15:01:47Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1128324","name":"Sense","why":"This add-on is silently installed and attempts to change user settings like the home page and default search, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":["browser.startup.homepage","browser.search.defaultenginename"],"id":"f8f8695c-a356-a1d6-9291-502b377c63c2","schema":1480349193877},{"guid":"{184AA5E6-741D-464a-820E-94B3ABC2F3B4}","blockID":"i968","enabled":true,"last_modified":1480349211687,"details":{"who":"All users who have this add-on installed.","created":"2015-08-04T09:41:27Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1164243","name":"Java String Helper (malware)","why":"This is a malicious add-on that poses as a Java extension."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"fac1d2cb-eed7-fcef-5d5a-43c556371bd7","schema":1480349193877},{"guid":"7d51fb17-b199-4d8f-894e-decaff4fc36a@a298838b-7f50-4c7c-9277-df6abbd42a0c.com","blockID":"i455","enabled":true,"last_modified":1480349211660,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-09-25T10:28:36Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=919792","name":"Video Console (malware)","why":"This is a malicious extension that hijacks Facebook accounts and posts spam to the users' friends."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"dd4d2e17-4ce6-36b0-3035-93e9cc5846d4","schema":1480349193877},{"guid":"prositez@prz.com","blockID":"i764","enabled":true,"last_modified":1480349211628,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-10-29T16:43:15Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1073810","name":"ProfSitez","why":"This add-on is silently installed into users' systems. It uses very unsafe practices to load its code, and leaks information of all web browsing activity. These are all violations of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"684ad4fd-2cbd-ce2a-34cd-bc66b20ac8af","schema":1480349193877},{"guid":"/^toolbar[0-9]*@findwide\\.com$/","blockID":"i874","enabled":true,"last_modified":1480349211601,"details":{"who":"All users who have this add-on installed. Users who wish to continue using the add-on can enable it in the Add-ons Manager.","created":"2015-03-04T14:54:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1082758","name":"FindWide Toolbars","why":"This add-on is silently installed into users' systems, in violation of our Add-on Guidelines.\r\n"},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":["browser.startup.homepage","browser.search.defaultenginename"],"id":"a317ad9f-af4d-e086-4afd-cd5eead1ed62","schema":1480349193877},{"guid":"{25D77636-38B1-1260-887C-2D4AFA92D6A4}","blockID":"i536","enabled":true,"last_modified":1480349211555,"details":{"who":"All Firefox users who have this extension installed.","created":"2014-01-13T10:36:05Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=959279","name":"Microsoft DirectInput Object (malware)","why":"This is a malicious extension that is installed alongside a trojan. It hijacks searches on selected sites."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"cd174588-940e-f5b3-12ea-896c957bd4b3","schema":1480349193877},{"guid":"fdm_ffext@freedownloadmanager.org","blockID":"i216","enabled":true,"last_modified":1480349211163,"details":{"who":"All Firefox users who have installed version 1.5.7.5 of the Free Download Manager extension.","created":"2012-11-27T12:47:51Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=789700","name":"Free Download Manager","why":"Version 1.5.7.5 of the Free Download Manager extension is causing frequent crashes in recent versions of Firefox. Version 1.5.7.6 corrects this problem, but it is currently not available on addons.mozilla.org. We recommend all users to update to the new version once it becomes available."},"versionRange":[{"targetApplication":[],"minVersion":"1.5.7.5","maxVersion":"1.5.7.5","severity":1}],"prefs":[],"id":"736417a2-6161-9973-991a-aff566314733","schema":1480349193877},{"guid":"{badea1ae-72ed-4f6a-8c37-4db9a4ac7bc9}","blockID":"i543","enabled":true,"last_modified":1480349211119,"details":{"who":"All Firefox users who have this add-on installed. If you wish to continue using this add-on, you can enable it in the Add-ons Manager.","created":"2014-01-28T14:28:18Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=963809","name":"Address Bar Search","why":"This add-on is apparently malware that is silently installed into users' systems, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"8c1dd68e-7df6-0c37-2f41-107745a7be54","schema":1480349193877},{"guid":"addon@gemaoff","blockID":"i1230","enabled":true,"last_modified":1480349211044,"details":{"who":"All users who have this add-on installed.","created":"2016-06-08T16:15:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1251911","name":"YouTube Unblocker (addon@gemaoff)","why":"These add-ons are copies of YouTube Unblocker, which was originally blocked due to malicious activity."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"6bc49e9f-322f-9952-15a6-0a723a61c2d9","schema":1480349193877},{"guid":"{d87d56b2-1379-49f4-b081-af2850c79d8e}","blockID":"i726","enabled":true,"last_modified":1480349211007,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-10-13T16:01:03Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1080835","name":"Website Xplorer Lite","why":"This add-on is silently installed into users' systems. It uses very unsafe practices to load its code, and leaks information of all web browsing activity. These are all violations of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"7b0895b4-dd4f-1c91-f4e3-31afdbdf3178","schema":1480349193877},{"guid":"OKitSpace@OKitSpace.es","blockID":"i469","enabled":true,"last_modified":1480349210982,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-11-07T15:35:01Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=935779","name":"Installer bundle (malware)","why":"This add-on is part of a malicious Firefox installer bundle."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"6a11aa68-0dae-5524-cc96-a5053a31c466","schema":1480349193877},{"guid":"{c96d1ae6-c4cf-4984-b110-f5f561b33b5a}","blockID":"i808","enabled":true,"last_modified":1480349210956,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-12-19T09:36:52Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1073810","name":"Better Web","why":"This add-on is silently installed into users' systems. It uses very unsafe practices to load its code, and leaks information of all web browsing activity. These are all violations of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"0413d46b-8205-d9e0-65df-4caa3e6355c4","schema":1480349193877},{"guid":"lightningnewtab@gmail.com","blockID":"i554","enabled":true,"last_modified":1480349210931,"details":{"who":"All Firefox users who have this add-on installed. If you wish to continue using this add-on, it can be enabled in the Add-ons Manager.","created":"2014-02-19T15:28:24Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=974041","name":"Lightning SpeedDial","why":"This add-on is silently installed in Firefox and includes a companion extension that also performs malicious actions."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"875513e1-e6b1-a383-2ec5-eb4deb87eafc","schema":1480349193877},{"guid":"/^ext@bettersurfplus/","blockID":"i506","enabled":true,"last_modified":1480349210905,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-12-10T15:10:31Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=939254","name":"BetterSurf (malware)","why":"This add-on appears to be malware and is installed silently in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"b4da06d2-a0fd-09b6-aadb-7e3b29c3be3a","schema":1480349193877},{"guid":"thefoxonlybetter@quicksaver","blockID":"i706","enabled":true,"last_modified":1480349210859,"details":{"who":"All Firefox users who have any of these versions of the add-on installed.","created":"2014-08-27T14:50:32Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1053469","name":"The Fox, Only Better (malicious versions)","why":"Certain versions of The Fox, Only Better weren't developed by the original developer, and are likely malicious in nature. This violates the Add-on Guidelines for reusing an already existent ID."},"versionRange":[{"targetApplication":[],"minVersion":"1.6.160","maxVersion":"1.6.160","severity":3}],"prefs":[],"id":"bb2b2114-f8e7-511d-04dc-abc8366712cc","schema":1480349193877},{"guid":"CortonExt@ext.com","blockID":"i336","enabled":true,"last_modified":1480349210805,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-04-22T16:10:17Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=864551","name":"CortonExt","why":"This add-on is reported to be installed without user consent, with a non-descriptive name, and ties a number of browser features to Amazon URLs, probably monetizing on affiliate codes."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"a5bdd05d-eb4c-ce34-9909-a677b4322384","schema":1480349193877},{"guid":"1chtw@facebook.com","blockID":"i430","enabled":true,"last_modified":1480349210773,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-08-05T16:42:24Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=901770","name":" Mozilla Service Pack (malware)","why":"This is a malicious add-on that uses a deceptive name and hijacks social networks."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"bf1e31c7-ba50-1075-29ae-47368ac1d6de","schema":1480349193877},{"guid":"lrcsTube@hansanddeta.com","blockID":"i344","enabled":true,"last_modified":1480349210718,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-05-06T16:44:04Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=866944","name":"LyricsTube","why":"This add-on is silently installed, violating our Add-on Guidelines.\r\n\r\nUsers who wish to continue using this add-on can enable it in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"424b9f39-d028-b1fb-d011-d8ffbbd20fe9","schema":1480349193877},{"guid":"{341f4dac-1966-47ff-aacf-0ce175f1498a}","blockID":"i356","enabled":true,"last_modified":1480349210665,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-05-23T14:45:35Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=868129","name":"MyFreeGames","why":"This add-on is silently installed, violating our Add-on Guidelines.\r\n\r\nUsers who wish to continue using this add-on can enable it in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"560e08b1-3471-ad34-8ca9-463f5ca5328c","schema":1480349193877},{"guid":"/^({d6e79525-4524-4707-9b97-1d70df8e7e59}|{ddb4644d-1a37-4e6d-8b6e-8e35e2a8ea6c}|{e55007f4-80c5-418e-ac33-10c4d60db01e}|{e77d8ca6-3a60-4ae9-8461-53b22fa3125b}|{e89a62b7-248e-492f-9715-43bf8c507a2f}|{5ce3e0cb-aa83-45cb-a7da-a2684f05b8f3})$/","blockID":"i518","enabled":true,"last_modified":1480349210606,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-12-20T12:56:17Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=947509","name":"Re-markit","why":"The installer that includes this add-on violates the Add-on Guidelines by silently installing the add-on, and using multiple add-on IDs."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"145b0f22-501e-39eb-371e-ec8342a5add9","schema":1480349193877},{"guid":"{72b98dbc-939a-4e0e-b5a9-9fdbf75963ef}","blockID":"i772","enabled":true,"last_modified":1480349210536,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-10-31T16:15:26Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1073810","name":"SitezExpert","why":"This add-on is silently installed into users' systems. It uses very unsafe practices to load its code, and leaks information of all web browsing activity. These are all violations of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"386cb2c9-e674-ce2e-345f-d30a785f90c5","schema":1480349193877},{"guid":"hha8771ui3-Fo9j9h7aH98jsdfa8sda@jetpack","blockID":"i970","enabled":true,"last_modified":1480349210477,"details":{"who":"All users who have this add-on installed.","created":"2015-08-04T15:15:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1190963","name":"Video fix (malware)","why":"This is a malicious add-on that hijacks Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"3ca577d8-3685-4ba9-363b-5b2d8d8dd608","schema":1480349193877},{"guid":"{7e8a1050-cf67-4575-92df-dcc60e7d952d}","blockID":"i478","enabled":true,"last_modified":1480349210416,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-11-08T15:42:28Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=935796","name":"SweetPacks","why":"This add-on violates the Add-on Guidelines. Users who wish to continue using this add-on can enable it in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"1519eb45-fcaa-b531-490d-fe366490ed45","schema":1480349193877},{"guid":"/^({66b103a7-d772-4fcd-ace4-16f79a9056e0}|{6926c7f7-6006-42d1-b046-eba1b3010315}|{72cabc40-64b2-46ed-8648-26d831761150}|{73ee2cf2-7b76-4c49-b659-c3d8cf30825d}|{ca6446a5-73d5-4c35-8aa1-c71dc1024a18}|{5373a31d-9410-45e2-b299-4f61428f0be4})$/","blockID":"i521","enabled":true,"last_modified":1480349210351,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-12-20T13:14:29Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=947485","name":"appbario7","why":"The installer that includes this add-on violates the Add-on Guidelines by being silently installed and using multiple add-on IDs."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"983cb7fe-e0b4-6a2e-f174-d2670876b2cd","schema":1480349193877},{"guid":"{dd6b651f-dfb9-4142-b0bd-09912ad22674}","blockID":"i400","enabled":true,"last_modified":1480349210301,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-06-25T15:16:01Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=835678","name":"Searchqu","why":"This group of add-ons is silently installed, bypassing our install opt-in screen. This violates our Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"975d2126-f727-f5b9-ca01-b83345b80c56","schema":1480349193877},{"guid":"25p@9eAkaLq.net","blockID":"i730","enabled":true,"last_modified":1480349210275,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2014-10-16T16:35:35Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1076771","name":"YYOutoubeAdBlocke","why":"This add-on is silently installed and changes user settings without consent, in violation of the Add-on Guidelines\r\n"},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":["browser.startup.homepage"],"id":"5a0c5818-693f-43ae-f85a-c6928d9c2cc4","schema":1480349193877},{"guid":"thunder@xunlei.com","blockID":"i568","enabled":true,"last_modified":1480349210242,"details":{"who":"All Firefox users who have versions 2.0.6 or lower of the Thunder add-on installed on Mac OS.","created":"2014-03-28T15:48:38Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=988490","name":"Thunder, 2.0.6 and lower","why":"Versions 2.0.6 and lower of the Thunder add-on are causing startup crashes on Mac OS."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"2.0.6","severity":1}],"prefs":[],"os":"Darwin","id":"cee484f6-2d5d-f708-88be-cd12d825a79a","schema":1480349193877},{"guid":"tmbepff@trendmicro.com","blockID":"i1222","enabled":true,"last_modified":1480349209818,"details":{"who":"All users of this add-on. If you wish to continue using it, you can enable it in the Add-ons Manager.","created":"2016-05-24T12:10:34Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1275245","name":"Trend Micro BEP 9.1.0.1035 and lower","why":"Add-on is causing a high-frequency crash in Firefox"},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"9.1.0.1035","severity":1}],"prefs":[],"id":"8045c799-486a-927c-b972-b9da1c2dab2f","schema":1480349193877},{"guid":"pricepeep@getpricepeep.com","blockID":"i220","enabled":true,"last_modified":1480349209794,"details":{"who":"All Firefox users who have Pricepeed below 2.1.0.20 installed.","created":"2012-11-29T16:18:26Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=811433","name":"PricePeep","why":"Versions older than 2.1.0.20 of the PricePeep add-on were silently side-installed with other software, injecting advertisements in Firefox. Versions 2.1.0.20 and above don't have the install problems are not blocked."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"2.1.0.19.99","severity":1}],"prefs":[],"id":"227b9a8d-c18d-239c-135e-d79e614fe392","schema":1480349193877},{"guid":"ytd@mybrowserbar.com","blockID":"i360","enabled":true,"last_modified":1480349209770,"details":{"who":"All Firefox users who have this add-on installed. Users who want to enable the add-on again can do so in the Add-ons Manager tab.","created":"2013-06-06T12:29:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=845969","name":"YouTube Downloader","why":"The installer that includes this add-on performs Firefox settings changes separately from the add-on install, making it very difficult to opt-out to these changes."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"63669524-93fe-4823-95ba-37cf6cbd4914","schema":1480349193877},{"guid":"hoverst@facebook.com","blockID":"i498","enabled":true,"last_modified":1480349209745,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-12-04T15:17:58Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=946029","name":"Adobe Flash Player (malware)","why":"This is a malicious Firefox extension that uses a deceptive name and hijacks users' Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"2b25ba3e-45db-0e6c-965a-3acda1a44117","schema":1480349193877},{"guid":"toolbar@ask.com","blockID":"i606","enabled":true,"last_modified":1480349209713,"details":{"who":"All Firefox users who have these versions of the Ask Toolbar installed. Users who wish to continue using it can enable it in the Add-ons Manager.\r\n","created":"2014-06-12T14:20:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1024719","name":"Ask Toolbar (old Avira Security Toolbar bundle)","why":"Certain old versions of the Ask Toolbar are causing problems to users when trying to open new tabs. Using more recent versions of the Ask Toolbar should also fix this problem.\r\n"},"versionRange":[{"targetApplication":[],"minVersion":"3.15.13","maxVersion":"3.15.13.*","severity":1}],"prefs":[],"id":"c3d88e22-386a-da3b-8aba-3cb526e08053","schema":1480349193877},{"guid":"advance@windowsclient.com","blockID":"i508","enabled":true,"last_modified":1480349209674,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-12-16T10:15:01Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=950773","name":"Microsoft .NET Framework Assistant (malware)","why":"This is not the Microsoft .NET Framework Assistant created and distributed by Microsoft. It is a malicious extension that is distributed under the same name to trick users into installing it, and turns users into a botnet that conducts SQL injection attacks on visited websites."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"e5d30a74-732e-c3fa-f13b-097ee28d4b27","schema":1480349193877},{"guid":"{5eeb83d0-96ea-4249-942c-beead6847053}","blockID":"i756","enabled":true,"last_modified":1480349209625,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2014-10-17T16:30:30Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1080846","name":"SmarterPower","why":"This add-on is silently installed into users' systems, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"e101dbc0-190c-f6d8-e168-0c1380581cc9","schema":1480349193877},{"guid":"/^({7e8a1050-cf67-4575-92df-dcc60e7d952d}|{b3420a9c-a397-4409-b90d-bcf22da1a08a}|{eca6641f-2176-42ba-bdbe-f3e327f8e0af}|{707dca12-3f99-4d94-afea-06dcc0ae0108}|{aea20431-87fc-40be-bc5b-18066fe2819c}|{30ee6676-1ba6-455a-a7e8-298fa863a546})$/","blockID":"i523","enabled":true,"last_modified":1480349209559,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-12-20T13:42:15Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=947481","name":"SweetPacks","why":"The installer that includes this add-on violates the Add-on Guidelines by making changes that can't be easily reverted."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"a3a6bc8e-46a1-b3d5-1b20-58b90ba099c3","schema":1480349193877},{"guid":"{e0352044-1439-48ba-99b6-b05ed1a4d2de}","blockID":"i710","enabled":true,"last_modified":1480349209491,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-09-30T15:28:14Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1073810","name":"Site Counselor","why":"This add-on is silently installed into users' systems. It uses very unsafe practices to load its code, and leaks information of all web browsing activity. These are all violations of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"b8fedf07-dcaf-f0e3-b42b-32db75c4c304","schema":1480349193877},{"guid":"{bee6eb20-01e0-ebd1-da83-080329fb9a3a}","blockID":"i642","enabled":true,"last_modified":1480349209443,"details":{"who":"All Firefox users who have this version of the add-on installed.","created":"2014-07-10T15:02:26Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1036757","name":"Flash and Video Download, between 40.10.1 and 44.10.1","why":"Certain versions of the Flash and Video Download extension weren't developed by the original developer, and are likely malicious in nature. This violates the Add-on Guidelines for reusing an already existent ID."},"versionRange":[{"targetApplication":[],"minVersion":"40.10.1","maxVersion":"44.10.1","severity":3}],"prefs":[],"id":"16db0c85-02ec-4f7c-24a3-a504fbce902d","schema":1480349193877},{"guid":"addlyrics@addlyrics.net","blockID":"i426","enabled":true,"last_modified":1480349209383,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-07-09T15:25:30Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=891605","name":"Add Lyrics","why":"This add-on is silently installed, violating our Add-on Guidelines.\r\n\r\nUsers who wish to continue using this add-on can enable it in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"81678e9e-ebf0-47d6-e409-085c25e67c7e","schema":1480349193877},{"guid":"{7b1bf0b6-a1b9-42b0-b75d-252036438bdc}","blockID":"i638","enabled":true,"last_modified":1480349209260,"details":{"who":"All Firefox users who have this version of the add-on installed.","created":"2014-07-08T16:07:56Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1036137","name":"YouTube High Definition 27.8 and 27.9","why":"Versions 27.8 and 27.9 of the YouTube High Definition extension weren't developed by the original developer, and are likely malicious in nature. It violates the Add-on Guidelines for reusing an already existent ID."},"versionRange":[{"targetApplication":[],"minVersion":"27.8","maxVersion":"27.9","severity":3}],"prefs":[],"id":"ffdc8ba0-d548-dc5b-d2fd-79a20837124b","schema":1480349193877},{"guid":"toolbar@ask.com","blockID":"i610","enabled":true,"last_modified":1480349209128,"details":{"who":"All Firefox users who have these versions of the Ask Toolbar installed. Users who wish to continue using it can enable it in the Add-ons Manager.\r\n","created":"2014-06-12T14:21:47Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1024719","name":"Ask Toolbar (old Avira Security Toolbar bundle)","why":"Certain old versions of the Ask Toolbar are causing problems to users when trying to open new tabs. Using more recent versions of the Ask Toolbar should also fix this problem.\r\n"},"versionRange":[{"targetApplication":[],"minVersion":"3.15.22","maxVersion":"3.15.22.*","severity":1}],"prefs":[],"id":"935dfec3-d017-5660-db5b-94ae7cea6e5f","schema":1480349193877},{"guid":"info@allpremiumplay.info","blockID":"i163","enabled":true,"last_modified":1480349209076,"details":{"who":"All Firefox users who have these add-ons installed.","created":"2012-10-29T16:40:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=806451","name":"Codec-C (malware)","why":"These are malicious add-ons that are distributed with a trojan and negatively affect web browsing."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"6afbf9b8-ae3a-6a48-0f6c-7a3e065ec043","schema":1480349193877},{"guid":"now.msn.com@services.mozilla.org","blockID":"i490","enabled":true,"last_modified":1480349209021,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-11-27T08:06:04Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=926378","name":"MSNNow (discontinued social provider)","why":"As part of their ongoing work to fine-tune their editorial mix, msnNOW has decided that msnNOW will stop publishing on Dec. 3, 2013. Rather than having a single home for trending content, they will continue integrating that material throughout all MSN channels. A big thank you to everyone who followed msnNOW stories using the Firefox sidebar"},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"de7d699d-016d-d973-5e39-52568de6ffde","schema":1480349193877},{"guid":"fftoolbar2014@etech.com","blockID":"i858","enabled":true,"last_modified":1480349208988,"details":{"who":"All Firefox users who have this add-on installed.","created":"2015-02-11T15:32:36Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1131078","name":"FF Toolbar","why":"This add-on is silently installed and changes users' settings, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":["browser.startup.homepage","browser.search.defaultenginename"],"id":"6877bf40-9e45-7017-4dac-14d09e7f0ef6","schema":1480349193877},{"guid":"mbrnovone@facebook.com","blockID":"i477","enabled":true,"last_modified":1480349208962,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-11-08T15:35:51Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=936249","name":"Mozilla Security Service (malware)","why":"This add-on is malware that hijacks Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"758c2503-766d-a2f5-4c58-7cea93acfe05","schema":1480349193877},{"guid":"{739df940-c5ee-4bab-9d7e-270894ae687a}","blockID":"i530","enabled":true,"last_modified":1480349208933,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-12-20T14:49:25Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=949558","name":"WhiteSmoke New","why":"The installer that includes this add-on violates the Add-on Guidelines by making changes that can't be easily reverted."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"f8097aa6-3009-6dfc-59df-353ba6b1142b","schema":1480349193877},{"guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","blockID":"i115","enabled":true,"last_modified":1480349208904,"details":{"who":"All Firefox users who have this add-on installed.","created":"2012-08-01T13:53:00Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=779014","name":"Adobe Flash Player (malware)","why":"This extension is malware that is installed under false pretenses, and it conducts attacks against certain video websites."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"aef9312d-5f2e-a44d-464d-6113394148e3","schema":1480349193877},{"guid":"g99hiaoekjoasiijdkoleabsy278djasi@jetpack","blockID":"i1022","enabled":true,"last_modified":1480349208877,"details":{"who":"All users who have this add-on installed.","created":"2015-09-28T15:23:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1208708","name":"WatchIt (malware)","why":"This is a malicious add-on that hijacks Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"25e057ea-f500-67df-d078-ec3f37f99036","schema":1480349193877},{"guid":"firefoxaddon@youtubeenhancer.com","blockID":"i636","enabled":true,"last_modified":1480349208851,"details":{"who":"All Firefox users who have this version of the add-on installed.","created":"2014-07-08T15:58:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1033120","name":"YoutubeEnhancer - Firefox","why":"Version 199.7.0 of the YoutubeEnhancer extension isn't developed by the original developer, and is likely malicious in nature. It violates the Add-on Guidelines for reusing an already existent ID."},"versionRange":[{"targetApplication":[],"minVersion":"199.7.0","maxVersion":"199.7.0","severity":3}],"prefs":[],"id":"204a074b-da87-2784-f15b-43a9ea9a6b36","schema":1480349193877},{"guid":"extacylife@a.com","blockID":"i505","enabled":true,"last_modified":1480349208823,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-12-09T15:08:51Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=947741","name":"Facebook Haber (malware)","why":"This is a malicious extension that hijacks users' Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"5acadb8d-d3be-e0e0-4656-9107f9de0ea9","schema":1480349193877},{"guid":"{746505DC-0E21-4667-97F8-72EA6BCF5EEF}","blockID":"i842","enabled":true,"last_modified":1480349208766,"details":{"who":"All Firefox users who have this add-on installed.","created":"2015-02-06T14:45:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1128325","name":"Shopper-Pro","why":"This add-on is silently installed into users' systems, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"5f19c5fb-1c78-cbd6-8a03-1678efb54cbc","schema":1480349193877},{"guid":"{51c77233-c0ad-4220-8388-47c11c18b355}","blockID":"i580","enabled":true,"last_modified":1480349208691,"details":{"who":"All Firefox users who have this add-on installed. If you wish to continue using this add-on, it can be enabled in the Add-ons Manager.","created":"2014-04-30T13:55:35Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1004132","name":"Browser Utility","why":"This add-on is silently installed into Firefox, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"0.1.9999999","severity":1}],"prefs":[],"id":"daa2c60a-5009-2c65-a432-161d50bef481","schema":1480349193877},{"guid":"{a2bfe612-4cf5-48ea-907c-f3fb25bc9d6b}","blockID":"i712","enabled":true,"last_modified":1480349208027,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-09-30T15:28:22Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1073810","name":"Website Xplorer","why":"This add-on is silently installed into users' systems. It uses very unsafe practices to load its code, and leaks information of all web browsing activity. These are all violations of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"13450534-93d7-f2a2-7f0a-e4e3948c4dc1","schema":1480349193877},{"guid":"ScorpionSaver@jetpack","blockID":"i539","enabled":true,"last_modified":1480349207972,"details":{"who":"All Firefox users who have this add-on installed. If you wish to continue using this add-on, you can enable it in the Add-ons Manager.","created":"2014-01-28T14:00:30Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=963826","name":"ScorpionSaver","why":"This add-on is being silently installed, in violation of the Add-on Guidelines"},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"3499c968-6e8b-37f1-5f6e-2384807c2a6d","schema":1480349193877},{"guid":"unblocker20@unblocker.yt","blockID":"i1212","enabled":true,"last_modified":1480349207912,"details":{"who":"All users who have this add-on installed.","created":"2016-05-05T18:13:29Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1251911","name":"YouTube Unblocker 2.0","why":"This add-on is a copy of YouTube Unblocker, which was originally blocked due to malicious activity."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"2.0.0","severity":3}],"prefs":[],"id":"57785030-909f-e985-2a82-8bd057781227","schema":1480349193877},{"guid":"{D19CA586-DD6C-4a0a-96F8-14644F340D60}","blockID":"i42","enabled":true,"last_modified":1480349207877,"details":{"who":"Users of McAfee ScriptScan versions 14.4.0 and below for all versions of Firefox and SeaMonkey.","created":"2011-10-03T09:38:39Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=690184","name":"McAfee ScriptScan","why":"This add-on causes a high volume of crashes."},"versionRange":[{"targetApplication":[],"minVersion":"0.1","maxVersion":"14.4.0","severity":1}],"prefs":[],"id":"1d35ac9d-49df-23cf-51f5-f3c228ad0dc9","schema":1480349193877},{"guid":"gjhrjenrengoe@jfdnkwelfwkm.com","blockID":"i1042","enabled":true,"last_modified":1480349207840,"details":{"who":"All users who have this add-on installed.","created":"2015-10-07T13:12:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1212174","name":"Avant Player (malware)","why":"This is a malicious add-on that takes over Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"d6453893-becc-7617-2050-0db284e0e0db","schema":1480349193877},{"guid":"/^(@9338379C-DD5C-4A45-9A36-9733DC806FAE|9338379C-DD5C-4A45-9A36-9733DC806FAE|@EBC7B466-8A28-4061-81B5-10ACC05FFE53|@bd6a97c0-4b18-40ed-bce7-3b7d3309e3c4222|@bd6a97c0-4b18-40ed-bce7-3b7d3309e3c4|@b2d6a97c0-4b18-40ed-bce7-3b7d3309e3c4222)$/","blockID":"i1079","enabled":true,"last_modified":1480349207815,"details":{"who":"All Firefox users who have these add-ons installed.","created":"2016-01-18T12:32:32Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1240597","name":"Default SearchProtected (malware)","why":"These add-ons are malicious, manipulating registry and search settings for users."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"ddc5237e-42e4-1bf1-54d3-a5e5799dd828","schema":1480349193877},{"guid":"{33e0daa6-3af3-d8b5-6752-10e949c61516}","blockID":"i282","enabled":true,"last_modified":1480349207789,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using this add-on can enable it in the Add-ons Manager.","created":"2013-02-15T12:19:26Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=835683","name":"Complitly","why":"This add-on violates our add-on guidelines, bypassing the third party opt-in screen."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"1.1.999","severity":1}],"prefs":[],"id":"1f94bc8d-9d5f-c8f5-45c0-ad1f6e147c71","schema":1480349193877},{"guid":"toolbar@ask.com","blockID":"i608","enabled":true,"last_modified":1480349207761,"details":{"who":"All Firefox users who have these versions of the Ask Toolbar installed. Users who wish to continue using it can enable it in the Add-ons Manager.\r\n","created":"2014-06-12T14:20:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1024719","name":"Ask Toolbar (old Avira Security Toolbar bundle)","why":"Certain old versions of the Ask Toolbar are causing problems to users when trying to open new tabs. Using more recent versions of the Ask Toolbar should also fix this problem.\r\n"},"versionRange":[{"targetApplication":[],"minVersion":"3.15.18","maxVersion":"3.15.20.*","severity":1}],"prefs":[],"id":"e7d50ff2-5948-d571-6711-37908ccb863f","schema":1480349193877},{"guid":"chiang@programmer.net","blockID":"i340","enabled":true,"last_modified":1480349207736,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-04-30T07:44:09Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=867156","name":"Cache Manager (malware)","why":"This is a malicious add-on that logs keyboard input and sends it to a remote server."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"d50d0434-78e4-faa7-ce2a-9b0a8bb5120e","schema":1480349193877},{"guid":"{63eb5ed4-e1b3-47ec-a253-f8462f205350}","blockID":"i786","enabled":true,"last_modified":1480349207705,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-11-18T12:33:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1073810","name":"FF-Plugin","why":"This add-on is silently installed into users' systems. It uses very unsafe practices to load its code, and leaks information of all web browsing activity. These are all violations of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"ca4558a2-8ce4-3ca0-3d29-63019f680c8c","schema":1480349193877},{"guid":"jid1-4vUehhSALFNqCw@jetpack","blockID":"i634","enabled":true,"last_modified":1480349207680,"details":{"who":"All Firefox users who have this version of the add-on installed.","created":"2014-07-04T14:13:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1033002","name":"YouTube Plus Plus 99.7","why":"Version 99.7 of the YouTube Plus Plus extension isn't developed by the original developer, and is likely malicious in nature. It violates the Add-on Guidelines for reusing an already existent ID."},"versionRange":[{"targetApplication":[],"minVersion":"99.7","maxVersion":"99.7","severity":3}],"prefs":[],"id":"a6d017cb-e33f-2239-4e42-ab4e7cfb19fe","schema":1480349193877},{"guid":"{aab02ab1-33cf-4dfa-8a9f-f4e60e976d27}","blockID":"i820","enabled":true,"last_modified":1480349207654,"details":{"who":"All Firefox users who have this add-on installed.","created":"2015-01-13T09:27:49Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1073810","name":"Incredible Web","why":"This add-on is silently installed into users' systems without their consent, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"847ecc6e-1bc1-f7ff-e1d5-a76e6b8447d2","schema":1480349193877},{"guid":"torntv@torntv.com","blockID":"i320","enabled":true,"last_modified":1480349207608,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-03-20T16:35:24Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=845610","name":"TornTV","why":"This add-on doesn't follow our Add-on Guidelines, bypassing our third party install opt-in screen. Users who wish to continue using this extension can enable it in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"cdd492b8-8101-74a9-5760-52ff709fd445","schema":1480349193877},{"guid":"crossriderapp12555@crossrider.com","blockID":"i674","enabled":true,"last_modified":1480349207561,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using this add-on can enable it in the Add-ons Manager.","created":"2014-07-22T16:26:19Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=877836","name":"JollyWallet","why":"The add-on is silently installed, in violation of our Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"d4467e20-0f71-f0e0-8cd6-40c82b6c7379","schema":1480349193877},{"guid":"pluggets@gmail.com","blockID":"i435","enabled":true,"last_modified":1480349207535,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-08-09T13:12:14Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=903544","name":"Facebook Pluggets Plugin (malware)","why":"This add-on is malware that hijacks users' Facebook accounts and posts spam on their behalf. "},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"3a63fd92-9290-02fb-a2e8-bc1b4424201a","schema":1480349193877},{"guid":"344141-fasf9jas08hasoiesj9ia8ws@jetpack","blockID":"i1038","enabled":true,"last_modified":1480349207485,"details":{"who":"All users who have this add-on installed.","created":"2015-10-05T16:42:09Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1211169","name":"Video Plugin (malware)","why":"This is a malicious add-on that hijacks Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"f7986b7b-9b5a-d372-8147-8b4bd6f5a29b","schema":1480349193877},{"guid":"/^brasilescape.*\\@facebook\\.com$//","blockID":"i485","enabled":true,"last_modified":1480349207424,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-11-14T15:57:03Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=938835","name":"Facebook Video Pack (malware)","why":"This add-on is malware that hijacks Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"17a2bf85-b44a-4745-1b48-8be0c151d697","schema":1480349193877},{"guid":"meOYKQEbBBjH5Ml91z0p9Aosgus8P55bjTa4KPfl@jetpack","blockID":"i998","enabled":true,"last_modified":1480349207370,"details":{"who":"All users who have this add-on installed.","created":"2015-09-07T13:54:25Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1201164","name":"Smooth Player (malware)","why":"This is a malicious add-on that hijacks Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"30c3e511-9e8d-15ee-0867-d61047e56515","schema":1480349193877},{"guid":"{8dc5c42e-9204-2a64-8b97-fa94ff8a241f}","blockID":"i770","enabled":true,"last_modified":1480349207320,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-10-30T14:52:52Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1088726","name":"Astrmenda Search","why":"This add-on is silently installed and is considered malware, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":["browser.startup.homepage","browser.search.defaultenginename"],"id":"8a9c7702-0349-70d6-e64e-3a666ab084c6","schema":1480349193877},{"guid":"savingsslider@mybrowserbar.com","blockID":"i752","enabled":true,"last_modified":1480349207290,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2014-10-17T16:18:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=963788","name":"Slick Savings","why":"This add-on is silently installed into users' systems, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"9b1faf30-5725-7847-d993-b5cdaabc9829","schema":1480349193877},{"guid":"youtubeunblocker__web@unblocker.yt","blockID":"i1129","enabled":true,"last_modified":1480349207262,"details":{"who":"All users who have this add-on installed.","created":"2016-03-01T21:20:05Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1251911","name":"YouTube Unblocker","why":"The add-on has a mechanism that updates certain configuration files from the developer\u2019s website. This mechanism has a vulnerability that is being exploited through this website (unblocker.yt) to change security settings in Firefox and install malicious add-ons."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"aa246b36-0a80-81e3-2129-4847e872d5fe","schema":1480349193877},{"guid":"toolbar@ask.com","blockID":"i612","enabled":true,"last_modified":1480349206818,"details":{"who":"All Firefox users who have these versions of the Ask Toolbar installed. Users who wish to continue using it can enable it in the Add-ons Manager.\r\n","created":"2014-06-12T14:23:00Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1024719","name":"Ask Toolbar (old Avira Security Toolbar bundle)","why":"Certain old versions of the Ask Toolbar are causing problems to users when trying to open new tabs. Using more recent versions of the Ask Toolbar should also fix this problem.\r\n"},"versionRange":[{"targetApplication":[],"minVersion":"3.15.24","maxVersion":"3.15.24.*","severity":1}],"prefs":[],"id":"e0ff9df4-60e4-dbd0-8018-57f395e6610a","schema":1480349193877},{"guid":"{1e4ea5fc-09e5-4f45-a43b-c048304899fc}","blockID":"i812","enabled":true,"last_modified":1480349206784,"details":{"who":"All Firefox users who have this add-on installed.","created":"2015-01-06T13:22:39Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1073810","name":"Great Finder","why":"This add-on is silently installed into users' systems. It uses very unsafe practices to load its code, and leaks information of all web browsing activity. These are all violations of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"1ea40b9f-2423-a2fd-a5e9-4ec1df2715f4","schema":1480349193877},{"guid":"psid-vhvxQHMZBOzUZA@jetpack","blockID":"i70","enabled":true,"last_modified":1480349206758,"details":{"who":"All Firefox users who have installed this add-on.","created":"2012-02-23T13:44:41Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=730059","name":"PublishSync (malware)","why":"Add-on spams Facebook accounts and blocks Facebook warnings."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"f1528b02-7cef-0e80-f747-8bbf1f0f2f06","schema":1480349193877},{"guid":"{B18B1E5C-4D81-11E1-9C00-AFEB4824019B}","blockID":"i447","enabled":true,"last_modified":1480349206733,"details":{"who":"All Firefox users who have this add-on installed. The add-on can be enabled again in the Add-ons Manager.","created":"2013-09-06T16:00:19Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=788838","name":"My Smart Tabs","why":"This add-on is installed silently, in violation of our Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"40332fae-0444-a141-ade9-8d9e50370f56","schema":1480349193877},{"guid":"crossriderapp8812@crossrider.com","blockID":"i314","enabled":true,"last_modified":1480349206708,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-03-06T14:14:51Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=835665","name":"Coupon Companion","why":"This add-on doesn't follow our Add-on Guidelines, bypassing our third party install opt-in screen. Users who wish to continue using this extension can enable it in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"06c07e28-0a34-e5ee-e724-491a2f6ce586","schema":1480349193877},{"guid":"/^(ffxtlbr@mixidj\\.com|{c0c2693d-2ee8-47b4-9df7-b67a0ee31988}|{67097627-fd8e-4f6b-af4b-ecb65e50112e}|{f6f0f973-a4a3-48cf-9a7a-b7a69c30d71a}|{a3d0e35f-f1da-4ccb-ae77-e9d27777e68d}|{1122b43d-30ee-403f-9bfa-3cc99b0caddd})$/","blockID":"i540","enabled":true,"last_modified":1480349206678,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-01-28T14:07:56Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=963819","name":"MixiDJ (malware)","why":"This add-on has been repeatedly blocked before and keeps showing up with new add-on IDs, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"4c03ddda-bb3f-f097-0a7b-b7b77b050584","schema":1480349193877},{"guid":"hansin@topvest.id","blockID":"i836","enabled":true,"last_modified":1480349206628,"details":{"who":"All Firefox users who have this add-on installed.","created":"2015-02-06T14:17:39Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1130406","name":"Inside News (malware)","why":"This is a malicious add-on that hijacks Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"0945a657-f28d-a02c-01b2-5115b3f90d7a","schema":1480349193877},{"guid":"lfind@nijadsoft.net","blockID":"i358","enabled":true,"last_modified":1480349206603,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-05-24T14:09:47Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=874131","name":"Lyrics Finder","why":"This add-on is silently installed, violating our Add-on Guidelines.\r\n\r\nUsers who wish to continue using this add-on can enable it in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"2307f11c-6216-0dbf-a464-b2921055ce2b","schema":1480349193877},{"guid":"plugin@getwebcake.com","blockID":"i484","enabled":true,"last_modified":1480349206578,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-11-14T09:55:24Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=938264","name":"WebCake","why":"This add-on violates the Add-on Guidelines and is broadly considered to be malware. Users who wish to continue using this add-on can enable it in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"2865addd-da1c-20c4-742f-6a2270da2e78","schema":1480349193877},{"guid":"{c0c2693d-2ee8-47b4-9df7-b67a0ee31988}","blockID":"i354","enabled":true,"last_modified":1480349206525,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-05-23T14:31:21Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=837838","name":"Mixi DJ","why":"This add-on is silently installed, violating our Add-on Guidelines.\r\n\r\nUsers who wish to continue using this add-on can enable it in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"03a745c3-0ee7-e262-ba31-62d4f78ddb62","schema":1480349193877},{"guid":"/^({7316e43a-3ebd-4bb4-95c1-9caf6756c97f}|{0cc09160-108c-4759-bab1-5c12c216e005}|{ef03e721-f564-4333-a331-d4062cee6f2b}|{465fcfbb-47a4-4866-a5d5-d12f9a77da00}|{7557724b-30a9-42a4-98eb-77fcb0fd1be3}|{b7c7d4b0-7a84-4b73-a7ef-48ef59a52c3b})$/","blockID":"i520","enabled":true,"last_modified":1480349206491,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-12-20T13:11:46Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=947485","name":"appbario7","why":"The installer that includes this add-on violates the Add-on Guidelines by being silently installed and using multiple add-on IDs."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"e3901c48-9c06-fecb-87d3-efffd9940c22","schema":1480349193877},{"guid":"{354dbb0a-71d5-4e9f-9c02-6c88b9d387ba}","blockID":"i538","enabled":true,"last_modified":1480349206465,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-01-27T10:13:17Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=964081","name":"Show Mask ON (malware)","why":"This is a malicious add-on that hijacks Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"aad90253-8921-b5df-3658-45a70d75f3d7","schema":1480349193877},{"guid":"{8E9E3331-D360-4f87-8803-52DE43566502}","blockID":"i461","enabled":true,"last_modified":1480349206437,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-10-17T16:10:51Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=906071","name":"Updater By SweetPacks","why":"This is a companion add-on for the SweetPacks Toolbar which is blocked due to guideline violations."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"ae8cca6e-4258-545f-9a69-3d908264a701","schema":1480349193877},{"guid":"info@bflix.info","blockID":"i172","enabled":true,"last_modified":1480349206384,"details":{"who":"All Firefox users who have this add-on installed.","created":"2012-10-30T13:39:22Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=806802","name":"Bflix (malware)","why":"These are malicious add-ons that are distributed with a trojan and negatively affect web browsing."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"7a9062f4-218d-51d2-9b8c-b282e6eada4f","schema":1480349193877},{"guid":"{dff137ae-1ffd-11e3-8277-b8ac6f996f26}","blockID":"i450","enabled":true,"last_modified":1480349206312,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-09-18T16:19:34Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=917861","name":"Addons Engine (malware)","why":"This is add-on is malware that silently redirects popular search queries to a third party."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"8e583fe4-1c09-9bea-2473-faecf3260685","schema":1480349193877},{"guid":"12x3q@3244516.com","blockID":"i493","enabled":true,"last_modified":1480349206286,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-12-02T12:49:36Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=939254","name":"BetterSurf (malware)","why":"This add-on appears to be malware and is installed silently in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"af2a9e74-3753-9ff1-d899-5d1e79ed3dce","schema":1480349193877},{"guid":"{20AD702C-661E-4534-8CE9-BA4EC9AD6ECC}","blockID":"i626","enabled":true,"last_modified":1480349206261,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-06-19T15:16:38Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1027886","name":"V-Bates","why":"This add-on is probably silently installed, and is causing significant stability issues for users, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"9b9ccabe-8f9a-e3d1-a689-1aefba1f33b6","schema":1480349193877},{"guid":"{c5e48979-bd7f-4cf7-9b73-2482a67a4f37}","blockID":"i736","enabled":true,"last_modified":1480349206231,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2014-10-17T15:22:41Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1080842","name":"ClearThink","why":"This add-on is silently installed into users' systems, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"6e8b3e4f-2f59-cde3-e6d2-5bc6e216c506","schema":1480349193877},{"guid":"{41339ee8-61ed-489d-b049-01e41fd5d7e0}","blockID":"i810","enabled":true,"last_modified":1480349206165,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-12-23T10:32:26Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1073810","name":"FireWeb","why":"This add-on is silently installed into users' systems. It uses very unsafe practices to load its code, and leaks information of all web browsing activity. These are all violations of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"a35f2ca6-aec4-c01d-170e-650258ebcd2c","schema":1480349193877},{"guid":"jid0-l9BxpNUhx1UUgRfKigWzSfrZqAc@jetpack","blockID":"i640","enabled":true,"last_modified":1480349206133,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-07-09T14:35:40Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1036640","name":"Bitcoin Mining Software","why":"This add-on attempts to gather private user data and send it to a remote location. It doesn't appear to be very effective at it, but its malicious nature is undeniable."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"8fe3c35e-1a6f-a89a-fa96-81bda3b71db1","schema":1480349193877},{"guid":"{845cab51-d8d2-472f-8bd9-2b44642d97c2}","blockID":"i460","enabled":true,"last_modified":1480349205746,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-10-17T15:50:38Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=927456","name":"Vafmusic9","why":"This add-on is silently installed and handles users' settings, violating some of the Add-on Guidelines. Users who wish to continue using this add-on can enable it in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"8538ccb4-3b71-9858-3f6d-c0fff7af58b0","schema":1480349193877},{"guid":"SpecialSavings@SpecialSavings.com","blockID":"i676","enabled":true,"last_modified":1480349205688,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using this add-on can enable it in the Add-ons Manager.","created":"2014-07-22T16:31:56Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=881511","name":"SpecialSavings","why":"This is add-on is generally considered to be unwanted and is probably silently installed, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"5e921810-fc3a-0729-6749-47e38ad10a22","schema":1480349193877},{"guid":"afurladvisor@anchorfree.com","blockID":"i434","enabled":true,"last_modified":1480349205645,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-08-09T11:26:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=844945","name":"Hotspot Shield Helper","why":"This add-on bypasses the external install opt in screen in Firefox, violating the Add-on Guidelines. Users who wish to continue using this add-on can enable it in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"083585eb-d7e7-e228-5fbf-bf35c52044e4","schema":1480349193877},{"guid":"addonhack@mozilla.kewis.ch","blockID":"i994","enabled":true,"last_modified":1480349205584,"details":{"who":"All users who have this add-on installed.","created":"2015-09-01T15:32:36Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1200848","name":"Addon Hack","why":"This add-on is a proof of concept of malicious behavior in an add-on. In itself it doesn't cause any harm, but it still needs to be blocked for security reasons."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"81f75571-ca2a-0e50-a925-daf2037ce63c","schema":1480349193877},{"guid":"info@thebflix.com","blockID":"i174","enabled":true,"last_modified":1480349205526,"details":{"who":"All Firefox users who have these add-ons installed.","created":"2012-10-30T13:40:31Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=806802","name":"Bflix (malware)","why":"These are malicious add-ons that are distributed with a trojan and negatively affect web browsing."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"811a61d4-9435-133e-6262-fb72486c36b0","schema":1480349193877},{"guid":"{EEE6C361-6118-11DC-9C72-001320C79847}","blockID":"i392","enabled":true,"last_modified":1480349205455,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-06-25T12:38:45Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=881447","name":"SweetPacks Toolbar","why":"This add-on changes search settings without user interaction, and fails to reset them after it is removed. This violates our Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"c1dc6607-4c0a-4031-9f14-70ef1ae1edcb","schema":1480349193877},{"guid":"/^(4cb61367-efbf-4aa1-8e3a-7f776c9d5763@cdece6e9-b2ef-40a9-b178-291da9870c59\\.com|0efc9c38-1ec7-49ed-8915-53a48b6b7600@e7f17679-2a42-4659-83c5-7ba961fdf75a\\.com|6be3335b-ef79-4b0b-a0ba-b87afbc6f4ad@6bbb4d2e-e33e-4fa5-9b37-934f4fb50182\\.com)$/","blockID":"i531","enabled":true,"last_modified":1480349205287,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-12-20T15:01:22Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=949672","name":"Feven","why":"The installer that includes this add-on violates the Add-on Guidelines by making changes that can't be easily reverted and using multiple IDs."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"46aa79a9-d329-f713-d4f2-07d31fe7071e","schema":1480349193877},{"guid":"afext@anchorfree.com","blockID":"i466","enabled":true,"last_modified":1480349205108,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-11-07T13:32:41Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=933988","name":"Hotspot Shield Extension","why":"This add-on doesn't respect user choice, violating the Add-on Guidelines. Users who wish to continue using this add-on can enable it in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"8176f879-bd73-5468-e908-2d7cfc115ac2","schema":1480349193877},{"guid":"{FCE04E1F-9378-4f39-96F6-5689A9159E45}","blockID":"i920","enabled":true,"last_modified":1480349204978,"details":{"who":"All Firefox users who have this add-on installed in Firefox 39 and above.\r\n","created":"2015-06-09T15:26:47Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1173154","name":"RealPlayer Browser Record Plugin","why":"Certain versions of this extension are causing startup crashes in Firefox 39 and above.\r\n"},"versionRange":[{"targetApplication":[{"minVersion":"39.0a1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"}],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"eb191ff0-20f4-6e04-4344-d880af4faf51","schema":1480349193877},{"guid":"{9CE11043-9A15-4207-A565-0C94C42D590D}","blockID":"i503","enabled":true,"last_modified":1480349204951,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-12-06T11:58:38Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=947384","name":"XUL Cache (malware)","why":"This is a malicious extension that uses a deceptive name to stay in users' systems."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"dcdae267-8d3a-5671-dff2-f960febbbb20","schema":1480349193877},{"guid":"/^[a-z0-9]+@foxysecure[a-z0-9]*\\.com$/","blockID":"i766","enabled":true,"last_modified":1480349204925,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using this add-on can enable it in the Add-ons Manager.","created":"2014-10-30T14:22:18Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1088615","name":"Fox Sec 7","why":"This add-on is silently installed into users' systems, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"503fbd7c-04cd-65f3-9d0e-3ecf427b4a8f","schema":1480349193877},{"guid":"/^(jid1-W4CLFIRExukJIFW@jetpack|jid1-W4CLFIRExukJIFW@jetpack_1|jid1-W3CLwrP[a-z]+@jetpack)$/","blockID":"i1078","enabled":true,"last_modified":1480349204899,"details":{"who":"All Firefox users who have this add-on installed.","created":"2016-01-18T10:31:51Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1240561","name":"Adobe Flash Player (malware)","why":"This is a malicious extension that tries to pass itself for the Adobe Flash Player and hides itself in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"b026fe67-ec77-a240-2fa1-e78f581a6fe4","schema":1480349193877},{"guid":"{0153E448-190B-4987-BDE1-F256CADA672F}","blockID":"i914","enabled":true,"last_modified":1480349204871,"details":{"who":"All Firefox users who have this add-on installed in Firefox 39 and above.","created":"2015-06-02T09:56:58Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1170633","name":"RealPlayer Browser Record Plugin","why":"Certain versions of this extension are causing startup crashes in Firefox 39 and above."},"versionRange":[{"targetApplication":[{"minVersion":"39.0a1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"}],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"2bfe0d89-e458-9d0e-f944-ddeaf8c4db6c","schema":1480349193877},{"guid":"{77beece6-3997-403a-92fa-0055bfcf88e5}","blockID":"i452","enabled":true,"last_modified":1480349204844,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-09-18T16:34:58Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=916966","name":"Entrusted11","why":"This add-on doesn't follow our Add-on Guidelines, manipulating settings without reverting them on removal. Users who wish to continue using this add-on can enable it in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"d348f91f-caeb-a803-dfd9-fd5d285aa0fa","schema":1480349193877},{"guid":"dealcabby@jetpack","blockID":"i222","enabled":true,"last_modified":1480349204818,"details":{"who":"All Firefox users who have this add-on installed.","created":"2012-11-29T16:20:24Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=811435","name":"DealCabby","why":"This add-on is silently side-installed with other software, injecting advertisements in Firefox."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"6585f0bd-4f66-71e8-c565-d9762c5c084a","schema":1480349193877},{"guid":"{3c9a72a0-b849-40f3-8c84-219109c27554}","blockID":"i510","enabled":true,"last_modified":1480349204778,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-12-17T14:27:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=951301","name":"Facebook Haber (malware)","why":"This add-on is malware that hijacks users' Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"7cfa3d0b-0ab2-5e3a-8143-1031c180e32f","schema":1480349193877},{"guid":"{4ED1F68A-5463-4931-9384-8FFF5ED91D92}","blockID":"i1245","enabled":true,"last_modified":1480349204748,"details":{"who":"All users who have McAfee SiteAdvisor lower than 4.0. \r\n\r\nTo resolve this issue, users will need to uninstall McAfee SiteAdvisor/WebAdvisor, reboot the computer, and then reinstall McAfee SiteAdvisor/WebAdvisor. \r\n\r\nFor detailed instructions, please refer to the McAfee support knowledge base.","created":"2016-07-14T21:24:02Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1286368","name":"McAfee SiteAdvisor lower than 4.0","why":"Old versions of McAfee SiteAdvisor cause startup crashes starting with Firefox 48.0 beta."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"3.9.9","severity":1}],"prefs":[],"id":"d727d8c5-3329-c98a-7c7e-38b0813ca516","schema":1480349193877},{"guid":"{2aab351c-ad56-444c-b935-38bffe18ad26}","blockID":"i500","enabled":true,"last_modified":1480349204716,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-12-04T15:29:44Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=946087","name":"Adobe Photo (malware)","why":"This is a malicious Firefox extension that uses a deceptive name and hijacks users' Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"f7a76d34-ddcd-155e-9fae-5967bd796041","schema":1480349193877},{"guid":"jid1-4P0kohSJxU1qGg@jetpack","blockID":"i488","enabled":true,"last_modified":1480349204668,"details":{"who":"All Firefox users who have version 1.2.50 of the Hola extension. Updating to the latest version should remove the block.","created":"2013-11-25T12:14:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=942935","name":"Hola, version 1.2.50","why":"Version 1.2.50 of the Hola extension is causing frequent crashes in Firefox. All users are strongly recommended to update to the latest version, which shouldn't have this problem."},"versionRange":[{"targetApplication":[],"minVersion":"1.2.50","maxVersion":"1.2.50","severity":1}],"prefs":[],"id":"5c7f1635-b39d-4278-5f95-9042399c776e","schema":1480349193877},{"guid":"{0A92F062-6AC6-8180-5881-B6E0C0DC2CC5}","blockID":"i864","enabled":true,"last_modified":1480349204612,"details":{"who":"All users who have this add-on installed. Users who wish to continue using the add-on can enable it in the Add-ons Manager.","created":"2015-02-26T12:56:19Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1131220","name":"BlockAndSurf","why":"This add-on is silently installed into users' systems and makes unwanted settings changes, in violation of our Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":["browser.startup.homepage","browser.search.defaultenginename"],"id":"acb16d1c-6274-93a3-7c1c-7ed36ede64a9","schema":1480349193877},{"guid":"jid0-Y6TVIzs0r7r4xkOogmJPNAGFGBw@jetpack","blockID":"i322","enabled":true,"last_modified":1480349204532,"details":{"who":"All users who have this add-on installed.","created":"2013-03-22T14:39:40Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=847018","name":"Flash Player (malware)","why":"This extension is malware, installed pretending to be the Flash Player plugin."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"54df22cd-19ce-a7f0-63cc-ffe3113748b9","schema":1480349193877},{"guid":"trackerbird@bustany.org","blockID":"i986","enabled":true,"last_modified":1480349204041,"details":{"who":"All Thunderbird users who have this version of the add-on installed on Thunderbird 38.0a2 and above.","created":"2015-08-17T15:56:04Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1189264","name":"trackerbird 1.2.6","why":"This add-on is causing consistent crashes on Thunderbird 38.0a2 and above."},"versionRange":[{"targetApplication":[{"minVersion":"38.0a2","guid":"{3550f703-e582-4d05-9a08-453d09bdfdc6}","maxVersion":"*"}],"minVersion":"1.2.6","maxVersion":"1.2.6","severity":1}],"prefs":[],"id":"bb1c699e-8790-4528-0b6d-4f83b7a3152d","schema":1480349193877},{"guid":"{0134af61-7a0c-4649-aeca-90d776060cb3}","blockID":"i448","enabled":true,"last_modified":1480349203968,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-09-13T16:15:39Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=912746","name":"KeyBar add-on","why":"This add-on doesn't follow our Add-on Guidelines. It manipulates settings without reverting them on removal. Users who wish to continue using this add-on can enable it in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"cf428416-4974-8bb4-7928-c0cb2cfe7957","schema":1480349193877},{"guid":"/^(firefox@vebergreat\\.net|EFGLQA@78ETGYN-0W7FN789T87\\.COM)$/","blockID":"i564","enabled":true,"last_modified":1480349203902,"details":{"who":"All Firefox users who have these add-ons installed. If you wish to continue using these add-ons, you can enable them in the Add-ons Manager.","created":"2014-03-05T13:02:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=974104","name":"veberGreat and vis (Free Driver Scout bundle)","why":"These add-ons are silently installed by the Free Driver Scout installer, in violation of our Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"487538f1-698e-147e-6395-986759ceed7e","schema":1480349193877},{"guid":"69ffxtbr@PackageTracer_69.com","blockID":"i882","enabled":true,"last_modified":1480349203836,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2015-04-10T16:18:35Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1153001","name":"PackageTracer","why":"This add-on appears to be malware, hijacking user's settings, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":["browser.startup.homepage","browser.search.defaultenginename"],"id":"0d37b4e0-3c60-fdad-dd8c-59baff6eae87","schema":1480349193877},{"guid":"{ACAA314B-EEBA-48e4-AD47-84E31C44796C}","blockID":"i496","enabled":true,"last_modified":1480349203779,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-12-03T16:07:59Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=945530","name":"DVDVideoSoft Menu","why":"The installer that includes this add-on violates the Add-on Guidelines by making settings changes that can't be easily reverted."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"70d2c912-8d04-8065-56d6-d793b13d5f67","schema":1480349193877},{"guid":"jid1-4vUehhSALFNqCw@jetpack","blockID":"i632","enabled":true,"last_modified":1480349203658,"details":{"who":"All Firefox users who have this version of the add-on installed.","created":"2014-07-01T13:16:55Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1033002","name":"YouTube Plus Plus 100.7","why":"Version 100.7 of the YouTube Plus Plus extension isn't developed by the original developer, and is likely malicious in nature. It violates the Add-on Guidelines for reusing an already existent ID."},"versionRange":[{"targetApplication":[],"minVersion":"100.7","maxVersion":"100.7","severity":3}],"prefs":[],"id":"8bef6026-6697-99cd-7c1f-812877c4211d","schema":1480349193877},{"guid":"{a9bb9fa0-4122-4c75-bd9a-bc27db3f9155}","blockID":"i404","enabled":true,"last_modified":1480349203633,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-06-25T15:16:43Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=835678","name":"Searchqu","why":"This group of add-ons is silently installed, bypassing our install opt-in screen. This violates our Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"fb7a1dc7-16a0-4f70-8289-4df494e0d0fa","schema":1480349193877},{"guid":"P2@D.edu","blockID":"i850","enabled":true,"last_modified":1480349203605,"details":{"who":"All Firefox users who have this add-on installed.","created":"2015-02-09T15:29:21Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1128269","name":"unIsaless","why":"This add-on is silently installed and performs unwanted actions, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"49536a29-fc7e-9fd0-f415-e15ac090fa56","schema":1480349193877},{"guid":"linksicle@linksicle.com","blockID":"i472","enabled":true,"last_modified":1480349203581,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-11-07T15:38:38Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=935779","name":"Installer bundle (malware)","why":"This add-on is part of a malicious Firefox installer bundle."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"9b5b15b3-6da7-cb7c-3c44-30b4fe079d52","schema":1480349193877},{"guid":"{377e5d4d-77e5-476a-8716-7e70a9272da0}","blockID":"i398","enabled":true,"last_modified":1480349203519,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-06-25T15:15:46Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=835678","name":"Searchqu","why":"This group of add-ons is silently installed, bypassing our install opt-in screen. This violates our Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"ea94df32-2a85-23da-43f7-3fc5714530ec","schema":1480349193877},{"guid":"{4933189D-C7F7-4C6E-834B-A29F087BFD23}","blockID":"i437","enabled":true,"last_modified":1480349203486,"details":{"who":"All Firefox users.","created":"2013-08-09T15:14:27Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=900695","name":"Win32.SMSWebalta (malware)","why":"This add-on is widely reported to be malware."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"cbef1357-d6bc-c8d3-7a82-44af6b1c390f","schema":1480349193877},{"guid":"{ADFA33FD-16F5-4355-8504-DF4D664CFE10}","blockID":"i306","enabled":true,"last_modified":1480349203460,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using this add-on can enable it in the Add-ons Manager.","created":"2013-02-28T12:56:48Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=844972","name":"Nation Toolbar","why":"This add-on is silently installed, bypassing our third-party opt-in screen, in violation of our Add-on Guidelines. It's also possible that it changes user settings without their consent."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"017fd151-37ca-4646-4763-1d303fb918fa","schema":1480349193877},{"guid":"detgdp@gmail.com","blockID":"i884","enabled":true,"last_modified":1480349203433,"details":{"who":"All Firefox users who have this add-on installed.","created":"2015-04-10T16:21:34Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1152614","name":"Security Protection (malware)","why":"This add-on appears to be malware, hijacking user settings, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":["browser.startup.homepage","browser.search.defaultenginename"],"id":"1b5cc88e-499d-2a47-d793-982d4c05e6ee","schema":1480349193877},{"guid":"/^(67314b39-24e6-4f05-99f3-3f88c7cddd17@6c5fa560-13a3-4d42-8e90-53d9930111f9\\.com|ffxtlbr@visualbee\\.com|{7aeae561-714b-45f6-ace3-4a8aed6e227b}|{7093ee04-f2e4-4637-a667-0f730797b3a0}|{53c4024f-5a2e-4f2a-b33e-e8784d730938})$/","blockID":"i514","enabled":true,"last_modified":1480349203408,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-12-20T12:25:50Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=947473","name":"VisualBee Toolbar","why":"The installer that includes this add-on violates the Add-on Guidelines by using multiple add-on IDs and making unwanted settings changes."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"5f91eee1-7303-3f97-dfe6-1e897a156c7f","schema":1480349193877},{"guid":"FXqG@xeeR.net","blockID":"i720","enabled":true,"last_modified":1480349203341,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2014-10-02T12:23:01Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1076771","name":"GoSSave","why":"This add-on is silently installed into users' systems and changes settings without consent, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":["browser.startup.homepage"],"id":"8ebbc061-a4ff-b75b-ec42-eb17c42a2956","schema":1480349193877},{"guid":"{87934c42-161d-45bc-8cef-ef18abe2a30c}","blockID":"i547","enabled":true,"last_modified":1480349203310,"details":{"who":"All Firefox users who have this add-on installed. If you wish to continue using it, it can be enabled in the Add-ons Manager.","created":"2014-01-30T12:42:01Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=798621","name":"Ad-Aware Security Toolbar","why":"This add-on is silently installed and makes various unwanted changes, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"3.7.9999999999","severity":1}],"prefs":[],"id":"bcfbc502-24c2-4699-7435-e4837118f05a","schema":1480349193877},{"guid":"kallow@facebook.com","blockID":"i495","enabled":true,"last_modified":1480349203247,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-12-02T15:09:42Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=945426","name":"Facebook Security Service (malware)","why":"This is a malicious Firefox extension that uses a deceptive name and hijacks users' Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"1a2c37a9-e7cc-2d03-2043-098d36b8aca2","schema":1480349193877},{"guid":"support@lastpass.com","blockID":"i1261","enabled":true,"last_modified":1480349203208,"details":{"who":"All users who install affected versions of this add-on - beta versions 4.0 to 4.1.20a from addons.mozilla.org or lastpass.com.","created":"2016-07-29T14:17:31Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1289907","name":"LastPass addon","why":"LastPass have announced there are security issues that would allow a malicious website to perform some actions (e.g. deleting passwords) without the user's knowledge. Beta versions 4.0 to 4.1.20a of their add-on that were available from addons.mozilla.org are affected and Lastpass also distributed these versions direct from their website."},"versionRange":[{"targetApplication":[],"minVersion":"4.0.0a","maxVersion":"4.1.20a","severity":1}],"prefs":[],"id":"ffe94023-b4aa-87ac-962c-5beabe34b1a0","schema":1480349193877},{"guid":"008abed2-b43a-46c9-9a5b-a771c87b82da@1ad61d53-2bdc-4484-a26b-b888ecae1906.com","blockID":"i528","enabled":true,"last_modified":1480349203131,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-12-20T14:40:58Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=949565","name":"weDownload Manager Pro","why":"The installer that includes this add-on violates the Add-on Guidelines by being silently installed."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"da46065f-1c68-78f7-80fc-8ae07b5df68d","schema":1480349193877},{"guid":"{25dd52dc-89a8-469d-9e8f-8d483095d1e8}","blockID":"i714","enabled":true,"last_modified":1480349203066,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-10-01T15:36:06Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1073810","name":"Web Counselor","why":"This add-on is silently installed into users' systems. It uses very unsafe practices to load its code, and leaks information of all web browsing activity. These are all violations of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"e46c31ad-0ab3-e48a-47aa-9fa91b675fda","schema":1480349193877},{"guid":"{B1FC07E1-E05B-4567-8891-E63FBE545BA8}","blockID":"i926","enabled":true,"last_modified":1480349202708,"details":{"who":"All Firefox users who have this add-on installed in Firefox 39 and above.\r\n","created":"2015-06-09T15:28:46Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1173154","name":"RealPlayer Browser Record Plugin","why":"Certain versions of this extension are causing startup crashes in Firefox 39 and above.\r\n"},"versionRange":[{"targetApplication":[{"minVersion":"39.0a1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"}],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"09868783-261a-ac24-059d-fc772218c1ba","schema":1480349193877},{"guid":"/^(torntv@torntv\\.com|trtv3@trtv\\.com|torntv2@torntv\\.com|e2fd07a6-e282-4f2e-8965-85565fcb6384@b69158e6-3c3b-476c-9d98-ae5838c5b707\\.com)$/","blockID":"i529","enabled":true,"last_modified":1480349202677,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-12-20T14:46:03Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=949559","name":"TornTV","why":"The installer that includes this add-on violates the Add-on Guidelines by being silently installed."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"040e5ec2-ea34-816a-f99f-93296ce845e8","schema":1480349193877},{"guid":"249911bc-d1bd-4d66-8c17-df533609e6d8@c76f3de9-939e-4922-b73c-5d7a3139375d.com","blockID":"i532","enabled":true,"last_modified":1480349202631,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-12-20T15:02:01Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=949672","name":"Feven","why":"The installer that includes this add-on violates the Add-on Guidelines by making changes that can't be easily reverted and using multiple IDs."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"d32b850d-82d5-b63d-087c-fb2041b2c232","schema":1480349193877},{"guid":"thefoxonlybetter@quicksaver","blockID":"i704","enabled":true,"last_modified":1480349202588,"details":{"who":"All Firefox users who have any of these versions of the add-on installed.","created":"2014-08-27T14:49:02Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1053469","name":"The Fox, Only Better (malicious versions)","why":"Certain versions of The Fox, Only Better weren't developed by the original developer, and are likely malicious in nature. This violates the Add-on Guidelines for reusing an already existent ID."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"0.*","severity":3}],"prefs":[],"id":"79ea6621-b414-17a4-4872-bfc4af7fd428","schema":1480349193877},{"guid":"{B40794A0-7477-4335-95C5-8CB9BBC5C4A5}","blockID":"i429","enabled":true,"last_modified":1480349202541,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-07-30T14:31:17Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=899178","name":"Video Player 1.3 (malware)","why":"This add-on is malware that spreads spam through Facebook."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"d98b2b76-4082-3387-ae33-971d973fa278","schema":1480349193877},{"guid":"firefoxaddon@youtubeenhancer.com","blockID":"i648","enabled":true,"last_modified":1480349202462,"details":{"who":"All Firefox users who have this version of the add-on installed.","created":"2014-07-10T15:12:48Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1036757","name":"YouTube Enhancer Plus, versions between 199.7.0 and 208.7.0","why":"Certain versions of the YouTube Enhancer Plus extension weren't developed by the original developer, and are likely malicious in nature. This violates the Add-on Guidelines for reusing an already existent ID."},"versionRange":[{"targetApplication":[],"minVersion":"199.7.0","maxVersion":"208.7.0","severity":3}],"prefs":[],"id":"7e64d7fc-ff16-8687-dbd1-bc4c7dfc5097","schema":1480349193877},{"guid":"addon@defaulttab.com","blockID":"i362","enabled":true,"last_modified":1480349202429,"details":{"who":"All users who have this add-on installed. Users who wish to enable it again can do so in the Add-ons Manager tab.","created":"2013-06-06T12:57:29Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=863387","name":"Default Tab","why":"Old versions of this add-on had been silently installed into users' systems, without showing the opt-in install page that is built into Firefox."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"1.4.4","severity":1}],"prefs":[],"id":"df3fe753-5bae-bfb4-022b-6b6bfc534937","schema":1480349193877},{"guid":"{7D4F1959-3F72-49d5-8E59-F02F8AA6815D}","blockID":"i394","enabled":true,"last_modified":1480349202341,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-06-25T12:40:41Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=881447","name":"Updater By SweetPacks","why":"This is a companion add-on for the SweetPacks Toolbar which is blocked due to guideline violations."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"851c2b8e-ea19-3a63-eac5-f931a8da5d6e","schema":1480349193877},{"guid":"g@uzcERQ6ko.net","blockID":"i776","enabled":true,"last_modified":1480349202307,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2014-10-31T16:23:36Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1076771","name":"GoSave","why":"This add-on is silently installed and changes user settings without consent, in violation of the Add-on Guidelines"},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":["browser.startup.homepage","browser.search.defaultenginename"],"id":"ee1e1a44-b51b-9f12-819d-64c3e515a147","schema":1480349193877},{"guid":"ffxtlbr@incredibar.com","blockID":"i318","enabled":true,"last_modified":1480349202280,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-03-20T14:40:32Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=812264","name":"IncrediBar","why":"This add-on doesn't follow our Add-on Guidelines, bypassing our third party install opt-in screen. Users who wish to continue using this extension can enable it in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"9e84b07c-84d5-c932-85f2-589713d7e380","schema":1480349193877},{"guid":"M1uwW0@47z8gRpK8sULXXLivB.com","blockID":"i870","enabled":true,"last_modified":1480349202252,"details":{"who":"All users who have this add-on installed.","created":"2015-03-04T14:34:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1131159","name":"Flash Player 11 (malware)","why":"This is a malicious add-on that goes by the the name \"Flash Player 11\"."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"71d961b2-37d1-d393-76f5-3afeef57e749","schema":1480349193877},{"guid":"jid1-qj0w91o64N7Eeg@jetpack","blockID":"i650","enabled":true,"last_modified":1480349202186,"details":{"who":"All Firefox users who have this version of the add-on installed.","created":"2014-07-10T15:14:26Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1036757","name":"YouTube ALL HTML5, versions between 39.5.1 and 47.0.4","why":"Certain versions of the YouTube ALL HTML5 extension weren't developed by the original developer, and are likely malicious in nature. This violates the Add-on Guidelines for reusing an already existent ID."},"versionRange":[{"targetApplication":[],"minVersion":"39.5.1","maxVersion":"47.0.4","severity":3}],"prefs":[],"id":"b30b1f7a-2a30-a6cd-fc20-6c9cb23c7198","schema":1480349193877},{"guid":"4zffxtbr-bs@VideoDownloadConverter_4z.com","blockID":"i507","enabled":true,"last_modified":1480349202156,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-12-12T15:37:23Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=949266","name":"VideoDownloadConverter","why":"Certain versions of this add-on contains an executable that is flagged by multiple tools as malware. Newer versions no longer use it."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"5.75.3.25126","severity":1}],"prefs":[],"id":"0a0f106a-ecc6-c537-1818-b36934943e91","schema":1480349193877},{"guid":"hdv@vovcacik.addons.mozilla.org","blockID":"i656","enabled":true,"last_modified":1480349202125,"details":{"who":"All Firefox users who have this version of the add-on installed.","created":"2014-07-10T15:22:59Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1036757","name":"High Definition Video, version 102.0","why":"Certain versions of the High Definition Video extension weren't developed by the original developer, and are likely malicious in nature. This violates the Add-on Guidelines for reusing an already existent ID."},"versionRange":[{"targetApplication":[],"minVersion":"102.0","maxVersion":"102.0","severity":3}],"prefs":[],"id":"972249b2-bba8-b508-2ead-c336631135ac","schema":1480349193877},{"guid":"@video_downloader_pro","blockID":"i1265","enabled":true,"last_modified":1480349202099,"details":{"who":"Users of versions of 1.2.1 to 1.2.5 inclusive.","created":"2016-08-26T18:26:39Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1298335","name":"Video Downloader Pro","why":"Versions 1.2.1 to 1.2.5 of Video Downloader Pro included code that violated our polices - affected versions send every visited url to a remote server without the user's consent. Versions older than 1.2.1 and more recent than 1.2.5 are okay."},"versionRange":[{"targetApplication":[],"minVersion":"1.2.1","maxVersion":"1.2.5","severity":1}],"prefs":[],"id":"ff9c8def-7d50-66b4-d42a-f9a4b04bd224","schema":1480349193877},{"guid":"contato@facefollow.net","blockID":"i509","enabled":true,"last_modified":1480349202067,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-12-16T16:15:15Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=950846","name":"Face follow","why":"This add-on spams users' Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"56f15747-af8c-342c-6877-a41eeacded84","schema":1480349193877},{"guid":"wecarereminder@bryan","blockID":"i666","enabled":true,"last_modified":1480349202039,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2014-07-10T16:18:36Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=818614","name":"We-Care Reminder","why":"This add-on is being silently installed by various software packages, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"51e0ead7-144c-c1f4-32f2-25fc5fcde870","schema":1480349193877},{"guid":"/^({83a8ce1b-683c-4784-b86d-9eb601b59f38}|{ef1feedd-d8da-4930-96f1-0a1a598375c6}|{79ff1aae-701f-4ca5-aea3-74b3eac6f01b}|{8a184644-a171-4b05-bc9a-28d75ffc9505}|{bc09c55d-0375-4dcc-836e-0e3c8addfbda}|{cef81415-2059-4dd5-9829-1aef3cf27f4f})$/","blockID":"i526","enabled":true,"last_modified":1480349202010,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-12-20T14:12:31Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=949566","name":"KeyBar add-on","why":"The installer that includes this add-on violates the Add-on Guidelines by making changes that can't be easily reverted and uses multiple IDs."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"9dfa4e92-bbf2-66d1-59a9-51402d1d226c","schema":1480349193877},{"guid":"{d9284e50-81fc-11da-a72b-0800200c9a66}","blockID":"i806","enabled":true,"last_modified":1480349201976,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable the add-on in the Add-on Manager.","created":"2014-12-16T08:35:41Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1106948","name":"Yoono","why":"Starting with Firefox 34, current versions of the Yoono add-on cause all tabs to appear blank."},"versionRange":[{"targetApplication":[{"minVersion":"34.0a1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"}],"minVersion":"0","maxVersion":"7.7.34","severity":1}],"prefs":[],"id":"ccdceb04-3083-012f-9d9f-aac85f10b494","schema":1480349193877},{"guid":"{f2548724-373f-45fe-be6a-3a85e87b7711}","blockID":"i768","enabled":true,"last_modified":1480349201854,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-10-30T14:52:09Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1088726","name":"Astro New Tab","why":"This add-on is silently installed and is considered malware, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":["browser.startup.homepage","browser.search.defaultenginename"],"id":"8510e9e2-c7d8-90d0-a2ff-eb09293acc6e","schema":1480349193877},{"guid":"KSqOiTeSJEDZtTGuvc18PdPmYodROmYzfpoyiCr2@jetpack","blockID":"i1032","enabled":true,"last_modified":1480349201504,"details":{"who":"All users who have this add-on installed.","created":"2015-10-05T16:22:58Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1211172","name":"Video Player (malware)","why":"This is a malicious add-on that hijacks Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"3d9188ac-235f-773a-52a2-261b3ea9c03c","schema":1480349193877},{"guid":"{849ded12-59e9-4dae-8f86-918b70d213dc}","blockID":"i708","enabled":true,"last_modified":1480349201453,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2014-09-02T16:29:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1047102","name":"Astromenda New Tab","why":"This add-on is silently installed and changes homepage and search settings without the user's consent, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":["browser.startup.homepage","browser.search.defaultenginename"],"id":"a319bfee-464f-1c33-61ad-738c52842fbd","schema":1480349193877},{"guid":"grjkntbhr@hgergerherg.com","blockID":"i1018","enabled":true,"last_modified":1480349201425,"details":{"who":"All users who have this add-on installed.","created":"2015-09-24T16:04:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1208196","name":"GreenPlayer (malware)","why":"This is a malicious add-on that hijacks Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"9c47d940-bdd9-729f-e32e-1774d87f24b5","schema":1480349193877},{"guid":"quick_start@gmail.com","blockID":"i588","enabled":true,"last_modified":1480349201398,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-06-03T15:53:15Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1011316","name":"Quick Start (malware)","why":"This add-on appears to be malware that is installed without user consent."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"2affbebe-8776-3edb-28b9-237cb8b85f97","schema":1480349193877},{"guid":"/^(matchersite(pro(srcs?)?)?\\@matchersite(pro(srcs?)?)?\\.com)|((pro)?sitematcher(_srcs?|pro|site|sitesrc|-generic)?\\@(pro)?sitematcher(_srcs?|pro|site|sitesrc|-generic)?\\.com)$/","blockID":"i668","enabled":true,"last_modified":1480349201372,"details":{"who":"All Firefox users who have any of these add-ons installed. User who wish to continue using these add-ons can enable them in the Add-ons Manager.","created":"2014-07-17T14:35:14Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1039892","name":"Site Matcher","why":"This is a group of add-ons that are being distributed under multiple different IDs and likely being silently installed, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"52e1a2de-ab35-be27-4810-334f681ccc4a","schema":1480349193877},{"guid":"{EEF73632-A085-4fd3-A778-ECD82C8CB297}","blockID":"i165","enabled":true,"last_modified":1480349201262,"details":{"who":"All Firefox users who have these add-ons installed.","created":"2012-10-29T16:41:06Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=806451","name":"Codec-M (malware)","why":"These are malicious add-ons that are distributed with a trojan and negatively affect web browsing."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"e5ecd02a-20ee-749b-d5cf-3d74d1173a1f","schema":1480349193877},{"guid":"firefox-extension@mozilla.org","blockID":"i688","enabled":true,"last_modified":1480349201235,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-08-06T17:13:00Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1049533","name":"FinFisher (malware)","why":"This is a malicious add-on that hides itself under the name Java_plugin, among others."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"98aca74a-69c7-9960-cccc-096a4a4adc6c","schema":1480349193877},{"guid":"jid1-vW9nopuIAJiRHw@jetpack","blockID":"i570","enabled":true,"last_modified":1480349201204,"details":{"who":"All Firefox users who have this add-on installed. Those who wish to continue using it can enable it in the Add-ons Manager.","created":"2014-03-31T16:17:27Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=990291","name":"SmileysWeLove","why":"This add-on is silently installed, reverts settings changes to enforce its own, and is also causing stability problems in Firefox, all in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"bf2abd66-f910-650e-89aa-cd1d5c2f8a89","schema":1480349193877},{"guid":"87aukfkausiopoawjsuifhasefgased278djasi@jetpack","blockID":"i1050","enabled":true,"last_modified":1480349201157,"details":{"who":"All users who have this add-on installed.","created":"2015-11-02T14:53:21Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1220461","name":"Trace Video (malware)","why":"This is a malicious add-on that poses as a video update and hijacks Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"cb4cfac0-79c2-0fbf-206a-324aa3abbea5","schema":1480349193877},{"guid":"{e44a1809-4d10-4ab8-b343-3326b64c7cdd}","blockID":"i451","enabled":true,"last_modified":1480349201128,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-09-18T16:33:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=916966","name":"Entrusted","why":"This add-on doesn't follow our Add-on Guidelines, manipulating settings without reverting them on removal. Users who wish to continue using this add-on can enable it in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"ad5f53ed-7a43-cb1f-cbd7-41808fac1791","schema":1480349193877},{"guid":"{21EAF666-26B3-4A3C-ABD0-CA2F5A326744}","blockID":"i620","enabled":true,"last_modified":1480349201096,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-06-12T15:27:00Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1024752","name":"V-Bates","why":"This add-on is probably silently installed, and is causing significant stability issues for users, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"2d8833db-01a7-a758-080f-19e47abc54cb","schema":1480349193877},{"guid":"{1FD91A9C-410C-4090-BBCC-55D3450EF433}","blockID":"i338","enabled":true,"last_modified":1480349201059,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-04-24T11:30:28Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=844979","name":"DataMngr (malware)","why":"This extension overrides search settings, and monitors any further changes done to them so that they can be reverted. This violates our add-on guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"2e35995f-bec6-aa2b-3372-346d3325f72e","schema":1480349193877},{"guid":"9598582LLKmjasieijkaslesae@jetpack","blockID":"i996","enabled":true,"last_modified":1480349201029,"details":{"who":"All users who have this add-on installed.","created":"2015-09-07T13:50:27Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1201165","name":"Secure Player (malware)","why":"This is a malicious add-on that takes over Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"52f9c6e7-f7d5-f52e-cc35-eb99ef8b4b6a","schema":1480349193877},{"guid":"{bf7380fa-e3b4-4db2-af3e-9d8783a45bfc}","blockID":"i406","enabled":true,"last_modified":1480349201000,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-06-27T10:46:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=776404","name":"uTorrentBar","why":"This add-on changes search settings without user interaction, and fails to reset them after it is removed. This violates our Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"3bcefc4b-110c-f3b8-17ad-f9fc97c1120a","schema":1480349193877},{"guid":"{ce7e73df-6a44-4028-8079-5927a588c948}","blockID":"i117","enabled":true,"last_modified":1480349200972,"details":{"who":"All Firefox users who have this add-on installed.","created":"2012-08-10T08:50:52Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=781269","name":"Search By Image (by Google)","why":"The Search By Image (by Google) extension causes very high CPU utilization during regular browsing, often damaging user experience significantly, in a way that is very difficult to associate with the extension.\r\n\r\nUsers who want to continue using the add-on regardless of its performance impact can enable it in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"1.0.8","severity":1}],"prefs":[],"id":"fb1f9aed-2f1f-3e2c-705d-3b34ca9168b6","schema":1480349193877},{"guid":"{424b0d11-e7fe-4a04-b7df-8f2c77f58aaf}","blockID":"i800","enabled":true,"last_modified":1480349200939,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-12-15T10:51:56Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1080839","name":"Astromenda NT","why":"This add-on is silently installed and is considered malware, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":["browser.startup.homepage","browser.search.defaultenginename"],"id":"07bdf6aa-cfc8-ed21-6b36-6f90af02b169","schema":1480349193877},{"guid":"toolbar@ask.com","blockID":"i618","enabled":true,"last_modified":1480349200911,"details":{"who":"All Firefox users who have these versions of the Ask Toolbar installed. Users who wish to continue using it can enable it in the Add-ons Manager.\r\n","created":"2014-06-12T14:25:04Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1024719","name":"Ask Toolbar (old Avira Security Toolbar bundle)","why":"Certain old versions of the Ask Toolbar are causing problems to users when trying to open new tabs. Using more recent versions of the Ask Toolbar should also fix this problem.\r\n"},"versionRange":[{"targetApplication":[],"minVersion":"3.15.31","maxVersion":"3.15.31.*","severity":1}],"prefs":[],"id":"825feb43-d6c2-7911-4189-6f589f612c34","schema":1480349193877},{"guid":"{167d9323-f7cc-48f5-948a-6f012831a69f}","blockID":"i262","enabled":true,"last_modified":1480349200885,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-01-29T13:33:25Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=812303","name":"WhiteSmoke (malware)","why":"This add-on is silently side-installed by other software, and doesn't do much more than changing the users' settings, without reverting them on removal."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"a8f249fe-3db8-64b8-da89-7b584337a7af","schema":1480349193877},{"guid":"/^({988919ff-0cd8-4d0c-bc7e-60d55a49eb64}|{494b9726-9084-415c-a499-68c07e187244}|{55b95864-3251-45e9-bb30-1a82589aaff1}|{eef3855c-fc2d-41e6-8d91-d368f51b3055}|{90a1b331-c2b4-4933-9f63-ba7b84d60d58}|{d2cf9842-af95-48cd-b873-bfbb48cd7f5e})$/","blockID":"i541","enabled":true,"last_modified":1480349200819,"details":{"who":"All Firefox users who have this add-on installed","created":"2014-01-28T14:09:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=963819","name":"MixiDJ (malware)","why":"This add-on has been repeatedly blocked before and keeps showing up with new add-on IDs, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"36196aed-9d0d-ebee-adf1-d1f7fadbc48f","schema":1480349193877},{"guid":"{29b136c9-938d-4d3d-8df8-d649d9b74d02}","blockID":"i598","enabled":true,"last_modified":1480349200775,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2014-06-12T13:21:25Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1011322","name":"Mega Browse","why":"This add-on is silently installed, in violation with our Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"63b1c965-27c3-cd06-1b76-8721add39edf","schema":1480349193877},{"guid":"{6e7f6f9f-8ce6-4611-add2-05f0f7049ee6}","blockID":"i868","enabled":true,"last_modified":1480349200690,"details":{"who":"All users who have this add-on installed. Users who wish to continue using the add-on can enable it in the Add-ons Manager.","created":"2015-02-26T14:58:59Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1086574","name":"Word Proser","why":"This add-on is silently installed into users' systems, in violation of our Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"f54797da-cdcd-351a-c95e-874b64b0d226","schema":1480349193877},{"guid":"{02edb56b-9b33-435b-b7df-b2843273a694}","blockID":"i438","enabled":true,"last_modified":1480349200338,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-08-09T15:27:49Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=896581","name":"KeyBar Toolbar","why":"This add-on doesn't follow our Add-on Guidelines. It is installed bypassing the Firefox opt-in screen, and manipulates settings without reverting them on removal. Users who wish to continue using this add-on can enable it in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"896710d2-5a65-e9b0-845b-05aa72c2bd51","schema":1480349193877},{"guid":"{e1aaa9f8-4500-47f1-9a0a-b02bd60e4076}","blockID":"i646","enabled":true,"last_modified":1480349200312,"details":{"who":"All Firefox users who have this version of the add-on installed.","created":"2014-07-10T15:10:05Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1036757","name":"Youtube Video Replay, version 178.7.0","why":"Certain versions of the Youtube Video Replay extension weren't developed by the original developer, and are likely malicious in nature. This violates the Add-on Guidelines for reusing an already existent ID."},"versionRange":[{"targetApplication":[],"minVersion":"178.7.0","maxVersion":"178.7.0","severity":3}],"prefs":[],"id":"ac5d1083-6753-bbc1-a83d-c63c35371b22","schema":1480349193877},{"guid":"{1cdbda58-45f8-4d91-b566-8edce18f8d0a}","blockID":"i724","enabled":true,"last_modified":1480349200288,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-10-13T16:00:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1080835","name":"Website Counselor Pro","why":"This add-on is silently installed into users' systems. It uses very unsafe practices to load its code, and leaks information of all web browsing activity. These are all violations of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"7b70bd36-d2f7-26fa-9038-8b8dd132cd81","schema":1480349193877},{"guid":"{b12785f5-d8d0-4530-a3ea-5c4263b85bef}","blockID":"i988","enabled":true,"last_modified":1480349200171,"details":{"who":"All users who have this add-on installed. Those who wish continue using this add-on can enable it in the Add-ons Manager.","created":"2015-08-17T16:04:35Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1161573","name":"Hero Fighter Community Toolbar","why":"This add-on overrides user's preferences without consent, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"3e6d73f2-e8e3-af69-866e-30d3977b09e4","schema":1480349193877},{"guid":"{c2d64ff7-0ab8-4263-89c9-ea3b0f8f050c}","blockID":"i39","enabled":true,"last_modified":1480349200047,"details":{"who":"Users of MediaBar versions 4.3.1.00 and below in all versions of Firefox.","created":"2011-07-19T10:18:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=665775","name":"MediaBar","why":"This add-on causes a high volume of crashes and is incompatible with certain versions of Firefox."},"versionRange":[{"targetApplication":[],"minVersion":"0.1","maxVersion":"4.3.1.00","severity":1}],"prefs":[],"id":"e928a115-9d8e-86a4-e2c7-de39627bd9bf","schema":1480349193877},{"guid":"{9edd0ea8-2819-47c2-8320-b007d5996f8a}","blockID":"i684","enabled":true,"last_modified":1480349199962,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using this add-on can enable it in the Add-ons Manager.","created":"2014-08-06T13:33:33Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1033857","name":"webget","why":"This add-on is believed to be silently installed in Firefox, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":["browser.search.defaultenginename"],"id":"d38561f5-370f-14be-1443-a74dad29b1f3","schema":1480349193877},{"guid":"/^({ad9a41d2-9a49-4fa6-a79e-71a0785364c8})|(ffxtlbr@mysearchdial\\.com)$/","blockID":"i670","enabled":true,"last_modified":1480349199927,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using this add-on can enable it in the Add-ons Manager.","created":"2014-07-18T15:47:35Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1036740","name":"MySearchDial","why":"This add-on has been repeatedly been silently installed into users' systems, and is known for changing the default search without user consent, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":["browser.search.defaultenginename"],"id":"a04075e6-5df2-2e1f-85a6-3a0171247349","schema":1480349193877},{"guid":"odtffplugin@ibm.com","blockID":"i982","enabled":true,"last_modified":1480349199886,"details":{"who":"All users who have these versions installed. The latest versions of this add-on aren't blocked, so updating to them should be sufficient to fix this problem.","created":"2015-08-11T11:25:43Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1190630","name":"IBM Endpoint Manager for Remote Control 9.0.1.1 to 9.0.1.100","why":"Certain versions of the IBM Remote Control add-on could leave a machine vulnerable to run untrusted code."},"versionRange":[{"targetApplication":[],"minVersion":"9.0.1.1","maxVersion":"9.0.1.100","severity":1}],"prefs":[],"id":"f6e3e5d2-9331-1097-ba4b-cf2e484b7187","schema":1480349193877},{"guid":"support@todoist.com","blockID":"i1030","enabled":true,"last_modified":1480349199850,"details":{"who":"All users who have this add-on installed. Users who wish to continue using this add-on can enable it in the Add-ons Manager.","created":"2015-10-01T16:53:06Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1205479","name":"Todoist","why":"This add-on is sending all sites visited by the user to a remote server, additionally doing so in an unsafe way."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"3.9","severity":1}],"prefs":[],"id":"d0a84aab-0661-b3c5-c184-a2fd3f9dfb9c","schema":1480349193877},{"guid":"/^({1f43c8af-e9e4-4e5a-b77a-f51c7a916324}|{3a3bd700-322e-440a-8a6a-37243d5c7f92}|{6a5b9fc2-733a-4964-a96a-958dd3f3878e}|{7b5d6334-8bc7-4bca-a13e-ff218d5a3f17}|{b87bca5b-2b5d-4ae8-ad53-997aa2e238d4}|{bf8e032b-150f-4656-8f2d-6b5c4a646e0d})$/","blockID":"i1136","enabled":true,"last_modified":1480349199818,"details":{"who":"All users who have this add-on installed.","created":"2016-03-04T17:56:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1251940","name":"Watcher (malware)","why":"This is a malicious add-on that hides itself from view and disables various security features in Firefox."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"a2d0378f-ebe4-678c-62d8-2e4c6a613c17","schema":1480349193877},{"guid":"liiros@facebook.com","blockID":"i814","enabled":true,"last_modified":1480349199791,"details":{"who":"All Firefox users who have this add-on installed.","created":"2015-01-09T12:49:05Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1119657","name":"One Tab (malware)","why":"This add-on is silently installed into users' systems without their consent and performs unwanted operations."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"387c054d-cc9f-7ebd-c814-b4c1fbcb2880","schema":1480349193877},{"guid":"youtubeunblocker@unblocker.yt","blockID":"i1128","enabled":true,"last_modified":1480349199768,"details":{"who":"All users who have this add-on installed.","created":"2016-03-01T21:18:33Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1251911","name":"YouTube Unblocker","why":"The add-on has a mechanism that updates certain configuration files from the developer\u2019s website. This mechanism has a vulnerability that is being exploited through this website (unblocker.yt) to change security settings in Firefox and install malicious add-ons."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"3395fce1-42dd-e31a-1466-2da3f32456a0","schema":1480349193877},{"guid":"{97E22097-9A2F-45b1-8DAF-36AD648C7EF4}","blockID":"i916","enabled":true,"last_modified":1480349199738,"details":{"who":"All Firefox users who have this add-on installed in Firefox 39 and above.\r\n","created":"2015-06-02T09:57:38Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1170633","name":"RealPlayer Browser Record Plugin","why":"Certain versions of this extension are causing startup crashes in Firefox 39 and above.\r\n"},"versionRange":[{"targetApplication":[{"minVersion":"39.0a1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"}],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"94fba774-c4e6-046a-bc7d-ede787a9d0fe","schema":1480349193877},{"guid":"{b64982b1-d112-42b5-b1e4-d3867c4533f8}","blockID":"i167","enabled":true,"last_modified":1480349199673,"details":{"who":"All Firefox users who have this add-on installed.","created":"2012-10-29T17:17:46Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=805973","name":"Browser Manager","why":"This add-on is a frequent cause for browser crashes and other problems."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"00bbe501-2d27-7a1c-c344-6eea1c707473","schema":1480349193877},{"guid":"{58bd07eb-0ee0-4df0-8121-dc9b693373df}","blockID":"i286","enabled":true,"last_modified":1480349199619,"details":{"who":"All Firefox users who have this extension installed.","created":"2013-02-18T10:54:28Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=842206","name":"Browser Protect / bProtector (malware)","why":"This extension is malicious and is installed under false pretenses, causing problems for many Firefox users. Note that this is not the same BrowserProtect extension that is listed on our add-ons site. That one is safe to use."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"b40a60d3-b9eb-09eb-bb02-d50b27aaac9f","schema":1480349193877},{"guid":"trtv3@trtv.com","blockID":"i465","enabled":true,"last_modified":1480349199560,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-11-01T15:21:49Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=845610","name":"TornTV","why":"This add-on doesn't follow our Add-on Guidelines, bypassing our third party install opt-in screen. Users who wish to continue using this extension can enable it in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"3d4d8a33-2eff-2556-c699-9be0841a8cd4","schema":1480349193877},{"guid":"youtube@downloader.yt","blockID":"i1231","enabled":true,"last_modified":1480349199528,"details":{"who":"All users who have this add-on installed.","created":"2016-06-09T14:50:27Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1278932","name":"YouTube downloader","why":"The add-on has a mechanism that updates certain configuration files from the developer\u2019s website. This mechanism has a vulnerability that can being exploited through this website (downloader.yt) to change security settings in Firefox and/or install malicious add-ons. \r\n"},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"8514eaee-850c-e27a-a058-8badeeafc26e","schema":1480349193877},{"guid":"low_quality_flash@pie2k.com","blockID":"i658","enabled":true,"last_modified":1480349199504,"details":{"who":"All Firefox users who have this version of the add-on installed.","created":"2014-07-10T15:27:51Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1036757","name":"Low Quality Flash, versions between 46.2 and 47.1","why":"Certain versions of the Low Quality Flash extension weren't developed by the original developer, and are likely malicious in nature. This violates the Add-on Guidelines for reusing an already existent ID."},"versionRange":[{"targetApplication":[],"minVersion":"46.2","maxVersion":"47.1","severity":3}],"prefs":[],"id":"b869fae6-c18c-0d39-59a2-603814656404","schema":1480349193877},{"guid":"{d2cf9842-af95-48cd-b873-bfbb48cd7f5e}","blockID":"i439","enabled":true,"last_modified":1480349199478,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-08-09T16:08:18Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=902569","name":"Mixi DJ V45","why":"This is another instance of the previously blocked Mixi DJ add-on, which doesn't follow our Add-on Guidelines. If you wish to continue using it, it can be enabled in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"e81c31fc-265e-61b9-d4c1-0e2f31f1652e","schema":1480349193877},{"guid":"/^({b95faac1-a3d7-4d69-8943-ddd5a487d966}|{ecce0073-a837-45a2-95b9-600420505f7e}|{2713b394-286f-4d7c-89ea-4174eeab9f5a}|{da7a20cf-bef4-4342-ad78-0240fdf87055})$/","blockID":"i624","enabled":true,"last_modified":1480349199446,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using this add-on can enable it in the Add-ons Manager.","created":"2014-06-18T13:50:38Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=947482","name":"WiseConvert","why":"This add-on is known to change user settings without their consent, is distributed under multiple add-on IDs, and is also correlated with reports of tab functions being broken in Firefox, in violation of the Add-on Guidelines.\r\n"},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"ed57d7a6-5996-c7da-8e07-1ad125183e84","schema":1480349193877},{"guid":"{f894a29a-f065-40c3-bb19-da6057778493}","blockID":"i742","enabled":true,"last_modified":1480349199083,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2014-10-17T15:46:59Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1080817","name":"Spigot Shopping Assistant","why":"This add-on appears to be silently installed into users' systems, and changes settings without consent, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"39d8334e-4b7c-4336-2d90-e6aa2d783967","schema":1480349193877},{"guid":"plugin@analytic-s.com","blockID":"i467","enabled":true,"last_modified":1480349199026,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-11-07T14:08:48Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=935797","name":"Analytics","why":"This add-on bypasses the external install opt in screen in Firefox, violating the Add-on Guidelines. Users who wish to continue using this add-on can enable it in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"ffbed3f3-e5c9-bc6c-7530-f68f47b7efd6","schema":1480349193877},{"guid":"{C4A4F5A0-4B89-4392-AFAC-D58010E349AF}","blockID":"i678","enabled":true,"last_modified":1480349198947,"details":{"who":"All Firefox users who have this add-on installed. If you wish to continue using it, you can enable it in the Add-ons Manager.","created":"2014-07-23T14:12:23Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=895668","name":"DataMngr","why":"This add-on is generally silently installed, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"151021fc-ce4e-a734-e075-4ece19610f64","schema":1480349193877},{"guid":"HxLVJK1ioigz9WEWo8QgCs3evE7uW6LEExAniBGG@jetpack","blockID":"i1036","enabled":true,"last_modified":1480349198894,"details":{"who":"All users who have this add-on installed.","created":"2015-10-05T16:37:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1211170","name":"Mega Player (malware)","why":"This is a malicious add-on that hijacks Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"32e34b41-a73c-72d4-c96c-136917ad1d4d","schema":1480349193877},{"guid":"{6af08a71-380e-42dd-9312-0111d2bc0630}","blockID":"i822","enabled":true,"last_modified":1480349198826,"details":{"who":"All Firefox users who have this add-on installed.","created":"2015-01-27T09:50:40Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1126353","name":"{6af08a71-380e-42dd-9312-0111d2bc0630} (malware)","why":"This add-on appears to be malware, hiding itself in the Add-ons Manager, and keeping track of certain user actions."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"96d0c12b-a6cf-4539-c1cf-a1c75c14ff24","schema":1480349193877},{"guid":"colmer@yopmail.com","blockID":"i550","enabled":true,"last_modified":1480349198744,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-02-06T15:49:25Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=968445","name":"Video Plugin Facebook (malware)","why":"This add-on is malware that hijacks Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"c394d10b-384e-cbd0-f357-9c521715c373","schema":1480349193877},{"guid":"fplayer@adobe.flash","blockID":"i444","enabled":true,"last_modified":1480349198667,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-08-26T14:49:48Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=909433","name":"Flash Player (malware)","why":"This add-on is malware disguised as the Flash Player plugin."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"c6557989-1b59-72a9-da25-b816c4a4c723","schema":1480349193877},{"guid":"ascsurfingprotection@iobit.com","blockID":"i740","enabled":true,"last_modified":1480349198637,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2014-10-17T15:39:59Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=963776","name":"Advanced SystemCare Surfing Protection","why":"This add-on is silently installed into users' systems, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"4405f99d-c9b7-c496-1b45-268163ce29b7","schema":1480349193877},{"guid":"{6E19037A-12E3-4295-8915-ED48BC341614}","blockID":"i24","enabled":true,"last_modified":1480349198606,"details":{"who":"Users of RelevantKnowledge version 1.3.328.4 and older in Firefox 4 and later.","created":"2011-03-02T17:42:56Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=615518","name":"comScore RelevantKnowledge","why":"This add-on causes a high volume of Firefox crashes."},"versionRange":[{"targetApplication":[{"minVersion":"3.7a1pre","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"}],"minVersion":"0.1","maxVersion":"1.3.328.4","severity":1}],"prefs":[],"id":"7c189c5e-f95b-0aef-e9e3-8e879336503b","schema":1480349193877},{"guid":"crossriderapp4926@crossrider.com","blockID":"i91","enabled":true,"last_modified":1480349198547,"details":{"who":"All Firefox users who have installed this add-on.","created":"2012-05-14T14:16:43Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=754648","name":"Remove My Timeline (malware)","why":"Versions of this add-on prior to 0.81.44 automatically post message to users' walls and hide them from their view. Version 0.81.44 corrects this."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"0.81.43","severity":1}],"prefs":[],"id":"5ee3e72e-96fb-c150-fc50-dd581e960963","schema":1480349193877},{"guid":"/^(93abedcf-8e3a-4d02-b761-d1441e437c09@243f129d-aee2-42c2-bcd1-48858e1c22fd\\.com|9acfc440-ac2d-417a-a64c-f6f14653b712@09f9a966-9258-4b12-af32-da29bdcc28c5\\.com|58ad0086-1cfb-48bb-8ad2-33a8905572bc@5715d2be-69b9-4930-8f7e-64bdeb961cfd\\.com)$/","blockID":"i544","enabled":true,"last_modified":1480349198510,"details":{"who":"All Firefox users who have this add-on installed. If you wish to continue using it, it can be enabled in the Add-ons Manager.","created":"2014-01-30T11:51:19Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=949596","name":"SuperLyrics","why":"This add-on is in violation of the Add-on Guidelines, using multiple add-on IDs and potentially doing other unwanted activities."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"d8d25967-9814-3b65-0787-a0525c16e11e","schema":1480349193877},{"guid":"wHO@W9.net","blockID":"i980","enabled":true,"last_modified":1480349198483,"details":{"who":"All users who have this add-on installed.","created":"2015-08-11T11:20:01Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1192468","name":"BestSavEFOrYoU (malware)","why":"This is a malicious add-on that hijacks Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"4beb917f-68f2-1f91-beed-dff6d83006f8","schema":1480349193877},{"guid":"frhegnejkgner@grhjgewfewf.com","blockID":"i1040","enabled":true,"last_modified":1480349198458,"details":{"who":"All users who have this add-on installed.","created":"2015-10-07T13:03:37Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1212451","name":"Async Codec (malware)","why":"This is a malicious add-on that hijacks Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"fb6ab4ce-5517-bd68-2cf7-a93a109a528a","schema":1480349193877},{"guid":"firefox@luckyleap.net","blockID":"i471","enabled":true,"last_modified":1480349198433,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-11-07T15:38:33Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=935779","name":"Installer bundle (malware)","why":"This add-on is part of a malicious Firefox installer bundle."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"3a9e04c7-5e64-6297-8442-2816915aad77","schema":1480349193877},{"guid":"auto-plugin-checker@jetpack","blockID":"i1210","enabled":true,"last_modified":1480349198401,"details":{"who":"All users of this add-on. If you wish to continue using it, you can enable it in the Add-ons Manager.","created":"2016-05-04T16:25:27Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1270175","name":"auto-plugin-checker","why":"This add-on reports every visited URL to a third party without disclosing it to the user."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"3e202419-5318-2025-b579-c828af24a06e","schema":1480349193877},{"guid":"lugcla21@gmail.com","blockID":"i432","enabled":true,"last_modified":1480349198372,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-08-06T13:16:22Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=902072","name":"FB Color Changer (malware)","why":"This add-on includes malicious code that spams users' Facebook accounts with unwanted messages."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"b6943f35-9429-1f8e-bf8e-fe37979fe183","schema":1480349193877},{"guid":"{99079a25-328f-4bd4-be04-00955acaa0a7}","blockID":"i402","enabled":true,"last_modified":1480349198341,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-06-25T15:16:17Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=835678","name":"Searchqu","why":"This group of add-ons is silently installed, bypassing our install opt-in screen. This violates our Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"16008331-8b47-57c8-a6f7-989914d1cb8a","schema":1480349193877},{"guid":"{81b13b5d-fba1-49fd-9a6b-189483ac548a}","blockID":"i473","enabled":true,"last_modified":1480349198317,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-11-07T15:38:43Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=935779","name":"Installer bundle (malware)","why":"This add-on is part of a malicious Firefox installer bundle."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"76debc7b-b875-6da4-4342-1243cbe437f6","schema":1480349193877},{"guid":"{e935dd68-f90d-46a6-b89e-c4657534b353}","blockID":"i732","enabled":true,"last_modified":1480349198260,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-10-16T16:38:24Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1073810","name":"Sites Pro","why":"This add-on is silently installed into users' systems. It uses very unsafe practices to load its code, and leaks information of all web browsing activity. These are all violations of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"97fdc235-ac1a-9f20-1b4a-17c2f0d89ad1","schema":1480349193877},{"guid":"{32da2f20-827d-40aa-a3b4-2fc4a294352e}","blockID":"i748","enabled":true,"last_modified":1480349198223,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2014-10-17T16:02:20Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=963787","name":"Start Page","why":"This add-on is silently installed into users' systems, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"6c980c8e-4a3c-7912-4a3a-80add457575a","schema":1480349193877},{"guid":"chinaescapeone@facebook.com","blockID":"i431","enabled":true,"last_modified":1480349198192,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-08-05T16:43:24Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=901770","name":"F-Secure Security Pack (malware)","why":"This is a malicious add-on that uses a deceptive name and hijacks social networks."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"fbd89a9d-9c98-8481-e4cf-93e327ca8be1","schema":1480349193877},{"guid":"{cc6cc772-f121-49e0-b1f0-c26583cb0c5e}","blockID":"i716","enabled":true,"last_modified":1480349198148,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-10-02T12:12:34Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1073810","name":"Website Counselor","why":"This add-on is silently installed into users' systems. It uses very unsafe practices to load its code, and leaks information of all web browsing activity. These are all violations of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"debcd28c-884b-ca42-d983-6fabf91034dd","schema":1480349193877},{"guid":"{906000a4-88d9-4d52-b209-7a772970d91f}","blockID":"i474","enabled":true,"last_modified":1480349197744,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-11-07T15:38:48Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=935779","name":"Installer bundle (malware)","why":"This add-on is part of a malicious Firefox installer bundle."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"326d05b9-ace7-67c6-b094-aad926c185a5","schema":1480349193877},{"guid":"{A34CAF42-A3E3-11E5-945F-18C31D5D46B0}","blockID":"i1227","enabled":true,"last_modified":1480349197699,"details":{"who":"All users of this add-on. If you wish to continue using it, you can enable it in the Add-ons Manager.","created":"2016-05-31T15:45:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1274995","name":"Mococheck WAP browser","why":"This add-on downgrades the security of all iframes from https to http and changes important Firefox security preferences."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":["security.csp.enable","security.fileuri.strict_origin_policy","security.mixed_content.block_active_content"],"id":"2230a5ce-a8f8-a20a-7974-3b960a03aba9","schema":1480349193877},{"guid":"{AB2CE124-6272-4b12-94A9-7303C7397BD1}","blockID":"i20","enabled":true,"last_modified":1480349197667,"details":{"who":"Users of Skype extension versions below 5.2.0.7165 for all versions of Firefox.","created":"2011-01-20T18:39:25Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=627278","name":"Skype extension","why":"This add-on causes a high volume of Firefox crashes and introduces severe performance issues. Please update to the latest version. For more information, please read our announcement."},"versionRange":[{"targetApplication":[],"minVersion":"0.1","maxVersion":"5.2.0.7164","severity":1}],"prefs":[],"id":"60e16015-1803-197a-3241-484aa961d18f","schema":1480349193877},{"guid":"f6682b47-e12f-400b-9bc0-43b3ccae69d1@39d6f481-b198-4349-9ebe-9a93a86f9267.com","blockID":"i682","enabled":true,"last_modified":1480349197636,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using this add-on can enable it in the Add-ons Manager.","created":"2014-08-04T16:07:20Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1043017","name":"enformation","why":"This add-on is being silently installed, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"a7ae65cd-0869-67e8-02f8-6d22c56a83d4","schema":1480349193877},{"guid":"rally_toolbar_ff@bulletmedia.com","blockID":"i537","enabled":true,"last_modified":1480349197604,"details":{"who":"All Firefox users who have this extension installed. If you want to continue using it, you can enable it in the Add-ons Manager.","created":"2014-01-23T15:51:48Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=950267","name":"Rally Toolbar","why":"The installer that includes this add-on violates the Add-on Guidelines by silently installing it."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"4ac6eb63-b51a-3296-5b02-bae77f424032","schema":1480349193877},{"guid":"x77IjS@xU.net","blockID":"i774","enabled":true,"last_modified":1480349197578,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2014-10-31T16:22:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1076771","name":"YoutubeAdBlocke","why":"This add-on is silently installed and changes user settings without consent, in violation of the Add-on Guidelines\r\n"},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":["browser.startup.homepage","browser.search.defaultenginename"],"id":"4771da14-bcf2-19b1-3d71-bc61a1c7d457","schema":1480349193877},{"guid":"{49c53dce-afa0-49a1-a08b-2eb8e8444128}","blockID":"i441","enabled":true,"last_modified":1480349197550,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-08-09T16:58:50Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=844985","name":"ytbyclick","why":"This add-on is silently installed, violating our Add-on Guidelines. Users who wish to continue using this add-on can enable it in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"5f08d720-58c2-6acb-78ad-7af45c82c90b","schema":1480349193877},{"guid":"searchengine@gmail.com","blockID":"i886","enabled":true,"last_modified":1480349197525,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using this add-on can enable it in the Add-on Manager.","created":"2015-04-10T16:25:21Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1152555","name":"Search Enginer","why":"This add-on appears to be malware, being silently installed and hijacking user settings, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":["browser.startup.homepage","browser.search.defaultenginename"],"id":"46de4f6e-2b29-7334-ebbb-e0048f114f7b","schema":1480349193877},{"guid":"{bb7b7a60-f574-47c2-8a0b-4c56f2da9802}","blockID":"i754","enabled":true,"last_modified":1480349197500,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2014-10-17T16:27:32Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1080850","name":"AdvanceElite","why":"This add-on is silently installed into users' systems, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"f222ceb2-9b69-89d1-8dce-042d8131a12e","schema":1480349193877},{"guid":"/^(test3@test.org|test2@test.org|test@test.org|support@mozilla.org)$/","blockID":"i1119","enabled":true,"last_modified":1480349197468,"details":{"who":"All users who have these add-ons installed.","created":"2016-01-25T13:31:43Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1242721","name":"test.org add-ons (malware)","why":"These add-ons are malicious, or at least attempts at being malicious, using misleading names and including risky code."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"afd2a0d7-b050-44c9-4e45-b63696d9b22f","schema":1480349193877},{"guid":"/^((34qEOefiyYtRJT@IM5Munavn\\.com)|(Mro5Fm1Qgrmq7B@ByrE69VQfZvZdeg\\.com)|(KtoY3KGxrCe5ie@yITPUzbBtsHWeCdPmGe\\.com)|(9NgIdLK5Dq4ZMwmRo6zk@FNt2GCCLGyUuOD\\.com)|(NNux7bWWW@RBWyXdnl6VGls3WAwi\\.com)|(E3wI2n@PEHTuuNVu\\.com)|(2d3VuWrG6JHBXbQdbr@3BmSnQL\\.com))$/","blockID":"i324","enabled":true,"last_modified":1480349197432,"details":{"who":"All users who have this add-on installed.","created":"2013-03-22T14:48:00Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=841791","name":"Flash Player (malware)","why":"This extension is malware, installed pretending to be the Flash Player plugin."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"5be3a399-af3e-644e-369d-628273b3fdc2","schema":1480349193877},{"guid":"axtara__web@axtara.com","blockID":"i1263","enabled":true,"last_modified":1480349197404,"details":{"who":"All users who have version 1.1.1 or less of this add-on installed.","created":"2016-08-17T16:47:06Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1251911","name":"AXTARA Search (pre 1.1.2)","why":"Old versions of this add-on contained code from YouTube Unblocker, which was originally blocked due to malicious activity. Version 1.1.2 is now okay."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"1.1.1","severity":3}],"prefs":[],"id":"c58be1c9-3d63-a948-219f-e3225e1eec8e","schema":1480349193877},{"guid":"{8f894ed3-0bf2-498e-a103-27ef6e88899f}","blockID":"i792","enabled":true,"last_modified":1480349197368,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-11-26T13:49:30Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1073810","name":"ExtraW","why":"This add-on is silently installed into users' systems. It uses very unsafe practices to load its code, and leaks information of all web browsing activity. These are all violations of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"bebc9e15-59a1-581d-0163-329d7414edff","schema":1480349193877},{"guid":"profsites@pr.com","blockID":"i734","enabled":true,"last_modified":1480349197341,"details":{"who":"All Firefox users who have this add-on installed.\r\n","created":"2014-10-16T16:39:26Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1073810","name":"ProfSites","why":"This add-on is silently installed into users' systems. It uses very unsafe practices to load its code, and leaks information of all web browsing activity. These are all violations of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"0d6d84d7-0b3f-c5ab-57cc-6b66b0775a23","schema":1480349193877},{"guid":"{872b5b88-9db5-4310-bdd0-ac189557e5f5}","blockID":"i497","enabled":true,"last_modified":1480349197240,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-12-03T16:08:09Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=945530","name":"DVDVideoSoft Menu","why":"The installer that includes this add-on violates the Add-on Guidelines by making settings changes that can't be easily reverted."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"e8da89c4-c585-77e4-9872-591d20723a7e","schema":1480349193877},{"guid":"123456789@offeringmedia.com","blockID":"i664","enabled":true,"last_modified":1480349197208,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-07-10T15:41:24Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1036757","name":"Taringa MP3 / Adobe Flash","why":"This is a malicious add-on that attempts to hide itself by impersonating the Adobe Flash plugin."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"6d0a7dda-d92a-c8e2-21be-c92b0a88ac8d","schema":1480349193877},{"guid":"firefoxdav@icloud.com","blockID":"i1214","enabled":true,"last_modified":1480349197172,"details":{"who":"All users of this add-on. If you wish to continue using it, you can enable it in the Add-ons Manager.","created":"2016-05-17T16:55:39Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1271358","name":"iCloud Bookmarks","why":"This add-on is causing frequent and persistent crashing."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"1.4.22","severity":1}],"prefs":[],"id":"2dddd7a7-b081-45e2-3eeb-2a7f76a1465f","schema":1480349193877},{"guid":"youplayer@addons.mozilla.org","blockID":"i660","enabled":true,"last_modified":1480349197136,"details":{"who":"All Firefox users who have this version of the add-on installed.","created":"2014-07-10T15:31:04Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1036757","name":"YouPlayer, versions between 79.9.8 and 208.0.1","why":"Certain versions of the YouPlayer extension weren't developed by the original developer, and are likely malicious in nature. This violates the Add-on Guidelines for reusing an already existent ID."},"versionRange":[{"targetApplication":[],"minVersion":"79.9.8","maxVersion":"208.0.1","severity":3}],"prefs":[],"id":"82dca22b-b889-5d9d-3fc9-b2184851f2d1","schema":1480349193877},{"guid":"{df6bb2ec-333b-4267-8c4f-3f27dc8c6e07}","blockID":"i487","enabled":true,"last_modified":1480349197109,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-11-19T14:59:45Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=940681","name":"Facebook 2013 (malware)","why":"This is a malicious add-on that hijacks Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"5867c409-b342-121e-3c3b-426e2f0ba1d4","schema":1480349193877},{"guid":"/^({4e988b08-8c51-45c1-8d74-73e0c8724579}|{93ec97bf-fe43-4bca-a735-5c5d6a0a40c4}|{aed63b38-7428-4003-a052-ca6834d8bad3}|{0b5130a9-cc50-4ced-99d5-cda8cc12ae48}|{C4CFC0DE-134F-4466-B2A2-FF7C59A8BFAD})$/","blockID":"i524","enabled":true,"last_modified":1480349197082,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-12-20T13:43:21Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=947481","name":"SweetPacks","why":"The installer that includes this add-on violates the Add-on Guidelines by making changes that can't be easily reverted."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"1a3a26a2-cdaa-e5ba-f6ac-47b98ae2cc26","schema":1480349193877},{"guid":"foxyproxy@eric.h.jung","blockID":"i950","enabled":true,"last_modified":1480349197056,"details":{"who":"All users who have this add-on installed on Thunderbird 38 and above.","created":"2015-07-15T09:34:44Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1183890","name":"FoxyProxy Standard for Thunderbird","why":"This add-on is causing consistent startup crashes on Thunderbird 38 and above."},"versionRange":[{"targetApplication":[{"minVersion":"38.0a2","guid":"{3550f703-e582-4d05-9a08-453d09bdfdc6}","maxVersion":"*"},{"minVersion":"2.35","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"}],"minVersion":"0","maxVersion":"4.5.5","severity":1}],"prefs":[],"id":"5ee8203d-bea2-6cd5-9ba0-d1922ffb3d21","schema":1480349193877},{"guid":"{82AF8DCA-6DE9-405D-BD5E-43525BDAD38A}","blockID":"i1056","enabled":true,"last_modified":1480349197027,"details":{"who":"All users who have this add-on installed in Firefox 43 and above. User who wish to continue using this add-on can enable it in the Add-ons Manager.","created":"2015-11-17T14:03:05Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1225639","name":"Skype Click to Call","why":"This add-on is associated with frequent shutdown crashes in Firefox."},"versionRange":[{"targetApplication":[{"minVersion":"43.0a1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"}],"minVersion":"0","maxVersion":"7.5.0.9082","severity":1}],"prefs":[],"id":"484f8386-c415-7499-a8a0-f4e16f5a142f","schema":1480349193877},{"guid":"{22119944-ED35-4ab1-910B-E619EA06A115}","blockID":"i45","enabled":true,"last_modified":1480349196995,"details":{"who":"Users of version 7.9.20.6 of RoboForm Toolbar and earlier on Firefox 48 and above.","created":"2011-11-19T06:14:56Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=699134","name":"Roboform","why":"Older versions of the RoboForm Toolbar add-on are causing crashes in Firefox 48 and above. The developer has released a fix, available in versions 7.9.21+."},"versionRange":[{"targetApplication":[{"minVersion":"8.0a1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"}],"minVersion":"0.1","maxVersion":"7.9.20.6","severity":1}],"prefs":[],"id":"5f7f9e13-d3e8-ea74-8341-b83e36d67d94","schema":1480349193877},{"guid":"{87b5a11e-3b54-42d2-9102-0a7cb1f79ebf}","blockID":"i838","enabled":true,"last_modified":1480349196965,"details":{"who":"All Firefox users who have this add-on installed.","created":"2015-02-06T14:29:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1128327","name":"Cyti Web (malware)","why":"This add-on is silently installed and performs unwanted actions, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"1ba0e57c-4c0c-4eb6-26e7-c2016769c343","schema":1480349193877},{"guid":"/^({bf67a47c-ea97-4caf-a5e3-feeba5331231}|{24a0cfe1-f479-4b19-b627-a96bf1ea3a56})$/","blockID":"i542","enabled":true,"last_modified":1480349196622,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-01-28T14:10:49Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=963819","name":"MixiDJ (malware)","why":"This add-on has been repeatedly blocked before and keeps showing up with new add-on IDs, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"fc442b64-1b5d-bebb-c486-f431b154f3db","schema":1480349193877},{"guid":"/^({ebd898f8-fcf6-4694-bc3b-eabc7271eeb1}|{46008e0d-47ac-4daa-a02a-5eb69044431a}|{213c8ed6-1d78-4d8f-8729-25006aa86a76}|{fa23121f-ee7c-4bd8-8c06-123d087282c5}|{19803860-b306-423c-bbb5-f60a7d82cde5})$/","blockID":"i622","enabled":true,"last_modified":1480349196597,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using this add-on can enable it in the Add-ons Manager.","created":"2014-06-18T13:48:26Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=947482","name":"WiseConvert","why":"This add-on is known to change user settings without their consent, is distributed under multiple add-on IDs, and is also correlated with reports of tab functions being broken in Firefox, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"ffd184fa-aa8f-8a75-ff00-ce285dec5b22","schema":1480349193877},{"guid":"/^({fa95f577-07cb-4470-ac90-e843f5f83c52}|ffxtlbr@speedial\\.com)$/","blockID":"i696","enabled":true,"last_modified":1480349196565,"details":{"who":"All Firefox users who have any of these add-ons installed. Users who wish to continue using these add-ons can enable them in the Add-ons Manager.","created":"2014-08-21T13:55:41Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1031115","name":"Speedial","why":"These add-ons are silently installed and change homepage and search defaults without user consent, in violation of the Add-on Guidelines. They are also distributed under more than one add-on ID."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":["browser.startup.homepage","browser.search.defaultenginename"],"id":"130c7419-f727-a2fb-3891-627bc69a43bb","schema":1480349193877},{"guid":"pennerdu@faceobooks.ws","blockID":"i442","enabled":true,"last_modified":1480349196541,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-08-13T14:00:36Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=904050","name":"Console Video (malware)","why":"This is a malicious add-on that hijacks Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"fb83e48e-a780-9d06-132c-9ecc65b43674","schema":1480349193877},{"guid":"anttoolbar@ant.com","blockID":"i88","enabled":true,"last_modified":1480349196509,"details":{"who":"All Firefox users who have installed version 2.4.6.4 of the Ant Video Downloader and Player add-on.","created":"2012-05-01T10:32:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=748269","name":"Ant Video Downloader and Player","why":"Version 2.4.6.4 of the Ant Video Downloader and Player add-on is causing a very high number of crashes in Firefox. There's an updated version 2.4.6.5 that doesn't have this problem. All users are recommended to update as soon as possible."},"versionRange":[{"targetApplication":[],"minVersion":"2.4.6.4","maxVersion":"2.4.6.4","severity":1}],"prefs":[],"id":"9eef435b-39d4-2b73-0810-44b0d3ff52ad","schema":1480349193877},{"guid":"{E90FA778-C2B7-41D0-9FA9-3FEC1CA54D66}","blockID":"i446","enabled":true,"last_modified":1480349196471,"details":{"who":"All Firefox users who have this add-on installed. The add-on can be enabled again in the Add-ons Manager.","created":"2013-09-06T15:59:29Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=788838","name":"YouTube to MP3 Converter","why":"This add-on is installed silently, in violation of our Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"83eb6337-a3b6-84e4-e76c-ee9200b80796","schema":1480349193877},{"guid":"{ad7ce998-a77b-4062-9ffb-1d0b7cb23183}","blockID":"i804","enabled":true,"last_modified":1480349196438,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-12-15T10:53:58Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1080839","name":"Astromenda Search Addon","why":"This add-on is silently installed and is considered malware, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":["browser.startup.homepage","browser.search.defaultenginename"],"id":"633f9999-c81e-bd7a-e756-de7d34feb39d","schema":1480349193877},{"guid":"{52b0f3db-f988-4788-b9dc-861d016f4487}","blockID":"i584","enabled":true,"last_modified":1480349196363,"details":{"who":"All Firefox users who have these add-ons installed. If you wish to continue using these add-ons, you can enable them in the Add-ons Manager.","created":"2014-05-22T11:07:00Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=974104","name":"Web Check (Free Driver Scout bundle)","why":"Versions of this add-on are silently installed by the Free Driver Scout installer, in violation of our Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"0.1.9999999","severity":1}],"prefs":[],"id":"cba0ac44-90f9-eabb-60b0-8da2b645e067","schema":1480349193877},{"guid":"dodatek@flash2.pl","blockID":"i1279","enabled":true,"last_modified":1480349196331,"details":{"who":"Any user with version 1.3 or newer of this add-on installed.","created":"2016-10-27T15:52:00Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312748","name":"Aktualizacja Flash WORK addon","why":"This add-on claims to be a flash plugin and it does some work on youtube, but it also steals your facebook and adfly credentials and sends them to a remote server."},"versionRange":[{"targetApplication":[],"minVersion":"1.3","maxVersion":"*","severity":3}],"prefs":[],"id":"2dab5211-f9ec-a1bf-c617-6f94f28b5ee1","schema":1480349193877},{"guid":"{2d069a16-fca1-4e81-81ea-5d5086dcbd0c}","blockID":"i440","enabled":true,"last_modified":1480349196294,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-08-09T16:26:46Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=903647","name":"GlitterFun","why":"This add-on is installed silently and doesn't follow many other of the Add-on Guidelines. If you want to continue using this add-on, you can enable it in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"e3f77f3c-b1d6-3b29-730a-846007b9cb16","schema":1480349193877},{"guid":"xivars@aol.com","blockID":"i501","enabled":true,"last_modified":1480349196247,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-12-04T15:34:32Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=946420","name":"Video Plugin Facebook (malware)","why":"This is a malicious Firefox extension that uses a deceptive name and hijacks users' Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"3303d201-7006-3c0d-5fd5-45503e2e690c","schema":1480349193877},{"guid":"2bbadf1f-a5af-499f-9642-9942fcdb7c76@f05a14cc-8842-4eee-be17-744677a917ed.com","blockID":"i700","enabled":true,"last_modified":1480349196212,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using this add-on can enable it in the Add-ons Manager.","created":"2014-08-21T16:15:16Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1052599","name":"PIX Image Viewer","why":"This add-on is widely considered malware and is apparently installed silently into users' systems, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"1b72889b-90e6-ea58-4fe8-d48257df7d8b","schema":1480349193877},{"guid":"/^[0-9a-f]+@[0-9a-f]+\\.info/","blockID":"i256","enabled":true,"last_modified":1480349196184,"details":{"who":"All Firefox users who have installed any of these add-ons.","created":"2013-01-22T12:16:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=806451","name":"Codec extensions (malware)","why":"The set of extensions labeled as Codec, Codec-M, Codec-C and other names are malware being distributed as genuine add-ons.\r\n\r\nIf you think an add-on you installed was incorrectly blocked and the block dialog pointed you to this page, please comment on this blog post."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"0c654540-00f2-0ad4-c9be-7ca2ace5341e","schema":1480349193877},{"guid":"toolbar@ask.com","blockID":"i600","enabled":true,"last_modified":1480349196158,"details":{"who":"All Firefox users who have these versions of the Ask Toolbar installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2014-06-12T14:16:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1024719","name":"Ask Toolbar (old Avira Security Toolbar bundle)","why":"Certain old versions of the Ask Toolbar are causing problems to users when trying to open new tabs. Using more recent versions of the Ask Toolbar should also fix this problem."},"versionRange":[{"targetApplication":[],"minVersion":"3.15.5","maxVersion":"3.15.5.*","severity":1}],"prefs":[],"id":"51c4ab3b-9ad3-c5c3-98c8-a220025fc5a3","schema":1480349193877},{"guid":"{729c9605-0626-4792-9584-4cbe65b243e6}","blockID":"i788","enabled":true,"last_modified":1480349196123,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-11-20T10:07:19Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1073810","name":"Browser Ext Assistance","why":"This add-on is silently installed into users' systems. It uses very unsafe practices to load its code, and leaks information of all web browsing activity. These are all violations of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"3c588238-2501-6a53-65ea-5c8ff0f3e51d","schema":1480349193877},{"guid":"unblocker20__web@unblocker.yt","blockID":"i1213","enabled":true,"last_modified":1480349196088,"details":{"who":"All users who have this add-on installed.","created":"2016-05-09T17:28:18Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1251911","name":"YouTube Unblocker 2.0","why":"This add-on is a copy of YouTube Unblocker, which was originally blocked due to malicious activity."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"de305335-e9f3-f410-cf5c-f88b7ad4b088","schema":1480349193877},{"guid":"webbooster@iminent.com","blockID":"i630","enabled":true,"last_modified":1480349196032,"details":{"who":"All Firefox users who have any of these add-ons installed. Users who wish to continue using them can enable them in the Add-ons Manager.","created":"2014-06-26T15:49:27Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=866943","name":"Iminent Minibar","why":"These add-ons have been silently installed repeatedly, and change settings without user consent, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":["browser.startup.homepage","browser.search.defaultenginename"],"id":"d894ea79-8215-7a0c-b0e9-be328c3afceb","schema":1480349193877},{"guid":"jid1-uabu5A9hduqzCw@jetpack","blockID":"i1016","enabled":true,"last_modified":1480349196001,"details":{"who":"All users who have this add-on installed.","created":"2015-09-24T09:49:42Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1208051","name":"SpeedFox (malware)","why":"This add-on is injecting unwanted and unexpected advertisements into all web pages, and masking this behavior as ad-blocking in its code."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"31397419-3dfa-9db3-f1aa-e812d4220669","schema":1480349193877},{"guid":"/^firefox@(jumpflip|webconnect|browsesmart|mybuzzsearch|outobox|greygray|lemurleap|divapton|secretsauce|batbrowse|whilokii|linkswift|qualitink|browsefox|kozaka|diamondata|glindorus|saltarsmart|bizzybolt|websparkle)\\.(com?|net|org|info|biz)$/","blockID":"i548","enabled":true,"last_modified":1480349195955,"details":{"who":"All Firefox users who have one or more of these add-ons installed. If you wish to continue using any of these add-ons, they can be enabled in the Add-ons Manager.","created":"2014-01-30T15:06:01Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=937405","name":"Yontoo add-ons","why":"A large amount of add-ons developed by Yontoo are known to be silently installed and otherwise violate the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"bfaf3510-397e-48e6-cc4f-74202aaaed54","schema":1480349193877},{"guid":"firefox@bandoo.com","blockID":"i23","enabled":true,"last_modified":1480349195915,"details":{"who":"Users of Bandoo version 5.0 for Firefox 3.6 and later.","created":"2011-03-01T23:30:23Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=629634","name":"Bandoo","why":"This add-on causes a high volume of Firefox crashes."},"versionRange":[{"targetApplication":[{"minVersion":"3.7a1pre","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"}],"minVersion":"5.0","maxVersion":"5.0","severity":1}],"prefs":[],"id":"bd487cf4-3f6a-f956-a6e9-842ac8deeac5","schema":1480349193877},{"guid":"5nc3QHFgcb@r06Ws9gvNNVRfH.com","blockID":"i372","enabled":true,"last_modified":1480349195887,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-06-18T13:23:40Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=875752","name":"Flash Player 11 (malware)","why":"This add-on is malware pretending to be the Flash Player plugin."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"dc71fcf5-fae4-5a5f-6455-ca7bbe4202db","schema":1480349193877},{"guid":"/^(7tG@zEb\\.net|ru@gfK0J\\.edu)$/","blockID":"i854","enabled":true,"last_modified":1480349195851,"details":{"who":"All Firefox users who have this add-on installed.","created":"2015-02-09T15:41:36Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=952255","name":"youtubeadblocker (malware)","why":"This add-on is silently installed and performs unwanted actions, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"cfe42207-67a9-9b88-f80c-994e6bdd0c55","schema":1480349193877},{"guid":"{a7aae4f0-bc2e-a0dd-fb8d-68ce32c9261f}","blockID":"i378","enabled":true,"last_modified":1480349195823,"details":{"who":"All Firefox users who have installed this add-on.","created":"2013-06-18T15:58:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=865090","name":"Myanmar Extension for Facebook (malware)","why":"This extension is malware that hijacks Facebook accounts for malicious purposes."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"30ecd9b9-4023-d9ef-812d-f1a75bb189b0","schema":1480349193877},{"guid":"a88a77ahjjfjakckmmabsy278djasi@jetpack","blockID":"i1034","enabled":true,"last_modified":1480349195798,"details":{"who":"All users who have this add-on installed.","created":"2015-10-05T16:28:48Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1211171","name":"Fast Unlock (malware)","why":"This is a malicious add-on that takes over Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"f801f112-3e8f-770f-10db-384349a36026","schema":1480349193877},{"guid":"crossriderapp5060@crossrider.com","blockID":"i228","enabled":true,"last_modified":1480349195769,"details":{"who":"All Firefox users who have this add-on installed.","created":"2012-11-29T16:31:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=810016","name":"Savings Sidekick","why":"This add-on is silently side-installed by other software, and it overrides user preferences and inserts advertisements in web content."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"a37f76ac-7b77-b5a3-bac8-addaacf34bae","schema":1480349193877},{"guid":"/^(saamazon@mybrowserbar\\.com)|(saebay@mybrowserbar\\.com)$/","blockID":"i672","enabled":true,"last_modified":1480349195347,"details":{"who":"All Firefox users who have these add-ons installed. Users wishing to continue using these add-ons can enable them in the Add-ons Manager.","created":"2014-07-22T15:13:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1011337","name":"Spigot Shopping Assistant","why":"These add-ons are being silently installed, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"e072a461-ee5a-c83d-8d4e-5686eb585a15","schema":1480349193877},{"guid":"{b99c8534-7800-48fa-bd71-519a46cdc7e1}","blockID":"i596","enabled":true,"last_modified":1480349195319,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2014-06-12T13:19:59Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1011325","name":"BrowseMark","why":"This add-on is silently installed, in violation with our Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"f411bb0f-7c82-9061-4a80-cabc8ff45beb","schema":1480349193877},{"guid":"/^({94d62e35-4b43-494c-bf52-ba5935df36ef}|firefox@advanceelite\\.com|{bb7b7a60-f574-47c2-8a0b-4c56f2da9802})$/","blockID":"i856","enabled":true,"last_modified":1480349195286,"details":{"who":"All Firefox users who have this add-on installed.","created":"2015-02-09T15:51:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1130323","name":"AdvanceElite (malware)","why":"This add-on is silently installed and performs unwanted actions, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"e3d52650-d3e2-4cef-71f7-e6188f56fe4d","schema":1480349193877},{"guid":"{458fb825-2370-4973-bf66-9d7142141847}","blockID":"i1024","enabled":true,"last_modified":1480349195258,"details":{"who":"All users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2015-09-29T09:25:27Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1209588","name":"Web Shield","why":"This add-on hides itself in the Add-ons Manager, interrupts the Firefox update process, and reportedly causes other problems to users, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":["app.update.auto","app.update.enabled","app.update.interval","app.update.url"],"id":"32c5baa7-d547-eaab-302d-b873c83bfe2d","schema":1480349193877},{"guid":"{f2456568-e603-43db-8838-ffa7c4a685c7}","blockID":"i778","enabled":true,"last_modified":1480349195215,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-11-07T13:53:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1073810","name":"Sup-SW","why":"This add-on is silently installed into users' systems. It uses very unsafe practices to load its code, and leaks information of all web browsing activity. These are all violations of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"93568fa2-0cb7-4e1d-e893-d7261e81547c","schema":1480349193877},{"guid":"{77BEC163-D389-42c1-91A4-C758846296A5}","blockID":"i566","enabled":true,"last_modified":1480349195185,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-on Manager.","created":"2014-03-05T13:20:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=964594","name":"V-Bates","why":"This add-on is silently installed into Firefox, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"080edbac-25d6-e608-abdd-feb1ce7a9a77","schema":1480349193877},{"guid":"helper@vidscrab.com","blockID":"i1077","enabled":true,"last_modified":1480349195157,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using the add-on can enable it in the Add-ons Manager.","created":"2016-01-14T14:32:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1231010","name":"YouTube Video Downloader (from AddonCrop)","why":"This add-on injects remote scripts and injects unwanted content into web pages."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"36b2e1e0-5fda-bde3-db55-dfcbe24dfd04","schema":1480349193877},{"guid":"/^ext@WebexpEnhancedV1alpha[0-9]+\\.net$/","blockID":"i535","enabled":true,"last_modified":1480349195123,"details":{"who":"All Firefox users who have this add-on installed. If you wish to continue using this add-on, it can be enabled in the Add-ons Manager.","created":"2014-01-09T11:22:19Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=952717","name":"Webexp Enhanced","why":"This add-on is generally unwanted by users and uses multiple random IDs in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"c7d6a30d-f3ee-40fb-5256-138dd4593a61","schema":1480349193877},{"guid":"jid1-XLjasWL55iEE1Q@jetpack","blockID":"i578","enabled":true,"last_modified":1480349195058,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-04-28T16:25:03Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1002037","name":"Flash Player (malware)","why":"This is a malicious add-on that presents itself as \"Flash Player\" but is really injecting unwanted content into Facebook pages."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"1e75b2f0-02fc-77a4-ad2f-52a4caff1a71","schema":1480349193877},{"guid":"{a3a5c777-f583-4fef-9380-ab4add1bc2a8}","blockID":"i142","enabled":true,"last_modified":1480349195007,"details":{"who":"Todos los usuarios de Firefox que instalaron la versi\u00f3n 4.2 del complemento Cuevana Stream.\r\n\r\nAll Firefox users who have installed version 4.2 of the Cuevana Stream add-on.","created":"2012-09-18T13:37:47Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=792132","name":"Cuevana Stream (malicious version)","why":"Espa\u00f1ol\r\nUna versi\u00f3n maliciosa del complemento Cuevana Stream (4.2) fue colocada en el sitio Cuevana y distribuida a muchos usuarios del sitio. Esta versi\u00f3n recopila informaci\u00f3n de formularios web y los env\u00eda a una direcci\u00f3n remota con fines maliciosos. Se le recomienda a todos los usuarios que instalaron esta versi\u00f3n que cambien sus contrase\u00f1as inmediatamente, y que se actualicen a la nueva versi\u00f3n segura, que es la 4.3.\r\n\r\nEnglish\r\nA malicious version of the Cuevana Stream add-on (4.2) was uploaded to the Cuevana website and distributed to many of its users. This version takes form data and sends it to a remote location with malicious intent. It is recommended that all users who installed this version to update their passwords immediately, and update to the new safe version, version 4.3.\r\n\r\n"},"versionRange":[{"targetApplication":[],"minVersion":"4.2","maxVersion":"4.2","severity":3}],"prefs":[],"id":"91e551b9-7e94-60e2-f1bd-52f25844ab16","schema":1480349193877},{"guid":"{34712C68-7391-4c47-94F3-8F88D49AD632}","blockID":"i922","enabled":true,"last_modified":1480349194976,"details":{"who":"All Firefox users who have this add-on installed in Firefox 39 and above.\r\n","created":"2015-06-09T15:27:31Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1173154","name":"RealPlayer Browser Record Plugin","why":"Certain versions of this extension are causing startup crashes in Firefox 39 and above.\r\n"},"versionRange":[{"targetApplication":[{"minVersion":"39.0a1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"}],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"dd350efb-34ac-2bb5-5afd-eed722dbb916","schema":1480349193877},{"guid":"PDVDZDW52397720@XDDWJXW57740856.com","blockID":"i846","enabled":true,"last_modified":1480349194949,"details":{"who":"All Firefox users who have this add-on installed.","created":"2015-02-06T15:03:39Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1128320","name":"Ge-Force","why":"This add-on is silently installed and attempts to change user settings like the home page and default search, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":["browser.startup.homepage","browser.search.defaultenginename"],"id":"c33e950c-c977-ed89-c86a-3be8c4be1967","schema":1480349193877},{"guid":"{977f3b97-5461-4346-92c8-a14c749b77c9}","blockID":"i69","enabled":true,"last_modified":1480349194919,"details":{"who":"All Firefox users who have this add-on installed.","created":"2012-02-22T16:41:23Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=729356","name":"Zuperface+","why":"This add-on adds apps to users' accounts, with full access permissions, and sends spam posts using these apps, all without any consent from users."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"f105bdc7-7ebd-587c-6344-1533249f50b3","schema":1480349193877},{"guid":"discoverypro@discoverypro.com","blockID":"i582","enabled":true,"last_modified":1480349194878,"details":{"who":"All Firefox users who have this add-on installed. If you wish to continue using this add-on, you can enabled it in the Add-ons Manager.","created":"2014-04-30T16:10:03Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1004231","name":"Website Discovery Pro","why":"This add-on is silently installed by the CNET installer for MP3 Rocket and probably other software packages. This is in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"34eab242-6fbc-a459-a89e-0dc1a0b8355d","schema":1480349193877},{"guid":"jid1-bKSXgRwy1UQeRA@jetpack","blockID":"i680","enabled":true,"last_modified":1480349194851,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using this add-on can enable it in the Add-ons Manager.","created":"2014-08-01T16:34:01Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=979856","name":"Trusted Shopper","why":"This add-on is silently installed into user's systems, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"f701b790-b266-c69d-0fba-f2d189cb0f34","schema":1480349193877},{"guid":"bcVX5@nQm9l.org","blockID":"i848","enabled":true,"last_modified":1480349194799,"details":{"who":"All Firefox users who have this add-on installed.","created":"2015-02-09T15:21:17Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1128266","name":"boomdeal","why":"This add-on is silently installed and performs unwanted actions, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"f8d6d4e1-b9e6-07f5-2b49-192106a45d82","schema":1480349193877},{"guid":"aytac@abc.com","blockID":"i504","enabled":true,"last_modified":1480349194724,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-12-06T12:07:58Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=947341","name":"Facebook Haber (malware)","why":"This is a malicious extension that hijacks users' Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"bfaf8298-dd69-165c-e1ed-ad55584abd18","schema":1480349193877},{"guid":"Adobe@flash.com","blockID":"i136","enabled":true,"last_modified":1480349194647,"details":{"who":"All Firefox users who have this add-on installed.","created":"2012-09-10T16:09:06Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=790100","name":"Adobe Flash (malware)","why":"This add-on is malware posing as a legitimate Adobe product."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"47ac744e-3176-5cb6-1d02-b460e0c7ada0","schema":1480349193877},{"guid":"{515b2424-5911-40bd-8a2c-bdb20286d8f5}","blockID":"i491","enabled":true,"last_modified":1480349194580,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-11-29T14:52:24Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=940753","name":"Connect DLC","why":"The installer that includes this add-on violates the Add-on Guidelines by making changes that can't be easily reverted."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"6d658443-b34a-67ad-934e-cbf7cd407460","schema":1480349193877},{"guid":"/^({3f3cddf8-f74d-430c-bd19-d2c9147aed3d}|{515b2424-5911-40bd-8a2c-bdb20286d8f5}|{17464f93-137e-4646-a0c6-0dc13faf0113}|{d1b5aad5-d1ae-4b20-88b1-feeaeb4c1ebc}|{aad50c91-b136-49d9-8b30-0e8d3ead63d0})$/","blockID":"i516","enabled":true,"last_modified":1480349194521,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-12-20T12:38:20Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=947478","name":"Connect DLC","why":"The installer that includes this add-on violates the Add-on Guidelines by making changes that can't be easily reverted and being distributed under multiple add-on IDs."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"96f8e157-8b8b-8e2e-76cd-6850599b4370","schema":1480349193877},{"guid":"wxtui502n2xce9j@no14","blockID":"i1012","enabled":true,"last_modified":1480349194463,"details":{"who":"All users who have this add-on installed.","created":"2015-09-21T13:04:09Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1206157","name":"Video fix (malware)","why":"This is a malicious add-on that takes over Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"246798ac-25fa-f4a4-258c-a71f9f6ae091","schema":1480349193877},{"guid":"flashX@adobe.com","blockID":"i168","enabled":true,"last_modified":1480349194428,"details":{"who":"All Firefox users who have this add-on installed.","created":"2012-10-30T12:07:41Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=807052","name":"Zombie Browser Pack","why":"This is an exploit proof-of-concept created for a conference presentation, which will probably be copied and modified for malicious purposes. \r\n"},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"d7c69812-801c-8d8e-12cb-c5171bdc48a1","schema":1480349193877},{"guid":"/^(ff\\-)?dodate(kKKK|XkKKK|k|kk|kkx|kR)@(firefox|flash(1)?)\\.pl|dode(ee)?k@firefoxnet\\.pl|(addon|1)@upsolutions\\.pl$/","blockID":"i1278","enabled":true,"last_modified":1480349194386,"details":{"who":"Any user with a version of this add-on installed.","created":"2016-10-27T10:52:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312748","name":"Aktualizacja dodatku Flash Add-on","why":"This add-on claims to be a flash plugin and it does some work on youtube, but it also steals your facebook and adfly credentials and sends them to a remote server."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"389aec65-a15d-8276-c7a8-691ac283c9f1","schema":1480349193877},{"guid":"tmbepff@trendmicro.com","blockID":"i1223","enabled":true,"last_modified":1480349194331,"details":{"who":"All users of this add-on. If you wish to continue using it, you can enable it in the Add-ons Manager.","created":"2016-05-30T17:07:04Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1275245","name":"Trend Micro BEP 9.2 to 9.2.0.1023","why":"Add-on is causing a high-frequency crash in Firefox."},"versionRange":[{"targetApplication":[],"minVersion":"9.2","maxVersion":"9.2.0.1023","severity":1}],"prefs":[],"id":"46f75b67-2675-bdde-be93-7ea03475d405","schema":1480349193877},{"guid":"{4889ddce-7a83-45e6-afc9-1e4f1149fff4}","blockID":"i840","enabled":true,"last_modified":1480349193867,"details":{"who":"All Firefox users who have this add-on installed.","created":"2015-02-06T14:30:06Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1128327","name":"Cyti Web (malware)","why":"This add-on is silently installed and performs unwanted actions, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"be600f35-0633-29f3-c571-819e19d85db9","schema":1480343836083},{"guid":"{55dce8ba-9dec-4013-937e-adbf9317d990","blockID":"i690","enabled":true,"last_modified":1480349193833,"details":{"who":"All Firefox users. Users who wish to continue using this add-on can enable it in the Add-ons Manager.","created":"2014-08-12T16:23:46Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1048647","name":"Deal Keeper","why":"This add-on is being silently installed in users' systems, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"512b0d40-a10a-5ddc-963b-b9c487eb1422","schema":1480343836083},{"guid":"/^new@kuot\\.pro|{13ec6687-0b15-4f01-a5a0-7a891c18e4ee}|rebeccahoppkins(ty(tr)?)?@gmail\\.com|{501815af-725e-45be-b0f2-8f36f5617afc}|{9bdb5f1f-b1e1-4a75-be31-bdcaace20a99}|{e9d93e1d-792f-4f95-b738-7adb0e853b7b}|dojadewaskurwa@gmail\\.com$/","blockID":"i1414","enabled":true,"last_modified":1480349193798,"details":{"who":"All users who have this add-on installed.","created":"2016-10-28T18:06:03Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312748","name":"Aktualizacja dodatku Flash (malware)","why":"This add-on claims to be a flash plugin and it does some work on youtube, but it also steals your facebook and adfly credentials and sends them to a remote server."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"5cebc983-bc88-d5f8-6807-bd1cbfcd82fd","schema":1480343836083},{"guid":"/^pink@.*\\.info$/","blockID":"i238","enabled":true,"last_modified":1480349193764,"details":{"who":"All Firefox users (Firefox 19 and above) who have any of these add-ons installed.","created":"2012-12-07T13:46:20Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=806543","name":"Pink add-ons (malware)","why":"This is a set of malicious add-ons that affect many users and are installed without their consent."},"versionRange":[{"targetApplication":[{"minVersion":"18.0","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"}],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"0d964264-8bd6-b78d-3c6c-92046c7dc8d0","schema":1480343836083},{"guid":"{58d2a791-6199-482f-a9aa-9b725ec61362}","blockID":"i746","enabled":true,"last_modified":1480349193730,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2014-10-17T16:01:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=963787","name":"Start Page","why":"This add-on is silently installed into users' systems, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"8ebbc7d0-635c-b74a-de9f-16eb5837b36a","schema":1480343836083},{"guid":"{94cd2cc3-083f-49ba-a218-4cda4b4829fd}","blockID":"i590","enabled":true,"last_modified":1480349193649,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using this add-on can enable it in the Add-ons Manager.","created":"2014-06-03T16:12:50Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1013678","name":"Value Apps","why":"This add-on is silently installed into users' profiles, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"556b8d4d-d6c2-199d-9f33-8eccca07e8e7","schema":1480343836083},{"guid":"contentarget@maildrop.cc","blockID":"i818","enabled":true,"last_modified":1480349193622,"details":{"who":"All Firefox users who have this add-on installed.","created":"2015-01-12T09:29:19Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1119971","name":"Astro Play (malware)","why":"This is a malicious extension that hijacks Facebook accounts."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"440e9923-027a-6089-e036-2f78937dc193","schema":1480343836083},{"guid":"unblocker30__web@unblocker.yt","blockID":"i1228","enabled":true,"last_modified":1480349193595,"details":{"who":"All users who have this add-on installed.","created":"2016-06-01T15:17:22Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1251911","name":"YouTube Unblocker 3.0","why":"This add-on is a copy of YouTube Unblocker, which was originally blocked due to malicious activity."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"2d83e640-ef9d-f260-f5a3-a1a5c8390bfc","schema":1480343836083},{"guid":"noOpus@outlook.com","blockID":"i816","enabled":true,"last_modified":1480349193537,"details":{"who":"All Firefox users who have this add-on installed.","created":"2015-01-09T12:52:32Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1119659","name":"Full Screen (malware)","why":"This add-on is silently installed into users' systems without their consent and performs unwanted operations."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"b64d7cef-8b6c-2575-16bc-732fca7db377","schema":1480343836083},{"guid":"{c95a4e8e-816d-4655-8c79-d736da1adb6d}","blockID":"i433","enabled":true,"last_modified":1480349193510,"details":{"who":"All Firefox users who have this add-on installed.","created":"2013-08-09T11:25:49Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=844945","name":"Hotspot Shield","why":"This add-on bypasses the external install opt in screen in Firefox, violating the Add-on Guidelines. Users who wish to continue using this add-on can enable it in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"b3168278-a8ae-4882-7f26-355bc362bed0","schema":1480343836083},{"guid":"{9802047e-5a84-4da3-b103-c55995d147d1}","blockID":"i722","enabled":true,"last_modified":1480349193482,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-10-07T12:58:14Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1073810","name":"Web Finder Pro","why":"This add-on is silently installed into users' systems. It uses very unsafe practices to load its code, and leaks information of all web browsing activity. These are all violations of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"50097c29-26b1-bf45-ffe1-83da217eb127","schema":1480343836083},{"guid":"/^({bf9194c2-b86d-4ebc-9b53-1c08b6ff779e}|{61a83e16-7198-49c6-8874-3e4e8faeb4f3}|{f0af464e-5167-45cf-9cf0-66b396d1918c}|{5d9968c3-101c-4944-ba71-72d77393322d}|{01e86e69-a2f8-48a0-b068-83869bdba3d0})$/","blockID":"i515","enabled":true,"last_modified":1480349193449,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using it can enable it in the Add-ons Manager.","created":"2013-12-20T12:26:49Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=947473","name":"VisualBee Toolbar","why":"The installer that includes this add-on violates the Add-on Guidelines by using multiple add-on IDs and making unwanted settings changes."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"029fa6f9-2351-40b7-5443-9a66e057f199","schema":1480343836083},{"guid":"/^({d50bfa5f-291d-48a8-909c-5f1a77b31948}|{d54bc985-6e7b-46cd-ad72-a4a266ad879e}|{d89e5de3-5543-4363-b320-a98cf150f86a}|{f3465017-6f51-4980-84a5-7bee2f961eba}|{fae25f38-ff55-46ea-888f-03b49aaf8812})$/","blockID":"i1137","enabled":true,"last_modified":1480349193419,"details":{"who":"All users who have this add-on installed.","created":"2016-03-04T17:56:42Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1251940","name":"Watcher (malware)","why":"This is a malicious add-on that hides itself from view and disables various security features in Firefox."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"252e18d0-85bc-7bb3-6197-5f126424c9b3","schema":1480343836083},{"guid":"ffxtlbr@claro.com","blockID":"i218","enabled":true,"last_modified":1480349193385,"details":{"who":"All Firefox users who have installed this add-on.","created":"2012-11-29T16:07:00Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=816762","name":"Claro Toolbar","why":"The Claro Toolbar is side-installed with other software, unexpectedly changing users' settings and then making it impossible for these settings to be reverted by users."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"e017a3b2-9b37-b8a0-21b0-bc412ae8a7f4","schema":1480343836083},{"guid":"/^(.*@(unblocker\\.yt|sparpilot\\.com))|(axtara@axtara\\.com)$/","blockID":"i1229","enabled":true,"last_modified":1480349193344,"details":{"who":"All users who have this add-on installed.","created":"2016-06-03T15:28:39Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1251911","name":"YouTube Unblocker (various)","why":"These add-ons are copies of YouTube Unblocker, which was originally blocked due to malicious activity."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"c677cc5d-5b1e-8aa2-5cea-5a8dddce2ecf","schema":1480343836083},{"guid":"/^(j003-lqgrmgpcekslhg|SupraSavings|j003-dkqonnnthqjnkq|j003-kaggrpmirxjpzh)@jetpack$/","blockID":"i692","enabled":true,"last_modified":1480349193295,"details":{"who":"All Firefox users who have this add-on installed. Users who wish to continue using this add-on can enable it in the Add-ons Manager.","created":"2014-08-12T16:27:06Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1048656","name":"SupraSavings","why":"This add-on is being silently installed in users' systems, in violation of the Add-on Guidelines."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"b0d30256-4581-1489-c241-d2e85b6c38f4","schema":1480343836083},{"guid":"helperbar@helperbar.com","blockID":"i258","enabled":true,"last_modified":1480349193254,"details":{"who":"All Firefox users who have this add-on installed. This only applies to version 1.0 of Snap.do. Version 1.1 fixed all the issues for which this block was created.","created":"2013-01-28T13:52:26Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=817786","name":"Snap.do","why":"This extension violates a number of our Add-on Guidelines, particularly on installation and settings handling. It also causes some stability problems in Firefox due to the way the toolbar is handled.\r\n\r\nUsers who wish to keep the add-on enabled can enable it again in the Add-ons Manager."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"1.0","severity":1}],"prefs":[],"id":"f1ede5b8-7757-5ec5-d8ed-1a01889154aa","schema":1480343836083},{"guid":"/^((support2_en@adobe14\\.com)|(XN4Xgjw7n4@yUWgc\\.com)|(C7yFVpIP@WeolS3acxgS\\.com)|(Kbeu4h0z@yNb7QAz7jrYKiiTQ3\\.com)|(aWQzX@a6z4gWdPu8FF\\.com)|(CBSoqAJLYpCbjTP90@JoV0VMywCjsm75Y0toAd\\.com)|(zZ2jWZ1H22Jb5NdELHS@o0jQVWZkY1gx1\\.com))$/","blockID":"i326","enabled":true,"last_modified":1480349193166,"details":{"who":"All users who have this add-on installed.","created":"2013-03-22T14:49:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=841791","name":"Flash Player (malware)","why":"This extension is malware, installed pretending to be the Flash Player plugin."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"3142020b-8af9-1bac-60c5-ce5ad0ff3d42","schema":1480343836083},{"guid":"newmoz@facebook.com","blockID":"i576","enabled":true,"last_modified":1480349193114,"details":{"who":"All Firefox users who have this add-on installed.","created":"2014-04-22T14:34:42Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=997986","name":"Facebook Service Pack (malware)","why":"This add-on is malware that hijacks Facebook user accounts and sends spam on the user's behalf."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"d85798d3-9b87-5dd9-ace2-64914b93df77","schema":1480343836083},{"guid":"flvto@hotger.com","blockID":"i1211","enabled":true,"last_modified":1480349193088,"details":{"who":"All users of this add-on. If you wish to continue using it, you can enable it in the Add-ons Manager.","created":"2016-05-04T16:26:32Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1270175","name":"YouTube to MP3 Button","why":"This add-on reports every visited URL to a third party without disclosing it to the user."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":1}],"prefs":[],"id":"a14d355f-719f-3b97-506c-083cc97cebaa","schema":1480343836083},{"guid":"{0F827075-B026-42F3-885D-98981EE7B1AE}","blockID":"i334","enabled":true,"last_modified":1480349192987,"details":{"who":"All Firefox users who have this extension installed.","created":"2013-04-16T13:25:01Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=862272","name":"Browser Protect / bProtector (malware)","why":"This extension is malicious and is installed under false pretenses, causing problems for many Firefox users. Note that this is not the same BrowserProtect extension that is listed on our add-ons site. That one is safe to use."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":3}],"prefs":[],"id":"aad4545f-8f9d-dd53-2aa8-e8945cad6185","schema":1480343836083}]} \ No newline at end of file diff --git a/services/blocklists/certificates.json b/services/blocklists/certificates.json new file mode 100644 index 000000000000..1739698d5718 --- /dev/null +++ b/services/blocklists/certificates.json @@ -0,0 +1 @@ +{"data":[{"serialNumber":"TA5iEg==","enabled":true,"last_modified":1485907697001,"details":{"who":".","created":"2017-01-31T23:06:38Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1334069","name":"Revoked intermediates","why":"."},"issuerName":"MIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp","id":"16319df7-453c-d980-4624-d73d9cf43143","schema":1485795317518},{"serialNumber":"BydSYg==","enabled":true,"last_modified":1485907696954,"details":{"who":".","created":"2017-01-31T23:06:37Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1334069","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=","id":"ec171905-2990-30e0-74bb-9fc327c1c4bd","schema":1485795317518},{"serialNumber":"Iqpyf/YoGgvHc8HiDAxAI8o=","enabled":true,"last_modified":1485907696908,"details":{"who":".","created":"2017-01-31T23:06:38Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1334069","name":"Revoked intermediates","why":"."},"issuerName":"MFwxCzAJBgNVBAYTAkJFMRUwEwYDVQQLEwxUcnVzdGVkIFJvb3QxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExGzAZBgNVBAMTElRydXN0ZWQgUm9vdCBDQSBHMg==","id":"6fa017d2-461c-8de0-f8a1-ab0531097d8e","schema":1485795317518},{"serialNumber":"Hwexgn/ZCJicZPcsIyI8zxQ=","enabled":true,"last_modified":1485907696863,"details":{"who":".","created":"2017-01-31T23:06:38Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1334069","name":"Revoked intermediates","why":"."},"issuerName":"MFAxJDAiBgNVBAsTG0dsb2JhbFNpZ24gRUNDIFJvb3QgQ0EgLSBSNDETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbg==","id":"4df86909-6b1c-f7cd-c71b-bb4b895d441f","schema":1485795317518},{"serialNumber":"RnQ3dg5KdDZs0nyFZk4=","enabled":true,"last_modified":1485907696819,"details":{"who":".","created":"2017-01-31T23:06:38Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1334069","name":"Revoked intermediates","why":"."},"issuerName":"MFAxJDAiBgNVBAsTG0dsb2JhbFNpZ24gRUNDIFJvb3QgQ0EgLSBSNDETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbg==","id":"0971a89d-b11f-97c9-2ac2-f706757b75fb","schema":1485795317518},{"serialNumber":"RnQ3dYovwvB0D5q2YGY=","enabled":true,"last_modified":1485907696773,"details":{"who":".","created":"2017-01-31T23:06:38Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1334069","name":"Revoked intermediates","why":"."},"issuerName":"MFAxJDAiBgNVBAsTG0dsb2JhbFNpZ24gRUNDIFJvb3QgQ0EgLSBSNDETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbg==","id":"d739cdcd-0078-92a9-2c46-6a5231f3d888","schema":1485795317518},{"serialNumber":"ALxyZmb/WL/wAuUiPK5oK/g=","enabled":true,"last_modified":1484704581273,"details":{"who":".","created":"2017-01-18T01:12:58Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1329981","name":"Revoked intermediates","why":"."},"issuerName":"MD4xCzAJBgNVBAYTAlBMMRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBDQQ==","id":"d6bedca3-c2b7-0402-337e-7788b9c97b85","schema":1484704580928},{"serialNumber":"AKrMYlJmUUin8FOM/0TJrmk=","enabled":true,"last_modified":1484704580920,"details":{"who":".","created":"2017-01-18T01:12:58Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1329981","name":"Revoked intermediates","why":"."},"issuerName":"MIGFMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01PRE8gQ0EgTGltaXRlZDErMCkGA1UEAxMiQ09NT0RPIFJTQSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQ==","id":"42e2ce60-f40f-97a6-dd47-3ea2e2dd72d8","schema":1483471396473},{"serialNumber":"e7wSpVxmgAS5/ioLi2iBIA==","enabled":true,"last_modified":1484704580894,"details":{"who":".","created":"2017-01-18T01:12:58Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1329981","name":"Revoked intermediates","why":"."},"issuerName":"MD4xCzAJBgNVBAYTAlBMMRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBDQQ==","id":"59b02ba9-97ec-924b-d797-2c61c2be0d87","schema":1483471396473},{"serialNumber":"Bydrxg==","enabled":true,"last_modified":1484704580868,"details":{"who":".","created":"2017-01-18T01:12:58Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1329981","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=","id":"224d1360-5aed-b81f-f24c-3d34e2ca3ec4","schema":1483471396473},{"serialNumber":"Byc85g==","enabled":true,"last_modified":1484704580840,"details":{"who":".","created":"2017-01-18T01:12:58Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1329981","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=","id":"25a0eefb-aa44-23df-4dda-bb166836d4c1","schema":1483471396473},{"serialNumber":"CdYL9vSQCEKzBwjO10ud2w==","enabled":true,"last_modified":1484704580815,"details":{"who":".","created":"2017-01-18T01:12:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1329981","name":"Revoked intermediates","why":"."},"issuerName":"MDwxGzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBDQTEQMA4GA1UEChMHQ29tU2lnbjELMAkGA1UEBhMCSUw=","id":"479ac2a4-7b6a-8db3-c5a2-be10eb5dec57","schema":1483471396473},{"serialNumber":"fbsHfUkagQtznc3rtY1uDg==","enabled":true,"last_modified":1484704580787,"details":{"who":".","created":"2017-01-18T01:12:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1329981","name":"Revoked intermediates","why":"."},"issuerName":"MDwxGzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBDQTEQMA4GA1UEChMHQ29tU2lnbjELMAkGA1UEBhMCSUw=","id":"b1b1a5db-3c68-21be-8264-7146b0ee9e6b","schema":1483471396473},{"serialNumber":"AJiU+bpWh2Uc4xFRf8GM9yA=","enabled":true,"last_modified":1484704580760,"details":{"who":".","created":"2017-01-18T01:12:58Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1329981","name":"Revoked intermediates","why":"."},"issuerName":"MD8xJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjEXMBUGA1UEAxMORFNUIFJvb3QgQ0EgWDM=","id":"60daf8a1-a929-0177-e7ba-76fff95fd20b","schema":1483471396473},{"serialNumber":"Hnms0W0OxHSYE2F0XE97sw==","enabled":true,"last_modified":1484704580734,"details":{"who":".","created":"2017-01-18T01:12:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1329981","name":"Revoked intermediates","why":"."},"issuerName":"MDwxGzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBDQTEQMA4GA1UEChMHQ29tU2lnbjELMAkGA1UEBhMCSUw=","id":"55b72394-f4c1-3001-cf84-10f2068f2768","schema":1483471396473},{"serialNumber":"Bye2Cg==","enabled":true,"last_modified":1484704580708,"details":{"who":".","created":"2017-01-18T01:12:58Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1329981","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=","id":"e2277fc3-1aac-7c20-0cb7-f4fd6c79eedb","schema":1483471396473},{"serialNumber":"CMNfzETd7XxesS9FOUj9Mg==","enabled":true,"last_modified":1484704580680,"details":{"who":".","created":"2017-01-18T01:12:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1329981","name":"Revoked intermediates","why":"."},"issuerName":"MIGVMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTEdMBsGA1UEAxMUVVROLVVTRVJGaXJzdC1PYmplY3Q=","id":"49251465-af0d-3e93-cb1a-9d0b2ac356b2","schema":1483471396473},{"serialNumber":"XJ8pGvGNM9RIcLUG9YQjLQ==","enabled":true,"last_modified":1484704580653,"details":{"who":".","created":"2017-01-18T01:12:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1329981","name":"Revoked intermediates","why":"."},"issuerName":"MDwxGzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBDQTEQMA4GA1UEChMHQ29tU2lnbjELMAkGA1UEBhMCSUw=","id":"c83b4498-ea23-7723-1c2c-b673115792d8","schema":1483471396473},{"serialNumber":"e9JTGBe45yw=","enabled":true,"last_modified":1484704580623,"details":{"who":".","created":"2017-01-18T01:12:58Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1329981","name":"Revoked intermediates","why":"."},"issuerName":"MGoxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xOzA5BgNVBAMMMlN0YWF0IGRlciBOZWRlcmxhbmRlbiBPcmdhbmlzYXRpZSBTZXJ2aWNlcyBDQSAtIEcz","id":"20d69a85-62b2-72c7-1107-110b43d2aeb2","schema":1483471396473},{"serialNumber":"YR0zGQAAAAAAAw==","enabled":true,"last_modified":1484704580597,"details":{"who":".","created":"2017-01-18T01:12:58Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1329981","name":"Revoked intermediates","why":"."},"issuerName":"MGcxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpGcmF1bmhvZmVyMSEwHwYDVQQLExhGcmF1bmhvZmVyIENvcnBvcmF0ZSBQS0kxIDAeBgNVBAMTF0ZyYXVuaG9mZXIgUm9vdCBDQSAyMDA3","id":"4204c7d6-1838-5925-2461-1bc0e03515d4","schema":1483471396473},{"serialNumber":"AQw=","enabled":true,"last_modified":1484704580571,"details":{"who":".","created":"2017-01-18T01:12:58Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1329981","name":"Revoked intermediates","why":"."},"issuerName":"MHExCzAJBgNVBAYTAkRFMRwwGgYDVQQKExNEZXV0c2NoZSBUZWxla29tIEFHMR8wHQYDVQQLExZULVRlbGVTZWMgVHJ1c3QgQ2VudGVyMSMwIQYDVQQDExpEZXV0c2NoZSBUZWxla29tIFJvb3QgQ0EgMg==","id":"f8c41076-a3f0-439a-9d5e-41e27e019a77","schema":1483471396473},{"serialNumber":"ESDDtMgFFiaUfKo7HD9qImM7","enabled":true,"last_modified":1484704580544,"details":{"who":".","created":"2017-01-18T01:12:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1329981","name":"Revoked intermediates","why":"."},"issuerName":"MEAxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEcx","id":"ec0960f7-7ae1-23e7-5006-6652da817daa","schema":1483471396473},{"serialNumber":"RFlmmjulj6Ve7PfBi44nnw==","enabled":true,"last_modified":1484704580517,"details":{"who":".","created":"2017-01-18T01:12:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1329981","name":"Revoked intermediates","why":"."},"issuerName":"MCgxCzAJBgNVBAYTAkJFMRkwFwYDVQQDExBCZWxnaXVtIFJvb3QgQ0Ey","id":"0e7b9a2c-3604-5b89-4dff-796122174bdc","schema":1483471396473},{"serialNumber":"ESBrHE7sFC7CQ8EM681xA3CY","enabled":true,"last_modified":1484704580491,"details":{"who":".","created":"2017-01-18T01:12:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1329981","name":"Revoked intermediates","why":"."},"issuerName":"MEAxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEcx","id":"0595dc75-9356-ba32-a15e-05e3072b7f54","schema":1483471396473},{"serialNumber":"AjpW","enabled":true,"last_modified":1484704580465,"details":{"who":".","created":"2017-01-18T01:12:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1329981","name":"Revoked intermediates","why":"."},"issuerName":"MEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0E=","id":"b7e26b4d-bbe1-1c4e-ef9b-12471bcb9bf8","schema":1483471396473},{"serialNumber":"a9rf7/BmG9JkKvRuy7J5QA==","enabled":true,"last_modified":1484704580438,"details":{"who":".","created":"2017-01-18T01:12:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1329981","name":"Revoked intermediates","why":"."},"issuerName":"MIGVMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTEdMBsGA1UEAxMUVVROLVVTRVJGaXJzdC1PYmplY3Q=","id":"fcfc3b3c-0a59-d143-f5fd-7600dd8efa87","schema":1483471396473},{"serialNumber":"ZECgRdZEsns=","enabled":true,"last_modified":1484704580412,"details":{"who":".","created":"2017-01-18T01:12:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1329981","name":"Revoked intermediates","why":"."},"issuerName":"MGExCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xMjAwBgNVBAMMKVN0YWF0IGRlciBOZWRlcmxhbmRlbiBPcmdhbmlzYXRpZSBDQSAtIEcy","id":"4652f392-127d-a5bf-4ed6-b07b9fa72247","schema":1483471396473},{"serialNumber":"AJBQSPqrEvDE2Hz8xH39Low=","enabled":true,"last_modified":1484704580385,"details":{"who":".","created":"2017-01-18T01:12:58Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1329981","name":"Revoked intermediates","why":"."},"issuerName":"MD8xJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjEXMBUGA1UEAxMORFNUIFJvb3QgQ0EgWDM=","id":"c279dd67-2ce1-e090-1e04-0c11fe3ddf8e","schema":1483471396473},{"serialNumber":"frj5jTuqBnQ4fljPvVU3KA==","enabled":true,"last_modified":1484704580358,"details":{"who":".","created":"2017-01-18T01:12:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1329981","name":"Revoked intermediates","why":"."},"issuerName":"MCgxCzAJBgNVBAYTAkJFMRkwFwYDVQQDExBCZWxnaXVtIFJvb3QgQ0Ey","id":"85acb18c-16b6-12c7-83ae-1e0d94251362","schema":1483471396473},{"serialNumber":"ByfFnw==","enabled":true,"last_modified":1484704580332,"details":{"who":".","created":"2017-01-18T01:12:58Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1329981","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=","id":"d0da2ea3-1cad-5c9e-4c75-c83acfeabc8d","schema":1483471396473},{"serialNumber":"ByembA==","enabled":true,"last_modified":1484704580305,"details":{"who":".","created":"2017-01-18T01:12:58Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1329981","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=","id":"fcd51190-7eaf-291e-b6e5-45e447de7291","schema":1483471396473},{"serialNumber":"RH7WhshwXRK6f0VfOfjXgQ==","enabled":true,"last_modified":1484704580277,"details":{"who":".","created":"2017-01-18T01:12:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1329981","name":"Revoked intermediates","why":"."},"issuerName":"MCgxCzAJBgNVBAYTAkJFMRkwFwYDVQQDExBCZWxnaXVtIFJvb3QgQ0Ey","id":"003234b2-f425-eae6-9596-040747dab2b9","schema":1483471396473},{"serialNumber":"SurdtfsuPcXXDpY2LkBpYO6BT7o=","enabled":true,"last_modified":1483471394790,"details":{"who":".","created":"2017-01-03T18:41:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDM=","id":"034627e4-44c6-fbf2-275a-4ed3431a4094","schema":1483471393228},{"serialNumber":"Er0moq4zwH8ke2pYafIKdg==","enabled":true,"last_modified":1483471394768,"details":{"who":".","created":"2017-01-03T18:41:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMw==","id":"85c81ed8-787f-ffcf-2a63-1be622db8d04","schema":1483471393228},{"serialNumber":"BydiAg==","enabled":true,"last_modified":1483471394746,"details":{"who":".","created":"2017-01-03T18:41:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=","id":"9194c97e-3baa-0446-9642-0d6211c3f019","schema":1483471393228},{"serialNumber":"eLumDUO40KwnecZLJxFM2A==","enabled":true,"last_modified":1483471394725,"details":{"who":".","created":"2017-01-03T18:41:52Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MCgxCzAJBgNVBAYTAkJFMRkwFwYDVQQDExBCZWxnaXVtIFJvb3QgQ0Ey","id":"c2cc63c7-5274-9901-5f67-0a13355a8aa8","schema":1483471393228},{"serialNumber":"Bw==","enabled":true,"last_modified":1483471394702,"details":{"who":".","created":"2017-01-03T18:41:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MDQxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25h","id":"92e2494f-f3cd-7638-7fe1-a3cb8d8939fa","schema":1483471393228},{"serialNumber":"GpO48aJ8GngtwECqZhm/xA==","enabled":true,"last_modified":1483471394681,"details":{"who":".","created":"2017-01-03T18:41:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAy","id":"bdfdc34f-ba9a-7b25-6cb6-24c547eb8a10","schema":1483471393228},{"serialNumber":"Cw==","enabled":true,"last_modified":1483471394658,"details":{"who":".","created":"2017-01-03T18:41:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MFIxCzAJBgNVBAYTAk5MMRkwFwYDVQQKDBBEaWdpZGVudGl0eSBCLlYuMSgwJgYDVQQDDB9EaWdpZGVudGl0eSBPcmdhbmlzYXRpZSBDQSAtIEcy","id":"7574eb9e-6978-dcb7-5a6f-d4c3dd855254","schema":1483471393228},{"serialNumber":"IA==","enabled":true,"last_modified":1483471394635,"details":{"who":".","created":"2017-01-03T18:41:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MDQxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25h","id":"d82f446f-181a-5ac3-0ced-854e3cde100c","schema":1483471393228},{"serialNumber":"OfJBIhFwAdQ=","enabled":true,"last_modified":1483471394613,"details":{"who":".","created":"2017-01-03T18:41:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MGsxCzAJBgNVBAYTAklUMQ4wDAYDVQQHDAVNaWxhbjEjMCEGA1UECgwaQWN0YWxpcyBTLnAuQS4vMDMzNTg1MjA5NjcxJzAlBgNVBAMMHkFjdGFsaXMgQXV0aGVudGljYXRpb24gUm9vdCBDQQ==","id":"b8fdddf1-27c1-5f6e-58a1-295e2c8c0ea5","schema":1483471393228},{"serialNumber":"MABJTA==","enabled":true,"last_modified":1483471394591,"details":{"who":".","created":"2017-01-03T18:41:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MEgxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdTZWN1cmVUcnVzdCBDb3Jwb3JhdGlvbjEXMBUGA1UEAxMOU2VjdXJlVHJ1c3QgQ0E=","id":"71e08617-c00a-8b62-53c2-2a61e21e6155","schema":1483471393228},{"serialNumber":"HA==","enabled":true,"last_modified":1483471394569,"details":{"who":".","created":"2017-01-03T18:41:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MDQxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25h","id":"6a6d36e6-8939-0a83-3fd5-c38652b165ed","schema":1483471393228},{"serialNumber":"DA==","enabled":true,"last_modified":1483471394547,"details":{"who":".","created":"2017-01-03T18:41:55Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"ME0xCzAJBgNVBAYTAk5MMRkwFwYDVQQKDBBEaWdpZGVudGl0eSBCLlYuMSMwIQYDVQQDDBpEaWdpZGVudGl0eSBCdXJnZXIgQ0EgLSBHMg==","id":"460643a1-23f3-1beb-0f14-ecb4b6e26cc9","schema":1483471393228},{"serialNumber":"CLc=","enabled":true,"last_modified":1483471394524,"details":{"who":".","created":"2017-01-03T18:41:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDM=","id":"49eb43cf-91d4-66ce-1a86-b8674ff83d4d","schema":1483471393228},{"serialNumber":"QAAnEQ==","enabled":true,"last_modified":1483471394501,"details":{"who":".","created":"2017-01-03T18:41:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MEoxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdTZWN1cmVUcnVzdCBDb3Jwb3JhdGlvbjEZMBcGA1UEAxMQU2VjdXJlIEdsb2JhbCBDQQ==","id":"bb5c827f-3458-93fe-f80f-2982f0d19d34","schema":1483471393228},{"serialNumber":"AjqK","enabled":true,"last_modified":1483471394478,"details":{"who":".","created":"2017-01-03T18:41:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0E=","id":"d6f9a6d9-d936-dfaf-d396-8ae96769ef10","schema":1483471393228},{"serialNumber":"ByfNeA==","enabled":true,"last_modified":1483471394453,"details":{"who":".","created":"2017-01-03T18:41:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=","id":"02ec8a09-2ae4-cd2a-4fa1-5037fa945391","schema":1483471393228},{"serialNumber":"JLiDzgpL7oFNgJN+jIjt7w==","enabled":true,"last_modified":1483471394090,"details":{"who":".","created":"2017-01-03T18:41:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBSb290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWU=","id":"5631f49c-a1fb-803e-ecf2-3ba82ca79f2e","schema":1483471393228},{"serialNumber":"BwImeaRkSZQLYwFREwKo3R1Jn+8=","enabled":true,"last_modified":1483471394067,"details":{"who":".","created":"2017-01-03T18:41:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDM=","id":"c2de8edd-fd89-36dd-63d0-d3a1df92274a","schema":1483471393228},{"serialNumber":"HxT1XSjIpzjMprp9Qu1gYQ==","enabled":true,"last_modified":1483471394046,"details":{"who":".","created":"2017-01-03T18:41:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAx","id":"46d4712b-6db2-ce7e-0efd-675f3be896cf","schema":1483471393228},{"serialNumber":"QDi5sA==","enabled":true,"last_modified":1483471394023,"details":{"who":".","created":"2017-01-03T18:41:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MIGCMQswCQYDVQQGEwJVUzEeMBwGA1UECxMVd3d3LnhyYW1wc2VjdXJpdHkuY29tMSQwIgYDVQQKExtYUmFtcCBTZWN1cml0eSBTZXJ2aWNlcyBJbmMxLTArBgNVBAMTJFhSYW1wIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQ==","id":"8acc0cad-dee8-7e2e-1799-e1a7b8b989c3","schema":1483471393228},{"serialNumber":"BA==","enabled":true,"last_modified":1483471394000,"details":{"who":".","created":"2017-01-03T18:41:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MDQxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25h","id":"b9ac21bb-8c1e-e562-5418-bbf6f6323c45","schema":1483471393228},{"serialNumber":"KuzHPJLdK5hNgJRo3R47Ag==","enabled":true,"last_modified":1483471393978,"details":{"who":".","created":"2017-01-03T18:41:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBSb290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWU=","id":"91b7f544-9de1-efea-08d4-4ebafc9a3608","schema":1483471393228},{"serialNumber":"B+U=","enabled":true,"last_modified":1483471393956,"details":{"who":".","created":"2017-01-03T18:41:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDM=","id":"86fe91df-ebb8-f20d-2031-2bc815b14a25","schema":1483471393228},{"serialNumber":"Byeaqw==","enabled":true,"last_modified":1483471393933,"details":{"who":".","created":"2017-01-03T18:41:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=","id":"b97a8dce-04d9-7dba-6463-ae95d61524f4","schema":1483471393228},{"serialNumber":"LU4d0t7PAsZNgJGZcb+o/w==","enabled":true,"last_modified":1483471393911,"details":{"who":".","created":"2017-01-03T18:41:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBSb290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWU=","id":"efdf0a12-4ba1-f84d-a88d-fc384251583c","schema":1483471393228},{"serialNumber":"BAAAAAABIg08FMU=","enabled":true,"last_modified":1483471393889,"details":{"who":".","created":"2017-01-03T18:41:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIyMRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu","id":"6c0561bc-fea3-ba35-bbdb-2b2672b67d36","schema":1483471393228},{"serialNumber":"AjqL","enabled":true,"last_modified":1483471393867,"details":{"who":".","created":"2017-01-03T18:41:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0E=","id":"4be7b89c-27a6-e95e-c6f9-bf652d4a0b97","schema":1483471393228},{"serialNumber":"FQ==","enabled":true,"last_modified":1483471393845,"details":{"who":".","created":"2017-01-03T18:41:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MDQxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25h","id":"89946691-d008-fd14-bd7a-443206d647c6","schema":1483471393228},{"serialNumber":"BydInw==","enabled":true,"last_modified":1483471393823,"details":{"who":".","created":"2017-01-03T18:41:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=","id":"e1a83fb0-93df-deb8-68cd-17f4997ea58b","schema":1483471393228},{"serialNumber":"JD1wxDd8IgmiqX7MyPPg1g==","enabled":true,"last_modified":1483471393801,"details":{"who":".","created":"2017-01-03T18:41:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAx","id":"f5ad7ea6-4ac9-b9cd-776f-d2afb53fb91b","schema":1483471393228},{"serialNumber":"Qh/SqA==","enabled":true,"last_modified":1483471393779,"details":{"who":".","created":"2017-01-03T18:41:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5","id":"ad8a2f72-7124-3e33-3060-414ce2bd8be3","schema":1483471393228},{"serialNumber":"J8mznxvTvOR5p4Br3a3sm5j5iM0=","enabled":true,"last_modified":1483471393750,"details":{"who":".","created":"2017-01-03T18:41:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAkZSMRMwEQYDVQQKEwpDZXJ0aW5vbWlzMRcwFQYDVQQLEw4wMDAyIDQzMzk5ODkwMzEdMBsGA1UEAxMUQ2VydGlub21pcyAtIFJvb3QgQ0E=","id":"d3f6b499-297d-e9c8-081c-44e2331bcf29","schema":1483471393228},{"serialNumber":"AIChpbGNqu4XKp9J70syKEs=","enabled":true,"last_modified":1483471393727,"details":{"who":".","created":"2017-01-03T18:41:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAy","id":"f184ba74-06de-9247-104e-160b6d210962","schema":1483471393228},{"serialNumber":"Cj0=","enabled":true,"last_modified":1483471393705,"details":{"who":".","created":"2017-01-03T18:41:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDM=","id":"c5fdcbc2-71d8-0a58-3375-0c7d92526cf1","schema":1483471393228},{"serialNumber":"Aw==","enabled":true,"last_modified":1483471393683,"details":{"who":".","created":"2017-01-03T18:41:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MDQxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25h","id":"0e8a05ee-feae-fc46-15b9-eaa2d11f4a60","schema":1483471393228},{"serialNumber":"BAAAAAABRE7wRk4=","enabled":true,"last_modified":1483471393659,"details":{"who":".","created":"2017-01-03T18:41:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIyMRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu","id":"ac8d3825-3fef-6d3e-2690-7360d1ef57a4","schema":1483471393228},{"serialNumber":"QDi5sQ==","enabled":true,"last_modified":1483471393637,"details":{"who":".","created":"2017-01-03T18:41:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MIGCMQswCQYDVQQGEwJVUzEeMBwGA1UECxMVd3d3LnhyYW1wc2VjdXJpdHkuY29tMSQwIgYDVQQKExtYUmFtcCBTZWN1cml0eSBTZXJ2aWNlcyBJbmMxLTArBgNVBAMTJFhSYW1wIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQ==","id":"4b03d4c1-705b-458e-5bdc-f729f67eeb91","schema":1483471393228},{"serialNumber":"WJ2qHzWUqTk=","enabled":true,"last_modified":1483471393615,"details":{"who":".","created":"2017-01-03T18:41:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MGsxCzAJBgNVBAYTAklUMQ4wDAYDVQQHDAVNaWxhbjEjMCEGA1UECgwaQWN0YWxpcyBTLnAuQS4vMDMzNTg1MjA5NjcxJzAlBgNVBAMMHkFjdGFsaXMgQXV0aGVudGljYXRpb24gUm9vdCBDQQ==","id":"f93061a9-8afa-1d74-e063-4134d318f00b","schema":1483471393228},{"serialNumber":"VUtahOwvvmJFwlvmGDZP5w==","enabled":true,"last_modified":1483471393592,"details":{"who":".","created":"2017-01-03T18:41:52Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MCgxCzAJBgNVBAYTAkJFMRkwFwYDVQQDExBCZWxnaXVtIFJvb3QgQ0Ey","id":"9c88bc12-466d-fcdd-cc53-349d4e041332","schema":1483471393228},{"serialNumber":"L1fHogsVxmfMBka5q4uzaQ==","enabled":true,"last_modified":1483471393569,"details":{"who":".","created":"2017-01-03T18:41:52Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MCgxCzAJBgNVBAYTAkJFMRkwFwYDVQQDExBCZWxnaXVtIFJvb3QgQ0Ey","id":"d3c14505-c104-150c-0a2d-e5f9e92b6152","schema":1483471393228},{"serialNumber":"cJ+vg4742XhNgJW2ot9eIg==","enabled":true,"last_modified":1483471393547,"details":{"who":".","created":"2017-01-03T18:41:55Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBSb290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWU=","id":"58bf9d8a-9a68-b41f-453c-8af8844bc07c","schema":1483471393228},{"serialNumber":"LizeWXFWP5pZPI/dLc+PVQ==","enabled":true,"last_modified":1483471393221,"details":{"who":".","created":"2017-01-03T18:41:52Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MCgxCzAJBgNVBAYTAkJFMRkwFwYDVQQDExBCZWxnaXVtIFJvb3QgQ0Ey","id":"cb1a1172-56d6-4150-1f50-eb2131f442f5","schema":1480617578654},{"serialNumber":"Ew==","enabled":true,"last_modified":1483471393199,"details":{"who":".","created":"2017-01-03T18:41:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MDQxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25h","id":"a0ff8e3f-e68d-5ee2-21e3-26cd0f46673b","schema":1480617578654},{"serialNumber":"BAAAAAABElatX7I=","enabled":true,"last_modified":1483471393177,"details":{"who":".","created":"2017-01-03T18:41:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIyMRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu","id":"00ac492e-04f7-ee6d-5fd2-bb12b97a4b7f","schema":1480617578654},{"serialNumber":"ANX8SnNRxCmsE/GCl5hw+8A=","enabled":true,"last_modified":1483471393155,"details":{"who":".","created":"2017-01-03T18:41:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAy","id":"a09db9b3-2faa-73ab-67ff-61dcbf700ec7","schema":1480617578654},{"serialNumber":"VBSf+IncsTB3RZS4KFCJPQ==","enabled":true,"last_modified":1483471393133,"details":{"who":".","created":"2017-01-03T18:41:52Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MCgxCzAJBgNVBAYTAkJFMRkwFwYDVQQDExBCZWxnaXVtIFJvb3QgQ0Ey","id":"7e816865-7c1d-2519-f114-e69a280768f4","schema":1480617578654},{"serialNumber":"DA==","enabled":true,"last_modified":1483471393111,"details":{"who":".","created":"2017-01-03T18:41:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MFIxCzAJBgNVBAYTAk5MMRkwFwYDVQQKDBBEaWdpZGVudGl0eSBCLlYuMSgwJgYDVQQDDB9EaWdpZGVudGl0eSBPcmdhbmlzYXRpZSBDQSAtIEcy","id":"5b760d02-fdd7-d6be-cb6f-4d30bf97746e","schema":1480617578654},{"serialNumber":"QDi5rw==","enabled":true,"last_modified":1483471393088,"details":{"who":".","created":"2017-01-03T18:41:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MIGCMQswCQYDVQQGEwJVUzEeMBwGA1UECxMVd3d3LnhyYW1wc2VjdXJpdHkuY29tMSQwIgYDVQQKExtYUmFtcCBTZWN1cml0eSBTZXJ2aWNlcyBJbmMxLTArBgNVBAMTJFhSYW1wIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQ==","id":"7de029af-ddf3-02be-ca26-5bb95b080d14","schema":1480617578654},{"serialNumber":"MABJSw==","enabled":true,"last_modified":1483471393066,"details":{"who":".","created":"2017-01-03T18:41:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MEgxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdTZWN1cmVUcnVzdCBDb3Jwb3JhdGlvbjEXMBUGA1UEAxMOU2VjdXJlVHJ1c3QgQ0E=","id":"411b4e82-2ddd-20c2-20b3-8d77145f6901","schema":1480617578654},{"serialNumber":"Ermwtg==","enabled":true,"last_modified":1483471393043,"details":{"who":".","created":"2017-01-03T18:41:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MFAxCzAJBgNVBAYTAkpQMRgwFgYDVQQKEw9TRUNPTSBUcnVzdC5uZXQxJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmljYXRpb24gUm9vdENBMQ==","id":"9d8a83d8-d651-42a0-ac1c-0ee414f3e31a","schema":1480617578654},{"serialNumber":"Nbc68Q8EHza72P/hSWcddw==","enabled":true,"last_modified":1483471393021,"details":{"who":".","created":"2017-01-03T18:41:52Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MCgxCzAJBgNVBAYTAkJFMRkwFwYDVQQDExBCZWxnaXVtIFJvb3QgQ0Ey","id":"d0513de2-6da9-d68d-78cc-a2292a9d18fb","schema":1480617578654},{"serialNumber":"Ig==","enabled":true,"last_modified":1483471392998,"details":{"who":".","created":"2017-01-03T18:41:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MDQxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25h","id":"872ba8c8-a236-9ac0-85ea-08630f5b17e2","schema":1480617578654},{"serialNumber":"APdCebq8ZyZr/T0luxlicNw=","enabled":true,"last_modified":1483471392976,"details":{"who":".","created":"2017-01-03T18:41:52Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MD8xCzAJBgNVBAYTAlRXMTAwLgYDVQQKDCdHb3Zlcm5tZW50IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHk=","id":"7a24e461-9fd0-b17f-01e0-f44866b800f1","schema":1480617578654},{"serialNumber":"Ermw0Q==","enabled":true,"last_modified":1483471392954,"details":{"who":".","created":"2017-01-03T18:41:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MFAxCzAJBgNVBAYTAkpQMRgwFgYDVQQKEw9TRUNPTSBUcnVzdC5uZXQxJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmljYXRpb24gUm9vdENBMQ==","id":"fff46511-7357-4559-3d36-75fc74034299","schema":1480617578654},{"serialNumber":"Ajp/","enabled":true,"last_modified":1483471392932,"details":{"who":".","created":"2017-01-03T18:41:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0E=","id":"272f2a95-6aec-f333-22ad-709d6118a87b","schema":1480617578654},{"serialNumber":"Fw==","enabled":true,"last_modified":1483471392911,"details":{"who":".","created":"2017-01-03T18:41:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MDQxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25h","id":"4f0dfd30-9278-4f20-25c3-436798595b84","schema":1480617578654},{"serialNumber":"K1ftto7Xcb0YKwQ6uMvOIA==","enabled":true,"last_modified":1483471392889,"details":{"who":".","created":"2017-01-03T18:41:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MD8xCzAJBgNVBAYTAlRXMTAwLgYDVQQKDCdHb3Zlcm5tZW50IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHk=","id":"29eab149-524e-b1da-e2b9-dc4a784ab64b","schema":1480617578654},{"serialNumber":"STMAFQ==","enabled":true,"last_modified":1483471392867,"details":{"who":".","created":"2017-01-03T18:41:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MDIxCzAJBgNVBAYTAkNOMQ4wDAYDVQQKEwVDTk5JQzETMBEGA1UEAxMKQ05OSUMgUk9PVA==","id":"91609507-ef23-7672-3a5d-06dfb9b0dac4","schema":1480617578654},{"serialNumber":"U+1Y1QpJc0FOR5JdCJ01gQ==","enabled":true,"last_modified":1483471392845,"details":{"who":".","created":"2017-01-03T18:41:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAx","id":"79f39790-1151-6bb2-0a50-fc596b82bedd","schema":1480617578654},{"serialNumber":"TAA2G+UIK6mqznQKBT77NA==","enabled":true,"last_modified":1483471392823,"details":{"who":".","created":"2017-01-03T18:41:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMw==","id":"d51879d6-0a85-8311-5b14-ad993cec17e6","schema":1480617578654},{"serialNumber":"Iw==","enabled":true,"last_modified":1483471392801,"details":{"who":".","created":"2017-01-03T18:41:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MDQxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25h","id":"532dd854-cdef-6452-2793-1e36d091d9ec","schema":1480617578654},{"serialNumber":"Qh/O5w==","enabled":true,"last_modified":1483471392779,"details":{"who":".","created":"2017-01-03T18:41:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5","id":"756ab100-8a14-daf7-bf06-9fe423863208","schema":1480617578654},{"serialNumber":"Ajp+","enabled":true,"last_modified":1483471392757,"details":{"who":".","created":"2017-01-03T18:41:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0E=","id":"41f2401b-5c31-724f-ad6c-28f3f6f47634","schema":1480617578654},{"serialNumber":"AUa47POQ1dN5","enabled":true,"last_modified":1483471392735,"details":{"who":".","created":"2017-01-03T18:41:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MFExCzAJBgNVBAYTAkpQMRMwEQYDVQQKEwpGdWppIFhlcm94MS0wKwYDVQQDEyRGdWppIFhlcm94IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IDI=","id":"0956d064-8750-eee2-b0c7-7e1c2d1d6f25","schema":1480617578654},{"serialNumber":"Pgyeh2mqlVzqI9hFntRbUQ==","enabled":true,"last_modified":1483471392712,"details":{"who":".","created":"2017-01-03T18:41:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMw==","id":"134969c5-0bf4-4054-eaa1-b24feaa76aef","schema":1480617578654},{"serialNumber":"Gg==","enabled":true,"last_modified":1483471392689,"details":{"who":".","created":"2017-01-03T18:41:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1315199","name":"Revoked intermediates","why":"."},"issuerName":"MDQxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25h","id":"141d8e99-193b-d108-382b-7d97e6912d8c","schema":1480617578654},{"serialNumber":"ESDYXNBhF+dePFjojs7u2vj1","enabled":true,"last_modified":1480349168043,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB","id":"f7f193ca-c34e-866a-8abf-d44188a78cb0","schema":1480349159276},{"serialNumber":"TA6BjA==","enabled":true,"last_modified":1480349168021,"details":{"who":".","created":"2016-10-27T17:52:14Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp","id":"2a9d41c8-d3e7-a40a-a79a-899902aa73cb","schema":1480349159276},{"serialNumber":"XhcFm2g619rt8Sro+a4rHA==","enabled":true,"last_modified":1480349167999,"details":{"who":".","created":"2016-04-28T21:08:06Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzI=","id":"a01f2d94-e1ee-2139-5652-c216331e357a","schema":1480349159276},{"serialNumber":"F6QlB/yX+A==","enabled":true,"last_modified":1480349167976,"details":{"who":".","created":"2016-10-27T17:52:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=","id":"a7fa8b99-3e2a-2c03-dffd-ab341eae59af","schema":1480349159276},{"serialNumber":"Bydxog==","enabled":true,"last_modified":1480349167954,"details":{"who":".","created":"2016-10-27T17:52:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=","id":"35f6f9f8-eb17-39d2-50a7-2b40f01e2584","schema":1480349159276},{"serialNumber":"CqnbFQ==","enabled":true,"last_modified":1480349167931,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=","id":"3b60bc42-674b-7822-113f-c8dc6d1b015e","schema":1480349159276},{"serialNumber":"Xrr31RF0DoIzMKXS6XtD+g==","enabled":true,"last_modified":1480349167904,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIGXMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTEfMB0GA1UEAxMWVVROLVVTRVJGaXJzdC1IYXJkd2FyZQ==","id":"c0d2651b-f567-0f6d-ce3c-16e7d19390d0","schema":1480349159276},{"serialNumber":"Qh/SnQ==","enabled":true,"last_modified":1480349167882,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5","id":"7326aa15-9b3e-44ca-c1c5-0ed1ff29521f","schema":1480349159276},{"serialNumber":"H08=","enabled":true,"last_modified":1480349167861,"details":{"who":".","created":"2016-04-28T21:08:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzQ=","id":"2ac02b19-f616-0dc3-6d01-28e1bea3dd93","schema":1480349159276},{"serialNumber":"NMpMcEnex3eXx4ohk9glcQ==","enabled":true,"last_modified":1480349167827,"details":{"who":".","created":"2016-03-01T21:22:27Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1252142","name":"exceptional SHA-1 Certificates","why":"."},"issuerName":"MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=","id":"8e453b5c-3f81-2694-2f10-73ec8c406c49","schema":1480349159276},{"serialNumber":"AQAAAAA=","enabled":true,"last_modified":1480349167797,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIGVMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTE=","id":"a3b400ad-0b4d-aa11-e8b5-82019fbc84d5","schema":1480349159276},{"serialNumber":"Ikdj3zYXXGsC/Afm9Tvx+g==","enabled":true,"last_modified":1480349167774,"details":{"who":".","created":"2016-10-27T17:52:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIGpMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3RlLCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYDVQQLEy8oYykgMjAwNiB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEfMB0GA1UEAxMWdGhhd3RlIFByaW1hcnkgUm9vdCBDQQ==","id":"e8b2d24e-5aaf-86dd-441e-b4781d5370db","schema":1480349159276},{"serialNumber":"acI1CFIgmwSFBoU5+ahDgg==","enabled":true,"last_modified":1480349167744,"details":{"who":".","created":"2016-04-28T21:08:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MHcxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEoMCYGA1UEAxMfU3ltYW50ZWMgQ2xhc3MgMyBFViBTU0wgQ0EgLSBHMw==","id":"938358e4-4c70-beb4-0fbe-02009feee6b6","schema":1480349159276},{"serialNumber":"BAAAAAABA/A35EU=","enabled":true,"last_modified":1480349167722,"details":{"who":".","created":"2016-01-18T14:43:37Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==","id":"97fbf7c4-3ef2-f54f-0029-1ba6540c63ea","schema":1480349159276},{"serialNumber":"UVKsEezpGWOVQ4W9esstng==","enabled":true,"last_modified":1480349167701,"details":{"who":".","created":"2016-04-28T21:08:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MHcxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEoMCYGA1UEAxMfU3ltYW50ZWMgQ2xhc3MgMyBFViBTU0wgQ0EgLSBHMg==","id":"c4c22010-0cb9-e9af-005d-2483612d864e","schema":1480349159276},{"serialNumber":"F5Bg/C8eXg==","enabled":true,"last_modified":1480349167343,"details":{"who":".","created":"2016-10-27T17:52:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=","id":"4295bb93-6e34-a58a-4d1c-238615b57cb0","schema":1480349159276},{"serialNumber":"AImQERVYPoeb","enabled":true,"last_modified":1480349167322,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MHExCzAJBgNVBAYTAkRFMRwwGgYDVQQKExNEZXV0c2NoZSBUZWxla29tIEFHMR8wHQYDVQQLExZULVRlbGVTZWMgVHJ1c3QgQ2VudGVyMSMwIQYDVQQDExpEZXV0c2NoZSBUZWxla29tIFJvb3QgQ0EgMg==","id":"4ca8f1a1-0dc0-881f-b497-cc5574f2494d","schema":1480349159276},{"serialNumber":"J2La+q+JOURNWkX60OP2lQ==","enabled":true,"last_modified":1480349167291,"details":{"who":".","created":"2016-07-14T14:40:23Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1286752","name":"Symantec erroneous SHA-1 certificates","why":"."},"issuerName":"MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=","id":"8662e9a7-fe16-d1fc-0993-d16dd2f01012","schema":1480349159276},{"serialNumber":"BAAAAAABHkSl5ao=","enabled":true,"last_modified":1480349167269,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MG0xCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRswGQYDVQQLExJQcmltYXJ5IENsYXNzIDEgQ0ExJjAkBgNVBAMTHUdsb2JhbFNpZ24gUHJpbWFyeSBDbGFzcyAxIENB","id":"7cfc5a53-f950-c15b-4dbb-8124fadcf871","schema":1480349159276},{"serialNumber":"RUT1Gehd1KKYPfqOlgspoQ==","enabled":true,"last_modified":1480349167246,"details":{"who":".","created":"2016-04-28T21:08:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MEQxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQDExRHZW9UcnVzdCBTU0wgQ0EgLSBHMw==","id":"8855fafd-e48b-680d-ff15-a022057d9b9e","schema":1480349159276},{"serialNumber":"BAAAAAABKUXDqxw=","enabled":true,"last_modified":1480349167224,"details":{"who":".","created":"2016-01-18T14:41:26Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==","id":"0a92faa8-b870-3a38-036e-9b95185fcb6a","schema":1480349159276},{"serialNumber":"CqZgEvHAsnzkT//QV9KjXw==","enabled":true,"last_modified":1480349167202,"details":{"who":".","created":"2016-04-28T21:08:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MGMxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xHTAbBgNVBAsTFERvbWFpbiBWYWxpZGF0ZWQgU1NMMR4wHAYDVQQDExV0aGF3dGUgRFYgU1NMIENBIC0gRzI=","id":"39008976-298e-f664-50c0-56f8ae6c4df5","schema":1480349159276},{"serialNumber":"OUvvVscW0/NltofkmV9qmg==","enabled":true,"last_modified":1480349167179,"details":{"who":".","created":"2016-04-28T21:08:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MEYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR8wHQYDVQQDExZHZW9UcnVzdCBTSEEyNTYgU1NMIENB","id":"a5eb3877-5e7d-200a-cee3-f63b8004d58e","schema":1480349159276},{"serialNumber":"ORFgmCj072NjcJnrxOMfQA==","enabled":true,"last_modified":1480349167156,"details":{"who":".","created":"2016-04-28T21:08:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzM=","id":"995df7f2-6bd4-12c6-b1aa-fcfe7618b193","schema":1480349159276},{"serialNumber":"GN2Hrh9Ltms=","enabled":true,"last_modified":1480349167125,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIGVMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTE=","id":"460ae779-c915-9daf-9a13-e0bf953322cb","schema":1480349159276},{"serialNumber":"ARQ=","enabled":true,"last_modified":1480349167102,"details":{"who":".","created":"2015-05-05T11:10:09Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155119","name":"T-Systems intermediate certificate","why":"."},"issuerName":"MHExCzAJBgNVBAYTAkRFMRwwGgYDVQQKExNEZXV0c2NoZSBUZWxla29tIEFHMR8wHQYDVQQLExZULVRlbGVTZWMgVHJ1c3QgQ2VudGVyMSMwIQYDVQQDExpEZXV0c2NoZSBUZWxla29tIFJvb3QgQ0EgMg==","id":"2826cef9-e4b4-53f9-e3cf-c5870fc778dd","schema":1480349159276},{"serialNumber":"DAk9hy8DhHSo+aQetvPB/fY=","enabled":true,"last_modified":1480349167079,"details":{"who":".","created":"2016-01-18T14:46:49Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MFwxCzAJBgNVBAYTAkJFMRUwEwYDVQQLEwxUcnVzdGVkIFJvb3QxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExGzAZBgNVBAMTElRydXN0ZWQgUm9vdCBDQSBHMg==","id":"b42066e0-0c88-e02b-620f-c41c2118c4e7","schema":1480349159276},{"serialNumber":"BHk=","enabled":true,"last_modified":1480349167057,"details":{"who":".","created":"2016-11-03T12:48:38Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1309305","name":"Hongkong Post e-Cert CA 1-10 certificates","why":"."},"issuerName":"MEcxCzAJBgNVBAYTAkhLMRYwFAYDVQQKEw1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25na29uZyBQb3N0IFJvb3QgQ0EgMQ==","id":"5048a7c5-79c8-68d7-06a3-19e8ba32e5fc","schema":1480349159276},{"serialNumber":"OnvXX72mvUI2Id/NMzegmg==","enabled":true,"last_modified":1480349167035,"details":{"who":".","created":"2016-04-28T21:08:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=","id":"92d843e8-4e72-2832-b56f-6e488e677d0f","schema":1480349159276},{"serialNumber":"ZgwfEqZnBsUNvNuZ77FbQA==","enabled":true,"last_modified":1480349167012,"details":{"who":".","created":"2016-04-28T21:08:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MGgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEiMCAGA1UEAxMZR2VvVHJ1c3QgRFYgU1NMIFNIQTI1NiBDQQ==","id":"73ae5fed-730d-94db-04ef-2aafd5ff75b8","schema":1480349159276},{"serialNumber":"Qh/QbQ==","enabled":true,"last_modified":1480349166989,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5","id":"6e4739fe-1aed-2320-4dc3-832043a31fc8","schema":1480349159276},{"serialNumber":"L79XLVO2ZmtAu7FAG8Wmzw==","enabled":true,"last_modified":1480349166968,"details":{"who":".","created":"2016-04-28T21:08:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzM=","id":"7d2a48b3-0b2e-59ae-2002-8edb4da20bd2","schema":1480349159276},{"serialNumber":"BUrYjru5px1ym4QUN33TOQ==","enabled":true,"last_modified":1480349166946,"details":{"who":".","created":"2016-04-28T21:08:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MGMxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xHTAbBgNVBAsTFERvbWFpbiBWYWxpZGF0ZWQgU1NMMR4wHAYDVQQDExV0aGF3dGUgRFYgU1NMIENBIC0gRzI=","id":"e95bb238-6d35-2cce-9744-d6a672b0a874","schema":1480349159276},{"serialNumber":"ESByNJZ5TPjg9iZyL6a/h5Zx","enabled":true,"last_modified":1480349166921,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB","id":"51935a37-2964-18cf-b34c-a20c2c2250ea","schema":1480349159276},{"serialNumber":"Aw==","enabled":true,"last_modified":1480349166898,"details":{"who":".","created":"2016-11-03T12:46:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1314673","name":"SecureSign Public CA11 intermediate CA cert","why":"."},"issuerName":"MFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RDQTEx","id":"ec4f91dd-7560-920a-f178-e8ae460dd595","schema":1480349159276},{"serialNumber":"BAAAAAABFUtaxac=","enabled":true,"last_modified":1480349166876,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxTaWduIFJvb3QgQ0E=","id":"8d87b3cd-b954-f4f1-bfb2-a0e60645301c","schema":1480349159276},{"serialNumber":"ATE3ew==","enabled":true,"last_modified":1480349166855,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFwxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xLTArBgNVBAMMJFN0YWF0IGRlciBOZWRlcmxhbmRlbiBCdXJnZXIgQ0EgLSBHMg==","id":"83ac91ce-0f5e-ae4e-2010-b0da5616cd59","schema":1480349159276},{"serialNumber":"LnfcUaXG/pxV2CpXM5+YSg==","enabled":true,"last_modified":1480349166833,"details":{"who":".","created":"2016-04-28T21:08:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=","id":"4c743a6f-af95-49a6-bd4a-d1ee8160c537","schema":1480349159276},{"serialNumber":"BGU=","enabled":true,"last_modified":1480349166811,"details":{"who":".","created":"2016-11-03T12:49:39Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1309305","name":"Hongkong Post e-Cert CA 1-10 certificates","why":"."},"issuerName":"MEcxCzAJBgNVBAYTAkhLMRYwFAYDVQQKEw1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25na29uZyBQb3N0IFJvb3QgQ0EgMQ==","id":"4de7908c-45e7-3b7f-a91a-8cefb1ecf830","schema":1480349159276},{"serialNumber":"BAAAAAABJZbEU4I=","enabled":true,"last_modified":1480349166787,"details":{"who":".","created":"2016-01-18T14:42:46Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==","id":"19c9a896-fbf0-8ad0-92cd-4aca2577c006","schema":1480349159276},{"serialNumber":"BAAAAAABIg08D3U=","enabled":true,"last_modified":1480349166478,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIyMRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu","id":"4aec7420-aa59-53b8-1373-d3c0a7ebc837","schema":1480349159276},{"serialNumber":"CgFBQgAAAUFcf/EVAAAAAg==","enabled":true,"last_modified":1480349166455,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MD8xJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjEXMBUGA1UEAxMORFNUIFJvb3QgQ0EgWDM=","id":"d60a94e9-3f7f-a20f-1dcc-c87ccc78fb99","schema":1480349159276},{"serialNumber":"dItWlz2V62Philqj9m6Pbg==","enabled":true,"last_modified":1480349166433,"details":{"who":".","created":"2016-04-28T21:08:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzM=","id":"abb0df0d-6716-9a25-ae33-806e93276cd4","schema":1480349159276},{"serialNumber":"CcL+EA==","enabled":true,"last_modified":1480349166405,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=","id":"3cef2b9e-ddcd-cc40-8d59-49408409a3bb","schema":1480349159276},{"serialNumber":"TA6EVg==","enabled":true,"last_modified":1480349166381,"details":{"who":".","created":"2016-04-12T12:50:50Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1263733","name":"Disney CA intermediate CA certificate","why":"."},"issuerName":"MIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp","id":"7b09e4fc-2261-e7c6-e926-5a7b5e74fc5e","schema":1480349159276},{"serialNumber":"GdXz4L1b6FKNCMG9Jz2tjA==","enabled":true,"last_modified":1480349166358,"details":{"who":".","created":"2016-04-28T21:08:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MGMxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xHTAbBgNVBAsTFERvbWFpbiBWYWxpZGF0ZWQgU1NMMR4wHAYDVQQDExV0aGF3dGUgRFYgU1NMIENBIC0gRzI=","id":"35f81fe8-9fa4-760b-9fd0-2de1b0191721","schema":1480349159276},{"serialNumber":"COwoDFvz7GD8R2K7Lo0rYQ==","enabled":true,"last_modified":1480349166330,"details":{"who":".","created":"2016-03-01T21:23:14Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1252142","name":"exceptional SHA-1 Certificates","why":"."},"issuerName":"MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=","id":"cc56260c-5f3a-3f4b-c712-78a8e7facd27","schema":1480349159276},{"serialNumber":"WD1AyQAAAAAAJQ==","enabled":true,"last_modified":1480349166308,"details":{"who":".","created":"2016-10-27T17:52:14Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIGKMQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEmMCQGA1UECxMdQ29weXJpZ2h0IChjKSAyMDA1IFdJU2VLZXkgU0ExFjAUBgNVBAsTDUludGVybmF0aW9uYWwxKTAnBgNVBAMTIFdJU2VLZXkgQ2VydGlmeUlEIEFkdmFuY2VkIEcxIENB","id":"8c984ecd-c61c-426a-97aa-3a808e4da482","schema":1480349159276},{"serialNumber":"GN2Hrh9LtnI=","enabled":true,"last_modified":1480349166286,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIGVMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTE=","id":"333f6eb2-cefe-1a3b-3726-a8320b047847","schema":1480349159276},{"serialNumber":"BAAAAAABJQcQRNU=","enabled":true,"last_modified":1480349166264,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIzMRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu","id":"2258e9bc-1c39-9db3-4fdb-c7eb12d0609c","schema":1480349159276},{"serialNumber":"Bg==","enabled":true,"last_modified":1480349166240,"details":{"who":".","created":"2016-07-28T12:15:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1289808","name":"FNMT revoked intermediate certificates","why":"."},"issuerName":"MDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTQ==","id":"b7fb6842-6407-8ae4-5e0f-e6daf112ed4f","schema":1480349159276},{"serialNumber":"IIxFSyNM6mWtCgTG0IL3Og==","enabled":true,"last_modified":1480349166215,"details":{"who":".","created":"2016-04-28T21:08:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MGMxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xHTAbBgNVBAsTFERvbWFpbiBWYWxpZGF0ZWQgU1NMMR4wHAYDVQQDExV0aGF3dGUgRFYgU1NMIENBIC0gRzI=","id":"6457eeb8-d83a-3818-c416-0dce6d71d471","schema":1480349159276},{"serialNumber":"BAAAAAABHkSl5AQ=","enabled":true,"last_modified":1480349166191,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxTaWduIFJvb3QgQ0E=","id":"de8e6484-fc97-6889-a1f9-dafd45786606","schema":1480349159276},{"serialNumber":"ByeQ9g==","enabled":true,"last_modified":1480349166170,"details":{"who":".","created":"2016-10-27T17:52:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=","id":"bb5a82a6-8da0-5390-a7d6-843bdb0c02c2","schema":1480349159276},{"serialNumber":"EQ==","enabled":true,"last_modified":1480349166148,"details":{"who":".","created":"2016-07-28T12:17:01Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1289808","name":"FNMT revoked intermediate certificates","why":"."},"issuerName":"MDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTQ==","id":"dcce309f-aa60-6484-eaed-aa8310440a5c","schema":1480349159276},{"serialNumber":"R4af5A==","enabled":true,"last_modified":1480349166126,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MEgxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdTZWN1cmVUcnVzdCBDb3Jwb3JhdGlvbjEXMBUGA1UEAxMOU2VjdXJlVHJ1c3QgQ0E=","id":"e60eeeb2-612e-ef08-d0b8-5e9f8e1a23a9","schema":1480349159276},{"serialNumber":"BAAAAAAA+X/GIyk=","enabled":true,"last_modified":1480349166102,"details":{"who":".","created":"2016-01-18T14:40:51Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==","id":"528cd047-ef3b-fc23-e37f-5d67fd3117e4","schema":1480349159276},{"serialNumber":"BYyEX2b5+K+myAIR7eXaRQ==","enabled":true,"last_modified":1480349166080,"details":{"who":".","created":"2016-07-14T14:40:23Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1286752","name":"Symantec erroneous SHA-1 certificates","why":"."},"issuerName":"MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=","id":"9be08dd3-1922-fb30-77dc-5cfcf00164a0","schema":1480349159276},{"serialNumber":"RurwlgVMxeP6Zepun0LGZA==","enabled":true,"last_modified":1480349166058,"details":{"who":".","created":"2016-10-27T17:52:14Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3Q=","id":"22a74468-602c-f4ac-0003-be4ce0167258","schema":1480349159276},{"serialNumber":"AJiWmg==","enabled":true,"last_modified":1480349166036,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBSb290IENB","id":"1525b265-22d6-3253-079c-c4ffca58458f","schema":1480349159276},{"serialNumber":"ESCLRVuhcUZaluIgIVlRJx+O","enabled":true,"last_modified":1480349166012,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB","id":"a6299e39-84a4-2dce-ffbb-751107660f4f","schema":1480349159276},{"serialNumber":"BAAAAAABCUVQ9No=","enabled":true,"last_modified":1480349165990,"details":{"who":".","created":"2016-01-18T14:43:20Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==","id":"a1d34c2f-4a03-0e35-ba5f-bc14138bcff5","schema":1480349159276},{"serialNumber":"BAAAAAABF2Tb8Bc=","enabled":true,"last_modified":1480349165968,"details":{"who":".","created":"2016-01-18T14:38:26Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MF8xCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRQwEgYDVQQLEwtQYXJ0bmVycyBDQTEfMB0GA1UEAxMWR2xvYmFsU2lnbiBQYXJ0bmVycyBDQQ==","id":"7e19f742-420e-dbe9-f691-2d19430d75b2","schema":1480349159276},{"serialNumber":"GN2Hrh9Ltm4=","enabled":true,"last_modified":1480349165947,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIGVMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTE=","id":"20732fc6-dd20-fe76-b6b5-b78388b64bdd","schema":1480349159276},{"serialNumber":"fMTRbGCp280pnyE/u53zbA==","enabled":true,"last_modified":1480349165925,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIG9MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5","id":"44aa21e7-a92c-a0cc-6f6c-85b7ee52a87d","schema":1480349159276},{"serialNumber":"d8AtKymQwkOPDBj+hjPzFg==","enabled":true,"last_modified":1480349165591,"details":{"who":".","created":"2016-04-28T21:08:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=","id":"014a5b67-d566-0767-c9d7-48e54115a69a","schema":1480349159276},{"serialNumber":"Os2rnHWYhryvdOXfgan06A==","enabled":true,"last_modified":1480349165569,"details":{"who":".","created":"2016-10-27T17:52:14Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3Q=","id":"dc94f688-044b-f8a0-79f9-5dc2d42e3edb","schema":1480349159276},{"serialNumber":"e/fIfg2Dj2tkYIWVu2r82Cc=","enabled":true,"last_modified":1480349165547,"details":{"who":".","created":"2016-01-18T14:46:19Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MFwxCzAJBgNVBAYTAkJFMRUwEwYDVQQLEwxUcnVzdGVkIFJvb3QxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExGzAZBgNVBAMTElRydXN0ZWQgUm9vdCBDQSBHMg==","id":"9e8ec7bc-0f79-42c2-c9bc-32bfbbd3b591","schema":1480349159276},{"serialNumber":"EA==","enabled":true,"last_modified":1480349165523,"details":{"who":".","created":"2016-07-28T12:16:27Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1289808","name":"FNMT revoked intermediate certificates","why":"."},"issuerName":"MDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTQ==","id":"362a0532-ea75-9bc6-2e50-35d9566a6ad2","schema":1480349159276},{"serialNumber":"UU3AP1SMxmyhBFq7MRFZmf0=","enabled":true,"last_modified":1480349165501,"details":{"who":".","created":"2016-01-18T14:45:06Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MFwxCzAJBgNVBAYTAkJFMRUwEwYDVQQLEwxUcnVzdGVkIFJvb3QxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExGzAZBgNVBAMTElRydXN0ZWQgUm9vdCBDQSBHMg==","id":"4f2e59ff-cdf1-48ee-1122-961833187e49","schema":1480349159276},{"serialNumber":"ESBqoILo90ntDW7OTK43MS2F","enabled":true,"last_modified":1480349165479,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB","id":"0702b706-86e5-6a48-49fa-6c53b99009f3","schema":1480349159276},{"serialNumber":"GtXUVojhwOTkaQ4bTKblEQ==","enabled":true,"last_modified":1480349165453,"details":{"who":".","created":"2016-07-14T14:40:23Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1286752","name":"Symantec erroneous SHA-1 certificates","why":"."},"issuerName":"MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=","id":"9475e2f6-7247-cbe1-5055-8af86f39a149","schema":1480349159276},{"serialNumber":"KjoVfZ3by6+pL8fssyfM6A==","enabled":true,"last_modified":1480349165429,"details":{"who":".","created":"2016-04-28T21:08:06Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzM=","id":"f4c8162a-d49b-1cbd-adb9-5e6223793aa4","schema":1480349159276},{"serialNumber":"Bydr0Q==","enabled":true,"last_modified":1480349165407,"details":{"who":".","created":"2016-10-27T17:52:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=","id":"a85aef34-3bfe-2135-845d-466adadc414b","schema":1480349159276},{"serialNumber":"Xbevr3ut3Z9m1GuXC9SonA==","enabled":true,"last_modified":1480349165384,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIG9MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5","id":"549710cf-bcaa-843c-df9d-5962bad88a9a","schema":1480349159276},{"serialNumber":"CeagHQ==","enabled":true,"last_modified":1480349165355,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=","id":"d69db231-b7b5-4d79-147b-49198f93fc10","schema":1480349159276},{"serialNumber":"EAdmaA==","enabled":true,"last_modified":1480349165329,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=","id":"618009ee-0ef1-af4b-8841-349e6f82eacc","schema":1480349159276},{"serialNumber":"BAAAAAABHkSl7L4=","enabled":true,"last_modified":1480349165306,"details":{"who":".","created":"2016-01-18T14:47:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MIGBMQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTElMCMGA1UECxMcUHJpbWFyeSBPYmplY3QgUHVibGlzaGluZyBDQTEwMC4GA1UEAxMnR2xvYmFsU2lnbiBQcmltYXJ5IE9iamVjdCBQdWJsaXNoaW5nIENB","id":"636c65b9-2d52-8689-023f-7a23a0baec5b","schema":1480349159276},{"serialNumber":"BAAAAAABFqoAZoI=","enabled":true,"last_modified":1480349165285,"details":{"who":".","created":"2016-10-27T17:52:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==","id":"2b0d58aa-9c96-748f-4fc0-b1f413ca8e20","schema":1480349159276},{"serialNumber":"fwAAAQAAAUrz/HmrAAAAAg==","enabled":true,"last_modified":1480349165264,"details":{"who":".","created":"2016-02-24T20:04:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1250907","name":"IdenTrust cross certificate","why":"."},"issuerName":"MGExCzAJBgNVBAYTAlVTMRIwEAYDVQQKEwlJZGVuVHJ1c3QxIDAeBgNVBAsTF0lkZW5UcnVzdCBQdWJsaWMgU2VjdG9yMRwwGgYDVQQDExNJZGVuVHJ1c3QgQUNFUyBDQSAx","id":"352c78aa-997c-bdbe-66ba-930d66fde011","schema":1480349159276},{"serialNumber":"CeFU2w==","enabled":true,"last_modified":1480349165242,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=","id":"e8e298f0-efa2-0d08-458f-c085ee9df8f9","schema":1480349159276},{"serialNumber":"STMAjg==","enabled":true,"last_modified":1480349165209,"details":{"who":".","created":"2015-03-31T14:53:16Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1149603","name":"MCSHOLDING intermediate certificate","why":"."},"issuerName":"MDIxCzAJBgNVBAYTAkNOMQ4wDAYDVQQKEwVDTk5JQzETMBEGA1UEAxMKQ05OSUMgUk9PVA==","id":"c9897d2c-c68e-3c02-2f39-678954b0cf3e","schema":1480349159276},{"serialNumber":"bAOrKSMsmA0MLJyAJ5BRsUM=","enabled":true,"last_modified":1480349165175,"details":{"who":".","created":"2016-01-18T14:46:35Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MFwxCzAJBgNVBAYTAkJFMRUwEwYDVQQLEwxUcnVzdGVkIFJvb3QxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExGzAZBgNVBAMTElRydXN0ZWQgUm9vdCBDQSBHMg==","id":"7d44cb3e-28a5-16dd-024c-796312f780bc","schema":1480349159276},{"serialNumber":"F5BhE0zbgQ==","enabled":true,"last_modified":1480349165145,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=","id":"29925947-91ab-16a8-a5af-65558cdb27c2","schema":1480349159276},{"serialNumber":"BAAAAAABL07hUBg=","enabled":true,"last_modified":1480349165119,"details":{"who":".","created":"2016-10-27T17:52:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFYxCzAJBgNVBAYTAkpQMQ8wDQYDVQQKEwZKSVBERUMxGjAYBgNVBAsTEUpDQU4gU3ViIFJvb3QgQ0EwMRowGAYDVQQDExFKQ0FOIFN1YiBSb290IENBMA==","id":"1240480e-2ef8-8ac3-4314-4e8e494741b9","schema":1480349159276},{"serialNumber":"ESCyHU+xOECnh9Rf2IvgR8zS","enabled":true,"last_modified":1480349165097,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB","id":"3980401b-c0e2-0533-f0fb-0cc04685d248","schema":1480349159276},{"serialNumber":"CdWFNw==","enabled":true,"last_modified":1480349165075,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=","id":"f06ff510-954e-b917-fda1-2c3153788d7d","schema":1480349159276},{"serialNumber":"TrKEMhb2PKktH8lHg0AV5A==","enabled":true,"last_modified":1480349165048,"details":{"who":".","created":"2016-10-27T17:52:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMw==","id":"8b7985ab-ab8b-fcd2-cf88-cf8dad0f7a97","schema":1480349159276},{"serialNumber":"BAAAAAABJQdAjik=","enabled":true,"last_modified":1480349165026,"details":{"who":".","created":"2016-01-18T14:41:56Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==","id":"a75f5980-9149-fff9-70d5-b24121c3eaff","schema":1480349159276},{"serialNumber":"Cfk9lw==","enabled":true,"last_modified":1480349165002,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=","id":"59b587cb-401b-a5d0-8128-86c3691c4be1","schema":1480349159276},{"serialNumber":"BAAAAAABHkSl6mw=","enabled":true,"last_modified":1480349164725,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MG0xCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRswGQYDVQQLExJQcmltYXJ5IENsYXNzIDMgQ0ExJjAkBgNVBAMTHUdsb2JhbFNpZ24gUHJpbWFyeSBDbGFzcyAzIENB","id":"3cc60c06-a870-951e-1d12-4b29ee13989e","schema":1480349159276},{"serialNumber":"SdegFrLaFTCsoMAW5ED+zA==","enabled":true,"last_modified":1480349164704,"details":{"who":".","created":"2016-04-28T21:08:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MEQxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQDExRHZW9UcnVzdCBTU0wgQ0EgLSBHMg==","id":"9fbfe267-c715-8f7b-d9ad-166aad9f91af","schema":1480349159276},{"serialNumber":"BAAAAAABMxvC9bk=","enabled":true,"last_modified":1480349164681,"details":{"who":".","created":"2016-01-18T14:42:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==","id":"923a5e98-11f7-cdae-b073-45b525fb2294","schema":1480349159276},{"serialNumber":"Bydp0g==","enabled":true,"last_modified":1480349164658,"details":{"who":".","created":"2016-10-27T17:52:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=","id":"10e51569-072a-611a-c397-3050fdf22649","schema":1480349159276},{"serialNumber":"QZCrvQ==","enabled":true,"last_modified":1480349164636,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIGCMQswCQYDVQQGEwJVUzEeMBwGA1UECxMVd3d3LnhyYW1wc2VjdXJpdHkuY29tMSQwIgYDVQQKExtYUmFtcCBTZWN1cml0eSBTZXJ2aWNlcyBJbmMxLTArBgNVBAMTJFhSYW1wIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQ==","id":"6d791114-68b4-8c3c-ee3c-29ed83eced2e","schema":1480349159276},{"serialNumber":"AQAAAAI=","enabled":true,"last_modified":1480349164614,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIGVMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTE=","id":"bff9c953-6690-f618-cfea-7b936f3691a6","schema":1480349159276},{"serialNumber":"Aw1SPC56593ZCZ9vCNHKwQ==","enabled":true,"last_modified":1480349164590,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIG9MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5","id":"c395381f-fe34-7b6c-f56a-f20b20bf0d0d","schema":1480349159276},{"serialNumber":"BAAAAAABAJmPjfQ=","enabled":true,"last_modified":1480349164559,"details":{"who":".","created":"2016-01-18T14:44:22Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==","id":"24b096b4-987f-a21a-04d3-aedc9eaafc1e","schema":1480349159276},{"serialNumber":"BAAAAAABK84yjs8=","enabled":true,"last_modified":1480349164533,"details":{"who":".","created":"2016-10-27T17:52:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFYxCzAJBgNVBAYTAkpQMQ8wDQYDVQQKEwZKSVBERUMxGjAYBgNVBAsTEUpDQU4gU3ViIFJvb3QgQ0EwMRowGAYDVQQDExFKQ0FOIFN1YiBSb290IENBMA==","id":"8078d5ff-c93b-15d1-ebcf-607bdbfc159f","schema":1480349159276},{"serialNumber":"FJl6tXgNpSk=","enabled":true,"last_modified":1480349164510,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIGVMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTE=","id":"7ab0a200-7ecf-576f-bff9-652fb14c3af6","schema":1480349159276},{"serialNumber":"M0VSOewW3WI=","enabled":true,"last_modified":1480349164486,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MDwxHjAcBgNVBAMMFUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMCREU=","id":"f3688c95-3934-e80a-e32f-0d5dcb2f0c4c","schema":1480349159276},{"serialNumber":"VN2yeFexyXjPf34fHGmbhg==","enabled":true,"last_modified":1480349164463,"details":{"who":".","created":"2016-07-14T14:40:23Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1286752","name":"Symantec erroneous SHA-1 certificates","why":"."},"issuerName":"MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=","id":"bbcfc451-2fcc-b380-e579-bb6d11fc7d34","schema":1480349159276},{"serialNumber":"STMAeg==","enabled":true,"last_modified":1480349164433,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MDIxCzAJBgNVBAYTAkNOMQ4wDAYDVQQKEwVDTk5JQzETMBEGA1UEAxMKQ05OSUMgUk9PVA==","id":"a46be506-1dbc-41a9-2775-95d67708fb5f","schema":1480349159276},{"serialNumber":"Aa8e+91erglSMgsk/mtVaA==","enabled":true,"last_modified":1480349164410,"details":{"who":".","created":"2016-09-09T16:26:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1300977","name":"revoked.badssl.com certificate","why":"."},"issuerName":"ME0xCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJzAlBgNVBAMTHkRpZ2lDZXJ0IFNIQTIgU2VjdXJlIFNlcnZlciBDQQ==","id":"4b778ec2-ef45-c5b2-dc44-b00c87b11741","schema":1480349159276},{"serialNumber":"TurPPI6eivtNeGYdM0ZWXQ==","enabled":true,"last_modified":1480349164388,"details":{"who":".","created":"2016-04-28T21:08:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=","id":"8192a2fa-165d-3759-fd20-4b7d8e2a0e84","schema":1480349159276},{"serialNumber":"UKKK5ol/rKBZchAAOnZjaA==","enabled":true,"last_modified":1480349164365,"details":{"who":".","created":"2016-04-28T21:08:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MEMxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xHTAbBgNVBAMTFHRoYXd0ZSBTSEEyNTYgU1NMIENB","id":"ca0c5f15-2808-8c94-3f77-6a277d6738b2","schema":1480349159276},{"serialNumber":"UMUwXwT1Z4juyQ/CNTf4mw==","enabled":true,"last_modified":1480349164342,"details":{"who":".","created":"2016-04-28T21:08:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=","id":"c623e511-79c8-cbe6-6a6e-0d9896f07e71","schema":1480349159276},{"serialNumber":"Ew1ee9Jq7Q/Dig3ACF4V6Q==","enabled":true,"last_modified":1480349164320,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIGTMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dD","id":"c011d2b4-73bc-27e5-3d3a-ab00be2a4d05","schema":1480349159276},{"serialNumber":"XLhHIg7vP+tWfRqvuKeAxw==","enabled":true,"last_modified":1480349164297,"details":{"who":".","created":"2016-04-28T21:08:06Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzM=","id":"520c26f8-9a60-5949-0372-c9d93f9e95dd","schema":1480349159276},{"serialNumber":"E5I2y6sIonl4a+TmlXc7fw==","enabled":true,"last_modified":1480349164275,"details":{"who":".","created":"2016-04-28T21:08:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MGMxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xHTAbBgNVBAsTFERvbWFpbiBWYWxpZGF0ZWQgU1NMMR4wHAYDVQQDExV0aGF3dGUgRFYgU1NMIENBIC0gRzI=","id":"ee842f50-9d56-8fdf-fa55-8b55b8519b81","schema":1480349159276},{"serialNumber":"Jq6jgeApiT9O4W2Tx/NTRQ==","enabled":true,"last_modified":1480349164253,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIGVMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTEdMBsGA1UEAxMUVVROLVVTRVJGaXJzdC1PYmplY3Q=","id":"3b658f17-11f9-7550-d991-3e9a1397402d","schema":1480349159276},{"serialNumber":"BAAAAAABHkSl6Co=","enabled":true,"last_modified":1480349164232,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MG0xCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRswGQYDVQQLExJQcmltYXJ5IENsYXNzIDIgQ0ExJjAkBgNVBAMTHUdsb2JhbFNpZ24gUHJpbWFyeSBDbGFzcyAyIENB","id":"6eb0fa3b-c226-f411-0fab-df88962a5769","schema":1480349159276},{"serialNumber":"ESD9YhzIEOwiOT7Nwip+E1KI","enabled":true,"last_modified":1480349164209,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB","id":"d6172148-c2ee-a904-db40-079b10436cca","schema":1480349159276},{"serialNumber":"Eg==","enabled":true,"last_modified":1480349164187,"details":{"who":".","created":"2016-07-28T12:17:24Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1289808","name":"FNMT revoked intermediate certificates","why":"."},"issuerName":"MDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTQ==","id":"34561e12-916b-083e-6fa6-181b5b89ec80","schema":1480349159276},{"serialNumber":"NvEJoRYL2yvAZrAjbDIipQ==","enabled":true,"last_modified":1480349164164,"details":{"who":".","created":"2016-04-28T21:08:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MIG1MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMS8wLQYDVQQDEyZWZXJpU2lnbiBDbGFzcyAzIFNlY3VyZSBTZXJ2ZXIgQ0EgLSBHMw==","id":"b1119d43-b3b8-1f41-6fbb-9cf2f67a521d","schema":1480349159276},{"serialNumber":"ESCC9oPNcRdPOox+SjWm9dTX","enabled":true,"last_modified":1480349163834,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB","id":"8858e9fc-cc55-54ea-fe45-c4e533c2e410","schema":1480349159276},{"serialNumber":"D9UltDPl4XVfSSqQOvdiwQ==","enabled":true,"last_modified":1480349163810,"details":{"who":".","created":"2015-03-31T11:14:46Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1145157","name":"live.fi certificate","why":"."},"issuerName":"MIGQMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01PRE8gQ0EgTGltaXRlZDE2MDQGA1UEAxMtQ09NT0RPIFJTQSBEb21haW4gVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB","id":"0a9323dd-982f-c62d-a9b4-b9d04617fc62","schema":1480349159276},{"serialNumber":"OYBKgxEHpW/8XGAGAlvJyMA=","enabled":true,"last_modified":1480349163788,"details":{"who":".","created":"2016-01-18T14:45:35Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MFwxCzAJBgNVBAYTAkJFMRUwEwYDVQQLEwxUcnVzdGVkIFJvb3QxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExGzAZBgNVBAMTElRydXN0ZWQgUm9vdCBDQSBHMg==","id":"d6dfdc76-52ae-2843-3484-7fbff46f0100","schema":1480349159276},{"serialNumber":"EM8bDLBnnoYe4LnWpLIhS4esr3I=","enabled":true,"last_modified":1480349163764,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDI=","id":"be09b295-68d1-9c01-97ee-10df36acd3ea","schema":1480349159276},{"serialNumber":"BAAAAAABJ/ufRdg=","enabled":true,"last_modified":1480349163739,"details":{"who":".","created":"2016-01-18T14:39:41Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==","id":"5d64f82e-9ad8-fde1-a8c9-2d94552a8ad4","schema":1480349159276},{"serialNumber":"BAAAAAABHJRKMpA=","enabled":true,"last_modified":1480349163715,"details":{"who":".","created":"2016-01-18T14:43:51Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==","id":"f5b2da3a-5176-b4e4-240a-181f39f6756b","schema":1480349159276},{"serialNumber":"BAAAAAABBHYoIFs=","enabled":true,"last_modified":1480349163691,"details":{"who":".","created":"2016-01-18T14:40:18Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==","id":"f59ed73e-f3c5-eef3-4481-3ca8af0b0688","schema":1480349159276},{"serialNumber":"BAAAAAABHhw1vwc=","enabled":true,"last_modified":1480349163668,"details":{"who":".","created":"2016-01-18T14:37:41Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MF8xCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRQwEgYDVQQLEwtQYXJ0bmVycyBDQTEfMB0GA1UEAxMWR2xvYmFsU2lnbiBQYXJ0bmVycyBDQQ==","id":"1b1856c1-f4f5-82ca-ba57-d94739e74576","schema":1480349159276},{"serialNumber":"TqfXw+FkhxfVgE9GVMgjWQ==","enabled":true,"last_modified":1480349163645,"details":{"who":".","created":"2016-04-28T21:08:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MGMxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xHTAbBgNVBAsTFERvbWFpbiBWYWxpZGF0ZWQgU1NMMR4wHAYDVQQDExV0aGF3dGUgRFYgU1NMIENBIC0gRzI=","id":"60f6a3be-ad83-a868-d645-7aad77914bc8","schema":1480349159276},{"serialNumber":"LdbnCbsA9sOgI4mkUpWXPw==","enabled":true,"last_modified":1480349163622,"details":{"who":".","created":"2016-03-01T21:21:56Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1252142","name":"exceptional SHA-1 Certificates","why":"."},"issuerName":"MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=","id":"d839b1ed-7d39-5e57-687c-2f4d6f0514e5","schema":1480349159276},{"serialNumber":"ANygrItIJ2rcKlyS3Lue07U=","enabled":true,"last_modified":1480349163595,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MEgxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdTZWN1cmVUcnVzdCBDb3Jwb3JhdGlvbjEXMBUGA1UEAxMOU2VjdXJlVHJ1c3QgQ0E=","id":"d55572d9-be60-5967-948a-7dae793ab30f","schema":1480349159276},{"serialNumber":"BydeGg==","enabled":true,"last_modified":1480349163572,"details":{"who":".","created":"2016-10-27T17:52:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=","id":"b7d8b0e0-9747-6a09-ab6b-051c57579fe9","schema":1480349159276},{"serialNumber":"ESCVop+Q4/OBgtf4WJkr01Gh","enabled":true,"last_modified":1480349163548,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB","id":"7602529c-c2ea-d18b-9b2a-fdb70ca936f9","schema":1480349159276},{"serialNumber":"BAAAAAABGMG0Gmw=","enabled":true,"last_modified":1480349163514,"details":{"who":".","created":"2016-01-18T14:42:31Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==","id":"317aeda4-6de7-7b11-76cb-3b0afa9aaf86","schema":1480349159276},{"serialNumber":"O2S99lVUxErLSk56GvWRv+E=","enabled":true,"last_modified":1480349163492,"details":{"who":".","created":"2016-01-18T14:47:04Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MFwxCzAJBgNVBAYTAkJFMRUwEwYDVQQLEwxUcnVzdGVkIFJvb3QxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExGzAZBgNVBAMTElRydXN0ZWQgUm9vdCBDQSBHMg==","id":"27847bcc-dbaf-196f-ed5e-c1c022798717","schema":1480349159276},{"serialNumber":"By7fBTreouRwX/qrpgSUsg==","enabled":true,"last_modified":1480349163470,"details":{"who":".","created":"2016-03-01T21:16:35Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1252142","name":"exceptional SHA-1 Certificates","why":"."},"issuerName":"MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=","id":"322de470-76d3-a45d-740f-342a6a8eb863","schema":1480349159276},{"serialNumber":"ezdAeCxKH7BFs7vn3byYaw==","enabled":true,"last_modified":1480349163448,"details":{"who":".","created":"2016-04-28T21:08:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=","id":"fc5bde6b-45b9-c141-7171-0a6f37e7938a","schema":1480349159276},{"serialNumber":"VLm3Xe60+1YgPpXCGtXLng==","enabled":true,"last_modified":1480349163426,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIG9MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5","id":"055d66b6-8fbd-93df-f2c4-dcdb41943212","schema":1480349159276},{"serialNumber":"cDggUYfwJ3A1YcdoeT6s4A==","enabled":true,"last_modified":1480349163403,"details":{"who":".","created":"2016-04-28T21:08:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MEExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxUaGF3dGUsIEluYy4xGzAZBgNVBAMTElRoYXd0ZSBTR0MgQ0EgLSBHMg==","id":"093f20b4-93b8-a171-cbe7-3e24a543c7e9","schema":1480349159276},{"serialNumber":"a9/VeyVWrzFD7rM2PEHwQA==","enabled":true,"last_modified":1480349163377,"details":{"who":".","created":"2016-04-28T21:08:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=","id":"c02a9772-b351-59dc-8633-1293ac9addee","schema":1480349159276},{"serialNumber":"ESCis569omrbb20yySF39+aE","enabled":true,"last_modified":1480349163350,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB","id":"aaa19866-32ce-e842-6431-6d357fafe8d8","schema":1480349159276},{"serialNumber":"F5Bg6C237Q==","enabled":true,"last_modified":1480349163327,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=","id":"57ddfa31-3f08-298a-d7bd-712e3aaea567","schema":1480349159276},{"serialNumber":"HZyLf+K70FKc+jomm8DiDw==","enabled":true,"last_modified":1480349163302,"details":{"who":".","created":"2016-04-28T21:08:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=","id":"452f4798-87d4-8df1-b275-177456d2f1c8","schema":1480349159276},{"serialNumber":"CskruA==","enabled":true,"last_modified":1480349163280,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=","id":"e92cad12-4098-0817-e317-3674d4242ba9","schema":1480349159276},{"serialNumber":"a12RvBNhznU=","enabled":true,"last_modified":1480349163257,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MDwxHjAcBgNVBAMMFUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMCREU=","id":"33154d98-0f20-7e7d-d2d0-3244a7d1f971","schema":1480349159276},{"serialNumber":"CjM=","enabled":true,"last_modified":1480349162955,"details":{"who":".","created":"2016-10-27T17:52:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDM=","id":"283b292b-1212-a713-c8be-c976c0222410","schema":1480349159276},{"serialNumber":"NTgf4iwIfeyJPIomw2dwSXEwtxQ=","enabled":true,"last_modified":1480349162930,"details":{"who":".","created":"2016-10-27T17:52:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDM=","id":"542dbfc0-0faa-2398-9670-cd249525fd2c","schema":1480349159276},{"serialNumber":"Cd/dug==","enabled":true,"last_modified":1480349162902,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=","id":"3cf54b7b-336d-7c80-4596-d5a7762329d9","schema":1480349159276},{"serialNumber":"M64Z5ufZzDRVTHkJR1uXzw==","enabled":true,"last_modified":1480349162880,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBSb290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWU=","id":"5d6d86a0-7e3e-b832-83e5-afc1eb2e294f","schema":1480349159276},{"serialNumber":"BAAAAAABIBnBjWg=","enabled":true,"last_modified":1480349162857,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxTaWduIFJvb3QgQ0E=","id":"0713fba9-386c-888f-cbe5-5188ff2696a4","schema":1480349159276},{"serialNumber":"fWK0j/Vi8vNWg3VAGjc02w==","enabled":true,"last_modified":1480349162835,"details":{"who":".","created":"2016-07-14T14:40:23Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1286752","name":"Symantec erroneous SHA-1 certificates","why":"."},"issuerName":"MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=","id":"a4428979-4be6-3ba2-f435-aa8e4574ffe0","schema":1480349159276},{"serialNumber":"JpUvYJyWjdGmeoH7YcYunw==","enabled":true,"last_modified":1480349162803,"details":{"who":".","created":"2016-04-28T21:08:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MEExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xGzAZBgNVBAMTEnRoYXd0ZSBTU0wgQ0EgLSBHMg==","id":"929de7d6-0669-5601-0b8f-9a192bf1cb17","schema":1480349159276},{"serialNumber":"45KI4WIxyXfNrdtdj7C6","enabled":true,"last_modified":1480349162781,"details":{"who":".","created":"2016-04-28T21:08:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=","id":"7cb25ddb-9f7e-7297-e8b4-c50d019f0cf7","schema":1480349159276},{"serialNumber":"BQ==","enabled":true,"last_modified":1480349162758,"details":{"who":".","created":"2016-07-28T12:15:22Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1289808","name":"FNMT revoked intermediate certificates","why":"."},"issuerName":"MDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTQ==","id":"7c28e9e7-b9ce-f4ed-8d5a-e7b9e534fba5","schema":1480349159276},{"serialNumber":"F7PAjw2k0dTX5escPnyVOBo=","enabled":true,"last_modified":1480349162734,"details":{"who":".","created":"2016-01-18T14:45:19Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MFwxCzAJBgNVBAYTAkJFMRUwEwYDVQQLEwxUcnVzdGVkIFJvb3QxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExGzAZBgNVBAMTElRydXN0ZWQgUm9vdCBDQSBHMg==","id":"3c7e3e8e-5c25-8fbf-0006-2c92256e0a4b","schema":1480349159276},{"serialNumber":"Sx51x7V8pYe8rp7PMP/3qg==","enabled":true,"last_modified":1480349162710,"details":{"who":".","created":"2016-04-28T21:08:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=","id":"4006917e-3260-59cd-eb3f-f4d1167cf888","schema":1480349159276},{"serialNumber":"DHmmaw==","enabled":true,"last_modified":1480349162686,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=","id":"0abfb8ad-d1b7-5f0e-cbea-630f2424171d","schema":1480349159276},{"serialNumber":"CcHC/g==","enabled":true,"last_modified":1480349162661,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=","id":"cba8acd8-a291-1ad6-9581-ed647dd5d56d","schema":1480349159276},{"serialNumber":"ATE0vw==","enabled":true,"last_modified":1480349162632,"details":{"who":".","created":"2015-05-08T10:53:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155114","name":"Intermediate CA's under Staat der Nederlanden Root CA","why":"."},"issuerName":"MGExCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xMjAwBgNVBAMMKVN0YWF0IGRlciBOZWRlcmxhbmRlbiBPcmdhbmlzYXRpZSBDQSAtIEcy","id":"fc71cbb8-4e2a-2835-d5be-4c48cd3650bb","schema":1480349159276},{"serialNumber":"BAAAAAABLF5/HXY=","enabled":true,"last_modified":1480349162610,"details":{"who":".","created":"2016-10-27T17:52:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==","id":"ca59600c-e90a-e85a-43b8-22bc76bb0e1f","schema":1480349159276},{"serialNumber":"BXA=","enabled":true,"last_modified":1480349162580,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDI=","id":"a44b5bf8-8158-1924-7626-e1ba2d2031f7","schema":1480349159276},{"serialNumber":"VOcIuNbTqkpOMUyI108FOg==","enabled":true,"last_modified":1480349162557,"details":{"who":".","created":"2016-03-01T21:24:01Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1252142","name":"exceptional SHA-1 Certificates","why":"."},"issuerName":"MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=","id":"43e72628-c1a5-2091-2dcd-41bbde768c73","schema":1480349159276},{"serialNumber":"ATFpsA==","enabled":true,"last_modified":1480349162533,"details":{"who":".","created":"2015-05-08T10:53:40Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155114","name":"Intermediate CA's under Staat der Nederlanden Root CA","why":"."},"issuerName":"MFkxCzAJBgNVBAYTAk5MMR4wHAYDVQQKExVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xKjAoBgNVBAMTIVN0YWF0IGRlciBOZWRlcmxhbmRlbiBPdmVyaGVpZCBDQQ==","id":"325bb598-839b-f7aa-8a22-08ab8c09e803","schema":1480349159276},{"serialNumber":"UV9aaDeNRNtQuXjRYk4Skhg=","enabled":true,"last_modified":1480349162506,"details":{"who":".","created":"2016-01-18T14:45:50Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MFwxCzAJBgNVBAYTAkJFMRUwEwYDVQQLEwxUcnVzdGVkIFJvb3QxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExGzAZBgNVBAMTElRydXN0ZWQgUm9vdCBDQSBHMg==","id":"c11dd0af-83d5-61ec-63af-5b816a3ae557","schema":1480349159276},{"serialNumber":"bzTw0uq05TUYEGS98bh0Ww==","enabled":true,"last_modified":1480349162483,"details":{"who":".","created":"2016-07-14T14:40:23Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1286752","name":"Symantec erroneous SHA-1 certificates","why":"."},"issuerName":"MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=","id":"6b743fc3-1ce6-8dfe-52f1-9f3e6a31f15a","schema":1480349159276},{"serialNumber":"Gd/pPu+qLnXUdvP9sW73CQ==","enabled":true,"last_modified":1480349162460,"details":{"who":".","created":"2016-03-01T21:21:30Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1252142","name":"exceptional SHA-1 Certificates","why":"."},"issuerName":"MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=","id":"2da11236-c2d8-7804-7de3-ffd711406b04","schema":1480349159276},{"serialNumber":"BAAAAAABJ/v3ZwA=","enabled":true,"last_modified":1480349162438,"details":{"who":".","created":"2016-10-27T17:52:09Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIyMRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu","id":"9f6615be-a0b9-519a-1e26-2bd7aaf5953b","schema":1480349159276},{"serialNumber":"BAAAAAABGMGjftY=","enabled":true,"last_modified":1480349162415,"details":{"who":".","created":"2016-01-18T14:39:05Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==","id":"5f1ab732-8d48-0102-fb50-46ce74fc1a90","schema":1480349159276},{"serialNumber":"Rvm2CEw2IC2Mu/ax0A46QQ==","enabled":true,"last_modified":1480349162392,"details":{"who":".","created":"2016-04-28T21:08:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MGMxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xHTAbBgNVBAsTFERvbWFpbiBWYWxpZGF0ZWQgU1NMMR4wHAYDVQQDExV0aGF3dGUgRFYgU1NMIENBIC0gRzI=","id":"82f97501-85ba-bb19-f68f-ca7ce68ca7b3","schema":1480349159276},{"serialNumber":"BAAAAAABJpQ0AbA=","enabled":true,"last_modified":1480349162369,"details":{"who":".","created":"2016-10-27T17:52:14Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MDsxGDAWBgNVBAoTD0N5YmVydHJ1c3QsIEluYzEfMB0GA1UEAxMWQ3liZXJ0cnVzdCBHbG9iYWwgUm9vdA==","id":"520cee2c-e36a-936e-d551-a51ee9c659c8","schema":1480349159276},{"serialNumber":"ByfHkw==","enabled":true,"last_modified":1480349161997,"details":{"who":".","created":"2016-10-27T17:52:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=","id":"74d82589-0fde-91da-20cc-22fbd84cd0aa","schema":1480349159276},{"serialNumber":"ESC8DawWRiAyEMd38UXbfgPR","enabled":true,"last_modified":1480349161969,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB","id":"6147b64f-da46-ba30-2b9e-30b515e8f6b9","schema":1480349159276},{"serialNumber":"BAAAAAABK84ykc0=","enabled":true,"last_modified":1480349161946,"details":{"who":".","created":"2016-10-27T17:52:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFYxCzAJBgNVBAYTAkpQMQ8wDQYDVQQKEwZKSVBERUMxGjAYBgNVBAsTEUpDQU4gU3ViIFJvb3QgQ0EwMRowGAYDVQQDExFKQ0FOIFN1YiBSb290IENBMA==","id":"0a42070f-3149-2b91-1bbe-c54de4ed1be8","schema":1480349159276},{"serialNumber":"GN2Hrh9LtnM=","enabled":true,"last_modified":1480349161925,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIGVMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTE=","id":"dc28966b-d7db-b55f-1606-c5bff610bf99","schema":1480349159276},{"serialNumber":"FJl6tXgNpSg=","enabled":true,"last_modified":1480349161902,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIGVMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTE=","id":"bab58b65-8ef7-f3c2-fc13-88f72a0840f7","schema":1480349159276},{"serialNumber":"ESDItX4ruWiLnrlz0rk4/bmz","enabled":true,"last_modified":1480349161872,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB","id":"c12d5f3c-b722-948f-b367-857845ed5e8e","schema":1480349159276},{"serialNumber":"bx/XHJqcwxDOptxJ2lh5vw==","enabled":true,"last_modified":1480349161850,"details":{"who":".","created":"2016-04-28T21:08:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MEQxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQDExRHZW9UcnVzdCBTU0wgQ0EgLSBHMw==","id":"a0da0bd1-8bec-4c82-fb9b-636ddcde057d","schema":1480349159276},{"serialNumber":"Mq0P6o03FDk0B2bnJ+mYPGo=","enabled":true,"last_modified":1480349161828,"details":{"who":".","created":"2016-01-18T14:47:39Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MFwxCzAJBgNVBAYTAkJFMRUwEwYDVQQLEwxUcnVzdGVkIFJvb3QxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExGzAZBgNVBAMTElRydXN0ZWQgUm9vdCBDQSBHMg==","id":"54f096a5-3608-9b68-ddca-a200e799ba06","schema":1480349159276},{"serialNumber":"BAAAAAABJ/ufQg8=","enabled":true,"last_modified":1480349161807,"details":{"who":".","created":"2016-01-18T14:43:00Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==","id":"61db13cb-74d9-e675-a1e8-db5f78eb3f4e","schema":1480349159276},{"serialNumber":"BAAAAAABM6d3Z0s=","enabled":true,"last_modified":1480349161785,"details":{"who":".","created":"2016-10-27T17:52:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==","id":"b9c439ef-fcf3-2263-c14e-80727cbef898","schema":1480349159276},{"serialNumber":"FNISyWWTGi5Yco6fGh58/A==","enabled":true,"last_modified":1480349161763,"details":{"who":".","created":"2016-04-28T21:08:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MEExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xGzAZBgNVBAMTEnRoYXd0ZSBTU0wgQ0EgLSBHMg==","id":"bab0ff94-c98e-7843-97b3-a4d1e044715b","schema":1480349159276},{"serialNumber":"VfTSum25nb65YPlpuhJAvg==","enabled":true,"last_modified":1480349161740,"details":{"who":".","created":"2016-04-28T21:08:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MEQxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQDExRHZW9UcnVzdCBTU0wgQ0EgLSBHMg==","id":"91149dc9-6cc4-a670-1799-7bd05c159858","schema":1480349159276},{"serialNumber":"OhrtngFwotLcm4i+z00SjA==","enabled":true,"last_modified":1480349161718,"details":{"who":".","created":"2016-04-28T21:08:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MH8xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEwMC4GA1UEAxMnU3ltYW50ZWMgQ2xhc3MgMyBFQ0MgMjU2IGJpdCBFViBDQSAtIEcy","id":"337e2f4b-02c4-c70d-55be-09c8ea41731c","schema":1480349159276},{"serialNumber":"AN9bfYOvlR1t","enabled":true,"last_modified":1480349161696,"details":{"who":".","created":"2015-07-13T09:05:40Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1181126","name":"RCS Certification Authority","why":"."},"issuerName":"MDcxJDAiBgNVBAMTG1JDUyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEPMA0GA1UEChMGSFQgc3Js","id":"18c0d37b-739d-04c6-04f2-a615be5b9948","schema":1480349159276},{"serialNumber":"F5BhENPfVw==","enabled":true,"last_modified":1480349161666,"details":{"who":".","created":"2016-10-27T17:52:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=","id":"72a65abf-9828-365f-4d4a-78457d7bdec4","schema":1480349159276},{"serialNumber":"ESISuBo/wdW2tBztKmHdFCFz","enabled":true,"last_modified":1480349161641,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB","id":"2ad44cbf-32ca-5245-c881-6d6f290ac2c1","schema":1480349159276},{"serialNumber":"CrTHPEE6AZSfI3jysin2bA==","enabled":true,"last_modified":1480349161619,"details":{"who":".","created":"2015-09-21T13:21:25Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1205651","name":"Misused certificate","why":"."},"issuerName":"MEQxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xHjAcBgNVBAMTFXRoYXd0ZSBFViBTU0wgQ0EgLSBHMw==","id":"13987e52-821e-1fe3-3743-393136b17167","schema":1480349159276},{"serialNumber":"WX89jn8yGZVvoKTD9jDfRQ==","enabled":true,"last_modified":1480349161596,"details":{"who":".","created":"2016-04-28T21:08:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MEQxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQDExRHZW9UcnVzdCBTU0wgQ0EgLSBHMg==","id":"a15c9fa5-cd6e-362d-1341-1e95c11c38fb","schema":1480349159276},{"serialNumber":"JV/LVzSKI/wsDgg3UuZHlA==","enabled":true,"last_modified":1480349161575,"details":{"who":".","created":"2016-03-01T21:22:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1252142","name":"exceptional SHA-1 Certificates","why":"."},"issuerName":"MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=","id":"ba7935ef-b624-3eef-5ae8-a78044ec3af0","schema":1480349159276},{"serialNumber":"sPNcCSE9Nkg3jy5IN1xe2Q==","enabled":true,"last_modified":1480349161553,"details":{"who":".","created":"2016-01-18T14:44:46Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MFwxCzAJBgNVBAYTAkJFMRUwEwYDVQQLEwxUcnVzdGVkIFJvb3QxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExGzAZBgNVBAMTElRydXN0ZWQgUm9vdCBDQSBHMg==","id":"edc761c4-8b47-5314-0cd1-c894612ebfc3","schema":1480349159276},{"serialNumber":"buROL/l2GuXISv+/JVLkdA==","enabled":true,"last_modified":1480349161531,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA2IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHNQ==","id":"963548ca-bde2-1843-f140-1c26e8e40def","schema":1480349159276},{"serialNumber":"Cfk9oA==","enabled":true,"last_modified":1480349161510,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=","id":"e85980d5-12f0-f624-7904-2d6cedeacd55","schema":1480349159276},{"serialNumber":"IyIVazG4RE9AERkb+ekH8w==","enabled":true,"last_modified":1480349161489,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5","id":"be3014a7-3d3b-08c7-02d9-5a74f601a1b1","schema":1480349159276},{"serialNumber":"HNo1DR4XCe4mS1iUMsY6Wg==","enabled":true,"last_modified":1480349161466,"details":{"who":".","created":"2016-04-28T21:08:06Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzM=","id":"fd51f7d8-2006-663f-4779-3cf559ee5e74","schema":1480349159276},{"serialNumber":"Ai7cBJYqBE0I9NdyoZfRrw==","enabled":true,"last_modified":1480349161443,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIG9MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5","id":"f7582bc8-dbdb-37dd-b24c-418242bbc4e0","schema":1480349159276},{"serialNumber":"UUFV3S2cUidOOv7ESN65Ng==","enabled":true,"last_modified":1480349161103,"details":{"who":".","created":"2016-07-14T14:40:23Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1286752","name":"Symantec erroneous SHA-1 certificates","why":"."},"issuerName":"MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=","id":"24ccf065-b88b-0fc9-1d1f-6c7722ca4faa","schema":1480349159276},{"serialNumber":"EDQMI0tR4kSntv1O37N10g==","enabled":true,"last_modified":1480349161077,"details":{"who":".","created":"2016-04-28T21:08:06Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzI=","id":"e7509e16-1cd3-599e-2630-495ab52d3b71","schema":1480349159276},{"serialNumber":"BAAAAAABI54PryQ=","enabled":true,"last_modified":1480349161051,"details":{"who":".","created":"2016-01-18T14:48:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MIGBMQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTElMCMGA1UECxMcUHJpbWFyeSBPYmplY3QgUHVibGlzaGluZyBDQTEwMC4GA1UEAxMnR2xvYmFsU2lnbiBQcmltYXJ5IE9iamVjdCBQdWJsaXNoaW5nIENB","id":"e3bd531e-1ee4-7407-27ce-6fdc9cecbbdc","schema":1480349159276},{"serialNumber":"Byc68g==","enabled":true,"last_modified":1480349161021,"details":{"who":".","created":"2016-10-27T17:52:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=","id":"308f27b5-fc0e-da9a-2b7f-e65a1cb5cd47","schema":1480349159276},{"serialNumber":"AuhvPsYZfVP6UDsuyjeZ4Q==","enabled":true,"last_modified":1480349160991,"details":{"who":".","created":"2016-04-28T21:08:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MHMxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEkMCIGA1UEAxMbU3ltYW50ZWMgQ2xhc3MgMyBEU0EgU1NMIENB","id":"a0482eed-1e3f-7b9f-a433-94e4a4da49a1","schema":1480349159276},{"serialNumber":"BAAAAAABMrS7t2g=","enabled":true,"last_modified":1480349160963,"details":{"who":".","created":"2016-01-18T14:39:59Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==","id":"41a888b9-2e84-9782-69dc-d9153a3bd3aa","schema":1480349159276},{"serialNumber":"Ermwxw==","enabled":true,"last_modified":1480349160941,"details":{"who":".","created":"2016-07-21T16:52:32Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1197885","name":"SECOM intermediate certificate","why":"."},"issuerName":"MFAxCzAJBgNVBAYTAkpQMRgwFgYDVQQKEw9TRUNPTSBUcnVzdC5uZXQxJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmljYXRpb24gUm9vdENBMQ==","id":"1220feb9-9e66-0b24-3409-c5d1a1f8d24f","schema":1480349159276},{"serialNumber":"BAAAAAABCfhiO+s=","enabled":true,"last_modified":1480349160914,"details":{"who":".","created":"2016-01-18T14:36:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MF8xCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRQwEgYDVQQLEwtQYXJ0bmVycyBDQTEfMB0GA1UEAxMWR2xvYmFsU2lnbiBQYXJ0bmVycyBDQQ==","id":"e17ded97-6669-eecc-54fa-81f9a81ed281","schema":1480349159276},{"serialNumber":"cXXMzbWDHMIdCotb3h64yw==","enabled":true,"last_modified":1480349160892,"details":{"who":".","created":"2016-07-21T16:58:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1288354","name":"Symantec AATL ECC Intermediate CA cert","why":"."},"issuerName":"MIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA3IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHNA==","id":"a9970f7e-bac4-3b91-eae3-b0335ce0d1c2","schema":1480349159276},{"serialNumber":"OqQ2rV0ISTc308Z/oQgzFw==","enabled":true,"last_modified":1480349160870,"details":{"who":".","created":"2016-04-28T21:08:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MIG1MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMS8wLQYDVQQDEyZWZXJpU2lnbiBDbGFzcyAzIFNlY3VyZSBTZXJ2ZXIgQ0EgLSBHMw==","id":"781f8787-6508-d6aa-c508-13ac2bb0d930","schema":1480349159276},{"serialNumber":"Cyr1PA==","enabled":true,"last_modified":1480349160848,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=","id":"ec93f86d-fea2-7eea-42d4-7cf7a397e097","schema":1480349159276},{"serialNumber":"F5Bg+EziQQ==","enabled":true,"last_modified":1480349160826,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=","id":"64229466-b4da-c63f-e088-ab1b5ba37930","schema":1480349159276},{"serialNumber":"BAAAAAABEAuMoRs=","enabled":true,"last_modified":1480349160804,"details":{"who":".","created":"2016-10-27T17:52:09Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIyMRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu","id":"fe2dd507-9fc4-a6db-7ee0-255452bea28a","schema":1480349159276},{"serialNumber":"BAAAAAABHkSHlSo=","enabled":true,"last_modified":1480349160782,"details":{"who":".","created":"2016-01-18T14:39:24Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==","id":"04460239-09d9-2a76-191e-f344a8e5d0bd","schema":1480349159276},{"serialNumber":"BAAAAAABKB/OGqI=","enabled":true,"last_modified":1480349160759,"details":{"who":".","created":"2016-01-18T14:41:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==","id":"6b5475ec-8181-e7b8-4245-c7e2ffed213c","schema":1480349159276},{"serialNumber":"ESDu2nhlLPzfx+LYgjlYFP/k","enabled":true,"last_modified":1480349160736,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB","id":"dc98c4eb-836f-6ca0-6673-6678fc45516a","schema":1480349159276},{"serialNumber":"BA==","enabled":true,"last_modified":1480349160714,"details":{"who":".","created":"2016-07-28T12:14:46Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1289808","name":"FNMT revoked intermediate certificates","why":"."},"issuerName":"MDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTQ==","id":"765f426d-748a-5f3d-e409-35eac9be8240","schema":1480349159276},{"serialNumber":"Aw==","enabled":true,"last_modified":1480349160684,"details":{"who":".","created":"2016-10-27T17:52:14Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIGFMQswCQYDVQQGEwJVUzEgMB4GA1UECgwXV2VsbHMgRmFyZ28gV2VsbHNTZWN1cmUxHDAaBgNVBAsME1dlbGxzIEZhcmdvIEJhbmsgTkExNjA0BgNVBAMMLVdlbGxzU2VjdXJlIFB1YmxpYyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eQ==","id":"644e3fde-7ab5-556a-85ef-c5fac8b8c7de","schema":1480349159276},{"serialNumber":"BAAAAAABMYnGRuw=","enabled":true,"last_modified":1480349160660,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIzMRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu","id":"0a9335d8-3fa3-5d0b-7b27-72ddd14b5f74","schema":1480349159276},{"serialNumber":"Byd5cg==","enabled":true,"last_modified":1480349160638,"details":{"who":".","created":"2016-10-27T17:52:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=","id":"f046b001-5aa9-09b4-995d-23ad9f15db30","schema":1480349159276},{"serialNumber":"ESJJweWBPhoXAaB9c8SHwI4O","enabled":true,"last_modified":1480349160614,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB","id":"1bdc6228-2f9d-ad26-30b2-408959ede857","schema":1480349159276},{"serialNumber":"LTRcDHabRHU=","enabled":true,"last_modified":1480349160593,"details":{"who":".","created":"2016-10-27T17:52:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MGExCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xMjAwBgNVBAMMKVN0YWF0IGRlciBOZWRlcmxhbmRlbiBPcmdhbmlzYXRpZSBDQSAtIEcy","id":"86e95439-a9f5-e04e-5241-268cf0186425","schema":1480349159276},{"serialNumber":"YNOos6YJoPC77qwSGCpb7w==","enabled":true,"last_modified":1480349160571,"details":{"who":".","created":"2016-04-28T21:08:06Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzM=","id":"3c4f4898-da76-0a38-a765-18d9436285f2","schema":1480349159276},{"serialNumber":"BAAAAAABHkSHki0=","enabled":true,"last_modified":1480349160547,"details":{"who":".","created":"2016-10-27T17:52:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==","id":"e057bdab-4ad6-7e50-83ce-1099b84cce04","schema":1480349159276},{"serialNumber":"A9GPKQ8jv9oIxfwiOy7qxQ==","enabled":true,"last_modified":1480349160524,"details":{"who":".","created":"2016-07-14T14:40:23Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1286752","name":"Symantec erroneous SHA-1 certificates","why":"."},"issuerName":"MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=","id":"4bb8966b-1db9-844d-4904-d823539cdf7e","schema":1480349159276},{"serialNumber":"Cbssdw==","enabled":true,"last_modified":1480349160216,"details":{"who":".","created":"2016-10-27T17:52:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=","id":"661e65a5-ee0b-7a82-12c3-731cb560e112","schema":1480349159276},{"serialNumber":"CcHC1w==","enabled":true,"last_modified":1480349160190,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=","id":"26890617-93ad-e85f-550a-afb414cd110c","schema":1480349159276},{"serialNumber":"DjIvBkX+ECVbB/C3i6w2Gg==","enabled":true,"last_modified":1480349160165,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB","id":"657b91b1-9447-8c4a-db57-e0f0e2b10439","schema":1480349159276},{"serialNumber":"UoRGnb96CUDTxIqVry6LBg==","enabled":true,"last_modified":1480349160143,"details":{"who":".","created":"2015-04-07T11:04:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1150585","name":"XS4ALL certificate","why":"."},"issuerName":"MIGQMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01PRE8gQ0EgTGltaXRlZDE2MDQGA1UEAxMtQ09NT0RPIFJTQSBEb21haW4gVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB","id":"9084bc79-01cf-2ddc-b077-cd6c6251dd2b","schema":1480349159276},{"serialNumber":"PAdKZPiaac2CvPxbOrsHOw==","enabled":true,"last_modified":1480349160119,"details":{"who":".","created":"2016-04-28T21:08:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=","id":"b79e2eb5-754d-4c21-1d8a-8c363f70dadc","schema":1480349159276},{"serialNumber":"EqthLKdUgwI=","enabled":true,"last_modified":1480349160086,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIGQMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxOzA5BgNVBAMTMkFyaXN0b3RsZSBVbml2ZXJzaXR5IG9mIFRoZXNzYWxvbmlraSBDZW50cmFsIENBIFI0","id":"5b9744a8-bd65-b926-2920-8d8e5e1acd7d","schema":1480349159276},{"serialNumber":"OE4/d+p3YRzzcSl+kmZ8Mw==","enabled":true,"last_modified":1480349160058,"details":{"who":".","created":"2016-04-28T21:08:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MGgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEiMCAGA1UEAxMZR2VvVHJ1c3QgRFYgU1NMIFNIQTI1NiBDQQ==","id":"fd2fe6f3-d095-5c3d-3c6b-afe00cb665c0","schema":1480349159276},{"serialNumber":"QZCrvA==","enabled":true,"last_modified":1480349160028,"details":{"who":".","created":"2016-10-27T17:52:14Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIGCMQswCQYDVQQGEwJVUzEeMBwGA1UECxMVd3d3LnhyYW1wc2VjdXJpdHkuY29tMSQwIgYDVQQKExtYUmFtcCBTZWN1cml0eSBTZXJ2aWNlcyBJbmMxLTArBgNVBAMTJFhSYW1wIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQ==","id":"32f968f5-4426-66ad-d1ab-9dda7b6f0c85","schema":1480349159276},{"serialNumber":"AygWP2Fgd2T+iLbmAlKT6g==","enabled":true,"last_modified":1480349159993,"details":{"who":".","created":"2016-04-28T21:08:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=","id":"e23bcca2-1fb1-abd2-5ed7-892c5f08c4ff","schema":1480349159276},{"serialNumber":"CqL7CA==","enabled":true,"last_modified":1480349159963,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=","id":"1a0c71ac-7f34-eeb0-2f71-1c14ee8e6552","schema":1480349159276},{"serialNumber":"E77H6yvyFQjO0PcN3x0H+Q==","enabled":true,"last_modified":1480349159939,"details":{"who":".","created":"2016-04-28T21:08:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MH4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEvMC0GA1UEAxMmU3ltYW50ZWMgQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzQ=","id":"be9e31eb-6a06-7699-708a-732a081a10c7","schema":1480349159276},{"serialNumber":"YRJNfMoc12IpmW+Enpv3Pdo=","enabled":true,"last_modified":1480349159914,"details":{"who":".","created":"2016-01-18T14:46:04Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MFwxCzAJBgNVBAYTAkJFMRUwEwYDVQQLEwxUcnVzdGVkIFJvb3QxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExGzAZBgNVBAMTElRydXN0ZWQgUm9vdCBDQSBHMg==","id":"3bb8f2d9-511b-121d-da29-23041d3c15c1","schema":1480349159276},{"serialNumber":"ATFEdg==","enabled":true,"last_modified":1480349159890,"details":{"who":".","created":"2015-05-08T10:54:05Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155114","name":"Intermediate CA's under Staat der Nederlanden Root CA","why":"."},"issuerName":"MFkxCzAJBgNVBAYTAk5MMR4wHAYDVQQKExVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xKjAoBgNVBAMTIVN0YWF0IGRlciBOZWRlcmxhbmRlbiBPdmVyaGVpZCBDQQ==","id":"4a17f132-602c-2d30-a781-145087794075","schema":1480349159276},{"serialNumber":"e0bEFhI16xx9U1yvlI56rA==","enabled":true,"last_modified":1480349159869,"details":{"who":".","created":"2016-04-28T21:08:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MEExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxUaGF3dGUsIEluYy4xGzAZBgNVBAMTElRoYXd0ZSBTR0MgQ0EgLSBHMg==","id":"07b97387-d755-0bbb-6e4c-616a7cb69cb4","schema":1480349159276},{"serialNumber":"GN2Hrh9LtnA=","enabled":true,"last_modified":1480349159846,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIGVMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTE=","id":"b3fb394d-f951-b49e-d856-f93028850feb","schema":1480349159276},{"serialNumber":"AQAAAAU=","enabled":true,"last_modified":1480349159825,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIGVMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTE=","id":"2448ada0-833d-0d4d-3bcd-2c73cff02fb4","schema":1480349159276},{"serialNumber":"BAAAAAABCFiEp9s=","enabled":true,"last_modified":1480349159804,"details":{"who":".","created":"2016-01-18T14:38:03Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MF8xCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRQwEgYDVQQLEwtQYXJ0bmVycyBDQTEfMB0GA1UEAxMWR2xvYmFsU2lnbiBQYXJ0bmVycyBDQQ==","id":"5cef5dc2-95f2-0ac8-3273-153a09d3d227","schema":1480349159276},{"serialNumber":"CSY=","enabled":true,"last_modified":1480349159782,"details":{"who":".","created":"2016-10-27T17:52:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDM=","id":"b4c9041b-f5a5-dec1-b221-7286a32a6309","schema":1480349159276},{"serialNumber":"BAAAAAABHJRKNmk=","enabled":true,"last_modified":1480349159760,"details":{"who":".","created":"2016-01-18T14:44:06Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==","id":"824e9b09-808e-e8cb-f2dd-ba669df011bc","schema":1480349159276},{"serialNumber":"DYifRdP6aQQ8MLbXZY2f5g==","enabled":true,"last_modified":1480349159739,"details":{"who":".","created":"2016-04-28T21:08:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MGMxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xHTAbBgNVBAsTFERvbWFpbiBWYWxpZGF0ZWQgU1NMMR4wHAYDVQQDExV0aGF3dGUgRFYgU1NMIENBIC0gRzI=","id":"59a292db-d567-6485-167f-1cb5af33f437","schema":1480349159276},{"serialNumber":"BAAAAAABL07hTcY=","enabled":true,"last_modified":1480349159716,"details":{"who":".","created":"2016-10-27T17:52:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFYxCzAJBgNVBAYTAkpQMQ8wDQYDVQQKEwZKSVBERUMxGjAYBgNVBAsTEUpDQU4gU3ViIFJvb3QgQ0EwMRowGAYDVQQDExFKQ0FOIFN1YiBSb290IENBMA==","id":"0a5a0233-bb8a-e4cc-5bb6-03cee44a07c2","schema":1480349159276},{"serialNumber":"L7tgs/W85vnhV7I7qJ6N/g==","enabled":true,"last_modified":1480349159694,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MF4xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5","id":"e38e4e46-413a-eac8-9e85-1b9ee06f535d","schema":1480349159276},{"serialNumber":"BAAAAAABLM/7qjk=","enabled":true,"last_modified":1480349159673,"details":{"who":".","created":"2016-01-18T14:40:36Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==","id":"62dfeb32-e132-09a3-e4ba-e48c21d027de","schema":1480349159276},{"serialNumber":"BAAAAAABHkSHjz8=","enabled":true,"last_modified":1480349159649,"details":{"who":".","created":"2016-01-18T14:41:41Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==","id":"880134d0-617c-ec1b-3568-4c74af31bcc1","schema":1480349159276},{"serialNumber":"Cfk9qg==","enabled":true,"last_modified":1480349159625,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpERk4tVmVyZWluMRAwDgYDVQQLEwdERk4tUEtJMSQwIgYDVQQDExtERk4tVmVyZWluIFBDQSBHbG9iYWwgLSBHMDE=","id":"9debdd66-d615-073f-26f7-011a8c54b484","schema":1480349159276},{"serialNumber":"AQAAAAM=","enabled":true,"last_modified":1480349159267,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIGVMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTE=","id":"e4d16e1f-ac86-e9c0-2122-8a7d7d2dcdc0","schema":1480343774567},{"serialNumber":"ESAyW/JX3+hZIp44EAMlXU2b","enabled":true,"last_modified":1480349159244,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB","id":"6b135741-bfc6-1b3f-eb4b-4569aae2ab34","schema":1480343774567},{"serialNumber":"AQAAAAQ=","enabled":true,"last_modified":1480349159206,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIGVMQswCQYDVQQGEwJHUjFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTE=","id":"263f03a7-53f0-2140-89a5-46e7740d755a","schema":1480343774567},{"serialNumber":"ESByYNtAIfizf2L3NMzCH8zZ","enabled":true,"last_modified":1480349159183,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB","id":"853889e5-ad93-77ea-f9c0-a0907c9a3576","schema":1480343774567},{"serialNumber":"BYOGvG32ukb1Yxj2oKoFyw==","enabled":true,"last_modified":1480349159159,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIG9MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5","id":"b049208e-5f4c-60a6-ac91-45f093defc33","schema":1480343774567},{"serialNumber":"P6G7IYSL2RZxtzTh8I6qPA==","enabled":true,"last_modified":1480349159136,"details":{"who":".","created":"2016-04-28T21:08:06Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzI=","id":"222a4201-120e-64f4-5f6f-b2314470365c","schema":1480343774567},{"serialNumber":"D/wZ7+m1Mv8SONSEFcs73w==","enabled":true,"last_modified":1480349159113,"details":{"who":".","created":"2016-10-27T17:52:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIGuMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTE2MDQGA1UEAxMtVVROLVVTRVJGaXJzdC1DbGllbnQgQXV0aGVudGljYXRpb24gYW5kIEVtYWls","id":"d7fdf5b8-f8a5-b105-297d-d0e3617e59fc","schema":1480343774567},{"serialNumber":"eR1nUEz8k+nDSBD+bb5uIQ==","enabled":true,"last_modified":1480349159091,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIG9MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5","id":"f6fb7b44-64cd-37b9-b9f6-fbe1210cb160","schema":1480343774567},{"serialNumber":"QZBvapTZFvmYktEPsBYLQQ==","enabled":true,"last_modified":1480349159069,"details":{"who":".","created":"2016-04-28T21:08:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MIG1MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMS8wLQYDVQQDEyZWZXJpU2lnbiBDbGFzcyAzIFNlY3VyZSBTZXJ2ZXIgQ0EgLSBHMw==","id":"b6f5b3ee-6cac-57a7-b4e9-83e84f1020b8","schema":1480343774567},{"serialNumber":"BAAAAAABKUXDqA8=","enabled":true,"last_modified":1480349159034,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxTaWduIFJvb3QgQ0E=","id":"e48f4383-6df1-0a9b-8063-a2add391a879","schema":1480343774567},{"serialNumber":"BAAAAAABLF5/Gog=","enabled":true,"last_modified":1480349159011,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxTaWduIFJvb3QgQ0E=","id":"bc0be7d5-b8d3-1ac2-8a63-f5bf8b00ba3c","schema":1480343774567},{"serialNumber":"UW3oKZKTDsrPy/rfwmGNaQ==","enabled":true,"last_modified":1480349158980,"details":{"who":".","created":"2016-04-28T21:08:06Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MGYxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzM=","id":"2a14bce1-47bb-e067-74a6-46be30e576a7","schema":1480343774567},{"serialNumber":"CSU=","enabled":true,"last_modified":1480349158957,"details":{"who":".","created":"2016-10-27T17:52:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDM=","id":"77e152ae-89a4-53b1-62d4-fb7c2cd5037b","schema":1480343774567},{"serialNumber":"U3t2Vk8pfxTcaUPpIq0seQ==","enabled":true,"last_modified":1480349158934,"details":{"who":".","created":"2016-10-27T17:52:14Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3Q=","id":"2c8f7191-fc5f-c2e0-af8d-852faefcdadf","schema":1480343774567},{"serialNumber":"BAAAAAABAPpuVh0=","enabled":true,"last_modified":1480349158899,"details":{"who":".","created":"2016-01-18T14:38:46Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1155145","name":"GlobalSign certs","why":"."},"issuerName":"MHExKDAmBgNVBAMTH0dsb2JhbFNpZ24gUm9vdFNpZ24gUGFydG5lcnMgQ0ExHTAbBgNVBAsTFFJvb3RTaWduIFBhcnRuZXJzIENBMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMQswCQYDVQQGEwJCRQ==","id":"fce6cca1-707c-c4f2-6de2-26c4663cda01","schema":1480343774567},{"serialNumber":"U4P1tUoxl/XkztlVHdtdgw==","enabled":true,"last_modified":1480349158876,"details":{"who":".","created":"2016-10-27T17:52:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMw==","id":"ed4d2530-eb3e-800f-41b2-e70023185673","schema":1480343774567},{"serialNumber":"U3SgRR3J+D6575WuCxuXeQ==","enabled":true,"last_modified":1480349158854,"details":{"who":".","created":"2016-04-28T21:08:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MHsxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3JhdGlvbjEfMB0GA1UECxMWU3ltYW50ZWMgVHJ1c3QgTmV0d29yazEsMCoGA1UEAxMjU3ltYW50ZWMgQ2xhc3MgMyBFQ0MgMjU2IGJpdCBTU0wgQ0E=","id":"72e44e74-fb5d-fc97-abdd-02050d3ab727","schema":1480343774567},{"serialNumber":"EEpERSryZFMagbsNw/WoWQ==","enabled":true,"last_modified":1480349158820,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MIGXMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTEfMB0GA1UEAxMWVVROLVVTRVJGaXJzdC1IYXJkd2FyZQ==","id":"a4f11626-67e9-24e5-81a5-aca8126934c3","schema":1480343774567},{"serialNumber":"BAAAAAABJQcQQN0=","enabled":true,"last_modified":1480349158794,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIzMRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu","id":"e7328f54-0f56-48a2-3bab-d4c9b41a2b13","schema":1480343774567},{"serialNumber":"BydKkg==","enabled":true,"last_modified":1480349158772,"details":{"who":".","created":"2016-10-27T17:52:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MFoxCzAJBgNVBAYTAklFMRIwEAYDVQQKEwlCYWx0aW1vcmUxEzARBgNVBAsTCkN5YmVyVHJ1c3QxIjAgBgNVBAMTGUJhbHRpbW9yZSBDeWJlclRydXN0IFJvb3Q=","id":"6b9bc0cc-c1fa-50eb-5ece-812ee9bac5b6","schema":1480343774567},{"serialNumber":"cpqpXVWPk5AXzGw+zNIcBw==","enabled":true,"last_modified":1480349158750,"details":{"who":".","created":"2016-04-28T21:08:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MEQxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQDExRHZW9UcnVzdCBTU0wgQ0EgLSBHMw==","id":"ac8d05cd-d85d-8caa-ed13-261b83c183c2","schema":1480343774567},{"serialNumber":"CWhp","enabled":true,"last_modified":1480349158726,"details":{"who":".","created":"2016-04-28T21:08:06Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1267648","name":"Symantec test certificates","why":"."},"issuerName":"MGExCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEbMBkGA1UEAxMSR2VvVHJ1c3QgRFYgU1NMIENB","id":"ff01b36d-3bcc-2157-1f89-b1841120c97e","schema":1480343774567},{"serialNumber":"ESCEUbthDurBjJw0/h/FfuNY","enabled":true,"last_modified":1480349158695,"details":{"who":".","created":"2016-10-27T17:52:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xhc3MgMiBQcmltYXJ5IENB","id":"2c047b2c-43aa-d0be-e2c9-2acac789bd55","schema":1480343774567},{"serialNumber":"TXxtAQ==","enabled":true,"last_modified":1480349158671,"details":{"who":".","created":"2016-10-27T17:52:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1312150","name":"Revoked intermediates","why":"."},"issuerName":"MEoxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdTZWN1cmVUcnVzdCBDb3Jwb3JhdGlvbjEZMBcGA1UEAxMQU2VjdXJlIEdsb2JhbCBDQQ==","id":"ea4847df-ca17-c476-11df-b14c1d6658a0","schema":1480343774567},{"serialNumber":"YR3YYQAAAAAABA==","enabled":true,"last_modified":1480349158647,"details":{"who":".","created":"2015-05-08T10:51:23Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1142137","name":"T-Systems intermediate cert","why":"."},"issuerName":"MGcxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpGcmF1bmhvZmVyMSEwHwYDVQQLExhGcmF1bmhvZmVyIENvcnBvcmF0ZSBQS0kxIDAeBgNVBAMTF0ZyYXVuaG9mZXIgUm9vdCBDQSAyMDA3","id":"ae8bec3c-3b92-822e-53f1-68394cbb1758","schema":1480343774567}]} \ No newline at end of file diff --git a/services/blocklists/gfx.json b/services/blocklists/gfx.json new file mode 100644 index 000000000000..630ee78e91e3 --- /dev/null +++ b/services/blocklists/gfx.json @@ -0,0 +1 @@ +{"data":[{"vendor":"0x10de","blockID":"g200","enabled":true,"feature":"WEBGL_MSAA","devices":[],"id":"ae36a32e-5f4f-2f98-804f-22b0de5e7bfa","last_modified":1480349135384,"details":{"who":"All Firefox users.","created":"2012-11-12T10:35:32Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=809550","name":"Mac OS X WebGL anti-aliasing","why":"Security problems."},"os":"Darwin 11","featureStatus":"BLOCKED_DEVICE","schema":1480349134676},{"driverVersionComparator":"EQUAL","driverVersion":"10.18.10.3947","vendor":"0x8086","blockID":"g1217","enabled":true,"feature":"HARDWARE_VIDEO_DECODING","devices":[],"id":"a3fe9700-b9e6-1c31-f94b-030f72f4aa07","last_modified":1480349135360,"details":{"who":".","created":"2016-05-23T15:43:58Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1266220","name":"10.18.10.3947 winnt 6.0","why":"."},"os":"WINNT 6.0","featureStatus":"BLOCKED_DRIVER_VERSION","schema":1480349134676},{"driverVersionComparator":"EQUAL","driverVersion":"8.15.10.2086","vendor":"0x8086","blockID":"g1124","enabled":true,"devices":["0x2a42","0x2e22","0x2e12","0x2e32","0x0046"],"id":"851c8fcb-5763-bf89-813d-0f98cdd6f8c1","last_modified":1480349135337,"details":{"who":".","created":"2016-02-22T23:40:14Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1170143","name":"Intel Driver 8.15.10.2086","why":"."},"os":"All","featureStatus":"BLOCKED_DRIVER_VERSION","schema":1480349134676},{"vendor":"0x10de","blockID":"g202","enabled":true,"feature":"WEBGL_MSAA","devices":[],"id":"a825cb5d-36f6-54b0-31b3-6668aae49cdd","last_modified":1480349135314,"details":{"who":"All Firefox users.","created":"2012-11-12T10:37:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=809550","name":"Mac OS X WebGL anti-aliasing","why":"Security problems."},"os":"Darwin 12","featureStatus":"BLOCKED_DEVICE","schema":1480349134676},{"vendor":"0x8086","blockID":"g208","enabled":true,"feature":"WEBGL_MSAA","devices":[],"id":"a8e8aa1a-8e70-af51-065d-81ed31d23221","last_modified":1480349135291,"details":{"who":"All Firefox users.","created":"2012-11-12T10:42:34Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=809550","name":"Mac OS X WebGL anti-aliasing","why":"Security problems"},"os":"Darwin 12","featureStatus":"BLOCKED_DEVICE","schema":1480349134676},{"driverVersionComparator":"EQUAL","driverVersion":"8.15.10.1994","vendor":"0x8086","blockID":"g1073","enabled":true,"devices":["0x2a42","0x2e22","0x2e12","0x2e32","0x0046"],"id":"13f75dff-c65f-eab1-4be5-864a79503ad5","last_modified":1480349135267,"details":{"who":".","created":"2015-12-21T16:01:46Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1207993","name":"Crash in igd10umd32.dll@0x18f35","why":"."},"os":"All","featureStatus":"BLOCKED_DRIVER_VERSION","schema":1480349134676},{"driverVersionComparator":"EQUAL","driverVersion":"10.18.10.3947","vendor":"0x8086","blockID":"g1221","enabled":true,"feature":"HARDWARE_VIDEO_DECODING","devices":[],"id":"65ad7851-4af6-2a10-1d47-72943e63dcf0","last_modified":1480349135245,"details":{"who":".","created":"2016-05-23T15:47:17Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1266220","name":"10.18.10.3947 winnt 10.0","why":"."},"os":"WINNT 10.0","featureStatus":"BLOCKED_DRIVER_VERSION","schema":1480349134676},{"driverVersionComparator":"EQUAL","driverVersion":"10.18.10.3947","vendor":"0x8086","blockID":"g1216","enabled":true,"feature":"HARDWARE_VIDEO_DECODING","devices":[],"id":"18968a19-7317-cc56-f9fc-f568f40abca4","last_modified":1480349135215,"details":{"who":".","created":"2016-05-23T15:32:22Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1266220","name":"10.18.10.3947 winnt 5.2","why":"."},"os":"WINNT 5.2","featureStatus":"BLOCKED_DRIVER_VERSION","schema":1480349134676},{"driverVersionComparator":"EQUAL","driverVersion":"10.18.10.3947","vendor":"0x8086","blockID":"g1215","enabled":true,"feature":"HARDWARE_VIDEO_DECODING","devices":[],"id":"5c141970-5076-0af4-152f-efb3642a7b14","last_modified":1480349135171,"details":{"who":".","created":"2016-05-23T15:31:32Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1266220","name":"10.18.10.3947 winnt 5.1","why":"."},"os":"WINNT 5.1","featureStatus":"BLOCKED_DRIVER_VERSION","schema":1480349134676},{"vendor":"0x1002","blockID":"g234","enabled":true,"feature":"WEBGL_MSAA","devices":[],"id":"3310f8b8-1789-1b13-9326-5531943514ae","last_modified":1480349135145,"details":{"who":"All Firefox users.","created":"2012-11-30T12:50:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=815437","name":"Mac OS X WebGL anti-aliasing (AMD)","why":"Security problems."},"os":"Darwin 12","featureStatus":"BLOCKED_DEVICE","schema":1480349134676},{"vendor":"0x1002","blockID":"g230","enabled":true,"feature":"WEBGL_MSAA","devices":[],"id":"4769433c-51e9-a0f9-eef5-45829ac54243","last_modified":1480349135120,"details":{"who":"All Firefox users.","created":"2012-11-30T12:48:55Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=815437","name":"Mac OS X WebGL anti-aliasing (AMD)","why":"Security problems."},"os":"Darwin 10","featureStatus":"BLOCKED_DEVICE","schema":1480349134676},{"driverVersionComparator":"EQUAL","driverVersion":"10.18.10.3947","vendor":"0x8086","blockID":"g1218","enabled":true,"feature":"HARDWARE_VIDEO_DECODING","devices":[],"id":"7a3ea538-8519-2845-53bf-6a4be0ff9e6b","last_modified":1480349135096,"details":{"who":".","created":"2016-05-23T15:44:43Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1266220","name":"10.18.10.3947 winnt 6.1","why":"."},"os":"WINNT 6.1","featureStatus":"BLOCKED_DRIVER_VERSION","schema":1480349134676},{"vendor":"0x10de","blockID":"g198","enabled":true,"feature":"WEBGL_MSAA","devices":[],"id":"c9551a39-62fb-f652-8032-cbe9d2ce419c","last_modified":1480349135072,"details":{"who":"All Firefox users.","created":"2012-11-12T10:34:32Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=809550","name":"Mac OS X WebGL anti-aliasing","why":"Security problems."},"os":"Darwin 10","featureStatus":"BLOCKED_DEVICE","schema":1480349134676},{"driverVersionComparator":"LESS_THAN","driverVersion":"6.14.10.5218","vendor":"0x8086","blockID":"g511","enabled":true,"feature":"DIRECT3D_9_LAYERS","devices":[],"id":"37ffcc44-0d03-681e-69bf-89c38111fcdd","last_modified":1480349135048,"details":{"who":"All Firefox users.","created":"2013-12-18T14:29:36Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=951422","name":"Intel driver < 6.14.10.5216 for DIRECT3D_9_LAYERS on XP","why":"Stability."},"os":"WINNT 5.1","featureStatus":"BLOCKED_DRIVER_VERSION","schema":1480349134676},{"driverVersionComparator":"LESS_THAN_OR_EQUAL","driverVersion":"8.17.12.5896","vendor":"0x10de","blockID":"g36","enabled":true,"feature":"DIRECT3D_9_LAYERS","devices":["0x0a6c"],"id":"6ac4f440-9661-ee18-248f-f3b7b6eb8deb","last_modified":1480349134662,"details":{"who":"","created":"2011-03-01T12:13:42Z","bug":"","name":"","why":""},"os":"WINNT 6.1","featureStatus":"BLOCKED_DRIVER_VERSION","schema":1480343737148},{"driverVersionComparator":"EQUAL","driverVersion":"8.15.10.1855","vendor":"0x8086","blockID":"g1069","enabled":true,"devices":["0x2a42","0x2e22","0x2e12","0x2e32","0x0046"],"id":"9928c898-4941-555d-e502-54a90e9e5371","last_modified":1480349134638,"details":{"who":".","created":"2015-12-21T15:58:51Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1207993","name":"Crash in igd10umd32.dll@0x18f35","why":"."},"os":"All","featureStatus":"BLOCKED_DRIVER_VERSION","schema":1480343737148},{"driverVersionComparator":"LESS_THAN","driverVersion":"15.201.1151.0","vendor":"0x1002","blockID":"g974","enabled":true,"feature":"DIRECT2D","devices":["0x6920","0x6921","0x6928","0x6929","0x692b","0x692f","0x6930","0x6938","0x6939","0x6900","0x6901","0x6902","0x6903","0x6907","0x7300","0x9870","0x9874","0x9875","0x9876","0x9877"],"id":"ec9cf554-49de-e5ea-bbdc-54f84d290605","last_modified":1480349134615,"details":{"who":"All users who have these cards on Windows 10.","created":"2015-08-11T10:30:37Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1189266","name":"ATI cards on Windows 10","why":"Crashes on Windows 10."},"os":"WINNT 10.0","featureStatus":"BLOCKED_DRIVER_VERSION","schema":1480343737148},{"vendor":"0x1002","blockID":"g280","enabled":true,"feature":"DIRECT3D_9_LAYERS","devices":["0x9802","0x9803","0x9803","0x9804","0x9805","0x9806","0x9807"],"id":"9b7a25d9-075e-e5e9-678e-af1292db7463","last_modified":1480349134582,"details":{"who":"All Firefox user who use this driver.","created":"2013-02-13T14:52:05Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=840161","name":"AMD Radeon HD 6290/6300/6310/6320 for Direct3D 9","why":"Crashes."},"os":"WINNT 6.1","featureStatus":"BLOCKED_DEVICE","schema":1480343737148},{"driverVersionComparator":"LESS_THAN_OR_EQUAL","driverVersion":"8.15.10.2413","vendor":"0x8086","blockID":"g984","enabled":true,"feature":"DIRECT2D","devices":[],"id":"f1830d7b-c807-afda-1b97-f41474157165","last_modified":1480349134550,"details":{"who":"All users using these driver versions.","created":"2015-08-14T16:21:45Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1193802","name":"Intel graphics block","why":"Major graphics artifacts."},"os":"All","featureStatus":"BLOCKED_DRIVER_VERSION","schema":1480343737148},{"driverVersionComparator":"EQUAL","driverVersion":"8.15.10.1872","vendor":"0x8086","blockID":"g1070","enabled":true,"devices":["0x2a42","0x2e22","0x2e12","0x2e32","0x0046"],"id":"0f7b2114-976c-db1c-2d9a-02d47d1968e1","last_modified":1480349134528,"details":{"who":".","created":"2015-12-21T15:59:29Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1207993","name":"Crash in igd10umd32.dll@0x18f35","why":"."},"os":"All","featureStatus":"BLOCKED_DRIVER_VERSION","schema":1480343737148},{"driverVersionComparator":"EQUAL","driverVersion":"8.982.0.0","vendor":"0x1022","blockID":"g148","enabled":true,"feature":"DIRECT3D_9_LAYERS","devices":[],"id":"85925d60-d04e-2cbd-cdee-de70ea6be4f4","last_modified":1480349134505,"details":{"who":"All Firefox users who have these drivers installed.","created":"2012-09-25T14:31:35Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=793869","name":"ATI/AMD driver 8.982.0.0 (Direct3D)","why":"Some features in these drivers are causing frequent crashes in Firefox."},"os":"All","featureStatus":"BLOCKED_DRIVER_VERSION","schema":1480343737148},{"driverVersionComparator":"LESS_THAN_OR_EQUAL","driverVersion":"9.10.8.0","vendor":"0x1002","blockID":"g192","enabled":true,"feature":"DIRECT2D","devices":[],"id":"5e34680b-5279-4ffc-7382-b1bc661b3094","last_modified":1480349134483,"details":{"who":"All Firefox users.","created":"2012-11-02T16:33:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=806991","name":"AMD DIRECT2D on Windows 8, [0x1002]","why":"Crashes."},"os":"WINNT 6.2","featureStatus":"BLOCKED_DRIVER_VERSION","schema":1480343737148},{"driverVersionComparator":"LESS_THAN_OR_EQUAL","driverVersion":"8.17.12.5896","vendor":"0x10de","blockID":"g35","enabled":true,"feature":"DIRECT2D","devices":["0x0a6c"],"id":"00a6b9d2-285f-83f0-0a1f-ef0205a60067","last_modified":1480349134459,"details":{"who":"","created":"2011-03-01T12:13:40Z","bug":"","name":"","why":""},"os":"WINNT 6.1","featureStatus":"BLOCKED_DRIVER_VERSION","schema":1480343737148},{"driverVersionComparator":"EQUAL","driverVersion":"8.15.10.1883","vendor":"0x8086","blockID":"g1071","enabled":true,"devices":["0x2a42","0x2e22","0x2e12","0x2e32","0x0046"],"id":"d4297784-dbac-906c-16b7-1a8792e868de","last_modified":1480349134436,"details":{"who":".","created":"2015-12-21T16:00:05Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1207993","name":"Crash in igd10umd32.dll@0x18f35","why":"."},"os":"All","featureStatus":"BLOCKED_DRIVER_VERSION","schema":1480343737148},{"driverVersionComparator":"EQUAL","driverVersion":"8.982.0.0","vendor":"0x1002","blockID":"g150","enabled":true,"feature":"DIRECT3D_9_LAYERS","devices":[],"id":"6a3c05bb-f971-d3d4-2a02-184e6970ba87","last_modified":1480349134413,"details":{"who":"All Firefox users who have these drivers installed.","created":"2012-09-25T14:33:17Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=793869","name":"ATI/AMD driver 8.982.0.0 (Direct3D)","why":"Some features in these drivers are causing frequent crashes in Firefox."},"os":"All","featureStatus":"BLOCKED_DRIVER_VERSION","schema":1480343737148},{"driverVersionComparator":"EQUAL","driverVersion":"8.982.0.0","vendor":"0x1002","blockID":"g144","enabled":true,"feature":"DIRECT2D","devices":[],"id":"35e25a7c-d77d-6b43-fa5e-39b7e9c8a481","last_modified":1480349134391,"details":{"who":"All Firefox users who have these drivers installed.","created":"2012-09-24T08:23:25Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=792480","name":"ATI/AMD driver 8.982.0.0","why":"Some features in these drivers are causing frequent crashes in Firefox."},"os":"All","featureStatus":"BLOCKED_DRIVER_VERSION","schema":1480343737148},{"driverVersionComparator":"LESS_THAN","driverVersion":"6.14.10.5218","vendor":"0x8086","blockID":"g1251","enabled":true,"feature":"WEBGL_ANGLE","devices":[],"id":"ea27a4d2-ed88-0190-db12-473820b340b2","last_modified":1480349134369,"details":{"who":".","created":"2016-07-22T12:30:30Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1283601","name":"Intel driver < 6.14.10.5216 for DIRECT3D_9_LAYERS on XP","why":"."},"versionRange":{"maxVersion":"49.9"},"os":"WINNT 5.1","featureStatus":"BLOCKED_DRIVER_VERSION","schema":1480343737148},{"vendor":"0x8086","blockID":"g206","enabled":true,"feature":"WEBGL_MSAA","devices":[],"id":"91cc2cec-11dd-0f77-ffad-f57e69b3f441","last_modified":1480349134345,"details":{"who":"All Firefox users.","created":"2012-11-12T10:39:32Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=809550","name":"Mac OS X WebGL anti-aliasing","why":"Security problems"},"os":"Darwin 11","featureStatus":"BLOCKED_DEVICE","schema":1480343737148},{"driverVersionComparator":"EQUAL","driverVersion":"8.15.10.1851","vendor":"0x8086","blockID":"g1068","enabled":true,"devices":["0x2a42","0x2e22","0x2e12","0x2e32","0x0046"],"id":"b7452893-25cc-497a-626c-aacee78683c6","last_modified":1480349134323,"details":{"who":".","created":"2015-12-21T15:58:01Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1207993","name":"Crash in igd10umd32.dll@0x18f35","why":"."},"os":"All","featureStatus":"BLOCKED_DRIVER_VERSION","schema":1480343737148},{"driverVersionComparator":"EQUAL","driverVersion":"10.18.10.3947","vendor":"0x8086","blockID":"g1219","enabled":true,"feature":"HARDWARE_VIDEO_DECODING","devices":[],"id":"73e4e12d-f27a-1113-b0e9-c05cb4dd78d2","last_modified":1480349134301,"details":{"who":".","created":"2016-05-23T15:45:21Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1266220","name":"10.18.10.3947 winnt 6.2","why":"."},"os":"WINNT 6.2","featureStatus":"BLOCKED_DRIVER_VERSION","schema":1480343737148},{"driverVersionComparator":"GREATER_THAN_OR_EQUAL","driverVersion":"7.0.0.0","vendor":"0x10de","blockID":"g37","enabled":true,"feature":"DIRECT3D_9_LAYERS","devices":[],"id":"fb507393-460e-685e-91de-1ce3b18ddbc0","last_modified":1480349134278,"details":{"who":"","created":"2011-03-14T14:11:51Z","bug":"","name":"","why":""},"os":"WINNT 5.1","featureStatus":"BLOCKED_DRIVER_VERSION","schema":1480343737148},{"driverVersionComparator":"EQUAL","driverVersion":"8.982.0.0","vendor":"0x1022","blockID":"g146","enabled":true,"feature":"DIRECT2D","devices":[],"id":"e6984930-7969-3cbc-fbaa-0f350afe6f14","last_modified":1480349134255,"details":{"who":"All Firefox users who have these drivers installed.","created":"2012-09-24T08:23:33Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=792480","name":"ATI/AMD driver 8.982.0.0","why":"Some features in these drivers are causing frequent crashes in Firefox."},"os":"All","featureStatus":"BLOCKED_DRIVER_VERSION","schema":1480343737148},{"driverVersionComparator":"LESS_THAN","driverVersion":"15.201.1151.0","vendor":"0x1002","blockID":"g992","enabled":true,"feature":"DIRECT2D","devices":["0x6920","0x6921","0x6928","0x6929","0x692b","0x692f","0x6930","0x6938","0x6939","0x6900","0x6901","0x6902","0x6903","0x6907","0x7300","0x9870","0x9874","0x9875","0x9876","0x9877"],"id":"77b27d80-1ebe-04de-2db9-bb197acbac32","last_modified":1480349134232,"details":{"who":"Users who have these cards installed.","created":"2015-08-20T09:56:09Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1189266","name":"ATI cards on Windows 10","why":"Crashing."},"os":"WINNT 8.1","featureStatus":"BLOCKED_DRIVER_VERSION","schema":1480343737148},{"vendor":"0x1002","blockID":"g232","enabled":true,"feature":"WEBGL_MSAA","devices":[],"id":"8f8e9025-a9ec-5f1e-ae9f-aee28176bdf7","last_modified":1480349134210,"details":{"who":"All Firefox users.","created":"2012-11-30T12:49:56Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=809550","name":"Mac OS X WebGL anti-aliasing (AMD)","why":"Security problems."},"os":"Darwin 11","featureStatus":"BLOCKED_DEVICE","schema":1480343737148},{"driverVersionComparator":"EQUAL","driverVersion":"10.18.10.3947","vendor":"0x8086","blockID":"g1220","enabled":true,"feature":"HARDWARE_VIDEO_DECODING","devices":[],"id":"1f91fdd6-8b89-d948-d05a-86491c705ce2","last_modified":1480349134187,"details":{"who":".","created":"2016-05-23T15:46:34Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1266220","name":"10.18.10.3947 winnt 6.3","why":"."},"os":"WINNT 6.3","featureStatus":"BLOCKED_DRIVER_VERSION","schema":1480343737148},{"vendor":"0x8086","blockID":"g204","enabled":true,"feature":"WEBGL_MSAA","devices":[],"id":"33866148-1d41-2d4c-27b8-5f147467686b","last_modified":1480349134160,"details":{"who":"All Firefox users.","created":"2012-11-12T10:38:32Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=809550","name":"Mac OS X WebGL anti-aliasing","why":"Security problems."},"os":"Darwin 10","featureStatus":"BLOCKED_DEVICE","schema":1480343737148},{"vendor":"0x1002","blockID":"g278","enabled":true,"feature":"DIRECT2D","devices":["0x9802","0x9803","0x9803","0x9804","0x9805","0x9806","0x9807"],"id":"bccdbab1-c335-6f2e-6d0a-d563ccb2f1f4","last_modified":1480349134138,"details":{"who":"All Firefox users using these drivers.","created":"2013-02-13T14:50:33Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=840161","name":"AMD Radeon HD 6290/6300/6310/6320 for Direct2D","why":"Crashes"},"os":"WINNT 6.1","featureStatus":"BLOCKED_DEVICE","schema":1480343737148},{"driverVersionComparator":"EQUAL","driverVersion":"8.15.10.1892","vendor":"0x8086","blockID":"g1072","enabled":true,"devices":["0x2a42","0x2e22","0x2e12","0x2e32","0x0046"],"id":"d780a857-b80d-0049-981e-1a8d3ebe485e","last_modified":1480349134115,"details":{"who":".","created":"2015-12-21T16:00:50Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1207993","name":"Crash in igd10umd32.dll@0x18f35","why":"."},"os":"All","featureStatus":"BLOCKED_DRIVER_VERSION","schema":1480343737148},{"driverVersionComparator":"LESS_THAN_OR_EQUAL","driverVersion":"9.10.8.0","vendor":"0x1022","blockID":"g194","enabled":true,"feature":"DIRECT2D","devices":[],"id":"0afc5fe9-1f81-7fde-2424-0cb4d933c173","last_modified":1480349134090,"details":{"who":"All Firefox users.","created":"2012-11-02T16:35:37Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=806991","name":"AMD DIRECT2D on Windows 8, [0x1022]","why":"Crashes."},"os":"WINNT 6.2","featureStatus":"BLOCKED_DRIVER_VERSION","schema":1480343737148}]} \ No newline at end of file diff --git a/services/blocklists/moz.build b/services/blocklists/moz.build new file mode 100644 index 000000000000..9fdcba5b2ecf --- /dev/null +++ b/services/blocklists/moz.build @@ -0,0 +1,15 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +FINAL_TARGET_FILES.defaults.blocklists += ['addons.json', + 'certificates.json', + 'gfx.json', + 'plugins.json'] + +FINAL_TARGET_FILES.defaults.pinning += ['pins.json'] + +if CONFIG['MOZ_BUILD_APP'] == 'browser': + DIST_SUBDIR = 'browser' diff --git a/services/blocklists/pins.json b/services/blocklists/pins.json new file mode 100644 index 000000000000..ccb562190823 --- /dev/null +++ b/services/blocklists/pins.json @@ -0,0 +1 @@ +{"data":[]} \ No newline at end of file diff --git a/services/blocklists/plugins.json b/services/blocklists/plugins.json new file mode 100644 index 000000000000..9f634908ca12 --- /dev/null +++ b/services/blocklists/plugins.json @@ -0,0 +1 @@ +{"data":[{"infoURL":"https://get.adobe.com/flashplayer/","matchName":"","blockID":"p1419","enabled":true,"matchFilename":"libflashplayer\\.so","last_modified":1486576001966,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-11-16T18:40:26Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1316179","name":"Flash Player Plugin on Linux 11.2.202.637 to 11.2.202.643 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on Adobe's Flash page."},"versionRange":[{"targetApplication":[],"minVersion":"11.2.202.637","maxVersion":"11.2.202.643","severity":0,"vulnerabilityStatus":1}],"matchDescription":"","os":"Linux","id":"32d5edbf-0547-fa2d-8cc2-138676a17bc0","schema":1486575789918},{"infoURL":"https://get.adobe.com/flashplayer/","matchName":"","blockID":"p1420","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1486575979474,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-11-16T18:42:06Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1316179","name":"Flash Player Plugin 23.0.0.185 to 23.0.0.205 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on Adobe's Flash page."},"versionRange":[{"targetApplication":[],"minVersion":"23.0.0.185","maxVersion":"23.0.0.205","severity":0,"vulnerabilityStatus":1}],"matchDescription":"","os":"","id":"24ac1e2b-8e0a-a084-5123-cb87d4ceb898","schema":1486575789918},{"infoURL":"https://get.adobe.com/flashplayer/","matchName":"","blockID":"p1274","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1486575908463,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-09-23T15:32:00Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1286380","name":"Flash Player Plugin 22.0.0.192 to 22.0.0.211 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on Adobe's Flash page."},"versionRange":[{"targetApplication":[],"minVersion":"22.0.0.192","maxVersion":"22.0.0.211","severity":0,"vulnerabilityStatus":1}],"matchDescription":"","os":"","id":"6ef87143-6593-e234-a77c-6af69ad1567b","schema":1486575789918},{"infoURL":"https://get.adobe.com/flashplayer/","matchName":"","blockID":"p160","enabled":true,"matchFilename":"NPSWF32\\.dll","last_modified":1486575890885,"details":{"who":"All Firefox users who have this plugin installed.","created":"2012-10-05T12:34:22Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=797378","name":"Adobe Flash 10.2.* and lower","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on Adobe's Flash page."},"versionRange":[{"targetApplication":[{"minVersion":"4.0","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"16.*"}],"minVersion":"0","maxVersion":"10.2.9999","severity":0,"vulnerabilityStatus":1}],"matchDescription":"","os":"","id":"a61c906e-fe1f-b569-1807-96ffa59b2b6c","schema":1486575789918},{"infoURL":"https://get.adobe.com/flashplayer/","matchName":"","blockID":"p1422","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1486575869178,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-12-20T17:54:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1323300","name":"Flash Player Plugin 23.0.0.205 to 23.0.0.207 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on Adobe's Flash page."},"versionRange":[{"targetApplication":[],"minVersion":"23.0.0.205","maxVersion":"23.0.0.207","severity":0,"vulnerabilityStatus":1}],"matchDescription":"","os":"","id":"ee3019e9-2572-ecb2-3de3-abc4842d7e0a","schema":1486575789918},{"infoURL":"https://get.adobe.com/flashplayer/","matchName":"","blockID":"p1421","enabled":true,"matchFilename":"libflashplayer\\.so","last_modified":1486575857101,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-12-20T17:52:30Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1323300","name":"Flash Player Plugin on Linux 11.2.202.643 to 23.0.0.207 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on Adobe's Flash page."},"versionRange":[{"targetApplication":[],"minVersion":"11.2.202.643","maxVersion":"23.0.0.207","severity":0,"vulnerabilityStatus":1}],"matchDescription":"","os":"Linux","id":"c867bfd8-ec29-0800-8689-4b90b89fa870","schema":1486575789918},{"infoURL":"https://get.adobe.com/flashplayer/","matchName":"","blockID":"p1494","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1486575835268,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2017-01-17T20:58:38Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1330086","name":"Flash Player Plugin 23.0.0.207 to 24.0.0.186 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on Adobe's Flash page."},"versionRange":[{"targetApplication":[],"minVersion":"23.0.0.207","maxVersion":"24.0.0.186","severity":0,"vulnerabilityStatus":1}],"matchDescription":"","os":"","id":"9234afc8-8f7f-602a-9c84-7d7f2685802a","schema":1486575789918},{"infoURL":"https://get.adobe.com/flashplayer/","matchName":"","blockID":"p1495","enabled":true,"matchFilename":"libflashplayer\\.so","last_modified":1486575789909,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2017-01-17T20:59:52Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1330086","name":"Flash Player Plugin on Linux 23.0.0.207 to 24.0.0.186 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on Adobe's Flash page."},"versionRange":[{"targetApplication":[],"minVersion":"23.0.0.207","maxVersion":"24.0.0.186","severity":0,"vulnerabilityStatus":1}],"matchDescription":"","os":"Linux","id":"22b0fa08-8712-69cd-4ba4-9fb5ab9398d1","schema":1485795310261},{"blockID":"p152","enabled":true,"matchFilename":"npctrl\\.dll","last_modified":1480349149757,"details":{"who":"All Firefox users who have this plugin installed.","created":"2012-10-05T10:34:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=797378","name":"Silverlight 4.1.10328.0 and lower","why":"This plugin is outdated and is potentially insecure. Affected users should go to the plugin check page and update to the latest version."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"4.1.10328.0","severity":0,"vulnerabilityStatus":1}],"id":"abdcbe90-5575-6b4b-12de-bbabd93ecf57","schema":1480349144394},{"infoURL":"https://java.com/","blockID":"p904","enabled":true,"matchFilename":"JavaAppletPlugin\\.plugin","last_modified":1480349149710,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2015-05-19T09:01:42Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1159917","name":"Java Plugin 8 update 44 and lower (click-to-play), Mac OS X","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"Java 8","maxVersion":"Java 8 Update 44","severity":0,"vulnerabilityStatus":1}],"id":"47f6217d-0aa6-1e39-a9c9-cc64d57bb91f","schema":1480349144394},{"infoURL":"https://java.com/","matchName":"Java\\(TM\\) Platform SE 7 U(8[1-9]|90)(\\s[^\\d\\._U]|$)","blockID":"p1061","enabled":true,"matchFilename":"npjp2\\.dll","last_modified":1480349149684,"details":{"who":"All users who have these versions of the Java plugin installed.","created":"2015-12-02T12:39:41Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1217932","name":"Java Plugin 7 update 81 to 90 (click-to-play), Windows","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[],"severity":0,"vulnerabilityStatus":1}],"id":"69196ada-69bd-6454-eea8-6f8b2037368c","schema":1480349144394},{"infoURL":"https://www.microsoft.com/getsilverlight","blockID":"p1120","enabled":true,"matchFilename":"(Silverlight\\.plugin|npctrl\\.dll)","last_modified":1480349149661,"details":{"who":"All users who have these versions of the Silverlight plugin installed.","created":"2016-02-03T09:42:43Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1241237","name":"Silverlight plugin 5.1.41105.0 and lower (click to play)","why":"Old versions of the Silverlight plugin are known to have critical security vulnerabilities. You can get the latest version of Silverlight here."},"versionRange":[{"targetApplication":[],"minVersion":"5.1.20125","maxVersion":"5.1.41105.0","severity":0,"vulnerabilityStatus":1}],"id":"f0bfeb8c-04ee-d5ef-6670-b28c0e0d0f58","schema":1480349144394},{"blockID":"p102","enabled":true,"matchFilename":"npmozax\\.dll","last_modified":1480349149636,"details":{"who":"All Firefox users who have this plugin installed.","created":"2012-06-07T17:43:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=695927","name":"Mozilla ActiveX Plug-in","why":"This plugin was discontinued years ago and only worked up to Firefox version 1.5. Because plugins aren't marked as incompatible, there are still many users who have it installed and have recently been experiencing crashes related to it."},"versionRange":[{"minVersion":"0","maxVersion":"*","targetApplication":[]}],"id":"2e001e2f-483b-7595-8810-3672e0346950","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1020","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349149604,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2015-09-25T14:51:38Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1193001","name":"Flash Player Plugin 13.* (click-to-play)","why":"The 13.* branch of the Flash Player plugin has been discontinued by Adobe and has known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"13.0","maxVersion":"13.*","severity":0,"vulnerabilityStatus":1}],"id":"2c53180f-e759-b36e-0c58-acee77a8087a","schema":1480349144394},{"blockID":"p252","enabled":true,"matchFilename":"AdobePDFViewerNPAPI\\.plugin","last_modified":1480349149567,"details":{"who":"All Firefox users on Mac OS X who have installed the Adobe Reader XI plugin. Users are recommended to update when a new version of Adobe Reader becomes available, or to downgrade to the latest version of Adobe Reader 10.","created":"2013-01-15T10:56:30Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=826002","name":"Adobe Reader XI for Mac OS X","why":"The Adobe Reader XI plugin is causing frequent crashes on Firefox for Mac OS X. The impact and this block are currently limited to versions 11.0.0 and 11.0.01."},"versionRange":[{"targetApplication":[],"minVersion":"11.0.0","maxVersion":"11.0.01","severity":1}],"os":"Darwin","id":"821ddb3d-bba4-6479-28b6-9974383fa8c9","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1122","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349149544,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-02-17T16:26:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1247032","name":"Flash Player Plugin 18.0.0.268 to 18.0.0.326 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"18.0.0.268","maxVersion":"18.0.0.326","severity":0,"vulnerabilityStatus":1}],"id":"1c48b368-b291-62ef-c4b1-057cb63d54d8","schema":1480349144394},{"matchName":"Java\\(TM\\) Platform SE 6 U(39|40|41)(\\s[^\\d\\._U]|$)","blockID":"p300","enabled":true,"matchFilename":"npjp2\\.dll","last_modified":1480349149520,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2013-02-25T12:36:25Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=843373","name":"Java Plugin 6 updates 39 to 41 (click-to-play), Windows","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[{"minVersion":"17.0","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"},{"minVersion":"2.14","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"}],"severity":0,"vulnerabilityStatus":1}],"id":"d64e08b6-66b2-f534-53d8-1cbcbb139f2a","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p826","enabled":true,"matchFilename":"libflashplayer\\.so","last_modified":1480349149496,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2015-01-28T14:36:37Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1124654","name":"Flash Player Plugin on Linux 11.2.202.425 to 11.2.202.439 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"11.2.202.425","maxVersion":"11.2.202.439","severity":0,"vulnerabilityStatus":1}],"os":"Linux","id":"6738a409-5904-1031-56d4-6ce1b4eaccde","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p94","enabled":true,"matchFilename":"Flash\\ Player\\.plugin","last_modified":1480349149472,"details":{"who":"All Firefox users who have a version of the Flash Player Plugin older than 10.2.159.1.","created":"2012-05-23T09:15:23Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=754723","name":"Flash Player Plugin","why":"Old versions of the Flash Player plugin are targeted by known security vulnerabilities, and cause frequent Firefox crashes. We strongly recommend all users to visit the Flash Player homepage to download and install the latest available version of this plugin.\r\n\r\nThis is not an ordinary block. It's just an upgrade notification that will be shown to all users who have these old versions installed, asking them to download the latest version. If they choose to ignore the notification, the plugin will continue to work normally."},"versionRange":[{"targetApplication":[{"minVersion":"0.1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"17.0.1"},{"minVersion":"0","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"2.13.*"}],"minVersion":"0","maxVersion":"10.2.159.1","severity":0}],"id":"2a741cac-32d7-a67e-0bf7-b5b53a0ff22b","schema":1480349144394},{"blockID":"p32","enabled":true,"matchFilename":"npViewpoint.dll","last_modified":1480349149141,"details":{"who":"All users of the Viewpoint plugin for Firefox 3 and later.","created":"2011-03-31T16:28:26Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=539282","name":"Viewpoint","why":"This plugin causes a high volume of Firefox crashes."},"versionRange":[{"targetApplication":[{"minVersion":"3.0","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"}]}],"id":"1206e79a-4817-16e9-0f5e-7762a8d19216","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1066","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349149112,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2015-12-21T13:43:47Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1231191","name":"Flash Player Plugin 18.0.0.255 to 18.0.0.261 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"18.0.0.255","maxVersion":"18.0.0.261","severity":0,"vulnerabilityStatus":1}],"id":"f05bf2c1-7b19-c7bc-5a67-7976f29311d6","schema":1480349144394},{"infoURL":"https://java.com/","blockID":"p180","enabled":true,"matchFilename":"JavaAppletPlugin\\.plugin","last_modified":1480349149087,"details":{"who":"All users who have these versions of the plugin installed in Firefox 17 and above.","created":"2012-10-30T14:29:51Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=829111","name":"Java Plugin 7 update 10 and lower (click-to-play), Mac OS X","why":"The Java plugin is causing significant security problems. All users are strongly recommended to keep the plugin disabled unless necessary."},"versionRange":[{"targetApplication":[{"minVersion":"17.0","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"},{"minVersion":"2.14","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"}],"minVersion":"Java 7 Update 0","maxVersion":"Java 7 Update 10","severity":0,"vulnerabilityStatus":1}],"id":"12f38c07-c1e1-2464-2eab-d454cf471eab","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p830","enabled":true,"matchFilename":"libflashplayer\\.so","last_modified":1480349149064,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2015-02-05T15:38:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1128534","name":"Flash Player Plugin on Linux 11.2.202.439 to 11.2.202.441 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"11.2.202.439","maxVersion":"11.2.202.441","severity":0,"vulnerabilityStatus":1}],"os":"Linux","id":"17a664fb-d871-84e0-7418-dab7ecbd5f4b","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p828","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349149041,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2015-01-28T14:39:04Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1124654","name":"Flash Player Plugin 15.0.0.243 to 16.0.0.287 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"15.0.0.243","maxVersion":"16.0.0.287","severity":0,"vulnerabilityStatus":1}],"id":"e84ceee7-9202-1321-eb49-c068806128a3","schema":1480349144394},{"matchDescription":"^($|Unity Web Player version 5.0(\\.([0-2]|3f1))?[^0-9.])","blockID":"p1004","enabled":true,"matchFilename":"Unity Web Player\\.plugin","last_modified":1480349149017,"details":{"who":"All users who have these versions of the plugin installed","created":"2015-09-09T14:11:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=974012","name":"Unity Web Player 5.0 to 5.0.3f1 (click-to-play), Mac OS","why":"These versions of the Unity Web Player plugin have known vulnerabilities that can put users at risk."},"versionRange":[{"targetApplication":[],"severity":0,"vulnerabilityStatus":1}],"id":"5a0b69cb-a516-e7a2-ea3b-b4fafcc13c6b","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1415","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349148994,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-10-28T21:47:44Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1313435","name":"Flash Player Plugin 18.0.0.366 to 18.0.0.382 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"18.0.0.366","maxVersion":"18.0.0.382","severity":0,"vulnerabilityStatus":1}],"id":"36a133ef-3465-d7e4-6394-7b57e5f82dd8","schema":1480349144394},{"blockID":"p34","enabled":true,"matchFilename":"[Nn][Pp][Jj][Pp][Ii]1[56]0_[0-9]+\\.[Dd][Ll][Ll]","last_modified":1480349148971,"details":{"who":"Users of Java 2 Plugin versions 1.5_00 to 1.6_99 in Firefox 3.6 and later.","created":"2011-02-17T17:20:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=634639","name":"Java Plugin","why":"These versions of the Java plugin are no longer supported by Oracle and cause a high volume of Firefox crashes."},"versionRange":[{"targetApplication":[{"minVersion":"3.6a1pre","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"}]}],"id":"91618232-c650-5dc6-00fe-293c0baedc34","schema":1480349144394},{"blockID":"p248","enabled":true,"matchFilename":"Scorch\\.plugin","last_modified":1480349148945,"details":{"who":"All users who have Firefox 18 or above installed, and the Sibelius Scorch plugin.","created":"2013-01-14T09:26:47Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=829054","name":"Sibelius Scorch plugin","why":"The Sibelius Scorch plugin is not compatible with Firefox 18 and above, and is crashing whenever loaded on affected versions of Firefox. "},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"6.2.0b88","severity":1}],"id":"28b5baa1-6490-38e2-395f-53fc84aa12df","schema":1480349144394},{"blockID":"p254","enabled":true,"matchFilename":"PDF Browser Plugin\\.plugin","last_modified":1480349148920,"details":{"who":"All Firefox users on Mac OS X who are using the affected versions of the PDF Browser Plugin.","created":"2013-01-15T11:54:24Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=830410","name":"PDF Browser Plugin 2.4.2 and below","why":"The PDF Browser Plugin is causing frequent crashes on Firefox 18 and above. All users are recommended to keep the plugin disabled and update it if a new version becomes available."},"versionRange":[{"targetApplication":[{"minVersion":"18.0a1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"}],"minVersion":"0","maxVersion":"2.4.2","severity":1}],"id":"2dd1b53a-52db-2d0f-392a-410d5aade9d6","schema":1480349144394},{"infoURL":"https://get.adobe.com/shockwave/","blockID":"p1055","enabled":true,"matchFilename":"DirectorShockwave\\.plugin","last_modified":1480349148897,"details":{"who":"All users who have these versions of this plugin installed.","created":"2015-11-13T14:17:24Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1218880","name":"Shockwave for Director 12.2.0.162 and earlier, Mac OS X (click-to-play)","why":"Versions 12.2.0.162 and earlier of this plugin are affected by a critical security vulnerability that puts users at risk."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"12.2.0.162","severity":0,"vulnerabilityStatus":1}],"id":"da3808c0-b460-e177-1c78-0496b3671480","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p928","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349148874,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2015-06-30T14:09:48Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1177214","name":"Flash Player Plugin 13.0.0.269 to 13.0.0.295 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"13.0.0.269","maxVersion":"13.0.0.295","severity":0,"vulnerabilityStatus":1}],"id":"9ea82484-43fe-f039-bc0a-b254ca502357","schema":1480349144394},{"infoURL":"https://support.apple.com/en-us/HT205771","blockID":"p1151","enabled":true,"matchFilename":"npqtplugin\\.dll","last_modified":1480349148852,"details":{"who":"All users who have the QuickTime Plugin for Windows installed.","created":"2016-04-18T17:41:00Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1264874","name":"QuickTime Plugin for Windows","why":"The QuickTime Plugin for Windows has been discontinued by Apple and has known critical security vulnerabilities. All users are strongly encouraged to remove it or keep it disabled."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"*","severity":0,"vulnerabilityStatus":2}],"id":"bb8db302-9579-42d2-ff75-c61500f6a020","schema":1480349144394},{"blockID":"p28","enabled":true,"matchFilename":"NPFFAddOn.dll","last_modified":1480349148829,"details":{"who":"All users of Internet Saving Optimizer for all Mozilla applications.","created":"2011-03-31T16:28:26Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=512406","name":"Internet Saving Optimizer (plugin)","why":"This plugin causes a high volume of Firefox crashes and is considered malware."},"versionRange":[{"targetApplication":[],"maxVersion":"*"}],"id":"c85a4a9c-d61c-130f-d525-ea36becac235","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1048","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349148806,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2015-10-21T14:13:42Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1214459","name":"Flash Player Plugin 19.0 to 19.0.0.225 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"19.0","maxVersion":"19.0.0.225","severity":0,"vulnerabilityStatus":1}],"id":"d57e46e8-2fca-f631-db45-99c5808ed4c0","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p832","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349148782,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2015-02-05T15:41:17Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1128534","name":"Flash Player Plugin 16.0.0.295 to 16.0.0.304 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"16.0.0.295","maxVersion":"16.0.0.304","severity":0,"vulnerabilityStatus":1}],"id":"6105ecd0-5999-3754-8edb-6a00cef9d130","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1046","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349148759,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2015-10-21T14:12:49Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1214459","name":"Flash Player Plugin 18.0.0.233 to 18.0.0.254 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"18.0.0.233","maxVersion":"18.0.0.254","severity":0,"vulnerabilityStatus":1}],"id":"e5ec5094-7dfc-4dc8-1e6a-93a3f94b32f8","schema":1480349144394},{"matchName":"Java\\(TM\\) Platform SE 7 U(1[6-9]|2[0-4])(\\s[^\\d\\._U]|$)","blockID":"p420","enabled":true,"matchFilename":"npjp2\\.dll","last_modified":1480349148736,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2013-06-28T12:47:32Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=885362","name":"Java Plugin 7 update 16 to 24 (click-to-play), Windows","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[{"minVersion":"17.0","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"},{"minVersion":"2.14","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"}],"severity":0,"vulnerabilityStatus":1}],"id":"5942b7ae-bcdc-e329-9f17-f7a795c9ec83","schema":1480349144394},{"matchName":"Java\\(TM\\) Platform SE 7 U(2[5-9]|3\\d|4[0-4])(\\s[^\\d\\._U]|$)","blockID":"p458","enabled":true,"matchFilename":"npjp2\\.dll","last_modified":1480349148711,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2013-10-16T16:29:18Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=927273","name":"Java Plugin 7 update 25 to 44 (click-to-play), Windows","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[{"minVersion":"17.0","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"},{"minVersion":"2.14","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"}],"severity":0,"vulnerabilityStatus":1}],"id":"d199d513-3c49-b53c-9447-33c8021c0df2","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1252","enabled":true,"matchFilename":"libflashplayer\\.so","last_modified":1480349148687,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-07-25T13:22:01Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1286380","name":"Flash Player Plugin on Linux 11.2.202.621 to 11.2.202.626 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"11.2.202.621","maxVersion":"11.2.202.626","severity":0,"vulnerabilityStatus":1}],"os":"Linux","id":"7a8fdd50-4059-556f-5c6c-cb486d9239ba","schema":1480349144394},{"infoURL":"https://get.adobe.com/shockwave/","blockID":"p1054","enabled":true,"matchFilename":"np32dsw_[0-9]+\\.dll","last_modified":1480349148638,"details":{"who":"All users who have these versions of this plugin installed.","created":"2015-11-13T14:15:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1218880","name":"Shockwave for Director 12.2.0.162 and earlier, Windows (click-to-play)","why":"Versions 12.2.0.162 and earlier of this plugin are affected by a critical security vulnerability that puts users at risk."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"12.2.0.162","severity":0,"vulnerabilityStatus":1}],"id":"5cc4739b-ba83-7a19-4d85-c5362f5e0ccd","schema":1480349144394},{"blockID":"p298","enabled":true,"matchFilename":"JavaAppletPlugin\\.plugin","last_modified":1480349148613,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2013-02-25T12:35:34Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=843373","name":"Java Plugin 6 updates 39 to 41 (click-to-play), Mac OS X","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page.\r\n"},"versionRange":[{"targetApplication":[{"minVersion":"17.0","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"},{"minVersion":"2.14","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"}],"minVersion":"Java 6 Update 39","maxVersion":"Java 6 Update 41","severity":0,"vulnerabilityStatus":1}],"id":"cfd76877-e79d-8e8c-c6a7-6b596fd344e8","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1074","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349148566,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-01-07T12:52:22Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1235435","name":"Flash Player Plugin 19.0.0.246 to 20.0.0.235 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"19.0.0.246","maxVersion":"20.0.0.235","severity":0,"vulnerabilityStatus":1}],"id":"f47e2396-5eac-9458-dad1-2e8e91ccf0b5","schema":1480349144394},{"blockID":"p456","enabled":true,"matchFilename":"npvlc\\.dll","last_modified":1480349148527,"details":{"who":"All Firefox users who are using old versions of the VLC player plugin.","created":"2013-09-30T14:35:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=470936","name":"VLC Player plugin 2.0.5 and lower (click-to-play)","why":"Old versions of the VLC player are known to cause stability problems in Firefox. All users are recommended to update to the latest version of their VLC software."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"2.0.5","severity":0,"vulnerabilityStatus":1}],"id":"0cfaaefe-88a4-dda4-96bc-110e402ca9d5","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1149","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349148205,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-04-13T14:26:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1263476","name":"Flash Player Plugin 18.0.0.329 to 18.0.0.333 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"18.0.0.329","maxVersion":"18.0.0.333","severity":0,"vulnerabilityStatus":1}],"id":"7c1cefd7-67ac-9ab5-90e9-1eb8d4b4275a","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1224","enabled":true,"matchFilename":"libflashplayer\\.so","last_modified":1480349148157,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-05-31T15:18:16Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1275307","name":"Flash Player Plugin on Linux 11.2.202.577 to 11.2.202.616 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"11.2.202.577","maxVersion":"11.2.202.616","severity":0,"vulnerabilityStatus":1}],"os":"Linux","id":"fa1aab48-6b35-8e43-61ff-2902eeff4e86","schema":1480349144394},{"infoURL":"https://java.com/","matchName":"Java\\(TM\\) Platform SE 8 U(6[4-9]|7[0-6])(\\s[^\\d\\._U]|$)","blockID":"p1144","enabled":true,"matchFilename":"npjp2\\.dll","last_modified":1480349148133,"details":{"who":"All users who have these versions of the Java plugin installed.","created":"2016-03-31T16:18:15Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1259458","name":"Java Plugin 8 update 64 to 76 (click-to-play), Windows","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[],"severity":0,"vulnerabilityStatus":1}],"id":"b3c55844-79d2-66dd-0d44-82fb4533307e","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1140","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349148109,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-03-18T15:35:14Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1255519","name":"Flash Player Plugin 20.0.0.286 to 20.0.0.306 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"20.0.0.286","maxVersion":"20.0.0.306","severity":0,"vulnerabilityStatus":1}],"id":"17697ff4-a8d9-db56-240f-704921c23b4b","schema":1480349144394},{"matchName":"Java\\(TM\\) Plug-in 1\\.7\\.0_1[2-5]([^\\d\\._]|$)","blockID":"p296","enabled":true,"matchFilename":"libnpjp2\\.so","last_modified":1480349148080,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2013-02-25T12:34:37Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=843373","name":"Java Plugin 7 update 12 to 15 (click-to-play), Linux","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[{"minVersion":"17.0","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"},{"minVersion":"2.14","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"}],"severity":0,"vulnerabilityStatus":1}],"id":"5b7aaf34-48a3-dfa5-1db8-550faef41501","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p178","enabled":true,"matchFilename":"(NPSWF[0-9_]*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349148055,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2012-10-30T14:24:14Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=885517","name":"Flash Player Plugin between 11.0 and 11.7.700.169 (click-to-play)","why":"Old versions of the Flash Player plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[{"minVersion":"19.0a1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"},{"minVersion":"2.16a1","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"},{"minVersion":"17.0.4","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"17.0.*"}],"minVersion":"11.0","maxVersion":"11.7.700.169","severity":0,"vulnerabilityStatus":1}],"id":"e4c7ad3c-6b35-2eb7-0c19-35be376c71dc","schema":1480349144394},{"blockID":"p408","enabled":true,"matchFilename":"QuickTime Plugin\\.plugin","last_modified":1480349148032,"details":{"who":"All Firefox users who have affected versions of the QuickTime plugin installed.","created":"2013-06-28T09:52:37Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=837377","name":"QuickTime Plugin 7.6.5 and lower (click-to-play), Mac OS X","why":"Old versions of the QuickTime plugin are known to be insecure and cause stability problems. All users are recommended to update to the latest version available. You can check for updates in the plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"7.6.5","severity":0,"vulnerabilityStatus":1}],"id":"4f39cd0f-976c-1f71-2d9c-2abe1b4706d9","schema":1480349144394},{"infoURL":"https://java.com/","blockID":"p1059","enabled":true,"matchFilename":"JavaAppletPlugin\\.plugin","last_modified":1480349148009,"details":{"who":"All users who have these versions of the Java plugin installed.","created":"2015-12-02T12:37:58Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1217932","name":"Java Plugin 7 update 81 to 90 (click-to-play), Mac OS X","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"Java 7 Update 81","maxVersion":"Java 7 Update 90","severity":0,"vulnerabilityStatus":1}],"id":"799c4f10-d75d-30a0-5570-56df6be628e0","schema":1480349144394},{"matchDescription":"^($|Unity Web Player version ([0-3]|(4\\.([0-5]|6(\\.([0-5]|6f1)))?[^0-9.])))","blockID":"p558","enabled":true,"matchFilename":"Unity Web Player\\.plugin","last_modified":1480349147963,"details":{"who":"All Firefox users who have these versions of the plugin installed.","created":"2014-02-25T08:29:51Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=974012","name":"Unity Web Player 4.6.6f1 and lower (click-to-play), Mac OS","why":"Current versions of the Unity Web Player plugin have known vulnerabilities that can put users at risk."},"versionRange":[{"targetApplication":[],"severity":0,"vulnerabilityStatus":1}],"id":"bbf83e70-65f5-75af-b841-7cebcf3e38c1","schema":1480349144394},{"infoURL":"https://java.com/","matchName":"Java(\\(TM\\))? Plug-in 10\\.(9[1-7])(\\.[0-9]+)?([^\\d\\._]|$)","blockID":"p1145","enabled":true,"matchFilename":"libnpjp2\\.so","last_modified":1480349147940,"details":{"who":"All users who have these versions of the Java plugin installed.","created":"2016-03-31T16:18:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1259458","name":"Java Plugin 7 update 91 to 97 (click-to-play), Linux","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[],"severity":0,"vulnerabilityStatus":1}],"id":"d4e75c8c-9c32-6093-12cc-1de0fd8f9e87","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1234","enabled":true,"matchFilename":"libflashplayer\\.so","last_modified":1480349147915,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-06-23T12:52:14Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1280125","name":"Flash Player Plugin on Linux 11.2.202.616 to 11.2.202.621 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"11.2.202.616","maxVersion":"11.2.202.621","severity":0,"vulnerabilityStatus":1}],"os":"Linux","id":"a02005bf-ad55-ba8f-265a-532e874142d0","schema":1480349144394},{"matchName":"[0-6]\\.0\\.[01]\\d{2}\\.\\d+","blockID":"p33","enabled":true,"matchFilename":"npdeploytk.dll","last_modified":1480349147892,"details":{"who":"Users of Java Deployment Toolkit versions 6.0.200.0 and older in all versions of Firefox.","created":"2010-04-16T17:52:32Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=558584","name":"Java Deployment Toolkit","why":"This plugin has publicly-known security vulnerabilities. For more information, please visit the vendor page."},"versionRange":[{"targetApplication":[],"maxVersion":"","severity":1}],"id":"b12b4282-d327-06d6-6e62-4788ba2c4b2f","schema":1480349144394},{"infoURL":"https://java.com/","blockID":"p1060","enabled":true,"matchFilename":"JavaAppletPlugin\\.plugin","last_modified":1480349147868,"details":{"who":"All users who have these versions of the Java plugin installed.","created":"2015-12-02T12:38:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1217932","name":"Java Plugin 8 update 46 to 64 (click-to-play), Mac OS X","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"Java 8 Update 46","maxVersion":"Java 8 Update 64","severity":0,"vulnerabilityStatus":1}],"id":"aee0ad26-018f-392b-91f7-6a8aaf332774","schema":1480349144394},{"blockID":"p89","enabled":true,"matchFilename":"AdobePDFViewerNPAPI\\.plugin","last_modified":1480349147844,"details":{"who":"Firefox users on Mac OS X who have installed the Adobe Acrobat plugin.","created":"2012-05-04T11:29:46Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=750387","name":"Adobe Acrobat NPAPI Plug-in","why":"The Adobe Acrobat plugin doesn't work on Mac OS X in default (64-bit) mode, showing a blank page when users click on links to PDF files in Firefox. It also causes a significant number of crashes in 32-bit mode.\r\n\r\nThere's more information on this blog post."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"10.1.3","severity":1}],"os":"Darwin","id":"473f4d9c-e38e-a348-26d1-de7b842893d9","schema":1480349144394},{"matchName":"Java\\(TM\\) Plug-in 1\\.7\\.0(_0?([5-6]))?([^\\d\\._]|$)","blockID":"p132","enabled":true,"matchFilename":"libnpjp2\\.so","last_modified":1480349147820,"details":{"who":"All Firefox users who have the Java 7 plugin, updates 6 and below.","created":"2012-08-31T15:21:34Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=794247","name":"Java Plugin","why":"The Java 7 Runtime Environment, update versions 6 and below, has a serious security vulnerability that is fixed in the latest update. All Firefox users are strongly encouraged to update as soon as possible. This can be done on the Plugin Check page."},"versionRange":[{"targetApplication":[{"minVersion":"0.1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"17.*"},{"minVersion":"0.1","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"2.14.*"}],"severity":1}],"id":"572d0485-3388-7c2a-a062-b062e42c8710","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","matchDescription":"^Shockwave Flash (([1-9]\\.[0-9]+)|(10\\.([0-2]|(3 r(([0-9][0-9]?)|1(([0-7][0-9])|8[0-2]))))))( |$)","blockID":"p330","enabled":true,"matchFilename":"libflashplayer\\.so","last_modified":1480349147797,"details":{"who":"All Firefox users who have these versions on the Abode Flash plugin installed.","created":"2013-03-26T09:43:25Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=854550","name":"Adobe Flash for Linux 10.3.182.* and lower (click-to-play)","why":"Old versions of the Adobe Flash plugin are potentially insecure and unstable. All users are recommended to visit our plugin check page and check for updates."},"versionRange":[{"targetApplication":[{"minVersion":"19.0a1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"},{"minVersion":"2.16a1","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"},{"minVersion":"17.0.4","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"17.0.*"}],"severity":0,"vulnerabilityStatus":1}],"id":"abaff0eb-314f-e882-b96c-5c5a4755688f","schema":1480349144394},{"matchName":"Java\\(TM\\) Plug-in 1\\.6\\.0_(39|40|41)([^\\d\\._]|$)","blockID":"p302","enabled":true,"matchFilename":"libnpjp2\\.so","last_modified":1480349147773,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2013-02-25T12:37:17Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=843373","name":"Java Plugin 6 updates 39 to 41 (click-to-play), Linux","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page.\r\n"},"versionRange":[{"targetApplication":[{"minVersion":"17.0","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"},{"minVersion":"2.14","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"}],"severity":0,"vulnerabilityStatus":1}],"id":"caec8103-dec9-8018-eb3d-9cf21cbf68a6","schema":1480349144394},{"blockID":"p129","enabled":true,"matchFilename":"Silverlight\\.plugin","last_modified":1480349147746,"details":{"who":"All Firefox users on Mac OS X who have old versions of the Silverlight plugin.","created":"2012-08-22T10:37:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=782672","name":"Silverlight for Mac OS X","why":"Old versions of the Silverlight plugin for Mac OS X are causing serious stability problems in Firefox. Affected users can visit the official Silverlight page and get the latest version of the Silverlight plugin to correct this problem."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"5.0.99999","severity":1}],"id":"ab861311-9c24-5f55-0d3a-f0072868357c","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p930","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349147722,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2015-06-30T14:10:49Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1177214","name":"Flash Player Plugin 16.0.0.305 to 18.0.0.193 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"16.0.0.305","maxVersion":"18.0.0.193","severity":0,"vulnerabilityStatus":1}],"id":"f461aaf7-128b-ad5a-07a9-aba1ddde8a5c","schema":1480349144394},{"infoURL":"https://java.com/","blockID":"p1142","enabled":true,"matchFilename":"JavaAppletPlugin\\.plugin","last_modified":1480349147694,"details":{"who":"All users who have these versions of the Java plugin installed.","created":"2016-03-31T16:16:46Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1259458","name":"Java Plugin 8 update 64 to 76 (click-to-play), Mac OS X","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"Java 8 Update 64","maxVersion":"Java 8 Update 76","severity":0,"vulnerabilityStatus":1}],"id":"646ebafe-dd54-e45f-9569-c245ef72259d","schema":1480349144394},{"blockID":"p212","enabled":true,"matchFilename":"JavaAppletPlugin\\.plugin","last_modified":1480349147671,"details":{"who":"All Firefox users who have the Java 7 plugin, updates 7 and below.","created":"2012-11-22T09:33:07Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=812896","name":"Java Plugin 1.7u7 (Mac OS X)","why":"The Java 7 Runtime Environment, update version 7, has a serious security vulnerability that is fixed in the latest update. All Firefox users are strongly encouraged to update as soon as possible. This can be done on the Plugin Check page."},"versionRange":[{"targetApplication":[{"minVersion":"0.1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"17.*"},{"minVersion":"0.1","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"2.14.*"}],"minVersion":"Java 7 Update 07","maxVersion":"Java 7 Update 07","severity":1}],"id":"5ec1cd0f-d478-e6e0-989e-c91694b2a411","schema":1480349144394},{"blockID":"p250","enabled":true,"matchFilename":"npFoxitReaderPlugin\\.dll","last_modified":1480349147648,"details":{"who":"All Firefox users on Windows who have installed the Foxit Reader Plugin, versions 2.2.1.530 and below.","created":"2013-01-14T13:07:03Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=828982","name":"Foxit Reader Plugin 2.2.1.530 and below","why":"The Foxit Reader plugin is vulnerable to a critical security bug that can compromise a user's system by visiting a malicious site."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"2.2.1.530","severity":0,"vulnerabilityStatus":2}],"id":"c6299be0-ab77-8bbd-bcaf-c886cec4e799","schema":1480349144394},{"blockID":"p85","enabled":true,"matchFilename":"JavaPlugin2_NPAPI\\.plugin","last_modified":1480349147625,"details":{"who":"All Firefox users who have installed the Java plugin, JRE versions below 1.6.0_31 or between 1.7.0 and 1.7.0_2.","created":"2012-04-16T13:58:43Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=741592","name":"Java Plugin","why":"Outdated versions of the Java plugin are vulnerable to an actively exploited security issue. All Mac OS X users are strongly encouraged to update their Java plugin through Software Update, or disable it if no alternatives are available. For more information, please read our blog post or Oracle's Advisory.\r\n\r\n"},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"13.6.0","severity":1}],"id":"4df1324d-8236-b7ae-db55-4fb1b7db2754","schema":1480349144394},{"infoURL":"https://get.adobe.com/reader","blockID":"p1250","enabled":true,"matchFilename":"(nppdf32\\.dll)|(AdobePDFViewerNPAPI\\.plugin)","last_modified":1480349147602,"details":{"who":"All users who have this plugin installed.","created":"2016-07-21T22:22:11Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1286972","name":"Adobe Reader (Continuous) 15.016.20045","why":"Old versions of the Adobe Reader plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"15.016.20045","maxVersion":"15.016.20045","severity":0,"vulnerabilityStatus":1}],"id":"b9f6998a-7a45-7d83-7ee6-897e6b193e42","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1225","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349147283,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-05-31T15:19:20Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1275307","name":"Flash Player Plugin 18.0.0.333 to 18.0.0.343 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"18.0.0.333","maxVersion":"18.0.0.343","severity":0,"vulnerabilityStatus":1}],"id":"e512821f-6174-f3c0-8369-2f3148cc586c","schema":1480349144394},{"infoURL":"https://real.com/","blockID":"p1053","enabled":true,"matchFilename":"nprpplugin\\.dll","last_modified":1480349147260,"details":{"who":"All users who have these versions of the Real Player plugin. Affected users can visit our plugin check page and check for updates.","created":"2015-11-12T09:07:04Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1222130","name":"Real Player for Windows, 17.0.10.7 and lower, click-to-play","why":"Old versions of the Real Player plugin have serious security problems that could lead to system compromise."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"17.0.10.7","severity":0,"vulnerabilityStatus":1}],"id":"2a6a7300-fac0-6518-c44a-35b3c4c714c3","schema":1480349144394},{"infoURL":"https://java.com/","blockID":"p1141","enabled":true,"matchFilename":"JavaAppletPlugin\\.plugin","last_modified":1480349147237,"details":{"who":"All users who have these versions of the Java plugin installed.","created":"2016-03-31T16:16:02Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1259458","name":"Java Plugin 7 update 91 to 97 (click-to-play), Mac OS X","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"Java 7 Update 91","maxVersion":"Java 7 Update 97","severity":0,"vulnerabilityStatus":1}],"id":"2a432d6e-9545-66be-9f93-aefe9793f450","schema":1480349144394},{"blockID":"p422","enabled":true,"matchFilename":"JavaAppletPlugin\\.plugin","last_modified":1480349147214,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2013-06-28T12:48:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=885362","name":"Java Plugin 7 update 16 to 24 (click-to-play), Mac OS X","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[{"minVersion":"17.0","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"},{"minVersion":"2.14","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"}],"minVersion":"Java 7 Update 16","maxVersion":"Java 7 Update 24","severity":0,"vulnerabilityStatus":1}],"id":"709960a7-d268-0c70-d6ad-17bbed0cd1c4","schema":1480349144394},{"matchName":"Java\\(TM\\) Platform SE 7 U([0-9]|(1[0-1]))(\\s[^\\d\\._U]|$)","blockID":"p182","enabled":true,"matchFilename":"npjp2\\.dll","last_modified":1480349147191,"details":{"who":"All users who have these versions of the plugin installed in Firefox 17 and above.","created":"2012-10-30T14:33:04Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=829111","name":"Java Plugin 7 update 11 and lower (click-to-play), Windows","why":"The Java plugin is causing significant security problems. All users are strongly recommended to keep the plugin disabled unless necessary."},"versionRange":[{"targetApplication":[{"minVersion":"17.0","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"},{"minVersion":"2.14","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"}],"severity":0,"vulnerabilityStatus":1}],"id":"385d9911-f8bc-83e0-8cd2-94c98087938c","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p796","enabled":true,"matchFilename":"libflashplayer\\.so","last_modified":1480349147169,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2014-12-11T12:17:01Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1109795","name":"Flash Player Plugin on Linux 11.2.202.424 and lower (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities (CVE-2014-9163). All users are strongly recommended to update their Flash plugin."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"11.2.202.424","severity":0,"vulnerabilityStatus":1}],"os":"Linux","id":"db6eaad4-d391-8ef3-a5df-e7219a758682","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1075","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349147146,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-01-07T12:53:43Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1235435","name":"Flash Player Plugin 18.0.0.262 to 18.0.0.268 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"18.0.0.262","maxVersion":"18.0.0.268","severity":0,"vulnerabilityStatus":1}],"id":"c420fbcd-1a58-e6ba-5c85-f4a189cf7d90","schema":1480349144394},{"matchName":"Java\\(TM\\) Plug-in 1\\.7\\.0_(1[6-9]|2[0-4])([^\\d\\._]|$)","blockID":"p418","enabled":true,"matchFilename":"libnpjp2\\.so","last_modified":1480349147123,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2013-06-28T12:46:18Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=885362","name":"Java Plugin 7 update 16 to 24 (click-to-play), Linux","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[{"minVersion":"17.0","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"},{"minVersion":"2.14","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"}],"severity":0,"vulnerabilityStatus":1}],"id":"ee5c1584-0170-8702-5f99-e0325b4a91a8","schema":1480349144394},{"blockID":"p158","enabled":true,"matchFilename":"nppdf32\\.dll","last_modified":1480349147100,"details":{"who":"All Firefox users who have this plugin installed.","created":"2012-10-05T10:40:20Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=850745","name":"Adobe Reader 10.0 to 10.1.5.*","why":"This plugin is outdated and is potentially insecure. Affected users should go to the plugin check page and update to the latest version."},"versionRange":[{"targetApplication":[],"minVersion":"10.0","maxVersion":"10.1.5.9999","severity":0,"vulnerabilityStatus":1}],"id":"107c9a8c-2ef8-da26-75c3-bc26f8ae90fa","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1026","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349147077,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2015-10-01T09:48:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1206889","name":"Flash Player Plugin 18.0.0.204 to 18.0.0.232 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"18.0.0.204","maxVersion":"18.0.0.232","severity":0,"vulnerabilityStatus":1}],"id":"6c349faf-109f-4456-4d45-b793e3b7e20e","schema":1480349144394},{"infoURL":"https://java.com/","matchName":"Java\\(TM\\) Platform SE 8 U45(\\s[^\\d\\._U]|$)","blockID":"p960","enabled":true,"matchFilename":"npjp2\\.dll","last_modified":1480349147055,"details":{"who":"All users who have these versions of the Java plugin installed.","created":"2015-07-15T10:50:25Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1183369","name":"Java Plugin 8 update 45 (click-to-play), Windows","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[],"severity":0,"vulnerabilityStatus":1}],"id":"990fa997-1d4a-98ee-32de-a7471e81db42","schema":1480349144394},{"blockID":"p113","enabled":true,"matchFilename":"npuplaypc\\.dll","last_modified":1480349147031,"details":{"who":"All Firefox users who have this plugin installed.","created":"2012-07-30T12:11:59Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=778686","name":"Ubisoft Uplay","why":"Version 1.0.0.0 of the Ubisoft Uplay plugin has a security vulnerability that can be exploited by malicious websites to gain control of the user's system."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"1.0.0.0","severity":1}],"id":"ea3b767d-933b-3f54-f447-09bd2bfbc6e0","schema":1480349144394},{"blockID":"p366","enabled":true,"matchFilename":"Scorch\\.plugin","last_modified":1480349147009,"details":{"who":"All users who have Firefox 18 or above installed, and the Sibelius Scorch plugin.","created":"2013-06-11T13:20:32Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=879128","name":"Sibelius Scorch plugin","why":"The Sibelius Scorch plugin is not compatible with Firefox 18 and above, and is crashing whenever loaded on affected versions of Firefox. "},"versionRange":[{"targetApplication":[],"minVersion":"6.2.0","maxVersion":"6.2.0","severity":1}],"id":"43ec430a-75ec-6853-f62b-1a54489fea5f","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1067","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349146986,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2015-12-21T13:44:44Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1231191","name":"Flash Player Plugin 19.0.0.226 to 19.0.0.245 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"19.0.0.226","maxVersion":"19.0.0.245","severity":0,"vulnerabilityStatus":1}],"id":"ae2e1608-eaa4-68de-521e-9ffe22a9e3a4","schema":1480349144394},{"matchName":"Java\\(TM\\) Plug-in 1\\.6\\.0_3[1-8]([^\\d\\._]|$)","blockID":"p190","enabled":true,"matchFilename":"libnpjp2\\.so","last_modified":1480349146961,"details":{"who":"All users who have these versions of the plugin installed in Firefox 17 and above.","created":"2012-10-30T14:55:37Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=829111","name":"Java Plugin 6 updates 31 through 38 (click-to-play), Linux","why":"The Java plugin is causing significant security problems. All users are strongly recommended to keep the plugin disabled unless necessary."},"versionRange":[{"targetApplication":[{"minVersion":"17.0","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"},{"minVersion":"2.14","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"}],"severity":0,"vulnerabilityStatus":1}],"id":"9f9eb0ae-6495-aaa6-041a-d802cdb8e134","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1076","enabled":true,"matchFilename":"libflashplayer\\.so","last_modified":1480349146938,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-01-07T12:54:49Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1235435","name":"Flash Player Plugin on Linux 11.2.202.549 to 11.2.202.554 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"11.2.202.549","maxVersion":"11.2.202.554","severity":0,"vulnerabilityStatus":1}],"os":"Linux","id":"0beab50c-0ded-c200-557a-f759db85d8a1","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1253","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349146913,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-07-25T13:22:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1286380","name":"Flash Player Plugin 18.0.0.352 to 18.0.0.360 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"18.0.0.352","maxVersion":"18.0.0.360","severity":0,"vulnerabilityStatus":1}],"id":"84338b2a-bdee-c124-713e-5b5df3407882","schema":1480349144394},{"infoURL":"https://java.com/","matchName":"Java(\\(TM\\))? Plug-in 11\\.45(\\.[0-9]+)?([^\\d\\._]|$)","blockID":"p964","enabled":true,"matchFilename":"libnpjp2\\.so","last_modified":1480349146890,"details":{"who":"All users who have these versions of the Java plugin installed.","created":"2015-07-15T10:51:57Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1183369","name":"Java Plugin 8 update 45 (click-to-play), Linux","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[],"severity":0,"vulnerabilityStatus":1}],"id":"c2431673-3478-f1e1-5555-28e2d5377adc","schema":1480349144394},{"blockID":"p1002","enabled":true,"matchFilename":"npUnity3D32\\.dll","last_modified":1480349146867,"details":{"who":"All users who have these versions of the plugin installed.","created":"2015-09-09T14:07:27Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=974012","name":"Unity Web Player 5.0 to 5.0.3f1 (click-to-play), Windows","why":"These versions of the Unity Web Player plugin have known vulnerabilities that can put users at risk."},"versionRange":[{"targetApplication":[],"minVersion":"5.0","maxVersion":"5.0.3f1","severity":0,"vulnerabilityStatus":1}],"id":"48e45eea-fd32-2304-2776-fe75211a69e5","schema":1480349144394},{"blockID":"p123","enabled":true,"matchFilename":"JavaPlugin2_NPAPI\\.plugin","last_modified":1480349146842,"details":{"who":"All Firefox users who have installed the Java plugin, JRE versions below 1.6.0_33 or between 1.7.0 and 1.7.0_4.","created":"2012-08-14T09:29:42Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=780717","name":"Java Plugin","why":"Outdated versions of the Java plugin are vulnerable to an actively exploited security issue. All users are strongly encouraged to update their Java plugin. For more information, please read our blog post or Oracle's Advisory."},"versionRange":[{"targetApplication":[{"minVersion":"0.1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"17.*"},{"minVersion":"0.1","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"2.14.*"}],"minVersion":"0","maxVersion":"14.2.0","severity":1}],"id":"46bf36a7-1934-38f8-1fcc-c9c4bcc8343e","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1148","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349146818,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-04-13T14:25:14Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1263476","name":"Flash Player Plugin 20.0.0.306 to 21.0.0.197 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"20.0.0.306","maxVersion":"21.0.0.197","severity":0,"vulnerabilityStatus":1}],"id":"a3470c77-4449-48e3-f234-eeb93f702821","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1235","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349146794,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-06-23T12:54:00Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1280125","name":"Flash Player Plugin 18.0.0.343 to 18.0.0.352 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"18.0.0.343","maxVersion":"18.0.0.352","severity":0,"vulnerabilityStatus":1}],"id":"a435cc3b-9363-c7c3-e856-a0128966c809","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1150","enabled":true,"matchFilename":"libflashplayer\\.so","last_modified":1480349146772,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-04-13T14:28:17Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1263476","name":"Flash Player Plugin on Linux 11.2.202.569 to 11.2.202.577 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"11.2.202.569","maxVersion":"11.2.202.577","severity":0,"vulnerabilityStatus":1}],"os":"Linux","id":"f52d9f17-7676-2aad-48b8-af97f281fcb2","schema":1480349144394},{"matchName":"Java\\(TM\\) Platform SE 7 U[5-6](\\s[^\\d\\._U]|$)","blockID":"p134","enabled":true,"matchFilename":"npjp2\\.dll","last_modified":1480349146749,"details":{"who":"All Firefox users who have the Java 7 plugin, update 6 and below.","created":"2012-08-31T15:22:51Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=794247","name":"Java Plugin","why":"The Java 7 Runtime Environment, update versions 6 and below, has a serious security vulnerability that is fixed in the latest update. All Firefox users are strongly encouraged to update as soon as possible. This can be done on the Plugin Check page."},"versionRange":[{"targetApplication":[{"minVersion":"0.1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"17.*"},{"minVersion":"0.1","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"2.14.*"}],"severity":1}],"id":"1f519b98-a4b6-2a98-b1ff-b642f7b4d2bb","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p948","enabled":true,"matchFilename":"libflashplayer\\.so","last_modified":1480349146726,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2015-07-13T16:02:09Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1182751","name":"Flash Player Plugin on Linux 11.2.202.481 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"11.2.202.481","maxVersion":"11.2.202.481","severity":0,"vulnerabilityStatus":1}],"os":"Linux","id":"bcfe2592-6154-fcc7-cf0f-574eda317900","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p944","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349146378,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2015-07-13T16:00:02Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1182751","name":"Flash Player Plugin 13.0.0.302 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"13.0.0.302","maxVersion":"13.0.0.302","severity":0,"vulnerabilityStatus":1}],"id":"1fc0a5c5-fcfb-dfb4-9950-9e2f0b064010","schema":1480349144394},{"matchName":"Java\\(TM\\) Platform SE ((6( U(\\d|([0-2]\\d)|3[0-2]))?)|(7(\\sU[0-4])?))(\\s[^\\d\\._U]|$)","blockID":"p125","enabled":true,"matchFilename":"npjp2\\.dll","last_modified":1480349146351,"details":{"who":"All Firefox users who have installed the Java plugin, JRE versions below 1.6.0_33 or between 1.7.0 and 1.7.0_4.","created":"2012-08-14T09:31:17Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=780717","name":"Java Plugin","why":"Outdated versions of the Java plugin are vulnerable to an actively exploited security issue. All users are strongly encouraged to update their Java plugin. For more information, please read our blog post or Oracle's Advisory."},"versionRange":[{"targetApplication":[{"minVersion":"0.1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"17.*"},{"minVersion":"0.1","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"2.14.*"}],"severity":1}],"id":"7538347d-ca2e-09b8-c5d8-0a9d140f8c87","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p290","enabled":true,"matchFilename":"(NPSWF32\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349146327,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2013-02-25T10:15:59Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=807258","name":"Flash Player Plugin 10.3.183.19 to 10.3.183.66 (click-to-play)","why":"Old versions of the Flash Player plugin are potentially insecure and unstable. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[{"minVersion":"19.0a1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"},{"minVersion":"2.16a1","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"},{"minVersion":"17.0.4","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"17.0.*"}],"minVersion":"10.3.183.19","maxVersion":"10.3.183.66","severity":0,"vulnerabilityStatus":1}],"id":"b1177bd1-a518-b86a-8825-e4c91d2362de","schema":1480349144394},{"blockID":"p292","enabled":true,"matchFilename":"JavaAppletPlugin\\.plugin","last_modified":1480349146304,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2013-02-25T12:32:41Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=843373","name":"Java Plugin 7 update 12 to 15 (click-to-play), Mac OS X","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[{"minVersion":"17.0","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"},{"minVersion":"2.14","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"}],"minVersion":"Java 7 Update 12","maxVersion":"Java 7 Update 15","severity":0,"vulnerabilityStatus":1}],"id":"9a09fe22-c3d8-57e6-4e99-ecd06fb03081","schema":1480349144394},{"blockID":"p188","enabled":true,"matchFilename":"JavaAppletPlugin\\.plugin","last_modified":1480349146280,"details":{"who":"All users who have these versions of the plugin installed in Firefox 17 and above.","created":"2012-10-30T14:48:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=829111","name":"Java Plugin 6 updates 38 and lower (click-to-play), Mac OS X","why":"The Java plugin is causing significant security problems. All users are strongly recommended to keep the plugin disabled unless necessary."},"versionRange":[{"targetApplication":[{"minVersion":"17.0","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"},{"minVersion":"2.14","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"}],"minVersion":"Java 6 Update 0","maxVersion":"Java 6 Update 38","severity":0,"vulnerabilityStatus":1}],"id":"61944828-8178-71ab-e9c6-d846b5f45d96","schema":1480349144394},{"blockID":"p459","enabled":true,"matchFilename":"JavaAppletPlugin\\.plugin","last_modified":1480349146253,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2013-10-16T16:29:27Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=927273","name":"Java Plugin 7 update 25 to 44 (click-to-play), Mac OS X","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[{"minVersion":"17.0","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"},{"minVersion":"2.14","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"}],"minVersion":"Java 7 Update 25","maxVersion":"Java 7 Update 44","severity":0,"vulnerabilityStatus":1}],"id":"5b0bbf0e-dbae-7896-3c31-c6cb7a74e6fa","schema":1480349144394},{"matchName":"^Yahoo Application State Plugin$","blockID":"p26","enabled":true,"matchFilename":"npYState.dll","last_modified":1480349146230,"details":{"who":"Users of all versions of Yahoo Application State Plugin for Firefox 3 and later.\r\n\r\nUsers of all versions of Yahoo Application State Plugin for SeaMonkey 1.0.0.5 and later.","created":"2011-03-31T16:28:26Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=421993","name":"Yahoo Application State Plugin","why":"This plugin causes a high volume of Firefox and SeaMonkey crashes."},"versionRange":[{"targetApplication":[{"minVersion":"3.0a1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"3.*"}]}],"matchDescription":"^Yahoo Application State Plugin$","id":"6a1b6dfe-f463-3061-e8f8-6e896ccf2a8a","schema":1480349144394},{"infoURL":"https://java.com/","blockID":"p902","enabled":true,"matchFilename":"JavaAppletPlugin\\.plugin","last_modified":1480349146207,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2015-05-19T09:00:27Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1159917","name":"Java Plugin 7 update 45 to 78 (click-to-play), Mac OS X","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"Java 7 Update 45","maxVersion":"Java 7 Update 78","severity":0,"vulnerabilityStatus":1}],"id":"72de1aa2-6afe-2f5b-a93e-baa4c8c4578d","schema":1480349144394},{"blockID":"p154","enabled":true,"matchFilename":"npctrl\\.dll","last_modified":1480349146182,"details":{"who":"All Firefox users who have this plugin installed.","created":"2012-10-05T10:35:55Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=850744","name":"Silverlight 5.0 to 5.1.20124.*","why":"This plugin is outdated and is potentially insecure. Affected users should go to the plugin check page and update to the latest version."},"versionRange":[{"targetApplication":[],"minVersion":"5.0","maxVersion":"5.1.20124.9999","severity":0,"vulnerabilityStatus":1}],"id":"64b50946-53f8-182d-a239-bd585b0e0b0e","schema":1480349144394},{"matchDescription":"Flip4Mac","blockID":"p242","enabled":true,"last_modified":1480349146153,"details":{"who":"All Firefox (18 and above) users on Mac OS X who have installed a version of Flip4Mac older than 2.4.4.","created":"2012-12-21T13:32:36Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=821422","name":"Flip4Mac WMV Plugin","why":"Old versions of the Flip4Mac WMV plugin are causing significant stability problems in Firefox 18 and above. Users are encouraged update to the latest version of the plugin, available at the Flip4Mac site."},"versionRange":[{"targetApplication":[{"minVersion":"18.0a1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"}],"minVersion":"0","maxVersion":"2.4.3.999","severity":1}],"os":"Darwin","id":"cef6f402-bdf8-0ba6-66d8-8ac42c72d4be","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p834","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349146129,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2015-02-05T15:42:51Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1128534","name":"Flash Player Plugin 13.0.0.263 to 13.0.0.268 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"13.0.0.263","maxVersion":"13.0.0.268","severity":0,"vulnerabilityStatus":1}],"id":"5e42d3a0-dfc5-4edb-8a30-4d6eed694b01","schema":1480349144394},{"matchName":"Java\\(TM\\) Platform SE 6 U3[1-8](\\s[^\\d\\._U]|$)","blockID":"p186","enabled":true,"matchFilename":"npjp2\\.dll","last_modified":1480349146106,"details":{"who":"All users who have these versions of the plugin installed in Firefox 17 and above.","created":"2012-10-30T14:45:39Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=829111","name":"Java Plugin 6 updates 31 through 38 (click-to-play), Windows","why":"The Java plugin is causing significant security problems. All users are strongly recommended to keep the plugin disabled unless necessary."},"versionRange":[{"targetApplication":[{"minVersion":"17.0","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"},{"minVersion":"2.14","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"}],"severity":0,"vulnerabilityStatus":1}],"id":"8488cdb0-1f00-1349-abfc-f50e85c9163b","schema":1480349144394},{"infoURL":"https://get.adobe.com/reader","blockID":"p1247","enabled":true,"matchFilename":"(nppdf32\\.dll)|(AdobePDFViewerNPAPI\\.plugin)","last_modified":1480349146079,"details":{"who":"All users who have this plugin installed.","created":"2016-07-21T16:21:52Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1286972","name":"Adobe Reader (Classic) 15.006.30174","why":"Old versions of the Adobe Reader plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"15.006.30174","maxVersion":"15.006.30174","severity":0,"vulnerabilityStatus":1}],"id":"eba24802-0c93-b8d4-ca2d-c9c194c7462b","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","matchDescription":"^Shockwave Flash 11.(0|1) r[0-9]{1,3}$","blockID":"p332","enabled":true,"matchFilename":"libflashplayer\\.so","last_modified":1480349146047,"details":{"who":"All Firefox users who have these versions of the Adobe Flash Player plugin installed.","created":"2013-03-26T09:46:14Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=854550","name":"Adobe Flash for Linux 11.0 to 11.1.* (click-to-play)","why":"Old versions of the Adobe Flash Player plugin are potentially insecure and unstable. All users are recommended to visit our plugin check to check for updates."},"versionRange":[{"targetApplication":[{"minVersion":"19.0a1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"},{"minVersion":"2.16a1","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"},{"minVersion":"17.0.4","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"17.0.*"}],"severity":0,"vulnerabilityStatus":1}],"id":"38797744-cb92-1a49-4c81-2a900691fdba","schema":1480349144394},{"matchName":"Java\\(TM\\) Platform SE 7 U1[2-5](\\s[^\\d\\._U]|$)","blockID":"p294","enabled":true,"matchFilename":"npjp2\\.dll","last_modified":1480349146005,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2013-02-25T12:33:48Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=843373","name":"Java Plugin 7 update 12 to 15 (click-to-play), Windows","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[{"minVersion":"17.0","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"},{"minVersion":"2.14","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"}],"severity":0,"vulnerabilityStatus":1}],"id":"ab8aff96-ead4-615d-be44-bcb7c31699f0","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1065","enabled":true,"matchFilename":"libflashplayer\\.so","last_modified":1480349145967,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2015-12-21T13:42:42Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1231191","name":"Flash Player Plugin on Linux 11.2.202.540 to 11.2.202.548 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"11.2.202.540","maxVersion":"11.2.202.548","severity":0,"vulnerabilityStatus":1}],"os":"Linux","id":"6bd57804-385b-ec8b-d4ff-3997597c3924","schema":1480349144394},{"matchName":"Java(\\(TM\\))? Plug-in ((1\\.7\\.0_(2[5-9]|3\\d|4[0-4]))|(10\\.4[0-4](\\.[0-9]+)?))([^\\d\\._]|$)","blockID":"p457","enabled":true,"matchFilename":"libnpjp2\\.so","last_modified":1480349145942,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2013-10-16T16:28:58Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=927273","name":"Java Plugin 7 update 25 to 44 (click-to-play), Linux","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[{"minVersion":"17.0","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"},{"minVersion":"2.14","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"}],"severity":0,"vulnerabilityStatus":1}],"id":"5ca97332-f4b7-81f5-d441-6acb1834f332","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1236","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349145917,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-06-23T12:55:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1280125","name":"Flash Player Plugin 21.0.0.226 to 21.0.0.242 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"21.0.0.226","maxVersion":"21.0.0.242","severity":0,"vulnerabilityStatus":1}],"id":"392c2c9b-f2a7-1bd5-c01c-6035e810cbaf","schema":1480349144394},{"blockID":"p138","enabled":true,"matchFilename":"JavaAppletPlugin\\.plugin","last_modified":1480349145894,"details":{"who":"All Firefox users who have the Java 7 plugin, update 6 and below.","created":"2012-09-13T14:49:52Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=794247","name":"Java Plugin","why":"The Java 7 Runtime Environment, update versions 6 and below, has a serious security vulnerability that is fixed in the latest update. All Firefox users are strongly encouraged to update as soon as possible. This can be done on the Plugin Check page."},"versionRange":[{"targetApplication":[{"minVersion":"0.1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"17.*"},{"minVersion":"0.1","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"2.14.*"}],"minVersion":"Java 7 Update 01","maxVersion":"Java 7 Update 06","severity":1}],"id":"5e898a46-8ea9-2fab-5dfe-a43e51641d81","schema":1480349144394},{"blockID":"p31","enabled":true,"matchFilename":"NPMySrch.dll","last_modified":1480349145872,"details":{"who":"All users of MyWebSearch for all Mozilla applications.","created":"2011-03-31T16:28:26Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=449062","name":"MyWebSearch","why":"This plugin causes a high volume of Firefox crashes."},"versionRange":[{"targetApplication":[],"maxVersion":"*"}],"id":"2b2b85e9-4f64-9894-e3fa-3c05ead892b3","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p260","enabled":true,"matchFilename":"(NPSWF32\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349145849,"details":{"who":"All users who have these versions of the Flash plugin installed in Firefox 18 and above.","created":"2013-01-29T11:29:00Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=832038","name":"Flash Player Plugin 10.2.* and lower (click-to-play)","why":"Old versions of the Flash Player plugin are potentially insecure and unstable. All users are strongly recommended to check for updates at our plugin check page.\r\n\r\nFor more information and feedback, please visit this post."},"versionRange":[{"targetApplication":[{"minVersion":"18.0a1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"},{"minVersion":"2.14a1","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"},{"minVersion":"17.0.4","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"17.0.*"}],"minVersion":"0","maxVersion":"10.2.9999","severity":0,"vulnerabilityStatus":1}],"id":"ce0495ed-72b8-9cb4-7a1b-eaf7f77586f7","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1272","enabled":true,"matchFilename":"libflashplayer\\.so","last_modified":1480349145825,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-09-23T15:27:40Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1302525","name":"Flash Player Plugin on Linux 11.2.202.626 to 11.2.202.632 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"11.2.202.626","maxVersion":"11.2.202.632","severity":0,"vulnerabilityStatus":1}],"os":"Linux","id":"c6add809-fcd0-c504-c126-077800ebfdae","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1139","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349145802,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-03-18T15:34:16Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1255519","name":"Flash Player Plugin 18.0.0.326 to 18.0.0.329 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"18.0.0.326","maxVersion":"18.0.0.329","severity":0,"vulnerabilityStatus":1}],"id":"0a890ad6-f9f3-7df4-5154-966368c1789d","schema":1480349144394},{"blockID":"p572","enabled":true,"matchFilename":"npdjvu\\.dll","last_modified":1480349145775,"details":{"who":"All Firefox users who have this plugin installed. Updated versions can be found on this site.","created":"2014-04-08T14:42:05Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=992976","name":"DjVu Plugin Viewer 6.1.4.27993 and earlier (Windows)","why":"Versions 6.1.4.27993 and earlier of this plugin are known to have security vulnerabilities."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"6.1.4.27993","severity":0,"vulnerabilityStatus":1}],"id":"8a416fb1-29bf-ace9-02de-605d805b6e79","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1273","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349145748,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-09-23T15:28:24Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1302525","name":"Flash Player Plugin 18.0.0.360 to 18.0.0.366 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"18.0.0.360","maxVersion":"18.0.0.366","severity":0,"vulnerabilityStatus":1}],"id":"72e5f878-3202-b97a-d419-6e1e86a2fb18","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1044","enabled":true,"matchFilename":"libflashplayer\\.so","last_modified":1480349145406,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2015-10-21T14:11:52Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1214459","name":"Flash Player Plugin on Linux 11.2.202.509 to 11.2.202.539 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"11.2.202.509","maxVersion":"11.2.202.539","severity":0,"vulnerabilityStatus":1}],"os":"Linux","id":"10b322e3-61ec-1066-a88b-cd12c1da339b","schema":1480349144394},{"blockID":"p592","enabled":true,"matchFilename":"CiscoWebCommunicator\\.plugin","last_modified":1480349145382,"details":{"who":"All Firefox users who have installed a version of the Cisco Web Communicator plugin lower than 3.0.6.","created":"2014-06-11T16:48:48Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=980355","name":"Cisco Web Communicator < 3.0.6 (Mac OS X)","why":"Versions lower than 3.0.6 of the Cisco Web Communicator plugin are known to have security issues and should not be used. All users should update to version 3.0.6 or later. Find updates here."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"3.0.5.99999999999999","severity":0,"vulnerabilityStatus":1}],"id":"1f9f9b90-e733-3929-821f-1b78a8698747","schema":1480349144394},{"matchName":"^Yahoo Application State Plugin$","blockID":"p29","enabled":true,"matchFilename":"npYState.dll","last_modified":1480349145359,"details":{"who":"Users of all versions of Yahoo Application State Plugin for Firefox 3 and later.\r\n\r\nUsers of all versions of Yahoo Application State Plugin for SeaMonkey 1.0.0.5 and later.","created":"2011-03-31T16:28:26Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=421993","name":"Yahoo Application State Plugin (SeaMonkey)","why":"This plugin causes a high volume of Firefox and SeaMonkey crashes."},"versionRange":[{"targetApplication":[{"minVersion":"1.0.0.5","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"}]}],"matchDescription":"^Yahoo Application State Plugin$","id":"8f52a562-5438-731b-5c64-7f76009f1489","schema":1480349144394},{"matchName":"Java\\(TM\\) Plug-in 1\\.6\\.0_4[2-5]([^\\d\\._]|$)","blockID":"p412","enabled":true,"matchFilename":"libnpjp2\\.so","last_modified":1480349145336,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2013-06-28T12:42:20Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=885362","name":"Java Plugin 6 updates 42 to 45 (click-to-play), Linux","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[{"minVersion":"17.0","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"},{"minVersion":"2.14","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"}],"severity":0,"vulnerabilityStatus":1}],"id":"8f652c63-cda4-1640-0b0c-23025e336b20","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1412","enabled":true,"matchFilename":"libflashplayer\\.so","last_modified":1480349145312,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-10-28T17:14:48Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1313435","name":"Flash Player Plugin on Linux 11.2.202.632 to 11.2.202.637 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"11.2.202.632","maxVersion":"11.2.202.637","severity":0,"vulnerabilityStatus":1}],"os":"Linux","id":"c7393e90-d75b-2aac-21de-a0c460387ff5","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p176","enabled":true,"matchFilename":"(NPSWF32\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349145289,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2012-10-30T14:02:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=803152","name":"Flash Player Plugin 10.3 to 10.3.183.19 (click-to-play)","why":"Old versions of the Flash Player plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[{"minVersion":"19.0a1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"},{"minVersion":"2.16a1","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"},{"minVersion":"17.0.4","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"17.0.*"}],"minVersion":"10.3","maxVersion":"10.3.183.18.999","severity":0,"vulnerabilityStatus":1}],"id":"3b6278ac-d613-6769-c299-89385b8075d1","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1413","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349145265,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-10-28T17:15:49Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1313435","name":"Flash Player Plugin 22.0.0.211 to 23.0.0.185 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"22.0.0.211","maxVersion":"23.0.0.185","severity":0,"vulnerabilityStatus":1}],"id":"4fe73208-9a72-bea4-cd97-c106e6503d2e","schema":1480349144394},{"matchName":"Java\\(TM\\) Plug-in 1\\.7\\.0(_0?([0-9]|(1[0-1]))?)?([^\\d\\._]|$)","blockID":"p184","enabled":true,"matchFilename":"libnpjp2\\.so","last_modified":1480349145223,"details":{"who":"All users who have these versions of the plugin installed in Firefox 17 and above.","created":"2012-10-30T14:39:15Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=829111","name":"Java Plugin 7 update 11 and lower (click-to-play), Linux","why":"The Java plugin is causing significant security problems. All users are strongly recommended to keep the plugin disabled unless necessary."},"versionRange":[{"targetApplication":[{"minVersion":"17.0","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"},{"minVersion":"2.14","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"}],"severity":0,"vulnerabilityStatus":1}],"id":"06621403-39a8-3867-ba6e-406dc20c88af","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p932","enabled":true,"matchFilename":"libflashplayer\\.so","last_modified":1480349145175,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2015-06-30T14:12:05Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1177214","name":"Flash Player Plugin on Linux 11.2.202.442 to 11.2.202.467 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"11.2.202.442","maxVersion":"11.2.202.467","severity":0,"vulnerabilityStatus":1}],"os":"Linux","id":"f136f459-8d42-f2a1-5cd3-e8d24dd8f70d","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1121","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349145144,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-02-17T16:26:05Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1247032","name":"Flash Player Plugin 20.0.0.235 to 20.0.0.286 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"20.0.0.235","maxVersion":"20.0.0.286","severity":0,"vulnerabilityStatus":1}],"id":"c7d33934-7875-1e9e-ebcc-1a73e359951d","schema":1480349144394},{"infoURL":"https://java.com/","matchName":"Java(\\(TM\\))? Plug-in 11\\.(\\d|[1-3]\\d|4[0-4])(\\.[0-9]+)?([^\\d\\._]|$)","blockID":"p912","enabled":true,"matchFilename":"libnpjp2\\.so","last_modified":1480349145119,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2015-05-19T09:05:55Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1159917","name":"Java Plugin 8 update 44 and lower (click-to-play), Linux","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[],"severity":0,"vulnerabilityStatus":1}],"id":"f0a40537-9a13-1b4b-60e5-b9121835c1ca","schema":1480349144394},{"infoURL":"https://java.com/","matchName":"Java\\(TM\\) Platform SE 8( U([1-3]?\\d|4[0-4]))?(\\s[^\\d\\._U]|$)","blockID":"p908","enabled":true,"matchFilename":"npjp2\\.dll","last_modified":1480349145082,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2015-05-19T09:03:44Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1159917","name":"Java Plugin 8 update 44 and lower (click-to-play), Windows","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[],"severity":0,"vulnerabilityStatus":1}],"id":"79e165b4-599b-433d-d618-146f0c121ead","schema":1480349144394},{"infoURL":"https://java.com/","matchName":"Java(\\(TM\\))? Plug-in 11\\.(6[4-9]|7[0-6])(\\.[0-9]+)?([^\\d\\._]|$)","blockID":"p1146","enabled":true,"matchFilename":"libnpjp2\\.so","last_modified":1480349145057,"details":{"who":"All users who have these versions of the Java plugin installed.","created":"2016-03-31T16:19:31Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1259458","name":"Java Plugin 8 update 64 to 76 (click-to-play), Linux","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[],"severity":0,"vulnerabilityStatus":1}],"id":"bc99ed93-b527-12e2-c6e6-c61668a2e7d0","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1254","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349145005,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-07-25T13:24:40Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1286380","name":"Flash Player Plugin 21.0.0.242 to 22.0.0.192 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"21.0.0.242","maxVersion":"22.0.0.192","severity":0,"vulnerabilityStatus":1}],"id":"d9e50e5f-ffff-35d1-c0d0-66d0f1daef77","schema":1480349144394},{"infoURL":"https://java.com/","matchName":"Java\\(TM\\) Platform SE 7 U(79|80)(\\s[^\\d\\._U]|$)","blockID":"p958","enabled":true,"matchFilename":"npjp2\\.dll","last_modified":1480349144983,"details":{"who":"All users who have these versions of the Java plugin installed.","created":"2015-07-15T10:49:33Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1183369","name":"Java Plugin 7 update 79 to 80 (click-to-play), Windows","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[],"severity":0,"vulnerabilityStatus":1}],"id":"2cfa79ef-a2ab-d868-467d-d182242136a5","schema":1480349144394},{"blockID":"p156","enabled":true,"matchFilename":"nppdf32\\.dll","last_modified":1480349144959,"details":{"who":"All Firefox users who have this plugin installed.","created":"2012-10-05T10:38:46Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=797378","name":"Adobe Reader 9.5.1 and lower","why":"This plugin is outdated and is potentially insecure. Affected users should go to the plugin check page and update to the latest version."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"9.5.1","severity":0,"vulnerabilityStatus":1}],"id":"0dce3611-19e7-e8e4-5b5c-13593230f83c","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1123","enabled":true,"matchFilename":"libflashplayer\\.so","last_modified":1480349144934,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-02-17T16:28:21Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1247032","name":"Flash Player Plugin on Linux 11.2.202.554 to 11.2.202.559 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"11.2.202.554","maxVersion":"11.2.202.559","severity":0,"vulnerabilityStatus":1}],"os":"Linux","id":"dd7b1070-3be3-d859-ac45-691892512e3f","schema":1480349144394},{"blockID":"p574","enabled":true,"matchFilename":"NPDjVu\\.plugin","last_modified":1480349144910,"details":{"who":"All Firefox users who have this plugin installed. Updated versions can be found on this site.","created":"2014-04-08T14:43:54Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=992976","name":"DjVu Plugin Viewer 6.1.1 and earlier (Mac OS)","why":"Versions 6.1.1 and earlier of this plugin are known to have security vulnerabilities.\r\n"},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"6.1.1","severity":0,"vulnerabilityStatus":1}],"id":"c841472f-f976-c49a-169e-0c751012c3b1","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p798","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349144887,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2014-12-12T16:06:00Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1109795","name":"Flash Player Plugin 14.0 to 15.0.0.242 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities (CVE-2014-9163). All users are strongly recommended to update their Flash plugin."},"versionRange":[{"targetApplication":[],"minVersion":"14.0","maxVersion":"15.0.0.242","severity":0,"vulnerabilityStatus":1}],"id":"975c8d44-21f4-91f3-2e5a-44e0cfd33d06","schema":1480349144394},{"blockID":"p556","enabled":true,"matchFilename":"npUnity3D32\\.dll","last_modified":1480349144865,"details":{"who":"All Firefox users who have these versions of the plugin installed.","created":"2014-02-25T08:29:41Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=974012","name":"Unity Web Player 4.6.6f1 and lower (click-to-play), Windows","why":"Current versions of the Unity Web Player plugin have known vulnerabilities that can put users at risk."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"4.6.6f1","severity":0,"vulnerabilityStatus":1}],"id":"b90eb83c-1314-5b27-687b-98d8115b6106","schema":1480349144394},{"matchName":"Java\\(TM\\) Platform SE 6 U4[2-5](\\s[^\\d\\._U]|$)","blockID":"p414","enabled":true,"matchFilename":"npjp2\\.dll","last_modified":1480349144842,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2013-06-28T12:43:43Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=885362","name":"Java Plugin 6 updates 42 to 45 (click-to-play), Windows","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[{"minVersion":"17.0","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"},{"minVersion":"2.14","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"}],"severity":0,"vulnerabilityStatus":1}],"id":"e36516a6-8bb3-09cc-02e3-72c67046b42e","schema":1480349144394},{"matchName":"Java\\(TM\\) Platform SE 7 U7(\\s[^\\d\\._U]|$)","blockID":"p214","enabled":true,"matchFilename":"npjp2\\.dll","last_modified":1480349144817,"details":{"who":"All Firefox users who have the Java 7 plugin, updates 7 and below.","created":"2012-11-22T09:34:13Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=812896","name":"Java Plugin 1.7u7 (Windows)","why":"The Java 7 Runtime Environment, update version 7 and below, has a serious security vulnerability that is fixed in the latest update. All Firefox users are strongly encouraged to update as soon as possible. This can be done on the Plugin Check page."},"versionRange":[{"targetApplication":[{"minVersion":"0.1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"17.*"},{"minVersion":"0.1","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"2.14.*"}],"severity":1}],"id":"524ff62f-9564-a2b2-2585-88b88ea4c2f9","schema":1480349144394},{"infoURL":"https://java.com/","blockID":"p956","enabled":true,"matchFilename":"JavaAppletPlugin\\.plugin","last_modified":1480349144793,"details":{"who":"All users who have these versions of the Java plugin installed.","created":"2015-07-15T10:48:44Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1183369","name":"Java Plugin 8 update 45 (click-to-play), Mac OS X","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"Java 8 Update 45","maxVersion":"Java 8 Update 45","severity":0,"vulnerabilityStatus":1}],"id":"111881f9-a5bd-4919-4bab-9d7581d959d3","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p824","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349144769,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2015-01-28T14:35:08Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1124654","name":"Flash Player Plugin 13.0.0.259 to 13.0.0.263 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"13.0.0.259","maxVersion":"13.0.0.263","severity":0,"vulnerabilityStatus":1}],"id":"dc56898f-fb0f-23ce-f507-8b50206c5444","schema":1480349144394},{"matchName":"\\(TM\\)","blockID":"p80","enabled":true,"matchFilename":"(npjp2\\.dll)|(libnpjp2\\.so)","last_modified":1480349144745,"details":{"who":"All Firefox users who have installed the Java plugin, JRE versions below 1.6.0_31 or between 1.7.0 and 1.7.0_2.","created":"2012-04-02T15:18:50Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=739955","name":"Java Plugin","why":"Outdated versions of the Java plugin are vulnerable to an actively exploited security issue. All users are strongly encouraged to update their Java plugin. For more information, please read our blog post or Oracle's Advisory."},"versionRange":[{"targetApplication":[],"severity":1}],"matchDescription":"[^\\d\\._]((0(\\.\\d+(\\.\\d+([_\\.]\\d+)?)?)?)|(1\\.(([0-5](\\.\\d+([_\\.]\\d+)?)?)|(6(\\.0([_\\.](0?\\d|1\\d|2\\d|30))?)?)|(7(\\.0([_\\.][0-2])?)?))))([^\\d\\._]|$)","id":"34deed93-d9d9-81b4-7983-0594fb829ae7","schema":1480349144394},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p946","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349144384,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2015-07-13T16:01:04Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1182751","name":"Flash Player Plugin 18.0.0.203 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"18.0.0.203","maxVersion":"18.0.0.203","severity":0,"vulnerabilityStatus":1}],"id":"503ba184-168d-1fcd-9a4d-62a6f8a79d68","schema":1480343754054},{"matchName":"Java\\(TM\\) Plug-in 1\\.7\\.0(_0?7)?([^\\d\\._]|$)","blockID":"p210","enabled":true,"matchFilename":"libnpjp2\\.so","last_modified":1480349144360,"details":{"who":"All Firefox users who have the Java 7 plugin, updates 7 and below.","created":"2012-11-22T09:31:33Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=812896","name":"Java Plugin 1.7u7 (Linux)","why":"The Java 7 Runtime Environment, update version 7, has a serious security vulnerability that is fixed in the latest update. All Firefox users are strongly encouraged to update as soon as possible. This can be done on the Plugin Check page."},"versionRange":[{"targetApplication":[{"minVersion":"0.1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"17.*"},{"minVersion":"0.1","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"2.14.*"}],"severity":1}],"id":"8e562dba-7ae7-fa85-2c31-479c4e661056","schema":1480343754054},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p794","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349144337,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2014-12-11T05:48:53Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1109795","name":"Flash Player Plugin 10.3.183.66 to 13.0.0.258 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities (CVE-2014-9163). All users are strongly recommended to update their Flash plugin."},"versionRange":[{"targetApplication":[],"minVersion":"10.3.183.66","maxVersion":"13.0.0.258","severity":0,"vulnerabilityStatus":1}],"id":"a2933e35-58b8-6560-ba75-c763481ed59f","schema":1480343754054},{"blockID":"p328","enabled":true,"matchFilename":"Silverlight\\.plugin","last_modified":1480349144312,"details":{"who":"All Firefox users who have these versions of the plugin installed.","created":"2013-03-26T09:35:05Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=853629","name":"Silverlight for Mac OS X between 5.1 and 5.1.20124.* (click-to-play)","why":"Old versions of this plugin are potentially insecure and unstable. All affected users should visit the plugin check page to look for updates for their Silverlight plugin."},"versionRange":[{"targetApplication":[{"minVersion":"19.0a1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"},{"minVersion":"2.16a1","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"},{"minVersion":"17.0.4","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"17.0.*"}],"minVersion":"5.1","maxVersion":"5.1.20124.9999","severity":0,"vulnerabilityStatus":1}],"id":"dd81b232-09cb-e31d-ed8b-c5cc6ea28dd0","schema":1480343754054},{"infoURL":"https://java.com/","blockID":"p1052","enabled":true,"matchFilename":"JavaAppletPlugin\\.plugin","last_modified":1480349144290,"details":{"who":"All users who have this version of the plugin installed.","created":"2015-11-06T13:30:02Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=829111","name":"Java Plugin 7 update 11 (click-to-play), Mac OS X","why":"The Java plugin is causing significant security problems. All users are strongly recommended to keep the plugin disabled unless necessary."},"versionRange":[{"targetApplication":[],"minVersion":"Java 7 Update 11","maxVersion":"Java 7 Update 11","severity":0,"vulnerabilityStatus":1}],"id":"c62a171f-7564-734f-0310-bae88c3baf85","schema":1480343754054},{"matchName":"Java\\(TM\\) Plug-in 1\\.(6\\.0_(\\d|[0-2]\\d?|3[0-2])|7\\.0(_0?([1-4]))?)([^\\d\\._]|$)","blockID":"p119","enabled":true,"matchFilename":"libnpjp2\\.so","last_modified":1480349144265,"details":{"who":"All Firefox users who have installed the Java plugin, JRE versions below 1.6.0_33 or between 1.7.0 and 1.7.0_4.","created":"2012-08-14T09:27:32Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=780717","name":"Java Plugin","why":"Outdated versions of the Java plugin are vulnerable to an actively exploited security issue. All users are strongly encouraged to update their Java plugin. For more information, please read our blog post or Oracle's Advisory."},"versionRange":[{"targetApplication":[{"minVersion":"0.1","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"17.*"},{"minVersion":"0.1","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"2.14.*"}],"severity":1}],"id":"d1aa9366-d40b-a68d-b3ed-4b36e4939442","schema":1480343754054},{"infoURL":"https://java.com/","matchName":"Java(\\(TM\\))? Plug-in 10\\.(4[5-9]|(5|6)\\d|7[0-8])(\\.[0-9]+)?([^\\d\\._]|$)","blockID":"p910","enabled":true,"matchFilename":"libnpjp2\\.so","last_modified":1480349144233,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2015-05-19T09:04:46Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1159917","name":"Java Plugin 7 update 45 to 78 (click-to-play), Linux","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[],"severity":0,"vulnerabilityStatus":1}],"id":"f322be12-1b08-0d57-ed51-f7a6d6ec2c17","schema":1480343754054},{"blockID":"p428","enabled":true,"matchFilename":"np[dD]eployJava1\\.dll","last_modified":1480349144210,"details":{"who":"All Firefox users who have this plugin installed.","created":"2013-07-18T15:39:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=636633","name":"Java Deployment Toolkit (click-to-play)","why":"The Java Deployment Toolkit plugin is known to be insecure and is unnecessary in most cases. Users should keep it disabled unless strictly necessary."},"versionRange":[{"targetApplication":[],"severity":0,"vulnerabilityStatus":2}],"id":"d30a5b90-b84a-dfec-6147-fc04700a0d8b","schema":1480343754054},{"blockID":"p416","enabled":true,"matchFilename":"JavaAppletPlugin\\.plugin","last_modified":1480349144187,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2013-06-28T12:44:58Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=885362","name":"Java Plugin 6 updates 42 to 45 (click-to-play), Mac OS X","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[{"minVersion":"17.0","guid":"{ec8030f7-c20a-464f-9b0e-13a3a9e97384}","maxVersion":"*"},{"minVersion":"2.14","guid":"{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}","maxVersion":"*"}],"minVersion":"Java 6 Update 42","maxVersion":"Java 6 Update 45","severity":0,"vulnerabilityStatus":1}],"id":"02a5865d-f6ea-a330-674e-7dea7390680f","schema":1480343754054},{"blockID":"p594","enabled":true,"matchFilename":"npCiscoWebCommunicator\\.dll","last_modified":1480349144164,"details":{"who":"All Firefox users who have installed a version of the Cisco Web Communicator plugin lower than 3.0.6.","created":"2014-06-11T16:49:00Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=980355","name":"Cisco Web Communicator < 3.0.6 (Windows)","why":"Versions lower than 3.0.6 of the Cisco Web Communicator plugin are known to have security issues and should not be used. All users should update to version 3.0.6 or later. Find updates here."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"3.0.5.99999999999999","severity":0,"vulnerabilityStatus":1}],"id":"f11f91d6-f65e-8a05-310b-ad20494a868a","schema":1480343754054},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p938","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349144141,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2015-07-10T13:37:02Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1181458","name":"Flash Player Plugin 18.0.0.194 to 18.0.0.202 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"18.0.0.194","maxVersion":"18.0.0.202","severity":0,"vulnerabilityStatus":1}],"id":"1b954bda-3ae4-ce14-29fb-be2c94f1d89a","schema":1480343754054},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1226","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349144119,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-05-31T15:21:48Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1275307","name":"Flash Player Plugin 21.0.0.197 to 21.0.0.226 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"21.0.0.197","maxVersion":"21.0.0.226","severity":0,"vulnerabilityStatus":1}],"id":"8478742b-e3a9-aa23-c9a6-dc9c3cb90291","schema":1480343754054},{"infoURL":"https://java.com/","matchName":"Java(\\(TM\\))? Plug-in 11\\.(4[6-9]|5\\d|6[0-4])(\\.[0-9]+)?([^\\d\\._]|$)","blockID":"p1064","enabled":true,"matchFilename":"libnpjp2\\.so","last_modified":1480349144096,"details":{"who":"All users who have these versions of the Java plugin installed.","created":"2015-12-02T12:42:34Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1217932","name":"Java Plugin 8 update 46 to 64 (click-to-play), Linux","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[],"severity":0,"vulnerabilityStatus":1}],"id":"d5cb1745-d144-5375-f3ff-cd603d4c2cee","schema":1480343754054},{"infoURL":"https://java.com/","matchName":"Java\\(TM\\) Platform SE 7 U(4[5-9]|(5|6)\\d|7[0-8])(\\s[^\\d\\._U]|$)","blockID":"p906","enabled":true,"matchFilename":"npjp2\\.dll","last_modified":1480349144073,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2015-05-19T09:02:45Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1159917","name":"Java Plugin 7 update 45 to 78 (click-to-play), Windows","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[],"severity":0,"vulnerabilityStatus":1}],"id":"f254e5bc-12c7-7954-fe6b-8f1fdab0ae88","schema":1480343754054},{"blockID":"p240","enabled":true,"matchFilename":"DivXBrowserPlugin\\.plugin","last_modified":1480349144049,"details":{"who":"All Firefox users who have versions of the DivX Web Player plugin lower than 1.4.","created":"2012-12-19T13:03:27Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=821972","name":"DivX Web Player 1.4 (DivX 7) and below","why":"Old versions of the DivX Web Player plugin are causing significant stability problems on Firefox 18 and above, on Mac OS X. All users should update their DivX software to the latest available version, available at divx.com."},"versionRange":[{"targetApplication":[],"minVersion":"0","maxVersion":"1.4","severity":1}],"id":"d7f644bb-61aa-4594-f9fc-8dba7d9f3306","schema":1480343754054},{"infoURL":"https://java.com/","matchName":"Java(\\(TM\\))? Plug-in 10\\.(79|80)(\\.[0-9]+)?([^\\d\\._]|$)","blockID":"p962","enabled":true,"matchFilename":"libnpjp2\\.so","last_modified":1480349144026,"details":{"who":"All users who have these versions of the Java plugin installed.","created":"2015-07-15T10:51:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1183369","name":"Java Plugin 7 update 79 to 80 (click-to-play), Linux","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[],"severity":0,"vulnerabilityStatus":1}],"id":"7120e3c2-b293-65b5-2498-6451eab1e2c5","schema":1480343754054},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p936","enabled":true,"matchFilename":"libflashplayer\\.so","last_modified":1480349144002,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2015-07-10T13:35:04Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1181458","name":"Flash Player Plugin on Linux 11.2.202.468 to 11.2.202.480 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"11.2.202.468","maxVersion":"11.2.202.480","severity":0,"vulnerabilityStatus":1}],"os":"Linux","id":"44b7040d-1567-110d-6ec5-44673c052bd8","schema":1480343754054},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1028","enabled":true,"matchFilename":"libflashplayer\\.so","last_modified":1480349143976,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2015-10-01T09:50:47Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1206889","name":"Flash Player Plugin on Linux 11.2.202.482 to 11.2.202.508 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"11.2.202.482","maxVersion":"11.2.202.508","severity":0,"vulnerabilityStatus":1}],"os":"Linux","id":"0cc10d08-5e0c-47ea-614a-61f0f4a765d0","schema":1480343754054},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p940","enabled":true,"matchFilename":"(NPSWF32.*\\.dll)|(NPSWF64.*\\.dll)|(Flash\\ Player\\.plugin)","last_modified":1480349143953,"details":{"who":"All users who have these versions of the plugin installed in Firefox.","created":"2015-07-10T13:38:10Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1181458","name":"Flash Player Plugin 13.0.0.296 to 13.0.0.301 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"13.0.0.296","maxVersion":"13.0.0.301","severity":0,"vulnerabilityStatus":1}],"id":"de82ceab-e70e-06f4-3b83-8c7a4c99c589","schema":1480343754054},{"infoURL":"https://java.com/","matchName":"Java\\(TM\\) Platform SE 8 U(4[6-9]|5\\d|6[0-4])(\\s[^\\d\\._U]|$)","blockID":"p1062","enabled":true,"matchFilename":"npjp2\\.dll","last_modified":1480349143930,"details":{"who":"All users who have these versions of the Java plugin installed.","created":"2015-12-02T12:40:28Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1217932","name":"Java Plugin 8 update 46 to 64 (click-to-play), Windows","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[],"severity":0,"vulnerabilityStatus":1}],"id":"a20c77af-721b-833b-8fa8-49091d1c69d4","schema":1480343754054},{"infoURL":"https://java.com/","matchName":"Java\\(TM\\) Platform SE 7 U(9[1-7])(\\s[^\\d\\._U]|$)","blockID":"p1143","enabled":true,"matchFilename":"npjp2\\.dll","last_modified":1480349143905,"details":{"who":"All users who have these versions of the Java plugin installed.","created":"2016-03-31T16:17:32Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1259458","name":"Java Plugin 7 update 91 to 97 (click-to-play), Windows","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[],"severity":0,"vulnerabilityStatus":1}],"id":"be53f658-e719-fa77-e7fe-6bd6086f888e","schema":1480343754054},{"infoURL":"https://java.com/","blockID":"p954","enabled":true,"matchFilename":"JavaAppletPlugin\\.plugin","last_modified":1480349143879,"details":{"who":"All users who have these versions of the Java plugin installed.","created":"2015-07-15T10:47:55Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1183369","name":"Java Plugin 7 update 79 to 80 (click-to-play), Mac OS X","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"Java 7 Update 79","maxVersion":"Java 7 Update 80","severity":0,"vulnerabilityStatus":1}],"id":"9b6830b4-a4b0-ee63-ee21-e0bd6ba0d6fe","schema":1480343754054},{"infoURL":"https://get.adobe.com/reader","blockID":"p1246","enabled":true,"matchFilename":"(nppdf32\\.dll)|(AdobePDFViewerNPAPI\\.plugin)","last_modified":1480349143855,"details":{"who":"All users who have this plugin installed.","created":"2016-07-20T19:19:58Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1286972","name":"Adobe Reader 10.1.6 to 11.0.16","why":"Old versions of the Adobe Reader plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"10.1.6","maxVersion":"11.0.16 ","severity":0,"vulnerabilityStatus":1}],"id":"4e29bd83-d074-bd40-f238-5ea38ff0d8d0","schema":1480343754054},{"infoURL":"https://java.com/","matchName":"Java(\\(TM\\))? Plug-in 10\\.(8[1-9]|90)(\\.[0-9]+)?([^\\d\\._]|$)","blockID":"p1063","enabled":true,"matchFilename":"libnpjp2\\.so","last_modified":1480349143832,"details":{"who":"All users who have these versions of the Java plugin installed.","created":"2015-12-02T12:41:34Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1217932","name":"Java Plugin 7 update 81 to 90 (click-to-play), Linux","why":"Old versions of the Java plugin are potentially insecure and unstable. All users are strongly recommended to update on our plugin check page."},"versionRange":[{"targetApplication":[],"severity":0,"vulnerabilityStatus":1}],"id":"b6b9c6b9-b8c4-66a9-ed07-125b32e7a5ef","schema":1480343754054},{"infoURL":"https://get.adobe.com/flashplayer/","blockID":"p1138","enabled":true,"matchFilename":"libflashplayer\\.so","last_modified":1480349143807,"details":{"who":"All users who have these versions of the Flash plugin installed.","created":"2016-03-18T15:33:12Z","bug":"https://bugzilla.mozilla.org/show_bug.cgi?id=1255519","name":"Flash Player Plugin on Linux 11.2.202.559 to 11.2.202.569 (click-to-play)","why":"Old versions of the Flash Player plugin have known vulnerabilities. All users are strongly recommended to check for updates on our plugin check page."},"versionRange":[{"targetApplication":[],"minVersion":"11.2.202.559","maxVersion":"11.2.202.569","severity":0,"vulnerabilityStatus":1}],"os":"Linux","id":"f7b02575-c0a6-2198-dc9f-5deadbcccbb2","schema":1480343754054}]} \ No newline at end of file diff --git a/services/blocklists/readme.md b/services/blocklists/readme.md new file mode 100644 index 000000000000..659798101a1d --- /dev/null +++ b/services/blocklists/readme.md @@ -0,0 +1,29 @@ +# Blocklist + +The blocklist entries are synchronized locally from the Firefox Settings service. + +https://firefox.settings.services.mozilla.com + +In order to reduce the amount of data to be downloaded on first synchronization, +a JSON dump from the records present on the remote server is shipped with the +release. + +## How to update the JSON files ? + +Even though it is not a problem if the dumps are not up-to-date when shipped, here +are the commands to update them: + +``` +SERVICE_URL="https://firefox.settings.services.mozilla.com/v1" + +curl "$SERVICE_URL/buckets/blocklists/collections/certificates/records?" > services/blocklists/certificates.json +curl "$SERVICE_URL/buckets/blocklists/collections/gfx/records?" > services/blocklists/gfx.json +curl "$SERVICE_URL/buckets/blocklists/collections/plugins/records?" > services/blocklists/plugins.json +curl "$SERVICE_URL/buckets/blocklists/collections/addons/records?" > services/blocklists/addons.json + +curl "$SERVICE_URL/buckets/pinning/collections/pins/records?" > services/blocklists/pins.json +``` + +## TODO + +- Setup a bot to update it regularly. diff --git a/services/common/blocklist-clients.js b/services/common/blocklist-clients.js index a9bded3655fa..87f90945694e 100644 --- a/services/common/blocklist-clients.js +++ b/services/common/blocklist-clients.js @@ -7,15 +7,13 @@ this.EXPORTED_SYMBOLS = ["AddonBlocklistClient", "GfxBlocklistClient", "OneCRLBlocklistClient", - "PluginBlocklistClient", "PinningBlocklistClient", - "FILENAME_ADDONS_JSON", - "FILENAME_GFX_JSON", - "FILENAME_PLUGINS_JSON"]; + "PluginBlocklistClient"]; const { classes: Cc, interfaces: Ci, utils: Cu } = Components; Cu.import("resource://gre/modules/Services.jsm"); +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); const { Task } = Cu.import("resource://gre/modules/Task.jsm", {}); const { OS } = Cu.import("resource://gre/modules/osfile.jsm", {}); Cu.importGlobalProperties(["fetch"]); @@ -25,6 +23,9 @@ const { KintoHttpClient } = Cu.import("resource://services-common/kinto-http-cli const { FirefoxAdapter } = Cu.import("resource://services-common/kinto-storage-adapter.js", {}); const { CanonicalJSON } = Components.utils.import("resource://gre/modules/CanonicalJSON.jsm", {}); +XPCOMUtils.defineLazyModuleGetter(this, "FileUtils", "resource://gre/modules/FileUtils.jsm"); + +const KEY_APPDIR = "XCurProcD"; const PREF_SETTINGS_SERVER = "services.settings.server"; const PREF_BLOCKLIST_BUCKET = "services.blocklist.bucket"; const PREF_BLOCKLIST_ONECRL_COLLECTION = "services.blocklist.onecrl.collection"; @@ -48,9 +49,6 @@ const INVALID_SIGNATURE = "Invalid content/signature"; // filename, even though it isn't descriptive of who is using it. this.KINTO_STORAGE_PATH = "kinto.sqlite"; -this.FILENAME_ADDONS_JSON = "blocklist-addons.json"; -this.FILENAME_GFX_JSON = "blocklist-gfx.json"; -this.FILENAME_PLUGINS_JSON = "blocklist-plugins.json"; function mergeChanges(collection, localRecords, changes) { @@ -104,6 +102,29 @@ class BlocklistClient { }); } + get filename() { + return `${this.bucketName}/${this.collectionName}.json`; + } + + /** + * Load the the JSON file distributed with the release for this blocklist. + * + * For Bug 1257565 this method will have to try to load the file from the profile, + * in order to leverage the updateJSONBlocklist() below, which writes a new + * dump each time the collection changes. + */ + loadDumpFile() { + const fileURI = `resource://app/defaults/${this.filename}`; + return Task.spawn(function* loadFile() { + const response = yield fetch(fileURI); + if (!response.ok) { + throw new Error(`Could not read from '${fileURI}'`); + } + // Will be rejected if JSON is invalid. + return yield response.json(); + }); + } + validateCollectionSignature(remote, payload, collection, options = {}) { const {ignoreLocal} = options; @@ -145,14 +166,17 @@ class BlocklistClient { /** * Synchronize from Kinto server, if necessary. * - * @param {int} lastModified the lastModified date (on the server) for - the remote collection. - * @param {Date} serverTime the current date return by the server. - * @return {Promise} which rejects on sync or process failure. + * @param {int} lastModified the lastModified date (on the server) for + the remote collection. + * @param {Date} serverTime the current date return by the server. + * @param {Object} options additional advanced options. + * @param {bool} options.loadDump load initial dump from disk on first sync (default: true) + * @return {Promise} which rejects on sync or process failure. */ - maybeSync(lastModified, serverTime) { + maybeSync(lastModified, serverTime, options = {loadDump: true}) { + const {loadDump} = options; const remote = Services.prefs.getCharPref(PREF_SETTINGS_SERVER); - let enforceCollectionSigning = + const enforceCollectionSigning = Services.prefs.getBoolPref(PREF_BLOCKLIST_ENFORCE_SIGNING); // if there is a signerName and collection signing is enforced, add a @@ -177,13 +201,30 @@ class BlocklistClient { }; const collection = this._kinto.collection(this.collectionName, options); - const collectionLastModified = yield collection.db.getLastModified(); + let collectionLastModified = yield collection.db.getLastModified(); + + // If there is no data currently in the collection, attempt to import + // initial data from the application defaults. + // This allows to avoid synchronizing the whole collection content on + // cold start. + if (!collectionLastModified && loadDump) { + try { + const initialData = yield this.loadDumpFile(); + yield collection.db.loadDump(initialData.data); + collectionLastModified = yield collection.db.getLastModified(); + } catch (e) { + // Report but go-on. + Cu.reportError(e); + } + } + // If the data is up to date, there's no need to sync. We still need // to record the fact that a check happened. if (lastModified <= collectionLastModified) { this.updateLastCheck(serverTime); return; } + // Fetch changes from server. try { const {ok} = yield collection.sync({remote}); @@ -315,10 +356,13 @@ function* updatePinningList(records) { function* updateJSONBlocklist(filename, records) { // Write JSON dump for synchronous load at startup. const path = OS.Path.join(OS.Constants.Path.profileDir, filename); + const blocklistFolder = OS.Path.dirname(path); + + yield OS.File.makeDir(blocklistFolder, {from: OS.Constants.Path.profileDir}); + const serialized = JSON.stringify({data: records}, null, 2); try { yield OS.File.writeAtomic(path, serialized, {tmpPath: path + ".tmp"}); - // Notify change to `nsBlocklistService` const eventData = {filename}; Services.cpmm.sendAsyncMessage("Blocklist:reload-from-disk", eventData); @@ -338,21 +382,21 @@ this.OneCRLBlocklistClient = new BlocklistClient( this.AddonBlocklistClient = new BlocklistClient( Services.prefs.getCharPref(PREF_BLOCKLIST_ADDONS_COLLECTION), PREF_BLOCKLIST_ADDONS_CHECKED_SECONDS, - updateJSONBlocklist.bind(undefined, FILENAME_ADDONS_JSON), + (records) => updateJSONBlocklist(this.AddonBlocklistClient.filename, records), Services.prefs.getCharPref(PREF_BLOCKLIST_BUCKET) ); this.GfxBlocklistClient = new BlocklistClient( Services.prefs.getCharPref(PREF_BLOCKLIST_GFX_COLLECTION), PREF_BLOCKLIST_GFX_CHECKED_SECONDS, - updateJSONBlocklist.bind(undefined, FILENAME_GFX_JSON), + (records) => updateJSONBlocklist(this.GfxBlocklistClient.filename, records), Services.prefs.getCharPref(PREF_BLOCKLIST_BUCKET) ); this.PluginBlocklistClient = new BlocklistClient( Services.prefs.getCharPref(PREF_BLOCKLIST_PLUGINS_COLLECTION), PREF_BLOCKLIST_PLUGINS_CHECKED_SECONDS, - updateJSONBlocklist.bind(undefined, FILENAME_PLUGINS_JSON), + (records) => updateJSONBlocklist(this.PluginBlocklistClient.filename, records), Services.prefs.getCharPref(PREF_BLOCKLIST_BUCKET) ); diff --git a/services/common/tests/unit/test_blocklist_certificates.js b/services/common/tests/unit/test_blocklist_certificates.js index 96e6cec10fcf..392bc1b59ece 100644 --- a/services/common/tests/unit/test_blocklist_certificates.js +++ b/services/common/tests/unit/test_blocklist_certificates.js @@ -12,9 +12,10 @@ const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1", let server; // set up what we need to make storage adapters -const kintoFilename = "kinto.sqlite"; +let sqliteHandle; +const KINTO_FILENAME = "kinto.sqlite"; -function do_get_kinto_collection(collectionName, sqliteHandle) { +function do_get_kinto_collection(collectionName) { let config = { // Set the remote to be some server that will cause test failure when // hit since we should never hit the server directly, only via maybeSync() @@ -35,8 +36,8 @@ add_task(function* test_something() { const configPath = "/v1/"; const recordsPath = "/v1/buckets/blocklists/collections/certificates/records"; - Services.prefs.setCharPref("services.settings.server", - `http://localhost:${server.identity.primaryPort}/v1`); + const dummyServerURL = `http://localhost:${server.identity.primaryPort}/v1`; + Services.prefs.setCharPref("services.settings.server", dummyServerURL); // register a handler function handleResponse(request, response) { @@ -66,24 +67,45 @@ add_task(function* test_something() { // Test an empty db populates yield OneCRLBlocklistClient.maybeSync(2000, Date.now()); + sqliteHandle = yield FirefoxAdapter.openConnection({path: KINTO_FILENAME}); + const collection = do_get_kinto_collection("certificates"); + // Open the collection, verify it's been populated: - // Our test data has a single record; it should be in the local collection - let sqliteHandle = yield FirefoxAdapter.openConnection({path: kintoFilename}); - let collection = do_get_kinto_collection("certificates", sqliteHandle); let list = yield collection.list(); + // We know there will be initial values from the JSON dump. + // (at least as many as in the dump shipped when this test was written). + do_check_true(list.data.length >= 363); + + // No sync will be intented if maybeSync() is up-to-date. + Services.prefs.clearUserPref("services.settings.server"); + Services.prefs.setIntPref("services.blocklist.onecrl.checked", 0); + // Use any last_modified older than highest shipped in JSON dump. + yield OneCRLBlocklistClient.maybeSync(123456, Date.now()); + // Last check value was updated. + do_check_neq(0, Services.prefs.getIntPref("services.blocklist.onecrl.checked")); + + // Restore server pref. + Services.prefs.setCharPref("services.settings.server", dummyServerURL); + // clear the collection, save a non-zero lastModified so we don't do + // import of initial data when we sync again. + yield collection.clear(); + // a lastModified value of 1000 means we get a remote collection with a + // single record + yield collection.db.saveLastModified(1000); + yield OneCRLBlocklistClient.maybeSync(2000, Date.now()); + + // Open the collection, verify it's been updated: + // Our test data now has two records; both should be in the local collection + list = yield collection.list(); do_check_eq(list.data.length, 1); - yield sqliteHandle.close(); // Test the db is updated when we call again with a later lastModified value yield OneCRLBlocklistClient.maybeSync(4000, Date.now()); // Open the collection, verify it's been updated: // Our test data now has two records; both should be in the local collection - sqliteHandle = yield FirefoxAdapter.openConnection({path: kintoFilename}); - collection = do_get_kinto_collection("certificates", sqliteHandle); list = yield collection.list(); do_check_eq(list.data.length, 3); - yield sqliteHandle.close(); // Try to maybeSync with the current lastModified value - no connection // should be attempted. @@ -104,8 +126,7 @@ add_task(function* test_something() { // Check that a sync completes even when there's bad data in the // collection. This will throw on fail, so just calling maybeSync is an // acceptible test. - Services.prefs.setCharPref("services.settings.server", - `http://localhost:${server.identity.primaryPort}/v1`); + Services.prefs.setCharPref("services.settings.server", dummyServerURL); yield OneCRLBlocklistClient.maybeSync(5000, Date.now()); }); @@ -122,6 +143,7 @@ function run_test() { do_register_cleanup(function() { server.stop(() => { }); + return sqliteHandle.close(); }); } @@ -150,6 +172,17 @@ function getSampleResponse(req, port) { "responseBody": JSON.stringify({"settings":{"batch_max_requests":25}, "url":`http://localhost:${port}/v1/`, "documentation":"https://kinto.readthedocs.org/", "version":"1.5.1", "commit":"cbc6f58", "hello":"kinto"}) }, "GET:/v1/buckets/blocklists/collections/certificates/records?_sort=-last_modified": { + "sampleHeaders": [ + "Access-Control-Allow-Origin: *", + "Access-Control-Expose-Headers: Retry-After, Content-Length, Alert, Backoff", + "Content-Type: application/json; charset=UTF-8", + "Server: waitress", + "Etag: \"1000\"" + ], + "status": {status: 200, statusText: "OK"}, + "responseBody": JSON.stringify({"data":[{}]}) + }, + "GET:/v1/buckets/blocklists/collections/certificates/records?_sort=-last_modified&_since=1000": { "sampleHeaders": [ "Access-Control-Allow-Origin: *", "Access-Control-Expose-Headers: Retry-After, Content-Length, Alert, Backoff", diff --git a/services/common/tests/unit/test_blocklist_clients.js b/services/common/tests/unit/test_blocklist_clients.js index 997b590f7863..9fa1f0427c34 100644 --- a/services/common/tests/unit/test_blocklist_clients.js +++ b/services/common/tests/unit/test_blocklist_clients.js @@ -17,9 +17,9 @@ const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1", const kintoFilename = "kinto.sqlite"; const gBlocklistClients = [ - {client: BlocklistClients.AddonBlocklistClient, filename: BlocklistClients.FILENAME_ADDONS_JSON, testData: ["i808", "i720", "i539"]}, - {client: BlocklistClients.PluginBlocklistClient, filename: BlocklistClients.FILENAME_PLUGINS_JSON, testData: ["p1044", "p32", "p28"]}, - {client: BlocklistClients.GfxBlocklistClient, filename: BlocklistClients.FILENAME_GFX_JSON, testData: ["g204", "g200", "g36"]}, + {client: BlocklistClients.AddonBlocklistClient, testData: ["i808", "i720", "i539"]}, + {client: BlocklistClients.PluginBlocklistClient, testData: ["p1044", "p32", "p28"]}, + {client: BlocklistClients.GfxBlocklistClient, testData: ["g204", "g200", "g36"]}, ]; @@ -57,14 +57,10 @@ function* clear_state() { } finally { yield sqliteHandle.close(); } - } - // Remove profile data. - for (let {filename} of gBlocklistClients) { - const blocklist = FileUtils.getFile(KEY_PROFILEDIR, [filename]); - if (blocklist.exists()) { - blocklist.remove(true); - } + // Remove profile data. + const path = OS.Path.join(OS.Constants.Path.profileDir, client.filename); + yield OS.File.remove(path, { ignoreAbsent: true }); } } @@ -121,7 +117,7 @@ function run_test() { add_task(function* test_records_obtained_from_server_are_stored_in_db() { for (let {client} of gBlocklistClients) { // Test an empty db populates - yield client.maybeSync(2000, Date.now()); + yield client.maybeSync(2000, Date.now(), {loadDump: false}); // Open the collection, verify it's been populated: // Our test data has a single record; it should be in the local collection @@ -135,11 +131,11 @@ add_task(function* test_records_obtained_from_server_are_stored_in_db() { add_task(clear_state); add_task(function* test_list_is_written_to_file_in_profile() { - for (let {client, filename, testData} of gBlocklistClients) { - const profFile = FileUtils.getFile(KEY_PROFILEDIR, [filename]); + for (let {client, testData} of gBlocklistClients) { + const profFile = FileUtils.getFile(KEY_PROFILEDIR, client.filename.split("/")); strictEqual(profFile.exists(), false); - yield client.maybeSync(2000, Date.now()); + yield client.maybeSync(2000, Date.now(), {loadDump: false}); strictEqual(profFile.exists(), true); const content = yield readJSON(profFile.path); @@ -159,9 +155,9 @@ add_task(function* test_current_server_time_is_saved_in_pref() { add_task(clear_state); add_task(function* test_update_json_file_when_addons_has_changes() { - for (let {client, filename, testData} of gBlocklistClients) { - yield client.maybeSync(2000, Date.now() - 1000); - const profFile = FileUtils.getFile(KEY_PROFILEDIR, [filename]); + for (let {client, testData} of gBlocklistClients) { + yield client.maybeSync(2000, Date.now() - 1000, {loadDump: false}); + const profFile = FileUtils.getFile(KEY_PROFILEDIR, client.filename.split("/")); const fileLastModified = profFile.lastModifiedTime = profFile.lastModifiedTime - 1000; const serverTime = Date.now(); @@ -179,24 +175,24 @@ add_task(function* test_update_json_file_when_addons_has_changes() { add_task(clear_state); add_task(function* test_sends_reload_message_when_blocklist_has_changes() { - for (let {client, filename} of gBlocklistClients) { + for (let {client} of gBlocklistClients) { let received = yield new Promise((resolve, reject) => { Services.ppmm.addMessageListener("Blocklist:reload-from-disk", { receiveMessage(aMsg) { resolve(aMsg) } }); - client.maybeSync(2000, Date.now() - 1000); + client.maybeSync(2000, Date.now() - 1000, {loadDump: false}); }); - equal(received.data.filename, filename); + equal(received.data.filename, client.filename); } }); add_task(clear_state); add_task(function* test_do_nothing_when_blocklist_is_up_to_date() { - for (let {client, filename} of gBlocklistClients) { - yield client.maybeSync(2000, Date.now() - 1000); - const profFile = FileUtils.getFile(KEY_PROFILEDIR, [filename]); + for (let {client} of gBlocklistClients) { + yield client.maybeSync(2000, Date.now() - 1000, {loadDump: false}); + const profFile = FileUtils.getFile(KEY_PROFILEDIR, client.filename.split("/")); const fileLastModified = profFile.lastModifiedTime = profFile.lastModifiedTime - 1000; const serverTime = Date.now(); diff --git a/services/common/tests/unit/test_blocklist_signatures.js b/services/common/tests/unit/test_blocklist_signatures.js index ca1f46306a11..f84f18bf299e 100644 --- a/services/common/tests/unit/test_blocklist_signatures.js +++ b/services/common/tests/unit/test_blocklist_signatures.js @@ -294,7 +294,8 @@ add_task(function* test_check_signatures() { // With all of this set up, we attempt a sync. This will resolve if all is // well and throw if something goes wrong. - yield OneCRLBlocklistClient.maybeSync(1000, startTime); + // We don't want to load initial json dumps in this test suite. + yield OneCRLBlocklistClient.maybeSync(1000, startTime, {loadDump: false}); // Check that some additions (2 records) to the collection have a valid // signature. diff --git a/services/common/tests/unit/xpcshell.ini b/services/common/tests/unit/xpcshell.ini index 474883eee311..f9f49897803d 100644 --- a/services/common/tests/unit/xpcshell.ini +++ b/services/common/tests/unit/xpcshell.ini @@ -9,6 +9,8 @@ support-files = [test_load_modules.js] [test_blocklist_certificates.js] +# Initial JSON data for blocklists are not shipped on Android. +skip-if = os == "android" [test_blocklist_clients.js] [test_blocklist_updater.js] [test_blocklist_pinning.js] diff --git a/services/moz.build b/services/moz.build index 2109d512a5a7..b8230ecc94ff 100644 --- a/services/moz.build +++ b/services/moz.build @@ -10,7 +10,10 @@ DIRS += [ ] if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'android': - DIRS += ['fxaccounts'] + DIRS += [ + 'fxaccounts', + 'blocklists', + ] if CONFIG['MOZ_SERVICES_SYNC']: DIRS += ['sync'] diff --git a/tools/lint/eslint/modules.json b/tools/lint/eslint/modules.json index 258d70f2b9d7..6d8dab647f82 100644 --- a/tools/lint/eslint/modules.json +++ b/tools/lint/eslint/modules.json @@ -17,7 +17,7 @@ "AsyncSpellCheckTestHelper.jsm": ["onSpellCheck"], "AutoMigrate.jsm": ["AutoMigrate"], "Battery.jsm": ["GetBattery", "Battery"], - "blocklist-clients.js": ["AddonBlocklistClient", "GfxBlocklistClient", "OneCRLBlocklistClient", "PluginBlocklistClient", "FILENAME_ADDONS_JSON", "FILENAME_GFX_JSON", "FILENAME_PLUGINS_JSON"], + "blocklist-clients.js": ["AddonBlocklistClient", "GfxBlocklistClient", "OneCRLBlocklistClient", "PluginBlocklistClient"], "blocklist-updater.js": ["checkVersions", "addTestBlocklistClient"], "bogus_element_type.jsm": [], "bookmark_validator.js": ["BookmarkValidator", "BookmarkProblemData"], From f06e779e2dcb70247cfdc6af07bade80abf20809 Mon Sep 17 00:00:00 2001 From: Jamie Nicol Date: Thu, 9 Feb 2017 18:00:32 +0000 Subject: [PATCH 019/234] Bug 1339578 - Remove min active layer size for animations; r=mattwoodrow Even for very small layers we want to avoid doing work on the main thread. At the same time, however, increase the minimum active layer size for animations which come from restyles. These involve the main thread anyway, so there is less to be gained from using an active layer. Since switching items between active and inactive can have large knock-on effects, we want to make sure it really is worth making the layer active. MozReview-Commit-ID: 8N6xlVW4Dp3 --HG-- extra : rebase_source : bd9a97899faaf187e5e148126711bb0ff5a29ee6 --- devtools/server/tests/browser/animation.html | 4 +- dom/animation/AnimationPerformanceWarning.cpp | 7 -- dom/animation/AnimationPerformanceWarning.h | 1 - .../file_animation_performance_warning.html | 10 ++- .../chrome/layout/layout_errors.properties | 3 - gfx/thebes/gfxPrefs.h | 1 + layout/painting/nsDisplayList.cpp | 64 +++++++------------ 7 files changed, 29 insertions(+), 61 deletions(-) diff --git a/devtools/server/tests/browser/animation.html b/devtools/server/tests/browser/animation.html index d10a9873dda4..01847ac61446 100644 --- a/devtools/server/tests/browser/animation.html +++ b/devtools/server/tests/browser/animation.html @@ -12,8 +12,8 @@ .simple-animation { display: inline-block; - width: 50px; - height: 50px; + width: 64px; + height: 64px; border-radius: 50%; background: red; diff --git a/dom/animation/AnimationPerformanceWarning.cpp b/dom/animation/AnimationPerformanceWarning.cpp index 3214de1aaa17..02368a30e81c 100644 --- a/dom/animation/AnimationPerformanceWarning.cpp +++ b/dom/animation/AnimationPerformanceWarning.cpp @@ -33,13 +33,6 @@ AnimationPerformanceWarning::ToLocalizedString( const char* key = nullptr; switch (mType) { - case Type::ContentTooSmall: - MOZ_ASSERT(mParams && mParams->Length() == 2, - "Parameter's length should be 2 for ContentTooSmall"); - - return NS_SUCCEEDED( - ToLocalizedStringWithIntParams<2>( - "CompositorAnimationWarningContentTooSmall", aLocalizedString)); case Type::ContentTooLarge: MOZ_ASSERT(mParams && mParams->Length() == 6, "Parameter's length should be 6 for ContentTooLarge"); diff --git a/dom/animation/AnimationPerformanceWarning.h b/dom/animation/AnimationPerformanceWarning.h index 914af1352028..5c3649c00ce0 100644 --- a/dom/animation/AnimationPerformanceWarning.h +++ b/dom/animation/AnimationPerformanceWarning.h @@ -20,7 +20,6 @@ namespace mozilla { struct AnimationPerformanceWarning { enum class Type : uint8_t { - ContentTooSmall, ContentTooLarge, TransformBackfaceVisibilityHidden, TransformPreserve3D, diff --git a/dom/animation/test/chrome/file_animation_performance_warning.html b/dom/animation/test/chrome/file_animation_performance_warning.html index 9f72bdc4d960..7033f1603720 100644 --- a/dom/animation/test/chrome/file_animation_performance_warning.html +++ b/dom/animation/test/chrome/file_animation_performance_warning.html @@ -840,7 +840,7 @@ function testMultipleAnimationsWithGeometricAnimations() { function testSmallElements() { [ { - desc: 'opacity on too small element', + desc: 'opacity on small element', frames: { opacity: [0, 1] }, @@ -855,13 +855,12 @@ function testSmallElements() { expected: [ { property: 'opacity', - runningOnCompositor: false, - warning: /Animation cannot be run on the compositor because frame size \(8, 8\) is smaller than \(16, 16\)/ + runningOnCompositor: true } ] }, { - desc: 'transform on too small element', + desc: 'transform on small element', frames: { transform: ['translate(0px)', 'translate(100px)'] }, @@ -869,8 +868,7 @@ function testSmallElements() { expected: [ { property: 'transform', - runningOnCompositor: false, - warning: /Animation cannot be run on the compositor because frame size \(8, 8\) is smaller than \(16, 16\)/ + runningOnCompositor: true } ] }, diff --git a/dom/locales/en-US/chrome/layout/layout_errors.properties b/dom/locales/en-US/chrome/layout/layout_errors.properties index 6f85dacb578a..d08fe6d6edba 100644 --- a/dom/locales/en-US/chrome/layout/layout_errors.properties +++ b/dom/locales/en-US/chrome/layout/layout_errors.properties @@ -11,9 +11,6 @@ ImageMapPolyOddNumberOfCoords=The “coords” attribute of the GetVisualOverflowRectRelativeToSelf().ToOutsidePixels( aFrame->PresContext()->AppUnitsPerDevPixel()); - static const int MIN_ACTIVE_LAYER_SIZE_DEV_PIXELS = 16; return visibleDevPixels.Size() < - nsIntSize(MIN_ACTIVE_LAYER_SIZE_DEV_PIXELS, MIN_ACTIVE_LAYER_SIZE_DEV_PIXELS); -} - -static void -SetAnimationPerformanceWarningForTooSmallItem(nsIFrame* aFrame, - nsCSSPropertyID aProperty) -{ - // We use ToNearestPixels() here since ToOutsidePixels causes some sort of - // errors. See https://bugzilla.mozilla.org/show_bug.cgi?id=1258904#c19 - nsIntRect visibleDevPixels = aFrame->GetVisualOverflowRectRelativeToSelf().ToNearestPixels( - aFrame->PresContext()->AppUnitsPerDevPixel()); - - // Set performance warning only if the visible dev pixels is not empty - // because dev pixels is empty if the frame has 'preserve-3d' style. - if (visibleDevPixels.IsEmpty()) { - return; - } - - EffectCompositor::SetPerformanceWarning(aFrame, aProperty, - AnimationPerformanceWarning( - AnimationPerformanceWarning::Type::ContentTooSmall, - { visibleDevPixels.Width(), visibleDevPixels.Height() })); + nsIntSize(gfxPrefs::LayoutMinActiveLayerSize(), + gfxPrefs::LayoutMinActiveLayerSize()); } /* static */ bool nsDisplayOpacity::NeedsActiveLayer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) { - if (ActiveLayerTracker::IsStyleAnimated(aBuilder, aFrame, - eCSSProperty_opacity) || - EffectCompositor::HasAnimationsForCompositor(aFrame, - eCSSProperty_opacity)) { - if (!IsItemTooSmallForActiveLayer(aFrame)) { - return true; - } - SetAnimationPerformanceWarningForTooSmallItem(aFrame, eCSSProperty_opacity); + if (EffectCompositor::HasAnimationsForCompositor(aFrame, + eCSSProperty_opacity) || + (ActiveLayerTracker::IsStyleAnimated(aBuilder, aFrame, + eCSSProperty_opacity) && + !IsItemTooSmallForActiveLayer(aFrame))) { + return true; } return false; } @@ -6881,17 +6858,20 @@ already_AddRefed nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBu bool nsDisplayTransform::MayBeAnimated(nsDisplayListBuilder* aBuilder) { - // Here we check if the *post-transform* bounds of this item are big enough - // to justify an active layer. - if (ActiveLayerTracker::IsStyleAnimated(aBuilder, - mFrame, - eCSSProperty_transform) || - EffectCompositor::HasAnimationsForCompositor(mFrame, - eCSSProperty_transform)) { - if (!IsItemTooSmallForActiveLayer(mFrame)) { - return true; - } - SetAnimationPerformanceWarningForTooSmallItem(mFrame, eCSSProperty_transform); + // If EffectCompositor::HasAnimationsForCompositor() is true then we can + // completely bypass the main thread for this animation, so it is always + // worthwhile. + // For ActiveLayerTracker::IsStyleAnimated() cases the main thread is + // already involved so there is less to be gained. + // Therefore we check that the *post-transform* bounds of this item are + // big enough to justify an active layer. + if (EffectCompositor::HasAnimationsForCompositor(mFrame, + eCSSProperty_transform) || + (ActiveLayerTracker::IsStyleAnimated(aBuilder, + mFrame, + eCSSProperty_transform) && + !IsItemTooSmallForActiveLayer(mFrame))) { + return true; } return false; } From 44537c73ada5320fef1497c54b2d7ec109ed0c28 Mon Sep 17 00:00:00 2001 From: Julian Descottes Date: Tue, 21 Feb 2017 17:51:01 +0100 Subject: [PATCH 020/234] Bug 1321467 - display grid line numbers with extended grid lines;r=zer0 Clamp the x and y positions for the grid line numbers to make sure they are always visible, even if extended grid lines is turned on. MozReview-Commit-ID: 3sxdWtKyXKN --HG-- extra : rebase_source : a242af83e654cd3cf1e234ad63a4852b47e9f8fb --- devtools/server/actors/highlighters/css-grid.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/devtools/server/actors/highlighters/css-grid.js b/devtools/server/actors/highlighters/css-grid.js index 0e5b189a2e1e..4f992d339aa3 100644 --- a/devtools/server/actors/highlighters/css-grid.js +++ b/devtools/server/actors/highlighters/css-grid.js @@ -652,11 +652,16 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, { renderGridLineNumber(lineNumber, linePos, startPos, dimensionType) { this.ctx.save(); + let textWidth = this.ctx.measureText(lineNumber).width; + // Guess the font height based on the measured width + let textHeight = textWidth * 2; + if (dimensionType === COLUMNS) { - this.ctx.fillText(lineNumber, linePos, startPos); + let yPos = Math.max(startPos, textHeight); + this.ctx.fillText(lineNumber, linePos, yPos); } else { - let textWidth = this.ctx.measureText(lineNumber).width; - this.ctx.fillText(lineNumber, startPos - textWidth, linePos); + let xPos = Math.max(startPos, textWidth); + this.ctx.fillText(lineNumber, xPos - textWidth, linePos); } this.ctx.restore(); From 38caddf718fe2ee145bd5743b0c54b9c8aed6a08 Mon Sep 17 00:00:00 2001 From: Huxley Date: Wed, 22 Feb 2017 06:12:52 -0800 Subject: [PATCH 021/234] servo: Merge #15665 - fixed an issue related with .DS_Store (from UnICorN21:ds_store); r=SimonSapin --- - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #15581. - [ ] There are tests for these changes OR - [ ] These changes do not require tests because _____ Source-Repo: https://github.com/servo/servo Source-Revision: 7adc79047dc1fafef3615cb8fcc8e4a43764f262 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 2e49175de83bee2706ee876b4f3086025c49f5e3 --- servo/python/servo/testing_commands.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/servo/python/servo/testing_commands.py b/servo/python/servo/testing_commands.py index 2417483c4df2..0733911d2b4a 100644 --- a/servo/python/servo/testing_commands.py +++ b/servo/python/servo/testing_commands.py @@ -232,7 +232,7 @@ class MachCommands(CommandBase): test_patterns.append(test) if not packages: - packages = set(os.listdir(path.join(self.context.topdir, "tests", "unit"))) + packages = set(os.listdir(path.join(self.context.topdir, "tests", "unit"))) - set(['.DS_Store']) packages.discard('stylo') @@ -345,7 +345,7 @@ class MachCommands(CommandBase): test_patterns.append(test) if not packages: - packages = set(os.listdir(path.join(self.context.topdir, "tests", "compiletest"))) + packages = set(os.listdir(path.join(self.context.topdir, "tests", "compiletest"))) - set(['.DS_Store']) packages.remove("helper") From 6c749c1bbdbb9b80937a05910edfa8fc8e422683 Mon Sep 17 00:00:00 2001 From: Jan Beich Date: Mon, 20 Feb 2017 20:00:50 +0000 Subject: [PATCH 022/234] Bug 1341108 - Work around libcubeb backends without multi-channel support. r=jya MozReview-Commit-ID: H5ROBTMVkkE --HG-- extra : rebase_source : 70869fd590575f98f515c4b7deb90180399e8588 --- dom/media/MediaPrefs.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dom/media/MediaPrefs.h b/dom/media/MediaPrefs.h index ef923cb96861..66127e2bb8ff 100644 --- a/dom/media/MediaPrefs.h +++ b/dom/media/MediaPrefs.h @@ -90,10 +90,11 @@ private: DECL_MEDIA_PREF("accessibility.monoaudio.enable", MonoAudio, bool, false); DECL_MEDIA_PREF("media.resampling.enabled", AudioSinkResampling, bool, false); DECL_MEDIA_PREF("media.resampling.rate", AudioSinkResampleRate, uint32_t, 48000); -#if defined(ANDROID) - DECL_MEDIA_PREF("media.forcestereo.enabled", AudioSinkForceStereo, bool, true); -#else +#if defined(XP_WIN) || defined(XP_DARWIN) || defined(MOZ_PULSEAUDIO) + // libcubeb backend implement .get_preferred_channel_layout DECL_MEDIA_PREF("media.forcestereo.enabled", AudioSinkForceStereo, bool, false); +#else + DECL_MEDIA_PREF("media.forcestereo.enabled", AudioSinkForceStereo, bool, true); #endif // VideoSink DECL_MEDIA_PREF("media.ruin-av-sync.enabled", RuinAvSync, bool, false); From c9d5d5a98333417558408e1b705ec9e77d73427a Mon Sep 17 00:00:00 2001 From: Ted Campbell Date: Thu, 16 Feb 2017 16:47:17 -0500 Subject: [PATCH 023/234] Bug 1273858 - Support LexicalEnvironmentObjects during Ion bailout r=jandem MozReview-Commit-ID: 8BLiJNOcrS2 --HG-- extra : rebase_source : e8efb5eb35e5e0a9aee082109bd45c8893b82b44 --- js/src/jit/BaselineBailouts.cpp | 25 +++++++++++++++++-------- js/src/jit/BaselineJIT.h | 4 ++++ js/src/jit/IonBuilder.cpp | 3 +++ js/src/jit/JitFrames.cpp | 8 +++++++- 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/js/src/jit/BaselineBailouts.cpp b/js/src/jit/BaselineBailouts.cpp index 2cfd283868ec..a035cecf0b27 100644 --- a/js/src/jit/BaselineBailouts.cpp +++ b/js/src/jit/BaselineBailouts.cpp @@ -137,6 +137,8 @@ struct BaselineStackBuilder header_->resumeFramePtr = nullptr; header_->resumeAddr = nullptr; header_->resumePC = nullptr; + header_->tryPC = nullptr; + header_->faultPC = nullptr; header_->monitorStub = nullptr; header_->numFrames = 0; header_->checkGlobalDeclarationConflicts = false; @@ -729,14 +731,12 @@ InitFromBailout(JSContext* cx, HandleScript caller, jsbytecode* callerPC, Value v = iter.read(); if (v.isObject()) { envChain = &v.toObject(); - if (fun && - ((fun->needsCallObject() && envChain->is()) || - (fun->needsNamedLambdaEnvironment() && - !fun->needsCallObject() && - envChain->is() && - &envChain->as().scope() == - script->maybeNamedLambdaScope()))) - { + + // If Ion has updated env slot from UndefinedValue, it will be the + // complete initial environment, so we can set the HAS_INITIAL_ENV + // flag if needed. + if (fun && fun->needsFunctionEnvironmentObjects()) { + MOZ_ASSERT(fun->nonLazyScript()->initialEnvironmentShape()); MOZ_ASSERT(!fun->needsExtraBodyVarEnvironment()); flags |= BaselineFrame::HAS_INITIAL_ENV; } @@ -1822,6 +1822,8 @@ jit::FinishBailoutToBaseline(BaselineBailoutInfo* bailoutInfo) BaselineFrame* topFrame = GetTopBaselineFrame(cx); topFrame->setOverridePc(bailoutInfo->resumePC); + jsbytecode* faultPC = bailoutInfo->faultPC; + jsbytecode* tryPC = bailoutInfo->tryPC; uint32_t numFrames = bailoutInfo->numFrames; MOZ_ASSERT(numFrames > 0); BailoutKind bailoutKind = bailoutInfo->bailoutKind; @@ -1939,6 +1941,13 @@ jit::FinishBailoutToBaseline(BaselineBailoutInfo* bailoutInfo) return false; } + // If we are catching an exception, we need to unwind scopes. + // See |SettleOnTryNote| + if (cx->isExceptionPending() && faultPC) { + EnvironmentIter ei(cx, topFrame, faultPC); + UnwindEnvironment(cx, ei, tryPC); + } + JitSpew(JitSpew_BaselineBailouts, " Restored outerScript=(%s:%" PRIuSIZE ",%u) innerScript=(%s:%" PRIuSIZE ",%u) (bailoutKind=%u)", outerScript->filename(), outerScript->lineno(), outerScript->getWarmUpCount(), diff --git a/js/src/jit/BaselineJIT.h b/js/src/jit/BaselineJIT.h index 7056e967ece5..caace7a244ed 100644 --- a/js/src/jit/BaselineJIT.h +++ b/js/src/jit/BaselineJIT.h @@ -592,6 +592,10 @@ struct BaselineBailoutInfo // The bytecode pc where we will resume. jsbytecode* resumePC; + // The bytecode pc of try block and fault block. + jsbytecode* tryPC; + jsbytecode* faultPC; + // If resuming into a TypeMonitor IC chain, this field holds the // address of the first stub in that chain. If this field is // set, then the actual jitcode resumed into is the jitcode for diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index d2637af2476f..36caa85e2670 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -1172,6 +1172,9 @@ IonBuilder::initEnvironmentChain(MDefinition* callee) env = constant(ObjectValue(script()->global().lexicalEnvironment())); } + // Update the environment slot from UndefinedValue only after initial + // environment is created so that bailout doesn't see a partial env. + // See: |InitFromBailout| current->setEnvironmentChain(env); return Ok(); } diff --git a/js/src/jit/JitFrames.cpp b/js/src/jit/JitFrames.cpp index ffd20add1cbb..edb13eceb136 100644 --- a/js/src/jit/JitFrames.cpp +++ b/js/src/jit/JitFrames.cpp @@ -464,8 +464,14 @@ HandleExceptionIon(JSContext* cx, const InlineFrameIterator& frame, ResumeFromEx jsbytecode* catchPC = script->main() + tn->start + tn->length; ExceptionBailoutInfo excInfo(frame.frameNo(), catchPC, tn->stackDepth); uint32_t retval = ExceptionHandlerBailout(cx, frame, rfe, excInfo, overrecursed); - if (retval == BAILOUT_RETURN_OK) + if (retval == BAILOUT_RETURN_OK) { + // Record exception locations to allow scope unwinding in + // |FinishBailoutToBaseline| + MOZ_ASSERT(cx->isExceptionPending()); + rfe->bailoutInfo->tryPC = UnwindEnvironmentToTryPc(frame.script(), tn); + rfe->bailoutInfo->faultPC = frame.pc(); return; + } // Error on bailout clears pending exception. MOZ_ASSERT(!cx->isExceptionPending()); From 8b4e69e2207f1bd8af1428dc6b3717a492a8f255 Mon Sep 17 00:00:00 2001 From: Ted Campbell Date: Fri, 10 Feb 2017 13:49:21 -0500 Subject: [PATCH 024/234] Bug 1273858 - Ion-compile JSOP_PUSHLEXICALENV/JSOP_POPLEXICALENV r=jandem MozReview-Commit-ID: CqD2GUGoNyY --HG-- extra : rebase_source : 7e6600dad166aaa861682da46e138c1021032698 --- js/src/jit/BytecodeAnalysis.cpp | 2 ++ js/src/jit/CodeGenerator.cpp | 16 +++++++++++++++ js/src/jit/CodeGenerator.h | 1 + js/src/jit/IonBuilder.cpp | 24 +++++++++++++++++++++-- js/src/jit/IonBuilder.h | 1 + js/src/jit/Lowering.cpp | 13 +++++++++++++ js/src/jit/Lowering.h | 1 + js/src/jit/MIR.h | 30 +++++++++++++++++++++++++++++ js/src/jit/MOpcodes.h | 1 + js/src/jit/VMFunctions.h | 1 + js/src/jit/shared/LIR-shared.h | 18 +++++++++++++++++ js/src/jit/shared/LOpcodes-shared.h | 1 + js/src/vm/EnvironmentObject.cpp | 14 ++++++-------- js/src/vm/EnvironmentObject.h | 7 ++----- 14 files changed, 115 insertions(+), 15 deletions(-) diff --git a/js/src/jit/BytecodeAnalysis.cpp b/js/src/jit/BytecodeAnalysis.cpp index f15420a7d0f1..8654bd6316c6 100644 --- a/js/src/jit/BytecodeAnalysis.cpp +++ b/js/src/jit/BytecodeAnalysis.cpp @@ -168,6 +168,8 @@ BytecodeAnalysis::init(TempAllocator& alloc, GSNCache& gsn) case JSOP_LAMBDA_ARROW: case JSOP_DEFFUN: case JSOP_DEFVAR: + case JSOP_PUSHLEXICALENV: + case JSOP_POPLEXICALENV: usesEnvironmentChain_ = true; break; diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index 35e661feffb8..03fcddaf102d 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -3433,6 +3433,22 @@ CodeGenerator::visitFunctionEnvironment(LFunctionEnvironment* lir) masm.loadPtr(environment, ToRegister(lir->output())); } +typedef LexicalEnvironmentObject* (*NewLexicalEnvironmentObjectFn)(JSContext*, + Handle, + HandleObject, gc::InitialHeap); +static const VMFunction NewLexicalEnvironmentObjectInfo = + FunctionInfo(LexicalEnvironmentObject::create, + "LexicalEnvironmentObject::create"); + +void +CodeGenerator::visitNewLexicalEnvironmentObject(LNewLexicalEnvironmentObject* lir) +{ + pushArg(Imm32(gc::DefaultHeap)); + pushArg(ToRegister(lir->enclosing())); + pushArg(ImmGCPtr(lir->mir()->scope())); + callVM(NewLexicalEnvironmentObjectInfo, lir); +} + void CodeGenerator::visitGuardObjectIdentity(LGuardObjectIdentity* guard) { diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h index 84cee889b310..db7cc5500bca 100644 --- a/js/src/jit/CodeGenerator.h +++ b/js/src/jit/CodeGenerator.h @@ -287,6 +287,7 @@ class CodeGenerator final : public CodeGeneratorSpecific void visitSinCos(LSinCos *lir); void visitStringSplit(LStringSplit* lir); void visitFunctionEnvironment(LFunctionEnvironment* lir); + void visitNewLexicalEnvironmentObject(LNewLexicalEnvironmentObject* lir); void visitCallGetProperty(LCallGetProperty* lir); void visitCallGetElement(LCallGetElement* lir); void visitCallSetElement(LCallSetElement* lir); diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 36caa85e2670..058c5e51110d 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -2207,6 +2207,13 @@ IonBuilder::inspectOpcode(JSOp op) case JSOP_SETFUNNAME: return jsop_setfunname(GET_UINT8(pc)); + case JSOP_PUSHLEXICALENV: + return jsop_pushlexicalenv(GET_UINT32_INDEX(pc)); + + case JSOP_POPLEXICALENV: + current->setEnvironmentChain(walkEnvironmentChain(1)); + return Ok(); + case JSOP_ITER: return jsop_iter(GET_INT8(pc)); @@ -2270,10 +2277,8 @@ IonBuilder::inspectOpcode(JSOp op) return Ok(); #ifdef DEBUG - case JSOP_PUSHLEXICALENV: case JSOP_FRESHENLEXICALENV: case JSOP_RECREATELEXICALENV: - case JSOP_POPLEXICALENV: // These opcodes are currently unhandled by Ion, but in principle // there's no reason they couldn't be. Whenever this happens, OSR // will have to consider that JSOP_{FRESHEN,RECREATE}LEXICALENV @@ -11849,6 +11854,21 @@ IonBuilder::jsop_setfunname(uint8_t prefixKind) return resumeAfter(ins); } +AbortReasonOr +IonBuilder::jsop_pushlexicalenv(uint32_t index) +{ + MOZ_ASSERT(analysis().usesEnvironmentChain()); + + LexicalScope* scope = &script()->getScope(index)->as(); + MNewLexicalEnvironmentObject* ins = + MNewLexicalEnvironmentObject::New(alloc(), current->environmentChain(), scope); + + current->add(ins); + current->setEnvironmentChain(ins); + + return resumeAfter(ins); +} + AbortReasonOr IonBuilder::jsop_setarg(uint32_t arg) { diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index 6972746ff7ea..a12744e11d9f 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -561,6 +561,7 @@ class IonBuilder AbortReasonOr jsop_lambda(JSFunction* fun); AbortReasonOr jsop_lambda_arrow(JSFunction* fun); AbortReasonOr jsop_setfunname(uint8_t prefixKind); + AbortReasonOr jsop_pushlexicalenv(uint32_t index); AbortReasonOr jsop_functionthis(); AbortReasonOr jsop_globalthis(); AbortReasonOr jsop_typeof(); diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index 231ffa7a015f..6933452cf33a 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -2517,6 +2517,19 @@ LIRGenerator::visitSetFunName(MSetFunName* ins) assignSafepoint(lir, ins); } +void +LIRGenerator::visitNewLexicalEnvironmentObject(MNewLexicalEnvironmentObject* ins) +{ + MDefinition* enclosing = ins->enclosing(); + MOZ_ASSERT(enclosing->type() == MIRType::Object); + + LNewLexicalEnvironmentObject* lir = + new(alloc()) LNewLexicalEnvironmentObject(useRegisterAtStart(enclosing)); + + defineReturn(lir, ins); + assignSafepoint(lir, ins); +} + void LIRGenerator::visitKeepAliveObject(MKeepAliveObject* ins) { diff --git a/js/src/jit/Lowering.h b/js/src/jit/Lowering.h index 4062c09602bc..0d48bb657691 100644 --- a/js/src/jit/Lowering.h +++ b/js/src/jit/Lowering.h @@ -186,6 +186,7 @@ class LIRGenerator : public LIRGeneratorSpecific void visitLambda(MLambda* ins); void visitLambdaArrow(MLambdaArrow* ins); void visitSetFunName(MSetFunName* ins); + void visitNewLexicalEnvironmentObject(MNewLexicalEnvironmentObject* ins); void visitKeepAliveObject(MKeepAliveObject* ins); void visitSlots(MSlots* ins); void visitElements(MElements* ins); diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index 1fa698bbb424..980fb666e557 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -11530,6 +11530,36 @@ class MFunctionEnvironment } }; +// Allocate a new LexicalEnvironmentObject. +class MNewLexicalEnvironmentObject + : public MUnaryInstruction, + public SingleObjectPolicy::Data +{ + CompilerGCPointer scope_; + + MNewLexicalEnvironmentObject(MDefinition* enclosing, LexicalScope* scope) + : MUnaryInstruction(enclosing), + scope_(scope) + { + setResultType(MIRType::Object); + } + + public: + INSTRUCTION_HEADER(NewLexicalEnvironmentObject) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, enclosing)) + + LexicalScope* scope() const { + return scope_; + } + bool possiblyCalls() const override { + return true; + } + bool appendRoots(MRootList& roots) const override { + return roots.append(scope_); + } +}; + // Store to vp[slot] (slots that are not inline in an object). class MStoreSlot : public MBinaryInstruction, diff --git a/js/src/jit/MOpcodes.h b/js/src/jit/MOpcodes.h index bf4e42170591..dc3aa9d80dd7 100644 --- a/js/src/jit/MOpcodes.h +++ b/js/src/jit/MOpcodes.h @@ -172,6 +172,7 @@ namespace jit { _(LoadSlot) \ _(StoreSlot) \ _(FunctionEnvironment) \ + _(NewLexicalEnvironmentObject) \ _(FilterTypeSet) \ _(TypeBarrier) \ _(MonitorTypes) \ diff --git a/js/src/jit/VMFunctions.h b/js/src/jit/VMFunctions.h index 43dbdc9c415f..5bdc4f36eeba 100644 --- a/js/src/jit/VMFunctions.h +++ b/js/src/jit/VMFunctions.h @@ -278,6 +278,7 @@ template <> struct TypeToDataType { static const DataType result template <> struct TypeToDataType { static const DataType result = Type_Object; }; template <> struct TypeToDataType { static const DataType result = Type_Object; }; template <> struct TypeToDataType { static const DataType result = Type_Object; }; +template <> struct TypeToDataType { static const DataType result = Type_Object; }; template <> struct TypeToDataType { static const DataType result = Type_Object; }; template <> struct TypeToDataType { static const DataType result = Type_Object; }; template <> struct TypeToDataType { static const DataType result = Type_Object; }; diff --git a/js/src/jit/shared/LIR-shared.h b/js/src/jit/shared/LIR-shared.h index d30ccae31f0c..d30151ca7692 100644 --- a/js/src/jit/shared/LIR-shared.h +++ b/js/src/jit/shared/LIR-shared.h @@ -7050,6 +7050,24 @@ class LFunctionEnvironment : public LInstructionHelper<1, 1, 0> } }; +// Allocate a new LexicalEnvironmentObject. +class LNewLexicalEnvironmentObject : public LCallInstructionHelper<1, 1, 0> +{ + public: + LIR_HEADER(NewLexicalEnvironmentObject) + + explicit LNewLexicalEnvironmentObject(const LAllocation& enclosing) { + setOperand(0, enclosing); + } + const LAllocation* enclosing() { + return getOperand(0); + } + + MNewLexicalEnvironmentObject* mir() const { + return mir_->toNewLexicalEnvironmentObject(); + } +}; + class LCallGetProperty : public LCallInstructionHelper { public: diff --git a/js/src/jit/shared/LOpcodes-shared.h b/js/src/jit/shared/LOpcodes-shared.h index 5c319de64c00..e70c204a9ec1 100644 --- a/js/src/jit/shared/LOpcodes-shared.h +++ b/js/src/jit/shared/LOpcodes-shared.h @@ -319,6 +319,7 @@ _(StoreFixedSlotV) \ _(StoreFixedSlotT) \ _(FunctionEnvironment) \ + _(NewLexicalEnvironmentObject) \ _(GetPropertyCacheV) \ _(GetPropertyCacheT) \ _(GetPropertyPolymorphicV) \ diff --git a/js/src/vm/EnvironmentObject.cpp b/js/src/vm/EnvironmentObject.cpp index 044c282783b8..cafc846668cc 100644 --- a/js/src/vm/EnvironmentObject.cpp +++ b/js/src/vm/EnvironmentObject.cpp @@ -889,8 +889,8 @@ LexicalEnvironmentObject::createTemplateObject(JSContext* cx, HandleShape shape, } /* static */ LexicalEnvironmentObject* -LexicalEnvironmentObject::createTemplateObject(JSContext* cx, Handle scope, - HandleObject enclosing, gc::InitialHeap heap) +LexicalEnvironmentObject::create(JSContext* cx, Handle scope, + HandleObject enclosing, gc::InitialHeap heap) { assertSameCompartment(cx, enclosing); MOZ_ASSERT(scope->hasEnvironment()); @@ -915,7 +915,7 @@ LexicalEnvironmentObject::create(JSContext* cx, Handle scope, AbstractFramePtr frame) { RootedObject enclosing(cx, frame.environmentChain()); - return createTemplateObject(cx, scope, enclosing, gc::DefaultHeap); + return create(cx, scope, enclosing, gc::DefaultHeap); } /* static */ LexicalEnvironmentObject* @@ -997,8 +997,7 @@ LexicalEnvironmentObject::clone(JSContext* cx, Handle { Rooted scope(cx, &env->scope()); RootedObject enclosing(cx, &env->enclosingEnvironment()); - Rooted copy(cx, createTemplateObject(cx, scope, enclosing, - gc::TenuredHeap)); + Rooted copy(cx, create(cx, scope, enclosing, gc::TenuredHeap)); if (!copy) return nullptr; @@ -1016,7 +1015,7 @@ LexicalEnvironmentObject::recreate(JSContext* cx, Handle scope(cx, &env->scope()); RootedObject enclosing(cx, &env->enclosingEnvironment()); - return createTemplateObject(cx, scope, enclosing, gc::TenuredHeap); + return create(cx, scope, enclosing, gc::TenuredHeap); } bool @@ -1071,8 +1070,7 @@ NamedLambdaObject::create(JSContext* cx, HandleFunction callee, #endif LexicalEnvironmentObject* obj = - LexicalEnvironmentObject::createTemplateObject(cx, scope.as(), - enclosing, heap); + LexicalEnvironmentObject::create(cx, scope.as(), enclosing, heap); if (!obj) return nullptr; diff --git a/js/src/vm/EnvironmentObject.h b/js/src/vm/EnvironmentObject.h index 94da7299b3c1..fcc17ca95e2d 100644 --- a/js/src/vm/EnvironmentObject.h +++ b/js/src/vm/EnvironmentObject.h @@ -477,11 +477,8 @@ class LexicalEnvironmentObject : public EnvironmentObject } public: - static LexicalEnvironmentObject* createTemplateObject(JSContext* cx, - Handle scope, - HandleObject enclosing, - gc::InitialHeap heap); - + static LexicalEnvironmentObject* create(JSContext* cx, Handle scope, + HandleObject enclosing, gc::InitialHeap heap); static LexicalEnvironmentObject* create(JSContext* cx, Handle scope, AbstractFramePtr frame); static LexicalEnvironmentObject* createGlobal(JSContext* cx, Handle global); From 9f630025f0f9a329ea982aa4d90d01481daebdf1 Mon Sep 17 00:00:00 2001 From: Ted Campbell Date: Wed, 15 Feb 2017 15:28:15 -0500 Subject: [PATCH 025/234] Bug 1273858 - Ion-compile JSOP_FRESHENLEXICALENV/JSOP_RECREATELEXICALENV r=jandem MozReview-Commit-ID: DHFceqW3YlD --HG-- extra : rebase_source : 5ec23b06c9469934abe4ea5c34d798339ffe230c --- js/src/jit/CodeGenerator.cpp | 13 +++++++++++++ js/src/jit/CodeGenerator.h | 1 + js/src/jit/IonBuilder.cpp | 30 +++++++++++++++++++---------- js/src/jit/IonBuilder.h | 1 + js/src/jit/Lowering.cpp | 13 +++++++++++++ js/src/jit/Lowering.h | 1 + js/src/jit/MIR.h | 27 ++++++++++++++++++++++++++ js/src/jit/MOpcodes.h | 1 + js/src/jit/VMFunctions.cpp | 11 +++++++++++ js/src/jit/VMFunctions.h | 2 ++ js/src/jit/shared/LIR-shared.h | 18 +++++++++++++++++ js/src/jit/shared/LOpcodes-shared.h | 1 + 12 files changed, 109 insertions(+), 10 deletions(-) diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index 03fcddaf102d..73b753351d50 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -3449,6 +3449,19 @@ CodeGenerator::visitNewLexicalEnvironmentObject(LNewLexicalEnvironmentObject* li callVM(NewLexicalEnvironmentObjectInfo, lir); } +typedef JSObject* (*CopyLexicalEnvironmentObjectFn)(JSContext*, HandleObject, bool); +static const VMFunction CopyLexicalEnvironmentObjectInfo = + FunctionInfo(js::jit::CopyLexicalEnvironmentObject, + "js::jit::CopyLexicalEnvironmentObject"); + +void +CodeGenerator::visitCopyLexicalEnvironmentObject(LCopyLexicalEnvironmentObject* lir) +{ + pushArg(Imm32(lir->mir()->copySlots())); + pushArg(ToRegister(lir->env())); + callVM(CopyLexicalEnvironmentObjectInfo, lir); +} + void CodeGenerator::visitGuardObjectIdentity(LGuardObjectIdentity* guard) { diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h index db7cc5500bca..bdfb2a0c3d2c 100644 --- a/js/src/jit/CodeGenerator.h +++ b/js/src/jit/CodeGenerator.h @@ -288,6 +288,7 @@ class CodeGenerator final : public CodeGeneratorSpecific void visitStringSplit(LStringSplit* lir); void visitFunctionEnvironment(LFunctionEnvironment* lir); void visitNewLexicalEnvironmentObject(LNewLexicalEnvironmentObject* lir); + void visitCopyLexicalEnvironmentObject(LCopyLexicalEnvironmentObject* lir); void visitCallGetProperty(LCallGetProperty* lir); void visitCallGetElement(LCallGetElement* lir); void visitCallSetElement(LCallSetElement* lir); diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 058c5e51110d..c0f251679180 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -2214,6 +2214,12 @@ IonBuilder::inspectOpcode(JSOp op) current->setEnvironmentChain(walkEnvironmentChain(1)); return Ok(); + case JSOP_FRESHENLEXICALENV: + return jsop_copylexicalenv(true); + + case JSOP_RECREATELEXICALENV: + return jsop_copylexicalenv(false); + case JSOP_ITER: return jsop_iter(GET_INT8(pc)); @@ -2276,16 +2282,6 @@ IonBuilder::inspectOpcode(JSOp op) pushConstant(MagicValue(JS_IS_CONSTRUCTING)); return Ok(); -#ifdef DEBUG - case JSOP_FRESHENLEXICALENV: - case JSOP_RECREATELEXICALENV: - // These opcodes are currently unhandled by Ion, but in principle - // there's no reason they couldn't be. Whenever this happens, OSR - // will have to consider that JSOP_{FRESHEN,RECREATE}LEXICALENV - // mutates the env chain -- right now MBasicBlock::environmentChain() - // caches the env chain. JSOP_{FRESHEN,RECREATE}LEXICALENV must - // update that stale value. -#endif default: break; } @@ -11869,6 +11865,20 @@ IonBuilder::jsop_pushlexicalenv(uint32_t index) return resumeAfter(ins); } +AbortReasonOr +IonBuilder::jsop_copylexicalenv(bool copySlots) +{ + MOZ_ASSERT(analysis().usesEnvironmentChain()); + + MCopyLexicalEnvironmentObject* ins = + MCopyLexicalEnvironmentObject::New(alloc(), current->environmentChain(), copySlots); + + current->add(ins); + current->setEnvironmentChain(ins); + + return resumeAfter(ins); +} + AbortReasonOr IonBuilder::jsop_setarg(uint32_t arg) { diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index a12744e11d9f..178fc84cbe12 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -562,6 +562,7 @@ class IonBuilder AbortReasonOr jsop_lambda_arrow(JSFunction* fun); AbortReasonOr jsop_setfunname(uint8_t prefixKind); AbortReasonOr jsop_pushlexicalenv(uint32_t index); + AbortReasonOr jsop_copylexicalenv(bool copySlots); AbortReasonOr jsop_functionthis(); AbortReasonOr jsop_globalthis(); AbortReasonOr jsop_typeof(); diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index 6933452cf33a..31c2fa7c6cee 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -2530,6 +2530,19 @@ LIRGenerator::visitNewLexicalEnvironmentObject(MNewLexicalEnvironmentObject* ins assignSafepoint(lir, ins); } +void +LIRGenerator::visitCopyLexicalEnvironmentObject(MCopyLexicalEnvironmentObject* ins) +{ + MDefinition* env = ins->env(); + MOZ_ASSERT(env->type() == MIRType::Object); + + LCopyLexicalEnvironmentObject* lir = + new(alloc()) LCopyLexicalEnvironmentObject(useRegisterAtStart(env)); + + defineReturn(lir, ins); + assignSafepoint(lir, ins); +} + void LIRGenerator::visitKeepAliveObject(MKeepAliveObject* ins) { diff --git a/js/src/jit/Lowering.h b/js/src/jit/Lowering.h index 0d48bb657691..b09cf2a1db7b 100644 --- a/js/src/jit/Lowering.h +++ b/js/src/jit/Lowering.h @@ -187,6 +187,7 @@ class LIRGenerator : public LIRGeneratorSpecific void visitLambdaArrow(MLambdaArrow* ins); void visitSetFunName(MSetFunName* ins); void visitNewLexicalEnvironmentObject(MNewLexicalEnvironmentObject* ins); + void visitCopyLexicalEnvironmentObject(MCopyLexicalEnvironmentObject* ins); void visitKeepAliveObject(MKeepAliveObject* ins); void visitSlots(MSlots* ins); void visitElements(MElements* ins); diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index 980fb666e557..852ad69e7ef3 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -11560,6 +11560,33 @@ class MNewLexicalEnvironmentObject } }; +// Allocate a new LexicalEnvironmentObject from existing one +class MCopyLexicalEnvironmentObject + : public MUnaryInstruction, + public SingleObjectPolicy::Data +{ + bool copySlots_; + + MCopyLexicalEnvironmentObject(MDefinition* env, bool copySlots) + : MUnaryInstruction(env), + copySlots_(copySlots) + { + setResultType(MIRType::Object); + } + + public: + INSTRUCTION_HEADER(CopyLexicalEnvironmentObject) + TRIVIAL_NEW_WRAPPERS + NAMED_OPERANDS((0, env)) + + bool copySlots() const { + return copySlots_; + } + bool possiblyCalls() const override { + return true; + } +}; + // Store to vp[slot] (slots that are not inline in an object). class MStoreSlot : public MBinaryInstruction, diff --git a/js/src/jit/MOpcodes.h b/js/src/jit/MOpcodes.h index dc3aa9d80dd7..e93ef8ba399f 100644 --- a/js/src/jit/MOpcodes.h +++ b/js/src/jit/MOpcodes.h @@ -173,6 +173,7 @@ namespace jit { _(StoreSlot) \ _(FunctionEnvironment) \ _(NewLexicalEnvironmentObject) \ + _(CopyLexicalEnvironmentObject) \ _(FilterTypeSet) \ _(TypeBarrier) \ _(MonitorTypes) \ diff --git a/js/src/jit/VMFunctions.cpp b/js/src/jit/VMFunctions.cpp index 62f54adab830..92d6dfb6ab82 100644 --- a/js/src/jit/VMFunctions.cpp +++ b/js/src/jit/VMFunctions.cpp @@ -924,6 +924,17 @@ NewArgumentsObject(JSContext* cx, BaselineFrame* frame, MutableHandleValue res) return true; } +JSObject* +CopyLexicalEnvironmentObject(JSContext* cx, HandleObject env, bool copySlots) +{ + Handle lexicalEnv = env.as(); + + if (copySlots) + return LexicalEnvironmentObject::clone(cx, lexicalEnv); + + return LexicalEnvironmentObject::recreate(cx, lexicalEnv); +} + JSObject* InitRestParameter(JSContext* cx, uint32_t length, Value* rest, HandleObject templateObj, HandleObject objRes) diff --git a/js/src/jit/VMFunctions.h b/js/src/jit/VMFunctions.h index 5bdc4f36eeba..100b6ed2e766 100644 --- a/js/src/jit/VMFunctions.h +++ b/js/src/jit/VMFunctions.h @@ -714,6 +714,8 @@ InitFunctionEnvironmentObjects(JSContext* cx, BaselineFrame* frame); MOZ_MUST_USE bool NewArgumentsObject(JSContext* cx, BaselineFrame* frame, MutableHandleValue res); +JSObject* CopyLexicalEnvironmentObject(JSContext* cx, HandleObject env, bool copySlots); + JSObject* InitRestParameter(JSContext* cx, uint32_t length, Value* rest, HandleObject templateObj, HandleObject res); diff --git a/js/src/jit/shared/LIR-shared.h b/js/src/jit/shared/LIR-shared.h index d30151ca7692..16725819b6dd 100644 --- a/js/src/jit/shared/LIR-shared.h +++ b/js/src/jit/shared/LIR-shared.h @@ -7068,6 +7068,24 @@ class LNewLexicalEnvironmentObject : public LCallInstructionHelper<1, 1, 0> } }; +// Copy a LexicalEnvironmentObject. +class LCopyLexicalEnvironmentObject : public LCallInstructionHelper<1, 1, 0> +{ + public: + LIR_HEADER(CopyLexicalEnvironmentObject) + + explicit LCopyLexicalEnvironmentObject(const LAllocation& env) { + setOperand(0, env); + } + const LAllocation* env() { + return getOperand(0); + } + + MCopyLexicalEnvironmentObject* mir() const { + return mir_->toCopyLexicalEnvironmentObject(); + } +}; + class LCallGetProperty : public LCallInstructionHelper { public: diff --git a/js/src/jit/shared/LOpcodes-shared.h b/js/src/jit/shared/LOpcodes-shared.h index e70c204a9ec1..3e6c4d584fbc 100644 --- a/js/src/jit/shared/LOpcodes-shared.h +++ b/js/src/jit/shared/LOpcodes-shared.h @@ -320,6 +320,7 @@ _(StoreFixedSlotT) \ _(FunctionEnvironment) \ _(NewLexicalEnvironmentObject) \ + _(CopyLexicalEnvironmentObject) \ _(GetPropertyCacheV) \ _(GetPropertyCacheT) \ _(GetPropertyPolymorphicV) \ From 2fe8cd4877baea1f73d15d691e64836e8bcaea68 Mon Sep 17 00:00:00 2001 From: Ted Campbell Date: Thu, 16 Feb 2017 22:51:18 -0500 Subject: [PATCH 026/234] Bug 1273858 - Testcases r=jandem MozReview-Commit-ID: AasrybVpMgN --HG-- extra : rebase_source : b311f7aac944f2468b5d6cfd357c0308f934f589 --- js/src/jit-test/tests/ion/bug1273858-1.js | 53 +++++++++++++++++++++++ js/src/jit-test/tests/ion/bug1273858-2.js | 46 ++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 js/src/jit-test/tests/ion/bug1273858-1.js create mode 100644 js/src/jit-test/tests/ion/bug1273858-2.js diff --git a/js/src/jit-test/tests/ion/bug1273858-1.js b/js/src/jit-test/tests/ion/bug1273858-1.js new file mode 100644 index 000000000000..89769ffe583f --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1273858-1.js @@ -0,0 +1,53 @@ +// |jit-test| --no-threads + +function t1() { + let x = []; + + for (let k = 0; k < 100; ++k) + x[k] = () => k; // Lexical capture + + try { + eval("k"); + throw false; + } + catch (e) { + if (!(e instanceof ReferenceError)) + throw "Loop index escaped block"; + } + + for (var i = 0; i < 100; ++i) + if (x[i]() != i) + throw "Bad let capture"; +} +t1(); +t1(); +t1(); +t1(); + +function t2() { + let x = []; + let y = {}; + + for (var i = 0; i < 100; ++i) + x[i] = i; + + for (const k of x) + y[k] = () => k; // Lexical capture + + try { + eval("k"); + throw false; + } + catch (e) { + if (!(e instanceof ReferenceError)) + throw "Loop index escaped block"; + } + + for (var i = 0; i < 100; ++i) + if (y[i]() != i) + throw "Bad const capture"; +} +t2(); +t2(); +t2(); +t2(); diff --git a/js/src/jit-test/tests/ion/bug1273858-2.js b/js/src/jit-test/tests/ion/bug1273858-2.js new file mode 100644 index 000000000000..6d274cf02b95 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1273858-2.js @@ -0,0 +1,46 @@ +// |jit-test| --no-threads + +function t1() { + let x = []; + + try + { + for (let k = 0; k < 100; ++k) + { + let w = () => k; // Lexical capture + + if (w() > 10) + { + throw () => w; // Lexical capture + } + + x[k] = w; + } + } + catch (e) + { + // 'w' and 'k' should leave scope as exception unwinds + + try { + eval("k"); + throw false; + } + catch (e) { + if (!(e instanceof ReferenceError)) + throw "Loop index escaped block"; + } + + try { + eval("w"); + throw false; + } + catch (e) { + if (!(e instanceof ReferenceError)) + throw "Local name escaped block"; + } + } +} +t1(); +t1(); +t1(); +t1(); From a9d7b6deb50ea244a1654daacdd056c1e859e27f Mon Sep 17 00:00:00 2001 From: Matheus Longaray Date: Fri, 13 Jan 2017 19:04:16 +0100 Subject: [PATCH 027/234] Bug 1323987 - Add about:printpreview redirector. r=mconley This patch adds a new entry for "about:printpreview" in nsAboutRedirector. We also make sure the URI is maintained when redirecting. MozReview-Commit-ID: 3LlyNJqKOhZ --HG-- extra : rebase_source : b5641d09d35e3d1394fe4fc53c518caa3a27df46 --- docshell/base/nsAboutRedirector.cpp | 14 +++++++++++--- docshell/build/nsDocShellModule.cpp | 1 + 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/docshell/base/nsAboutRedirector.cpp b/docshell/base/nsAboutRedirector.cpp index d09cc0b2b354..3e05efeae95f 100644 --- a/docshell/base/nsAboutRedirector.cpp +++ b/docshell/base/nsAboutRedirector.cpp @@ -138,6 +138,12 @@ static const RedirEntry kRedirMap[] = { { "webrtc", "chrome://global/content/aboutwebrtc/aboutWebrtc.html", nsIAboutModule::ALLOW_SCRIPT + }, + { + "printpreview", "about:blank", + nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT | + nsIAboutModule::HIDE_FROM_ABOUTABOUT | + nsIAboutModule::URI_CAN_LOAD_IN_CHILD } }; static const int kRedirTotal = mozilla::ArrayLength(kRedirMap); @@ -173,9 +179,11 @@ nsAboutRedirector::NewChannel(nsIURI* aURI, &isUIResource); NS_ENSURE_SUCCESS(rv, rv); - nsLoadFlags loadFlags = - isUIResource ? static_cast(nsIChannel::LOAD_NORMAL) - : static_cast(nsIChannel::LOAD_REPLACE); + bool isAboutBlank = NS_IsAboutBlank(tempURI); + + nsLoadFlags loadFlags = isUIResource || isAboutBlank + ? static_cast(nsIChannel::LOAD_NORMAL) + : static_cast(nsIChannel::LOAD_REPLACE); rv = NS_NewChannelInternal(getter_AddRefs(tempChannel), tempURI, diff --git a/docshell/build/nsDocShellModule.cpp b/docshell/build/nsDocShellModule.cpp index 1e62e147947e..9b0828cd852c 100644 --- a/docshell/build/nsDocShellModule.cpp +++ b/docshell/build/nsDocShellModule.cpp @@ -189,6 +189,7 @@ const mozilla::Module::ContractIDEntry kDocShellContracts[] = { { NS_ABOUT_MODULE_CONTRACTID_PREFIX "support", &kNS_ABOUT_REDIRECTOR_MODULE_CID }, { NS_ABOUT_MODULE_CONTRACTID_PREFIX "telemetry", &kNS_ABOUT_REDIRECTOR_MODULE_CID }, { NS_ABOUT_MODULE_CONTRACTID_PREFIX "webrtc", &kNS_ABOUT_REDIRECTOR_MODULE_CID }, + { NS_ABOUT_MODULE_CONTRACTID_PREFIX "printpreview", &kNS_ABOUT_REDIRECTOR_MODULE_CID }, { NS_URI_LOADER_CONTRACTID, &kNS_URI_LOADER_CID }, { NS_DOCUMENTLOADER_SERVICE_CONTRACTID, &kNS_DOCUMENTLOADER_SERVICE_CID }, { NS_HANDLERSERVICE_CONTRACTID, &kNS_CONTENTHANDLERSERVICE_CID, mozilla::Module::CONTENT_PROCESS_ONLY }, From 4e111ff76c7cd066f9f67f76fa661b65b65652c0 Mon Sep 17 00:00:00 2001 From: Matheus Longaray Date: Mon, 9 Jan 2017 19:35:31 +0100 Subject: [PATCH 028/234] Bug 1323987 - Keep saving about:blank and about:newtab to disk. r=mikedeboer This patch creates a new method that verifies if the tab state we're passed is something we should keep to be reopened at session restore. This is used when we are saving the current session state to disk. This method is very similar to _shouldSaveTabState, however, "about:blank" and "about:newtab" tabs will still be saved to disk. MozReview-Commit-ID: 70zKFeUG9uQ --HG-- extra : rebase_source : 994412066334f7a1e85707a011225d7c5b65c319 --- .../components/sessionstore/SessionStore.jsm | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/browser/components/sessionstore/SessionStore.jsm b/browser/components/sessionstore/SessionStore.jsm index 4581eec3d2e0..c4b680e0d92f 100644 --- a/browser/components/sessionstore/SessionStore.jsm +++ b/browser/components/sessionstore/SessionStore.jsm @@ -388,7 +388,7 @@ this.SessionStore = { let win = aState.windows[i]; for (let j = win.tabs.length - 1; j >= 0; j--) { let tab = win.tabs[j]; - if (!SessionStoreInternal._shouldSaveTabState(tab)) { + if (!SessionStoreInternal._shouldSaveTab(tab)) { win.tabs.splice(j, 1); if (win.selected > j) { win.selected--; @@ -4198,10 +4198,29 @@ var SessionStoreInternal = { !(aTabState.entries.length == 1 && (aTabState.entries[0].url == "about:blank" || aTabState.entries[0].url == "about:newtab" || + aTabState.entries[0].url == "about:printpreview" || aTabState.entries[0].url == "about:privatebrowsing") && !aTabState.userTypedValue); }, + /** + * Determine if the tab state we're passed is something we should keep to be + * reopened at session restore. This is used when we are saving the current + * session state to disk. This method is very similar to _shouldSaveTabState, + * however, "about:blank" and "about:newtab" tabs will still be saved to disk. + * + * @param aTabState + * The current tab state + * @returns boolean + */ + _shouldSaveTab: function ssi_shouldSaveTab(aTabState) { + // If the tab has one of the following transient about: history entry, + // then we don't actually want to write this tab's data to disk. + return aTabState.entries.length && + !(aTabState.entries[0].url == "about:printpreview" || + aTabState.entries[0].url == "about:privatebrowsing"); + }, + /** * This is going to take a state as provided at startup (via * nsISessionStartup.state) and split it into 2 parts. The first part From d06e88eb2aacfa03535e853136e1ac26b792424e Mon Sep 17 00:00:00 2001 From: Matheus Longaray Date: Thu, 5 Jan 2017 17:38:13 +0100 Subject: [PATCH 029/234] Bug 1323987 - Update browser printing code accordingly. r=mconley This patch updates browser printing code to make use of about:printpreview when loading new tab for print preview. The same URI is used when the user makes use of simplify page feature while print previewing. MozReview-Commit-ID: DXHT71hpnWo --HG-- extra : rebase_source : 9ccda6cd971931df70093177c6a9bdd16c93b7db --- browser/base/content/browser.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 5f8eb2af5c08..621d2cc76fb0 100755 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -3436,7 +3436,7 @@ var PrintPreviewListener = { let browser = gBrowser.selectedBrowser; let preferredRemoteType = browser.remoteType; this._tabBeforePrintPreview = gBrowser.selectedTab; - this._printPreviewTab = gBrowser.loadOneTab("about:blank", { + this._printPreviewTab = gBrowser.loadOneTab("about:printpreview", { inBackground: false, preferredRemoteType, sameProcessAsFrameLoader: browser.frameLoader @@ -3447,7 +3447,7 @@ var PrintPreviewListener = { }, createSimplifiedBrowser() { let browser = this._tabBeforePrintPreview.linkedBrowser; - this._simplifyPageTab = gBrowser.loadOneTab("about:blank", { + this._simplifyPageTab = gBrowser.loadOneTab("about:printpreview", { inBackground: true, sameProcessAsFrameLoader: browser.frameLoader }); From b932981d58a90fb0e599a1c97112401d62153a4e Mon Sep 17 00:00:00 2001 From: Matheus Longaray Date: Thu, 16 Feb 2017 16:50:15 +0100 Subject: [PATCH 030/234] Bug 1323987 - Set document URI after content viewer is created to host preview. r=mconley This patch sets document URI to about:printpreview after content viewer is created to host preview. MozReview-Commit-ID: GD5x70cwXck --HG-- extra : rebase_source : 746562bf0d47b919b1fcd3becdae92078e635e73 --- docshell/base/nsDocShell.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 75206c188018..c4128ee6315f 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -14347,10 +14347,19 @@ nsDocShell::GetPrintPreview(nsIWebBrowserPrint** aPrintPreview) #if NS_PRINT_PREVIEW nsCOMPtr print = do_QueryInterface(mContentViewer); if (!print || !print->IsInitializedForPrintPreview()) { + // XXX: Creating a brand new content viewer to host preview every + // time we enter here seems overwork. We could skip ahead to where + // we QI the mContentViewer if the current URI is either about:blank + // or about:printpreview. Stop(nsIWebNavigation::STOP_ALL); nsCOMPtr principal = nsNullPrincipal::CreateWithInheritedAttributes(this); - nsresult rv = CreateAboutBlankContentViewer(principal, nullptr); + nsCOMPtr uri; + NS_NewURI(getter_AddRefs(uri), NS_LITERAL_CSTRING("about:printpreview")); + nsresult rv = CreateAboutBlankContentViewer(principal, uri); NS_ENSURE_SUCCESS(rv, rv); + // Here we manually set current URI since we have just created a + // brand new content viewer (about:blank) to host preview. + SetCurrentURI(uri, nullptr, true, 0); print = do_QueryInterface(mContentViewer); NS_ENSURE_STATE(print); print->InitializeForPrintPreview(); From db5c89c552c301d1e8f03f0da87bef62fa5999a5 Mon Sep 17 00:00:00 2001 From: Tomislav Jovanovic Date: Wed, 22 Feb 2017 00:30:41 +0100 Subject: [PATCH 031/234] Bug 1340556 - Add tests for clipboardRead from the background page r=mixedpuppy MozReview-Commit-ID: 1eQ1JUBt5ps --HG-- rename : toolkit/components/extensions/test/mochitest/test_clipboard.html => toolkit/components/extensions/test/mochitest/test_ext_clipboard.html extra : rebase_source : c8d1eeb6c4b324bf3cb6357eff8d8a5fb266b686 --- .../test/mochitest/mochitest-common.ini | 2 +- ...clipboard.html => test_ext_clipboard.html} | 32 ++++++++++++++++--- 2 files changed, 29 insertions(+), 5 deletions(-) rename toolkit/components/extensions/test/mochitest/{test_clipboard.html => test_ext_clipboard.html} (86%) diff --git a/toolkit/components/extensions/test/mochitest/mochitest-common.ini b/toolkit/components/extensions/test/mochitest/mochitest-common.ini index 5e7cd345b068..adf5540c12fb 100644 --- a/toolkit/components/extensions/test/mochitest/mochitest-common.ini +++ b/toolkit/components/extensions/test/mochitest/mochitest-common.ini @@ -46,7 +46,7 @@ support-files = !/toolkit/components/passwordmgr/test/authenticate.sjs !/dom/tests/mochitest/geolocation/network_geolocation.sjs -[test_clipboard.html] +[test_ext_clipboard.html] # skip-if = # disabled test case with_permission_allow_copy, see inline comment. [test_ext_inIncognitoContext_window.html] skip-if = os == 'android' # Android does not support multiple windows. diff --git a/toolkit/components/extensions/test/mochitest/test_clipboard.html b/toolkit/components/extensions/test/mochitest/test_ext_clipboard.html similarity index 86% rename from toolkit/components/extensions/test/mochitest/test_clipboard.html rename to toolkit/components/extensions/test/mochitest/test_ext_clipboard.html index eb95c6063930..16b3e2cc528d 100644 --- a/toolkit/components/extensions/test/mochitest/test_clipboard.html +++ b/toolkit/components/extensions/test/mochitest/test_ext_clipboard.html @@ -50,8 +50,8 @@ add_task(function* test_background_clipboard_permissions() { yield extension.unload(); }); -/** Selecting text in a bg page is not possible, skip test until it's fixed. -add_task(function* with_permission_allow_copy() { +/** Selecting text in a bg page is not possible, bug 1272869. +add_task(function* test_background_clipboard_copy() { function backgroundScript() { browser.test.onMessage.addListener(txt => { browser.test.assertEq(true, doCopy(txt), @@ -60,7 +60,7 @@ add_task(function* with_permission_allow_copy() { browser.test.sendMessage("ready"); } let extensionData = { - background: `${doCopy};(${backgroundScript})();`, + background: `(${shared})();(${backgroundScript})();`, manifest: { permissions: [ "clipboardWrite", @@ -79,7 +79,8 @@ add_task(function* with_permission_allow_copy() { }); yield extension.unload(); -}); */ +}); +*/ add_task(function* test_contentscript_clipboard_permissions() { function contentScript() { @@ -184,6 +185,29 @@ add_task(function* test_contentscript_clipboard_paste() { yield extension.unload(); }); +add_task(function* test_background_clipboard_paste() { + function background() { + browser.test.sendMessage("paste", doPaste()); + } + + const extension = ExtensionTestUtils.loadExtension({ + manifest: { + permissions: ["clipboardRead"], + }, + background: `(${shared})();(${background})();`, + }); + + const STRANGE = "Stranger Things"; + SpecialPowers.clipboardCopyString(STRANGE); + + yield extension.startup(); + + const paste = yield extension.awaitMessage("paste"); + is(paste, STRANGE, "the correct string was pasted"); + + yield extension.unload(); +}); + From 1b57a97a4b0108e9ae77b7ad8e27077a416ef3d2 Mon Sep 17 00:00:00 2001 From: Sergei Chernov Date: Mon, 30 Jan 2017 18:16:49 +0200 Subject: [PATCH 032/234] Bug 1320567 - Certificate Transparency - telemetry reports of CT Policy compliance. r=keeler MozReview-Commit-ID: GtIz5O3FJ6H --HG-- extra : rebase_source : 47836d0f8e13147778cd2d792bdbc1d97d298610 --- .../manager/ssl/SSLServerCertVerification.cpp | 55 +++++++++++++++++++ toolkit/components/telemetry/Histograms.json | 27 +++++++++ .../telemetry/histogram-whitelists.json | 4 +- 3 files changed, 85 insertions(+), 1 deletion(-) diff --git a/security/manager/ssl/SSLServerCertVerification.cpp b/security/manager/ssl/SSLServerCertVerification.cpp index 606b4992c387..419cab4086fb 100644 --- a/security/manager/ssl/SSLServerCertVerification.cpp +++ b/security/manager/ssl/SSLServerCertVerification.cpp @@ -1283,6 +1283,7 @@ GatherTelemetryForSingleSCT(const ct::VerifiedSCT& verifiedSct) void GatherCertificateTransparencyTelemetry(const UniqueCERTCertList& certList, + bool isEV, const CertificateTransparencyInfo& info) { if (!info.enabled) { @@ -1306,6 +1307,59 @@ GatherCertificateTransparencyTelemetry(const UniqueCERTCertList& certList, // Note that sctsCount can also be 0 in case we've received SCT binary data, // but it failed to parse (e.g. due to unsupported CT protocol version). Telemetry::Accumulate(Telemetry::SSL_SCTS_PER_CONNECTION, sctsCount); + + // Report CT Policy compliance of EV certificates. + if (isEV) { + uint32_t evCompliance = 0; + switch (info.policyCompliance) { + case ct::CTPolicyCompliance::Compliant: + evCompliance = 1; + break; + case ct::CTPolicyCompliance::NotEnoughScts: + evCompliance = 2; + break; + case ct::CTPolicyCompliance::NotDiverseScts: + evCompliance = 3; + break; + case ct::CTPolicyCompliance::Unknown: + default: + MOZ_ASSERT_UNREACHABLE("Unexpected CTPolicyCompliance type"); + } + Telemetry::Accumulate(Telemetry::SSL_CT_POLICY_COMPLIANCE_OF_EV_CERTS, + evCompliance); + } + + // Get the root cert. + CERTCertListNode* rootNode = CERT_LIST_TAIL(certList); + MOZ_ASSERT(rootNode); + if (!rootNode) { + return; + } + MOZ_ASSERT(!CERT_LIST_END(rootNode, certList)); + if (CERT_LIST_END(rootNode, certList)) { + return; + } + CERTCertificate* rootCert = rootNode->cert; + MOZ_ASSERT(rootCert); + if (!rootCert) { + return; + } + + // Report CT Policy compliance by CA. + switch (info.policyCompliance) { + case ct::CTPolicyCompliance::Compliant: + AccumulateTelemetryForRootCA( + Telemetry::SSL_CT_POLICY_COMPLIANT_CONNECTIONS_BY_CA, rootCert); + break; + case ct::CTPolicyCompliance::NotEnoughScts: + case ct::CTPolicyCompliance::NotDiverseScts: + AccumulateTelemetryForRootCA( + Telemetry::SSL_CT_POLICY_NON_COMPLIANT_CONNECTIONS_BY_CA, rootCert); + break; + case ct::CTPolicyCompliance::Unknown: + default: + MOZ_ASSERT_UNREACHABLE("Unexpected CTPolicyCompliance type"); + } } // Note: Takes ownership of |peerCertChain| if SECSuccess is not returned. @@ -1390,6 +1444,7 @@ AuthCertificate(CertVerifier& certVerifier, SECSuccess); GatherSuccessfulValidationTelemetry(certList); GatherCertificateTransparencyTelemetry(certList, + /*isEV*/ evOidPolicy != SEC_OID_UNKNOWN, certificateTransparencyInfo); // The connection may get terminated, for example, if the server requires diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index 757af7379c30..8e8afcb830dc 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -8751,6 +8751,33 @@ "n_values": 100, "description": "If certificate verification failed in a TLS handshake, what was the error? (see MapCertErrorToProbeValue in security/manager/ssl/SSLServerCertVerification.cpp and the values in security/pkix/include/pkix/Result.h)" }, + "SSL_CT_POLICY_COMPLIANCE_OF_EV_CERTS": { + "alert_emails": ["seceng-telemetry@mozilla.com"], + "expires_in_version": "62", + "kind": "enumerated", + "n_values": 10, + "bug_numbers": [1320567], + "releaseChannelCollection": "opt-out", + "description": "Certificate Transparency Policy compliance of successfully established SSL connections with EV certificate (1=Compliant, 2=Insufficient number of SCTs, 3=Insufficient diversity of CT Log operators)" + }, + "SSL_CT_POLICY_COMPLIANT_CONNECTIONS_BY_CA": { + "alert_emails": ["seceng-telemetry@mozilla.com"], + "expires_in_version": "never", + "kind": "enumerated", + "n_values": 256, + "bug_numbers": [1320567], + "releaseChannelCollection": "opt-out", + "description": "Number of successfully established TLS connections compliant with the Certificate Transparency Policy, by CA. See https://dxr.mozilla.org/mozilla-central/source/security/manager/ssl/RootHashes.inc for names of CAs. Bucket zero holds CAs not present in the list." + }, + "SSL_CT_POLICY_NON_COMPLIANT_CONNECTIONS_BY_CA": { + "alert_emails": ["seceng-telemetry@mozilla.com"], + "expires_in_version": "never", + "kind": "enumerated", + "n_values": 256, + "bug_numbers": [1320567], + "releaseChannelCollection": "opt-out", + "description": "Number of successfully established TLS connections NOT compliant with the Certificate Transparency Policy, by CA. See https://dxr.mozilla.org/mozilla-central/source/security/manager/ssl/RootHashes.inc for names of CAs. Bucket zero holds CAs not present in the list." + }, "SSL_PERMANENT_CERT_ERROR_OVERRIDES": { "alert_emails": ["seceng@mozilla.org"], "expires_in_version": "default", diff --git a/toolkit/components/telemetry/histogram-whitelists.json b/toolkit/components/telemetry/histogram-whitelists.json index dd9624f28186..8e91f9195468 100644 --- a/toolkit/components/telemetry/histogram-whitelists.json +++ b/toolkit/components/telemetry/histogram-whitelists.json @@ -1824,7 +1824,9 @@ "GFX_CRASH", "GC_REASON_2", "GC_MINOR_REASON", - "GC_MINOR_REASON_LONG" + "GC_MINOR_REASON_LONG", + "SSL_CT_POLICY_COMPLIANT_CONNECTIONS_BY_CA", + "SSL_CT_POLICY_NON_COMPLIANT_CONNECTIONS_BY_CA" ], "expiry_default": [ "A11Y_CONSUMERS", From e3c3c9bba8a19c33ea5e492634610928bde4fb57 Mon Sep 17 00:00:00 2001 From: Hiroyuki Ikezoe Date: Wed, 22 Feb 2017 08:17:18 -0800 Subject: [PATCH 033/234] servo: Merge #15683 - Fill missing property in keyframe (from hiikezoe:fill-missing-property-in-keyframe); r=emilio This is a PR of https://bugzilla.mozilla.org/show_bug.cgi?id=1340961 All patches has been reviewed by @emilio. Thanks! --- - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [ ] These changes fix #__ (github issue number if applicable). - [X] There are tests for these changes Source-Repo: https://github.com/servo/servo Source-Revision: 4f7e422054237c8ba0a8e521a615a6012b90eab4 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 88f25cc970f606ceb4a586cc2aa2273d2b9f48d8 --- servo/components/style/keyframes.rs | 27 +-- .../helpers/animated_properties.mako.rs | 2 +- .../style/properties/properties.mako.rs | 32 +++- servo/ports/geckolib/glue.rs | 47 ++++- servo/tests/unit/style/keyframes.rs | 179 +++++++++++++++++- 5 files changed, 262 insertions(+), 25 deletions(-) diff --git a/servo/components/style/keyframes.rs b/servo/components/style/keyframes.rs index 07de56158eaf..fcb05c8dc340 100644 --- a/servo/components/style/keyframes.rs +++ b/servo/components/style/keyframes.rs @@ -15,6 +15,7 @@ use properties::{PropertyDeclarationId, LonghandId, DeclaredValue}; use properties::PropertyDeclarationParseResult; use properties::animated_properties::TransitionProperty; use properties::longhands::transition_timing_function::single_value::SpecifiedValue as SpecifiedTimingFunction; +use properties::property_bit_field::PropertyBitField; use std::fmt; use std::sync::Arc; use style_traits::ToCss; @@ -244,21 +245,23 @@ pub struct KeyframesAnimation { pub properties_changed: Vec, } -/// Get all the animated properties in a keyframes animation. Note that it's not -/// defined what happens when a property is not on a keyframe, so we only peek -/// the props of the first one. -/// -/// In practice, browsers seem to try to do their best job at it, so we might -/// want to go through all the actual keyframes and deduplicate properties. -fn get_animated_properties(keyframe: &Keyframe) -> Vec { +/// Get all the animated properties in a keyframes animation. +fn get_animated_properties(keyframes: &[Arc>]) -> Vec { let mut ret = vec![]; + let mut seen = PropertyBitField::new(); // NB: declarations are already deduplicated, so we don't have to check for // it here. - for &(ref declaration, importance) in keyframe.block.read().declarations.iter() { - assert!(!importance.important()); + for keyframe in keyframes { + let keyframe = keyframe.read(); + for &(ref declaration, importance) in keyframe.block.read().declarations.iter() { + assert!(!importance.important()); - if let Some(property) = TransitionProperty::from_declaration(declaration) { - ret.push(property); + if let Some(property) = TransitionProperty::from_declaration(declaration) { + if !seen.has_transition_property_bit(&property) { + ret.push(property); + seen.set_transition_property_bit(&property); + } + } } } @@ -284,7 +287,7 @@ impl KeyframesAnimation { return result; } - result.properties_changed = get_animated_properties(&keyframes[0].read()); + result.properties_changed = get_animated_properties(keyframes); if result.properties_changed.is_empty() { return result; } diff --git a/servo/components/style/properties/helpers/animated_properties.mako.rs b/servo/components/style/properties/helpers/animated_properties.mako.rs index 3c05fc06e312..8001e9457a6d 100644 --- a/servo/components/style/properties/helpers/animated_properties.mako.rs +++ b/servo/components/style/properties/helpers/animated_properties.mako.rs @@ -43,7 +43,7 @@ use values::specified::Angle as SpecifiedAngle; /// property. // NB: This needs to be here because it needs all the longhands generated // beforehand. -#[derive(Copy, Clone, Debug, PartialEq)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub enum TransitionProperty { /// All, any animatable property changing should generate a transition. diff --git a/servo/components/style/properties/properties.mako.rs b/servo/components/style/properties/properties.mako.rs index be76f0cf1a3d..e0623fcf7805 100644 --- a/servo/components/style/properties/properties.mako.rs +++ b/servo/components/style/properties/properties.mako.rs @@ -181,8 +181,10 @@ pub mod animated_properties { // TODO(SimonSapin): Convert this to a syntax extension rather than a Mako template. // Maybe submit for inclusion in libstd? -mod property_bit_field { +#[allow(missing_docs)] +pub mod property_bit_field { use logical_geometry::WritingMode; + use properties::animated_properties::TransitionProperty; /// A bitfield for all longhand properties, in order to quickly test whether /// we've seen one of them. @@ -213,7 +215,7 @@ mod property_bit_field { pub fn get_${property.ident}(&self) -> bool { self.get(${i}) } - #[allow(non_snake_case)] + #[allow(non_snake_case, missing_docs)] #[inline] pub fn set_${property.ident}(&mut self) { self.set(${i}) @@ -238,6 +240,32 @@ mod property_bit_field { } % endif % endfor + + /// Set the corresponding bit of TransitionProperty. + /// This function will panic if TransitionProperty::All is given. + pub fn set_transition_property_bit(&mut self, property: &TransitionProperty) { + match *property { + % for i, prop in enumerate(data.longhands): + % if prop.animatable: + TransitionProperty::${prop.camel_case} => self.set(${i}), + % endif + % endfor + TransitionProperty::All => unreachable!("Tried to set TransitionProperty::All in a PropertyBitfield"), + } + } + + /// Return true if the corresponding bit of TransitionProperty is set. + /// This function will panic if TransitionProperty::All is given. + pub fn has_transition_property_bit(&self, property: &TransitionProperty) -> bool { + match *property { + % for i, prop in enumerate(data.longhands): + % if prop.animatable: + TransitionProperty::${prop.camel_case} => self.get(${i}), + % endif + % endfor + TransitionProperty::All => unreachable!("Tried to get TransitionProperty::All in a PropertyBitfield"), + } + } } } diff --git a/servo/ports/geckolib/glue.rs b/servo/ports/geckolib/glue.rs index 54aac9b46948..c7e6ede116f7 100644 --- a/servo/ports/geckolib/glue.rs +++ b/servo/ports/geckolib/glue.rs @@ -1435,6 +1435,9 @@ pub extern "C" fn Servo_StyleSet_FillKeyframesForName(raw_data: RawServoStyleSet timing_function: *const nsTimingFunction, style: ServoComputedValuesBorrowed, keyframes: RawGeckoKeyframeListBorrowedMut) -> bool { + use style::gecko_bindings::structs::Keyframe; + use style::properties::property_bit_field::PropertyBitField; + let data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut(); let name = unsafe { Atom::from(name.as_ref().unwrap().as_str_unchecked()) }; let style_timing_function = unsafe { timing_function.as_ref().unwrap() }; @@ -1455,16 +1458,25 @@ pub extern "C" fn Servo_StyleSet_FillKeyframesForName(raw_data: RawServoStyleSet &timing_function) }; + fn add_computed_property_value(keyframe: *mut Keyframe, + index: usize, + style: &ComputedValues, + property: &TransitionProperty) { + let block = style.to_declaration_block(property.clone().into()); + unsafe { + (*keyframe).mPropertyValues.set_len((index + 1) as u32); + (*keyframe).mPropertyValues[index].mProperty = property.clone().into(); + // FIXME. Do not set computed values once we handles missing keyframes + // with additive composition. + (*keyframe).mPropertyValues[index].mServoDeclarationBlock.set_arc_leaky( + Arc::new(RwLock::new(block))); + } + } + match step.value { KeyframesStepValue::ComputedValues => { for (index, property) in animation.properties_changed.iter().enumerate() { - let block = style.to_declaration_block(property.clone().into()); - unsafe { - (*keyframe).mPropertyValues.set_len((index + 1) as u32); - (*keyframe).mPropertyValues[index].mProperty = property.clone().into(); - (*keyframe).mPropertyValues[index].mServoDeclarationBlock.set_arc_leaky( - Arc::new(RwLock::new(block))); - } + add_computed_property_value(keyframe, index, style, property); } }, KeyframesStepValue::Declarations { ref block } => { @@ -1476,16 +1488,33 @@ pub extern "C" fn Servo_StyleSet_FillKeyframesForName(raw_data: RawServoStyleSet .filter(|&&(ref declaration, _)| { declaration.is_animatable() }); + + let mut seen = PropertyBitField::new(); + for (index, &(ref declaration, _)) in animatable.enumerate() { unsafe { + let property = TransitionProperty::from_declaration(declaration).unwrap(); (*keyframe).mPropertyValues.set_len((index + 1) as u32); - (*keyframe).mPropertyValues[index].mProperty = - TransitionProperty::from_declaration(declaration).unwrap().into(); + (*keyframe).mPropertyValues[index].mProperty = property.into(); (*keyframe).mPropertyValues[index].mServoDeclarationBlock.set_arc_leaky( Arc::new(RwLock::new( PropertyDeclarationBlock { declarations: vec![ (declaration.clone(), Importance::Normal) ], important_count: 0 }))); + if step.start_percentage.0 == 0. || + step.start_percentage.0 == 1. { + seen.set_transition_property_bit(&property); + } + } + } + + // Append missing property values in the initial or the finial keyframes. + if step.start_percentage.0 == 0. || + step.start_percentage.0 == 1. { + for (index, property) in animation.properties_changed.iter().enumerate() { + if !seen.has_transition_property_bit(&property) { + add_computed_property_value(keyframe, index, style, property); + } } } }, diff --git a/servo/tests/unit/style/keyframes.rs b/servo/tests/unit/style/keyframes.rs index 14c79bfa1bff..d01dbcab2d0d 100644 --- a/servo/tests/unit/style/keyframes.rs +++ b/servo/tests/unit/style/keyframes.rs @@ -5,7 +5,10 @@ use parking_lot::RwLock; use std::sync::Arc; use style::keyframes::{Keyframe, KeyframesAnimation, KeyframePercentage, KeyframeSelector}; -use style::properties::PropertyDeclarationBlock; +use style::keyframes::{KeyframesStep, KeyframesStepValue}; +use style::properties::{DeclaredValue, PropertyDeclaration, PropertyDeclarationBlock, Importance}; +use style::properties::animated_properties::TransitionProperty; +use style::values::specified::{LengthOrPercentageOrAuto, NoCalcLength}; #[test] fn test_empty_keyframe() { @@ -38,3 +41,177 @@ fn test_no_property_in_keyframe() { assert_eq!(format!("{:#?}", animation), format!("{:#?}", expected)); } + +#[test] +fn test_missing_property_in_initial_keyframe() { + let declarations_on_initial_keyframe = + Arc::new(RwLock::new(PropertyDeclarationBlock { + declarations: vec![ + (PropertyDeclaration::Width( + DeclaredValue::Value(LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32)))), + Importance::Normal), + ], + important_count: 0, + })); + + let declarations_on_final_keyframe = + Arc::new(RwLock::new(PropertyDeclarationBlock { + declarations: vec![ + (PropertyDeclaration::Width( + DeclaredValue::Value(LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32)))), + Importance::Normal), + + (PropertyDeclaration::Height( + DeclaredValue::Value(LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32)))), + Importance::Normal), + ], + important_count: 0, + })); + + let keyframes = vec![ + Arc::new(RwLock::new(Keyframe { + selector: KeyframeSelector::new_for_unit_testing(vec![KeyframePercentage::new(0.)]), + block: declarations_on_initial_keyframe.clone(), + })), + + Arc::new(RwLock::new(Keyframe { + selector: KeyframeSelector::new_for_unit_testing(vec![KeyframePercentage::new(1.)]), + block: declarations_on_final_keyframe.clone(), + })), + ]; + let animation = KeyframesAnimation::from_keyframes(&keyframes); + let expected = KeyframesAnimation { + steps: vec![ + KeyframesStep { + start_percentage: KeyframePercentage(0.), + value: KeyframesStepValue::Declarations { block: declarations_on_initial_keyframe }, + declared_timing_function: false, + }, + KeyframesStep { + start_percentage: KeyframePercentage(1.), + value: KeyframesStepValue::Declarations { block: declarations_on_final_keyframe }, + declared_timing_function: false, + }, + ], + properties_changed: vec![TransitionProperty::Width, TransitionProperty::Height], + }; + + assert_eq!(format!("{:#?}", animation), format!("{:#?}", expected)); +} + +#[test] +fn test_missing_property_in_final_keyframe() { + let declarations_on_initial_keyframe = + Arc::new(RwLock::new(PropertyDeclarationBlock { + declarations: vec![ + (PropertyDeclaration::Width( + DeclaredValue::Value(LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32)))), + Importance::Normal), + + (PropertyDeclaration::Height( + DeclaredValue::Value(LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32)))), + Importance::Normal), + ], + important_count: 0, + })); + + let declarations_on_final_keyframe = + Arc::new(RwLock::new(PropertyDeclarationBlock { + declarations: vec![ + (PropertyDeclaration::Height( + DeclaredValue::Value(LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32)))), + Importance::Normal), + ], + important_count: 0, + })); + + let keyframes = vec![ + Arc::new(RwLock::new(Keyframe { + selector: KeyframeSelector::new_for_unit_testing(vec![KeyframePercentage::new(0.)]), + block: declarations_on_initial_keyframe.clone(), + })), + + Arc::new(RwLock::new(Keyframe { + selector: KeyframeSelector::new_for_unit_testing(vec![KeyframePercentage::new(1.)]), + block: declarations_on_final_keyframe.clone(), + })), + ]; + let animation = KeyframesAnimation::from_keyframes(&keyframes); + let expected = KeyframesAnimation { + steps: vec![ + KeyframesStep { + start_percentage: KeyframePercentage(0.), + value: KeyframesStepValue::Declarations { block: declarations_on_initial_keyframe }, + declared_timing_function: false, + }, + KeyframesStep { + start_percentage: KeyframePercentage(1.), + value: KeyframesStepValue::Declarations { block: declarations_on_final_keyframe }, + declared_timing_function: false, + }, + ], + properties_changed: vec![TransitionProperty::Width, TransitionProperty::Height], + }; + + assert_eq!(format!("{:#?}", animation), format!("{:#?}", expected)); +} + +#[test] +fn test_missing_keyframe_in_both_of_initial_and_final_keyframe() { + let declarations = + Arc::new(RwLock::new(PropertyDeclarationBlock { + declarations: vec![ + (PropertyDeclaration::Width( + DeclaredValue::Value(LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32)))), + Importance::Normal), + + (PropertyDeclaration::Height( + DeclaredValue::Value(LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32)))), + Importance::Normal), + ], + important_count: 0, + })); + + let keyframes = vec![ + Arc::new(RwLock::new(Keyframe { + selector: KeyframeSelector::new_for_unit_testing(vec![KeyframePercentage::new(0.)]), + block: Arc::new(RwLock::new(PropertyDeclarationBlock { + declarations: vec![], + important_count: 0, + })) + })), + Arc::new(RwLock::new(Keyframe { + selector: KeyframeSelector::new_for_unit_testing(vec![KeyframePercentage::new(0.5)]), + block: declarations.clone(), + })), + ]; + let animation = KeyframesAnimation::from_keyframes(&keyframes); + let expected = KeyframesAnimation { + steps: vec![ + KeyframesStep { + start_percentage: KeyframePercentage(0.), + value: KeyframesStepValue::Declarations { + block: Arc::new(RwLock::new(PropertyDeclarationBlock { + // XXX: Should we use ComputedValues in this case? + declarations: vec![], + important_count: 0, + })) + }, + declared_timing_function: false, + }, + KeyframesStep { + start_percentage: KeyframePercentage(0.5), + value: KeyframesStepValue::Declarations { block: declarations }, + declared_timing_function: false, + }, + KeyframesStep { + start_percentage: KeyframePercentage(1.), + value: KeyframesStepValue::ComputedValues, + declared_timing_function: false, + } + ], + properties_changed: vec![TransitionProperty::Width, TransitionProperty::Height], + }; + + assert_eq!(format!("{:#?}", animation), format!("{:#?}", expected)); +} From 649c21ef13caef188e7ee3c61b55133eaa6f88b6 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Thu, 14 Apr 2016 16:29:53 -0500 Subject: [PATCH 034/234] Bug 1268134 - Add actor to target windows by ID. r=ochameau MozReview-Commit-ID: EDwcd7j1yhH --HG-- extra : rebase_source : f585b5f0d2f62dd8f467f48d5e3e7f06d802900e --- devtools/server/actors/moz.build | 1 + devtools/server/actors/root.js | 52 ++++++++++++++-- devtools/server/actors/window.js | 83 +++++++++++++++++++++++++ devtools/server/docs/actor-hierarchy.md | 5 ++ 4 files changed, 135 insertions(+), 6 deletions(-) create mode 100644 devtools/server/actors/window.js diff --git a/devtools/server/actors/moz.build b/devtools/server/actors/moz.build index af9e041dea4e..ba2c2e93e564 100644 --- a/devtools/server/actors/moz.build +++ b/devtools/server/actors/moz.build @@ -66,6 +66,7 @@ DevToolsModules( 'webextension-inspected-window.js', 'webextension.js', 'webgl.js', + 'window.js', 'worker-list.js', 'worker.js', ) diff --git a/devtools/server/actors/root.js b/devtools/server/actors/root.js index ffaa2c78b88a..941dca8ffde4 100644 --- a/devtools/server/actors/root.js +++ b/devtools/server/actors/root.js @@ -7,6 +7,7 @@ "use strict"; const { Cc, Ci, Cu } = require("chrome"); +const Services = require("Services"); const { ActorPool, appendExtraActors, createExtraActors } = require("devtools/server/actors/common"); const { DebuggerServer } = require("devtools/server/main"); @@ -14,6 +15,8 @@ loader.lazyGetter(this, "ppmm", () => { return Cc["@mozilla.org/parentprocessmessagemanager;1"].getService( Ci.nsIMessageBroadcaster); }); +loader.lazyRequireGetter(this, "WindowActor", + "devtools/server/actors/window", true); /* Root actor for the remote debugging protocol. */ @@ -167,12 +170,15 @@ RootActor.prototype = { // Added in Firefox 40. Indicates that the backend supports registering custom // commands through the WebConsoleCommands API. webConsoleCommands: true, - // Whether root actor exposes tab actors - // if allowChromeProcess is true, you can fetch a ChromeActor instance - // to debug chrome and any non-content ressource via getProcess request - // if allocChromeProcess is defined, but not true, it means that root actor - // no longer expose tab actors, but also that getProcess forbids - // exposing actors for security reasons + // Whether root actor exposes tab actors and access to any window. + // If allowChromeProcess is true, you can: + // * get a ChromeActor instance to debug chrome and any non-content + // resource via getProcess requests + // * get a WindowActor instance to debug windows which could be chrome, + // like browser windows via getWindow requests + // If allowChromeProcess is defined, but not true, it means that root actor + // no longer expose tab actors, but also that the above requests are + // forbidden for security reasons. get allowChromeProcess() { return DebuggerServer.allowChromeProcess; }, @@ -232,6 +238,7 @@ RootActor.prototype = { this.conn = null; this._tabActorPool = null; this._globalActorPool = null; + this._windowActorPool = null; this._parameters = null; this._chromeActor = null; this._processActors.clear(); @@ -338,6 +345,38 @@ RootActor.prototype = { }); }, + onGetWindow: function ({ outerWindowID }) { + if (!DebuggerServer.allowChromeProcess) { + return { + from: this.actorID, + error: "forbidden", + message: "You are not allowed to debug windows." + }; + } + let window = Services.wm.getOuterWindowWithId(outerWindowID); + if (!window) { + return { + from: this.actorID, + error: "notFound", + message: `No window found with outerWindowID ${outerWindowID}`, + }; + } + + if (!this._windowActorPool) { + this._windowActorPool = new ActorPool(this.conn); + this.conn.addActorPool(this._windowActorPool); + } + + let actor = new WindowActor(this.conn, window); + actor.parentID = this.actorID; + this._windowActorPool.addActor(actor); + + return { + from: this.actorID, + window: actor.form(), + }; + }, + onTabListChanged: function () { this.conn.send({ from: this.actorID, type: "tabListChanged" }); /* It's a one-shot notification; no need to watch any more. */ @@ -539,6 +578,7 @@ RootActor.prototype = { RootActor.prototype.requestTypes = { "listTabs": RootActor.prototype.onListTabs, "getTab": RootActor.prototype.onGetTab, + "getWindow": RootActor.prototype.onGetWindow, "listAddons": RootActor.prototype.onListAddons, "listWorkers": RootActor.prototype.onListWorkers, "listServiceWorkerRegistrations": RootActor.prototype.onListServiceWorkerRegistrations, diff --git a/devtools/server/actors/window.js b/devtools/server/actors/window.js new file mode 100644 index 000000000000..c6c5ff55ba99 --- /dev/null +++ b/devtools/server/actors/window.js @@ -0,0 +1,83 @@ +/* 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/. */ + +"use strict"; + +const { Ci } = require("chrome"); +const Services = require("Services"); +const { TabActor } = require("./tab"); + +/** + * Creates a WindowActor for debugging a single window, like a browser window in Firefox, + * but it can be used to reach any window in the process. (Currently this is parent + * process only because the root actor's `onGetWindow` doesn't try to cross process + * boundaries.) Both chrome and content windows are supported. + * + * Most of the implementation is inherited from TabActor. WindowActor exposes all tab + * actors via its form() request, like TabActor. + * + * You can request a specific window's actor via RootActor.getWindow(). + * + * @param connection DebuggerServerConnection + * The connection to the client. + * @param window DOMWindow + * The window. + */ +function WindowActor(connection, window) { + TabActor.call(this, connection); + + let docShell = window.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDocShell); + Object.defineProperty(this, "docShell", { + value: docShell, + configurable: true + }); +} + +WindowActor.prototype = Object.create(TabActor.prototype); + +// Bug 1266561: This setting is mysteriously named, we should split up the +// functionality that is triggered by it. +WindowActor.prototype.isRootActor = true; + +WindowActor.prototype.observe = function (subject, topic, data) { + TabActor.prototype.observe.call(this, subject, topic, data); + if (!this.attached) { + return; + } + if (topic == "chrome-webnavigation-destroy") { + this._onDocShellDestroy(subject); + } +}; + +WindowActor.prototype._attach = function () { + if (this.attached) { + return false; + } + + TabActor.prototype._attach.call(this); + + // Listen for chrome docshells in addition to content docshells + if (this.docShell.itemType == Ci.nsIDocShellTreeItem.typeChrome) { + Services.obs.addObserver(this, "chrome-webnavigation-destroy", false); + } + + return true; +}; + +WindowActor.prototype._detach = function () { + if (!this.attached) { + return false; + } + + if (this.docShell.itemType == Ci.nsIDocShellTreeItem.typeChrome) { + Services.obs.removeObserver(this, "chrome-webnavigation-destroy"); + } + + TabActor.prototype._detach.call(this); + + return true; +}; + +exports.WindowActor = WindowActor; diff --git a/devtools/server/docs/actor-hierarchy.md b/devtools/server/docs/actor-hierarchy.md index 0b553addfacd..d6d6597d314f 100644 --- a/devtools/server/docs/actor-hierarchy.md +++ b/devtools/server/docs/actor-hierarchy.md @@ -60,6 +60,11 @@ and returns its `actorID`. That's the main role of RootActor. | Returned by "listWorkers" request to a ChildProcessActor to get workers | for the chrome of the child process. | + |-- WindowActor (window.js) + | Targets a single window, such as a browser window in Firefox, but it can + | be used to reach any window in the parent process. + | Returned by "getWindow" request to the root actor. + | |-- ChromeActor (chrome.js) | Targets all resources in the parent process of firefox | (chrome documents, JSM, JS XPCOM, etc.). From 24d384bd71ea302436aa257bcc8ffdfd6c9034d6 Mon Sep 17 00:00:00 2001 From: Myk Melez Date: Fri, 15 Apr 2016 16:08:52 -0700 Subject: [PATCH 035/234] Bug 1268134 - Render ascii tree art literally. r=ochameau MozReview-Commit-ID: FY12pPIpHe2 --HG-- extra : rebase_source : f5e0e05e56497e90fab9bb7979fecf915a09c743 --- devtools/server/docs/actor-hierarchy.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/devtools/server/docs/actor-hierarchy.md b/devtools/server/docs/actor-hierarchy.md index d6d6597d314f..324a1524b488 100644 --- a/devtools/server/docs/actor-hierarchy.md +++ b/devtools/server/docs/actor-hierarchy.md @@ -7,7 +7,8 @@ once a parent is removed from the pool, its children are removed as well. The overall hierarchy of actors looks like this: - RootActor: First one, automatically instantiated when we start connecting. +``` +RootActor: First one, automatically instantiated when we start connecting. | Mostly meant to instantiate new actors. | |--> Global-scoped actors: @@ -27,6 +28,7 @@ The overall hierarchy of actors looks like this: worker). Examples include the console and inspector actors. These actors may extend this hierarchy by having their own children, like LongStringActor, WalkerActor, etc. +``` ## RootActor @@ -36,7 +38,8 @@ All other actors have an `actorID` which is computed dynamically, so that you need to ask an existing actor to create an Actor and returns its `actorID`. That's the main role of RootActor. - RootActor (root.js) +``` +RootActor (root.js) | |-- BrowserTabActor (webbrowser.js) | Targets tabs living in the parent or child process. Note that this is @@ -78,6 +81,7 @@ and returns its `actorID`. That's the main role of RootActor. \-- BrowserAddonActor (addon.js) Targets the javascript of add-ons. Returned by "listAddons" request. +``` ## "TabActor" From 95f1b0a6e8469ddd56f19367380edb1aea522ff4 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Thu, 14 Apr 2016 17:09:49 -0500 Subject: [PATCH 036/234] Bug 1268134 - Add client and toolbox access to specific windows. r=ochameau MozReview-Commit-ID: 3IILOc6gZFi --HG-- extra : rebase_source : d92daa4671905dc50bef4a53a2a3fd3d66055105 --- devtools/client/framework/target-from-url.js | 43 ++++++++++++++----- .../framework/test/browser_target_from_url.js | 13 +++++- devtools/shared/client/main.js | 21 +++++++++ 3 files changed, 66 insertions(+), 11 deletions(-) diff --git a/devtools/client/framework/target-from-url.js b/devtools/client/framework/target-from-url.js index 4e2c30377134..d8c5ea9605ee 100644 --- a/devtools/client/framework/target-from-url.js +++ b/devtools/client/framework/target-from-url.js @@ -4,8 +4,6 @@ "use strict"; -const { Cu, Ci } = require("chrome"); - const { TargetFactory } = require("devtools/client/framework/target"); const { DebuggerServer } = require("devtools/server/main"); const { DebuggerClient } = require("devtools/shared/client/main"); @@ -21,20 +19,25 @@ const { Task } = require("devtools/shared/task"); * ws: * {Boolean} If true, connect via websocket instread of regular TCP connection. * - * type: tab, process - * {String} The type of target to connect to. Currently tabs and processes are supported types. + * type: tab, process, window + * {String} The type of target to connect to. * - * If type="tab": + * If type == "tab": * id: * {Number} the tab outerWindowID * chrome: Optional - * {Boolean} Force the creation of a chrome target. Gives more privileges to the tab - * actor. Allows chrome execution in the webconsole and see chrome files in - * the debugger. (handy when contributing to firefox) + * {Boolean} Force the creation of a chrome target. Gives more privileges to + * the tab actor. Allows chrome execution in the webconsole and see chrome + * files in the debugger. (handy when contributing to firefox) * - * If type="process": + * If type == "process": * id: - * {Number} the process id to debug. Default to 0, which is the parent process. + * {Number} the process id to debug. Default to 0, which is the parent + * process. + * + * If type == "window": + * id: + * {Number} the window outerWindowID * * @param {URL} url * The url to fetch query params from. @@ -93,6 +96,26 @@ exports.targetFromURL = Task.async(function* (url) { } throw ex; } + } else if (type == "window") { + // Fetch target for a remote window actor + DebuggerServer.allowChromeProcess = true; + try { + id = parseInt(id, 10); + if (isNaN(id)) { + throw new Error("targetFromURL, window requires id parameter"); + } + let response = yield client.mainRoot.getWindow({ + outerWindowID: id, + }); + form = response.window; + chrome = true; + } catch (ex) { + if (ex.error == "notFound") { + throw new Error(`targetFromURL, window with id:'${id}' ` + + "doesn't exist"); + } + throw ex; + } } else { throw new Error("targetFromURL, unsupported type='" + type + "' parameter"); } diff --git a/devtools/client/framework/test/browser_target_from_url.js b/devtools/client/framework/test/browser_target_from_url.js index 0707ee7d7c9a..d625732ffd4d 100644 --- a/devtools/client/framework/test/browser_target_from_url.js +++ b/devtools/client/framework/test/browser_target_from_url.js @@ -36,8 +36,19 @@ add_task(function* () { is(e.message, "targetFromURL, unsupported type='x' parameter"); } + info("Test browser window"); + let windowId = window.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindowUtils) + .outerWindowID; + target = yield targetFromURL(new URL("http://foo?type=window&id=" + windowId)); + is(target.url, window.location.href); + is(target.isLocalTab, false); + is(target.chrome, true); + is(target.isTabActor, true); + is(target.isRemote, true); + info("Test tab"); - let windowId = browser.outerWindowID; + windowId = browser.outerWindowID; target = yield targetFromURL(new URL("http://foo?type=tab&id=" + windowId)); assertIsTabTarget(target, TEST_URI); diff --git a/devtools/shared/client/main.js b/devtools/shared/client/main.js index 303c8570acbf..9e1123bc1af9 100644 --- a/devtools/shared/client/main.js +++ b/devtools/shared/client/main.js @@ -1741,6 +1741,27 @@ RootClient.prototype = { return this.request(packet); }, + /** + * Fetch the WindowActor for a specific window, like a browser window in + * Firefox, but it can be used to reach any window in the process. + * + * @param number outerWindowID + * The outerWindowID of the top level window you are looking for. + */ + getWindow: function ({ outerWindowID }) { + if (!outerWindowID) { + throw new Error("Must specify outerWindowID"); + } + + let packet = { + to: this.actor, + type: "getWindow", + outerWindowID, + }; + + return this.request(packet); + }, + /** * Description of protocol's actors and methods. * From 2130a7fbc28b8d693fc44e260acc33589a28886c Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Thu, 14 Apr 2016 20:05:59 -0500 Subject: [PATCH 037/234] Bug 1268134 - Setup fake toolbox host for standalone windows. r=ochameau MozReview-Commit-ID: CHzE4EdVkBR --HG-- extra : rebase_source : 1418533d80e59e007298bc06ec145fc4f55e78a1 --- devtools/client/framework/toolbox-init.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/devtools/client/framework/toolbox-init.js b/devtools/client/framework/toolbox-init.js index cb041c22d070..5a2a709d49d7 100644 --- a/devtools/client/framework/toolbox-init.js +++ b/devtools/client/framework/toolbox-init.js @@ -2,6 +2,8 @@ * 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/. */ +/* eslint-env browser */ + "use strict"; // URL constructor doesn't support about: scheme @@ -26,6 +28,23 @@ if (url.search.length > 1) { .getInterface(Ci.nsIDOMWindowUtils) .containerElement; + // If there's no containerElement (which happens when loading about:devtools-toolbox as + // a top level document), use the current window. + if (!host) { + host = { + contentWindow: window, + contentDocument: document, + // toolbox-host-manager.js wants to set attributes on the frame that contains it, + // but that is fine to skip and doesn't make sense when using the current window. + setAttribute() {}, + ownerDocument: document, + // toolbox-host-manager.js wants to listen for unload events from outside the frame, + // but this is fine to skip since the toolbox code listens inside the frame as well, + // and there is no outer document in this case. + addEventListener() {}, + }; + } + // Specify the default tool to open let tool = url.searchParams.get("tool"); From ba5aaf53e60eb99769ce38a66f044a54707dca23 Mon Sep 17 00:00:00 2001 From: Greg Mierzwinski Date: Mon, 20 Feb 2017 22:55:59 -0500 Subject: [PATCH 038/234] Bug 1301984 - Add code coverage to mochitest-plain tests. r=jmaher This patch allows the use of the flag '--jscov-dir-prefix' for mochitest plain tests to enable code coverage collection with the JS Debugger. It also enables the mochitest-plain tests for the linux64-jsdcov build platform. MozReview-Commit-ID: 6RqMEZ1I0D7 --HG-- extra : rebase_source : 351754541801f69f7c54807f6bdd3a3d1baf9222 --- taskcluster/ci/test/test-sets.yml | 1 + taskcluster/ci/test/tests.yml | 14 +++++++++-- testing/mochitest/runtests.py | 2 ++ .../mochitest/tests/SimpleTest/TestRunner.js | 25 +++++++++++++++++-- testing/mochitest/tests/SimpleTest/setup.js | 4 +++ .../configs/unittests/linux_unittest.py | 1 + .../mozharness/scripts/desktop_unittest.py | 3 ++- 7 files changed, 45 insertions(+), 5 deletions(-) diff --git a/taskcluster/ci/test/test-sets.yml b/taskcluster/ci/test/test-sets.yml index 58d152ca1fb2..97e28beb1b92 100644 --- a/taskcluster/ci/test/test-sets.yml +++ b/taskcluster/ci/test/test-sets.yml @@ -96,6 +96,7 @@ ccov-code-coverage-tests: - xpcshell jsdcov-code-coverage-tests: + - mochitest - mochitest-browser-chrome - mochitest-devtools-chrome - xpcshell diff --git a/taskcluster/ci/test/tests.yml b/taskcluster/ci/test/tests.yml index af21cbd4ec99..cd34114cebad 100644 --- a/taskcluster/ci/test/tests.yml +++ b/taskcluster/ci/test/tests.yml @@ -354,11 +354,15 @@ marionette: mochitest: description: "Mochitest plain run" - suite: mochitest/plain-chunked + suite: + by-test-platform: + linux64-jsdcov/opt: mochitest/plain-chunked-coverage + default: mochitest/plain-chunked treeherder-symbol: tc-M() loopback-video: true instance-size: by-test-platform: + linux64-jsdcov/opt: xlarge android.*: xlarge default: legacy # Bug 1281241: migrating to m3.large instances chunks: @@ -371,11 +375,13 @@ mochitest: e10s: by-test-platform: linux64-ccov/opt: false + linux64-jsdcov/opt: false android.*: false default: both max-run-time: by-test-platform: android-4.3-arm7-api-15/debug: 10800 + linux64-jsdcov/opt: 10800 default: 5400 allow-software-gl-layers: false mozharness: @@ -402,7 +408,11 @@ mochitest: - unittests/linux_unittest.py - remove_executables.py extra-options: - - --mochitest-suite=plain-chunked + by-test-platform: + linux64-jsdcov/opt: + - --mochitest-suite=plain-chunked-coverage + default: + - --mochitest-suite=plain-chunked mochitest-a11y: description: "Mochitest a11y run" diff --git a/testing/mochitest/runtests.py b/testing/mochitest/runtests.py index 573b03dd9ca1..a06d9e2fe884 100644 --- a/testing/mochitest/runtests.py +++ b/testing/mochitest/runtests.py @@ -978,6 +978,8 @@ class MochitestDesktop(object): self.urlOpts.append("dumpDMDAfterTest=true") if options.debugger: self.urlOpts.append("interactiveDebugger=true") + if options.jscov_dir_prefix: + self.urlOpts.append("jscovDirPrefix=%s" % options.jscov_dir_prefix) def normflavor(self, flavor): """ diff --git a/testing/mochitest/tests/SimpleTest/TestRunner.js b/testing/mochitest/tests/SimpleTest/TestRunner.js index 0407716aa8f5..865c90740441 100644 --- a/testing/mochitest/tests/SimpleTest/TestRunner.js +++ b/testing/mochitest/tests/SimpleTest/TestRunner.js @@ -108,6 +108,12 @@ TestRunner._numTimeouts = 0; TestRunner._currentTestStartTime = new Date().valueOf(); TestRunner._timeoutFactor = 1; +/** +* Used to collect code coverage with the js debugger. +*/ +TestRunner.jscovDirPrefix = ""; +var coverageCollector = {}; + TestRunner._checkForHangs = function() { function reportError(win, msg) { if ("SimpleTest" in win) { @@ -352,6 +358,12 @@ TestRunner.runTests = function (/*url...*/) { SpecialPowers.registerProcessCrashObservers(); + // Initialize code coverage + if (TestRunner.jscovDirPrefix != "") { + var CoverageCollector = SpecialPowers.Cu.import("resource://testing-common/CoverageUtils.jsm", {}).CoverageCollector; + coverageCollector = new CoverageCollector(TestRunner.jscovDirPrefix); + } + TestRunner._urls = flattenArguments(arguments); var singleTestRun = this._urls.length <= 1 && TestRunner.repeat <= 1; @@ -481,8 +493,12 @@ TestRunner.runNextTest = function() { if (TestRunner.onComplete) TestRunner.onComplete(); - } - TestRunner.generateFailureList(); + } + TestRunner.generateFailureList(); + + if (TestRunner.jscovDirPrefix != "") { + coverageCollector.finalize(); + } } }; @@ -505,6 +521,11 @@ TestRunner.testFinished = function(tests) { TestRunner.updateUI([{ result: false }]); return; } + + if (TestRunner.jscovDirPrefix != "") { + coverageCollector.recordTestCoverage(TestRunner.currentTestURL); + } + TestRunner._lastTestFinished = TestRunner._currentTest; TestRunner._loopIsRestarting = false; diff --git a/testing/mochitest/tests/SimpleTest/setup.js b/testing/mochitest/tests/SimpleTest/setup.js index 8b1b15ebc1e9..8fb223774a46 100644 --- a/testing/mochitest/tests/SimpleTest/setup.js +++ b/testing/mochitest/tests/SimpleTest/setup.js @@ -144,6 +144,10 @@ if (params.interactiveDebugger) { TestRunner.interactiveDebugger = true; } +if (params.jscovDirPrefix) { + TestRunner.jscovDirPrefix = params.jscovDirPrefix; +} + if (params.maxTimeouts) { TestRunner.maxTimeouts = params.maxTimeouts; } diff --git a/testing/mozharness/configs/unittests/linux_unittest.py b/testing/mozharness/configs/unittests/linux_unittest.py index e2f9c6901584..ff938c7b5656 100644 --- a/testing/mozharness/configs/unittests/linux_unittest.py +++ b/testing/mozharness/configs/unittests/linux_unittest.py @@ -183,6 +183,7 @@ config = { "plain-gpu": ["--subsuite=gpu"], "plain-clipboard": ["--subsuite=clipboard"], "plain-chunked": ["--chunk-by-dir=4"], + "plain-chunked-coverage": ["--chunk-by-dir=4", "--timeout=1200"], "mochitest-media": ["--subsuite=media"], "chrome": ["--flavor=chrome"], "chrome-gpu": ["--flavor=chrome", "--subsuite=gpu"], diff --git a/testing/mozharness/scripts/desktop_unittest.py b/testing/mozharness/scripts/desktop_unittest.py index befad6aaa370..bc888224623d 100755 --- a/testing/mozharness/scripts/desktop_unittest.py +++ b/testing/mozharness/scripts/desktop_unittest.py @@ -399,7 +399,8 @@ class DesktopUnittest(TestingMixin, MercurialScript, BlobUploadMixin, MozbaseMix if suite_category not in c["suite_definitions"]: self.fatal("'%s' not defined in the config!") - if suite in ('browser-chrome-coverage', 'xpcshell-coverage', 'mochitest-devtools-chrome-coverage'): + if suite in ('browser-chrome-coverage', 'xpcshell-coverage', + 'mochitest-devtools-chrome-coverage', 'plain-chunked-coverage'): base_cmd.append('--jscov-dir-prefix=%s' % dirs['abs_blob_upload_dir']) From efcc5fdcc9521eea346321a6442c18be5ab84b7f Mon Sep 17 00:00:00 2001 From: Connor Imes Date: Wed, 22 Feb 2017 09:05:37 -0800 Subject: [PATCH 039/234] servo: Merge #15458 - Update heartbeats-simple dependencies for bug fixes (from connorimes:hbs-0.4); r=emilio Updates heartbeats-simple dependencies for some bug fixes in native code (primarily for Windows). Now we create heartbeats as needed so we don't have to maintain a hardcoded list which keeps getting out of sync. --- - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #15471 (github issue number if applicable). - [ ] There are tests for these changes OR - [X] These changes do not require tests because it updates a dependency and performs some code maintenance. Source-Repo: https://github.com/servo/servo Source-Revision: 2bfea912dccd5e76e062143f3d48d2a66118fc59 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 2bef9da3e72c3091214b574e4d41b539d861b644 --- servo/components/profile/heartbeats.rs | 150 ++++++++++++------------- servo/tests/heartbeats/characterize.py | 3 + 2 files changed, 73 insertions(+), 80 deletions(-) diff --git a/servo/components/profile/heartbeats.rs b/servo/components/profile/heartbeats.rs index b05cbf74b714..4661dad61836 100644 --- a/servo/components/profile/heartbeats.rs +++ b/servo/components/profile/heartbeats.rs @@ -2,95 +2,55 @@ * 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/. */ - use heartbeats_simple::HeartbeatPow as Heartbeat; -use heartbeats_simple::HeartbeatPowContext as HeartbeatContext; use profile_traits::time::ProfilerCategory; +use self::synchronized_heartbeat::{heartbeat_window_callback, lock_and_work}; use servo_config::opts; use std::collections::HashMap; use std::env::var_os; use std::error::Error; use std::fs::File; -use std::mem; use std::path::Path; - -static mut HBS: Option<*mut HashMap> = None; - /// Initialize heartbeats pub fn init() { - let mut hbs: HashMap = HashMap::new(); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::Compositing); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutPerform); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutStyleRecalc); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutTextShaping); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutRestyleDamagePropagation); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutNonIncrementalReset); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutSelectorMatch); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutTreeBuilder); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutDamagePropagate); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutGeneratedContent); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutDisplayListSorting); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutFloatPlacementSpeculation); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutMain); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutStoreOverflow); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutParallelWarmup); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutDispListBuild); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::NetHTTPRequestResponse); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::PaintingPerTile); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::PaintingPrepBuff); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::Painting); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::ImageDecoding); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::ImageSaving); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptAttachLayout); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptConstellationMsg); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptDevtoolsMsg); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptDocumentEvent); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptDomEvent); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptEvaluate); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptEvent); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptFileRead); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptImageCacheMsg); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptInputEvent); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptNetworkEvent); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptParseHTML); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptPlannedNavigation); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptResize); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptSetScrollState); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptSetViewport); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptTimerEvent); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptStylesheetLoad); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptUpdateReplacedElement); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptWebSocketEvent); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptWorkerEvent); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptServiceWorkerEvent); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptParseXML); - maybe_create_heartbeat(&mut hbs, ProfilerCategory::ApplicationHeartbeat); - unsafe { - HBS = Some(mem::transmute(Box::new(hbs))); - } + lock_and_work(|hbs_opt| + if hbs_opt.is_none() { + let mut hbs: Box> = Box::new(HashMap::new()); + maybe_create_heartbeat(&mut hbs, ProfilerCategory::ApplicationHeartbeat); + *hbs_opt = Some(Box::into_raw(hbs)) + } + ); } /// Log regmaining buffer data and cleanup heartbeats pub fn cleanup() { - unsafe { - if let Some(hbs) = HBS { - let mut h: Box> = mem::transmute(hbs); - for (_, mut v) in h.iter_mut() { - // log any remaining heartbeat records before dropping - log_heartbeat_records(v); + let hbs_opt_box: Option>> = lock_and_work(|hbs_opt| + hbs_opt.take().map(|hbs_ptr| + unsafe { + Box::from_raw(hbs_ptr) } - h.clear(); + ) + ); + if let Some(mut hbs) = hbs_opt_box { + for (_, mut v) in hbs.iter_mut() { + // log any remaining heartbeat records before dropping + log_heartbeat_records(v); } - HBS = None; + hbs.clear(); } } /// Check if a heartbeat exists for the given category pub fn is_heartbeat_enabled(category: &ProfilerCategory) -> bool { - unsafe { - HBS.map_or(false, |m| (*m).contains_key(category)) - } + let is_enabled = lock_and_work(|hbs_opt| + hbs_opt.map_or(false, |hbs_ptr| + unsafe { + (*hbs_ptr).contains_key(category) + } + ) + ); + is_enabled || is_create_heartbeat(category) } /// Issue a heartbeat (if one exists) for the given category @@ -99,13 +59,18 @@ pub fn maybe_heartbeat(category: &ProfilerCategory, end_time: u64, start_energy: u64, end_energy: u64) { - unsafe { - if let Some(map) = HBS { - if let Some(mut h) = (*map).get_mut(category) { - (*h).heartbeat(0, 1, start_time, end_time, start_energy, end_energy); + lock_and_work(|hbs_opt| + if let Some(hbs_ptr) = *hbs_opt { + unsafe { + if !(*hbs_ptr).contains_key(category) { + maybe_create_heartbeat(&mut (*hbs_ptr), category.clone()); + } + if let Some(mut h) = (*hbs_ptr).get_mut(category) { + (*h).heartbeat(0, 1, start_time, end_time, start_energy, end_energy); + } } } - } + ); } // TODO(cimes): Android doesn't really do environment variables. Need a better way to configure dynamically. @@ -172,14 +137,39 @@ fn log_heartbeat_records(hb: &mut Heartbeat) { } } -/// Callback function used to log the window buffer. -/// When this is called from native C, the heartbeat is safely locked -extern fn heartbeat_window_callback(hb: *const HeartbeatContext) { - unsafe { - if let Some(map) = HBS { - for (_, v) in (*map).iter_mut() { - if &v.hb as *const HeartbeatContext == hb { - log_heartbeat_records(v); +mod synchronized_heartbeat { + use heartbeats_simple::HeartbeatPow as Heartbeat; + use heartbeats_simple::HeartbeatPowContext as HeartbeatContext; + use profile_traits::time::ProfilerCategory; + use std::collections::HashMap; + use std::sync::atomic::{ATOMIC_BOOL_INIT, AtomicBool, Ordering}; + use super::log_heartbeat_records; + + static mut HBS: Option<*mut HashMap> = None; + + // unfortunately can't encompass the actual hashmap in a Mutex (Heartbeat isn't Send/Sync), so we'll use a spinlock + static HBS_SPINLOCK: AtomicBool = ATOMIC_BOOL_INIT; + + pub fn lock_and_work(work: F) -> R + where F: FnOnce(&mut Option<*mut HashMap>) -> R { + while HBS_SPINLOCK.compare_and_swap(false, true, Ordering::SeqCst) {} + let result = unsafe { + work(&mut HBS) + }; + HBS_SPINLOCK.store(false, Ordering::SeqCst); + result + } + + /// Callback function used to log the window buffer. + /// When this is called from native C, the heartbeat is safely locked internally and the global lock is held. + /// If calling from this file, you must already hold the global lock! + pub extern fn heartbeat_window_callback(hb: *const HeartbeatContext) { + unsafe { + if let Some(hbs_ptr) = HBS { + for (_, v) in (*hbs_ptr).iter_mut() { + if &v.hb as *const HeartbeatContext == hb { + log_heartbeat_records(v); + } } } } diff --git a/servo/tests/heartbeats/characterize.py b/servo/tests/heartbeats/characterize.py index 948f5b9de43b..9674119c44bf 100644 --- a/servo/tests/heartbeats/characterize.py +++ b/servo/tests/heartbeats/characterize.py @@ -65,6 +65,9 @@ HEARTBEAT_PROFILER_CATEGORIES = [ ("ScriptWorkerEvent", HEARTBEAT_DEFAULT_WINDOW_SIZE), ("ScriptServiceWorkerEvent", HEARTBEAT_DEFAULT_WINDOW_SIZE), ("ScriptParseXML", HEARTBEAT_DEFAULT_WINDOW_SIZE), + ("ScriptEnterFullscreen", HEARTBEAT_DEFAULT_WINDOW_SIZE), + ("ScriptExitFullscreen", HEARTBEAT_DEFAULT_WINDOW_SIZE), + ("ScriptWebVREvent", HEARTBEAT_DEFAULT_WINDOW_SIZE), ("ApplicationHeartbeat", 100), ] ENERGY_READER_BIN = "energymon-file-provider" From 6d1d9fbf9208e150b9c1d4b3accfbb74b8e94a6f Mon Sep 17 00:00:00 2001 From: Brian Stack Date: Wed, 22 Feb 2017 09:33:32 -0800 Subject: [PATCH 040/234] Bug 1341704 - Fix assumption of uniqeness of treeherder jobs r=jmaher MozReview-Commit-ID: EDpsIvF2IEE --HG-- extra : rebase_source : 8ad736c151553bfd7df935b999aad93536e8603f --- taskcluster/taskgraph/action.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/taskcluster/taskgraph/action.py b/taskcluster/taskgraph/action.py index 601435d6a3dd..b115acba1c0b 100644 --- a/taskcluster/taskgraph/action.py +++ b/taskcluster/taskgraph/action.py @@ -125,11 +125,9 @@ def load_decisions(s, project, resultsets, filters): break offset += jobs_per_call filtered = [j for j in unfiltered if all([j[k] == filters[k] for k in filters])] - if len(filtered) > 1: - raise Exception("Too many jobs matched. Aborting.") - elif len(filtered) == 1: - if filtered[0]["result"] == "success": - break + if all([j["result"] == "success" for j in filtered]): + logger.info("Push found with all green jobs for this type. Continuing.") + break decisions += [t for t in unfiltered if t["job_type_name"] == "Gecko Decision Task"] for decision in decisions: From 7586d1571694e1ce5cdfc7324a94bc373a7c0179 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Wed, 15 Feb 2017 16:30:59 -0500 Subject: [PATCH 041/234] Bug 1336186 - Check separator position in sync bookmark validator. r=markh This reverts bug 1276152. MozReview-Commit-ID: Cdv4XPYl4cp --HG-- extra : rebase_source : 985e68e3908ed2abe080e7d0d9ae0c1ce338f5fe --- services/sync/modules/bookmark_validator.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/services/sync/modules/bookmark_validator.js b/services/sync/modules/bookmark_validator.js index daffb92d5b4c..a9095566b76f 100644 --- a/services/sync/modules/bookmark_validator.js +++ b/services/sync/modules/bookmark_validator.js @@ -766,6 +766,11 @@ class BookmarkValidator { differences.push("bmkUri"); } break; + case "separator": + if (server.pos != client.pos) { + differences.push("pos"); + } + break; case "livemark": if (server.feedUri != client.feedUri) { differences.push("feedUri"); From 757c29a90e0936a63614fd25aa5d2dfc91465ca5 Mon Sep 17 00:00:00 2001 From: Connor Brewster Date: Wed, 22 Feb 2017 09:46:27 -0800 Subject: [PATCH 042/234] servo: Merge #15438 - Add ImmutableOrigin to allow for serializing origins (from asajeffrey:url-serializable-origin); r=jdm This PR adds a serializable type `ImmutableOrigin` and a non-serializable type `MutableOrigin`. The immutable type represents an origin with `null` domain, and the mutable type represents an origin with a mutable domain. This separation is needed for implementing setting `document.domain`. --- - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #14892. - [X] These changes do not require tests because it's a refactoring which will enable other features. Source-Repo: https://github.com/servo/servo Source-Revision: 78e8c31a4d1890260dda83f2db85672f693c1e97 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 3f155b8a66957ab70878c9287541a2dfc9bbb7ef --- servo/Cargo.lock | 3 + servo/components/net/http_loader.rs | 7 +- servo/components/net_traits/request.rs | 7 +- servo/components/script/dom/bindings/trace.rs | 6 +- servo/components/script/dom/document.rs | 33 ++-- .../script/dom/domimplementation.rs | 4 +- servo/components/script/dom/domparser.rs | 4 +- .../script/dom/htmliframeelement.rs | 2 +- servo/components/script/dom/node.rs | 2 +- .../components/script/dom/servoparser/mod.rs | 2 +- servo/components/script/dom/window.rs | 11 +- servo/components/script/dom/xmldocument.rs | 7 +- servo/components/script/dom/xmlhttprequest.rs | 2 +- servo/components/script/lib.rs | 1 - servo/components/script/origin.rs | 61 ------- servo/components/script/script_thread.rs | 16 +- servo/components/url/Cargo.toml | 7 +- servo/components/url/lib.rs | 15 +- servo/components/url/origin.rs | 172 ++++++++++++++++++ servo/tests/unit/net/fetch.rs | 15 +- servo/tests/unit/script/origin.rs | 45 +++-- 21 files changed, 270 insertions(+), 152 deletions(-) delete mode 100644 servo/components/script/origin.rs create mode 100644 servo/components/url/origin.rs diff --git a/servo/Cargo.lock b/servo/Cargo.lock index 7f2a649894e5..e6354423afb4 100644 --- a/servo/Cargo.lock +++ b/servo/Cargo.lock @@ -2596,8 +2596,11 @@ dependencies = [ "heapsize 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", + "servo_rand 0.0.1", "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "url_serde 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "uuid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/servo/components/net/http_loader.rs b/servo/components/net/http_loader.rs index 63fa745707b6..56750d60f056 100644 --- a/servo/components/net/http_loader.rs +++ b/servo/components/net/http_loader.rs @@ -37,7 +37,7 @@ use net_traits::response::{HttpsState, Response, ResponseBody, ResponseType}; use openssl; use openssl::ssl::error::{OpensslError, SslError}; use resource_thread::AuthCache; -use servo_url::ServoUrl; +use servo_url::{ImmutableOrigin, ServoUrl}; use std::collections::HashSet; use std::error::Error; use std::io::{self, Read, Write}; @@ -51,7 +51,6 @@ use std::thread; use time; use time::Tm; use unicase::UniCase; -use url::Origin as UrlOrigin; use uuid; fn read_block(reader: &mut R) -> Result { @@ -389,7 +388,7 @@ fn send_response_to_devtools(devtools_chan: &Sender, let _ = devtools_chan.send(DevtoolsControlMsg::FromChrome(msg)); } -fn auth_from_cache(auth_cache: &Arc>, origin: &UrlOrigin) -> Option { +fn auth_from_cache(auth_cache: &Arc>, origin: &ImmutableOrigin) -> Option { if let Some(ref auth_entry) = auth_cache.read().unwrap().entries.get(&origin.ascii_serialization()) { let user_name = auth_entry.user_name.clone(); let password = Some(auth_entry.password.clone()); @@ -767,7 +766,7 @@ fn http_redirect_fetch(request: Rc, // Step 9 if cors_flag && !same_origin { - *request.origin.borrow_mut() = Origin::Origin(UrlOrigin::new_opaque()); + *request.origin.borrow_mut() = Origin::Origin(ImmutableOrigin::new_opaque()); } // Step 10 diff --git a/servo/components/net_traits/request.rs b/servo/components/net_traits/request.rs index dcdd87ac4b03..7178ec8ca994 100644 --- a/servo/components/net_traits/request.rs +++ b/servo/components/net_traits/request.rs @@ -6,10 +6,9 @@ use ReferrerPolicy; use hyper::header::Headers; use hyper::method::Method; use msg::constellation_msg::PipelineId; -use servo_url::ServoUrl; +use servo_url::{ImmutableOrigin, ServoUrl}; use std::cell::{Cell, RefCell}; use std::default::Default; -use url::Origin as UrlOrigin; /// An [initiator](https://fetch.spec.whatwg.org/#concept-request-initiator) #[derive(Copy, Clone, PartialEq, HeapSizeOf)] @@ -55,10 +54,10 @@ pub enum Destination { } /// A request [origin](https://fetch.spec.whatwg.org/#concept-request-origin) -#[derive(Clone, PartialEq, Debug, HeapSizeOf)] +#[derive(Clone, PartialEq, Debug, Serialize, Deserialize, HeapSizeOf)] pub enum Origin { Client, - Origin(UrlOrigin), + Origin(ImmutableOrigin), } /// A [referer](https://fetch.spec.whatwg.org/#concept-request-referrer) diff --git a/servo/components/script/dom/bindings/trace.rs b/servo/components/script/dom/bindings/trace.rs index aeddcdabe4b0..0e605780a20b 100644 --- a/servo/components/script/dom/bindings/trace.rs +++ b/servo/components/script/dom/bindings/trace.rs @@ -79,7 +79,7 @@ use script_traits::{UntrustedNodeAddress, WindowSizeData, WindowSizeType}; use selectors::matching::ElementSelectorFlags; use serde::{Deserialize, Serialize}; use servo_atoms::Atom; -use servo_url::ServoUrl; +use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl}; use smallvec::SmallVec; use std::cell::{Cell, RefCell, UnsafeCell}; use std::collections::{BTreeMap, HashMap, HashSet, VecDeque}; @@ -104,7 +104,6 @@ use style::stylesheets::SupportsRule; use style::values::specified::Length; use style::viewport::ViewportRule; use time::Duration; -use url::Origin as UrlOrigin; use uuid::Uuid; use webrender_traits::{WebGLBufferId, WebGLError, WebGLFramebufferId, WebGLProgramId}; use webrender_traits::{WebGLRenderbufferId, WebGLShaderId, WebGLTextureId}; @@ -317,9 +316,10 @@ unsafe impl JSTraceable for (A, } } -unsafe_no_jsmanaged_fields!(bool, f32, f64, String, ServoUrl, AtomicBool, AtomicUsize, UrlOrigin, Uuid, char); +unsafe_no_jsmanaged_fields!(bool, f32, f64, String, AtomicBool, AtomicUsize, Uuid, char); unsafe_no_jsmanaged_fields!(usize, u8, u16, u32, u64); unsafe_no_jsmanaged_fields!(isize, i8, i16, i32, i64); +unsafe_no_jsmanaged_fields!(ServoUrl, ImmutableOrigin, MutableOrigin); unsafe_no_jsmanaged_fields!(Image, ImageMetadata, ImageCacheChan, ImageCacheThread); unsafe_no_jsmanaged_fields!(Metadata); unsafe_no_jsmanaged_fields!(NetworkError); diff --git a/servo/components/script/dom/document.rs b/servo/components/script/dom/document.rs index 56053555f7ce..c836a46f1da0 100644 --- a/servo/components/script/dom/document.rs +++ b/servo/components/script/dom/document.rs @@ -105,7 +105,6 @@ use net_traits::CoreResourceMsg::{GetCookiesForUrl, SetCookiesForUrl}; use net_traits::request::RequestInit; use net_traits::response::HttpsState; use num_traits::ToPrimitive; -use origin::Origin; use script_layout_interface::message::{Msg, ReflowQueryType}; use script_runtime::{CommonScriptMsg, ScriptThreadEventCategory}; use script_thread::{MainThreadScriptMsg, Runnable}; @@ -116,7 +115,7 @@ use script_traits::{TouchEventType, TouchId}; use script_traits::UntrustedNodeAddress; use servo_atoms::Atom; use servo_config::prefs::PREFS; -use servo_url::ServoUrl; +use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl}; use std::ascii::AsciiExt; use std::borrow::ToOwned; use std::cell::{Cell, Ref, RefMut}; @@ -136,6 +135,7 @@ use style::str::{HTML_SPACE_CHARACTERS, split_html_space_chars, str_join}; use style::stylesheets::Stylesheet; use task_source::TaskSource; use time; +use url::Host; use url::percent_encoding::percent_decode; pub enum TouchEventResult { @@ -277,7 +277,7 @@ pub struct Document { https_state: Cell, touchpad_pressure_phase: Cell, /// The document's origin. - origin: Origin, + origin: MutableOrigin, /// https://w3c.github.io/webappsec-referrer-policy/#referrer-policy-states referrer_policy: Cell>, /// https://html.spec.whatwg.org/multipage/#dom-document-referrer @@ -424,7 +424,7 @@ impl Document { } } - pub fn origin(&self) -> &Origin { + pub fn origin(&self) -> &MutableOrigin { &self.origin } @@ -1949,7 +1949,7 @@ impl Document { pub fn new_inherited(window: &Window, has_browsing_context: HasBrowsingContext, url: Option, - origin: Origin, + origin: MutableOrigin, is_html_document: IsHTMLDocument, content_type: Option, last_modified: Option, @@ -2053,7 +2053,7 @@ impl Document { Ok(Document::new(window, HasBrowsingContext::No, None, - doc.origin().alias(), + doc.origin().clone(), IsHTMLDocument::NonHTMLDocument, None, None, @@ -2067,7 +2067,7 @@ impl Document { pub fn new(window: &Window, has_browsing_context: HasBrowsingContext, url: Option, - origin: Origin, + origin: MutableOrigin, doctype: IsHTMLDocument, content_type: Option, last_modified: Option, @@ -2154,7 +2154,7 @@ impl Document { HasBrowsingContext::No, None, // https://github.com/whatwg/html/issues/2109 - Origin::opaque_identifier(), + MutableOrigin::new(ImmutableOrigin::new_opaque()), doctype, None, None, @@ -2411,16 +2411,17 @@ impl DocumentMethods for Document { // https://html.spec.whatwg.org/multipage/#relaxing-the-same-origin-restriction fn Domain(&self) -> DOMString { // Step 1. - if self.browsing_context().is_none() { + if !self.has_browsing_context { return DOMString::new(); } - if let Some(host) = self.origin.host() { - // Step 4. - DOMString::from(host.to_string()) - } else { + // Step 2. + match self.origin.effective_domain() { // Step 3. - DOMString::new() + None => DOMString::new(), + // Step 4. + Some(Host::Domain(domain)) => DOMString::from(domain), + Some(host) => DOMString::from(host.to_string()), } } @@ -3077,7 +3078,7 @@ impl DocumentMethods for Document { return Ok(DOMString::new()); } - if !self.origin.is_scheme_host_port_tuple() { + if !self.origin.is_tuple() { return Err(Error::Security); } @@ -3097,7 +3098,7 @@ impl DocumentMethods for Document { return Ok(()); } - if !self.origin.is_scheme_host_port_tuple() { + if !self.origin.is_tuple() { return Err(Error::Security); } diff --git a/servo/components/script/dom/domimplementation.rs b/servo/components/script/dom/domimplementation.rs index 4ec27cc5b367..1de0a24863b1 100644 --- a/servo/components/script/dom/domimplementation.rs +++ b/servo/components/script/dom/domimplementation.rs @@ -80,7 +80,7 @@ impl DOMImplementationMethods for DOMImplementation { let doc = XMLDocument::new(win, HasBrowsingContext::No, None, - self.document.origin().alias(), + self.document.origin().clone(), IsHTMLDocument::NonHTMLDocument, Some(DOMString::from(content_type)), None, @@ -127,7 +127,7 @@ impl DOMImplementationMethods for DOMImplementation { let doc = Document::new(win, HasBrowsingContext::No, None, - self.document.origin().alias(), + self.document.origin().clone(), IsHTMLDocument::HTMLDocument, None, None, diff --git a/servo/components/script/dom/domparser.rs b/servo/components/script/dom/domparser.rs index d89ec3c15950..67d16934c663 100644 --- a/servo/components/script/dom/domparser.rs +++ b/servo/components/script/dom/domparser.rs @@ -61,7 +61,7 @@ impl DOMParserMethods for DOMParser { let document = Document::new(&self.window, HasBrowsingContext::No, Some(url.clone()), - doc.origin().alias(), + doc.origin().clone(), IsHTMLDocument::HTMLDocument, Some(content_type), None, @@ -79,7 +79,7 @@ impl DOMParserMethods for DOMParser { let document = Document::new(&self.window, HasBrowsingContext::No, Some(url.clone()), - doc.origin().alias(), + doc.origin().clone(), IsHTMLDocument::NonHTMLDocument, Some(content_type), None, diff --git a/servo/components/script/dom/htmliframeelement.rs b/servo/components/script/dom/htmliframeelement.rs index 3a1c9daf1c94..4ab827353847 100644 --- a/servo/components/script/dom/htmliframeelement.rs +++ b/servo/components/script/dom/htmliframeelement.rs @@ -167,7 +167,7 @@ impl HTMLIFrameElement { layout_threads: PREFS.get("layout.threads").as_u64().expect("count") as usize, }; - ScriptThread::process_attach_layout(new_layout_info, document.origin().alias()); + ScriptThread::process_attach_layout(new_layout_info, document.origin().clone()); } else { let load_info = IFrameLoadInfoWithData { info: load_info, diff --git a/servo/components/script/dom/node.rs b/servo/components/script/dom/node.rs index df335be75a68..96d3fceaff5d 100644 --- a/servo/components/script/dom/node.rs +++ b/servo/components/script/dom/node.rs @@ -1729,7 +1729,7 @@ impl Node { let document = Document::new(window, HasBrowsingContext::No, Some(document.url()), // https://github.com/whatwg/dom/issues/378 - document.origin().alias(), + document.origin().clone(), is_html_doc, None, None, DocumentActivity::Inactive, DocumentSource::NotFromParser, loader, diff --git a/servo/components/script/dom/servoparser/mod.rs b/servo/components/script/dom/servoparser/mod.rs index 39077930200b..149957576a23 100644 --- a/servo/components/script/dom/servoparser/mod.rs +++ b/servo/components/script/dom/servoparser/mod.rs @@ -110,7 +110,7 @@ impl ServoParser { let document = Document::new(window, HasBrowsingContext::No, Some(url.clone()), - context_document.origin().alias(), + context_document.origin().clone(), IsHTMLDocument::HTMLDocument, None, None, diff --git a/servo/components/script/dom/window.rs b/servo/components/script/dom/window.rs index 1fbe57ba1651..b6392fbdd19c 100644 --- a/servo/components/script/dom/window.rs +++ b/servo/components/script/dom/window.rs @@ -62,7 +62,6 @@ use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheThread}; use net_traits::storage_thread::StorageType; use num_traits::ToPrimitive; use open; -use origin::Origin; use profile_traits::mem::ProfilerChan as MemProfilerChan; use profile_traits::time::ProfilerChan as TimeProfilerChan; use rustc_serialize::base64::{FromBase64, STANDARD, ToBase64}; @@ -83,7 +82,7 @@ use servo_atoms::Atom; use servo_config::opts; use servo_config::prefs::PREFS; use servo_geometry::{f32_rect_to_au_rect, max_rect}; -use servo_url::ServoUrl; +use servo_url::{ImmutableOrigin, ServoUrl}; use std::ascii::AsciiExt; use std::borrow::ToOwned; use std::cell::Cell; @@ -660,10 +659,10 @@ impl WindowMethods for Window { "/" => { // TODO(#12715): Should be the origin of the incumbent settings // object, not self's. - Some(self.Document().origin().copy()) + Some(self.Document().origin().immutable().clone()) }, url => match ServoUrl::parse(&url) { - Ok(url) => Some(Origin::new(&url)), + Ok(url) => Some(url.origin().clone()), Err(_) => return Err(Error::Syntax), } }; @@ -1793,13 +1792,13 @@ fn debug_reflow_events(id: PipelineId, goal: &ReflowGoal, query_type: &ReflowQue struct PostMessageHandler { destination: Trusted, - origin: Option, + origin: Option, message: StructuredCloneData, } impl PostMessageHandler { fn new(window: &Window, - origin: Option, + origin: Option, message: StructuredCloneData) -> PostMessageHandler { PostMessageHandler { destination: Trusted::new(window), diff --git a/servo/components/script/dom/xmldocument.rs b/servo/components/script/dom/xmldocument.rs index eaf90fbfe013..c832e018360e 100644 --- a/servo/components/script/dom/xmldocument.rs +++ b/servo/components/script/dom/xmldocument.rs @@ -15,9 +15,8 @@ use dom::location::Location; use dom::node::Node; use dom::window::Window; use js::jsapi::{JSContext, JSObject}; -use origin::Origin; use script_traits::DocumentActivity; -use servo_url::ServoUrl; +use servo_url::{MutableOrigin, ServoUrl}; // https://dom.spec.whatwg.org/#xmldocument #[dom_struct] @@ -29,7 +28,7 @@ impl XMLDocument { fn new_inherited(window: &Window, has_browsing_context: HasBrowsingContext, url: Option, - origin: Origin, + origin: MutableOrigin, is_html_document: IsHTMLDocument, content_type: Option, last_modified: Option, @@ -55,7 +54,7 @@ impl XMLDocument { pub fn new(window: &Window, has_browsing_context: HasBrowsingContext, url: Option, - origin: Origin, + origin: MutableOrigin, doctype: IsHTMLDocument, content_type: Option, last_modified: Option, diff --git a/servo/components/script/dom/xmlhttprequest.rs b/servo/components/script/dom/xmlhttprequest.rs index 6fe89476994b..c5c3c6351294 100644 --- a/servo/components/script/dom/xmlhttprequest.rs +++ b/servo/components/script/dom/xmlhttprequest.rs @@ -1225,7 +1225,7 @@ impl XMLHttpRequest { Document::new(win, HasBrowsingContext::No, parsed_url, - doc.origin().alias(), + doc.origin().clone(), is_html_document, content_type, None, diff --git a/servo/components/script/lib.rs b/servo/components/script/lib.rs index 8a2829059c0b..e5c93357bd20 100644 --- a/servo/components/script/lib.rs +++ b/servo/components/script/lib.rs @@ -114,7 +114,6 @@ pub mod layout_wrapper; mod mem; mod microtask; mod network_listener; -pub mod origin; pub mod script_runtime; #[allow(unsafe_code)] pub mod script_thread; diff --git a/servo/components/script/origin.rs b/servo/components/script/origin.rs deleted file mode 100644 index 067eb77dcdac..000000000000 --- a/servo/components/script/origin.rs +++ /dev/null @@ -1,61 +0,0 @@ -/* 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/. */ - -use servo_url::ServoUrl; -use std::sync::Arc; -use url::Host; -use url::Origin as UrlOrigin; - -/// A representation of an [origin](https://html.spec.whatwg.org/multipage/#origin-2). -#[derive(HeapSizeOf, JSTraceable)] -pub struct Origin { - #[ignore_heap_size_of = "Arc has unclear ownership semantics"] - inner: Arc, -} - -impl Origin { - /// Create a new origin comprising a unique, opaque identifier. - pub fn opaque_identifier() -> Origin { - Origin { - inner: Arc::new(UrlOrigin::new_opaque()), - } - } - - /// Create a new origin for the given URL. - pub fn new(url: &ServoUrl) -> Origin { - Origin { - inner: Arc::new(url.origin()), - } - } - - /// Does this origin represent a host/scheme/port tuple? - pub fn is_scheme_host_port_tuple(&self) -> bool { - self.inner.is_tuple() - } - - /// Return the host associated with this origin. - pub fn host(&self) -> Option<&Host> { - match *self.inner { - UrlOrigin::Tuple(_, ref host, _) => Some(host), - UrlOrigin::Opaque(..) => None, - } - } - - /// https://html.spec.whatwg.org/multipage/#same-origin - pub fn same_origin(&self, other: &Origin) -> bool { - self.inner == other.inner - } - - pub fn copy(&self) -> Origin { - Origin { - inner: Arc::new((*self.inner).clone()), - } - } - - pub fn alias(&self) -> Origin { - Origin { - inner: self.inner.clone(), - } - } -} diff --git a/servo/components/script/script_thread.rs b/servo/components/script/script_thread.rs index ac093a7a5df9..2ab421c707bb 100644 --- a/servo/components/script/script_thread.rs +++ b/servo/components/script/script_thread.rs @@ -77,7 +77,6 @@ use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheResult, ImageCach use net_traits::request::{CredentialsMode, Destination, RequestInit}; use net_traits::storage_thread::StorageType; use network_listener::NetworkListener; -use origin::Origin; use profile_traits::mem::{self, OpaqueSender, Report, ReportKind, ReportsChan}; use profile_traits::time::{self, ProfilerCategory, profile}; use script_layout_interface::message::{self, NewLayoutThreadInfo, ReflowQueryType}; @@ -95,7 +94,7 @@ use script_traits::WebVREventMsg; use script_traits::webdriver_msg::WebDriverScriptCommand; use serviceworkerjob::{Job, JobQueue, AsyncJobHandler}; use servo_config::opts; -use servo_url::ServoUrl; +use servo_url::{MutableOrigin, ServoUrl}; use std::cell::Cell; use std::collections::{hash_map, HashMap, HashSet}; use std::default::Default; @@ -155,7 +154,8 @@ struct InProgressLoad { is_visible: bool, /// The requested URL of the load. url: ServoUrl, - origin: Origin, + /// The origin for the document + origin: MutableOrigin, } impl InProgressLoad { @@ -166,7 +166,7 @@ impl InProgressLoad { layout_chan: Sender, window_size: Option, url: ServoUrl, - origin: Origin) -> InProgressLoad { + origin: MutableOrigin) -> InProgressLoad { InProgressLoad { pipeline_id: id, frame_id: frame_id, @@ -545,7 +545,7 @@ impl ScriptThreadFactory for ScriptThread { let mut failsafe = ScriptMemoryFailsafe::new(&script_thread); - let origin = Origin::new(&load_data.url); + let origin = MutableOrigin::new(load_data.url.origin()); let new_load = InProgressLoad::new(id, frame_id, parent_info, layout_chan, window_size, load_data.url.clone(), origin); script_thread.start_page_load(new_load, load_data); @@ -611,7 +611,7 @@ impl ScriptThread { }); } - pub fn process_attach_layout(new_layout_info: NewLayoutInfo, origin: Origin) { + pub fn process_attach_layout(new_layout_info: NewLayoutInfo, origin: MutableOrigin) { SCRIPT_THREAD_ROOT.with(|root| { if let Some(script_thread) = root.get() { let script_thread = unsafe { &*script_thread }; @@ -791,7 +791,7 @@ impl ScriptThread { FromConstellation(ConstellationControlMsg::AttachLayout( new_layout_info)) => { self.profile_event(ScriptThreadEventCategory::AttachLayout, || { - let origin = Origin::new(&new_layout_info.load_data.url); + let origin = MutableOrigin::new(new_layout_info.load_data.url.origin()); self.handle_new_layout(new_layout_info, origin); }) } @@ -1208,7 +1208,7 @@ impl ScriptThread { window.set_scroll_offsets(scroll_offsets) } - fn handle_new_layout(&self, new_layout_info: NewLayoutInfo, origin: Origin) { + fn handle_new_layout(&self, new_layout_info: NewLayoutInfo, origin: MutableOrigin) { let NewLayoutInfo { parent_info, new_pipeline_id, diff --git a/servo/components/url/Cargo.toml b/servo/components/url/Cargo.toml index e6acfe076496..4cefa0611c65 100644 --- a/servo/components/url/Cargo.toml +++ b/servo/components/url/Cargo.toml @@ -10,11 +10,14 @@ name = "servo_url" path = "lib.rs" [features] -servo = ["heapsize", "heapsize_derive", "serde", "url/heap_size", "url_serde"] +servo = ["heapsize", "heapsize_derive", "serde", "serde_derive", "uuid/serde", "url/heap_size", "url_serde"] [dependencies] heapsize = {version = "0.3.0", optional = true} heapsize_derive = {version = "0.1", optional = true} serde = {version = "0.9", optional = true} +serde_derive = {version = "0.9", optional = true} +servo_rand = {path = "../rand"} url = "1.2" -url_serde = {version = "0.1", optional = true} +url_serde = {version = "0.1.3", optional = true} +uuid = {version = "0.4.0", features = ["v4"]} diff --git a/servo/components/url/lib.rs b/servo/components/url/lib.rs index 85933a509c71..e8d8d363fbf7 100644 --- a/servo/components/url/lib.rs +++ b/servo/components/url/lib.rs @@ -7,19 +7,26 @@ #![crate_name = "servo_url"] #![crate_type = "rlib"] -#[cfg(feature = "servo")] extern crate heapsize; +#[cfg(feature = "servo")] #[macro_use] extern crate heapsize; #[cfg(feature = "servo")] #[macro_use] extern crate heapsize_derive; #[cfg(feature = "servo")] extern crate serde; +#[cfg(feature = "servo")] #[macro_use] extern crate serde_derive; #[cfg(feature = "servo")] extern crate url_serde; +extern crate servo_rand; extern crate url; +extern crate uuid; + +pub mod origin; + +pub use origin::{OpaqueOrigin, ImmutableOrigin, MutableOrigin}; use std::fmt; use std::net::IpAddr; use std::ops::{Range, RangeFrom, RangeTo, RangeFull, Index}; use std::path::Path; use std::sync::Arc; -use url::{Url, Origin, Position}; +use url::{Url, Position}; #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] @@ -68,8 +75,8 @@ impl ServoUrl { self.0.path() } - pub fn origin(&self) -> Origin { - self.0.origin() + pub fn origin(&self) -> ImmutableOrigin { + ImmutableOrigin::new(self.0.origin()) } pub fn scheme(&self) -> &str { diff --git a/servo/components/url/origin.rs b/servo/components/url/origin.rs new file mode 100644 index 000000000000..3795b73fb61a --- /dev/null +++ b/servo/components/url/origin.rs @@ -0,0 +1,172 @@ +/* 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/. */ + +use servo_rand; +use servo_rand::Rng; +use std::cell::RefCell; +use std::rc::Rc; +use url::{Host, Origin}; +#[cfg(feature = "servo")] use url_serde; +use uuid::Uuid; + +/// The origin of an URL +#[derive(PartialEq, Eq, Clone, Debug)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))] +pub enum ImmutableOrigin { + /// A globally unique identifier + Opaque(OpaqueOrigin), + + /// Consists of the URL's scheme, host and port + Tuple( + String, + #[cfg_attr(feature = "servo", + serde(deserialize_with = "url_serde::deserialize", serialize_with = "url_serde::serialize"))] + Host, + u16, + ) +} + +impl ImmutableOrigin { + pub fn new(origin: Origin) -> ImmutableOrigin { + match origin { + Origin::Opaque(_) => ImmutableOrigin::new_opaque(), + Origin::Tuple(scheme, host, port) => ImmutableOrigin::Tuple(scheme, host, port), + } + } + + pub fn same_origin(&self, other: &MutableOrigin) -> bool { + self == other.immutable() + } + + pub fn same_origin_domain(&self, other: &MutableOrigin) -> bool { + !other.has_domain() && self == other.immutable() + } + + /// Creates a new opaque origin that is only equal to itself. + pub fn new_opaque() -> ImmutableOrigin { + ImmutableOrigin::Opaque(OpaqueOrigin(servo_rand::thread_rng().gen())) + } + + pub fn scheme(&self) -> Option<&str> { + match *self { + ImmutableOrigin::Opaque(_) => None, + ImmutableOrigin::Tuple(ref scheme, _, _) => Some(&**scheme), + } + } + + pub fn host(&self) -> Option<&Host> { + match *self { + ImmutableOrigin::Opaque(_) => None, + ImmutableOrigin::Tuple(_, ref host, _) => Some(host), + } + } + + pub fn port(&self) -> Option { + match *self { + ImmutableOrigin::Opaque(_) => None, + ImmutableOrigin::Tuple(_, _, port) => Some(port), + } + } + + pub fn into_url_origin(self) -> Origin { + match self { + ImmutableOrigin::Opaque(_) => Origin::new_opaque(), + ImmutableOrigin::Tuple(scheme, host, port) => Origin::Tuple(scheme, host, port), + } + } + + /// Return whether this origin is a (scheme, host, port) tuple + /// (as opposed to an opaque origin). + pub fn is_tuple(&self) -> bool { + match *self { + ImmutableOrigin::Opaque(..) => false, + ImmutableOrigin::Tuple(..) => true, + } + } + + /// https://html.spec.whatwg.org/multipage/#ascii-serialisation-of-an-origin + pub fn ascii_serialization(&self) -> String { + self.clone().into_url_origin().ascii_serialization() + } + + /// https://html.spec.whatwg.org/multipage/#unicode-serialisation-of-an-origin + pub fn unicode_serialization(&self) -> String { + self.clone().into_url_origin().unicode_serialization() + } +} + +/// Opaque identifier for URLs that have file or other schemes +#[derive(Eq, PartialEq, Clone, Debug)] +#[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] +pub struct OpaqueOrigin(Uuid); + +#[cfg(feature = "servo")] +known_heap_size!(0, OpaqueOrigin); + +/// A representation of an [origin](https://html.spec.whatwg.org/multipage/#origin-2). +#[derive(Clone, Debug)] +pub struct MutableOrigin(Rc<(ImmutableOrigin, RefCell>)>); + +#[cfg(feature = "servo")] +known_heap_size!(0, MutableOrigin); + +impl MutableOrigin { + pub fn new(origin: ImmutableOrigin) -> MutableOrigin { + MutableOrigin(Rc::new((origin, RefCell::new(None)))) + } + + pub fn immutable(&self) -> &ImmutableOrigin { + &(self.0).0 + } + + pub fn is_tuple(&self) -> bool { + self.immutable().is_tuple() + } + + pub fn scheme(&self) -> Option<&str> { + self.immutable().scheme() + } + + pub fn host(&self) -> Option<&Host> { + self.immutable().host() + } + + pub fn port(&self) -> Option { + self.immutable().port() + } + + pub fn same_origin(&self, other: &MutableOrigin) -> bool { + self.immutable() == other.immutable() + } + + pub fn same_origin_domain(&self, other: &MutableOrigin) -> bool { + if let Some(ref self_domain) = *(self.0).1.borrow() { + if let Some(ref other_domain) = *(other.0).1.borrow() { + self_domain == other_domain && + self.immutable().scheme() == other.immutable().scheme() + } else { + false + } + } else { + self.immutable().same_origin_domain(other) + } + } + + pub fn domain(&self) -> Option { + (self.0).1.borrow().clone() + } + + pub fn set_domain(&self, domain: Host) { + *(self.0).1.borrow_mut() = Some(domain); + } + + pub fn has_domain(&self) -> bool { + (self.0).1.borrow().is_some() + } + + pub fn effective_domain(&self) -> Option { + self.immutable().host() + .map(|host| self.domain().unwrap_or_else(|| host.clone())) + } +} diff --git a/servo/tests/unit/net/fetch.rs b/servo/tests/unit/net/fetch.rs index 4329e44884dd..43940f28a9ff 100644 --- a/servo/tests/unit/net/fetch.rs +++ b/servo/tests/unit/net/fetch.rs @@ -34,7 +34,7 @@ use net_traits::ReferrerPolicy; use net_traits::request::{Origin, RedirectMode, Referrer, Request, RequestMode}; use net_traits::response::{CacheState, Response, ResponseBody, ResponseType}; use servo_config::resource_files::resources_dir_path; -use servo_url::ServoUrl; +use servo_url::{ImmutableOrigin, ServoUrl}; use std::fs::File; use std::io::Read; use std::rc::Rc; @@ -43,7 +43,6 @@ use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::mpsc::{Sender, channel}; use time::{self, Duration}; use unicase::UniCase; -use url::Origin as UrlOrigin; // TODO write a struct that impls Handler for storing test values @@ -223,7 +222,7 @@ fn test_cors_preflight_fetch() { let target_url = url.clone().join("a.html").unwrap(); - let origin = Origin::Origin(UrlOrigin::new_opaque()); + let origin = Origin::Origin(ImmutableOrigin::new_opaque()); let mut request = Request::new(url.clone(), Some(origin), false, None); *request.referrer.borrow_mut() = Referrer::ReferrerUrl(target_url); *request.referrer_policy.get_mut() = Some(ReferrerPolicy::Origin); @@ -260,7 +259,7 @@ fn test_cors_preflight_cache_fetch() { }; let (mut server, url) = make_server(handler); - let origin = Origin::Origin(UrlOrigin::new_opaque()); + let origin = Origin::Origin(ImmutableOrigin::new_opaque()); let mut request = Request::new(url.clone(), Some(origin.clone()), false, None); *request.referrer.borrow_mut() = Referrer::NoReferrer; request.use_cors_preflight = true; @@ -309,7 +308,7 @@ fn test_cors_preflight_fetch_network_error() { }; let (mut server, url) = make_server(handler); - let origin = Origin::Origin(UrlOrigin::new_opaque()); + let origin = Origin::Origin(ImmutableOrigin::new_opaque()); let mut request = Request::new(url, Some(origin), false, None); *request.method.borrow_mut() = Method::Extension("CHICKEN".to_owned()); *request.referrer.borrow_mut() = Referrer::NoReferrer; @@ -378,7 +377,7 @@ fn test_fetch_response_is_cors_filtered() { let (mut server, url) = make_server(handler); // an origin mis-match will stop it from defaulting to a basic filtered response - let origin = Origin::Origin(UrlOrigin::new_opaque()); + let origin = Origin::Origin(ImmutableOrigin::new_opaque()); let mut request = Request::new(url, Some(origin), false, None); *request.referrer.borrow_mut() = Referrer::NoReferrer; request.mode = RequestMode::CorsMode; @@ -410,7 +409,7 @@ fn test_fetch_response_is_opaque_filtered() { let (mut server, url) = make_server(handler); // an origin mis-match will fall through to an Opaque filtered response - let origin = Origin::Origin(UrlOrigin::new_opaque()); + let origin = Origin::Origin(ImmutableOrigin::new_opaque()); let request = Request::new(url, Some(origin), false, None); *request.referrer.borrow_mut() = Referrer::NoReferrer; let fetch_response = fetch(request, None); @@ -800,7 +799,7 @@ fn test_opaque_filtered_fetch_async_returns_complete_response() { let (mut server, url) = make_server(handler); // an origin mis-match will fall through to an Opaque filtered response - let origin = Origin::Origin(UrlOrigin::new_opaque()); + let origin = Origin::Origin(ImmutableOrigin::new_opaque()); let request = Request::new(url, Some(origin), false, None); *request.referrer.borrow_mut() = Referrer::NoReferrer; diff --git a/servo/tests/unit/script/origin.rs b/servo/tests/unit/script/origin.rs index 6357587da893..526b12bf0f92 100644 --- a/servo/tests/unit/script/origin.rs +++ b/servo/tests/unit/script/origin.rs @@ -2,46 +2,45 @@ * 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/. */ -use script::origin::Origin; -use servo_url::ServoUrl; +use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl}; #[test] fn same_origin() { - let a = Origin::new(&ServoUrl::parse("http://example.com/a.html").unwrap()); - let b = Origin::new(&ServoUrl::parse("http://example.com/b.html").unwrap()); + let a = MutableOrigin::new(ServoUrl::parse("http://example.com/a.html").unwrap().origin()); + let b = MutableOrigin::new(ServoUrl::parse("http://example.com/b.html").unwrap().origin()); assert!(a.same_origin(&b)); - assert_eq!(a.is_scheme_host_port_tuple(), true); + assert_eq!(a.is_tuple(), true); } #[test] fn identical_origin() { - let a = Origin::new(&ServoUrl::parse("http://example.com/a.html").unwrap()); + let a = MutableOrigin::new(ServoUrl::parse("http://example.com/a.html").unwrap().origin()); assert!(a.same_origin(&a)); } #[test] fn cross_origin() { - let a = Origin::new(&ServoUrl::parse("http://example.com/a.html").unwrap()); - let b = Origin::new(&ServoUrl::parse("http://example.org/b.html").unwrap()); + let a = MutableOrigin::new(ServoUrl::parse("http://example.com/a.html").unwrap().origin()); + let b = MutableOrigin::new(ServoUrl::parse("http://example.org/b.html").unwrap().origin()); assert!(!a.same_origin(&b)); } #[test] -fn alias_same_origin() { - let a = Origin::new(&ServoUrl::parse("http://example.com/a.html").unwrap()); - let b = Origin::new(&ServoUrl::parse("http://example.com/b.html").unwrap()); - let c = b.alias(); +fn clone_same_origin() { + let a = MutableOrigin::new(ServoUrl::parse("http://example.com/a.html").unwrap().origin()); + let b = MutableOrigin::new(ServoUrl::parse("http://example.com/b.html").unwrap().origin()); + let c = b.clone(); assert!(a.same_origin(&c)); assert!(b.same_origin(&b)); assert!(c.same_origin(&b)); - assert_eq!(c.is_scheme_host_port_tuple(), true); + assert_eq!(c.is_tuple(), true); } #[test] -fn alias_cross_origin() { - let a = Origin::new(&ServoUrl::parse("http://example.com/a.html").unwrap()); - let b = Origin::new(&ServoUrl::parse("http://example.org/b.html").unwrap()); - let c = b.alias(); +fn clone_cross_origin() { + let a = MutableOrigin::new(ServoUrl::parse("http://example.com/a.html").unwrap().origin()); + let b = MutableOrigin::new(ServoUrl::parse("http://example.org/b.html").unwrap().origin()); + let c = b.clone(); assert!(!a.same_origin(&c)); assert!(b.same_origin(&c)); assert!(c.same_origin(&c)); @@ -49,16 +48,16 @@ fn alias_cross_origin() { #[test] fn opaque() { - let a = Origin::opaque_identifier(); - let b = Origin::opaque_identifier(); + let a = MutableOrigin::new(ImmutableOrigin::new_opaque()); + let b = MutableOrigin::new(ImmutableOrigin::new_opaque()); assert!(!a.same_origin(&b)); - assert_eq!(a.is_scheme_host_port_tuple(), false); + assert_eq!(a.is_tuple(), false); } #[test] fn opaque_clone() { - let a = Origin::opaque_identifier(); - let b = a.alias(); + let a = MutableOrigin::new(ImmutableOrigin::new_opaque()); + let b = a.clone(); assert!(a.same_origin(&b)); - assert_eq!(a.is_scheme_host_port_tuple(), false); + assert_eq!(a.is_tuple(), false); } From 379e80c372e885d8f8381fe75df6e71cb70ef224 Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Wed, 22 Feb 2017 10:47:26 -0800 Subject: [PATCH 043/234] Bug 1341740 - stylo: revendor rust dependencies after url upgrade on a CLOSED TREE. r=me MozReview-Commit-ID: FA6l4JHfB0r --- third_party/rust/uuid/.cargo-checksum.json | 1 + third_party/rust/uuid/.cargo-ok | 0 third_party/rust/uuid/.gitignore | 2 + third_party/rust/uuid/.travis.yml | 33 + third_party/rust/uuid/Cargo.toml | 24 + third_party/rust/uuid/LICENSE-APACHE | 201 +++ third_party/rust/uuid/LICENSE-MIT | 25 + third_party/rust/uuid/README.md | 105 ++ third_party/rust/uuid/benches/parse_str.rs | 87 ++ third_party/rust/uuid/src/lib.rs | 1152 ++++++++++++++++++ third_party/rust/uuid/src/rustc_serialize.rs | 34 + third_party/rust/uuid/src/serde.rs | 34 + third_party/rust/uuid/src/std_support.rs | 9 + toolkit/library/gtest/rust/Cargo.lock | 20 + toolkit/library/rust/Cargo.lock | 20 + 15 files changed, 1747 insertions(+) create mode 100644 third_party/rust/uuid/.cargo-checksum.json create mode 100644 third_party/rust/uuid/.cargo-ok create mode 100644 third_party/rust/uuid/.gitignore create mode 100644 third_party/rust/uuid/.travis.yml create mode 100644 third_party/rust/uuid/Cargo.toml create mode 100644 third_party/rust/uuid/LICENSE-APACHE create mode 100644 third_party/rust/uuid/LICENSE-MIT create mode 100644 third_party/rust/uuid/README.md create mode 100644 third_party/rust/uuid/benches/parse_str.rs create mode 100644 third_party/rust/uuid/src/lib.rs create mode 100644 third_party/rust/uuid/src/rustc_serialize.rs create mode 100644 third_party/rust/uuid/src/serde.rs create mode 100644 third_party/rust/uuid/src/std_support.rs diff --git a/third_party/rust/uuid/.cargo-checksum.json b/third_party/rust/uuid/.cargo-checksum.json new file mode 100644 index 000000000000..0ac3b899a08d --- /dev/null +++ b/third_party/rust/uuid/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"c1e953ee360e77de57f7b02f1b7880bd6a3dc22d1a69e953c2ac2c52cc52d247",".travis.yml":"a97f7d2ec6607ad106f78f63ef76a13d7bab70ca093c4fa00e575710b8d8d73a","Cargo.toml":"800cf478dd87f0853b0b5319d206cdef2d428c5041dc17ceb2d21b85125cf3d3","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"526ff5ed173a4d8c8665595191858bb48828ea02efa61503681b2fcce71443bd","benches/parse_str.rs":"625a29dab53768392428a7ab69c81ce25965a73b7971f575999f9ad1f4ee12a2","src/lib.rs":"904b43f801b6d3377545e8a494943903594ea6938977de0242927972a0f28644","src/rustc_serialize.rs":"5cb4ff0bb906b937e3f4cd854a14a9e9fbf57054db23874fbf2cf69e7f14bf9e","src/serde.rs":"e8581071a199e5ae0d981c09912df51840120f4fe38dbba8d80b3e91bdeef19d","src/std_support.rs":"bd1db679cf0299cb5f60501ccbe59ea14be9224ef6fbb740069c5e136d311def"},"package":"7cfec50b0842181ba6e713151b72f4ec84a6a7e2c9c8a8a3ffc37bb1cd16b231"} \ No newline at end of file diff --git a/third_party/rust/uuid/.cargo-ok b/third_party/rust/uuid/.cargo-ok new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/third_party/rust/uuid/.gitignore b/third_party/rust/uuid/.gitignore new file mode 100644 index 000000000000..4fffb2f89cbd --- /dev/null +++ b/third_party/rust/uuid/.gitignore @@ -0,0 +1,2 @@ +/target +/Cargo.lock diff --git a/third_party/rust/uuid/.travis.yml b/third_party/rust/uuid/.travis.yml new file mode 100644 index 000000000000..ee7070aaa696 --- /dev/null +++ b/third_party/rust/uuid/.travis.yml @@ -0,0 +1,33 @@ +language: rust +rust: + - stable + - beta + - nightly +sudo: false +before_script: + - pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH +script: + - cargo build --verbose --features "$FEATURES" + - cargo test --verbose --features "$FEATURES" + - | + [ $TRAVIS_RUST_VERSION != nightly ] || ( + cargo bench --features "$FEATURES" + ) + - cargo doc --no-deps --features "$FEATURES" +after_success: + - travis-cargo --only nightly doc-upload +env: + global: + secure: "HzcZYuf80pByt4J3OM+sfXg5dGPQjFTPfLYR907wfi8FD6mJu5yYbgPF4agz9sdnnNrtnmlghZ5WFljrl49oNC6RhcSc6YVmiRKs4DabMKKr3v9zZy1i2KuQ323cGpwUIVpq7+u8/vQAYPwRUPzZrVw57y5KKqEHbn2T85yFdqo=" + + matrix: + - FEATURES="" + - FEATURES="rustc-serialize" + - FEATURES="serde" + - FEATURES="use_std" + - FEATURES="v4" + - FEATURES="v5" + - FEATURES="rustc-serialize serde v4 v5 use_std" +notifications: + email: + on_success: never diff --git a/third_party/rust/uuid/Cargo.toml b/third_party/rust/uuid/Cargo.toml new file mode 100644 index 000000000000..983dc2331963 --- /dev/null +++ b/third_party/rust/uuid/Cargo.toml @@ -0,0 +1,24 @@ +[package] + +name = "uuid" +version = "0.4.0" +authors = ["The Rust Project Developers"] +license = "MIT/Apache-2.0" +readme = "README.md" +repository = "https://github.com/rust-lang/uuid" +homepage = "https://github.com/rust-lang/uuid" +documentation = "https://doc.rust-lang.org/uuid" +description = """ +A library to generate and parse UUIDs. +""" + +[dependencies] +rustc-serialize = { version = "0.3", optional = true } +serde = { version = "0.9", optional = true } +rand = { version = "0.3", optional = true } +sha1 = { version = "0.2", optional = true } + +[features] +use_std = [] +v4 = ["rand"] +v5 = ["sha1"] diff --git a/third_party/rust/uuid/LICENSE-APACHE b/third_party/rust/uuid/LICENSE-APACHE new file mode 100644 index 000000000000..16fe87b06e80 --- /dev/null +++ b/third_party/rust/uuid/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/third_party/rust/uuid/LICENSE-MIT b/third_party/rust/uuid/LICENSE-MIT new file mode 100644 index 000000000000..39d4bdb5acd3 --- /dev/null +++ b/third_party/rust/uuid/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2014 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/third_party/rust/uuid/README.md b/third_party/rust/uuid/README.md new file mode 100644 index 000000000000..37bfb3f70704 --- /dev/null +++ b/third_party/rust/uuid/README.md @@ -0,0 +1,105 @@ +uuid +==== + +[![Build Status](https://travis-ci.org/rust-lang-nursery/uuid.svg?branch=master)](https://travis-ci.org/rust-lang-nursery/uuid) + +A Rust library to generate and parse UUIDs. + +Provides support for Universally Unique Identifiers (UUIDs). A UUID is a unique +128-bit number, stored as 16 octets. UUIDs are used to assign unique identifiers +to entities without requiring a central allocating authority. + +They are particularly useful in distributed systems, though can be used in +disparate areas, such as databases and network protocols. Typically a UUID is +displayed in a readable string form as a sequence of hexadecimal digits, +separated into groups by hyphens. + +The uniqueness property is not strictly guaranteed, however for all practical +purposes, it can be assumed that an unintentional collision would be extremely +unlikely. + +[Documentation](https://doc.rust-lang.org/uuid) + +## Usage + +Add this to your `Cargo.toml`: + +```toml +[dependencies] +uuid = "0.3" +``` + +and this to your crate root: + +```rust +extern crate uuid; +``` + +## Examples + +To parse a simple UUID, then print the version and urn string format: + +```rust +extern crate uuid; +use uuid::Uuid; + +fn main() { + let my_uuid = Uuid::parse_str("936DA01F9ABD4d9d80C702AF85C822A8").unwrap(); + println!("Parsed a version {} UUID.", my_uuid.get_version_num()); + println!("{}", my_uuid); +} +``` + +The library supports 5 versions of UUID: + +Name | Version +---------|---------- +Mac | Version 1: MAC address +Dce | Version 2: DCE Security +Md5 | Version 3: MD5 hash +Random | Version 4: Random +Sha1 | Version 5: SHA-1 hash + +To create a new random (V4) UUID and print it out in hexadecimal form, first +you'll need to change how you depend on `uuid`: + +```toml +[dependencies] +uuid = { version = "0.2", features = ["v4"] } +``` + +Next, you'll write: + +```rust +extern crate uuid; +use uuid::Uuid; + +fn main() { + let my_uuid = Uuid::new_v4(); + println!("{}", my_uuid); +} +``` + +To create a new sha1-hash based (V5) UUID and print it out in hexadecimal form, +you'll also need to change how you depend on `uuid`: + +```toml +[dependencies] +uuid = { version = "0.2", features = ["v5"] } +``` + +Next, you'll write: + +```rust +extern crate uuid; +use uuid::Uuid; + +fn main() { + let my_uuid = Uuid::new_v5(&uuid::NAMESPACE_DNS, "foo"); + println!("{}", my_uuid); +} +``` + +## References + +[Wikipedia: Universally Unique Identifier](https://en.wikipedia.org/wiki/Universally_unique_identifier) diff --git a/third_party/rust/uuid/benches/parse_str.rs b/third_party/rust/uuid/benches/parse_str.rs new file mode 100644 index 000000000000..c1ed5da8a492 --- /dev/null +++ b/third_party/rust/uuid/benches/parse_str.rs @@ -0,0 +1,87 @@ +#![feature(test)] + +extern crate test; +extern crate uuid; + +use test::Bencher; +use uuid::Uuid; + +#[bench] +fn bench_parse(b: &mut Bencher) { + b.iter(|| { + let _ = Uuid::parse_str(""); + let _ = Uuid::parse_str("!"); + let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E45"); + let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-BBF-329BF39FA1E4"); + let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-BGBF-329BF39FA1E4"); + let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BFF329BF39FA1E4"); + let _ = Uuid::parse_str("F9168C5E-CEB2-4faa"); + let _ = Uuid::parse_str("F9168C5E-CEB2-4faaXB6BFF329BF39FA1E4"); + let _ = Uuid::parse_str("F9168C5E-CEB-24fa-eB6BFF32-BF39FA1E4"); + let _ = Uuid::parse_str("01020304-1112-2122-3132-41424344"); + let _ = Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c88"); + let _ = Uuid::parse_str("67e5504410b1426f9247bb680e5fe0cg8"); + let _ = Uuid::parse_str("67e5504410b1426%9247bb680e5fe0c8"); + + // Valid + let _ = Uuid::parse_str("00000000000000000000000000000000"); + let _ = Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8"); + let _ = Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8"); + let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4"); + let _ = Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c8"); + let _ = Uuid::parse_str("01020304-1112-2122-3132-414243444546"); + let _ = Uuid::parse_str("urn:uuid:67e55044-10b1-426f-9247-bb680e5fe0c8"); + + // Nil + let _ = Uuid::parse_str("00000000000000000000000000000000"); + let _ = Uuid::parse_str("00000000-0000-0000-0000-000000000000"); + + // Test error reporting + let _ = Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c"); + let _ = Uuid::parse_str("67e550X410b1426f9247bb680e5fe0cd"); + let _ = Uuid::parse_str("67e550-4105b1426f9247bb680e5fe0c"); + let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF1-02BF39FA1E4"); + }); +} + +#[bench] +fn bench_parse_invalid_len(b: &mut Bencher) { + b.iter(|| { + let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-BBF-329BF39FA1E4"); + }) +} + +#[bench] +fn bench_parse_invalid_character(b: &mut Bencher) { + b.iter(|| { + let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-BGBF-329BF39FA1E4"); + }) +} + +#[bench] +fn bench_parse_invalid_group_len(b: &mut Bencher) { + b.iter(|| { + let _ = Uuid::parse_str("01020304-1112-2122-3132-41424344"); + }); +} + +#[bench] +fn bench_parse_invalid_groups(b: &mut Bencher) { + b.iter(|| { + let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BFF329BF39FA1E4"); + }); +} + +#[bench] +fn bench_valid_hyphenated(b: &mut Bencher) { + b.iter(|| { + let _ = Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8"); + }); +} + +#[bench] +fn bench_valid_short(b: &mut Bencher) { + b.iter(|| { + let _ = Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c8"); + }); +} diff --git a/third_party/rust/uuid/src/lib.rs b/third_party/rust/uuid/src/lib.rs new file mode 100644 index 000000000000..bed8a37506be --- /dev/null +++ b/third_party/rust/uuid/src/lib.rs @@ -0,0 +1,1152 @@ +// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Generate and parse UUIDs +//! +//! Provides support for Universally Unique Identifiers (UUIDs). A UUID is a +//! unique 128-bit number, stored as 16 octets. UUIDs are used to assign +//! unique identifiers to entities without requiring a central allocating +//! authority. +//! +//! They are particularly useful in distributed systems, though can be used in +//! disparate areas, such as databases and network protocols. Typically a UUID +//! is displayed in a readable string form as a sequence of hexadecimal digits, +//! separated into groups by hyphens. +//! +//! The uniqueness property is not strictly guaranteed, however for all +//! practical purposes, it can be assumed that an unintentional collision would +//! be extremely unlikely. +//! +//! # Dependencies +//! +//! This crate by default has no dependencies and is `#![no_std]` compatible. +//! The following Cargo features, however, can be used to enable various pieces +//! of functionality. +//! +//! * `use_std` - adds in functionality available when linking to the standard +//! library, currently this is only the `impl Error for ParseError`. +//! * `v4` - adds the `Uuid::new_v4` function and the ability to randomly +//! generate a `Uuid`. +//! * `v5` - adds the `Uuid::new_v5` function and the ability to create a V5 +//! UUID based on the SHA1 hash of some data. +//! * `rustc-serialize` - adds the ability to serialize and deserialize a `Uuid` +//! using the `rustc-serialize` crate. +//! * `serde` - adds the ability to serialize and deserialize a `Uuid` using the +//! `serde` crate. +//! +//! By default, `uuid` can be depended on with: +//! +//! ```toml +//! [dependencies] +//! uuid = "0.2" +//! ``` +//! +//! To activate various features, use syntax like: +//! +//! ```toml +//! [dependencies] +//! uuid = { version = "0.2", features = ["serde", "v4"] } +//! ``` +//! +//! # Examples +//! +//! To parse a UUID given in the simple format and print it as a urn: +//! +//! ```rust +//! use uuid::Uuid; +//! +//! fn main() { +//! let my_uuid = Uuid::parse_str("936DA01F9ABD4d9d80C702AF85C822A8").unwrap(); +//! println!("{}", my_uuid.urn()); +//! } +//! ``` +//! +//! To create a new random (V4) UUID and print it out in hexadecimal form: +//! +//! ```ignore,rust +//! // Note that this requires the `v4` feature enabled in the uuid crate. +//! +//! use uuid::Uuid; +//! +//! fn main() { +//! let my_uuid = Uuid::new_v4(); +//! println!("{}", my_uuid); +//! } +//! ``` +//! +//! # Strings +//! +//! Examples of string representations: +//! +//! * simple: `936DA01F9ABD4d9d80C702AF85C822A8` +//! * hyphenated: `550e8400-e29b-41d4-a716-446655440000` +//! * urn: `urn:uuid:F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4` +//! +//! # References +//! +//! * [Wikipedia: Universally Unique Identifier]( +//! http://en.wikipedia.org/wiki/Universally_unique_identifier) +//! * [RFC4122: A Universally Unique IDentifier (UUID) URN Namespace]( +//! http://tools.ietf.org/html/rfc4122) + +#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", + html_favicon_url = "https://www.rust-lang.org/favicon.ico", + html_root_url = "https://doc.rust-lang.org/uuid/")] + +#![deny(warnings)] +#![no_std] + +#[cfg(feature = "v4")] +extern crate rand; +#[cfg(feature = "v5")] +extern crate sha1; + + +use core::fmt; +use core::hash; +use core::str::FromStr; + +// rustc-serialize and serde link to std, so go ahead an pull in our own std +// support in those situations as well. +#[cfg(any(feature = "use_std", + feature = "rustc-serialize", + feature = "serde"))] +mod std_support; +#[cfg(feature = "rustc-serialize")] +mod rustc_serialize; +#[cfg(feature = "serde")] +mod serde; + +#[cfg(feature = "v4")] +use rand::Rng; +#[cfg(feature = "v5")] +use sha1::Sha1; + +/// A 128-bit (16 byte) buffer containing the ID. +pub type UuidBytes = [u8; 16]; + +/// The version of the UUID, denoting the generating algorithm. +#[derive(PartialEq, Copy, Clone)] +pub enum UuidVersion { + /// Version 1: MAC address + Mac = 1, + /// Version 2: DCE Security + Dce = 2, + /// Version 3: MD5 hash + Md5 = 3, + /// Version 4: Random + Random = 4, + /// Version 5: SHA-1 hash + Sha1 = 5, +} + +/// The reserved variants of UUIDs. +#[derive(PartialEq, Copy, Clone)] +pub enum UuidVariant { + /// Reserved by the NCS for backward compatibility + NCS, + /// As described in the RFC4122 Specification (default) + RFC4122, + /// Reserved by Microsoft for backward compatibility + Microsoft, + /// Reserved for future expansion + Future, +} + +/// A Universally Unique Identifier (UUID). +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] +pub struct Uuid { + /// The 128-bit number stored in 16 bytes + bytes: UuidBytes, +} + +/// An adaptor for formatting a `Uuid` as a simple string. +pub struct Simple<'a> { + inner: &'a Uuid, +} + +/// An adaptor for formatting a `Uuid` as a hyphenated string. +pub struct Hyphenated<'a> { + inner: &'a Uuid, +} + +/// A UUID of the namespace of fully-qualified domain names +pub const NAMESPACE_DNS: Uuid = Uuid { + bytes: [0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, + 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8] +}; + +/// A UUID of the namespace of URLs +pub const NAMESPACE_URL: Uuid = Uuid { + bytes: [0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1, + 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8] +}; + +/// A UUID of the namespace of ISO OIDs +pub const NAMESPACE_OID: Uuid = Uuid { + bytes: [0x6b, 0xa7, 0xb8, 0x12, 0x9d, 0xad, 0x11, 0xd1, + 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8] +}; + +/// A UUID of the namespace of X.500 DNs (in DER or a text output format) +pub const NAMESPACE_X500: Uuid = Uuid { + bytes: [0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1, + 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8] +}; + + +/// An adaptor for formatting a `Uuid` as a URN string. +pub struct Urn<'a> { + inner: &'a Uuid, +} + +/// Error details for string parsing failures. +#[allow(missing_docs)] +#[derive(PartialEq, Eq, Copy, Clone, Debug)] +pub enum ParseError { + InvalidLength(usize), + InvalidCharacter(char, usize), + InvalidGroups(usize), + InvalidGroupLength(usize, usize, u8), +} + +const SIMPLE_LENGTH: usize = 32; +const HYPHENATED_LENGTH: usize = 36; + +/// Converts a ParseError to a string. +impl fmt::Display for ParseError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + ParseError::InvalidLength(found) => { + write!(f, + "Invalid length; expecting {} or {} chars, found {}", + SIMPLE_LENGTH, HYPHENATED_LENGTH, found) + } + ParseError::InvalidCharacter(found, pos) => { + write!(f, + "Invalid character; found `{}` (0x{:02x}) at offset {}", + found, + found as usize, + pos) + } + ParseError::InvalidGroups(found) => { + write!(f, + "Malformed; wrong number of groups: expected 1 or 5, found {}", + found) + } + ParseError::InvalidGroupLength(group, found, expecting) => { + write!(f, + "Malformed; length of group {} was {}, expecting {}", + group, + found, + expecting) + } + } + } +} + +// Length of each hyphenated group in hex digits. +const GROUP_LENS: [u8; 5] = [8, 4, 4, 4, 12]; +// Accumulated length of each hyphenated group in hex digits. +const ACC_GROUP_LENS: [u8; 5] = [8, 12, 16, 20, 32]; + +impl Uuid { + /// The 'nil UUID'. + /// + /// The nil UUID is special form of UUID that is specified to have all + /// 128 bits set to zero, as defined in [IETF RFC 4122 Section 4.1.7][RFC]. + /// + /// [RFC]: https://tools.ietf.org/html/rfc4122.html#section-4.1.7 + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use uuid::Uuid; + /// + /// let uuid = Uuid::nil(); + /// + /// assert_eq!(uuid.hyphenated().to_string(), + /// "00000000-0000-0000-0000-000000000000"); + /// ``` + pub fn nil() -> Uuid { + Uuid { bytes: [0; 16] } + } + + /// Creates a new `Uuid`. + /// + /// Note that not all versions can be generated currently and `None` will be + /// returned if the specified version cannot be generated. + /// + /// To generate a random UUID (`UuidVersion::Random`), then the `v4` + /// feature must be enabled for this crate. + pub fn new(v: UuidVersion) -> Option { + match v { + #[cfg(feature = "v4")] + UuidVersion::Random => Some(Uuid::new_v4()), + _ => None, + } + } + + /// Creates a random `Uuid`. + /// + /// This uses the `rand` crate's default task RNG as the source of random numbers. + /// If you'd like to use a custom generator, don't use this method: use the + /// [`rand::Rand trait`]'s `rand()` method instead. + /// + /// [`rand::Rand trait`]: ../../rand/rand/trait.Rand.html#tymethod.rand + /// + /// Note that usage of this method requires the `v4` feature of this crate + /// to be enabled. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use uuid::Uuid; + /// + /// let uuid = Uuid::new_v4(); + /// ``` + #[cfg(feature = "v4")] + pub fn new_v4() -> Uuid { + rand::thread_rng().gen() + } + + /// Creates a UUID using a name from a namespace, based on the SHA-1 hash. + /// + /// A number of namespaces are available as constants in this crate: + /// + /// * `NAMESPACE_DNS` + /// * `NAMESPACE_URL` + /// * `NAMESPACE_OID` + /// * `NAMESPACE_X500` + /// + /// Note that usage of this method requires the `v5` feature of this crate + /// to be enabled. + #[cfg(feature = "v5")] + pub fn new_v5(namespace: &Uuid, name: &str) -> Uuid { + let mut hash = Sha1::new(); + hash.update(namespace.as_bytes()); + hash.update(name.as_bytes()); + let buffer = hash.digest().bytes(); + let mut uuid = Uuid { bytes: [0; 16] }; + copy_memory(&mut uuid.bytes, &buffer[..16]); + uuid.set_variant(UuidVariant::RFC4122); + uuid.set_version(UuidVersion::Sha1); + uuid + } + + /// Creates a `Uuid` from four field values. + /// + /// # Errors + /// + /// This function will return an error if `d4`'s length is not 8 bytes. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use uuid::Uuid; + /// + /// let d4 = [12, 3, 9, 56, 54, 43, 8, 9]; + /// + /// let uuid = Uuid::from_fields(42, 12, 5, &d4); + /// let uuid = uuid.map(|uuid| uuid.hyphenated().to_string()); + /// + /// let expected_uuid = Ok(String::from("0000002a-000c-0005-0c03-0938362b0809")); + /// + /// assert_eq!(expected_uuid, uuid); + /// ``` + /// + /// An invalid length: + /// + /// ``` + /// use uuid::Uuid; + /// use uuid::ParseError; + /// + /// let d4 = [12]; + /// + /// let uuid = Uuid::from_fields(42, 12, 5, &d4); + /// + /// let expected_uuid = Err(ParseError::InvalidLength(1)); + /// + /// assert_eq!(expected_uuid, uuid); + /// ``` + pub fn from_fields(d1: u32, + d2: u16, + d3: u16, + d4: &[u8]) -> Result { + if d4.len() != 8 { + return Err(ParseError::InvalidLength(d4.len())) + } + + Ok(Uuid { + bytes: [ + (d1 >> 24) as u8, + (d1 >> 16) as u8, + (d1 >> 8) as u8, + (d1 >> 0) as u8, + (d2 >> 8) as u8, + (d2 >> 0) as u8, + (d3 >> 8) as u8, + (d3 >> 0) as u8, + d4[0], d4[1], d4[2], d4[3], d4[4], d4[5], d4[6], d4[7] + ], + }) + } + + /// Creates a `Uuid` using the supplied bytes. + /// + /// # Errors + /// + /// This function will return an error if `b` has any length other than 16. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use uuid::Uuid; + /// + /// let bytes = [4, 54, 67, 12, 43, 2, 98, 76, + /// 32, 50, 87, 5, 1, 33, 43, 87]; + /// + /// let uuid = Uuid::from_bytes(&bytes); + /// let uuid = uuid.map(|uuid| uuid.hyphenated().to_string()); + /// + /// let expected_uuid = Ok(String::from("0436430c-2b02-624c-2032-570501212b57")); + /// + /// assert_eq!(expected_uuid, uuid); + /// ``` + /// + /// An incorrect number of bytes: + /// + /// ``` + /// use uuid::Uuid; + /// use uuid::ParseError; + /// + /// let bytes = [4, 54, 67, 12, 43, 2, 98, 76]; + /// + /// let uuid = Uuid::from_bytes(&bytes); + /// + /// let expected_uuid = Err(ParseError::InvalidLength(8)); + /// + /// assert_eq!(expected_uuid, uuid); + /// ``` + pub fn from_bytes(b: &[u8]) -> Result { + let len = b.len(); + if len != 16 { + return Err(ParseError::InvalidLength(len)); + } + + let mut uuid = Uuid { bytes: [0; 16] }; + copy_memory(&mut uuid.bytes, b); + Ok(uuid) + } + + /// Specifies the variant of the UUID structure + #[allow(dead_code)] + fn set_variant(&mut self, v: UuidVariant) { + // Octet 8 contains the variant in the most significant 3 bits + self.bytes[8] = match v { + UuidVariant::NCS => self.bytes[8] & 0x7f, // b0xx... + UuidVariant::RFC4122 => (self.bytes[8] & 0x3f) | 0x80, // b10x... + UuidVariant::Microsoft => (self.bytes[8] & 0x1f) | 0xc0, // b110... + UuidVariant::Future => (self.bytes[8] & 0x1f) | 0xe0, // b111... + } + } + + /// Returns the variant of the `Uuid` structure. + /// + /// This determines the interpretation of the structure of the UUID. + /// Currently only the RFC4122 variant is generated by this module. + /// + /// * [Variant Reference](http://tools.ietf.org/html/rfc4122#section-4.1.1) + pub fn get_variant(&self) -> Option { + match self.bytes[8] { + x if x & 0x80 == 0x00 => Some(UuidVariant::NCS), + x if x & 0xc0 == 0x80 => Some(UuidVariant::RFC4122), + x if x & 0xe0 == 0xc0 => Some(UuidVariant::Microsoft), + x if x & 0xe0 == 0xe0 => Some(UuidVariant::Future), + _ => None, + } + } + + /// Specifies the version number of the `Uuid`. + #[allow(dead_code)] + fn set_version(&mut self, v: UuidVersion) { + self.bytes[6] = (self.bytes[6] & 0xF) | ((v as u8) << 4); + } + + /// Returns the version number of the `Uuid`. + /// + /// This represents the algorithm used to generate the contents. + /// + /// Currently only the Random (V4) algorithm is supported by this + /// module. There are security and privacy implications for using + /// older versions - see [Wikipedia: Universally Unique Identifier]( + /// http://en.wikipedia.org/wiki/Universally_unique_identifier) for + /// details. + /// + /// * [Version Reference](http://tools.ietf.org/html/rfc4122#section-4.1.3) + pub fn get_version_num(&self) -> usize { + (self.bytes[6] >> 4) as usize + } + + /// Returns the version of the `Uuid`. + /// + /// This represents the algorithm used to generate the contents + pub fn get_version(&self) -> Option { + let v = self.bytes[6] >> 4; + match v { + 1 => Some(UuidVersion::Mac), + 2 => Some(UuidVersion::Dce), + 3 => Some(UuidVersion::Md5), + 4 => Some(UuidVersion::Random), + 5 => Some(UuidVersion::Sha1), + _ => None, + } + } + + /// Return an array of 16 octets containing the UUID data + /// + /// # Examples + /// + /// ``` + /// use uuid::Uuid; + /// + /// let uuid = Uuid::nil(); + /// assert_eq!(uuid.as_bytes(), &[0; 16]); + /// + /// let uuid = Uuid::parse_str("936DA01F9ABD4d9d80C702AF85C822A8").unwrap(); + /// assert_eq!(uuid.as_bytes(), + /// &[147, 109, 160, 31, 154, 189, 77, 157, + /// 128, 199, 2, 175, 133, 200, 34, 168]); + /// ``` + pub fn as_bytes(&self) -> &[u8; 16] { + &self.bytes + } + + /// Returns a wrapper which when formatted via `fmt::Display` will format a + /// string of 32 hexadecimal digits. + /// + /// # Examples + /// + /// ``` + /// use uuid::Uuid; + /// + /// let uuid = Uuid::nil(); + /// assert_eq!(uuid.simple().to_string(), + /// "00000000000000000000000000000000"); + /// ``` + pub fn simple(&self) -> Simple { + Simple { inner: self } + } + + /// Returns a wrapper which when formatted via `fmt::Display` will format a + /// string of hexadecimal digits separated into groups with a hyphen. + /// + /// # Examples + /// + /// ``` + /// use uuid::Uuid; + /// + /// let uuid = Uuid::nil(); + /// assert_eq!(uuid.hyphenated().to_string(), + /// "00000000-0000-0000-0000-000000000000"); + /// ``` + pub fn hyphenated(&self) -> Hyphenated { + Hyphenated { inner: self } + } + + /// Returns a wrapper which when formatted via `fmt::Display` will format a + /// string of the UUID as a full URN string. + /// + /// # Examples + /// + /// ``` + /// use uuid::Uuid; + /// + /// let uuid = Uuid::nil(); + /// assert_eq!(uuid.urn().to_string(), + /// "urn:uuid:00000000-0000-0000-0000-000000000000"); + /// ``` + pub fn urn(&self) -> Urn { + Urn { inner: self } + } + + /// Parses a `Uuid` from a string of hexadecimal digits with optional hyphens. + /// + /// Any of the formats generated by this module (simple, hyphenated, urn) are + /// supported by this parsing function. + pub fn parse_str(mut input: &str) -> Result { + // Ensure length is valid for any of the supported formats + let len = input.len(); + if len == (HYPHENATED_LENGTH + 9) && input.starts_with("urn:uuid:") { + input = &input[9..]; + } else if len != SIMPLE_LENGTH && len != HYPHENATED_LENGTH { + return Err(ParseError::InvalidLength(len)); + } + + // `digit` counts only hexadecimal digits, `i_char` counts all chars. + let mut digit = 0; + let mut group = 0; + let mut acc = 0; + let mut buffer = [0u8; 16]; + + for (i_char, chr) in input.chars().enumerate() { + if digit as usize >= SIMPLE_LENGTH && group == 0 { + return Err(ParseError::InvalidLength(len)); + } + + if digit % 2 == 0 { + // First digit of the byte. + match chr { + // Calulate upper half. + '0'...'9' => acc = chr as u8 - '0' as u8, + 'a'...'f' => acc = chr as u8 - 'a' as u8 + 10, + 'A'...'F' => acc = chr as u8 - 'A' as u8 + 10, + // Found a group delimiter + '-' => { + if ACC_GROUP_LENS[group] != digit { + // Calculate how many digits this group consists of in the input. + let found = if group > 0 { + digit - ACC_GROUP_LENS[group - 1] + } else { + digit + }; + return Err(ParseError::InvalidGroupLength(group, + found as usize, + GROUP_LENS[group])); + } + // Next group, decrement digit, it is incremented again at the bottom. + group += 1; + digit -= 1; + } + _ => return Err(ParseError::InvalidCharacter(chr, i_char)), + } + } else { + // Second digit of the byte, shift the upper half. + acc *= 16; + match chr { + '0'...'9' => acc += chr as u8 - '0' as u8, + 'a'...'f' => acc += chr as u8 - 'a' as u8 + 10, + 'A'...'F' => acc += chr as u8 - 'A' as u8 + 10, + '-' => { + // The byte isn't complete yet. + let found = if group > 0 { + digit - ACC_GROUP_LENS[group - 1] + } else { + digit + }; + return Err(ParseError::InvalidGroupLength(group, + found as usize, + GROUP_LENS[group])); + } + _ => return Err(ParseError::InvalidCharacter(chr, i_char)), + } + buffer[(digit / 2) as usize] = acc; + } + digit += 1; + } + + // Now check the last group. + if group != 0 && group != 4 { + return Err(ParseError::InvalidGroups(group + 1)); + } else if ACC_GROUP_LENS[4] != digit { + return Err(ParseError::InvalidGroupLength(group, + (digit - ACC_GROUP_LENS[3]) as usize, + GROUP_LENS[4])); + } + + Ok(Uuid::from_bytes(&mut buffer).unwrap()) + } + + /// Tests if the UUID is nil + pub fn is_nil(&self) -> bool { + self.bytes.iter().all(|&b| b == 0) + } +} + +fn copy_memory(dst: &mut [u8], src: &[u8]) { + for (slot, val) in dst.iter_mut().zip(src.iter()) { + *slot = *val; + } +} + +impl Default for Uuid { + /// Returns the nil UUID, which is all zeroes + fn default() -> Uuid { + Uuid::nil() + } +} + +impl FromStr for Uuid { + type Err = ParseError; + + /// Parse a hex string and interpret as a `Uuid`. + /// + /// Accepted formats are a sequence of 32 hexadecimal characters, + /// with or without hyphens (grouped as 8, 4, 4, 4, 12). + fn from_str(us: &str) -> Result { + Uuid::parse_str(us) + } +} + +impl fmt::Debug for Uuid { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Uuid(\"{}\")", self.hyphenated()) + } +} + +impl fmt::Display for Uuid { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.hyphenated().fmt(f) + } +} + +impl hash::Hash for Uuid { + fn hash(&self, state: &mut S) { + self.bytes.hash(state) + } +} + +impl<'a> fmt::Display for Simple<'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + for byte in self.inner.bytes.iter() { + try!(write!(f, "{:02x}", byte)); + } + Ok(()) + } +} + +impl<'a> fmt::Display for Hyphenated<'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let data1 = ((self.inner.bytes[0] as u32) << 24) | + ((self.inner.bytes[1] as u32) << 16) | + ((self.inner.bytes[2] as u32) << 8) | + ((self.inner.bytes[3] as u32) << 0); + let data2 = ((self.inner.bytes[4] as u16) << 8) | + ((self.inner.bytes[5] as u16) << 0); + let data3 = ((self.inner.bytes[6] as u16) << 8) | + ((self.inner.bytes[7] as u16) << 0); + + write!(f, "{:08x}-\ + {:04x}-\ + {:04x}-\ + {:02x}{:02x}-\ + {:02x}{:02x}{:02x}{:02x}{:02x}{:02x}", + data1, + data2, + data3, + self.inner.bytes[8], + self.inner.bytes[9], + self.inner.bytes[10], + self.inner.bytes[11], + self.inner.bytes[12], + self.inner.bytes[13], + self.inner.bytes[14], + self.inner.bytes[15]) + } +} + +impl<'a> fmt::Display for Urn<'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "urn:uuid:{}", self.inner.hyphenated()) + } +} + +/// Generates a random `Uuid` (V4 conformant). +#[cfg(feature = "v4")] +impl rand::Rand for Uuid { + fn rand(rng: &mut R) -> Uuid { + let mut uuid = Uuid { bytes: [0; 16] }; + rng.fill_bytes(&mut uuid.bytes); + uuid.set_variant(UuidVariant::RFC4122); + uuid.set_version(UuidVersion::Random); + uuid + } +} + +#[cfg(test)] +mod tests { + extern crate std; + + use self::std::prelude::v1::*; + + use super::{NAMESPACE_DNS, NAMESPACE_URL, NAMESPACE_OID, NAMESPACE_X500}; + use super::{Uuid, UuidVariant, UuidVersion}; + + #[cfg(feature = "v4")] + use rand; + + fn new() -> Uuid { + Uuid::parse_str("F9168C5E-CEB2-4FAA-B6BF-329BF39FA1E4").unwrap() + } + + fn new2() -> Uuid { + Uuid::parse_str("F9168C5E-CEB2-4FAB-B6BF-329BF39FA1E4").unwrap() + } + + #[cfg(feature = "v5")] + static FIXTURE_V5: &'static [(&'static Uuid, &'static str, &'static str)] = &[ + (&NAMESPACE_DNS, "example.org", "aad03681-8b63-5304-89e0-8ca8f49461b5"), + (&NAMESPACE_DNS, "rust-lang.org", "c66bbb60-d62e-5f17-a399-3a0bd237c503"), + (&NAMESPACE_DNS, "42", "7c411b5e-9d3f-50b5-9c28-62096e41c4ed"), + (&NAMESPACE_DNS, "lorem ipsum", "97886a05-8a68-5743-ad55-56ab2d61cf7b"), + (&NAMESPACE_URL, "example.org", "54a35416-963c-5dd6-a1e2-5ab7bb5bafc7"), + (&NAMESPACE_URL, "rust-lang.org", "c48d927f-4122-5413-968c-598b1780e749"), + (&NAMESPACE_URL, "42", "5c2b23de-4bad-58ee-a4b3-f22f3b9cfd7d"), + (&NAMESPACE_URL, "lorem ipsum", "15c67689-4b85-5253-86b4-49fbb138569f"), + (&NAMESPACE_OID, "example.org", "34784df9-b065-5094-92c7-00bb3da97a30"), + (&NAMESPACE_OID, "rust-lang.org", "8ef61ecb-977a-5844-ab0f-c25ef9b8d5d6"), + (&NAMESPACE_OID, "42", "ba293c61-ad33-57b9-9671-f3319f57d789"), + (&NAMESPACE_OID, "lorem ipsum", "6485290d-f79e-5380-9e64-cb4312c7b4a6"), + (&NAMESPACE_X500, "example.org", "e3635e86-f82b-5bbc-a54a-da97923e5c76"), + (&NAMESPACE_X500, "rust-lang.org", "26c9c3e9-49b7-56da-8b9f-a0fb916a71a3"), + (&NAMESPACE_X500, "42", "e4b88014-47c6-5fe0-a195-13710e5f6e27"), + (&NAMESPACE_X500, "lorem ipsum", "b11f79a5-1e6d-57ce-a4b5-ba8531ea03d0"), + ]; + + #[test] + fn test_nil() { + let nil = Uuid::nil(); + let not_nil = new(); + + assert!(nil.is_nil()); + assert!(!not_nil.is_nil()); + } + + #[test] + fn test_new() { + if cfg!(feature = "v4") { + let uuid1 = Uuid::new(UuidVersion::Random).unwrap(); + let s = uuid1.simple().to_string(); + + assert!(s.len() == 32); + assert!(uuid1.get_version().unwrap() == UuidVersion::Random); + } else { + assert!(Uuid::new(UuidVersion::Random).is_none()); + } + + // Test unsupported versions + assert!(Uuid::new(UuidVersion::Mac) == None); + assert!(Uuid::new(UuidVersion::Dce) == None); + assert!(Uuid::new(UuidVersion::Md5) == None); + assert!(Uuid::new(UuidVersion::Sha1) == None); + } + + #[test] + #[cfg(feature = "v4")] + fn test_new_v4() { + let uuid1 = Uuid::new_v4(); + + assert!(uuid1.get_version().unwrap() == UuidVersion::Random); + assert!(uuid1.get_variant().unwrap() == UuidVariant::RFC4122); + } + + #[cfg(feature = "v5")] + #[test] + fn test_new_v5() { + for &(ref ns, ref name, _) in FIXTURE_V5 { + let uuid = Uuid::new_v5(*ns, *name); + assert!(uuid.get_version().unwrap() == UuidVersion::Sha1); + assert!(uuid.get_variant().unwrap() == UuidVariant::RFC4122); + } + } + + #[test] + fn test_predefined_namespaces() { + assert_eq!(NAMESPACE_DNS.hyphenated().to_string(), + "6ba7b810-9dad-11d1-80b4-00c04fd430c8"); + assert_eq!(NAMESPACE_URL.hyphenated().to_string(), + "6ba7b811-9dad-11d1-80b4-00c04fd430c8"); + assert_eq!(NAMESPACE_OID.hyphenated().to_string(), + "6ba7b812-9dad-11d1-80b4-00c04fd430c8"); + assert_eq!(NAMESPACE_X500.hyphenated().to_string(), + "6ba7b814-9dad-11d1-80b4-00c04fd430c8"); + } + + #[test] + #[cfg(feature = "v4")] + fn test_get_version_v4() { + let uuid1 = Uuid::new_v4(); + + assert!(uuid1.get_version().unwrap() == UuidVersion::Random); + assert_eq!(uuid1.get_version_num(), 4); + } + + #[cfg(feature = "v5")] + #[test] + fn test_get_version_v5() { + let uuid2 = Uuid::new_v5(&NAMESPACE_DNS, "rust-lang.org"); + + assert!(uuid2.get_version().unwrap() == UuidVersion::Sha1); + assert_eq!(uuid2.get_version_num(), 5); + } + + #[test] + fn test_get_variant() { + let uuid1 = new(); + let uuid2 = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap(); + let uuid3 = Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8").unwrap(); + let uuid4 = Uuid::parse_str("936DA01F9ABD4d9dC0C702AF85C822A8").unwrap(); + let uuid5 = Uuid::parse_str("F9168C5E-CEB2-4faa-D6BF-329BF39FA1E4").unwrap(); + let uuid6 = Uuid::parse_str("f81d4fae-7dec-11d0-7765-00a0c91e6bf6").unwrap(); + + assert!(uuid1.get_variant().unwrap() == UuidVariant::RFC4122); + assert!(uuid2.get_variant().unwrap() == UuidVariant::RFC4122); + assert!(uuid3.get_variant().unwrap() == UuidVariant::RFC4122); + assert!(uuid4.get_variant().unwrap() == UuidVariant::Microsoft); + assert!(uuid5.get_variant().unwrap() == UuidVariant::Microsoft); + assert!(uuid6.get_variant().unwrap() == UuidVariant::NCS); + } + + #[test] + fn test_parse_uuid_v4() { + use super::ParseError::*; + + // Invalid + assert_eq!(Uuid::parse_str(""), Err(InvalidLength(0))); + assert_eq!(Uuid::parse_str("!"), Err(InvalidLength(1))); + assert_eq!(Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E45"), + Err(InvalidLength(37))); + assert_eq!(Uuid::parse_str("F9168C5E-CEB2-4faa-BBF-329BF39FA1E4"), + Err(InvalidLength(35))); + assert_eq!(Uuid::parse_str("F9168C5E-CEB2-4faa-BGBF-329BF39FA1E4"), + Err(InvalidCharacter('G', 20))); + assert_eq!(Uuid::parse_str("F9168C5E-CEB2-4faa-B6BFF329BF39FA1E4"), + Err(InvalidGroups(4))); + assert_eq!(Uuid::parse_str("F9168C5E-CEB2-4faa"), + Err(InvalidLength(18))); + assert_eq!(Uuid::parse_str("F9168C5E-CEB2-4faaXB6BFF329BF39FA1E4"), + Err(InvalidCharacter('X', 18))); + assert_eq!(Uuid::parse_str("F9168C5E-CEB-24fa-eB6BFF32-BF39FA1E4"), + Err(InvalidGroupLength(1, 3, 4))); + assert_eq!(Uuid::parse_str("01020304-1112-2122-3132-41424344"), + Err(InvalidGroupLength(4, 8, 12))); + assert_eq!(Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c"), + Err(InvalidLength(31))); + assert_eq!(Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c88"), + Err(InvalidLength(33))); + assert_eq!(Uuid::parse_str("67e5504410b1426f9247bb680e5fe0cg8"), + Err(InvalidLength(33))); + assert_eq!(Uuid::parse_str("67e5504410b1426%9247bb680e5fe0c8"), + Err(InvalidCharacter('%', 15))); + assert_eq!(Uuid::parse_str("231231212212423424324323477343246663"), + Err(InvalidLength(36))); + + // Valid + assert!(Uuid::parse_str("00000000000000000000000000000000").is_ok()); + assert!(Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8").is_ok()); + assert!(Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4").is_ok()); + assert!(Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c8").is_ok()); + assert!(Uuid::parse_str("01020304-1112-2122-3132-414243444546").is_ok()); + assert!(Uuid::parse_str("urn:uuid:67e55044-10b1-426f-9247-bb680e5fe0c8").is_ok()); + + // Nil + let nil = Uuid::nil(); + assert!(Uuid::parse_str("00000000000000000000000000000000").unwrap() == nil); + assert!(Uuid::parse_str("00000000-0000-0000-0000-000000000000").unwrap() == nil); + + // Round-trip + let uuid_orig = new(); + let orig_str = uuid_orig.to_string(); + let uuid_out = Uuid::parse_str(&orig_str).unwrap(); + assert!(uuid_orig == uuid_out); + + // Test error reporting + assert_eq!(Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c"), + Err(InvalidLength(31))); + assert_eq!(Uuid::parse_str("67e550X410b1426f9247bb680e5fe0cd"), + Err(InvalidCharacter('X', 6))); + assert_eq!(Uuid::parse_str("67e550-4105b1426f9247bb680e5fe0c"), + Err(InvalidGroupLength(0, 6, 8))); + assert_eq!(Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF1-02BF39FA1E4"), + Err(InvalidGroupLength(3, 5, 4))); + } + + #[test] + fn test_to_simple_string() { + let uuid1 = new(); + let s = uuid1.simple().to_string(); + + assert!(s.len() == 32); + assert!(s.chars().all(|c| c.is_digit(16))); + } + + #[test] + fn test_to_string() { + let uuid1 = new(); + let s = uuid1.to_string(); + + assert!(s.len() == 36); + assert!(s.chars().all(|c| c.is_digit(16) || c == '-')); + } + + #[test] + fn test_display() { + let uuid1 = new(); + let s = uuid1.to_string(); + + assert_eq!(s, uuid1.hyphenated().to_string()); + } + + #[test] + fn test_to_hyphenated_string() { + let uuid1 = new(); + let s = uuid1.hyphenated().to_string(); + + assert!(s.len() == 36); + assert!(s.chars().all(|c| c.is_digit(16) || c == '-')); + } + + #[cfg(feature = "v5")] + #[test] + fn test_v5_to_hypenated_string() { + for &(ref ns, ref name, ref expected) in FIXTURE_V5 { + let uuid = Uuid::new_v5(*ns, *name); + assert_eq!(uuid.hyphenated().to_string(), *expected); + } + } + + #[test] + fn test_to_urn_string() { + let uuid1 = new(); + let ss = uuid1.urn().to_string(); + let s = &ss[9..]; + + assert!(ss.starts_with("urn:uuid:")); + assert!(s.len() == 36); + assert!(s.chars().all(|c| c.is_digit(16) || c == '-')); + } + + #[test] + fn test_to_simple_string_matching() { + let uuid1 = new(); + + let hs = uuid1.hyphenated().to_string(); + let ss = uuid1.simple().to_string(); + + let hsn = hs.chars().filter(|&c| c != '-').collect::(); + + assert!(hsn == ss); + } + + #[test] + fn test_string_roundtrip() { + let uuid = new(); + + let hs = uuid.hyphenated().to_string(); + let uuid_hs = Uuid::parse_str(&hs).unwrap(); + assert_eq!(uuid_hs, uuid); + + let ss = uuid.to_string(); + let uuid_ss = Uuid::parse_str(&ss).unwrap(); + assert_eq!(uuid_ss, uuid); + } + + #[test] + fn test_compare() { + let uuid1 = new(); + let uuid2 = new2(); + + assert!(uuid1 == uuid1); + assert!(uuid2 == uuid2); + assert!(uuid1 != uuid2); + assert!(uuid2 != uuid1); + } + + #[test] + fn test_from_fields() { + let d1: u32 = 0xa1a2a3a4; + let d2: u16 = 0xb1b2; + let d3: u16 = 0xc1c2; + let d4 = [0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8]; + + let u = Uuid::from_fields(d1, d2, d3, &d4).unwrap(); + + let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8"; + let result = u.simple().to_string(); + assert_eq!(result, expected); + } + + #[test] + fn test_from_bytes() { + let b = [0xa1, 0xa2, 0xa3, 0xa4, 0xb1, 0xb2, 0xc1, 0xc2, 0xd1, 0xd2, + 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8]; + + let u = Uuid::from_bytes(&b).unwrap(); + let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8"; + + assert_eq!(u.simple().to_string(), expected); + } + + #[test] + fn test_as_bytes() { + let u = new(); + let ub = u.as_bytes(); + + assert_eq!(ub.len(), 16); + assert!(!ub.iter().all(|&b| b == 0)); + } + + #[test] + fn test_bytes_roundtrip() { + let b_in: [u8; 16] = [0xa1, 0xa2, 0xa3, 0xa4, 0xb1, 0xb2, 0xc1, 0xc2, 0xd1, 0xd2, 0xd3, + 0xd4, 0xd5, 0xd6, 0xd7, 0xd8]; + + let u = Uuid::from_bytes(&b_in).unwrap(); + + let b_out = u.as_bytes(); + + assert_eq!(&b_in, b_out); + } + + #[test] + fn test_operator_eq() { + let u1 = new(); + let u2 = u1.clone(); + let u3 = new2(); + + assert!(u1 == u1); + assert!(u1 == u2); + assert!(u2 == u1); + + assert!(u1 != u3); + assert!(u3 != u1); + assert!(u2 != u3); + assert!(u3 != u2); + } + + #[test] + #[cfg(feature = "v4")] + fn test_rand_rand() { + let mut rng = rand::thread_rng(); + let u: Uuid = rand::Rand::rand(&mut rng); + let ub = u.as_bytes(); + + assert!(ub.len() == 16); + assert!(!ub.iter().all(|&b| b == 0)); + } + + #[test] + fn test_iterbytes_impl_for_uuid() { + let mut set = std::collections::HashSet::new(); + let id1 = new(); + let id2 = new2(); + set.insert(id1.clone()); + assert!(set.contains(&id1)); + assert!(!set.contains(&id2)); + } +} diff --git a/third_party/rust/uuid/src/rustc_serialize.rs b/third_party/rust/uuid/src/rustc_serialize.rs new file mode 100644 index 000000000000..c1b15f970c9b --- /dev/null +++ b/third_party/rust/uuid/src/rustc_serialize.rs @@ -0,0 +1,34 @@ +extern crate rustc_serialize; +extern crate std; + +use self::std::prelude::v1::*; +use self::rustc_serialize::{Encoder, Encodable, Decoder, Decodable}; + +use Uuid; + +impl Encodable for Uuid { + fn encode(&self, e: &mut E) -> Result<(), E::Error> { + e.emit_str(&self.hyphenated().to_string()) + } +} + +impl Decodable for Uuid { + fn decode(d: &mut D) -> Result { + let string = try!(d.read_str()); + string.parse::().map_err(|err| d.error(&err.to_string())) + } +} + +#[cfg(test)] +mod tests { + use super::rustc_serialize::json; + use Uuid; + + #[test] + fn test_serialize_round_trip() { + let u = Uuid::parse_str("F9168C5E-CEB2-4FAA-B6BF-329BF39FA1E4").unwrap(); + let s = json::encode(&u).unwrap(); + let u2 = json::decode(&s).unwrap(); + assert_eq!(u, u2); + } +} diff --git a/third_party/rust/uuid/src/serde.rs b/third_party/rust/uuid/src/serde.rs new file mode 100644 index 000000000000..080efa1f71b3 --- /dev/null +++ b/third_party/rust/uuid/src/serde.rs @@ -0,0 +1,34 @@ +extern crate serde; +extern crate std; + +use self::std::fmt; +use self::std::prelude::v1::*; +use self::serde::{de, Deserialize, Deserializer, Serialize, Serializer}; + +use Uuid; + +impl Serialize for Uuid { + fn serialize(&self, serializer: S) -> Result { + serializer.serialize_str(&self.hyphenated().to_string()) + } +} + +impl Deserialize for Uuid { + fn deserialize(deserializer: D) -> Result { + struct UuidVisitor; + + impl de::Visitor for UuidVisitor { + type Value = Uuid; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "a UUID string") + } + + fn visit_str(self, value: &str) -> Result { + value.parse::().map_err(|e| E::custom(e.to_string())) + } + } + + deserializer.deserialize_str(UuidVisitor) + } +} diff --git a/third_party/rust/uuid/src/std_support.rs b/third_party/rust/uuid/src/std_support.rs new file mode 100644 index 000000000000..1b97db528d20 --- /dev/null +++ b/third_party/rust/uuid/src/std_support.rs @@ -0,0 +1,9 @@ +extern crate std; + +use ParseError; + +impl std::error::Error for ParseError { + fn description(&self) -> &str { + "UUID parse error" + } +} diff --git a/toolkit/library/gtest/rust/Cargo.lock b/toolkit/library/gtest/rust/Cargo.lock index d72940fd882d..90e0a11db24b 100644 --- a/toolkit/library/gtest/rust/Cargo.lock +++ b/toolkit/library/gtest/rust/Cargo.lock @@ -860,11 +860,22 @@ dependencies = [ "heapsize 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "servo_rand" +version = "0.0.1" +dependencies = [ + "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "servo_url" version = "0.0.1" dependencies = [ + "servo_rand 0.0.1", "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "uuid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1128,6 +1139,14 @@ name = "utf8-ranges" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "uuid" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "vec_map" version = "0.6.0" @@ -1356,6 +1375,7 @@ dependencies = [ "checksum url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f5ba8a749fb4479b043733416c244fa9d1d3af3d7c23804944651c8a448cb87e" "checksum user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ef4711d107b21b410a3a974b1204d9accc8b10dad75d8324b5d755de1617d47" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" +"checksum uuid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7cfec50b0842181ba6e713151b72f4ec84a6a7e2c9c8a8a3ffc37bb1cd16b231" "checksum vec_map 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cac5efe5cb0fa14ec2f84f83c701c562ee63f6dcc680861b21d65c682adfb05f" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff" diff --git a/toolkit/library/rust/Cargo.lock b/toolkit/library/rust/Cargo.lock index becef23dd957..7aa58a7a4dcc 100644 --- a/toolkit/library/rust/Cargo.lock +++ b/toolkit/library/rust/Cargo.lock @@ -847,11 +847,22 @@ dependencies = [ "heapsize 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "servo_rand" +version = "0.0.1" +dependencies = [ + "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "servo_url" version = "0.0.1" dependencies = [ + "servo_rand 0.0.1", "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "uuid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1115,6 +1126,14 @@ name = "utf8-ranges" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "uuid" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "vec_map" version = "0.6.0" @@ -1343,6 +1362,7 @@ dependencies = [ "checksum url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f5ba8a749fb4479b043733416c244fa9d1d3af3d7c23804944651c8a448cb87e" "checksum user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ef4711d107b21b410a3a974b1204d9accc8b10dad75d8324b5d755de1617d47" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" +"checksum uuid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7cfec50b0842181ba6e713151b72f4ec84a6a7e2c9c8a8a3ffc37bb1cd16b231" "checksum vec_map 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cac5efe5cb0fa14ec2f84f83c701c562ee63f6dcc680861b21d65c682adfb05f" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff" From 69ab8f68560d2098b0b452d4b6e09d9560607daa Mon Sep 17 00:00:00 2001 From: Maja Frydrychowicz Date: Tue, 21 Feb 2017 15:08:09 -0500 Subject: [PATCH 044/234] Bug 1341415 - Require action sequences to have an id; r=ato+446296 MozReview-Commit-ID: DjjhIdDJ8HI --HG-- extra : rebase_source : e0474768ccc272392c97a58db541d27ad76ede1f --- testing/marionette/action.js | 7 ++----- testing/marionette/test_action.js | 23 ++++++----------------- 2 files changed, 8 insertions(+), 22 deletions(-) diff --git a/testing/marionette/action.js b/testing/marionette/action.js index 6f57e71a630f..b913457a8909 100644 --- a/testing/marionette/action.js +++ b/testing/marionette/action.js @@ -713,11 +713,8 @@ action.Sequence = class extends Array { // used here only to validate 'type' and InputState type let inputSourceState = InputState.fromJson(actionSequence); let id = actionSequence.id; - if (typeof id == "undefined") { - actionSequence.id = id = element.generateUUID(); - } else if (typeof id != "string") { - throw new InvalidArgumentError(`Expected 'id' to be a string, got: ${id}`); - } + assert.defined(id, "Expected 'id' to be defined"); + assert.string(id, error.pprint`Expected 'id' to be a string, got: ${id}`); let actionItems = actionSequence.actions; if (!Array.isArray(actionItems)) { throw new InvalidArgumentError( diff --git a/testing/marionette/test_action.js b/testing/marionette/test_action.js index 17e2ecd68a4b..74b0446b26a3 100644 --- a/testing/marionette/test_action.js +++ b/testing/marionette/test_action.js @@ -259,6 +259,10 @@ add_test(function test_processInputSourceActionSequenceValidation() { check(`actionSequence.id: ${getTypeString(actionSequence.id)}`, /Expected 'id' to be a string/); + actionSequence.id = undefined; + check(`actionSequence.id: ${getTypeString(actionSequence.id)}`, + /Expected 'id' to be defined/); + actionSequence.id = "some_id"; actionSequence.actions = -1; check(`actionSequence.actions: ${getTypeString(actionSequence.actions)}`, @@ -320,22 +324,6 @@ add_test(function test_processInputSourceActionSequenceKey() { run_next_test(); }); -add_test(function test_processInputSourceActionSequenceGenerateID() { - let actionItems = [ - { - type: "pause", - duration: 5000, - }, - ]; - let actionSequence = { - type: "key", - actions: actionItems, - }; - let actions = action.Sequence.fromJson(actionSequence); - equal(typeof actions[0].id, "string"); - ok(actions[0].id.match(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i)); - run_next_test(); -}); add_test(function test_processInputSourceActionSequenceInputStateMap() { let id = "1"; @@ -473,7 +461,8 @@ add_test(function test_extractActionChain_twoAndThreeTicks() { deepEqual(actionsByTick[2][0], expectedAction); // one empty action sequence - actionsByTick = action.Chain.fromJson([keyActionSequence, {type: "none", actions: []}]); + actionsByTick = action.Chain.fromJson( + [keyActionSequence, {type: "none", id: "some", actions: []}]); equal(keyActionItems.length, actionsByTick.length); equal(1, actionsByTick[0].length); run_next_test(); From c69d1507109af503b7ffae1b69651db6cd796295 Mon Sep 17 00:00:00 2001 From: Kate McKinley Date: Thu, 16 Feb 2017 10:48:59 +0900 Subject: [PATCH 045/234] Bug 1339669 - Update security.mixed_content.hsts_priming_cache_timeout default r=mayhemer MozReview-Commit-ID: CNFrPUyrdO8 --HG-- extra : rebase_source : 858da20cf65369ede5908b07921dfba501956b84 --- dom/security/nsMixedContentBlocker.cpp | 2 +- modules/libpref/init/all.js | 2 +- security/manager/ssl/security-prefs.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dom/security/nsMixedContentBlocker.cpp b/dom/security/nsMixedContentBlocker.cpp index 9999cacbaf79..fec95fc58891 100644 --- a/dom/security/nsMixedContentBlocker.cpp +++ b/dom/security/nsMixedContentBlocker.cpp @@ -61,7 +61,7 @@ bool nsMixedContentBlocker::sUseHSTS = false; // Do we send an HSTS priming request bool nsMixedContentBlocker::sSendHSTSPriming = false; // Default HSTS Priming failure timeout to 7 days, in seconds -uint32_t nsMixedContentBlocker::sHSTSPrimingCacheTimeout = (60 * 24 * 7); +uint32_t nsMixedContentBlocker::sHSTSPrimingCacheTimeout = (60 * 60 * 24 * 7); bool IsEligibleForHSTSPriming(nsIURI* aContentLocation) { diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 8f78a299e0f1..7cd04ddaaee6 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -5593,7 +5593,7 @@ pref("security.mixed_content.send_hsts_priming", true); pref("security.mixed_content.use_hsts", true); #endif // Approximately 1 week default cache for HSTS priming failures, in seconds -pref ("security.mixed_content.hsts_priming_cache_timeout", 10080); +pref ("security.mixed_content.hsts_priming_cache_timeout", 604800); // Force the channel to timeout in 3 seconds if we have not received // expects a time in milliseconds pref ("security.mixed_content.hsts_priming_request_timeout", 3000); diff --git a/security/manager/ssl/security-prefs.js b/security/manager/ssl/security-prefs.js index 2680aed9b44c..48959c144bcb 100644 --- a/security/manager/ssl/security-prefs.js +++ b/security/manager/ssl/security-prefs.js @@ -122,7 +122,7 @@ pref("security.mixed_content.send_hsts_priming", true); pref("security.mixed_content.use_hsts", true); #endif // Approximately 1 week default cache for HSTS priming failures, in seconds -pref ("security.mixed_content.hsts_priming_cache_timeout", 10080); +pref ("security.mixed_content.hsts_priming_cache_timeout", 604800); // Force the channel to timeout in 3 seconds if we have not received // expects a time in milliseconds pref ("security.mixed_content.hsts_priming_request_timeout", 3000); From 6aca49eb8a86000a5465a2122d5599fd8786f58f Mon Sep 17 00:00:00 2001 From: Grigory Kruglov Date: Wed, 22 Feb 2017 11:26:35 -0800 Subject: [PATCH 046/234] Bug 1336001 - Refactor BatchingUploader's state-holder objects to fix threading problems r=rnewman Previous state: - Two threads were racing to get to batchMeta - one to reset its state, and the other to read its internal state to construct a network request, and then to update its internal state. - This resulted in data corruption when payloads had to be split into multiple batches. A core problem was that there is a lot of state shared across thread boundaries. Specifically, BatchMeta is being written and read both by record consumer threads running off of a thread pool, and by the network worker thread(s). This patch refactors BatchMeta and scheduling of network runnables to ensure that cross-thread access is minimized, and "who owns/accesses what" is explicit. - PayloadDispatcher owns scheduling payload runnables and any data they need to share between each other. - UploaderMeta owns information that's necessary to process incoming records. MozReview-Commit-ID: 9hFs3fXGaGM --HG-- rename : mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/BatchMeta.java => mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/UploaderMeta.java rename : mobile/android/tests/background/junit4/src/org/mozilla/gecko/sync/repositories/uploaders/BatchMetaTest.java => mobile/android/tests/background/junit4/src/org/mozilla/gecko/sync/repositories/uploaders/UploaderMetaTest.java extra : rebase_source : f0f1a05f19f40a6514d4f0dac9d531b086c3f3ed --- mobile/android/base/android-services.mozbuild | 2 + .../gecko/sync/net/SyncStorageRequest.java | 4 - .../repositories/uploaders/BatchMeta.java | 185 +++++-------- .../uploaders/BatchingUploader.java | 240 +++++----------- .../uploaders/BufferSizeTracker.java | 10 +- .../sync/repositories/uploaders/Payload.java | 13 +- .../uploaders/PayloadDispatcher.java | 184 +++++++++++++ .../uploaders/PayloadUploadDelegate.java | 55 ++-- .../uploaders/RecordUploadRunnable.java | 13 +- .../repositories/uploaders/UploaderMeta.java | 58 ++++ .../test/TestServer11RepositorySession.java | 7 +- .../repositories/uploaders/BatchMetaTest.java | 258 ++++-------------- .../uploaders/BatchingUploaderTest.java | 213 +++++++++------ .../repositories/uploaders/PayloadTest.java | 28 -- .../uploaders/PayloadUploadDelegateTest.java | 248 +++++++++-------- .../uploaders/RecordUploadRunnableTest.java | 10 +- .../uploaders/UploaderMetaTest.java | 107 ++++++++ 17 files changed, 877 insertions(+), 758 deletions(-) create mode 100644 mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/PayloadDispatcher.java create mode 100644 mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/UploaderMeta.java create mode 100644 mobile/android/tests/background/junit4/src/org/mozilla/gecko/sync/repositories/uploaders/UploaderMetaTest.java diff --git a/mobile/android/base/android-services.mozbuild b/mobile/android/base/android-services.mozbuild index 118a0c44c913..b92b9e13ca2c 100644 --- a/mobile/android/base/android-services.mozbuild +++ b/mobile/android/base/android-services.mozbuild @@ -1022,8 +1022,10 @@ sync_java_files = [TOPSRCDIR + '/mobile/android/services/src/main/java/org/mozil 'sync/repositories/uploaders/BufferSizeTracker.java', 'sync/repositories/uploaders/MayUploadProvider.java', 'sync/repositories/uploaders/Payload.java', + 'sync/repositories/uploaders/PayloadDispatcher.java', 'sync/repositories/uploaders/PayloadUploadDelegate.java', 'sync/repositories/uploaders/RecordUploadRunnable.java', + 'sync/repositories/uploaders/UploaderMeta.java', 'sync/Server11PreviousPostFailedException.java', 'sync/Server11RecordPostFailedException.java', 'sync/setup/activities/ActivityUtils.java', diff --git a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/net/SyncStorageRequest.java b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/net/SyncStorageRequest.java index 989ac95abb53..6cabc4bd503c 100644 --- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/net/SyncStorageRequest.java +++ b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/net/SyncStorageRequest.java @@ -168,10 +168,6 @@ public class SyncStorageRequest implements Resource { public SyncStorageRequestDelegate delegate; protected BaseResource resource; - public SyncStorageRequest() { - super(); - } - // Default implementation. Override this. protected BaseResourceDelegate makeResourceDelegate(SyncStorageRequest request) { return new SyncStorageResourceDelegate(request); diff --git a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/BatchMeta.java b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/BatchMeta.java index 9515885862de..ffac59516b5c 100644 --- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/BatchMeta.java +++ b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/BatchMeta.java @@ -4,82 +4,94 @@ package org.mozilla.gecko.sync.repositories.uploaders; -import android.support.annotation.CheckResult; -import android.support.annotation.NonNull; import android.support.annotation.Nullable; import org.mozilla.gecko.background.common.log.Logger; import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.concurrent.ConcurrentLinkedQueue; -import org.mozilla.gecko.sync.repositories.uploaders.BatchingUploader.TokenModifiedException; -import org.mozilla.gecko.sync.repositories.uploaders.BatchingUploader.LastModifiedChangedUnexpectedly; -import org.mozilla.gecko.sync.repositories.uploaders.BatchingUploader.LastModifiedDidNotChange; /** - * Keeps track of token, Last-Modified value and GUIDs of succeeded records. + * Keeps track of various meta information about a batch series. + * + * NB regarding concurrent access: + * - this class expects access by possibly different, sequentially running threads. + * - concurrent access is not supported. */ -/* @ThreadSafe */ -public class BatchMeta extends BufferSizeTracker { +public class BatchMeta { private static final String LOG_TAG = "BatchMeta"; - // Will be set once first payload upload succeeds. We don't expect this to change until we - // commit the batch, and which point it must change. - /* @GuardedBy("this") */ private Long lastModified; + private volatile Boolean inBatchingMode; + @Nullable private volatile Long lastModified; + private volatile String token; - // Will be set once first payload upload succeeds. We don't expect this to ever change until - // a commit succeeds, at which point this gets set to null. - /* @GuardedBy("this") */ private String token; + // NB: many of the operations on ConcurrentLinkedQueue are not atomic (toArray, for example), + // and so use of this queue type is only possible because this class does not support concurrent + // access. + private final ConcurrentLinkedQueue successRecordGuids = new ConcurrentLinkedQueue<>(); - /* @GuardedBy("accessLock") */ private boolean isUnlimited = false; - - // Accessed by synchronously running threads. - /* @GuardedBy("accessLock") */ private final List successRecordGuids = new ArrayList<>(); - - /* @GuardedBy("accessLock") */ private boolean needsCommit = false; - - protected final Long collectionLastModified; - - public BatchMeta(@NonNull Object payloadLock, long maxBytes, long maxRecords, @Nullable Long collectionLastModified) { - super(payloadLock, maxBytes, maxRecords); - this.collectionLastModified = collectionLastModified; + BatchMeta(@Nullable Long initialLastModified, Boolean initialInBatchingMode) { + lastModified = initialLastModified; + inBatchingMode = initialInBatchingMode; } - protected void setIsUnlimited(boolean isUnlimited) { - synchronized (accessLock) { - this.isUnlimited = isUnlimited; + String[] getSuccessRecordGuids() { + // NB: This really doesn't play well with concurrent access. + final String[] guids = new String[this.successRecordGuids.size()]; + this.successRecordGuids.toArray(guids); + return guids; + } + + void recordSucceeded(final String recordGuid) { + // Sanity check. + if (recordGuid == null) { + throw new IllegalStateException("Record guid is unexpectedly null"); + } + + successRecordGuids.add(recordGuid); + } + + /* package-local */ void setInBatchingMode(boolean inBatchingMode) { + this.inBatchingMode = inBatchingMode; + } + + /* package-local */ Boolean getInBatchingMode() { + return inBatchingMode; + } + + @Nullable + protected Long getLastModified() { + return lastModified; + } + + void setLastModified(final Long newLastModified, final boolean expectedToChange) throws BatchingUploader.LastModifiedChangedUnexpectedly, BatchingUploader.LastModifiedDidNotChange { + if (lastModified == null) { + lastModified = newLastModified; + return; + } + + if (!expectedToChange && !lastModified.equals(newLastModified)) { + Logger.debug(LOG_TAG, "Last-Modified timestamp changed when we didn't expect it"); + throw new BatchingUploader.LastModifiedChangedUnexpectedly(); + + } else if (expectedToChange && lastModified.equals(newLastModified)) { + Logger.debug(LOG_TAG, "Last-Modified timestamp did not change when we expected it to"); + throw new BatchingUploader.LastModifiedDidNotChange(); + + } else { + lastModified = newLastModified; } } - @Override - protected boolean canFit(long recordDeltaByteCount) { - synchronized (accessLock) { - return isUnlimited || super.canFit(recordDeltaByteCount); - } - } - - @Override - @CheckResult - protected boolean addAndEstimateIfFull(long recordDeltaByteCount) { - synchronized (accessLock) { - needsCommit = true; - boolean isFull = super.addAndEstimateIfFull(recordDeltaByteCount); - return !isUnlimited && isFull; - } - } - - protected boolean needToCommit() { - synchronized (accessLock) { - return needsCommit; - } - } - - protected synchronized String getToken() { + @Nullable + protected String getToken() { return token; } - protected synchronized void setToken(final String newToken, boolean isCommit) throws TokenModifiedException { + void setToken(final String newToken, boolean isCommit) throws BatchingUploader.TokenModifiedException { // Set token once in a batching mode. // In a non-batching mode, this.token and newToken will be null, and this is a no-op. if (token == null) { @@ -91,7 +103,7 @@ public class BatchMeta extends BufferSizeTracker { if (isCommit) { // We expect token to be null when commit payload succeeds. if (newToken != null) { - throw new TokenModifiedException(); + throw new BatchingUploader.TokenModifiedException(); } else { token = null; } @@ -100,66 +112,11 @@ public class BatchMeta extends BufferSizeTracker { // We expect new token to always equal current token for non-commit payloads. if (!token.equals(newToken)) { - throw new TokenModifiedException(); + throw new BatchingUploader.TokenModifiedException(); } } - protected synchronized Long getLastModified() { - if (lastModified == null) { - return collectionLastModified; - } - return lastModified; + BatchMeta nextBatchMeta() { + return new BatchMeta(lastModified, inBatchingMode); } - - protected synchronized void setLastModified(final Long newLastModified, final boolean expectedToChange) throws LastModifiedChangedUnexpectedly, LastModifiedDidNotChange { - if (lastModified == null) { - lastModified = newLastModified; - return; - } - - if (!expectedToChange && !lastModified.equals(newLastModified)) { - Logger.debug(LOG_TAG, "Last-Modified timestamp changed when we didn't expect it"); - throw new LastModifiedChangedUnexpectedly(); - - } else if (expectedToChange && lastModified.equals(newLastModified)) { - Logger.debug(LOG_TAG, "Last-Modified timestamp did not change when we expected it to"); - throw new LastModifiedDidNotChange(); - - } else { - lastModified = newLastModified; - } - } - - protected ArrayList getSuccessRecordGuids() { - synchronized (accessLock) { - return new ArrayList<>(this.successRecordGuids); - } - } - - protected void recordSucceeded(final String recordGuid) { - // Sanity check. - if (recordGuid == null) { - throw new IllegalStateException(); - } - - synchronized (accessLock) { - successRecordGuids.add(recordGuid); - } - } - - @Override - protected boolean canFitRecordByteDelta(long byteDelta, long recordCount, long byteCount) { - return isUnlimited || super.canFitRecordByteDelta(byteDelta, recordCount, byteCount); - } - - @Override - protected void reset() { - synchronized (accessLock) { - super.reset(); - token = null; - lastModified = null; - successRecordGuids.clear(); - needsCommit = false; - } - } -} \ No newline at end of file +} diff --git a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/BatchingUploader.java b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/BatchingUploader.java index 26efbd13682d..996edea6b731 100644 --- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/BatchingUploader.java +++ b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/BatchingUploader.java @@ -17,6 +17,9 @@ import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionStoreDeleg import org.mozilla.gecko.sync.repositories.domain.Record; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicLong; @@ -38,14 +41,19 @@ import java.util.concurrent.atomic.AtomicLong; * * Once we go past using one batch this uploader is no longer "atomic". Partial state is exposed * to other clients after our first batch is committed and before our last batch is committed. - * However, our per-batch limits are high, X-I-U-S mechanics help protect downloading clients - * (as long as they implement X-I-U-S) with 412 error codes in case of interleaving upload and download, - * and most mobile clients will not be uploading large-enough amounts of data (especially structured - * data, such as bookmarks). + * However, our per-batch limits are (hopefully) high, X-I-U-S mechanics help protect downloading clients + * (as long as they implement X-I-U-S) with 412 error codes in case of interleaving upload and download. * * Last-Modified header returned with the first batch payload POST success is maintained for a batch, * to guard against concurrent-modification errors (different uploader commits before we're done). * + * Implementation notes: + * - RecordsChannel (via RepositorySession) delivers a stream of records for upload via {@link #process(Record)} + * - UploaderMeta is used to track batch-level information necessary for processing outgoing records + * - PayloadMeta is used to track payload-level information necessary for processing outgoing records + * - BatchMeta within PayloadDispatcher acts as a shared whiteboard which is used for tracking + * information across batches (last-modified, batching mode) as well as batch side-effects (stored guids) + * * Non-batching mode notes: * We also support Sync servers which don't enable batching for uploads. In this case, we respect * payload limits for individual uploads, and every upload is considered a commit. Batching limits @@ -56,29 +64,8 @@ import java.util.concurrent.atomic.AtomicLong; public class BatchingUploader { private static final String LOG_TAG = "BatchingUploader"; - private final Uri collectionUri; - - private volatile boolean recordUploadFailed = false; - - private final BatchMeta batchMeta; - private final Payload payload; - - // Accessed by synchronously running threads, OK to not synchronize and just make it volatile. - private volatile Boolean inBatchingMode; - - // Used to ensure we have thread-safe access to the following: - // - byte and record counts in both Payload and BatchMeta objects - // - buffers in the Payload object - private final Object payloadLock = new Object(); - - protected Executor workQueue; - protected final RepositorySessionStoreDelegate sessionStoreDelegate; - protected final Server11RepositorySession repositorySession; - - protected AtomicLong uploadTimestamp = new AtomicLong(0); - - protected static final int PER_RECORD_OVERHEAD_BYTE_COUNT = RecordUploadRunnable.RECORD_SEPARATOR.length; - protected static final int PER_PAYLOAD_OVERHEAD_BYTE_COUNT = RecordUploadRunnable.RECORDS_END.length; + private static final int PER_RECORD_OVERHEAD_BYTE_COUNT = RecordUploadRunnable.RECORD_SEPARATOR.length; + /* package-local */ static final int PER_PAYLOAD_OVERHEAD_BYTE_COUNT = RecordUploadRunnable.RECORDS_END.length; // Sanity check. RECORD_SEPARATOR and RECORD_START are assumed to be of the same length. static { @@ -87,20 +74,38 @@ public class BatchingUploader { } } + // Accessed by the record consumer thread pool. + // Will be re-created, so mark it as volatile. + private volatile Payload payload; + + // Accessed by both the record consumer thread pool and the network worker thread(s). + /* package-local */ final Uri collectionUri; + /* package-local */ final RepositorySessionStoreDelegate sessionStoreDelegate; + /* package-local */ @VisibleForTesting final PayloadDispatcher payloadDispatcher; + private final Server11RepositorySession repositorySession; + // Will be re-created, so mark it as volatile. + private volatile UploaderMeta uploaderMeta; + + // Used to ensure we have thread-safe access to the following: + // - byte and record counts in both Payload and BatchMeta objects + // - buffers in the Payload object + private final Object payloadLock = new Object(); + + public BatchingUploader(final Server11RepositorySession repositorySession, final Executor workQueue, final RepositorySessionStoreDelegate sessionStoreDelegate) { this.repositorySession = repositorySession; - this.workQueue = workQueue; this.sessionStoreDelegate = sessionStoreDelegate; this.collectionUri = Uri.parse(repositorySession.getServerRepository().collectionURI().toString()); InfoConfiguration config = repositorySession.getServerRepository().getInfoConfiguration(); - this.batchMeta = new BatchMeta( - payloadLock, config.maxTotalBytes, config.maxTotalRecords, - repositorySession.getServerRepository().getCollectionLastModified() - ); + this.uploaderMeta = new UploaderMeta(payloadLock, config.maxTotalBytes, config.maxTotalRecords); this.payload = new Payload(payloadLock, config.maxPostBytes, config.maxPostRecords); + + this.payloadDispatcher = new PayloadDispatcher( + workQueue, this, repositorySession.getServerRepository().getCollectionLastModified()); } + // Called concurrently from the threads running off of a record consumer thread pool. public void process(final Record record) { final String guid = record.guid; final byte[] recordBytes = record.toJSONBytes(); @@ -115,7 +120,7 @@ public class BatchingUploader { } synchronized (payloadLock) { - final boolean canFitRecordIntoBatch = batchMeta.canFit(recordDeltaByteCount); + final boolean canFitRecordIntoBatch = uploaderMeta.canFit(recordDeltaByteCount); final boolean canFitRecordIntoPayload = payload.canFit(recordDeltaByteCount); // Record fits! @@ -139,7 +144,6 @@ public class BatchingUploader { flush(true, false); Logger.debug(LOG_TAG, "Recording the incoming record into a new batch"); - batchMeta.reset(); // Keep track of the overflow record. addAndFlushIfNecessary(recordDeltaByteCount, recordBytes, guid); @@ -150,12 +154,11 @@ public class BatchingUploader { // Convenience function used from the process method; caller must hold a payloadLock. private void addAndFlushIfNecessary(long byteCount, byte[] recordBytes, String guid) { boolean isPayloadFull = payload.addAndEstimateIfFull(byteCount, recordBytes, guid); - boolean isBatchFull = batchMeta.addAndEstimateIfFull(byteCount); + boolean isBatchFull = uploaderMeta.addAndEstimateIfFull(byteCount); // Preemptive commit batch or upload a payload if they're estimated to be full. if (isBatchFull) { flush(true, false); - batchMeta.reset(); } else if (isPayloadFull) { flush(false, false); } @@ -164,136 +167,40 @@ public class BatchingUploader { public void noMoreRecordsToUpload() { Logger.debug(LOG_TAG, "Received 'no more records to upload' signal."); - // Run this after the last payload succeeds, so that we know for sure if we're in a batching - // mode and need to commit with a potentially empty payload. - workQueue.execute(new Runnable() { + // If we have any pending records in the Payload, flush them! + if (!payload.isEmpty()) { + flush(true, true); + return; + } + + // If we don't have any pending records, we still might need to send an empty "commit" + // payload if we are in the batching mode. + // The dispatcher will run the final flush on its executor if necessary after all payloads + // succeed and it knows for sure if we're in a batching mode. + payloadDispatcher.finalizeQueue(uploaderMeta.needToCommit(), new Runnable() { @Override public void run() { - commitIfNecessaryAfterLastPayload(); + flush(true, true); } }); } - @VisibleForTesting - protected void commitIfNecessaryAfterLastPayload() { - // Must be called after last payload upload finishes. - synchronized (payload) { - // If we have any pending records in the Payload, flush them! - if (!payload.isEmpty()) { - flush(true, true); - - // If we have an empty payload but need to commit the batch in the batching mode, flush! - } else if (batchMeta.needToCommit() && Boolean.TRUE.equals(inBatchingMode)) { - flush(true, true); - - // Otherwise, we're done. - } else { - finished(uploadTimestamp); - } - } - } - - /** - * We've been told by our upload delegate that a payload succeeded. - * Depending on the type of payload and batch mode status, inform our delegate of progress. - * - * @param response success response to our commit post - * @param isCommit was this a commit upload? - * @param isLastPayload was this a very last payload we'll upload? - */ - public void payloadSucceeded(final SyncStorageResponse response, final boolean isCommit, final boolean isLastPayload) { - // Sanity check. - if (inBatchingMode == null) { - throw new IllegalStateException("Can't process payload success until we know if we're in a batching mode"); - } - - // We consider records to have been committed if we're not in a batching mode or this was a commit. - // If records have been committed, notify our store delegate. - if (!inBatchingMode || isCommit) { - for (String guid : batchMeta.getSuccessRecordGuids()) { - sessionStoreDelegate.onRecordStoreSucceeded(guid); - } - } - - // If this was our very last commit, we're done storing records. - // Get Last-Modified timestamp from the response, and pass it upstream. - if (isLastPayload) { - finished(response.normalizedTimestampForHeader(SyncResponse.X_LAST_MODIFIED)); - } - } - - public void lastPayloadFailed() { - finished(uploadTimestamp); - } - - private void finished(long lastModifiedTimestamp) { - bumpTimestampTo(uploadTimestamp, lastModifiedTimestamp); - finished(uploadTimestamp); - } - - private void finished(AtomicLong lastModifiedTimestamp) { + /* package-local */ void finished(AtomicLong lastModifiedTimestamp) { repositorySession.storeDone(lastModifiedTimestamp.get()); } - public BatchMeta getCurrentBatch() { - return batchMeta; - } - - public void setInBatchingMode(boolean inBatchingMode) { - this.inBatchingMode = inBatchingMode; - + // Will be called from a thread dispatched by PayloadDispatcher. + // NB: Access to `uploaderMeta.isUnlimited` is guarded by the payloadLock. + /* package-local */ void setUnlimitedMode(boolean isUnlimited) { // If we know for sure that we're not in a batching mode, // consider our batch to be of unlimited size. - this.batchMeta.setIsUnlimited(!inBatchingMode); + this.uploaderMeta.setIsUnlimited(isUnlimited); } - public Boolean getInBatchingMode() { - return inBatchingMode; - } - - public void setLastModified(final Long lastModified, final boolean isCommit) throws BatchingUploaderException { - // Sanity check. - if (inBatchingMode == null) { - throw new IllegalStateException("Can't process Last-Modified before we know we're in a batching mode."); - } - - // In non-batching mode, every time we receive a Last-Modified timestamp, we expect it to change - // since records are "committed" (become visible to other clients) on every payload. - // In batching mode, we only expect Last-Modified to change when we commit a batch. - batchMeta.setLastModified(lastModified, isCommit || !inBatchingMode); - } - - public void recordSucceeded(final String recordGuid) { - Logger.debug(LOG_TAG, "Record store succeeded: " + recordGuid); - batchMeta.recordSucceeded(recordGuid); - } - - public void recordFailed(final String recordGuid) { - recordFailed(new Server11RecordPostFailedException(), recordGuid); - } - - public void recordFailed(final Exception e, final String recordGuid) { - Logger.debug(LOG_TAG, "Record store failed for guid " + recordGuid + " with exception: " + e.toString()); - recordUploadFailed = true; - sessionStoreDelegate.onRecordStoreFailed(e, recordGuid); - } - - public Server11RepositorySession getRepositorySession() { + /* package-local */ Server11RepositorySession getRepositorySession() { return repositorySession; } - private static void bumpTimestampTo(final AtomicLong current, long newValue) { - while (true) { - long existing = current.get(); - if (existing > newValue) { - return; - } - if (current.compareAndSet(existing, newValue)) { - return; - } - } - } - private void flush(final boolean isCommit, final boolean isLastPayload) { final ArrayList outgoing; final ArrayList outgoingGuids; @@ -306,39 +213,28 @@ public class BatchingUploader { outgoingGuids = payload.getRecordGuidsBuffer(); byteCount = payload.getByteCount(); } + payload = payload.nextPayload(); - workQueue.execute(new RecordUploadRunnable( - new BatchingAtomicUploaderMayUploadProvider(), - collectionUri, - batchMeta, - new PayloadUploadDelegate(this, outgoingGuids, isCommit, isLastPayload), - outgoing, - byteCount, - isCommit - )); + payloadDispatcher.queue(outgoing, outgoingGuids, byteCount, isCommit, isLastPayload); - payload.reset(); - } - - private class BatchingAtomicUploaderMayUploadProvider implements MayUploadProvider { - public boolean mayUpload() { - return !recordUploadFailed; + if (isCommit && !isLastPayload) { + uploaderMeta = uploaderMeta.nextUploaderMeta(); } } - public static class BatchingUploaderException extends Exception { + /* package-local */ static class BatchingUploaderException extends Exception { private static final long serialVersionUID = 1L; } - public static class RecordTooLargeToUpload extends BatchingUploaderException { + /* package-local */ static class LastModifiedDidNotChange extends BatchingUploaderException { private static final long serialVersionUID = 1L; } - public static class LastModifiedDidNotChange extends BatchingUploaderException { + /* package-local */ static class LastModifiedChangedUnexpectedly extends BatchingUploaderException { private static final long serialVersionUID = 1L; } - public static class LastModifiedChangedUnexpectedly extends BatchingUploaderException { - private static final long serialVersionUID = 1L; - } - public static class TokenModifiedException extends BatchingUploaderException { + /* package-local */ static class TokenModifiedException extends BatchingUploaderException { private static final long serialVersionUID = 1L; }; + private static class RecordTooLargeToUpload extends BatchingUploaderException { + private static final long serialVersionUID = 1L; + } } \ No newline at end of file diff --git a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/BufferSizeTracker.java b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/BufferSizeTracker.java index 7f4c305f3a78..5672947511e9 100644 --- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/BufferSizeTracker.java +++ b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/BufferSizeTracker.java @@ -19,7 +19,7 @@ public abstract class BufferSizeTracker { /* @GuardedBy("accessLock") */ private long byteCount = BatchingUploader.PER_PAYLOAD_OVERHEAD_BYTE_COUNT; /* @GuardedBy("accessLock") */ private long recordCount = 0; - /* @GuardedBy("accessLock") */ protected Long smallestRecordByteCount; + /* @GuardedBy("accessLock") */ private Long smallestRecordByteCount; protected final long maxBytes; protected final long maxRecords; @@ -87,14 +87,6 @@ public abstract class BufferSizeTracker { } } - @CallSuper - protected void reset() { - synchronized (accessLock) { - byteCount = BatchingUploader.PER_PAYLOAD_OVERHEAD_BYTE_COUNT; - recordCount = 0; - } - } - @CallSuper protected boolean canFitRecordByteDelta(long byteDelta, long recordCount, long byteCount) { return recordCount < maxRecords diff --git a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/Payload.java b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/Payload.java index 1ed9b57985cc..204eab3f1359 100644 --- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/Payload.java +++ b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/Payload.java @@ -37,15 +37,6 @@ public class Payload extends BufferSizeTracker { } } - @Override - protected void reset() { - synchronized (accessLock) { - super.reset(); - recordsBuffer.clear(); - recordGuidsBuffer.clear(); - } - } - protected ArrayList getRecordsBuffer() { synchronized (accessLock) { return new ArrayList<>(recordsBuffer); @@ -63,4 +54,8 @@ public class Payload extends BufferSizeTracker { return recordsBuffer.isEmpty(); } } + + Payload nextPayload() { + return new Payload(accessLock, maxBytes, maxRecords); + } } \ No newline at end of file diff --git a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/PayloadDispatcher.java b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/PayloadDispatcher.java new file mode 100644 index 000000000000..3382f5142b5c --- /dev/null +++ b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/PayloadDispatcher.java @@ -0,0 +1,184 @@ +/* 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/. */ + +package org.mozilla.gecko.sync.repositories.uploaders; + +import android.support.annotation.Nullable; +import android.support.annotation.VisibleForTesting; + +import org.mozilla.gecko.background.common.log.Logger; +import org.mozilla.gecko.sync.Server11RecordPostFailedException; +import org.mozilla.gecko.sync.net.SyncResponse; +import org.mozilla.gecko.sync.net.SyncStorageResponse; + +import java.util.ArrayList; +import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicLong; + +/** + * Dispatches payload runnables and handles their results. + * + * All of the methods, except for `queue` and `finalizeQueue`, will be called from the thread(s) + * running sequentially on the SingleThreadExecutor `executor`. + */ +class PayloadDispatcher { + private static final String LOG_TAG = "PayloadDispatcher"; + + // All payload runnables share the same whiteboard. + // It's accessed directly by the runnables; tests also make use of this direct access. + volatile BatchMeta batchWhiteboard; + private final AtomicLong uploadTimestamp = new AtomicLong(0); + + // Accessed from different threads sequentially running on the 'executor'. + private volatile boolean recordUploadFailed = false; + + private final Executor executor; + private final BatchingUploader uploader; + + PayloadDispatcher(Executor executor, BatchingUploader uploader, @Nullable Long initialLastModified) { + // Initially we don't know if we're in a batching mode. + this.batchWhiteboard = new BatchMeta(initialLastModified, null); + this.uploader = uploader; + this.executor = executor; + } + + void queue( + final ArrayList outgoing, + final ArrayList outgoingGuids, + final long byteCount, + final boolean isCommit, final boolean isLastPayload) { + + // Note that `executor` is expected to be a SingleThreadExecutor. + executor.execute(new BatchContextRunnable(isCommit) { + @Override + public void run() { + new RecordUploadRunnable( + new BatchingAtomicUploaderMayUploadProvider(), + uploader.collectionUri, + batchWhiteboard.getToken(), + new PayloadUploadDelegate( + uploader.getRepositorySession().getServerRepository().getAuthHeaderProvider(), + PayloadDispatcher.this, + outgoingGuids, + isCommit, + isLastPayload + ), + outgoing, + byteCount, + isCommit + ).run(); + } + }); + } + + void setInBatchingMode(boolean inBatchingMode) { + batchWhiteboard.setInBatchingMode(inBatchingMode); + uploader.setUnlimitedMode(!inBatchingMode); + } + + /** + * We've been told by our upload delegate that a payload succeeded. + * Depending on the type of payload and batch mode status, inform our delegate of progress. + * + * @param response success response to our commit post + * @param guids list of successfully posted record guids + * @param isCommit was this a commit upload? + * @param isLastPayload was this a very last payload we'll upload? + */ + void payloadSucceeded(final SyncStorageResponse response, final String[] guids, final boolean isCommit, final boolean isLastPayload) { + // Sanity check. + if (batchWhiteboard.getInBatchingMode() == null) { + throw new IllegalStateException("Can't process payload success until we know if we're in a batching mode"); + } + + // We consider records to have been committed if we're not in a batching mode or this was a commit. + // If records have been committed, notify our store delegate. + if (!batchWhiteboard.getInBatchingMode() || isCommit) { + for (String guid : guids) { + uploader.sessionStoreDelegate.onRecordStoreSucceeded(guid); + } + } + + // If this was our very last commit, we're done storing records. + // Get Last-Modified timestamp from the response, and pass it upstream. + if (isLastPayload) { + finished(response.normalizedTimestampForHeader(SyncResponse.X_LAST_MODIFIED)); + } + } + + void lastPayloadFailed() { + uploader.finished(uploadTimestamp); + } + + private void finished(long lastModifiedTimestamp) { + bumpTimestampTo(uploadTimestamp, lastModifiedTimestamp); + uploader.finished(uploadTimestamp); + } + + void finalizeQueue(final boolean needToCommit, final Runnable finalRunnable) { + executor.execute(new NonPayloadContextRunnable() { + @Override + public void run() { + // Must be called after last payload upload finishes. + if (needToCommit && Boolean.TRUE.equals(batchWhiteboard.getInBatchingMode())) { + finalRunnable.run(); + + // Otherwise, we're done. + } else { + uploader.finished(uploadTimestamp); + } + } + }); + } + + void recordFailed(final String recordGuid) { + recordFailed(new Server11RecordPostFailedException(), recordGuid); + } + + void recordFailed(final Exception e, final String recordGuid) { + Logger.debug(LOG_TAG, "Record store failed for guid " + recordGuid + " with exception: " + e.toString()); + recordUploadFailed = true; + uploader.sessionStoreDelegate.onRecordStoreFailed(e, recordGuid); + } + + void prepareForNextBatch() { + batchWhiteboard = batchWhiteboard.nextBatchMeta(); + } + + private static void bumpTimestampTo(final AtomicLong current, long newValue) { + while (true) { + long existing = current.get(); + if (existing > newValue) { + return; + } + if (current.compareAndSet(existing, newValue)) { + return; + } + } + } + + /** + * Allows tests to easily peek into the flow of upload tasks. + */ + @VisibleForTesting + abstract static class BatchContextRunnable implements Runnable { + boolean isCommit; + + BatchContextRunnable(boolean isCommit) { + this.isCommit = isCommit; + } + } + + /** + * Allows tests to tell apart non-payload runnables going through the executor. + */ + @VisibleForTesting + abstract static class NonPayloadContextRunnable implements Runnable {} + + private class BatchingAtomicUploaderMayUploadProvider implements MayUploadProvider { + public boolean mayUpload() { + return !recordUploadFailed; + } + } +} diff --git a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/PayloadUploadDelegate.java b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/PayloadUploadDelegate.java index e8bbb7df6597..8bfaf51bfef6 100644 --- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/PayloadUploadDelegate.java +++ b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/PayloadUploadDelegate.java @@ -18,18 +18,20 @@ import org.mozilla.gecko.sync.net.SyncStorageResponse; import java.util.ArrayList; -public class PayloadUploadDelegate implements SyncStorageRequestDelegate { +class PayloadUploadDelegate implements SyncStorageRequestDelegate { private static final String LOG_TAG = "PayloadUploadDelegate"; private static final String KEY_BATCH = "batch"; - private final BatchingUploader uploader; + private final AuthHeaderProvider headerProvider; + private final PayloadDispatcher dispatcher; private ArrayList postedRecordGuids; private final boolean isCommit; private final boolean isLastPayload; - public PayloadUploadDelegate(BatchingUploader uploader, ArrayList postedRecordGuids, boolean isCommit, boolean isLastPayload) { - this.uploader = uploader; + PayloadUploadDelegate(AuthHeaderProvider headerProvider, PayloadDispatcher dispatcher, ArrayList postedRecordGuids, boolean isCommit, boolean isLastPayload) { + this.headerProvider = headerProvider; + this.dispatcher = dispatcher; this.postedRecordGuids = postedRecordGuids; this.isCommit = isCommit; this.isLastPayload = isLastPayload; @@ -37,16 +39,17 @@ public class PayloadUploadDelegate implements SyncStorageRequestDelegate { @Override public AuthHeaderProvider getAuthHeaderProvider() { - return uploader.getRepositorySession().getServerRepository().getAuthHeaderProvider(); + return headerProvider; } @Override public String ifUnmodifiedSince() { - final Long lastModified = uploader.getCurrentBatch().getLastModified(); + final Long lastModified = dispatcher.batchWhiteboard.getLastModified(); if (lastModified == null) { return null; + } else { + return Utils.millisecondsToDecimalSecondsString(lastModified); } - return Utils.millisecondsToDecimalSecondsString(lastModified); } @Override @@ -80,8 +83,8 @@ public class PayloadUploadDelegate implements SyncStorageRequestDelegate { // If we got a 200, it could be either a non-batching result, or a batch commit. // - if we're in a batching mode, we expect this to be a commit. // If we got a 202, we expect there to be a token present in the response - if (response.getStatusCode() == 200 && uploader.getCurrentBatch().getToken() != null) { - if (uploader.getInBatchingMode() && !isCommit) { + if (response.getStatusCode() == 200 && dispatcher.batchWhiteboard.getToken() != null) { + if (dispatcher.batchWhiteboard.getInBatchingMode() && !isCommit) { handleRequestError( new IllegalStateException("Got 200 OK in batching mode, but this was not a commit payload") ); @@ -98,14 +101,14 @@ public class PayloadUploadDelegate implements SyncStorageRequestDelegate { // With sanity checks out of the way, can now safely say if we're in a batching mode or not. // We only do this once per session. - if (uploader.getInBatchingMode() == null) { - uploader.setInBatchingMode(body.containsKey(KEY_BATCH)); + if (dispatcher.batchWhiteboard.getInBatchingMode() == null) { + dispatcher.setInBatchingMode(body.containsKey(KEY_BATCH)); } // Tell current batch about the token we've received. // Throws if token changed after being set once, or if we got a non-null token after a commit. try { - uploader.getCurrentBatch().setToken(body.getString(KEY_BATCH), isCommit); + dispatcher.batchWhiteboard.setToken(body.getString(KEY_BATCH), isCommit); } catch (BatchingUploader.BatchingUploaderException e) { handleRequestError(e); return; @@ -113,9 +116,14 @@ public class PayloadUploadDelegate implements SyncStorageRequestDelegate { // Will throw if Last-Modified changed when it shouldn't have. try { - uploader.setLastModified( + // In non-batching mode, every time we receive a Last-Modified timestamp, we expect it + // to change since records are "committed" (become visible to other clients) on every + // payload. + // In batching mode, we only expect Last-Modified to change when we commit a batch. + dispatcher.batchWhiteboard.setLastModified( response.normalizedTimestampForHeader(SyncResponse.X_LAST_MODIFIED), - isCommit); + isCommit || !dispatcher.batchWhiteboard.getInBatchingMode() + ); } catch (BatchingUploader.BatchingUploaderException e) { handleRequestError(e); return; @@ -134,7 +142,7 @@ public class PayloadUploadDelegate implements SyncStorageRequestDelegate { Logger.trace(LOG_TAG, "Successful records: " + success.toString()); for (Object o : success) { try { - uploader.recordSucceeded((String) o); + dispatcher.batchWhiteboard.recordSucceeded((String) o); } catch (ClassCastException e) { Logger.error(LOG_TAG, "Got exception parsing POST success guid.", e); // Not much to be done. @@ -155,14 +163,23 @@ public class PayloadUploadDelegate implements SyncStorageRequestDelegate { if (failed != null && !failed.object.isEmpty()) { Logger.debug(LOG_TAG, "Failed records: " + failed.object.toString()); for (String guid : failed.keySet()) { - uploader.recordFailed(guid); + dispatcher.recordFailed(guid); } } // GC failed = null; // And we're done! Let uploader finish up. - uploader.payloadSucceeded(response, isCommit, isLastPayload); + dispatcher.payloadSucceeded( + response, + dispatcher.batchWhiteboard.getSuccessRecordGuids(), + isCommit, + isLastPayload + ); + + if (isCommit && !isLastPayload) { + dispatcher.prepareForNextBatch(); + } } @Override @@ -173,13 +190,13 @@ public class PayloadUploadDelegate implements SyncStorageRequestDelegate { @Override public void handleRequestError(Exception e) { for (String guid : postedRecordGuids) { - uploader.recordFailed(e, guid); + dispatcher.recordFailed(e, guid); } // GC postedRecordGuids = null; if (isLastPayload) { - uploader.lastPayloadFailed(); + dispatcher.lastPayloadFailed(); } } } \ No newline at end of file diff --git a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/RecordUploadRunnable.java b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/RecordUploadRunnable.java index ce2955102a88..1fdecf7ceaa4 100644 --- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/RecordUploadRunnable.java +++ b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/RecordUploadRunnable.java @@ -5,10 +5,12 @@ package org.mozilla.gecko.sync.repositories.uploaders; import android.net.Uri; +import android.support.annotation.Nullable; import android.support.annotation.VisibleForTesting; import org.mozilla.gecko.background.common.log.Logger; import org.mozilla.gecko.sync.Server11PreviousPostFailedException; +import org.mozilla.gecko.sync.Utils; import org.mozilla.gecko.sync.net.SyncStorageRequest; import org.mozilla.gecko.sync.net.SyncStorageRequestDelegate; @@ -45,11 +47,11 @@ public class RecordUploadRunnable implements Runnable { @VisibleForTesting public final boolean isCommit; private final Uri collectionUri; - private final BatchMeta batchMeta; + private final String batchToken; public RecordUploadRunnable(MayUploadProvider mayUploadProvider, Uri collectionUri, - BatchMeta batchMeta, + String batchToken, SyncStorageRequestDelegate uploadDelegate, ArrayList outgoing, long byteCount, @@ -58,7 +60,7 @@ public class RecordUploadRunnable implements Runnable { this.uploadDelegate = uploadDelegate; this.outgoing = outgoing; this.byteCount = byteCount; - this.batchMeta = batchMeta; + this.batchToken = batchToken; this.collectionUri = collectionUri; this.isCommit = isCommit; } @@ -144,7 +146,7 @@ public class RecordUploadRunnable implements Runnable { // Fortunately, BaseResource is currently synchronous. // If that ever changes, you'll need to block here. - final URI postURI = buildPostURI(isCommit, batchMeta, collectionUri); + final URI postURI = buildPostURI(isCommit, batchToken, collectionUri); final SyncStorageRequest request = new SyncStorageRequest(postURI); request.delegate = uploadDelegate; @@ -153,9 +155,8 @@ public class RecordUploadRunnable implements Runnable { } @VisibleForTesting - public static URI buildPostURI(boolean isCommit, BatchMeta batchMeta, Uri collectionUri) { + public static URI buildPostURI(boolean isCommit, @Nullable String batchToken, Uri collectionUri) { final Uri.Builder uriBuilder = collectionUri.buildUpon(); - final String batchToken = batchMeta.getToken(); if (batchToken != null) { uriBuilder.appendQueryParameter(QUERY_PARAM_BATCH, batchToken); diff --git a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/UploaderMeta.java b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/UploaderMeta.java new file mode 100644 index 000000000000..3df61c506012 --- /dev/null +++ b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/repositories/uploaders/UploaderMeta.java @@ -0,0 +1,58 @@ +/* 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/. */ + +package org.mozilla.gecko.sync.repositories.uploaders; + +import android.support.annotation.CheckResult; +import android.support.annotation.NonNull; + + +public class UploaderMeta extends BufferSizeTracker { + // Will be written and read by different threads. + /* @GuardedBy("accessLock") */ private volatile boolean isUnlimited = false; + + /* @GuardedBy("accessLock") */ private boolean needsCommit = false; + + public UploaderMeta(@NonNull Object payloadLock, long maxBytes, long maxRecords) { + super(payloadLock, maxBytes, maxRecords); + } + + protected void setIsUnlimited(boolean isUnlimited) { + synchronized (accessLock) { + this.isUnlimited = isUnlimited; + } + } + + @Override + protected boolean canFit(long recordDeltaByteCount) { + synchronized (accessLock) { + return isUnlimited || super.canFit(recordDeltaByteCount); + } + } + + @Override + @CheckResult + protected boolean addAndEstimateIfFull(long recordDeltaByteCount) { + synchronized (accessLock) { + needsCommit = true; + boolean isFull = super.addAndEstimateIfFull(recordDeltaByteCount); + return !isUnlimited && isFull; + } + } + + protected boolean needToCommit() { + synchronized (accessLock) { + return needsCommit; + } + } + + @Override + protected boolean canFitRecordByteDelta(long byteDelta, long recordCount, long byteCount) { + return isUnlimited || super.canFitRecordByteDelta(byteDelta, recordCount, byteCount); + } + + UploaderMeta nextUploaderMeta() { + return new UploaderMeta(accessLock, maxBytes, maxRecords); + } +} \ No newline at end of file diff --git a/mobile/android/tests/background/junit4/src/org/mozilla/android/sync/test/TestServer11RepositorySession.java b/mobile/android/tests/background/junit4/src/org/mozilla/android/sync/test/TestServer11RepositorySession.java index 96a366c2d90f..ea045309cef9 100644 --- a/mobile/android/tests/background/junit4/src/org/mozilla/android/sync/test/TestServer11RepositorySession.java +++ b/mobile/android/tests/background/junit4/src/org/mozilla/android/sync/test/TestServer11RepositorySession.java @@ -72,7 +72,12 @@ public class TestServer11RepositorySession { static final String SYNC_KEY = "eh7ppnb82iwr5kt3z3uyi5vr44"; public final AuthHeaderProvider authHeaderProvider = new BasicAuthHeaderProvider(TEST_USERNAME, TEST_PASSWORD); - protected final InfoCollections infoCollections = new InfoCollections(); + protected final InfoCollections infoCollections = new InfoCollections() { + @Override + public Long getTimestamp(String collection) { + return 0L; + } + }; protected final InfoConfiguration infoConfiguration = new InfoConfiguration(); // Few-second timeout so that our longer operations don't time out and cause spurious error-handling results. diff --git a/mobile/android/tests/background/junit4/src/org/mozilla/gecko/sync/repositories/uploaders/BatchMetaTest.java b/mobile/android/tests/background/junit4/src/org/mozilla/gecko/sync/repositories/uploaders/BatchMetaTest.java index 2e136c1176a9..2e2dc986def4 100644 --- a/mobile/android/tests/background/junit4/src/org/mozilla/gecko/sync/repositories/uploaders/BatchMetaTest.java +++ b/mobile/android/tests/background/junit4/src/org/mozilla/gecko/sync/repositories/uploaders/BatchMetaTest.java @@ -1,6 +1,3 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - package org.mozilla.gecko.sync.repositories.uploaders; import org.junit.Before; @@ -13,92 +10,80 @@ import static org.junit.Assert.*; @RunWith(TestRunner.class) public class BatchMetaTest { private BatchMeta batchMeta; - private long byteLimit = 1024; - private long recordLimit = 5; - private Object lock = new Object(); - private Long collectionLastModified = 123L; @Before public void setUp() throws Exception { - batchMeta = new BatchMeta(lock, byteLimit, recordLimit, collectionLastModified); - } - - @Test - public void testConstructor() { - assertEquals(batchMeta.collectionLastModified, collectionLastModified); - - BatchMeta otherBatchMeta = new BatchMeta(lock, byteLimit, recordLimit, null); - assertNull(otherBatchMeta.collectionLastModified); + batchMeta = new BatchMeta(null, null); } @Test public void testGetLastModified() { - // Defaults to collection L-M - assertEquals(batchMeta.getLastModified(), Long.valueOf(123L)); + assertNull(batchMeta.getLastModified()); try { batchMeta.setLastModified(333L, true); - } catch (BatchingUploader.LastModifiedChangedUnexpectedly e) { - } catch (BatchingUploader.LastModifiedDidNotChange e) {} + } catch (BatchingUploader.LastModifiedDidNotChange | BatchingUploader.LastModifiedChangedUnexpectedly e) { + } - assertEquals(batchMeta.getLastModified(), Long.valueOf(333L)); + assertEquals(Long.valueOf(333L), batchMeta.getLastModified()); } @Test public void testSetLastModified() { - assertEquals(batchMeta.getLastModified(), collectionLastModified); + BatchingUploaderTest.TestRunnableWithTarget tests = new BatchingUploaderTest.TestRunnableWithTarget() { + @Override + void tests() { + try { + batchMeta.setLastModified(123L, true); + assertEquals(Long.valueOf(123L), batchMeta.getLastModified()); + } catch (BatchingUploader.LastModifiedDidNotChange | BatchingUploader.LastModifiedChangedUnexpectedly e) { + fail("Should not check for modifications on first L-M set"); + } - try { - batchMeta.setLastModified(123L, true); - assertEquals(batchMeta.getLastModified(), Long.valueOf(123L)); - } catch (BatchingUploader.LastModifiedChangedUnexpectedly e) { - fail("Should not check for modifications on first L-M set"); - } catch (BatchingUploader.LastModifiedDidNotChange e) { - fail("Should not check for modifications on first L-M set"); - } + try { + batchMeta.setLastModified(123L, false); + assertEquals(Long.valueOf(123L), batchMeta.getLastModified()); + } catch (BatchingUploader.LastModifiedDidNotChange | BatchingUploader.LastModifiedChangedUnexpectedly e) { + fail("Should not check for modifications on first L-M set"); + } - // Now the same, but passing in 'false' for "expecting to change". - batchMeta.reset(); - assertEquals(batchMeta.getLastModified(), collectionLastModified); + // Test that we can't modify L-M when we're not expecting to + try { + batchMeta.setLastModified(333L, false); + } catch (BatchingUploader.LastModifiedChangedUnexpectedly e) { + assertTrue("Must throw when L-M changes unexpectedly", true); + } catch (BatchingUploader.LastModifiedDidNotChange e) { + fail("Not expecting did-not-change throw"); + } + assertEquals(Long.valueOf(123L), batchMeta.getLastModified()); - try { - batchMeta.setLastModified(123L, false); - assertEquals(batchMeta.getLastModified(), Long.valueOf(123L)); - } catch (BatchingUploader.LastModifiedChangedUnexpectedly e) { - fail("Should not check for modifications on first L-M set"); - } catch (BatchingUploader.LastModifiedDidNotChange e) { - fail("Should not check for modifications on first L-M set"); - } + // Test that we can modify L-M when we're expecting to + try { + batchMeta.setLastModified(333L, true); + } catch (BatchingUploader.LastModifiedChangedUnexpectedly e) { + fail("Not expecting changed-unexpectedly throw"); + } catch (BatchingUploader.LastModifiedDidNotChange e) { + fail("Not expecting did-not-change throw"); + } + assertEquals(Long.valueOf(333L), batchMeta.getLastModified()); - // Test that we can't modify L-M when we're not expecting to - try { - batchMeta.setLastModified(333L, false); - } catch (BatchingUploader.LastModifiedChangedUnexpectedly e) { - assertTrue("Must throw when L-M changes unexpectedly", true); - } catch (BatchingUploader.LastModifiedDidNotChange e) { - fail("Not expecting did-not-change throw"); - } - assertEquals(batchMeta.getLastModified(), Long.valueOf(123L)); + // Test that we catch L-M modifications that expect to change but actually don't + try { + batchMeta.setLastModified(333L, true); + } catch (BatchingUploader.LastModifiedChangedUnexpectedly e) { + fail("Not expecting changed-unexpectedly throw"); + } catch (BatchingUploader.LastModifiedDidNotChange e) { + assertTrue("Expected-to-change-but-did-not-change didn't throw", true); + } + assertEquals(Long.valueOf(333), batchMeta.getLastModified()); + } + }; - // Test that we can modify L-M when we're expecting to - try { - batchMeta.setLastModified(333L, true); - } catch (BatchingUploader.LastModifiedChangedUnexpectedly e) { - fail("Not expecting changed-unexpectedly throw"); - } catch (BatchingUploader.LastModifiedDidNotChange e) { - fail("Not expecting did-not-change throw"); - } - assertEquals(batchMeta.getLastModified(), Long.valueOf(333L)); - - // Test that we catch L-M modifications that expect to change but actually don't - try { - batchMeta.setLastModified(333L, true); - } catch (BatchingUploader.LastModifiedChangedUnexpectedly e) { - fail("Not expecting changed-unexpectedly throw"); - } catch (BatchingUploader.LastModifiedDidNotChange e) { - assertTrue("Expected-to-change-but-did-not-change didn't throw", true); - } - assertEquals(batchMeta.getLastModified(), Long.valueOf(333)); + tests + .setTarget(batchMeta) + .run() + .setTarget(new BatchMeta(123L, null)) + .run(); } @Test @@ -136,12 +121,12 @@ public class BatchMetaTest { @Test public void testRecordSucceeded() { - assertTrue(batchMeta.getSuccessRecordGuids().isEmpty()); + assertEquals(0, batchMeta.getSuccessRecordGuids().length); batchMeta.recordSucceeded("guid1"); - assertTrue(batchMeta.getSuccessRecordGuids().size() == 1); - assertTrue(batchMeta.getSuccessRecordGuids().contains("guid1")); + assertEquals(1, batchMeta.getSuccessRecordGuids().length); + assertEquals("guid1", batchMeta.getSuccessRecordGuids()[0]); try { batchMeta.recordSucceeded(null); @@ -150,133 +135,4 @@ public class BatchMetaTest { assertTrue("Should not be able to 'succeed' a null guid", true); } } - - @Test - public void testByteLimits() { - assertTrue(batchMeta.canFit(0)); - - // Should just fit - assertTrue(batchMeta.canFit(byteLimit - BatchingUploader.PER_PAYLOAD_OVERHEAD_BYTE_COUNT)); - - // Can't fit a record due to payload overhead. - assertFalse(batchMeta.canFit(byteLimit)); - - assertFalse(batchMeta.canFit(byteLimit + BatchingUploader.PER_PAYLOAD_OVERHEAD_BYTE_COUNT)); - assertFalse(batchMeta.canFit(byteLimit * 1000)); - - long recordDelta = byteLimit / 2; - assertFalse(batchMeta.addAndEstimateIfFull(recordDelta)); - - // Record delta shouldn't fit due to payload overhead. - assertFalse(batchMeta.canFit(recordDelta)); - } - - @Test - public void testCountLimits() { - // Our record limit is 5, let's add 4. - assertFalse(batchMeta.addAndEstimateIfFull(1)); - assertFalse(batchMeta.addAndEstimateIfFull(1)); - assertFalse(batchMeta.addAndEstimateIfFull(1)); - assertFalse(batchMeta.addAndEstimateIfFull(1)); - - // 5th record still fits in - assertTrue(batchMeta.canFit(1)); - - // Add the 5th record - assertTrue(batchMeta.addAndEstimateIfFull(1)); - - // 6th record won't fit - assertFalse(batchMeta.canFit(1)); - } - - @Test - public void testNeedCommit() { - assertFalse(batchMeta.needToCommit()); - - assertFalse(batchMeta.addAndEstimateIfFull(1)); - - assertTrue(batchMeta.needToCommit()); - - assertFalse(batchMeta.addAndEstimateIfFull(1)); - assertFalse(batchMeta.addAndEstimateIfFull(1)); - assertFalse(batchMeta.addAndEstimateIfFull(1)); - - assertTrue(batchMeta.needToCommit()); - - batchMeta.reset(); - - assertFalse(batchMeta.needToCommit()); - } - - @Test - public void testAdd() { - // Ensure we account for payload overhead twice when the batch is empty. - // Payload overhead is either RECORDS_START or RECORDS_END, and for an empty payload - // we need both. - assertTrue(batchMeta.getByteCount() == 2 * BatchingUploader.PER_PAYLOAD_OVERHEAD_BYTE_COUNT); - assertTrue(batchMeta.getRecordCount() == 0); - - assertFalse(batchMeta.addAndEstimateIfFull(1)); - - assertTrue(batchMeta.getByteCount() == (1 + BatchingUploader.PER_PAYLOAD_OVERHEAD_BYTE_COUNT)); - assertTrue(batchMeta.getRecordCount() == 1); - - assertFalse(batchMeta.addAndEstimateIfFull(1)); - assertFalse(batchMeta.addAndEstimateIfFull(1)); - assertFalse(batchMeta.addAndEstimateIfFull(1)); - - assertTrue(batchMeta.getByteCount() == (4 + BatchingUploader.PER_PAYLOAD_OVERHEAD_BYTE_COUNT)); - assertTrue(batchMeta.getRecordCount() == 4); - - assertTrue(batchMeta.addAndEstimateIfFull(1)); - - try { - assertTrue(batchMeta.addAndEstimateIfFull(1)); - fail("BatchMeta should not let us insert records that won't fit"); - } catch (IllegalStateException e) { - assertTrue(true); - } - } - - @Test - public void testReset() { - assertTrue(batchMeta.getByteCount() == 2 * BatchingUploader.PER_PAYLOAD_OVERHEAD_BYTE_COUNT); - assertTrue(batchMeta.getRecordCount() == 0); - assertTrue(batchMeta.getSuccessRecordGuids().isEmpty()); - - // Shouldn't throw even if already empty - batchMeta.reset(); - assertTrue(batchMeta.getByteCount() == 2 * BatchingUploader.PER_PAYLOAD_OVERHEAD_BYTE_COUNT); - assertTrue(batchMeta.getRecordCount() == 0); - assertTrue(batchMeta.getSuccessRecordGuids().isEmpty()); - - assertFalse(batchMeta.addAndEstimateIfFull(1)); - batchMeta.recordSucceeded("guid1"); - try { - batchMeta.setToken("MTIzNA", false); - } catch (BatchingUploader.TokenModifiedException e) {} - try { - batchMeta.setLastModified(333L, true); - } catch (BatchingUploader.LastModifiedChangedUnexpectedly e) { - } catch (BatchingUploader.LastModifiedDidNotChange e) {} - assertEquals(Long.valueOf(333L), batchMeta.getLastModified()); - assertEquals("MTIzNA", batchMeta.getToken()); - assertTrue(batchMeta.getSuccessRecordGuids().size() == 1); - - batchMeta.reset(); - - // Counts must be reset - assertTrue(batchMeta.getByteCount() == 2 * BatchingUploader.PER_PAYLOAD_OVERHEAD_BYTE_COUNT); - assertTrue(batchMeta.getRecordCount() == 0); - assertTrue(batchMeta.getSuccessRecordGuids().isEmpty()); - - // Collection L-M shouldn't change - assertEquals(batchMeta.collectionLastModified, collectionLastModified); - - // Token must be reset - assertNull(batchMeta.getToken()); - - // L-M must be reverted to collection L-M - assertEquals(batchMeta.getLastModified(), collectionLastModified); - } } \ No newline at end of file diff --git a/mobile/android/tests/background/junit4/src/org/mozilla/gecko/sync/repositories/uploaders/BatchingUploaderTest.java b/mobile/android/tests/background/junit4/src/org/mozilla/gecko/sync/repositories/uploaders/BatchingUploaderTest.java index 5ce94b222ad2..8b07ad1f9b9c 100644 --- a/mobile/android/tests/background/junit4/src/org/mozilla/gecko/sync/repositories/uploaders/BatchingUploaderTest.java +++ b/mobile/android/tests/background/junit4/src/org/mozilla/gecko/sync/repositories/uploaders/BatchingUploaderTest.java @@ -28,22 +28,28 @@ import java.util.concurrent.ExecutorService; @RunWith(TestRunner.class) public class BatchingUploaderTest { class MockExecutorService implements Executor { - public int totalPayloads = 0; - public int commitPayloads = 0; + int totalPayloads = 0; + int commitPayloads = 0; @Override public void execute(@NonNull Runnable command) { + if (command instanceof PayloadDispatcher.NonPayloadContextRunnable) { + command.run(); + return; + } + ++totalPayloads; - if (((RecordUploadRunnable) command).isCommit) { + if (((PayloadDispatcher.BatchContextRunnable) command).isCommit) { ++commitPayloads; } + command.run(); } } class MockStoreDelegate implements RepositorySessionStoreDelegate { - public int storeFailed = 0; - public int storeSucceeded = 0; - public int storeCompleted = 0; + int storeFailed = 0; + int storeSucceeded = 0; + int storeCompleted = 0; @Override public void onRecordStoreFailed(Exception ex, String recordGuid) { @@ -76,62 +82,76 @@ public class BatchingUploaderTest { } @Test - public void testProcessEvenPayloadBatch() { - BatchingUploader uploader = makeConstrainedUploader(2, 4); + public void testProcessEvenPayloadBatch() throws Exception { + TestRunnableWithTarget tests = new TestRunnableWithTarget() { + @Override + public void tests() { + MockRecord record = new MockRecord(Utils.generateGuid(), null, 0, false); + // 1st + target.process(record); + assertEquals(0, ((MockExecutorService) workQueue).totalPayloads); + assertEquals(0, ((MockExecutorService) workQueue).commitPayloads); + // 2nd -> payload full + target.process(record); + assertEquals(1, ((MockExecutorService) workQueue).totalPayloads); + assertEquals(0, ((MockExecutorService) workQueue).commitPayloads); + // 3rd + target.process(record); + assertEquals(1, ((MockExecutorService) workQueue).totalPayloads); + assertEquals(0, ((MockExecutorService) workQueue).commitPayloads); + // 4th -> batch & payload full + target.process(record); + assertEquals(2, ((MockExecutorService) workQueue).totalPayloads); + assertEquals(1, ((MockExecutorService) workQueue).commitPayloads); + // 5th + target.process(record); + assertEquals(2, ((MockExecutorService) workQueue).totalPayloads); + assertEquals(1, ((MockExecutorService) workQueue).commitPayloads); + // 6th -> payload full + target.process(record); + assertEquals(3, ((MockExecutorService) workQueue).totalPayloads); + assertEquals(1, ((MockExecutorService) workQueue).commitPayloads); + // 7th + target.process(record); + assertEquals(3, ((MockExecutorService) workQueue).totalPayloads); + assertEquals(1, ((MockExecutorService) workQueue).commitPayloads); + // 8th -> batch & payload full + target.process(record); + assertEquals(4, ((MockExecutorService) workQueue).totalPayloads); + assertEquals(2, ((MockExecutorService) workQueue).commitPayloads); + // 9th + target.process(record); + assertEquals(4, ((MockExecutorService) workQueue).totalPayloads); + assertEquals(2, ((MockExecutorService) workQueue).commitPayloads); + // 10th -> payload full + target.process(record); + assertEquals(5, ((MockExecutorService) workQueue).totalPayloads); + assertEquals(2, ((MockExecutorService) workQueue).commitPayloads); + // 11th + target.process(record); + assertEquals(5, ((MockExecutorService) workQueue).totalPayloads); + assertEquals(2, ((MockExecutorService) workQueue).commitPayloads); + // 12th -> batch & payload full + target.process(record); + assertEquals(6, ((MockExecutorService) workQueue).totalPayloads); + assertEquals(3, ((MockExecutorService) workQueue).commitPayloads); + // 13th + target.process(record); + assertEquals(6, ((MockExecutorService) workQueue).totalPayloads); + assertEquals(3, ((MockExecutorService) workQueue).commitPayloads); + } + }; - MockRecord record = new MockRecord(Utils.generateGuid(), null, 0, false); - // 1st - uploader.process(record); - assertEquals(0, ((MockExecutorService) workQueue).totalPayloads); - assertEquals(0, ((MockExecutorService) workQueue).commitPayloads); - // 2nd -> payload full - uploader.process(record); - assertEquals(1, ((MockExecutorService) workQueue).totalPayloads); - assertEquals(0, ((MockExecutorService) workQueue).commitPayloads); - // 3rd - uploader.process(record); - assertEquals(1, ((MockExecutorService) workQueue).totalPayloads); - assertEquals(0, ((MockExecutorService) workQueue).commitPayloads); - // 4th -> batch & payload full - uploader.process(record); - assertEquals(2, ((MockExecutorService) workQueue).totalPayloads); - assertEquals(1, ((MockExecutorService) workQueue).commitPayloads); - // 5th - uploader.process(record); - assertEquals(2, ((MockExecutorService) workQueue).totalPayloads); - assertEquals(1, ((MockExecutorService) workQueue).commitPayloads); - // 6th -> payload full - uploader.process(record); - assertEquals(3, ((MockExecutorService) workQueue).totalPayloads); - assertEquals(1, ((MockExecutorService) workQueue).commitPayloads); - // 7th - uploader.process(record); - assertEquals(3, ((MockExecutorService) workQueue).totalPayloads); - assertEquals(1, ((MockExecutorService) workQueue).commitPayloads); - // 8th -> batch & payload full - uploader.process(record); - assertEquals(4, ((MockExecutorService) workQueue).totalPayloads); - assertEquals(2, ((MockExecutorService) workQueue).commitPayloads); - // 9th - uploader.process(record); - assertEquals(4, ((MockExecutorService) workQueue).totalPayloads); - assertEquals(2, ((MockExecutorService) workQueue).commitPayloads); - // 10th -> payload full - uploader.process(record); - assertEquals(5, ((MockExecutorService) workQueue).totalPayloads); - assertEquals(2, ((MockExecutorService) workQueue).commitPayloads); - // 11th - uploader.process(record); - assertEquals(5, ((MockExecutorService) workQueue).totalPayloads); - assertEquals(2, ((MockExecutorService) workQueue).commitPayloads); - // 12th -> batch & payload full - uploader.process(record); - assertEquals(6, ((MockExecutorService) workQueue).totalPayloads); - assertEquals(3, ((MockExecutorService) workQueue).commitPayloads); - // 13th - uploader.process(record); - assertEquals(6, ((MockExecutorService) workQueue).totalPayloads); - assertEquals(3, ((MockExecutorService) workQueue).commitPayloads); + tests + .setTarget(makeConstrainedUploader(2, 4)) + .run(); + + // clear up between test runs + setUp(); + + tests + .setTarget(makeConstrainedUploader(2, 4, true)) + .run(); } @Test @@ -214,7 +234,7 @@ public class BatchingUploaderTest { // And now we tell uploader that batching isn't supported. // It shouldn't bother with batches from now on, just payloads. - uploader.setInBatchingMode(false); + uploader.setUnlimitedMode(true); // 6th uploader.process(record); @@ -294,7 +314,7 @@ public class BatchingUploaderTest { BatchingUploader uploader = makeConstrainedUploader(2, 4); final Random random = new Random(); - uploader.setInBatchingMode(false); + uploader.setUnlimitedMode(true); for (int i = 0; i < 15000; i++) { uploader.process(new MockRecord(Utils.generateGuid(), null, 0, false, random.nextInt(15000))); } @@ -310,7 +330,7 @@ public class BatchingUploaderTest { final int delay = random.nextInt(20); for (int i = 0; i < 15000; i++) { if (delay == i) { - uploader.setInBatchingMode(false); + uploader.setUnlimitedMode(true); } uploader.process(new MockRecord(Utils.generateGuid(), null, 0, false, random.nextInt(15000))); } @@ -325,8 +345,8 @@ public class BatchingUploaderTest { MockRecord record = new MockRecord(Utils.generateGuid(), null, 0, false); uploader.process(record); uploader.process(record); - uploader.setInBatchingMode(true); - uploader.commitIfNecessaryAfterLastPayload(); + uploader.payloadDispatcher.setInBatchingMode(true); + uploader.noMoreRecordsToUpload(); // One will be a payload post, the other one is batch commit (empty payload) assertEquals(2, ((MockExecutorService) workQueue).totalPayloads); assertEquals(1, ((MockExecutorService) workQueue).commitPayloads); @@ -342,7 +362,7 @@ public class BatchingUploaderTest { uploader.process(record); uploader.process(record); uploader.process(record); - uploader.commitIfNecessaryAfterLastPayload(); + uploader.noMoreRecordsToUpload(); // One will be a payload post, the other one is batch commit (one record payload) assertEquals(2, ((MockExecutorService) workQueue).totalPayloads); assertEquals(1, ((MockExecutorService) workQueue).commitPayloads); @@ -352,7 +372,7 @@ public class BatchingUploaderTest { public void testNoMoreRecordsNoOp() { BatchingUploader uploader = makeConstrainedUploader(2, 4); - uploader.commitIfNecessaryAfterLastPayload(); + uploader.noMoreRecordsToUpload(); assertEquals(0, ((MockExecutorService) workQueue).totalPayloads); assertEquals(0, ((MockExecutorService) workQueue).commitPayloads); } @@ -369,7 +389,7 @@ public class BatchingUploaderTest { assertEquals(2, ((MockExecutorService) workQueue).totalPayloads); assertEquals(1, ((MockExecutorService) workQueue).commitPayloads); - uploader.commitIfNecessaryAfterLastPayload(); + uploader.noMoreRecordsToUpload(); assertEquals(2, ((MockExecutorService) workQueue).totalPayloads); assertEquals(1, ((MockExecutorService) workQueue).commitPayloads); } @@ -383,8 +403,8 @@ public class BatchingUploaderTest { MockRecord record = new MockRecord(Utils.generateGuid(), null, 0, false); uploader.process(record); uploader.process(record); - uploader.setInBatchingMode(false); - uploader.commitIfNecessaryAfterLastPayload(); + uploader.setUnlimitedMode(true); + uploader.noMoreRecordsToUpload(); // One will be a payload post, the other one is batch commit (one record payload) assertEquals(1, ((MockExecutorService) workQueue).totalPayloads); assertEquals(0, ((MockExecutorService) workQueue).commitPayloads); @@ -398,24 +418,28 @@ public class BatchingUploaderTest { MockRecord record = new MockRecord(Utils.generateGuid(), null, 0, false); uploader.process(record); - uploader.commitIfNecessaryAfterLastPayload(); + uploader.noMoreRecordsToUpload(); assertEquals(1, ((MockExecutorService) workQueue).totalPayloads); assertEquals(1, ((MockExecutorService) workQueue).commitPayloads); } private BatchingUploader makeConstrainedUploader(long maxPostRecords, long maxTotalRecords) { + return makeConstrainedUploader(maxPostRecords, maxTotalRecords, false); + } + + private BatchingUploader makeConstrainedUploader(long maxPostRecords, long maxTotalRecords, boolean firstSync) { Server11RepositorySession server11RepositorySession = new Server11RepositorySession( - makeCountConstrainedRepository(maxPostRecords, maxTotalRecords) + makeCountConstrainedRepository(maxPostRecords, maxTotalRecords, firstSync) ); server11RepositorySession.setStoreDelegate(storeDelegate); return new BatchingUploader(server11RepositorySession, workQueue, storeDelegate); } - private Server11Repository makeCountConstrainedRepository(long maxPostRecords, long maxTotalRecords) { - return makeConstrainedRepository(1024, 1024, maxPostRecords, 4096, maxTotalRecords); + private Server11Repository makeCountConstrainedRepository(long maxPostRecords, long maxTotalRecords, boolean firstSync) { + return makeConstrainedRepository(1024, 1024, maxPostRecords, 4096, maxTotalRecords, firstSync); } - private Server11Repository makeConstrainedRepository(long maxRequestBytes, long maxPostBytes, long maxPostRecords, long maxTotalBytes, long maxTotalRecords) { + private Server11Repository makeConstrainedRepository(long maxRequestBytes, long maxPostBytes, long maxPostRecords, long maxTotalBytes, long maxTotalRecords, boolean firstSync) { ExtendedJSONObject infoConfigurationJSON = new ExtendedJSONObject(); infoConfigurationJSON.put(InfoConfiguration.MAX_TOTAL_BYTES, maxTotalBytes); infoConfigurationJSON.put(InfoConfiguration.MAX_TOTAL_RECORDS, maxTotalRecords); @@ -425,12 +449,29 @@ public class BatchingUploaderTest { InfoConfiguration infoConfiguration = new InfoConfiguration(infoConfigurationJSON); + InfoCollections infoCollections; + if (firstSync) { + infoCollections = new InfoCollections() { + @Override + public Long getTimestamp(String collection) { + return null; + } + }; + } else { + infoCollections = new InfoCollections() { + @Override + public Long getTimestamp(String collection) { + return 0L; + } + }; + } + try { return new Server11Repository( "dummyCollection", "http://dummy.url/", null, - new InfoCollections(), + infoCollections, infoConfiguration ); } catch (URISyntaxException e) { @@ -438,4 +479,22 @@ public class BatchingUploaderTest { return null; } } + + static abstract class TestRunnableWithTarget { + T target; + + TestRunnableWithTarget() {} + + TestRunnableWithTarget setTarget(T target) { + this.target = target; + return this; + } + + TestRunnableWithTarget run() { + tests(); + return this; + } + + abstract void tests(); + } } \ No newline at end of file diff --git a/mobile/android/tests/background/junit4/src/org/mozilla/gecko/sync/repositories/uploaders/PayloadTest.java b/mobile/android/tests/background/junit4/src/org/mozilla/gecko/sync/repositories/uploaders/PayloadTest.java index b1d6dd9d0882..033099f72b8e 100644 --- a/mobile/android/tests/background/junit4/src/org/mozilla/gecko/sync/repositories/uploaders/PayloadTest.java +++ b/mobile/android/tests/background/junit4/src/org/mozilla/gecko/sync/repositories/uploaders/PayloadTest.java @@ -106,32 +106,4 @@ public class PayloadTest { assertTrue(true); } } - - @Test - public void testReset() { - assertTrue(payload.getByteCount() == 2 * BatchingUploader.PER_PAYLOAD_OVERHEAD_BYTE_COUNT); - assertTrue(payload.getRecordCount() == 0); - assertTrue(payload.getRecordsBuffer().isEmpty()); - assertTrue(payload.getRecordGuidsBuffer().isEmpty()); - assertTrue(payload.isEmpty()); - - // Shouldn't throw even if already empty - payload.reset(); - assertTrue(payload.getByteCount() == 2 * BatchingUploader.PER_PAYLOAD_OVERHEAD_BYTE_COUNT); - assertTrue(payload.getRecordCount() == 0); - assertTrue(payload.getRecordsBuffer().isEmpty()); - assertTrue(payload.getRecordGuidsBuffer().isEmpty()); - assertTrue(payload.isEmpty()); - - byte[] recordBytes1 = new byte[100]; - assertFalse(payload.addAndEstimateIfFull(1, recordBytes1, "guid1")); - assertFalse(payload.isEmpty()); - payload.reset(); - - assertTrue(payload.getByteCount() == 2 * BatchingUploader.PER_PAYLOAD_OVERHEAD_BYTE_COUNT); - assertTrue(payload.getRecordCount() == 0); - assertTrue(payload.getRecordsBuffer().isEmpty()); - assertTrue(payload.getRecordGuidsBuffer().isEmpty()); - assertTrue(payload.isEmpty()); - } } \ No newline at end of file diff --git a/mobile/android/tests/background/junit4/src/org/mozilla/gecko/sync/repositories/uploaders/PayloadUploadDelegateTest.java b/mobile/android/tests/background/junit4/src/org/mozilla/gecko/sync/repositories/uploaders/PayloadUploadDelegateTest.java index fc43c2f5e54a..4fadfda624c8 100644 --- a/mobile/android/tests/background/junit4/src/org/mozilla/gecko/sync/repositories/uploaders/PayloadUploadDelegateTest.java +++ b/mobile/android/tests/background/junit4/src/org/mozilla/gecko/sync/repositories/uploaders/PayloadUploadDelegateTest.java @@ -11,11 +11,14 @@ import org.mozilla.gecko.sync.HTTPFailureException; import org.mozilla.gecko.sync.InfoCollections; import org.mozilla.gecko.sync.InfoConfiguration; import org.mozilla.gecko.sync.NonObjectJSONException; +import org.mozilla.gecko.sync.net.AuthHeaderProvider; import org.mozilla.gecko.sync.net.SyncResponse; import org.mozilla.gecko.sync.net.SyncStorageResponse; +import org.mozilla.gecko.sync.repositories.RepositorySession; import org.mozilla.gecko.sync.repositories.Server11Repository; import org.mozilla.gecko.sync.repositories.Server11RepositorySession; -import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionStoreDelegate; + +import static org.mockito.Mockito.mock; import java.io.ByteArrayInputStream; import java.util.ArrayList; @@ -28,14 +31,16 @@ import ch.boye.httpclientandroidlib.entity.BasicHttpEntity; import ch.boye.httpclientandroidlib.message.BasicHttpResponse; import ch.boye.httpclientandroidlib.message.BasicStatusLine; +import static org.mockito.Mockito.mock; + import static org.junit.Assert.*; @RunWith(TestRunner.class) public class PayloadUploadDelegateTest { - private BatchingUploader batchingUploader; + private PayloadDispatcher payloadDispatcher; + private AuthHeaderProvider authHeaderProvider; - class MockUploader extends BatchingUploader { - public final ArrayList successRecords = new ArrayList<>(); + class MockPayloadDispatcher extends PayloadDispatcher { public final HashMap failedRecords = new HashMap<>(); public boolean didLastPayloadFail = false; @@ -43,26 +48,24 @@ public class PayloadUploadDelegateTest { public int commitPayloadsSucceeded = 0; public int lastPayloadsSucceeded = 0; - public MockUploader(final Server11RepositorySession repositorySession, final Executor workQueue, final RepositorySessionStoreDelegate sessionStoreDelegate) { - super(repositorySession, workQueue, sessionStoreDelegate); + public int committedGuids = 0; + + public MockPayloadDispatcher(final Executor workQueue, final BatchingUploader uploader) { + super(workQueue, uploader, null); } @Override - public void payloadSucceeded(final SyncStorageResponse response, final boolean isCommit, final boolean isLastPayload) { + public void payloadSucceeded(final SyncStorageResponse response, String[] guids, final boolean isCommit, final boolean isLastPayload) { successResponses.add(response); if (isCommit) { ++commitPayloadsSucceeded; + committedGuids += guids.length; } if (isLastPayload) { ++lastPayloadsSucceeded; } } - @Override - public void recordSucceeded(final String recordGuid) { - successRecords.add(recordGuid); - } - @Override public void recordFailed(final String recordGuid) { recordFailed(new Exception(), recordGuid); @@ -85,14 +88,20 @@ public class PayloadUploadDelegateTest { "dummyCollection", "http://dummy.url/", null, - new InfoCollections(), + new InfoCollections() { + @Override + public Long getTimestamp(String collection) { + return 0L; + } + }, new InfoConfiguration() ); - batchingUploader = new MockUploader( - new Server11RepositorySession(server11Repository), + payloadDispatcher = new MockPayloadDispatcher( null, - null + mock(BatchingUploader.class) ); + + authHeaderProvider = mock(AuthHeaderProvider.class); } @Test @@ -101,16 +110,16 @@ public class PayloadUploadDelegateTest { postedGuids.add("testGuid1"); postedGuids.add("testGuid2"); PayloadUploadDelegate payloadUploadDelegate = new PayloadUploadDelegate( - batchingUploader, postedGuids, false, false); + authHeaderProvider, payloadDispatcher, postedGuids, false, false); // Test that non-2* responses aren't processed payloadUploadDelegate.handleRequestSuccess(makeSyncStorageResponse(404, null, null)); - assertEquals(2, ((MockUploader) batchingUploader).failedRecords.size()); - assertFalse(((MockUploader) batchingUploader).didLastPayloadFail); + assertEquals(2, ((MockPayloadDispatcher) payloadDispatcher).failedRecords.size()); + assertFalse(((MockPayloadDispatcher) payloadDispatcher).didLastPayloadFail); assertEquals(IllegalStateException.class, - ((MockUploader) batchingUploader).failedRecords.get("testGuid1").getClass()); + ((MockPayloadDispatcher) payloadDispatcher).failedRecords.get("testGuid1").getClass()); assertEquals(IllegalStateException.class, - ((MockUploader) batchingUploader).failedRecords.get("testGuid2").getClass()); + ((MockPayloadDispatcher) payloadDispatcher).failedRecords.get("testGuid2").getClass()); } @Test @@ -119,16 +128,16 @@ public class PayloadUploadDelegateTest { postedGuids.add("testGuid1"); postedGuids.add("testGuid2"); PayloadUploadDelegate payloadUploadDelegate = new PayloadUploadDelegate( - batchingUploader, postedGuids, false, false); + authHeaderProvider, payloadDispatcher, postedGuids, false, false); // Test that responses without X-Last-Modified header aren't processed payloadUploadDelegate.handleRequestSuccess(makeSyncStorageResponse(200, null, null)); - assertEquals(2, ((MockUploader) batchingUploader).failedRecords.size()); - assertFalse(((MockUploader) batchingUploader).didLastPayloadFail); + assertEquals(2, ((MockPayloadDispatcher) payloadDispatcher).failedRecords.size()); + assertFalse(((MockPayloadDispatcher) payloadDispatcher).didLastPayloadFail); assertEquals(IllegalStateException.class, - ((MockUploader) batchingUploader).failedRecords.get("testGuid1").getClass()); + ((MockPayloadDispatcher) payloadDispatcher).failedRecords.get("testGuid1").getClass()); assertEquals(IllegalStateException.class, - ((MockUploader) batchingUploader).failedRecords.get("testGuid2").getClass()); + ((MockPayloadDispatcher) payloadDispatcher).failedRecords.get("testGuid2").getClass()); } @Test @@ -137,16 +146,16 @@ public class PayloadUploadDelegateTest { postedGuids.add("testGuid1"); postedGuids.add("testGuid2"); PayloadUploadDelegate payloadUploadDelegate = new PayloadUploadDelegate( - batchingUploader, postedGuids, false, true); + authHeaderProvider, payloadDispatcher, postedGuids, false, true); // Test that we catch json processing errors payloadUploadDelegate.handleRequestSuccess(makeSyncStorageResponse(200, "non json body", "123")); - assertEquals(2, ((MockUploader) batchingUploader).failedRecords.size()); - assertTrue(((MockUploader) batchingUploader).didLastPayloadFail); + assertEquals(2, ((MockPayloadDispatcher) payloadDispatcher).failedRecords.size()); + assertTrue(((MockPayloadDispatcher) payloadDispatcher).didLastPayloadFail); assertEquals(NonObjectJSONException.class, - ((MockUploader) batchingUploader).failedRecords.get("testGuid1").getClass()); + ((MockPayloadDispatcher) payloadDispatcher).failedRecords.get("testGuid1").getClass()); assertEquals(NonObjectJSONException.class, - ((MockUploader) batchingUploader).failedRecords.get("testGuid2").getClass()); + ((MockPayloadDispatcher) payloadDispatcher).failedRecords.get("testGuid2").getClass()); } @Test @@ -154,13 +163,13 @@ public class PayloadUploadDelegateTest { ArrayList postedGuids = new ArrayList<>(1); postedGuids.add("testGuid1"); PayloadUploadDelegate payloadUploadDelegate = new PayloadUploadDelegate( - batchingUploader, postedGuids, false, true); + authHeaderProvider, payloadDispatcher, postedGuids, false, true); // Test that we catch absent tokens in 202 responses payloadUploadDelegate.handleRequestSuccess(makeSyncStorageResponse(202, "{\"success\": []}", "123")); - assertEquals(1, ((MockUploader) batchingUploader).failedRecords.size()); + assertEquals(1, ((MockPayloadDispatcher) payloadDispatcher).failedRecords.size()); assertEquals(IllegalStateException.class, - ((MockUploader) batchingUploader).failedRecords.get("testGuid1").getClass()); + ((MockPayloadDispatcher) payloadDispatcher).failedRecords.get("testGuid1").getClass()); } @Test @@ -169,19 +178,19 @@ public class PayloadUploadDelegateTest { postedGuids.add("testGuid1"); PayloadUploadDelegate payloadUploadDelegate = new PayloadUploadDelegate( - batchingUploader, postedGuids, false, false); + authHeaderProvider, payloadDispatcher, postedGuids, false, false); // Test that if in batching mode and saw the token, 200 must be a response to a commit try { - batchingUploader.getCurrentBatch().setToken("MTIzNA", true); + payloadDispatcher.batchWhiteboard.setToken("MTIzNA", true); } catch (BatchingUploader.BatchingUploaderException e) {} - batchingUploader.setInBatchingMode(true); + payloadDispatcher.setInBatchingMode(true); // not a commit, so should fail payloadUploadDelegate.handleRequestSuccess(makeSyncStorageResponse(200, "{\"success\": []}", "123")); - assertEquals(1, ((MockUploader) batchingUploader).failedRecords.size()); + assertEquals(1, ((MockPayloadDispatcher) payloadDispatcher).failedRecords.size()); assertEquals(IllegalStateException.class, - ((MockUploader) batchingUploader).failedRecords.get("testGuid1").getClass()); + ((MockPayloadDispatcher) payloadDispatcher).failedRecords.get("testGuid1").getClass()); } @Test @@ -191,32 +200,32 @@ public class PayloadUploadDelegateTest { postedGuids.add("guid2"); postedGuids.add("guid3"); PayloadUploadDelegate payloadUploadDelegate = new PayloadUploadDelegate( - batchingUploader, postedGuids, false, false); + authHeaderProvider, payloadDispatcher, postedGuids, false, false); payloadUploadDelegate.handleRequestSuccess( makeSyncStorageResponse(200, "{\"success\": [\"guid1\", \"guid2\", \"guid3\"]}", "123")); - assertEquals(0, ((MockUploader) batchingUploader).failedRecords.size()); - assertEquals(3, ((MockUploader) batchingUploader).successRecords.size()); - assertFalse(((MockUploader) batchingUploader).didLastPayloadFail); - assertEquals(1, ((MockUploader) batchingUploader).successResponses.size()); - assertEquals(0, ((MockUploader) batchingUploader).commitPayloadsSucceeded); - assertEquals(0, ((MockUploader) batchingUploader).lastPayloadsSucceeded); + assertEquals(0, ((MockPayloadDispatcher) payloadDispatcher).failedRecords.size()); + assertEquals(3, payloadDispatcher.batchWhiteboard.getSuccessRecordGuids().length); + assertFalse(((MockPayloadDispatcher) payloadDispatcher).didLastPayloadFail); + assertEquals(1, ((MockPayloadDispatcher) payloadDispatcher).successResponses.size()); + assertEquals(0, ((MockPayloadDispatcher) payloadDispatcher).commitPayloadsSucceeded); + assertEquals(0, ((MockPayloadDispatcher) payloadDispatcher).lastPayloadsSucceeded); // These should fail, because we're returning a non-changed L-M in a non-batching mode postedGuids.add("guid4"); postedGuids.add("guid6"); payloadUploadDelegate = new PayloadUploadDelegate( - batchingUploader, postedGuids, false, false); + authHeaderProvider, payloadDispatcher, postedGuids, false, false); payloadUploadDelegate.handleRequestSuccess( makeSyncStorageResponse(200, "{\"success\": [\"guid4\", 5, \"guid6\"]}", "123")); - assertEquals(5, ((MockUploader) batchingUploader).failedRecords.size()); - assertEquals(3, ((MockUploader) batchingUploader).successRecords.size()); - assertFalse(((MockUploader) batchingUploader).didLastPayloadFail); - assertEquals(1, ((MockUploader) batchingUploader).successResponses.size()); - assertEquals(0, ((MockUploader) batchingUploader).commitPayloadsSucceeded); - assertEquals(0, ((MockUploader) batchingUploader).lastPayloadsSucceeded); + assertEquals(5, ((MockPayloadDispatcher) payloadDispatcher).failedRecords.size()); + assertEquals(3, payloadDispatcher.batchWhiteboard.getSuccessRecordGuids().length); + assertFalse(((MockPayloadDispatcher) payloadDispatcher).didLastPayloadFail); + assertEquals(1, ((MockPayloadDispatcher) payloadDispatcher).successResponses.size()); + assertEquals(0, ((MockPayloadDispatcher) payloadDispatcher).commitPayloadsSucceeded); + assertEquals(0, ((MockPayloadDispatcher) payloadDispatcher).lastPayloadsSucceeded); assertEquals(BatchingUploader.LastModifiedDidNotChange.class, - ((MockUploader) batchingUploader).failedRecords.get("guid4").getClass()); + ((MockPayloadDispatcher) payloadDispatcher).failedRecords.get("guid4").getClass()); } @Test @@ -226,7 +235,7 @@ public class PayloadUploadDelegateTest { postedGuids.add("guid2"); postedGuids.add("guid3"); PayloadUploadDelegate payloadUploadDelegate = new PayloadUploadDelegate( - batchingUploader, postedGuids, false, false); + authHeaderProvider, payloadDispatcher, postedGuids, false, false); payloadUploadDelegate.handleRequestSuccess( makeSyncStorageResponse(200, "{\"success\": [\"guid1\", \"guid2\", \"guid3\"], \"failed\": {}}", "123")); @@ -234,94 +243,98 @@ public class PayloadUploadDelegateTest { postedGuids.add("guid4"); postedGuids.add("guid5"); payloadUploadDelegate = new PayloadUploadDelegate( - batchingUploader, postedGuids, false, false); + authHeaderProvider, payloadDispatcher, postedGuids, false, false); payloadUploadDelegate.handleRequestSuccess( makeSyncStorageResponse(200, "{\"success\": [\"guid4\", \"guid5\"], \"failed\": {}}", "333")); postedGuids = new ArrayList<>(); postedGuids.add("guid6"); payloadUploadDelegate = new PayloadUploadDelegate( - batchingUploader, postedGuids, false, true); + authHeaderProvider, payloadDispatcher, postedGuids, false, true); payloadUploadDelegate.handleRequestSuccess( makeSyncStorageResponse(200, "{\"success\": [\"guid6\"], \"failed\": {}}", "444")); - assertEquals(0, ((MockUploader) batchingUploader).failedRecords.size()); - assertEquals(6, ((MockUploader) batchingUploader).successRecords.size()); - assertFalse(((MockUploader) batchingUploader).didLastPayloadFail); - assertEquals(3, ((MockUploader) batchingUploader).successResponses.size()); - assertEquals(0, ((MockUploader) batchingUploader).commitPayloadsSucceeded); - assertEquals(1, ((MockUploader) batchingUploader).lastPayloadsSucceeded); - assertFalse(batchingUploader.getInBatchingMode()); + assertEquals(0, ((MockPayloadDispatcher) payloadDispatcher).failedRecords.size()); + assertEquals(6, payloadDispatcher.batchWhiteboard.getSuccessRecordGuids().length); + assertFalse(((MockPayloadDispatcher) payloadDispatcher).didLastPayloadFail); + assertEquals(3, ((MockPayloadDispatcher) payloadDispatcher).successResponses.size()); + assertEquals(0, ((MockPayloadDispatcher) payloadDispatcher).commitPayloadsSucceeded); + assertEquals(1, ((MockPayloadDispatcher) payloadDispatcher).lastPayloadsSucceeded); + assertFalse(payloadDispatcher.batchWhiteboard.getInBatchingMode()); postedGuids = new ArrayList<>(); postedGuids.add("guid7"); postedGuids.add("guid8"); payloadUploadDelegate = new PayloadUploadDelegate( - batchingUploader, postedGuids, false, true); + authHeaderProvider, payloadDispatcher, postedGuids, false, true); payloadUploadDelegate.handleRequestSuccess( makeSyncStorageResponse(200, "{\"success\": [\"guid8\"], \"failed\": {\"guid7\": \"reason\"}}", "555")); - assertEquals(1, ((MockUploader) batchingUploader).failedRecords.size()); - assertTrue(((MockUploader) batchingUploader).failedRecords.containsKey("guid7")); - assertEquals(7, ((MockUploader) batchingUploader).successRecords.size()); - assertFalse(((MockUploader) batchingUploader).didLastPayloadFail); - assertEquals(4, ((MockUploader) batchingUploader).successResponses.size()); - assertEquals(0, ((MockUploader) batchingUploader).commitPayloadsSucceeded); - assertEquals(2, ((MockUploader) batchingUploader).lastPayloadsSucceeded); - assertFalse(batchingUploader.getInBatchingMode()); + assertEquals(1, ((MockPayloadDispatcher) payloadDispatcher).failedRecords.size()); + assertTrue(((MockPayloadDispatcher) payloadDispatcher).failedRecords.containsKey("guid7")); + assertEquals(7, payloadDispatcher.batchWhiteboard.getSuccessRecordGuids().length); + assertFalse(((MockPayloadDispatcher) payloadDispatcher).didLastPayloadFail); + assertEquals(4, ((MockPayloadDispatcher) payloadDispatcher).successResponses.size()); + assertEquals(0, ((MockPayloadDispatcher) payloadDispatcher).commitPayloadsSucceeded); + assertEquals(2, ((MockPayloadDispatcher) payloadDispatcher).lastPayloadsSucceeded); + assertFalse(payloadDispatcher.batchWhiteboard.getInBatchingMode()); } @Test public void testHandleRequestSuccessBatching() { + assertNull(payloadDispatcher.batchWhiteboard.getInBatchingMode()); + ArrayList postedGuids = new ArrayList<>(); postedGuids.add("guid1"); postedGuids.add("guid2"); postedGuids.add("guid3"); PayloadUploadDelegate payloadUploadDelegate = new PayloadUploadDelegate( - batchingUploader, postedGuids, false, false); + authHeaderProvider, payloadDispatcher, postedGuids, false, false); payloadUploadDelegate.handleRequestSuccess( makeSyncStorageResponse(202, "{\"batch\": \"MTIzNA\", \"success\": [\"guid1\", \"guid2\", \"guid3\"], \"failed\": {}}", "123")); - assertTrue(batchingUploader.getInBatchingMode()); - assertEquals("MTIzNA", batchingUploader.getCurrentBatch().getToken()); + assertTrue(payloadDispatcher.batchWhiteboard.getInBatchingMode()); + assertEquals("MTIzNA", payloadDispatcher.batchWhiteboard.getToken()); postedGuids = new ArrayList<>(); postedGuids.add("guid4"); postedGuids.add("guid5"); postedGuids.add("guid6"); payloadUploadDelegate = new PayloadUploadDelegate( - batchingUploader, postedGuids, false, false); + authHeaderProvider, payloadDispatcher, postedGuids, false, false); payloadUploadDelegate.handleRequestSuccess( makeSyncStorageResponse(202, "{\"batch\": \"MTIzNA\", \"success\": [\"guid4\", \"guid5\", \"guid6\"], \"failed\": {}}", "123")); - assertTrue(batchingUploader.getInBatchingMode()); - assertEquals("MTIzNA", batchingUploader.getCurrentBatch().getToken()); + assertTrue(payloadDispatcher.batchWhiteboard.getInBatchingMode()); + assertEquals("MTIzNA", payloadDispatcher.batchWhiteboard.getToken()); postedGuids = new ArrayList<>(); postedGuids.add("guid7"); payloadUploadDelegate = new PayloadUploadDelegate( - batchingUploader, postedGuids, true, false); + authHeaderProvider, payloadDispatcher, postedGuids, true, false); payloadUploadDelegate.handleRequestSuccess( - makeSyncStorageResponse(200, "{\"success\": [\"guid6\"], \"failed\": {}}", "222")); + makeSyncStorageResponse(200, "{\"success\": [\"guid7\"], \"failed\": {}}", "222")); + + assertEquals(7, ((MockPayloadDispatcher) payloadDispatcher).committedGuids); // Even though everything indicates we're not in a batching, we were, so test that // we don't reset the flag. - assertTrue(batchingUploader.getInBatchingMode()); - assertNull(batchingUploader.getCurrentBatch().getToken()); + assertTrue(payloadDispatcher.batchWhiteboard.getInBatchingMode()); + assertNull(payloadDispatcher.batchWhiteboard.getToken()); postedGuids = new ArrayList<>(); postedGuids.add("guid8"); payloadUploadDelegate = new PayloadUploadDelegate( - batchingUploader, postedGuids, true, true); + authHeaderProvider, payloadDispatcher, postedGuids, true, true); payloadUploadDelegate.handleRequestSuccess( makeSyncStorageResponse(200, "{\"success\": [\"guid7\"], \"failed\": {}}", "333")); - assertEquals(0, ((MockUploader) batchingUploader).failedRecords.size()); - assertEquals(8, ((MockUploader) batchingUploader).successRecords.size()); - assertFalse(((MockUploader) batchingUploader).didLastPayloadFail); - assertEquals(4, ((MockUploader) batchingUploader).successResponses.size()); - assertEquals(2, ((MockUploader) batchingUploader).commitPayloadsSucceeded); - assertEquals(1, ((MockUploader) batchingUploader).lastPayloadsSucceeded); - assertTrue(batchingUploader.getInBatchingMode()); + assertEquals(0, ((MockPayloadDispatcher) payloadDispatcher).failedRecords.size()); + assertEquals(8, ((MockPayloadDispatcher) payloadDispatcher).committedGuids); + assertFalse(((MockPayloadDispatcher) payloadDispatcher).didLastPayloadFail); + assertEquals(4, ((MockPayloadDispatcher) payloadDispatcher).successResponses.size()); + assertEquals(2, ((MockPayloadDispatcher) payloadDispatcher).commitPayloadsSucceeded); + assertEquals(1, ((MockPayloadDispatcher) payloadDispatcher).lastPayloadsSucceeded); + assertTrue(payloadDispatcher.batchWhiteboard.getInBatchingMode()); } @Test @@ -330,21 +343,23 @@ public class PayloadUploadDelegateTest { postedGuids.add("testGuid1"); postedGuids.add("testGuid2"); postedGuids.add("testGuid3"); - PayloadUploadDelegate payloadUploadDelegate = new PayloadUploadDelegate(batchingUploader, postedGuids, false, false); + PayloadUploadDelegate payloadUploadDelegate = new PayloadUploadDelegate( + authHeaderProvider, payloadDispatcher, postedGuids, false, false); IllegalStateException e = new IllegalStateException(); payloadUploadDelegate.handleRequestError(e); - assertEquals(3, ((MockUploader) batchingUploader).failedRecords.size()); - assertEquals(e, ((MockUploader) batchingUploader).failedRecords.get("testGuid1")); - assertEquals(e, ((MockUploader) batchingUploader).failedRecords.get("testGuid2")); - assertEquals(e, ((MockUploader) batchingUploader).failedRecords.get("testGuid3")); - assertFalse(((MockUploader) batchingUploader).didLastPayloadFail); + assertEquals(3, ((MockPayloadDispatcher) payloadDispatcher).failedRecords.size()); + assertEquals(e, ((MockPayloadDispatcher) payloadDispatcher).failedRecords.get("testGuid1")); + assertEquals(e, ((MockPayloadDispatcher) payloadDispatcher).failedRecords.get("testGuid2")); + assertEquals(e, ((MockPayloadDispatcher) payloadDispatcher).failedRecords.get("testGuid3")); + assertFalse(((MockPayloadDispatcher) payloadDispatcher).didLastPayloadFail); - payloadUploadDelegate = new PayloadUploadDelegate(batchingUploader, postedGuids, false, true); + payloadUploadDelegate = new PayloadUploadDelegate( + authHeaderProvider, payloadDispatcher, postedGuids, false, true); payloadUploadDelegate.handleRequestError(e); - assertEquals(3, ((MockUploader) batchingUploader).failedRecords.size()); - assertTrue(((MockUploader) batchingUploader).didLastPayloadFail); + assertEquals(3, ((MockPayloadDispatcher) payloadDispatcher).failedRecords.size()); + assertTrue(((MockPayloadDispatcher) payloadDispatcher).didLastPayloadFail); } @Test @@ -353,35 +368,44 @@ public class PayloadUploadDelegateTest { postedGuids.add("testGuid1"); postedGuids.add("testGuid2"); postedGuids.add("testGuid3"); - PayloadUploadDelegate payloadUploadDelegate = new PayloadUploadDelegate(batchingUploader, postedGuids, false, false); + PayloadUploadDelegate payloadUploadDelegate = new PayloadUploadDelegate( + authHeaderProvider, payloadDispatcher, postedGuids, false, false); final HttpResponse response = new BasicHttpResponse( new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 503, "Illegal method/protocol")); payloadUploadDelegate.handleRequestFailure(new SyncStorageResponse(response)); - assertEquals(3, ((MockUploader) batchingUploader).failedRecords.size()); + assertEquals(3, ((MockPayloadDispatcher) payloadDispatcher).failedRecords.size()); assertEquals(HTTPFailureException.class, - ((MockUploader) batchingUploader).failedRecords.get("testGuid1").getClass()); + ((MockPayloadDispatcher) payloadDispatcher).failedRecords.get("testGuid1").getClass()); assertEquals(HTTPFailureException.class, - ((MockUploader) batchingUploader).failedRecords.get("testGuid2").getClass()); + ((MockPayloadDispatcher) payloadDispatcher).failedRecords.get("testGuid2").getClass()); assertEquals(HTTPFailureException.class, - ((MockUploader) batchingUploader).failedRecords.get("testGuid3").getClass()); + ((MockPayloadDispatcher) payloadDispatcher).failedRecords.get("testGuid3").getClass()); - payloadUploadDelegate = new PayloadUploadDelegate(batchingUploader, postedGuids, false, true); + payloadUploadDelegate = new PayloadUploadDelegate( + authHeaderProvider, payloadDispatcher, postedGuids, false, true); payloadUploadDelegate.handleRequestFailure(new SyncStorageResponse(response)); - assertEquals(3, ((MockUploader) batchingUploader).failedRecords.size()); - assertTrue(((MockUploader) batchingUploader).didLastPayloadFail); + assertEquals(3, ((MockPayloadDispatcher) payloadDispatcher).failedRecords.size()); + assertTrue(((MockPayloadDispatcher) payloadDispatcher).didLastPayloadFail); } @Test - public void testIfUnmodifiedSince() { + public void testIfUnmodifiedSinceNoLM() { PayloadUploadDelegate payloadUploadDelegate = new PayloadUploadDelegate( - batchingUploader, new ArrayList(), false, false); + authHeaderProvider, payloadDispatcher, new ArrayList(), false, false); assertNull(payloadUploadDelegate.ifUnmodifiedSince()); + } + @Test + public void testIfUnmodifiedSinceWithLM() { + PayloadUploadDelegate payloadUploadDelegate = new PayloadUploadDelegate( + authHeaderProvider, payloadDispatcher, new ArrayList(), false, false); try { - batchingUploader.getCurrentBatch().setLastModified(1471645412480L, true); - } catch (BatchingUploader.BatchingUploaderException e) {} + payloadDispatcher.batchWhiteboard.setLastModified(1471645412480L, true); + } catch (BatchingUploader.BatchingUploaderException e) { + fail(); + } assertEquals("1471645412.480", payloadUploadDelegate.ifUnmodifiedSince()); } diff --git a/mobile/android/tests/background/junit4/src/org/mozilla/gecko/sync/repositories/uploaders/RecordUploadRunnableTest.java b/mobile/android/tests/background/junit4/src/org/mozilla/gecko/sync/repositories/uploaders/RecordUploadRunnableTest.java index 269c253628b3..d12dff5be65d 100644 --- a/mobile/android/tests/background/junit4/src/org/mozilla/gecko/sync/repositories/uploaders/RecordUploadRunnableTest.java +++ b/mobile/android/tests/background/junit4/src/org/mozilla/gecko/sync/repositories/uploaders/RecordUploadRunnableTest.java @@ -17,22 +17,20 @@ import static org.junit.Assert.*; public class RecordUploadRunnableTest { @Test public void testBuildPostURI() throws Exception { - BatchMeta batchMeta = new BatchMeta(new Object(), 1, 1, null); URI postURI = RecordUploadRunnable.buildPostURI( - false, batchMeta, Uri.parse("http://example.com/")); + false, null, Uri.parse("http://example.com/")); assertEquals("http://example.com/?batch=true", postURI.toString()); postURI = RecordUploadRunnable.buildPostURI( - true, batchMeta, Uri.parse("http://example.com/")); + true, null, Uri.parse("http://example.com/")); assertEquals("http://example.com/?batch=true&commit=true", postURI.toString()); - batchMeta.setToken("MTIzNA", false); postURI = RecordUploadRunnable.buildPostURI( - false, batchMeta, Uri.parse("http://example.com/")); + false, "MTIzNA", Uri.parse("http://example.com/")); assertEquals("http://example.com/?batch=MTIzNA", postURI.toString()); postURI = RecordUploadRunnable.buildPostURI( - true, batchMeta, Uri.parse("http://example.com/")); + true, "MTIzNA", Uri.parse("http://example.com/")); assertEquals("http://example.com/?batch=MTIzNA&commit=true", postURI.toString()); } } \ No newline at end of file diff --git a/mobile/android/tests/background/junit4/src/org/mozilla/gecko/sync/repositories/uploaders/UploaderMetaTest.java b/mobile/android/tests/background/junit4/src/org/mozilla/gecko/sync/repositories/uploaders/UploaderMetaTest.java new file mode 100644 index 000000000000..1e5020ca67f8 --- /dev/null +++ b/mobile/android/tests/background/junit4/src/org/mozilla/gecko/sync/repositories/uploaders/UploaderMetaTest.java @@ -0,0 +1,107 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +package org.mozilla.gecko.sync.repositories.uploaders; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mozilla.gecko.background.testhelpers.TestRunner; + +import static org.junit.Assert.*; + +@RunWith(TestRunner.class) +public class UploaderMetaTest { + private UploaderMeta uploaderMeta; + private long byteLimit = 1024; + private long recordLimit = 5; + private Object lock = new Object(); + + @Before + public void setUp() throws Exception { + uploaderMeta = new UploaderMeta(lock, byteLimit, recordLimit); + } + + @Test + public void testByteLimits() { + assertTrue(uploaderMeta.canFit(0)); + + // Should just fit + assertTrue(uploaderMeta.canFit(byteLimit - BatchingUploader.PER_PAYLOAD_OVERHEAD_BYTE_COUNT)); + + // Can't fit a record due to payload overhead. + assertFalse(uploaderMeta.canFit(byteLimit)); + + assertFalse(uploaderMeta.canFit(byteLimit + BatchingUploader.PER_PAYLOAD_OVERHEAD_BYTE_COUNT)); + assertFalse(uploaderMeta.canFit(byteLimit * 1000)); + + long recordDelta = byteLimit / 2; + assertFalse(uploaderMeta.addAndEstimateIfFull(recordDelta)); + + // Record delta shouldn't fit due to payload overhead. + assertFalse(uploaderMeta.canFit(recordDelta)); + } + + @Test + public void testCountLimits() { + // Our record limit is 5, let's add 4. + assertFalse(uploaderMeta.addAndEstimateIfFull(1)); + assertFalse(uploaderMeta.addAndEstimateIfFull(1)); + assertFalse(uploaderMeta.addAndEstimateIfFull(1)); + assertFalse(uploaderMeta.addAndEstimateIfFull(1)); + + // 5th record still fits in + assertTrue(uploaderMeta.canFit(1)); + + // Add the 5th record + assertTrue(uploaderMeta.addAndEstimateIfFull(1)); + + // 6th record won't fit + assertFalse(uploaderMeta.canFit(1)); + } + + @Test + public void testNeedCommit() { + assertFalse(uploaderMeta.needToCommit()); + + assertFalse(uploaderMeta.addAndEstimateIfFull(1)); + + assertTrue(uploaderMeta.needToCommit()); + + assertFalse(uploaderMeta.addAndEstimateIfFull(1)); + assertFalse(uploaderMeta.addAndEstimateIfFull(1)); + assertFalse(uploaderMeta.addAndEstimateIfFull(1)); + + assertTrue(uploaderMeta.needToCommit()); + } + + @Test + public void testAdd() { + // Ensure we account for payload overhead twice when the batch is empty. + // Payload overhead is either RECORDS_START or RECORDS_END, and for an empty payload + // we need both. + assertTrue(uploaderMeta.getByteCount() == 2 * BatchingUploader.PER_PAYLOAD_OVERHEAD_BYTE_COUNT); + assertTrue(uploaderMeta.getRecordCount() == 0); + + assertFalse(uploaderMeta.addAndEstimateIfFull(1)); + + assertTrue(uploaderMeta.getByteCount() == (1 + BatchingUploader.PER_PAYLOAD_OVERHEAD_BYTE_COUNT)); + assertTrue(uploaderMeta.getRecordCount() == 1); + + assertFalse(uploaderMeta.addAndEstimateIfFull(1)); + assertFalse(uploaderMeta.addAndEstimateIfFull(1)); + assertFalse(uploaderMeta.addAndEstimateIfFull(1)); + + assertTrue(uploaderMeta.getByteCount() == (4 + BatchingUploader.PER_PAYLOAD_OVERHEAD_BYTE_COUNT)); + assertTrue(uploaderMeta.getRecordCount() == 4); + + assertTrue(uploaderMeta.addAndEstimateIfFull(1)); + + try { + assertTrue(uploaderMeta.addAndEstimateIfFull(1)); + fail("BatchMeta should not let us insert records that won't fit"); + } catch (IllegalStateException e) { + assertTrue(true); + } + } +} \ No newline at end of file From d5f4f05f70e1ddeeaf64e0f3c8bf5426aea60bb8 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Wed, 22 Feb 2017 11:18:59 -0500 Subject: [PATCH 047/234] Bug 1341668. Reenable various stylo dom reftests. r=bholley MozReview-Commit-ID: DP6KuAxGLsN --HG-- extra : rebase_source : 8ffc39f5486e3ae2e2cbed12006d0a76bb746856 --- dom/encoding/test/reftest/reftest-stylo.list | 4 +-- dom/html/reftests/reftest-stylo.list | 33 ++++++++++---------- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/dom/encoding/test/reftest/reftest-stylo.list b/dom/encoding/test/reftest/reftest-stylo.list index 229f6d5ffd5b..56d0b6c2ad92 100644 --- a/dom/encoding/test/reftest/reftest-stylo.list +++ b/dom/encoding/test/reftest/reftest-stylo.list @@ -1,6 +1,6 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing -# == bug863728-1.html bug863728-1.html +== bug863728-1.html bug863728-1.html == bug863728-2.html bug863728-2.html == bug863728-3.html bug863728-3.html -# == bug945215-1.html bug945215-1.html +== bug945215-1.html bug945215-1.html == bug945215-2.html bug945215-2.html diff --git a/dom/html/reftests/reftest-stylo.list b/dom/html/reftests/reftest-stylo.list index f2e3ff161d06..252eea833a63 100644 --- a/dom/html/reftests/reftest-stylo.list +++ b/dom/html/reftests/reftest-stylo.list @@ -6,17 +6,16 @@ include toblob-todataurl/reftest-stylo.list fails == 41464-1a.html 41464-1a.html fails == 41464-1b.html 41464-1b.html fails == 52019-1.html 52019-1.html -fails == 82711-1.html 82711-1.html +fails == 82711-1.html 82711-1.html # Bug 1341637 fails == 82711-2.html 82711-2.html -# == 82711-1-ref.html 82711-1-ref.html +fails == 82711-1-ref.html 82711-1-ref.html == 468263-1a.html 468263-1a.html == 468263-1b.html 468263-1b.html == 468263-1c.html 468263-1c.html -# == 468263-1d.html 468263-1d.html -# == 468263-2.html 468263-2.html -# == 468263-2.html 468263-2.html +== 468263-1d.html 468263-1d.html +fails == 468263-2.html 468263-2.html # Bug 1341642 fails == 484200-1.html 484200-1.html -# == 485377.html 485377.html +== 485377.html 485377.html == 557840.html 557840.html == 560059-video-dimensions.html 560059-video-dimensions.html fails == 573322-quirks.html 573322-quirks.html @@ -27,16 +26,16 @@ fails == 596455-2a.html 596455-2a.html fails == 596455-2b.html 596455-2b.html fails == 610935.html 610935.html == 649134-1.html 649134-1.html -# == 649134-2.html 649134-2.html +== 649134-2.html 649134-2.html fails == 741776-1.vtt 741776-1.vtt -# == bug448564-1_malformed.html bug448564-1_malformed.html -# == bug448564-1_malformed.html bug448564-1_malformed.html +== bug448564-1_malformed.html bug448564-1_malformed.html +== bug448564-1_malformed.html bug448564-1_malformed.html -# == bug448564-4a.html bug448564-4a.html -# == bug502168-1_malformed.html bug502168-1_malformed.html +== bug448564-4a.html bug448564-4a.html +== bug502168-1_malformed.html bug502168-1_malformed.html -# == responsive-image-load-shortcircuit.html responsive-image-load-shortcircuit.html +fails == responsive-image-load-shortcircuit.html responsive-image-load-shortcircuit.html == image-load-shortcircuit-1.html image-load-shortcircuit-1.html == image-load-shortcircuit-2.html image-load-shortcircuit-2.html @@ -44,7 +43,7 @@ fails == 741776-1.vtt 741776-1.vtt # image-orientation when determining the size of the image. # (Fuzzy necessary due to pixel-wise comparison of different JPEGs. # The vast majority of the fuzziness comes from Linux and WinXP.) -# == bug917595-iframe-1.html bug917595-iframe-1.html +fails == bug917595-iframe-1.html bug917595-iframe-1.html # Bug 1341647 fails == bug917595-exif-rotated.jpg bug917595-exif-rotated.jpg # Test support for SVG-as-image in elements. @@ -52,11 +51,11 @@ fails == bug917595-exif-rotated.jpg bug917595-exif-rotated.jpg == bug1106522-2.html bug1106522-2.html fails == href-attr-change-restyles.html href-attr-change-restyles.html -# == figure.html figure.html +== figure.html figure.html fails == pre-1.html pre-1.html -# == table-border-1.html table-border-1.html -# == table-border-2.html table-border-2.html -# == table-border-2.html table-border-2.html +fails == table-border-1.html table-border-1.html # Bug 1341651 +== table-border-2.html table-border-2.html +== table-border-2.html table-border-2.html # Test imageset is using permissions.default.image # pref(permissions.default.image,1) HTTP == bug1196784-with-srcset.html bug1196784-with-srcset.html From 2d64aff307b44415ac2ff6e49df5c489404fb594 Mon Sep 17 00:00:00 2001 From: Jan Henning Date: Sun, 19 Feb 2017 15:05:39 +0100 Subject: [PATCH 048/234] Bug 1340875 - Send the URL and title of the history entry that was actually open when the tab was closed. r=sebastian Currently, Recently Closed is displaying the last available history entry for each closed tab instead of the history entry that was actually being shown at the time the tab was closed. The Java session parser that is responsible for displaying the last session's tabs when not automatically restoring is already doing the correct thing and therefore doesn't need changing. MozReview-Commit-ID: DGaD52SzdpP --HG-- extra : rebase_source : 0f11b32d3d8f1061681706272b62dfb090e8e598 --- mobile/android/components/SessionStore.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mobile/android/components/SessionStore.js b/mobile/android/components/SessionStore.js index f997bd98b4f7..f5be202bbdf4 100644 --- a/mobile/android/components/SessionStore.js +++ b/mobile/android/components/SessionStore.js @@ -1766,11 +1766,11 @@ SessionStore.prototype = { let tabs = closedTabs .filter(tab => tab.isPrivate == isPrivate) .map(function (tab) { - // Get the url and title for the last entry in the session history. - let lastEntry = tab.entries[tab.entries.length - 1]; + // Get the url and title for the current entry in the session history. + let entry = tab.entries[tab.index - 1]; return { - url: lastEntry.url, - title: lastEntry.title || "", + url: entry.url, + title: entry.title || "", data: JSON.stringify(tab), }; }); From 74cac7296d5036600300b44dc6275fb190f4955d Mon Sep 17 00:00:00 2001 From: Aaron Klotz Date: Fri, 10 Feb 2017 11:18:26 -0700 Subject: [PATCH 049/234] Bug 1338596: Add support for agile references to mscom; r=jimm MozReview-Commit-ID: 1NZoFZntO3g --HG-- extra : rebase_source : 6d3ed1da4893747d38c1bd2c31671d8ecf535cfd --- ipc/mscom/AgileReference.cpp | 152 +++++++++++++++++++++++ ipc/mscom/AgileReference.h | 67 ++++++++++ ipc/mscom/DynamicallyLinkedFunctionPtr.h | 9 +- ipc/mscom/moz.build | 6 +- 4 files changed, 231 insertions(+), 3 deletions(-) create mode 100644 ipc/mscom/AgileReference.cpp create mode 100644 ipc/mscom/AgileReference.h diff --git a/ipc/mscom/AgileReference.cpp b/ipc/mscom/AgileReference.cpp new file mode 100644 index 000000000000..a7eb791148a2 --- /dev/null +++ b/ipc/mscom/AgileReference.cpp @@ -0,0 +1,152 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/mscom/AgileReference.h" + +#include "DynamicallyLinkedFunctionPtr.h" +#include "mozilla/DebugOnly.h" +#include "mozilla/Assertions.h" +#include "mozilla/Move.h" + +#if NTDDI_VERSION < NTDDI_WINBLUE + +// Declarations from Windows SDK specific to Windows 8.1 + +enum AgileReferenceOptions +{ + AGILEREFERENCE_DEFAULT = 0, + AGILEREFERENCE_DELAYEDMARSHAL = 1, +}; + +HRESULT WINAPI RoGetAgileReference(AgileReferenceOptions options, + REFIID riid, IUnknown* pUnk, + IAgileReference** ppAgileReference); + +#endif // NTDDI_VERSION < NTDDI_WINBLUE + +namespace mozilla { +namespace mscom { + +AgileReference::AgileReference(REFIID aIid, IUnknown* aObject) + : mIid(aIid) + , mGitCookie(0) +{ + /* + * There are two possible techniques for creating agile references. Starting + * with Windows 8.1, we may use the RoGetAgileReference API, which is faster. + * If that API is not available, we fall back to using the Global Interface + * Table. + */ + static const DynamicallyLinkedFunctionPtr + pRoGetAgileReference(L"ole32.dll", "RoGetAgileReference"); + + MOZ_ASSERT(aObject); + + if (pRoGetAgileReference && + SUCCEEDED(pRoGetAgileReference(AGILEREFERENCE_DEFAULT, aIid, aObject, + getter_AddRefs(mAgileRef)))) { + return; + } + + IGlobalInterfaceTable* git = ObtainGit(); + MOZ_ASSERT(git); + if (!git) { + return; + } + + DebugOnly hr = git->RegisterInterfaceInGlobal(aObject, aIid, + &mGitCookie); + MOZ_ASSERT(SUCCEEDED(hr)); +} + +AgileReference::AgileReference(AgileReference&& aOther) + : mIid(aOther.mIid) + , mAgileRef(Move(aOther.mAgileRef)) + , mGitCookie(aOther.mGitCookie) +{ + aOther.mGitCookie = 0; +} + +AgileReference::~AgileReference() +{ + if (!mGitCookie) { + return; + } + + IGlobalInterfaceTable* git = ObtainGit(); + MOZ_ASSERT(git); + if (!git) { + return; + } + + DebugOnly hr = git->RevokeInterfaceFromGlobal(mGitCookie); + MOZ_ASSERT(SUCCEEDED(hr)); +} + +HRESULT +AgileReference::Resolve(REFIID aIid, void** aOutInterface) +{ + MOZ_ASSERT(aOutInterface); + MOZ_ASSERT(mAgileRef || mGitCookie); + + if (!aOutInterface) { + return E_INVALIDARG; + } + + *aOutInterface = nullptr; + + if (mAgileRef) { + // IAgileReference lets you directly resolve the interface you want... + return mAgileRef->Resolve(aIid, aOutInterface); + } + + if (!mGitCookie) { + return E_UNEXPECTED; + } + + IGlobalInterfaceTable* git = ObtainGit(); + MOZ_ASSERT(git); + if (!git) { + return E_UNEXPECTED; + } + + RefPtr originalInterface; + HRESULT hr = git->GetInterfaceFromGlobal(mGitCookie, mIid, + getter_AddRefs(originalInterface)); + if (FAILED(hr)) { + return hr; + } + + if (aIid == mIid) { + originalInterface.forget(aOutInterface); + return S_OK; + } + + // ...Whereas the GIT requires us to obtain the same interface that we + // requested and then QI for the desired interface afterward. + return originalInterface->QueryInterface(aIid, aOutInterface); +} + +IGlobalInterfaceTable* +AgileReference::ObtainGit() +{ + // Internally to COM, the Global Interface Table is a singleton, therefore we + // don't worry about holding onto this reference indefinitely. + static IGlobalInterfaceTable * const sGit = []() -> IGlobalInterfaceTable * const { + IGlobalInterfaceTable* result = nullptr; + DebugOnly hr = + ::CoCreateInstance(CLSID_StdGlobalInterfaceTable, nullptr, + CLSCTX_INPROC_SERVER, IID_IGlobalInterfaceTable, + reinterpret_cast(&result)); + MOZ_ASSERT(SUCCEEDED(hr)); + return result; + }(); + + return sGit; +} + +} // namespace mscom +} // namespace mozilla diff --git a/ipc/mscom/AgileReference.h b/ipc/mscom/AgileReference.h new file mode 100644 index 000000000000..d571c1b38bd1 --- /dev/null +++ b/ipc/mscom/AgileReference.h @@ -0,0 +1,67 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_mscom_AgileReference_h +#define mozilla_mscom_AgileReference_h + +#include "mozilla/RefPtr.h" + +#include + +namespace mozilla { +namespace mscom { + +/** + * This class encapsulates an "agile reference." These are references that + * allow you to pass COM interfaces between apartments. When you have an + * interface that you would like to pass between apartments, you wrap that + * interface in an AgileReference and pass the agile reference instead. Then + * you unwrap the interface by calling AgileReference::Resolve. + * + * Sample usage: + * + * // In the multithreaded apartment, foo is an IFoo* + * auto myAgileRef = MakeUnique(IID_IFoo, foo); + * + * // myAgileRef is passed to our main thread, which runs in a single-threaded + * // apartment: + * + * RefPtr foo; + * HRESULT hr = myAgileRef->Resolve(IID_IFoo, getter_AddRefs(foo)); + * // Now foo may be called from the main thread + */ +class AgileReference +{ +public: + AgileReference(REFIID aIid, IUnknown* aObject); + AgileReference(AgileReference&& aOther); + + ~AgileReference(); + + explicit operator bool() const + { + return mAgileRef || mGitCookie; + } + + HRESULT Resolve(REFIID aIid, void** aOutInterface); + + AgileReference(const AgileReference& aOther) = delete; + AgileReference& operator=(const AgileReference& aOther) = delete; + AgileReference& operator=(AgileReference&& aOther) = delete; + +private: + IGlobalInterfaceTable* ObtainGit(); + +private: + REFIID mIid; + RefPtr mAgileRef; + DWORD mGitCookie; +}; + +} // namespace mscom +} // namespace mozilla + +#endif // mozilla_mscom_AgileReference_h diff --git a/ipc/mscom/DynamicallyLinkedFunctionPtr.h b/ipc/mscom/DynamicallyLinkedFunctionPtr.h index c774119c8148..32cd5c636d50 100644 --- a/ipc/mscom/DynamicallyLinkedFunctionPtr.h +++ b/ipc/mscom/DynamicallyLinkedFunctionPtr.h @@ -30,6 +30,13 @@ public: if (mModule) { mFunction = reinterpret_cast( ::GetProcAddress(mModule, aFuncName)); + + if (!mFunction) { + // Since the function doesn't exist, there is no point in holding a + // reference to mModule anymore. + ::FreeLibrary(mModule); + mModule = NULL; + } } } @@ -46,7 +53,7 @@ public: } } - R operator()(Args... args) + R operator()(Args... args) const { return mFunction(mozilla::Forward(args)...); } diff --git a/ipc/mscom/moz.build b/ipc/mscom/moz.build index 9a222a971359..5508fbda506b 100644 --- a/ipc/mscom/moz.build +++ b/ipc/mscom/moz.build @@ -6,6 +6,7 @@ EXPORTS.mozilla.mscom += [ 'Aggregation.h', + 'AgileReference.h', 'AsyncInvoker.h', 'COMApartmentRegion.h', 'COMPtrHolder.h', @@ -17,6 +18,7 @@ EXPORTS.mozilla.mscom += [ ] UNIFIED_SOURCES += [ + 'AgileReference.cpp', 'EnsureMTA.cpp', 'MainThreadRuntime.cpp', 'ProxyStream.cpp', @@ -58,5 +60,5 @@ include('/ipc/chromium/chromium-config.mozbuild') FINAL_LIBRARY = 'xul' -with Files("**"): - BUG_COMPONENT = ("Core", "Disability Access APIs") +with Files("**"): + BUG_COMPONENT = ("Core", "Disability Access APIs") From 2bca71e81c104dad96f914aaa554bd31758413fa Mon Sep 17 00:00:00 2001 From: Chris Pearce Date: Wed, 22 Feb 2017 10:45:22 +1300 Subject: [PATCH 050/234] Bug 1341441 - Include nsPrintfCString in GMPVideoDecoderParent.cpp. r=gerald Sometimes the build breaks because this file uses nsPrintfCString but doesn't include its header. MozReview-Commit-ID: CcawXkMucdA --HG-- extra : rebase_source : 3b36138053c1ffa557fd59af37cf1cfa4166493a --- dom/media/gmp/GMPVideoDecoderParent.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/dom/media/gmp/GMPVideoDecoderParent.cpp b/dom/media/gmp/GMPVideoDecoderParent.cpp index 792013b66169..f312f2a7cb27 100644 --- a/dom/media/gmp/GMPVideoDecoderParent.cpp +++ b/dom/media/gmp/GMPVideoDecoderParent.cpp @@ -15,6 +15,7 @@ #include "GMPContentParent.h" #include "GMPMessageUtils.h" #include "mozilla/gmp/GMPTypes.h" +#include "nsPrintfCString.h" namespace mozilla { From 0a1ee2355698c3abfa198181ec824f1c9b09872c Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Wed, 15 Feb 2017 17:40:03 -0500 Subject: [PATCH 051/234] Bug 1328065 - Record the target scroll id of scrollbar containers in the layer tree. r=mstange MozReview-Commit-ID: DoyM64JJ4N8 --HG-- extra : rebase_source : 4c31d9ce488670bb2aab32fcba8e53bba8eaa7cf --- gfx/layers/LayerAttributes.h | 5 +++-- gfx/layers/Layers.h | 6 ++++-- layout/generic/nsGfxScrollFrame.cpp | 5 ++++- layout/painting/nsDisplayList.cpp | 2 +- layout/painting/nsDisplayList.h | 7 ++----- layout/xul/nsSliderFrame.cpp | 5 ++--- 6 files changed, 16 insertions(+), 14 deletions(-) diff --git a/gfx/layers/LayerAttributes.h b/gfx/layers/LayerAttributes.h index 7fdcd23672d9..39d42e42176e 100644 --- a/gfx/layers/LayerAttributes.h +++ b/gfx/layers/LayerAttributes.h @@ -92,11 +92,12 @@ public: mScrollbarThumbRatio = aThumbRatio; return true; } - bool SetIsScrollbarContainer() { - if (mIsScrollbarContainer) { + bool SetIsScrollbarContainer(FrameMetrics::ViewID aScrollId) { + if (mIsScrollbarContainer && mScrollbarTargetContainerId == aScrollId) { return false; } mIsScrollbarContainer = true; + mScrollbarTargetContainerId = aScrollId; return true; } bool SetMixBlendMode(gfx::CompositionOp aMixBlendMode) { diff --git a/gfx/layers/Layers.h b/gfx/layers/Layers.h index 5be3b3c118ac..1af116ecd34e 100644 --- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -1297,9 +1297,11 @@ public: } // Set during construction for the container layer of scrollbar components. - void SetIsScrollbarContainer() + // |aScrollId| holds the scroll identifier of the scrollable content that + // the scrollbar is for. + void SetIsScrollbarContainer(FrameMetrics::ViewID aScrollId) { - if (mSimpleAttrs.SetIsScrollbarContainer()) { + if (mSimpleAttrs.SetIsScrollbarContainer(aScrollId)) { MutatedSimple(); } } diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index 9219796c7ca6..4f633cada5f5 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -2991,7 +2991,10 @@ AppendToTop(nsDisplayListBuilder* aBuilder, const nsDisplayListSet& aLists, uint32_t flags = (aFlags & APPEND_SCROLLBAR_CONTAINER) ? nsDisplayOwnLayer::SCROLLBAR_CONTAINER : 0; - newItem = new (aBuilder) nsDisplayOwnLayer(aBuilder, aSourceFrame, aSource, asr, flags); + FrameMetrics::ViewID scrollTarget = (aFlags & APPEND_SCROLLBAR_CONTAINER) + ? aBuilder->GetCurrentScrollbarTarget() + : FrameMetrics::NULL_SCROLL_ID; + newItem = new (aBuilder) nsDisplayOwnLayer(aBuilder, aSourceFrame, aSource, asr, flags, scrollTarget); } else { newItem = new (aBuilder) nsDisplayWrapList(aBuilder, aSourceFrame, aSource, asr); } diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp index 91434a0737d3..55ba00313a19 100644 --- a/layout/painting/nsDisplayList.cpp +++ b/layout/painting/nsDisplayList.cpp @@ -5570,7 +5570,7 @@ nsDisplayOwnLayer::BuildLayer(nsDisplayListBuilder* aBuilder, layer->SetScrollbarData(mScrollTarget, ScrollDirection::HORIZONTAL, mScrollbarThumbRatio); } if (mFlags & SCROLLBAR_CONTAINER) { - layer->SetIsScrollbarContainer(); + layer->SetIsScrollbarContainer(mScrollTarget); } if (mFlags & GENERATE_SUBDOC_INVALIDATIONS) { diff --git a/layout/painting/nsDisplayList.h b/layout/painting/nsDisplayList.h index bdc5a7154fef..4d7ecaffe48b 100644 --- a/layout/painting/nsDisplayList.h +++ b/layout/painting/nsDisplayList.h @@ -448,11 +448,8 @@ public: * Get the ViewID and the scrollbar flags corresponding to the scrollbar for * which we are building display items at the moment. */ - void GetScrollbarInfo(ViewID* aOutScrollbarTarget, uint32_t* aOutScrollbarFlags) - { - *aOutScrollbarTarget = mCurrentScrollbarTarget; - *aOutScrollbarFlags = mCurrentScrollbarFlags; - } + ViewID GetCurrentScrollbarTarget() const { return mCurrentScrollbarTarget; } + uint32_t GetCurrentScrollbarFlags() const { return mCurrentScrollbarFlags; } /** * Returns true if building a scrollbar, and the scrollbar will not be * layerized. diff --git a/layout/xul/nsSliderFrame.cpp b/layout/xul/nsSliderFrame.cpp index 8dd96f960ae4..8f18a491c6ff 100644 --- a/layout/xul/nsSliderFrame.cpp +++ b/layout/xul/nsSliderFrame.cpp @@ -355,10 +355,9 @@ nsSliderFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder, // that the event region that gets created for the thumb is included in // the nsDisplayOwnLayer contents. - uint32_t flags = 0; + uint32_t flags = aBuilder->GetCurrentScrollbarFlags(); mozilla::layers::FrameMetrics::ViewID scrollTargetId = - mozilla::layers::FrameMetrics::NULL_SCROLL_ID; - aBuilder->GetScrollbarInfo(&scrollTargetId, &flags); + aBuilder->GetCurrentScrollbarTarget(); bool thumbGetsLayer = (scrollTargetId != layers::FrameMetrics::NULL_SCROLL_ID); nsLayoutUtils::SetScrollbarThumbLayerization(thumb, thumbGetsLayer); From 0c1ff535c3882f89741e9725b7545e41d4b2d1bf Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Fri, 17 Feb 2017 15:42:30 -0500 Subject: [PATCH 052/234] Bug 1328065 - Better document scrollbar-related fields in HitTestingTreeNode. r=kats MozReview-Commit-ID: 3q3Kgs33qP0 --HG-- extra : rebase_source : ed802693e31fc5064795416a5064c4ad7fa453f3 --- gfx/layers/apz/src/HitTestingTreeNode.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gfx/layers/apz/src/HitTestingTreeNode.h b/gfx/layers/apz/src/HitTestingTreeNode.h index 0201aa575b45..4c355ff5f51e 100644 --- a/gfx/layers/apz/src/HitTestingTreeNode.h +++ b/gfx/layers/apz/src/HitTestingTreeNode.h @@ -128,9 +128,15 @@ private: uint64_t mLayersId; + // This is set for both scroll track and scroll thumb Container layers, and + // represents the scroll id of the scroll frame scrolled by the scrollbar. FrameMetrics::ViewID mScrollViewId; + + // This is set for scroll thumb Container layers only. ScrollDirection mScrollDir; int32_t mScrollThumbLength; + + // This is set for scroll track Container layers only. bool mIsScrollbarContainer; FrameMetrics::ViewID mFixedPosTarget; From dab52461add5465eecd1e33fe069993d0af4b277 Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Wed, 15 Feb 2017 17:41:40 -0500 Subject: [PATCH 053/234] Bug 1328065 - Modify APZ hit testing to target the content scrolled by the scrollbar when a scrollbar is hit. r=kats MozReview-Commit-ID: G2wMPIlUrz9 --HG-- extra : rebase_source : 346cd27d11a570aada70493c3308857b6e960b87 --- gfx/layers/apz/src/APZCTreeManager.cpp | 15 ++++++++++++--- gfx/layers/apz/src/HitTestingTreeNode.cpp | 6 ++++++ gfx/layers/apz/src/HitTestingTreeNode.h | 1 + 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/gfx/layers/apz/src/APZCTreeManager.cpp b/gfx/layers/apz/src/APZCTreeManager.cpp index 070a7a7202e1..700f5b0a8ecd 100644 --- a/gfx/layers/apz/src/APZCTreeManager.cpp +++ b/gfx/layers/apz/src/APZCTreeManager.cpp @@ -1793,11 +1793,20 @@ APZCTreeManager::GetAPZCAtPoint(HitTestingTreeNode* aNode, if (*aOutHitResult != HitNothing) { MOZ_ASSERT(resultNode); - if (aOutHitScrollbar) { - for (HitTestingTreeNode* n = resultNode; n; n = n->GetParent()) { - if (n->IsScrollbarNode()) { + for (HitTestingTreeNode* n = resultNode; n; n = n->GetParent()) { + if (n->IsScrollbarNode()) { + if (aOutHitScrollbar) { *aOutHitScrollbar = true; } + // If we hit a scrollbar, target the APZC for the content scrolled + // by the scrollbar. (The scrollbar itself doesn't scroll with the + // scrolled content, so it doesn't carry the scrolled content's + // scroll metadata). + ScrollableLayerGuid guid(n->GetLayersId(), 0, n->GetScrollTargetId()); + if (RefPtr scrollTarget = GetTargetNode(guid, &GuidComparatorIgnoringPresShell)) { + MOZ_ASSERT(scrollTarget->GetApzc()); + return scrollTarget->GetApzc(); + } } } diff --git a/gfx/layers/apz/src/HitTestingTreeNode.cpp b/gfx/layers/apz/src/HitTestingTreeNode.cpp index 4557e5054d73..8e916deeae18 100644 --- a/gfx/layers/apz/src/HitTestingTreeNode.cpp +++ b/gfx/layers/apz/src/HitTestingTreeNode.cpp @@ -128,6 +128,12 @@ HitTestingTreeNode::IsScrollbarNode() const return mIsScrollbarContainer || (mScrollDir != ScrollDirection::NONE); } +FrameMetrics::ViewID +HitTestingTreeNode::GetScrollTargetId() const +{ + return mScrollViewId; +} + void HitTestingTreeNode::SetFixedPosData(FrameMetrics::ViewID aFixedPosTarget) { diff --git a/gfx/layers/apz/src/HitTestingTreeNode.h b/gfx/layers/apz/src/HitTestingTreeNode.h index 4c355ff5f51e..628259524620 100644 --- a/gfx/layers/apz/src/HitTestingTreeNode.h +++ b/gfx/layers/apz/src/HitTestingTreeNode.h @@ -98,6 +98,7 @@ public: bool MatchesScrollDragMetrics(const AsyncDragMetrics& aDragMetrics) const; LayerIntCoord GetScrollThumbLength() const; bool IsScrollbarNode() const; + FrameMetrics::ViewID GetScrollTargetId() const; /* Fixed pos info */ From 63b193e7216edecc8c44a632614f1bad47d2a4aa Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Fri, 17 Feb 2017 15:47:51 -0500 Subject: [PATCH 054/234] Bug 1328065 - Add a pref to always layerize the scrollbar track, for test purposes. r=mstange MozReview-Commit-ID: GZY4tsdsFb4 --HG-- extra : rebase_source : e8a7aa5a1ccc813d220769bfe1c3e945e6fe81f4 --- gfx/thebes/gfxPrefs.h | 2 ++ layout/generic/nsGfxScrollFrame.cpp | 3 ++- modules/libpref/init/all.js | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/gfx/thebes/gfxPrefs.h b/gfx/thebes/gfxPrefs.h index e8bc5cce5f52..d1c58a5b6804 100644 --- a/gfx/thebes/gfxPrefs.h +++ b/gfx/thebes/gfxPrefs.h @@ -561,6 +561,8 @@ private: // This and code dependent on it should be removed once containerless scrolling looks stable. DECL_GFX_PREF(Once, "layout.scroll.root-frame-containers", LayoutUseContainersForRootFrames, bool, true); + // This pref is to be set by test code only. + DECL_GFX_PREF(Live, "layout.scrollbars.always-layerize-track", AlwaysLayerizeScrollbarTrackTestOnly, bool, false); DECL_GFX_PREF(Live, "layout.smaller-painted-layers", LayoutSmallerPaintedLayers, bool, false); DECL_GFX_PREF(Once, "media.hardware-video-decoding.force-enabled", diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index 4f633cada5f5..9ca009289a0f 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -3100,7 +3100,8 @@ ScrollFrameHelper::AppendScrollPartsTo(nsDisplayListBuilder* aBuilder, // Always create layers for overlay scrollbars so that we don't create a // giant layer covering the whole scrollport if both scrollbars are visible. bool isOverlayScrollbar = (flags != 0) && overlayScrollbars; - bool createLayer = aCreateLayer || isOverlayScrollbar; + bool createLayer = aCreateLayer || isOverlayScrollbar || + gfxPrefs::AlwaysLayerizeScrollbarTrackTestOnly(); nsDisplayListBuilder::AutoCurrentScrollbarInfoSetter infoSetter(aBuilder, scrollTargetId, flags, createLayer); diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 7cd04ddaaee6..9d6e25b89aac 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -716,6 +716,8 @@ pref("gfx.hidpi.enabled", 2); pref("layout.scroll.root-frame-containers", false); #endif +pref("layout.scrollbars.always-layerize-track", false); + // Whether to enable LayerScope tool and default listening port pref("gfx.layerscope.enabled", false); pref("gfx.layerscope.port", 23456); From 27734157c0a08f273dc78074eb9e422640b70bb7 Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Fri, 17 Feb 2017 16:40:08 -0500 Subject: [PATCH 055/234] Bug 1328065 - Add a mochitest for scrolling over the scrollbar of a subframe. r=kats MozReview-Commit-ID: 6Cna9amPCno --HG-- extra : rebase_source : c5649183c584e6dae558a9216a4120f7ab298e5b --- .../helper_scroll_over_scrollbar.html | 42 +++++++++++++++++++ gfx/layers/apz/test/mochitest/mochitest.ini | 1 + .../mochitest/test_group_wheelevents.html | 10 ++++- 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 gfx/layers/apz/test/mochitest/helper_scroll_over_scrollbar.html diff --git a/gfx/layers/apz/test/mochitest/helper_scroll_over_scrollbar.html b/gfx/layers/apz/test/mochitest/helper_scroll_over_scrollbar.html new file mode 100644 index 000000000000..cd805297b50f --- /dev/null +++ b/gfx/layers/apz/test/mochitest/helper_scroll_over_scrollbar.html @@ -0,0 +1,42 @@ + + + Wheel-scrolling over scrollbar + + + + + + + +
+
+
+ + diff --git a/gfx/layers/apz/test/mochitest/mochitest.ini b/gfx/layers/apz/test/mochitest/mochitest.ini index 09e62428ca76..5f7807fb510e 100644 --- a/gfx/layers/apz/test/mochitest/mochitest.ini +++ b/gfx/layers/apz/test/mochitest/mochitest.ini @@ -21,6 +21,7 @@ helper_scroll_inactive_perspective.html helper_scroll_inactive_zindex.html helper_scroll_on_position_fixed.html + helper_scroll_over_scrollbar.html helper_scrollto_tap.html helper_subframe_style.css helper_tall.html diff --git a/gfx/layers/apz/test/mochitest/test_group_wheelevents.html b/gfx/layers/apz/test/mochitest/test_group_wheelevents.html index 98c36f320240..9cad507eacd6 100644 --- a/gfx/layers/apz/test/mochitest/test_group_wheelevents.html +++ b/gfx/layers/apz/test/mochitest/test_group_wheelevents.html @@ -19,11 +19,19 @@ var prefs = [ ['mousewheel.transaction.timeout', 0] ] +// For helper_scroll_over_scrollbar, we need to set a pref to force +// layerization of the scrollbar track to reproduce the bug being fixed. +// Otherwise, the bug only manifests with overlay scrollbars on macOS, +// or in a XUL RCD, both of which are hard to materialize in a test. +var scrollbar_prefs = prefs.slice(); // make a copy +scrollbar_prefs.push(["layout.scrollbars.always-layerize-track", true]); + var subtests = [ {'file': 'helper_scroll_on_position_fixed.html', 'prefs': prefs}, {'file': 'helper_bug1271432.html', 'prefs': prefs}, {'file': 'helper_scroll_inactive_perspective.html', 'prefs': prefs}, - {'file': 'helper_scroll_inactive_zindex.html', 'prefs': prefs} + {'file': 'helper_scroll_inactive_zindex.html', 'prefs': prefs}, + {'file': 'helper_scroll_over_scrollbar.html', 'prefs': scrollbar_prefs} ]; if (isApzEnabled()) { From 8380e3f84879fa68f0d5ec9506d66848cee05cb7 Mon Sep 17 00:00:00 2001 From: Rail Aliiev Date: Tue, 21 Feb 2017 12:00:44 -0500 Subject: [PATCH 056/234] Bug 1337366 - SHA1 repacks configs for ESR52 r=jlund a=release DONTBUILD MozReview-Commit-ID: LM1wuXGLtn3 --HG-- rename : testing/mozharness/configs/partner_repacks/staging_release_mozilla-release_desktop.py => testing/mozharness/configs/partner_repacks/staging_release_mozilla-esr52_desktop.py extra : rebase_source : e470c6e7d0f52577e95afd730337b13b710e93d4 --- .../staging_release_mozilla-esr52_desktop.py | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 testing/mozharness/configs/partner_repacks/staging_release_mozilla-esr52_desktop.py diff --git a/testing/mozharness/configs/partner_repacks/staging_release_mozilla-esr52_desktop.py b/testing/mozharness/configs/partner_repacks/staging_release_mozilla-esr52_desktop.py new file mode 100644 index 000000000000..604407e6aa2a --- /dev/null +++ b/testing/mozharness/configs/partner_repacks/staging_release_mozilla-esr52_desktop.py @@ -0,0 +1,6 @@ +config = { + "appName": "Firefox", + "log_name": "partner_repack", + "repack_manifests_url": "https://github.com/mozilla-partners/mozilla-sha1-manifest", + "repo_file": "https://raw.githubusercontent.com/mozilla/git-repo/master/repo", +} From 65c356f7425f936e9fc23f769cb7e1c674586414 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Wed, 22 Feb 2017 15:48:57 -0500 Subject: [PATCH 057/234] Bug 1341792 - Fix 'recieve' typo. r=jdm MozReview-Commit-ID: 87XXbmboNk2 --HG-- extra : rebase_source : e9fe087a4773f56dbcfe2d7c1749fb236dca4aec --- layout/generic/nsFrame.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 37d39ba6629a..fdd6dd3aa585 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -4939,7 +4939,7 @@ nsFrame::ComputeSize(nsRenderingContext* aRenderingContext, result.ISize(aWM) = std::max(minISize, result.ISize(aWM)); // Compute block-axis size - // (but not if we have auto bsize or if we recieved the "eUseAutoBSize" + // (but not if we have auto bsize or if we received the "eUseAutoBSize" // flag -- then, we'll just stick with the bsize that we already calculated // in the initial ComputeAutoSize() call.) if (!(aFlags & nsIFrame::eUseAutoBSize)) { From ece0c71ad2ec5a9f6fc8442de9bb4f2433ec272f Mon Sep 17 00:00:00 2001 From: Sam Foster Date: Wed, 22 Feb 2017 13:06:47 -0800 Subject: [PATCH 058/234] Bug 1341793 - Fix 'recieve' typo in doccs. r=jdm MozReview-Commit-ID: 6sC3ILhC297 --HG-- extra : rebase_source : 42d4bf3cfdb8849ef333fe5d667a7baaef5bd62f --- toolkit/components/telemetry/docs/data/sync-ping.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toolkit/components/telemetry/docs/data/sync-ping.rst b/toolkit/components/telemetry/docs/data/sync-ping.rst index 1cc036b45104..d2cfd6ecd5a4 100644 --- a/toolkit/components/telemetry/docs/data/sync-ping.rst +++ b/toolkit/components/telemetry/docs/data/sync-ping.rst @@ -143,7 +143,7 @@ syncs.failureReason Stores error information, if any is present. Always contains the "name" property, which identifies the type of error it is. The types can be. -- ``httperror``: Indicates that we recieved an HTTP error response code, but are unable to be more specific about the error. Contains the following properties: +- ``httperror``: Indicates that we received an HTTP error response code, but are unable to be more specific about the error. Contains the following properties: - ``code``: Integer HTTP status code. @@ -165,7 +165,7 @@ Stores error information, if any is present. Always contains the "name" property - ``error``: The message provided by the error. -- ``sqlerror``: Indicates that we recieved a ``mozIStorageError`` from a database query. +- ``sqlerror``: Indicates that we received a ``mozIStorageError`` from a database query. - ``code``: Value of the ``error.result`` property, one of the constants listed `here `_. From 54ace62c98393bcdef4733f9897bd1879edf0adf Mon Sep 17 00:00:00 2001 From: Edouard Oger Date: Mon, 6 Feb 2017 16:31:31 -0500 Subject: [PATCH 059/234] Bug 1244622 - Add "Show More/All" (tabs) buttons in the Synced Tabs menu. r=markh MozReview-Commit-ID: 7z9fTVCDGgF --HG-- extra : rebase_source : 99afed681759d8f65605f6c11a8b0c72e8012888 --- .../customizableui/CustomizableWidgets.jsm | 61 ++++++++- .../customizableui/content/panelUI.inc.xul | 4 + .../customizableui/test/browser.ini | 2 +- ...on_sync.js => browser_synced_tabs_menu.js} | 120 +++++++++++++++--- .../locales/en-US/chrome/browser/browser.dtd | 8 ++ .../shared/customizableui/panelUI.inc.css | 6 +- services/sync/modules/SyncedTabs.jsm | 7 +- 7 files changed, 178 insertions(+), 30 deletions(-) rename browser/components/customizableui/test/{browser_967000_button_sync.js => browser_synced_tabs_menu.js} (75%) diff --git a/browser/components/customizableui/CustomizableWidgets.jsm b/browser/components/customizableui/CustomizableWidgets.jsm index 4b040872b6c8..c30defd9d5ab 100644 --- a/browser/components/customizableui/CustomizableWidgets.jsm +++ b/browser/components/customizableui/CustomizableWidgets.jsm @@ -309,6 +309,8 @@ const CustomizableWidgets = [ DECKINDEX_FETCHING: 2, DECKINDEX_NOCLIENTS: 3, }, + TABS_PER_PAGE: 25, + NEXT_PAGE_MIN_TABS: 5, // Minimum number of tabs displayed when we click "Show All" onCreated(aNode) { // Add an observer to the button so we get the animation during sync. // (Note the observer sets many attributes, including label and @@ -401,13 +403,13 @@ const CustomizableWidgets = [ _showTabsPromise: Promise.resolve(), // Update the tab list after any existing in-flight updates are complete. - _showTabs() { + _showTabs(paginationInfo) { this._showTabsPromise = this._showTabsPromise.then(() => { - return this.__showTabs(); + return this.__showTabs(paginationInfo); }); }, // Return a new promise to update the tab list. - __showTabs() { + __showTabs(paginationInfo) { let doc = this._tabsList.ownerDocument; return SyncedTabs.getTabClients().then(clients => { // The view may have been hidden while the promise was resolving. @@ -427,7 +429,7 @@ const CustomizableWidgets = [ this.setDeckIndex(this.deckIndices.DECKINDEX_TABS); this._clearTabList(); - SyncedTabs.sortTabClientsByLastUsed(clients, 50 /* maxTabs */); + SyncedTabs.sortTabClientsByLastUsed(clients); let fragment = doc.createDocumentFragment(); for (let client of clients) { @@ -436,7 +438,11 @@ const CustomizableWidgets = [ let separator = doc.createElementNS(kNSXUL, "menuseparator"); fragment.appendChild(separator); } - this._appendClient(client, fragment); + if (paginationInfo && paginationInfo.clientId == client.id) { + this._appendClient(client, fragment, paginationInfo.maxTabs); + } else { + this._appendClient(client, fragment); + } } this._tabsList.appendChild(fragment); }).catch(err => { @@ -466,7 +472,7 @@ const CustomizableWidgets = [ appendTo.appendChild(messageLabel); return messageLabel; }, - _appendClient(client, attachFragment) { + _appendClient(client, attachFragment, maxTabs = this.TABS_PER_PAGE) { let doc = attachFragment.ownerDocument; // Create the element for the remote client. let clientItem = doc.createElementNS(kNSXUL, "label"); @@ -482,10 +488,30 @@ const CustomizableWidgets = [ let label = this._appendMessageLabel("notabsforclientlabel", attachFragment); label.setAttribute("class", "PanelUI-remotetabs-notabsforclient-label"); } else { + // If this page will display all tabs, show no additional buttons. + // If the next page will display all the remaining tabs, show a "Show All" button + // Otherwise, show a "Shore More" button + let hasNextPage = client.tabs.length > maxTabs; + let nextPageIsLastPage = hasNextPage && maxTabs + this.TABS_PER_PAGE >= client.tabs.length; + if (nextPageIsLastPage) { + // When the user clicks "Show All", try to have at least NEXT_PAGE_MIN_TABS more tabs + // to display in order to avoid user frustration + maxTabs = Math.min(client.tabs.length - this.NEXT_PAGE_MIN_TABS, maxTabs); + } + if (hasNextPage) { + client.tabs = client.tabs.slice(0, maxTabs); + } for (let tab of client.tabs) { let tabEnt = this._createTabElement(doc, tab); attachFragment.appendChild(tabEnt); } + if (hasNextPage) { + let showAllEnt = this._createShowMoreElement(doc, client.id, + nextPageIsLastPage ? + Infinity : + maxTabs + this.TABS_PER_PAGE); + attachFragment.appendChild(showAllEnt); + } } }, _createTabElement(doc, tabInfo) { @@ -506,6 +532,29 @@ const CustomizableWidgets = [ }); return item; }, + _createShowMoreElement(doc, clientId, showCount) { + let labelAttr, tooltipAttr; + if (showCount === Infinity) { + labelAttr = "showAllLabel"; + tooltipAttr = "showAllTooltipText"; + } else { + labelAttr = "showMoreLabel"; + tooltipAttr = "showMoreTooltipText"; + } + let showAllItem = doc.createElementNS(kNSXUL, "toolbarbutton"); + showAllItem.setAttribute("itemtype", "showmorebutton"); + showAllItem.setAttribute("class", "subviewbutton"); + let label = this._tabsList.getAttribute(labelAttr); + showAllItem.setAttribute("label", label); + let tooltipText = this._tabsList.getAttribute(tooltipAttr); + showAllItem.setAttribute("tooltiptext", tooltipText); + showAllItem.addEventListener("click", e => { + e.preventDefault(); + e.stopPropagation(); + this._showTabs({ clientId, maxTabs: showCount }); + }); + return showAllItem; + } }, { id: "privatebrowsing-button", shortcutId: "key_privatebrowsing", diff --git a/browser/components/customizableui/content/panelUI.inc.xul b/browser/components/customizableui/content/panelUI.inc.xul index c604f6a22f4e..9753a4f52cab 100644 --- a/browser/components/customizableui/content/panelUI.inc.xul +++ b/browser/components/customizableui/content/panelUI.inc.xul @@ -125,6 +125,10 @@ diff --git a/browser/components/customizableui/test/browser.ini b/browser/components/customizableui/test/browser.ini index 1c1f30498e6a..1bdc51838698 100644 --- a/browser/components/customizableui/test/browser.ini +++ b/browser/components/customizableui/test/browser.ini @@ -100,7 +100,6 @@ skip-if = os == "linux" # Intermittent failures [browser_963639_customizing_attribute_non_customizable_toolbar.js] [browser_967000_button_charEncoding.js] [browser_967000_button_feeds.js] -[browser_967000_button_sync.js] [browser_968447_bookmarks_toolbar_items_in_panel.js] skip-if = os == "linux" # Intemittent failures - bug 979207 [browser_968565_insert_before_hidden_items.js] @@ -151,4 +150,5 @@ skip-if = os == "mac" [browser_customizemode_contextmenu_menubuttonstate.js] [browser_panel_toggle.js] [browser_switch_to_customize_mode.js] +[browser_synced_tabs_menu.js] [browser_check_tooltips_in_navbar.js] diff --git a/browser/components/customizableui/test/browser_967000_button_sync.js b/browser/components/customizableui/test/browser_synced_tabs_menu.js similarity index 75% rename from browser/components/customizableui/test/browser_967000_button_sync.js rename to browser/components/customizableui/test/browser_synced_tabs_menu.js index 7479aa70368d..2d6d4f87e88e 100644 --- a/browser/components/customizableui/test/browser_967000_button_sync.js +++ b/browser/components/customizableui/test/browser_synced_tabs_menu.js @@ -32,8 +32,8 @@ function updateTabsPanel() { // functions. let mockedInternal = { get isConfiguredToSyncTabs() { return true; }, - getTabClients() { return []; }, - syncTabs() {}, + getTabClients() { return Promise.resolve([]); }, + syncTabs() { return Promise.resolve(); }, hasSyncedThisSession: false, }; @@ -73,7 +73,9 @@ function* openPrefsFromMenuPanel(expectedPanelId, entryPoint) { let syncButton = document.getElementById("sync-button"); ok(syncButton, "The Sync button was added to the Panel Menu"); + let tabsUpdatedPromise = promiseObserverNotified("synced-tabs-menu:test:tabs-updated"); syncButton.click(); + yield tabsUpdatedPromise; let syncPanel = document.getElementById("PanelUI-remotetabs"); ok(syncPanel.getAttribute("current"), "Sync Panel is in view"); @@ -105,12 +107,16 @@ function* openPrefsFromMenuPanel(expectedPanelId, entryPoint) { ok(!isPanelUIOpen(), "The panel closed"); if (isPanelUIOpen()) { - let panelHidePromise = promisePanelHidden(window); - PanelUI.hide(); - yield panelHidePromise; + yield panelUIHide(); } } +function panelUIHide() { + let panelHidePromise = promisePanelHidden(window); + PanelUI.hide(); + return panelHidePromise; +} + function* asyncCleanup() { Services.prefs.clearUserPref("identity.fxaccounts.remote.signup.uri"); // reset the panel UI to the default state @@ -124,7 +130,12 @@ function* asyncCleanup() { } // When Sync is not setup. -add_task(() => openPrefsFromMenuPanel("PanelUI-remotetabs-setupsync", "synced-tabs")); +add_task(function* () { + document.getElementById("sync-reauth-state").hidden = true; + document.getElementById("sync-setup-state").hidden = false; + document.getElementById("sync-syncnow-state").hidden = true; + yield openPrefsFromMenuPanel("PanelUI-remotetabs-setupsync", "synced-tabs") +}); add_task(asyncCleanup); // When Sync is configured in a "needs reauthentication" state. @@ -142,9 +153,6 @@ add_task(function* () { Services.prefs.setCharPref("identity.mobilepromo.android", "http://example.com/?os=android&tail="); Services.prefs.setCharPref("identity.mobilepromo.ios", "http://example.com/?os=ios&tail="); - mockedInternal.getTabClients = () => []; - mockedInternal.syncTabs = () => Promise.resolve(); - document.getElementById("sync-reauth-state").hidden = true; document.getElementById("sync-setup-state").hidden = true; document.getElementById("sync-syncnow-state").hidden = false; @@ -190,7 +198,7 @@ add_task(function* () { ok(isPanelUIOpen(), "panel remains open after right-click"); is(gBrowser.tabs.length, 1, "no new tab was opened"); } - PanelUI.hide(); + yield panelUIHide(); Services.prefs.clearUserPref("identity.mobilepromo.android"); Services.prefs.clearUserPref("identity.mobilepromo.ios"); @@ -198,18 +206,15 @@ add_task(function* () { // Test the "Sync Now" button add_task(function* () { - mockedInternal.getTabClients = () => []; - mockedInternal.syncTabs = () => { - return Promise.resolve(); - } - // configure our broadcasters so we are in the right state. document.getElementById("sync-reauth-state").hidden = true; document.getElementById("sync-setup-state").hidden = true; document.getElementById("sync-syncnow-state").hidden = false; yield PanelUI.show(); + let tabsUpdatedPromise = promiseObserverNotified("synced-tabs-menu:test:tabs-updated"); document.getElementById("sync-button").click(); + yield tabsUpdatedPromise; let syncPanel = document.getElementById("PanelUI-remotetabs"); ok(syncPanel.getAttribute("current"), "Sync Panel is in view"); @@ -334,4 +339,89 @@ add_task(function* () { node = node.nextSibling; is(node, null, "no more entries"); + + yield panelUIHide(); +}); + +// Test the pagination capabilities (Show More/All tabs) +add_task(function* () { + mockedInternal.getTabClients = () => { + return Promise.resolve([ + { + id: "guid_desktop", + type: "client", + name: "My Desktop", + tabs: function() { + let allTabsDesktop = []; + // We choose 77 tabs, because TABS_PER_PAGE is 25, which means + // on the second to last page we should have 22 items shown + // (because we have to show at least NEXT_PAGE_MIN_TABS=5 tabs on the last page) + for (let i = 1; i <= 77; i++) { + allTabsDesktop.push({ title: "Tab #" + i }); + } + return allTabsDesktop; + }(), + } + ]); + }; + + // configure our broadcasters so we are in the right state. + document.getElementById("sync-reauth-state").hidden = true; + document.getElementById("sync-setup-state").hidden = true; + document.getElementById("sync-syncnow-state").hidden = false; + + yield PanelUI.show(); + let tabsUpdatedPromise = promiseObserverNotified("synced-tabs-menu:test:tabs-updated"); + document.getElementById("sync-button").click(); + yield tabsUpdatedPromise; + + // Check pre-conditions + let syncPanel = document.getElementById("PanelUI-remotetabs"); + ok(syncPanel.getAttribute("current"), "Sync Panel is in view"); + let subpanel = document.getElementById("PanelUI-remotetabs-main") + ok(!subpanel.hidden, "main pane is visible"); + let deck = document.getElementById("PanelUI-remotetabs-deck"); + is(deck.selectedIndex, DECKINDEX_TABS, "we should be showing tabs"); + + function checkTabsPage(tabsShownCount, showMoreLabel) { + let tabList = document.getElementById("PanelUI-remotetabs-tabslist"); + let node = tabList.firstChild; + is(node.getAttribute("itemtype"), "client", "node is a client entry"); + is(node.textContent, "My Desktop", "correct client"); + for (let i = 0; i < tabsShownCount; i++) { + node = node.nextSibling; + is(node.getAttribute("itemtype"), "tab", "node is a tab"); + is(node.getAttribute("label"), "Tab #" + (i + 1), "the tab is the correct one"); + } + let showMoreButton; + if (showMoreLabel) { + node = showMoreButton = node.nextSibling; + is(node.getAttribute("itemtype"), "showmorebutton", "node is a show more button"); + is(node.getAttribute("label"), showMoreLabel); + } + node = node.nextSibling; + is(node, null, "no more entries"); + + return showMoreButton; + } + + let showMoreButton; + function clickShowMoreButton() { + let promise = promiseObserverNotified("synced-tabs-menu:test:tabs-updated"); + showMoreButton.click(); + return promise; + } + + showMoreButton = checkTabsPage(25, "Show More"); + yield clickShowMoreButton(); + + showMoreButton = checkTabsPage(50, "Show More"); + yield clickShowMoreButton(); + + showMoreButton = checkTabsPage(72, "Show All"); + yield clickShowMoreButton(); + + checkTabsPage(77, null); + + yield panelUIHide(); }); diff --git a/browser/locales/en-US/chrome/browser/browser.dtd b/browser/locales/en-US/chrome/browser/browser.dtd index d6a467efc2d5..d3056804e967 100644 --- a/browser/locales/en-US/chrome/browser/browser.dtd +++ b/browser/locales/en-US/chrome/browser/browser.dtd @@ -358,6 +358,14 @@ These should match what Safari and other Apple applications use on OS X Lion. -- + + + + + + diff --git a/browser/themes/shared/customizableui/panelUI.inc.css b/browser/themes/shared/customizableui/panelUI.inc.css index 57e41347009c..9f2cebb0c0f8 100644 --- a/browser/themes/shared/customizableui/panelUI.inc.css +++ b/browser/themes/shared/customizableui/panelUI.inc.css @@ -1243,19 +1243,19 @@ menuitem.panel-subview-footer@menuStateActive@, color: GrayText; } -#PanelUI-remotetabs-tabslist > toolbarbutton, +#PanelUI-remotetabs-tabslist > toolbarbutton[itemtype="tab"], #PanelUI-historyItems > toolbarbutton { list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png"); } @media (min-resolution: 1.1dppx) { - #PanelUI-remotetabs-tabslist > toolbarbutton, + #PanelUI-remotetabs-tabslist > toolbarbutton[itemtype="tab"], #PanelUI-historyItems > toolbarbutton { list-style-image: url("chrome://mozapps/skin/places/defaultFavicon@2x.png"); } } -#PanelUI-remotetabs-tabslist > toolbarbutton > .toolbarbutton-icon, +#PanelUI-remotetabs-tabslist > toolbarbutton[itemtype="tab"] > .toolbarbutton-icon, #PanelUI-recentlyClosedWindows > toolbarbutton > .toolbarbutton-icon, #PanelUI-recentlyClosedTabs > toolbarbutton > .toolbarbutton-icon, #PanelUI-historyItems > toolbarbutton > .toolbarbutton-icon { diff --git a/services/sync/modules/SyncedTabs.jsm b/services/sync/modules/SyncedTabs.jsm index a8340dfe7363..7bc68f05b8d2 100644 --- a/services/sync/modules/SyncedTabs.jsm +++ b/services/sync/modules/SyncedTabs.jsm @@ -272,16 +272,13 @@ this.SyncedTabs = { return this._internal.syncTabs(force); }, - sortTabClientsByLastUsed(clients, maxTabs = Infinity) { - // First sort and filter the list of tabs for each client. Note that + sortTabClientsByLastUsed(clients) { + // First sort the list of tabs for each client. Note that // this module promises that the objects it returns are never // shared, so we are free to mutate those objects directly. for (let client of clients) { let tabs = client.tabs; tabs.sort((a, b) => b.lastUsed - a.lastUsed); - if (Number.isFinite(maxTabs)) { - client.tabs = tabs.slice(0, maxTabs); - } } // Now sort the clients - the clients are sorted in the order of the // most recent tab for that client (ie, it is important the tabs for From e648e0fb9ac59ed7ed2621c7e4750f64985d5536 Mon Sep 17 00:00:00 2001 From: Glenn Watson Date: Wed, 22 Feb 2017 10:32:52 -0800 Subject: [PATCH 060/234] servo: Merge #15681 - Update WR (inset box shadow fix, border-image support) (from glennw:update-wr-box-shadows); r=Wafflespeanut I have a follow up PR for Servo that uses the new border-image APIs, but I'll land that separately, so that we don't delay landing the WR update itself. Source-Repo: https://github.com/servo/servo Source-Revision: 800a1fde3fbda5e20c23a530085688909e9b8417 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 084b116eab04ae0278181224751dc40c389da8be --- servo/Cargo.lock | 50 ++++++++++---------- servo/components/layout/webrender_helpers.rs | 24 ++++++---- 2 files changed, 40 insertions(+), 34 deletions(-) diff --git a/servo/Cargo.lock b/servo/Cargo.lock index e6354423afb4..083c1b99f268 100644 --- a/servo/Cargo.lock +++ b/servo/Cargo.lock @@ -283,7 +283,7 @@ dependencies = [ "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", "offscreen_gl_context 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "servo_config 0.0.1", - "webrender_traits 0.16.0 (git+https://github.com/servo/webrender)", + "webrender_traits 0.18.0 (git+https://github.com/servo/webrender)", ] [[package]] @@ -297,7 +297,7 @@ dependencies = [ "ipc-channel 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", - "webrender_traits 0.16.0 (git+https://github.com/servo/webrender)", + "webrender_traits 0.18.0 (git+https://github.com/servo/webrender)", ] [[package]] @@ -418,8 +418,8 @@ dependencies = [ "servo_url 0.0.1", "style_traits 0.0.1", "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", - "webrender 0.17.0 (git+https://github.com/servo/webrender)", - "webrender_traits 0.16.0 (git+https://github.com/servo/webrender)", + "webrender 0.18.0 (git+https://github.com/servo/webrender)", + "webrender_traits 0.18.0 (git+https://github.com/servo/webrender)", ] [[package]] @@ -452,7 +452,7 @@ dependencies = [ "servo_remutex 0.0.1", "servo_url 0.0.1", "style_traits 0.0.1", - "webrender_traits 0.16.0 (git+https://github.com/servo/webrender)", + "webrender_traits 0.18.0 (git+https://github.com/servo/webrender)", "webvr_traits 0.0.1", ] @@ -672,7 +672,7 @@ dependencies = [ "servo_geometry 0.0.1", "servo_url 0.0.1", "style_traits 0.0.1", - "webrender_traits 0.16.0 (git+https://github.com/servo/webrender)", + "webrender_traits 0.18.0 (git+https://github.com/servo/webrender)", "x11 2.12.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -958,7 +958,7 @@ dependencies = [ "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", "truetype 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-script 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "webrender_traits 0.16.0 (git+https://github.com/servo/webrender)", + "webrender_traits 0.18.0 (git+https://github.com/servo/webrender)", "xi-unicode 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1037,7 +1037,7 @@ dependencies = [ "servo_url 0.0.1", "style_traits 0.0.1", "user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "webrender_traits 0.16.0 (git+https://github.com/servo/webrender)", + "webrender_traits 0.18.0 (git+https://github.com/servo/webrender)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "x11 2.12.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1339,7 +1339,7 @@ dependencies = [ "style_traits 0.0.1", "unicode-bidi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-script 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "webrender_traits 0.16.0 (git+https://github.com/servo/webrender)", + "webrender_traits 0.18.0 (git+https://github.com/servo/webrender)", ] [[package]] @@ -1379,7 +1379,7 @@ dependencies = [ "servo_geometry 0.0.1", "servo_url 0.0.1", "style 0.0.1", - "webrender_traits 0.16.0 (git+https://github.com/servo/webrender)", + "webrender_traits 0.18.0 (git+https://github.com/servo/webrender)", ] [[package]] @@ -1393,7 +1393,7 @@ dependencies = [ "profile_traits 0.0.1", "script_traits 0.0.1", "servo_url 0.0.1", - "webrender_traits 0.16.0 (git+https://github.com/servo/webrender)", + "webrender_traits 0.18.0 (git+https://github.com/servo/webrender)", ] [[package]] @@ -1478,8 +1478,8 @@ dependencies = [ "style 0.0.1", "style_traits 0.0.1", "webdriver_server 0.0.1", - "webrender 0.17.0 (git+https://github.com/servo/webrender)", - "webrender_traits 0.16.0 (git+https://github.com/servo/webrender)", + "webrender 0.18.0 (git+https://github.com/servo/webrender)", + "webrender_traits 0.18.0 (git+https://github.com/servo/webrender)", "webvr 0.0.1", "webvr_traits 0.0.1", ] @@ -1626,7 +1626,7 @@ dependencies = [ "heapsize_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", - "webrender_traits 0.16.0 (git+https://github.com/servo/webrender)", + "webrender_traits 0.18.0 (git+https://github.com/servo/webrender)", ] [[package]] @@ -1664,7 +1664,7 @@ dependencies = [ "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "webrender_traits 0.16.0 (git+https://github.com/servo/webrender)", + "webrender_traits 0.18.0 (git+https://github.com/servo/webrender)", "websocket 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1723,7 +1723,7 @@ dependencies = [ "servo_url 0.0.1", "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "webrender_traits 0.16.0 (git+https://github.com/servo/webrender)", + "webrender_traits 0.18.0 (git+https://github.com/servo/webrender)", "websocket 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2255,7 +2255,7 @@ dependencies = [ "tinyfiledialogs 2.5.9 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "webrender_traits 0.16.0 (git+https://github.com/servo/webrender)", + "webrender_traits 0.18.0 (git+https://github.com/servo/webrender)", "websocket 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)", "webvr 0.0.1", "webvr_traits 0.0.1", @@ -3167,8 +3167,8 @@ dependencies = [ [[package]] name = "webrender" -version = "0.17.0" -source = "git+https://github.com/servo/webrender#4221987984718bfc6312f92df9501d8fd7a88ea8" +version = "0.18.0" +source = "git+https://github.com/servo/webrender#e41f1413222d0b9f594649ac993a3e9e0ba35cbe" dependencies = [ "app_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "bincode 1.0.0-alpha2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3190,13 +3190,13 @@ dependencies = [ "thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "threadpool 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)", - "webrender_traits 0.16.0 (git+https://github.com/servo/webrender)", + "webrender_traits 0.18.0 (git+https://github.com/servo/webrender)", ] [[package]] name = "webrender_traits" -version = "0.16.0" -source = "git+https://github.com/servo/webrender#4221987984718bfc6312f92df9501d8fd7a88ea8" +version = "0.18.0" +source = "git+https://github.com/servo/webrender#e41f1413222d0b9f594649ac993a3e9e0ba35cbe" dependencies = [ "app_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3236,7 +3236,7 @@ dependencies = [ "msg 0.0.1", "script_traits 0.0.1", "servo_config 0.0.1", - "webrender_traits 0.16.0 (git+https://github.com/servo/webrender)", + "webrender_traits 0.18.0 (git+https://github.com/servo/webrender)", "webvr_traits 0.0.1", ] @@ -3576,8 +3576,8 @@ dependencies = [ "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff" "checksum webdriver 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cdc28802daddee94267a657ffeac2593a33881fb7a3a44fedd320b1319efcaf6" -"checksum webrender 0.17.0 (git+https://github.com/servo/webrender)" = "" -"checksum webrender_traits 0.16.0 (git+https://github.com/servo/webrender)" = "" +"checksum webrender 0.18.0 (git+https://github.com/servo/webrender)" = "" +"checksum webrender_traits 0.18.0 (git+https://github.com/servo/webrender)" = "" "checksum websocket 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4a1a6ea5ed0367f32eb3d94dcc58859ef4294b5f75ba983dbf56ac314af45d" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" diff --git a/servo/components/layout/webrender_helpers.rs b/servo/components/layout/webrender_helpers.rs index 665916594fd9..de50d3d0e7ec 100644 --- a/servo/components/layout/webrender_helpers.rs +++ b/servo/components/layout/webrender_helpers.rs @@ -270,35 +270,41 @@ impl WebRenderDisplayItemConverter for DisplayItem { } DisplayItem::Border(ref item) => { let rect = item.base.bounds.to_rectf(); + let widths = webrender_traits::BorderWidths { + left: item.border_widths.left.to_f32_px(), + top: item.border_widths.top.to_f32_px(), + right: item.border_widths.right.to_f32_px(), + bottom: item.border_widths.bottom.to_f32_px(), + }; let left = webrender_traits::BorderSide { - width: item.border_widths.left.to_f32_px(), color: item.color.left, style: item.style.left.to_border_style(), }; let top = webrender_traits::BorderSide { - width: item.border_widths.top.to_f32_px(), color: item.color.top, style: item.style.top.to_border_style(), }; let right = webrender_traits::BorderSide { - width: item.border_widths.right.to_f32_px(), color: item.color.right, style: item.style.right.to_border_style(), }; let bottom = webrender_traits::BorderSide { - width: item.border_widths.bottom.to_f32_px(), color: item.color.bottom, style: item.style.bottom.to_border_style(), }; let radius = item.radius.to_border_radius(); let clip = item.base.clip.to_clip_region(builder); + let details = webrender_traits::NormalBorder { + left: left, + top: top, + right: right, + bottom: bottom, + radius: radius, + }; builder.push_border(rect, clip, - left, - top, - right, - bottom, - radius); + widths, + webrender_traits::BorderDetails::Normal(details)); } DisplayItem::Gradient(ref item) => { let rect = item.base.bounds.to_rectf(); From 3d7955bc43dc174f5cf8b6f7dfd1e04465e8e997 Mon Sep 17 00:00:00 2001 From: Aaron Klotz Date: Fri, 17 Feb 2017 14:26:56 -0700 Subject: [PATCH 061/234] Bug 1338609: Add the ability to serialize and deserialize structs using Microsoft RPC to mscom; r=jimm MozReview-Commit-ID: CSkNYCIQYQe --HG-- extra : rebase_source : 8e357eb60adf2040d30f826b1805c35163456aa0 --- ipc/mscom/StructStream.cpp | 29 ++++ ipc/mscom/StructStream.h | 266 +++++++++++++++++++++++++++++++++++++ ipc/mscom/moz.build | 2 + 3 files changed, 297 insertions(+) create mode 100644 ipc/mscom/StructStream.cpp create mode 100644 ipc/mscom/StructStream.h diff --git a/ipc/mscom/StructStream.cpp b/ipc/mscom/StructStream.cpp new file mode 100644 index 000000000000..2640a5e0ecb6 --- /dev/null +++ b/ipc/mscom/StructStream.cpp @@ -0,0 +1,29 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include +#include + +/** + * These functions need to be defined in order for the types that use + * mozilla::mscom::StructToStream and mozilla::mscom::StructFromStream to work. + */ +extern "C" { + +void __RPC_FAR* __RPC_USER +midl_user_allocate(size_t aNumBytes) +{ + const unsigned long kRpcReqdBufAlignment = 8; + return _aligned_malloc(aNumBytes, kRpcReqdBufAlignment); +} + +void __RPC_USER +midl_user_free(void* aBuffer) +{ + _aligned_free(aBuffer); +} + +} // extern "C" diff --git a/ipc/mscom/StructStream.h b/ipc/mscom/StructStream.h new file mode 100644 index 000000000000..707567c7746e --- /dev/null +++ b/ipc/mscom/StructStream.h @@ -0,0 +1,266 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_mscom_StructStream_h +#define mozilla_mscom_StructStream_h + +#include "mozilla/Attributes.h" +#include "mozilla/UniquePtr.h" +#include "nscore.h" + +#include +#include +#include +#include + +/** + * This code is used for (de)serializing data structures that have been + * declared using midl, thus allowing us to use Microsoft RPC for marshaling + * data for our COM handlers that may run in other processes that are not ours. + */ + +namespace mozilla { +namespace mscom { + +namespace detail { + +typedef ULONG EncodedLenT; + +} // namespace detail + +class MOZ_NON_TEMPORARY_CLASS StructToStream +{ +public: + /** + * This constructor variant represents an empty/null struct to be serialized. + */ + StructToStream() + : mStatus(RPC_S_OK) + , mHandle(nullptr) + , mBuffer(nullptr) + , mEncodedLen(0) + { + } + + template + StructToStream(StructT& aSrcStruct, void (*aEncodeFnPtr)(handle_t, StructT*)) + : mStatus(RPC_X_INVALID_BUFFER) + , mHandle(nullptr) + , mBuffer(nullptr) + , mEncodedLen(0) + { + mStatus = ::MesEncodeDynBufferHandleCreate(&mBuffer, &mEncodedLen, + &mHandle); + if (mStatus != RPC_S_OK) { + return; + } + + MOZ_SEH_TRY { + aEncodeFnPtr(mHandle, &aSrcStruct); + } MOZ_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { + mStatus = ::RpcExceptionCode(); + return; + } + + if (!mBuffer || !mEncodedLen) { + mStatus = RPC_X_NO_MEMORY; + return; + } + } + + ~StructToStream() + { + if (mHandle) { + ::MesHandleFree(mHandle); + } + } + + static unsigned long GetEmptySize() + { + return sizeof(detail::EncodedLenT); + } + + static HRESULT WriteEmpty(IStream* aDestStream) + { + StructToStream emptyStruct; + return emptyStruct.Write(aDestStream); + } + + explicit operator bool() const + { + return mStatus == RPC_S_OK; + } + + bool IsEmpty() const + { + return mStatus == RPC_S_OK && !mEncodedLen; + } + + unsigned long GetSize() const + { + return sizeof(mEncodedLen) + mEncodedLen; + } + + HRESULT Write(IStream* aDestStream) + { + if (!aDestStream) { + return E_INVALIDARG; + } + if (mStatus != RPC_S_OK) { + return E_FAIL; + } + + ULONG bytesWritten; + HRESULT hr = aDestStream->Write(&mEncodedLen, sizeof(mEncodedLen), + &bytesWritten); + if (FAILED(hr)) { + return hr; + } + if (bytesWritten != sizeof(mEncodedLen)) { + return E_UNEXPECTED; + } + + if (mBuffer && mEncodedLen) { + hr = aDestStream->Write(mBuffer, mEncodedLen, &bytesWritten); + if (FAILED(hr)) { + return hr; + } + if (bytesWritten != mEncodedLen) { + return E_UNEXPECTED; + } + } + + return hr; + } + + StructToStream(const StructToStream&) = delete; + StructToStream(StructToStream&&) = delete; + StructToStream& operator=(const StructToStream&) = delete; + StructToStream& operator=(StructToStream&&) = delete; + +private: + RPC_STATUS mStatus; + handle_t mHandle; + char* mBuffer; + detail::EncodedLenT mEncodedLen; +}; + +class MOZ_NON_TEMPORARY_CLASS StructFromStream +{ + struct AlignedFreeDeleter + { + void operator()(void* aPtr) + { + ::_aligned_free(aPtr); + } + }; + + static const detail::EncodedLenT kRpcReqdBufAlignment = 8; + +public: + explicit StructFromStream(IStream* aStream) + : mStatus(RPC_X_INVALID_BUFFER) + , mHandle(nullptr) + { + MOZ_ASSERT(aStream); + + // Read the length of the encoded data first + detail::EncodedLenT encodedLen = 0; + ULONG bytesRead = 0; + HRESULT hr = aStream->Read(&encodedLen, sizeof(encodedLen), &bytesRead); + if (FAILED(hr)) { + return; + } + + // NB: Some implementations of IStream return S_FALSE to indicate EOF, + // other implementations return S_OK and set the number of bytes read to 0. + // We must handle both. + if (hr == S_FALSE || !bytesRead) { + mStatus = RPC_S_OBJECT_NOT_FOUND; + return; + } + + if (bytesRead != sizeof(encodedLen)) { + return; + } + + if (!encodedLen) { + mStatus = RPC_S_OBJECT_NOT_FOUND; + return; + } + + MOZ_ASSERT(encodedLen % kRpcReqdBufAlignment == 0); + if (encodedLen % kRpcReqdBufAlignment) { + return; + } + + // This memory allocation is fallible + mEncodedBuffer.reset(static_cast( + ::_aligned_malloc(encodedLen, kRpcReqdBufAlignment))); + if (!mEncodedBuffer) { + return; + } + + ULONG bytesReadFromStream = 0; + hr = aStream->Read(mEncodedBuffer.get(), encodedLen, &bytesReadFromStream); + if (FAILED(hr) || bytesReadFromStream != encodedLen) { + return; + } + + mStatus = ::MesDecodeBufferHandleCreate(mEncodedBuffer.get(), encodedLen, + &mHandle); + } + + ~StructFromStream() + { + if (mHandle) { + ::MesHandleFree(mHandle); + } + } + + explicit operator bool() const + { + return mStatus == RPC_S_OK || IsEmpty(); + } + + bool IsEmpty() const { return mStatus == RPC_S_OBJECT_NOT_FOUND; } + + template + bool Read(StructT* aDestStruct, void (*aDecodeFnPtr)(handle_t, StructT*)) + { + if (!aDestStruct || !aDecodeFnPtr || mStatus != RPC_S_OK) { + return false; + } + + // NB: Deserialization will fail with BSTRs unless the destination data + // is zeroed out! + ZeroMemory(aDestStruct, sizeof(StructT)); + + MOZ_SEH_TRY { + aDecodeFnPtr(mHandle, aDestStruct); + } MOZ_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { + mStatus = ::RpcExceptionCode(); + return false; + } + + return true; + } + + StructFromStream(const StructFromStream&) = delete; + StructFromStream(StructFromStream&&) = delete; + StructFromStream& operator=(const StructFromStream&) = delete; + StructFromStream& operator=(StructFromStream&&) = delete; + +private: + RPC_STATUS mStatus; + handle_t mHandle; + UniquePtr mEncodedBuffer; +}; + +} // namespace mscom +} // namespace mozilla + +#endif // mozilla_mscom_StructStream_h diff --git a/ipc/mscom/moz.build b/ipc/mscom/moz.build index 5508fbda506b..143d6371be69 100644 --- a/ipc/mscom/moz.build +++ b/ipc/mscom/moz.build @@ -34,6 +34,7 @@ if CONFIG['ACCESSIBILITY']: 'MainThreadHandoff.h', 'MainThreadInvoker.h', 'Registration.h', + 'StructStream.h', 'WeakRef.h', ] @@ -49,6 +50,7 @@ if CONFIG['ACCESSIBILITY']: 'InterceptorLog.cpp', 'MainThreadHandoff.cpp', 'MainThreadInvoker.cpp', + 'StructStream.cpp', ] LOCAL_INCLUDES += [ From dbb8cb16a7fe7f409595a7b396ee63b3ccf9bae9 Mon Sep 17 00:00:00 2001 From: Gerald Squelart Date: Tue, 21 Feb 2017 14:44:40 +1100 Subject: [PATCH 062/234] Bug 1341452 - Use MSC's __FUNCSIG__ or gcc/clang's __PRETTY_FUNCTION__ in MediaResult's RESULT_DETAIL - r=jya Since these are used in diagnostic messages intended for developers, more detailed information should help with distinguishing some issues. E.g.: Before: "Init" After: "virtual RefPtr mozilla::MP4Demuxer::Init()" MozReview-Commit-ID: TgNNn66Ilj --HG-- extra : rebase_source : 572af3a82d046bb790c4b54e13bc45451229c9e0 --- dom/media/MediaResult.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dom/media/MediaResult.h b/dom/media/MediaResult.h index bf00dae44acc..f73ef6da09db 100644 --- a/dom/media/MediaResult.h +++ b/dom/media/MediaResult.h @@ -59,7 +59,11 @@ private: nsCString mMessage; }; -#define RESULT_DETAIL(arg, ...) nsPrintfCString("%s: " arg, __func__, ##__VA_ARGS__) +#ifdef _MSC_VER +#define RESULT_DETAIL(arg, ...) nsPrintfCString("%s: " arg, __FUNCSIG__, ##__VA_ARGS__) +#else +#define RESULT_DETAIL(arg, ...) nsPrintfCString("%s: " arg, __PRETTY_FUNCTION__, ##__VA_ARGS__) +#endif } // namespace mozilla #endif // MediaResult_h_ From c76a0fb731d614dedb715faec290b22116ca898f Mon Sep 17 00:00:00 2001 From: Gerald Squelart Date: Tue, 21 Feb 2017 16:30:44 +1100 Subject: [PATCH 063/234] Bug 1341452 - Write nsresult name in MediaResult::Description() - r=jya Also only show the separator between code and message if there actually is a message. MozReview-Commit-ID: 6Cb4YnFi2fT --HG-- extra : rebase_source : 98183484972fa1c910f0e5e7fe4d46c763e97eb8 --- dom/media/MediaResult.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/dom/media/MediaResult.h b/dom/media/MediaResult.h index f73ef6da09db..a2e90af9ecd7 100644 --- a/dom/media/MediaResult.h +++ b/dom/media/MediaResult.h @@ -7,6 +7,8 @@ #ifndef MediaResult_h_ #define MediaResult_h_ +#include "nsString.h" // Required before 'mozilla/ErrorNames.h'!? +#include "mozilla/ErrorNames.h" #include "nsError.h" #include "nsPrintfCString.h" @@ -51,7 +53,13 @@ public: if (NS_SUCCEEDED(mCode)) { return nsCString(); } - return nsPrintfCString("0x%08" PRIx32 ": %s", static_cast(mCode), mMessage.get()); + nsCString name; + GetErrorName(mCode, static_cast(name)); + return nsPrintfCString("%s (0x%08" PRIx32 ")%s%s", + name.get(), + static_cast(mCode), + mMessage.IsEmpty() ? "" : " - ", + mMessage.get()); } private: From 5e50069015e390ff26b4d723f1ae312ff6577a8c Mon Sep 17 00:00:00 2001 From: Brian Birtles Date: Tue, 21 Feb 2017 13:50:43 +0900 Subject: [PATCH 064/234] Bug 1026804 - Turn on dom.event.highrestimestamp.enabled by default; r=smaug MozReview-Commit-ID: HDvzwTbERci --HG-- extra : rebase_source : 3cdb22268a905de36900d64e77440dc80875ffce --- modules/libpref/init/all.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index aa2b9309ce6d..649c6b1a60d1 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -1260,11 +1260,7 @@ pref("privacy.trackingprotection.lower_network_priority", false); pref("dom.event.contextmenu.enabled", true); pref("dom.event.clipboardevents.enabled", true); -#if defined(XP_WIN) && !defined(RELEASE_OR_BETA) || defined(MOZ_WIDGET_GTK) && !defined(RELEASE_OR_BETA) || defined(XP_MACOSX) && !defined(RELEASE_OR_BETA) || defined(MOZ_WIDGET_ANDROID) && !defined(RELEASE_OR_BETA) pref("dom.event.highrestimestamp.enabled", true); -#else -pref("dom.event.highrestimestamp.enabled", false); -#endif pref("dom.webcomponents.enabled", false); pref("dom.webcomponents.customelements.enabled", false); From 1cb166d7e98e2fb5d7ae2c5e5d080ac3e0f0f159 Mon Sep 17 00:00:00 2001 From: David Keeler Date: Wed, 22 Feb 2017 13:37:12 -0800 Subject: [PATCH 065/234] bug 1341734 - remove the disableSHA1rollout addon r=jcj MozReview-Commit-ID: 5PUT6csFK5H --HG-- extra : rebase_source : 8e7995d65421b0f2f1ff22ba83d4504a0fe97b4c --- .../extensions/disableSHA1rollout/README.md | 99 ------ .../disableSHA1rollout/bootstrap.js | 306 ------------------ .../disableSHA1rollout/install.rdf.in | 32 -- .../extensions/disableSHA1rollout/moz.build | 16 - browser/extensions/moz.build | 1 - .../talos/talos/xtalos/xperf_whitelist.json | 1 - 6 files changed, 455 deletions(-) delete mode 100644 browser/extensions/disableSHA1rollout/README.md delete mode 100644 browser/extensions/disableSHA1rollout/bootstrap.js delete mode 100644 browser/extensions/disableSHA1rollout/install.rdf.in delete mode 100644 browser/extensions/disableSHA1rollout/moz.build diff --git a/browser/extensions/disableSHA1rollout/README.md b/browser/extensions/disableSHA1rollout/README.md deleted file mode 100644 index ad9cff4b5ba7..000000000000 --- a/browser/extensions/disableSHA1rollout/README.md +++ /dev/null @@ -1,99 +0,0 @@ -This system add-on is a follow-up to the MITM prevalence experiment. The purpose -is to facilitate rolling out the disabling of SHA-1 in signatures on -certificates issued by publicly-trusted roots. When installed, this add-on will -perform a number of checks to determine if it should change the preference that -controls the SHA-1 policy. First, this should only apply to users on the beta -update channel. It should also only apply to users who have not otherwise -changed the policy to always allow or always forbid SHA-1. Additionally, it -must double-check that the user is not affected by a TLS intercepting proxy -using a publicly-trusted root. If these checks pass, the add-on will divide the -population into a test group and a control group (starting on a 10%/90% split). -The test group will have the policy changed. After doing this, a telemetry -payload is reported with the following values: - -* cohortName -- the name of the group this user is in: - 1. "notSafeToDisableSHA1" if the user is behind a MITM proxy using a - publicly-trusted root - 2. "optedOut" if the user already set the SHA-1 policy to always allow or - always forbid - 3. "optedIn" if the user already set the SHA-1 policy to only allow for - non-built-in roots - 4. "test" if the user is in the test cohort (and SHA-1 will be disabled) - 5. "control" if the user is not in the test cohort -* errorCode -- 0 for successful connections, some PR error code otherwise -* error -- a short description of one of four error conditions encountered, if - applicable, and an empty string otherwise: - 1. "timeout" if the connection to telemetry.mozilla.org timed out - 2. "user override" if the user has stored a permanent certificate exception - override for telemetry.mozilla.org (due to technical limitations, we can't - gather much information in this situation) - 3. "certificate reverification" if re-building the certificate chain after - connecting failed for some reason (unfortunately this step is necessary - due to technical limitations) - 4. "connection error" if the connection to telemetry.mozilla.org failed for - another reason -* chain -- a list of dictionaries each corresponding to a certificate in the - verified certificate chain, if it was successfully constructed. The first - entry is the end-entity certificate. The last entry is the root certificate. - This will be empty if the connection failed or if reverification failed. Each - element in the list contains the following values: - * sha256Fingerprint -- a hex string representing the SHA-256 hash of the - certificate - * isBuiltInRoot -- true if the certificate is a trust anchor in the web PKI, - false otherwise - * signatureAlgorithm -- a description of the algorithm used to sign the - certificate. Will be one of "md2WithRSAEncryption", "md5WithRSAEncryption", - "sha1WithRSAEncryption", "sha256WithRSAEncryption", - "sha384WithRSAEncryption", "sha512WithRSAEncryption", "ecdsaWithSHA1", - "ecdsaWithSHA224", "ecdsaWithSHA256", "ecdsaWithSHA384", "ecdsaWithSHA512", - or "unknown". -* disabledSHA1 -- true if SHA-1 was disabled, false otherwise -* didNotDisableSHA1Because -- a short string describing why SHA-1 could not be - disabled, if applicable. Reasons are limited to: - 1. "MITM" if the user is behind a TLS intercepting proxy using a - publicly-trusted root - 2. "connection error" if there was an error connecting to - telemetry.mozilla.org - 3. "code error" if some inconsistent state was detected, and it was - determined that the experiment should not attempt to change the - preference - 4. "preference:userReset" if the user reset the SHA-1 policy after it had - been changed by this add-on - 5. "preference:allow" if the user had already configured Firefox to always - accept SHA-1 signatures - 6. "preference:forbid" if the user had already configured Firefox to always - forbid SHA-1 signatures - -For a connection not intercepted by a TLS proxy and where the user is in the -test cohort, the expected result will be: - - { "cohortName": "test", - "errorCode": 0, - "error": "", - "chain": [ - { "sha256Fingerprint": "197feaf3faa0f0ad637a89c97cb91336bfc114b6b3018203cbd9c3d10c7fa86c", - "isBuiltInRoot": false, - "signatureAlgorithm": "sha256WithRSAEncryption" - }, - { "sha256Fingerprint": "154c433c491929c5ef686e838e323664a00e6a0d822ccc958fb4dab03e49a08f", - "isBuiltInRoot": false, - "signatureAlgorithm": "sha256WithRSAEncryption" - }, - { "sha256Fingerprint": "4348a0e9444c78cb265e058d5e8944b4d84f9662bd26db257f8934a443c70161", - "isBuiltInRoot": true, - "signatureAlgorithm": "sha1WithRSAEncryption" - } - ], - "disabledSHA1": true, - "didNotDisableSHA1Because": "" - } - -When this result is encountered, the user's preferences are updated to disable -SHA-1 in signatures on certificates issued by publicly-trusted roots. -Similarly, if the user is behind a TLS intercepting proxy but the root -certificate is not part of the public web PKI, we can also disable SHA-1 in -signatures on certificates issued by publicly-trusted roots. - -If the user has already indicated in their preferences that they will always -accept SHA-1 in signatures or that they will never accept SHA-1 in signatures, -then the preference is not changed. diff --git a/browser/extensions/disableSHA1rollout/bootstrap.js b/browser/extensions/disableSHA1rollout/bootstrap.js deleted file mode 100644 index 78419f28d336..000000000000 --- a/browser/extensions/disableSHA1rollout/bootstrap.js +++ /dev/null @@ -1,306 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu} = Components; - -Cu.import("resource://gre/modules/Preferences.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/UpdateUtils.jsm"); -Cu.import("resource://gre/modules/TelemetryController.jsm"); - - // Percentage of the population to attempt to disable SHA-1 for, by channel. -const TEST_THRESHOLD = { - beta: 0.1, // 10% -}; - -const PREF_COHORT_SAMPLE = "disableSHA1.rollout.cohortSample"; -const PREF_COHORT_NAME = "disableSHA1.rollout.cohort"; -const PREF_SHA1_POLICY = "security.pki.sha1_enforcement_level"; -const PREF_SHA1_POLICY_SET_BY_ADDON = "disableSHA1.rollout.policySetByAddOn"; -const PREF_SHA1_POLICY_RESET_BY_USER = "disableSHA1.rollout.userResetPref"; - -const SHA1_MODE_ALLOW = 0; -const SHA1_MODE_FORBID = 1; -const SHA1_MODE_IMPORTED_ROOTS_ONLY = 3; -const SHA1_MODE_CURRENT_DEFAULT = 4; - -function startup() { - Preferences.observe(PREF_SHA1_POLICY, policyPreferenceChanged); -} - -function install() { - let updateChannel = UpdateUtils.getUpdateChannel(false); - if (updateChannel in TEST_THRESHOLD) { - makeRequest().then(defineCohort).catch((e) => console.error(e)); - } -} - -function policyPreferenceChanged() { - let currentPrefValue = Preferences.get(PREF_SHA1_POLICY, - SHA1_MODE_CURRENT_DEFAULT); - Preferences.reset(PREF_SHA1_POLICY_RESET_BY_USER); - if (currentPrefValue == SHA1_MODE_CURRENT_DEFAULT) { - Preferences.set(PREF_SHA1_POLICY_RESET_BY_USER, true); - } -} - -function defineCohort(result) { - let userOptedOut = optedOut(); - let userOptedIn = optedIn(); - let shouldNotDisableSHA1Because = reasonToNotDisableSHA1(result); - let safeToDisableSHA1 = shouldNotDisableSHA1Because.length == 0; - let updateChannel = UpdateUtils.getUpdateChannel(false); - let testGroup = getUserSample() < TEST_THRESHOLD[updateChannel]; - - let cohortName; - if (!safeToDisableSHA1) { - cohortName = "notSafeToDisableSHA1"; - } else if (userOptedOut) { - cohortName = "optedOut"; - } else if (userOptedIn) { - cohortName = "optedIn"; - } else if (testGroup) { - cohortName = "test"; - Preferences.ignore(PREF_SHA1_POLICY, policyPreferenceChanged); - Preferences.set(PREF_SHA1_POLICY, SHA1_MODE_IMPORTED_ROOTS_ONLY); - Preferences.observe(PREF_SHA1_POLICY, policyPreferenceChanged); - Preferences.set(PREF_SHA1_POLICY_SET_BY_ADDON, true); - } else { - cohortName = "control"; - } - Preferences.set(PREF_COHORT_NAME, cohortName); - reportTelemetry(result, cohortName, shouldNotDisableSHA1Because, - cohortName == "test"); -} - -function shutdown(data, reason) { - Preferences.ignore(PREF_SHA1_POLICY, policyPreferenceChanged); -} - -function uninstall() { -} - -function getUserSample() { - let prefValue = Preferences.get(PREF_COHORT_SAMPLE, undefined); - let value = 0.0; - - if (typeof(prefValue) == "string") { - value = parseFloat(prefValue, 10); - return value; - } - - value = Math.random(); - - Preferences.set(PREF_COHORT_SAMPLE, value.toString().substr(0, 8)); - return value; -} - -function reportTelemetry(result, cohortName, didNotDisableSHA1Because, - disabledSHA1) { - result.cohortName = cohortName; - result.disabledSHA1 = disabledSHA1; - if (cohortName == "optedOut") { - let userResetPref = Preferences.get(PREF_SHA1_POLICY_RESET_BY_USER, false); - let currentPrefValue = Preferences.get(PREF_SHA1_POLICY, - SHA1_MODE_CURRENT_DEFAULT); - if (userResetPref) { - didNotDisableSHA1Because = "preference:userReset"; - } else if (currentPrefValue == SHA1_MODE_ALLOW) { - didNotDisableSHA1Because = "preference:allow"; - } else { - didNotDisableSHA1Because = "preference:forbid"; - } - } - result.didNotDisableSHA1Because = didNotDisableSHA1Because; - return TelemetryController.submitExternalPing("disableSHA1rollout", result, - {}); -} - -function optedIn() { - let policySetByAddOn = Preferences.get(PREF_SHA1_POLICY_SET_BY_ADDON, false); - let currentPrefValue = Preferences.get(PREF_SHA1_POLICY, - SHA1_MODE_CURRENT_DEFAULT); - return currentPrefValue == SHA1_MODE_IMPORTED_ROOTS_ONLY && !policySetByAddOn; -} - -function optedOut() { - // Users can also opt-out by setting the policy to always allow or always - // forbid SHA-1, or by resetting the preference after this add-on has changed - // it (in that case, this will be reported the next time this add-on is - // updated). - let currentPrefValue = Preferences.get(PREF_SHA1_POLICY, - SHA1_MODE_CURRENT_DEFAULT); - let userResetPref = Preferences.get(PREF_SHA1_POLICY_RESET_BY_USER, false); - return currentPrefValue == SHA1_MODE_ALLOW || - currentPrefValue == SHA1_MODE_FORBID || - userResetPref; -} - -function delocalizeAlgorithm(localizedString) { - let bundle = Services.strings.createBundle( - "chrome://pipnss/locale/pipnss.properties"); - let algorithmStringIdsToOIDDescriptionMap = { - "CertDumpMD2WithRSA": "md2WithRSAEncryption", - "CertDumpMD5WithRSA": "md5WithRSAEncryption", - "CertDumpSHA1WithRSA": "sha1WithRSAEncryption", - "CertDumpSHA256WithRSA": "sha256WithRSAEncryption", - "CertDumpSHA384WithRSA": "sha384WithRSAEncryption", - "CertDumpSHA512WithRSA": "sha512WithRSAEncryption", - "CertDumpAnsiX962ECDsaSignatureWithSha1": "ecdsaWithSHA1", - "CertDumpAnsiX962ECDsaSignatureWithSha224": "ecdsaWithSHA224", - "CertDumpAnsiX962ECDsaSignatureWithSha256": "ecdsaWithSHA256", - "CertDumpAnsiX962ECDsaSignatureWithSha384": "ecdsaWithSHA384", - "CertDumpAnsiX962ECDsaSignatureWithSha512": "ecdsaWithSHA512", - }; - - let description; - Object.keys(algorithmStringIdsToOIDDescriptionMap).forEach((l10nID) => { - let candidateLocalizedString = bundle.GetStringFromName(l10nID); - if (localizedString == candidateLocalizedString) { - description = algorithmStringIdsToOIDDescriptionMap[l10nID]; - } - }); - if (!description) { - return "unknown"; - } - return description; -} - -function getSignatureAlgorithm(cert) { - // Certificate ::= SEQUENCE { - // tbsCertificate TBSCertificate, - // signatureAlgorithm AlgorithmIdentifier, - // signatureValue BIT STRING } - let certificate = cert.ASN1Structure.QueryInterface(Ci.nsIASN1Sequence); - let signatureAlgorithm = certificate.ASN1Objects - .queryElementAt(1, Ci.nsIASN1Sequence); - // AlgorithmIdentifier ::= SEQUENCE { - // algorithm OBJECT IDENTIFIER, - // parameters ANY DEFINED BY algorithm OPTIONAL } - - // If parameters is NULL (or empty), signatureAlgorithm won't be a container - // under this implementation. Just get its displayValue. - if (!signatureAlgorithm.isValidContainer) { - return signatureAlgorithm.displayValue; - } - let oid = signatureAlgorithm.ASN1Objects.queryElementAt(0, Ci.nsIASN1Object); - return oid.displayValue; -} - -function processCertChain(chain) { - let output = []; - let enumerator = chain.getEnumerator(); - while (enumerator.hasMoreElements()) { - let cert = enumerator.getNext().QueryInterface(Ci.nsIX509Cert); - output.push({ - sha256Fingerprint: cert.sha256Fingerprint.replace(/:/g, "").toLowerCase(), - isBuiltInRoot: cert.isBuiltInRoot, - signatureAlgorithm: delocalizeAlgorithm(getSignatureAlgorithm(cert)), - }); - } - return output; -} - -class CertificateVerificationResult { - constructor(resolve) { - this.resolve = resolve; - } - - verifyCertFinished(aPRErrorCode, aVerifiedChain, aEVStatus) { - let result = { errorCode: aPRErrorCode, error: "", chain: [] }; - if (aPRErrorCode == 0) { - result.chain = processCertChain(aVerifiedChain); - } else { - result.error = "certificate reverification"; - } - this.resolve(result); - } -} - -function makeRequest() { - return new Promise((resolve) => { - let hostname = "telemetry.mozilla.org"; - let req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"] - .createInstance(Ci.nsIXMLHttpRequest); - req.open("GET", "https://" + hostname); - req.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE; - req.timeout = 30000; - req.addEventListener("error", (evt) => { - // If we can't connect to telemetry.mozilla.org, then how did we even - // download the experiment? In any case, we may still be able to get some - // information. - let result = { error: "connection error" }; - if (evt.target.channel && evt.target.channel.securityInfo) { - let securityInfo = evt.target.channel.securityInfo - .QueryInterface(Ci.nsITransportSecurityInfo); - if (securityInfo) { - result.errorCode = securityInfo.errorCode; - } - if (securityInfo && securityInfo.failedCertChain) { - result.chain = processCertChain(securityInfo.failedCertChain); - } - } - resolve(result); - }); - req.addEventListener("timeout", (evt) => { - resolve({ error: "timeout" }); - }); - req.addEventListener("load", (evt) => { - let securityInfo = evt.target.channel.securityInfo - .QueryInterface(Ci.nsITransportSecurityInfo); - if (securityInfo.securityState & - Ci.nsIWebProgressListener.STATE_CERT_USER_OVERRIDDEN) { - resolve({ error: "user override" }); - return; - } - let sslStatus = securityInfo.QueryInterface(Ci.nsISSLStatusProvider) - .SSLStatus; - let certdb = Cc["@mozilla.org/security/x509certdb;1"] - .getService(Ci.nsIX509CertDB); - let result = new CertificateVerificationResult(resolve); - // Unfortunately, we don't have direct access to the verified certificate - // chain as built by the AuthCertificate hook, so we have to re-build it - // here. In theory we are likely to get the same result. - certdb.asyncVerifyCertAtTime(sslStatus.serverCert, - 2, // certificateUsageSSLServer - 0, // flags - hostname, - Date.now() / 1000, - result); - }); - req.send(); - }); -} - -// As best we know, it is safe to disable SHA1 if the connection was successful -// and either the connection was MITM'd by a root not in the public PKI or the -// chain is part of the public PKI and is the one served by the real -// telemetry.mozilla.org. -// This will return a short string description of why it might not be safe to -// disable SHA1 or an empty string if it is safe to disable SHA1. -function reasonToNotDisableSHA1(result) { - if (!("errorCode" in result) || result.errorCode != 0) { - return "connection error"; - } - if (!("chain" in result)) { - return "code error"; - } - if (!result.chain[result.chain.length - 1].isBuiltInRoot) { - return ""; - } - if (result.chain.length != 3) { - return "MITM"; - } - const kEndEntityFingerprint = "197feaf3faa0f0ad637a89c97cb91336bfc114b6b3018203cbd9c3d10c7fa86c"; - const kIntermediateFingerprint = "154c433c491929c5ef686e838e323664a00e6a0d822ccc958fb4dab03e49a08f"; - const kRootFingerprint = "4348a0e9444c78cb265e058d5e8944b4d84f9662bd26db257f8934a443c70161"; - if (result.chain[0].sha256Fingerprint != kEndEntityFingerprint || - result.chain[1].sha256Fingerprint != kIntermediateFingerprint || - result.chain[2].sha256Fingerprint != kRootFingerprint) { - return "MITM"; - } - return ""; -} diff --git a/browser/extensions/disableSHA1rollout/install.rdf.in b/browser/extensions/disableSHA1rollout/install.rdf.in deleted file mode 100644 index 0caf0604e65b..000000000000 --- a/browser/extensions/disableSHA1rollout/install.rdf.in +++ /dev/null @@ -1,32 +0,0 @@ - - - -#filter substitution - - - - - disableSHA1rollout@mozilla.org - 1.0 - 2 - true - true - - - - - {ec8030f7-c20a-464f-9b0e-13a3a9e97384} - @MOZ_APP_VERSION@ - @MOZ_APP_MAXVERSION@ - - - - - SHA-1 deprecation staged rollout - Staged rollout deprecating SHA-1 in certificate signatures. - - diff --git a/browser/extensions/disableSHA1rollout/moz.build b/browser/extensions/disableSHA1rollout/moz.build deleted file mode 100644 index 202690cf341d..000000000000 --- a/browser/extensions/disableSHA1rollout/moz.build +++ /dev/null @@ -1,16 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION'] -DEFINES['MOZ_APP_MAXVERSION'] = CONFIG['MOZ_APP_MAXVERSION'] - -FINAL_TARGET_FILES.features['disableSHA1rollout@mozilla.org'] += [ - 'bootstrap.js' -] - -FINAL_TARGET_PP_FILES.features['disableSHA1rollout@mozilla.org'] += [ - 'install.rdf.in' -] diff --git a/browser/extensions/moz.build b/browser/extensions/moz.build index 31968a41d23b..b976dcdd0591 100644 --- a/browser/extensions/moz.build +++ b/browser/extensions/moz.build @@ -6,7 +6,6 @@ DIRS += [ 'aushelper', - 'disableSHA1rollout', 'e10srollout', 'pdfjs', 'pocket', diff --git a/testing/talos/talos/xtalos/xperf_whitelist.json b/testing/talos/talos/xtalos/xperf_whitelist.json index 91d18c5fdf42..e77b4bf61599 100644 --- a/testing/talos/talos/xtalos/xperf_whitelist.json +++ b/testing/talos/talos/xtalos/xperf_whitelist.json @@ -7,7 +7,6 @@ "{firefox}\\omni.ja": {"mincount": 0, "maxcount": 46, "minbytes": 0, "maxbytes": 3014656}, "{firefox}\\browser\\omni.ja": {"mincount": 0, "maxcount": 28, "minbytes": 0, "maxbytes": 1835008}, "{firefox}\\browser\\features\\aushelper@mozilla.org.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000}, - "{firefox}\\browser\\features\\disableSHA1rollout@mozilla.org.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000}, "{firefox}\\browser\\features\\e10srollout@mozilla.org.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000}, "{firefox}\\browser\\features\\flyweb@mozilla.org.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000}, "{firefox}\\browser\\features\\formautofill@mozilla.org.xpi": {"mincount": 0, "maxcount": 100, "minbytes": 0, "maxbytes": 10000000}, From da079e7d013bdc23cacf5da6502932bf9f22b0f5 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Wed, 22 Feb 2017 15:58:35 -0800 Subject: [PATCH 066/234] servo: Merge #15682 - Simplify defining arc ffi types (from upsuper:arc-types); r=Manishearth r? @Manishearth I don't have a good sense for creating syntax... so if you have any suggestion for the syntax of `impl_arc_ffi` macro, it would be appreciated. Source-Repo: https://github.com/servo/servo Source-Revision: af292c4a7180a35c632b16a4fb0aff9ae2933f77 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 5be76e20de735b8762a89b5e3ef88ded550ad81a --- servo/components/style/gecko/arc_types.rs | 58 +++++++++++++++ servo/components/style/gecko/conversions.rs | 37 +--------- servo/components/style/gecko/mod.rs | 1 + .../helpers/animated_properties.mako.rs | 11 --- servo/ports/geckolib/glue.rs | 71 ------------------- servo/tests/unit/stylo/check_bindings.py | 1 + 6 files changed, 61 insertions(+), 118 deletions(-) create mode 100644 servo/components/style/gecko/arc_types.rs diff --git a/servo/components/style/gecko/arc_types.rs b/servo/components/style/gecko/arc_types.rs new file mode 100644 index 000000000000..72f044c1c71e --- /dev/null +++ b/servo/components/style/gecko/arc_types.rs @@ -0,0 +1,58 @@ +/* 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/. */ + +//! This file lists all arc FFI types and defines corresponding addref +//! and release functions. This list corresponds to ServoArcTypeList.h +//! file in Gecko. + +#![allow(non_snake_case, missing_docs)] + +use gecko_bindings::bindings::{RawServoStyleSheet, RawServoStyleRule, RawServoImportRule}; +use gecko_bindings::bindings::{ServoComputedValues, ServoCssRules}; +use gecko_bindings::structs::{RawServoAnimationValue, RawServoDeclarationBlock}; +use gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI}; +use parking_lot::RwLock; +use properties::{ComputedValues, PropertyDeclarationBlock}; +use properties::animated_properties::AnimationValue; +use stylesheets::{CssRules, Stylesheet, StyleRule, ImportRule}; + +macro_rules! impl_arc_ffi { + ($servo_type:ty => $gecko_type:ty [$addref:ident, $release:ident]) => { + unsafe impl HasFFI for $servo_type { + type FFIType = $gecko_type; + } + unsafe impl HasArcFFI for $servo_type {} + + #[no_mangle] + pub unsafe extern "C" fn $addref(obj: &$gecko_type) -> () { + <$servo_type>::addref(obj); + } + + #[no_mangle] + pub unsafe extern "C" fn $release(obj: &$gecko_type) -> () { + <$servo_type>::release(obj); + } + } +} + +impl_arc_ffi!(RwLock => ServoCssRules + [Servo_CssRules_AddRef, Servo_CssRules_Release]); + +impl_arc_ffi!(Stylesheet => RawServoStyleSheet + [Servo_StyleSheet_AddRef, Servo_StyleSheet_Release]); + +impl_arc_ffi!(ComputedValues => ServoComputedValues + [Servo_ComputedValues_AddRef, Servo_ComputedValues_Release]); + +impl_arc_ffi!(RwLock => RawServoDeclarationBlock + [Servo_DeclarationBlock_AddRef, Servo_DeclarationBlock_Release]); + +impl_arc_ffi!(RwLock => RawServoStyleRule + [Servo_StyleRule_AddRef, Servo_StyleRule_Release]); + +impl_arc_ffi!(RwLock => RawServoImportRule + [Servo_ImportRule_AddRef, Servo_ImportRule_Release]); + +impl_arc_ffi!(AnimationValue => RawServoAnimationValue + [Servo_AnimationValue_AddRef, Servo_AnimationValue_Release]); diff --git a/servo/components/style/gecko/conversions.rs b/servo/components/style/gecko/conversions.rs index 7262a2f7f85b..a88d7c66d952 100644 --- a/servo/components/style/gecko/conversions.rs +++ b/servo/components/style/gecko/conversions.rs @@ -11,47 +11,12 @@ use app_units::Au; use gecko::values::convert_rgba_to_nscolor; use gecko_bindings::bindings::{Gecko_CreateGradient, Gecko_SetGradientImageValue, Gecko_SetUrlImageValue}; -use gecko_bindings::bindings::{RawServoStyleSheet, RawServoStyleRule, RawServoImportRule}; -use gecko_bindings::bindings::{ServoComputedValues, ServoCssRules}; use gecko_bindings::structs::{nsStyleCoord_CalcValue, nsStyleImage}; -use gecko_bindings::structs::RawServoDeclarationBlock; use gecko_bindings::structs::nsresult; use gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordDataMut}; -use gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI}; -use parking_lot::RwLock; -use properties::{ComputedValues, PropertyDeclarationBlock}; -use stylesheets::{CssRules, RulesMutateError, Stylesheet, StyleRule, ImportRule}; +use stylesheets::RulesMutateError; use values::computed::{CalcLengthOrPercentage, Gradient, Image, LengthOrPercentage, LengthOrPercentageOrAuto}; -unsafe impl HasFFI for Stylesheet { - type FFIType = RawServoStyleSheet; -} -unsafe impl HasArcFFI for Stylesheet {} -unsafe impl HasFFI for ComputedValues { - type FFIType = ServoComputedValues; -} -unsafe impl HasArcFFI for ComputedValues {} - -unsafe impl HasFFI for RwLock { - type FFIType = RawServoDeclarationBlock; -} -unsafe impl HasArcFFI for RwLock {} - -unsafe impl HasFFI for RwLock { - type FFIType = ServoCssRules; -} -unsafe impl HasArcFFI for RwLock {} - -unsafe impl HasFFI for RwLock { - type FFIType = RawServoStyleRule; -} -unsafe impl HasArcFFI for RwLock {} - -unsafe impl HasFFI for RwLock { - type FFIType = RawServoImportRule; -} -unsafe impl HasArcFFI for RwLock {} - impl From for nsStyleCoord_CalcValue { fn from(other: CalcLengthOrPercentage) -> nsStyleCoord_CalcValue { let has_percentage = other.percentage.is_some(); diff --git a/servo/components/style/gecko/mod.rs b/servo/components/style/gecko/mod.rs index ca87d081ef7e..625fa77bbfd3 100644 --- a/servo/components/style/gecko/mod.rs +++ b/servo/components/style/gecko/mod.rs @@ -4,6 +4,7 @@ //! Gecko-specific style-system bits. +pub mod arc_types; pub mod conversions; pub mod data; pub mod media_queries; diff --git a/servo/components/style/properties/helpers/animated_properties.mako.rs b/servo/components/style/properties/helpers/animated_properties.mako.rs index 8001e9457a6d..0c2b59eb2dab 100644 --- a/servo/components/style/properties/helpers/animated_properties.mako.rs +++ b/servo/components/style/properties/helpers/animated_properties.mako.rs @@ -232,17 +232,6 @@ impl AnimatedProperty { } } - -% if product == "gecko": - use gecko_bindings::structs::RawServoAnimationValue; - use gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI}; - - unsafe impl HasFFI for AnimationValue { - type FFIType = RawServoAnimationValue; - } - unsafe impl HasArcFFI for AnimationValue {} -% endif - /// An enum to represent a single computed value belonging to an animated /// property in order to be interpolated with another one. When interpolating, /// both values need to belong to the same property. diff --git a/servo/ports/geckolib/glue.rs b/servo/ports/geckolib/glue.rs index c7e6ede116f7..c7fb870706fb 100644 --- a/servo/ports/geckolib/glue.rs +++ b/servo/ports/geckolib/glue.rs @@ -332,17 +332,6 @@ pub extern "C" fn Servo_AnimationValues_Populate(anim: RawGeckoAnimationValueLis } } - -#[no_mangle] -pub extern "C" fn Servo_AnimationValue_AddRef(anim: RawServoAnimationValueBorrowed) -> () { - unsafe { AnimationValue::addref(anim) }; -} - -#[no_mangle] -pub extern "C" fn Servo_AnimationValue_Release(anim: RawServoAnimationValueBorrowed) -> () { - unsafe { AnimationValue::release(anim) }; -} - #[no_mangle] pub extern "C" fn Servo_StyleWorkerThreadCount() -> u32 { *NUM_THREADS as u32 @@ -530,16 +519,6 @@ pub extern "C" fn Servo_StyleSheet_GetRules(sheet: RawServoStyleSheetBorrowed) - Stylesheet::as_arc(&sheet).rules.clone().into_strong() } -#[no_mangle] -pub extern "C" fn Servo_StyleSheet_AddRef(sheet: RawServoStyleSheetBorrowed) -> () { - unsafe { Stylesheet::addref(sheet) }; -} - -#[no_mangle] -pub extern "C" fn Servo_StyleSheet_Release(sheet: RawServoStyleSheetBorrowed) -> () { - unsafe { Stylesheet::release(sheet) }; -} - #[no_mangle] pub extern "C" fn Servo_CssRules_ListTypes(rules: ServoCssRulesBorrowed, result: nsTArrayBorrowed_uintptr_t) -> () { @@ -588,26 +567,6 @@ pub extern "C" fn Servo_CssRules_DeleteRule(rules: ServoCssRulesBorrowed, index: } } -#[no_mangle] -pub extern "C" fn Servo_CssRules_AddRef(rules: ServoCssRulesBorrowed) -> () { - unsafe { RwLock::::addref(rules) }; -} - -#[no_mangle] -pub extern "C" fn Servo_CssRules_Release(rules: ServoCssRulesBorrowed) -> () { - unsafe { RwLock::::release(rules) }; -} - -#[no_mangle] -pub extern "C" fn Servo_StyleRule_AddRef(rule: RawServoStyleRuleBorrowed) -> () { - unsafe { RwLock::::addref(rule) }; -} - -#[no_mangle] -pub extern "C" fn Servo_StyleRule_Release(rule: RawServoStyleRuleBorrowed) -> () { - unsafe { RwLock::::release(rule) }; -} - #[no_mangle] pub extern "C" fn Servo_StyleRule_Debug(rule: RawServoStyleRuleBorrowed, result: *mut nsACString) -> () { let rule = RwLock::::as_arc(&rule); @@ -641,16 +600,6 @@ pub extern "C" fn Servo_StyleRule_GetSelectorText(rule: RawServoStyleRuleBorrowe rule.read().selectors.to_css(unsafe { result.as_mut().unwrap() }).unwrap(); } -#[no_mangle] -pub extern "C" fn Servo_ImportRule_AddRef(rule: RawServoImportRuleBorrowed) -> () { - unsafe { RwLock::::addref(rule) }; -} - -#[no_mangle] -pub extern "C" fn Servo_ImportRule_Release(rule: RawServoImportRuleBorrowed) -> () { - unsafe { RwLock::::release(rule) }; -} - #[no_mangle] pub extern "C" fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null: ServoComputedValuesBorrowedOrNull, pseudo_tag: *mut nsIAtom, @@ -727,16 +676,6 @@ pub extern "C" fn Servo_ComputedValues_Inherit( style.into_strong() } -#[no_mangle] -pub extern "C" fn Servo_ComputedValues_AddRef(ptr: ServoComputedValuesBorrowed) { - unsafe { ComputedValues::addref(ptr) }; -} - -#[no_mangle] -pub extern "C" fn Servo_ComputedValues_Release(ptr: ServoComputedValuesBorrowed) { - unsafe { ComputedValues::release(ptr) }; -} - /// See the comment in `Device` to see why it's ok to pass an owned reference to /// the pres context (hint: the context outlives the StyleSet, that holds the /// device alive). @@ -814,16 +753,6 @@ pub extern "C" fn Servo_DeclarationBlock_Clone(declarations: RawServoDeclaration Arc::new(RwLock::new(declarations.read().clone())).into_strong() } -#[no_mangle] -pub extern "C" fn Servo_DeclarationBlock_AddRef(declarations: RawServoDeclarationBlockBorrowed) { - unsafe { RwLock::::addref(declarations) }; -} - -#[no_mangle] -pub extern "C" fn Servo_DeclarationBlock_Release(declarations: RawServoDeclarationBlockBorrowed) { - unsafe { RwLock::::release(declarations) }; -} - #[no_mangle] pub extern "C" fn Servo_DeclarationBlock_Equals(a: RawServoDeclarationBlockBorrowed, b: RawServoDeclarationBlockBorrowed) diff --git a/servo/tests/unit/stylo/check_bindings.py b/servo/tests/unit/stylo/check_bindings.py index 28246639e57f..db5a11cc3a7e 100755 --- a/servo/tests/unit/stylo/check_bindings.py +++ b/servo/tests/unit/stylo/check_bindings.py @@ -33,5 +33,6 @@ with open(INPUT_FILE, "r") as bindings, open(OUTPUT_FILE, "w+") as tests: tests.write("}\n") with open(GLUE_FILE, "r") as glue, open(GLUE_OUTPUT_FILE, "w+") as glue_output: + glue_output.write("pub use style::gecko::arc_types::*;") for line in glue: glue_output.write(line.replace("pub extern \"C\" fn", "pub unsafe extern \"C\" fn")) From dc40936bd934a20def23f18fd629b4eaf300564a Mon Sep 17 00:00:00 2001 From: cku Date: Tue, 21 Feb 2017 00:08:38 +0800 Subject: [PATCH 067/234] Bug 1336480 - Part 1. Apply suface limitation in nsFilterInstance::ComputeNeededBoxes. r=mstange There is no need to limit output space bounds in nsFilterInstance::OutputFilterSpaceBounds(), it's just far too early. MozReview-Commit-ID: 9i9huKDGxq6 --HG-- extra : rebase_source : 3f7a16fe27f661e79087c6a302235b01f65169d5 --- layout/svg/nsFilterInstance.cpp | 30 ++++++++++++++++++++---------- layout/svg/nsSVGUtils.cpp | 2 +- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/layout/svg/nsFilterInstance.cpp b/layout/svg/nsFilterInstance.cpp index 6a061183625e..57599be44352 100644 --- a/layout/svg/nsFilterInstance.cpp +++ b/layout/svg/nsFilterInstance.cpp @@ -359,6 +359,19 @@ nsFilterInstance::BuildPrimitivesForFilter(const nsStyleFilter& aFilter, return cssFilterInstance.BuildPrimitives(mPrimitiveDescriptions, aInputIsTainted); } +static void +UpdateNeededBounds(const nsIntRegion& aRegion, nsIntRect& aBounds) +{ + aBounds = aRegion.GetBounds(); + + bool overflow; + IntSize surfaceSize = + nsSVGUtils::ConvertToSurfaceSize(aBounds.Size(), &overflow); + if (overflow) { + aBounds.SizeTo(surfaceSize); + } +} + void nsFilterInstance::ComputeNeededBoxes() { @@ -375,9 +388,9 @@ nsFilterInstance::ComputeNeededBoxes() sourceGraphicNeededRegion.And(sourceGraphicNeededRegion, mTargetBounds); - mSourceGraphic.mNeededBounds = sourceGraphicNeededRegion.GetBounds(); - mFillPaint.mNeededBounds = fillPaintNeededRegion.GetBounds(); - mStrokePaint.mNeededBounds = strokePaintNeededRegion.GetBounds(); + UpdateNeededBounds(sourceGraphicNeededRegion, mSourceGraphic.mNeededBounds); + UpdateNeededBounds(fillPaintNeededRegion, mFillPaint.mNeededBounds); + UpdateNeededBounds(strokePaintNeededRegion, mStrokePaint.mNeededBounds); } DrawResult @@ -385,6 +398,9 @@ nsFilterInstance::BuildSourcePaint(SourceInfo *aSource) { MOZ_ASSERT(mTargetFrame); nsIntRect neededRect = aSource->mNeededBounds; + if (neededRect.IsEmpty()) { + return DrawResult::SUCCESS; + } RefPtr offscreenDT = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget( @@ -575,13 +591,7 @@ nsFilterInstance::OutputFilterSpaceBounds() const if (numPrimitives <= 0) return nsIntRect(); - nsIntRect bounds = - mPrimitiveDescriptions[numPrimitives - 1].PrimitiveSubregion(); - bool overflow; - IntSize surfaceSize = - nsSVGUtils::ConvertToSurfaceSize(bounds.Size(), &overflow); - bounds.SizeTo(surfaceSize); - return bounds; + return mPrimitiveDescriptions[numPrimitives - 1].PrimitiveSubregion(); } nsIntRect diff --git a/layout/svg/nsSVGUtils.cpp b/layout/svg/nsSVGUtils.cpp index 53d39752d5c8..5bfb015dec36 100644 --- a/layout/svg/nsSVGUtils.cpp +++ b/layout/svg/nsSVGUtils.cpp @@ -1007,7 +1007,7 @@ nsSVGUtils::ConvertToSurfaceSize(const gfxSize& aSize, *aResultOverflows = surfaceSize.width != ceil(aSize.width) || surfaceSize.height != ceil(aSize.height); - if (!Factory::CheckSurfaceSize(surfaceSize)) { + if (!Factory::AllowedSurfaceSize(surfaceSize)) { surfaceSize.width = std::min(NS_SVG_OFFSCREEN_MAX_DIMENSION, surfaceSize.width); surfaceSize.height = std::min(NS_SVG_OFFSCREEN_MAX_DIMENSION, From 0c4924ad08d55a91de54b78be99885de41ede4e8 Mon Sep 17 00:00:00 2001 From: cku Date: Mon, 20 Feb 2017 18:04:44 +0800 Subject: [PATCH 068/234] Bug 1336480 - Part 2. Test case. r=mstange MozReview-Commit-ID: K4EZOOzd1ND --HG-- extra : rebase_source : d00b8c1e80c018e33dbf811c71f1a65bf5f4683e --- .../css-filters/filter-on-huge-bbox.html | 26 +++++++++++++++++++ .../svg/filters/css-filters/reftest.list | 4 +-- 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 layout/reftests/svg/filters/css-filters/filter-on-huge-bbox.html diff --git a/layout/reftests/svg/filters/css-filters/filter-on-huge-bbox.html b/layout/reftests/svg/filters/css-filters/filter-on-huge-bbox.html new file mode 100644 index 000000000000..6a75f19b276e --- /dev/null +++ b/layout/reftests/svg/filters/css-filters/filter-on-huge-bbox.html @@ -0,0 +1,26 @@ + + + + +
+ http://example.com + \ No newline at end of file diff --git a/layout/reftests/svg/filters/css-filters/reftest.list b/layout/reftests/svg/filters/css-filters/reftest.list index 9d4f35201bbd..73a5462e5ff3 100644 --- a/layout/reftests/svg/filters/css-filters/reftest.list +++ b/layout/reftests/svg/filters/css-filters/reftest.list @@ -29,6 +29,8 @@ skip-if(d2d) == blur-cap-large-radius-on-software.html blur-cap-large-radius-on- == drop-shadow.html drop-shadow-ref.html == drop-shadow-default-color.html drop-shadow-default-color-ref.html == drop-shadow-negative-offset.html drop-shadow-negative-offset-ref.html +== filter-on-huge-bbox.html pass.svg +== filter-on-outer-svg.html pass.svg fuzzy-if(d2d,1,10000) == grayscale.html grayscale-ref.html fuzzy-if(d2d,1,10000) == grayscale-one.html grayscale-one-ref.html fuzzy-if(d2d,1,10000) == grayscale-over-one.html grayscale-over-one-ref.html @@ -68,5 +70,3 @@ fuzzy-if(d2d,1,10000) == sepia-percent.html sepia-percent-ref.html == sepia-zero.html sepia-zero-ref.html fuzzy(2,125000) == scale-filtered-content-01.html scale-filtered-content-01-ref.html - -== filter-on-outer-svg.html pass.svg From 39855cf6b26723dcf6ce01fb20619dd35a3a7267 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Wed, 22 Feb 2017 19:30:57 -0500 Subject: [PATCH 069/234] Bug 1341927. Fix the stylo reftest setup to set prefs via the normal mechanism and hence not run afoul of the reftest harness canvas caching. r=heycam MozReview-Commit-ID: 9XlVwTV964w --HG-- extra : rebase_source : 70262f7d6863cdee769700d449f8e2183af7225d --- .../writing-mode/tables/reftest-stylo.list | 4 +-- layout/tools/reftest/reftest.jsm | 26 ++++++++++++------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/layout/reftests/writing-mode/tables/reftest-stylo.list b/layout/reftests/writing-mode/tables/reftest-stylo.list index 11a366e1b0ad..1635419fa5a4 100644 --- a/layout/reftests/writing-mode/tables/reftest-stylo.list +++ b/layout/reftests/writing-mode/tables/reftest-stylo.list @@ -71,8 +71,8 @@ asserts(1-2) == vertical-table-specified-width-2.html vertical-table-specified-w fails == wm-row-progression-002.xht wm-row-progression-002.xht fails == wm-row-progression-003.xht wm-row-progression-003.xht fails == wm-row-progression-004.xht wm-row-progression-004.xht -== wm-row-progression-004.xht wm-row-progression-005.xht -== wm-row-progression-004.xht wm-row-progression-006.xht +fails == wm-row-progression-005.xht wm-row-progression-005.xht +fails == wm-row-progression-006.xht wm-row-progression-006.xht fails == wm-row-progression-007.xht wm-row-progression-007.xht # == table-caption-top-1.html table-caption-top-1.html diff --git a/layout/tools/reftest/reftest.jsm b/layout/tools/reftest/reftest.jsm index 3c4cd59f30c5..79e5f3878e40 100644 --- a/layout/tools/reftest/reftest.jsm +++ b/layout/tools/reftest/reftest.jsm @@ -845,6 +845,14 @@ function AddTestItem(aTest, aFilter) gURLs.push(aTest); } +function AddStyloTestPrefs(aSandbox, aTestPrefSettings, aRefPrefSettings) +{ + AddPrefSettings("test-", "layout.css.servo.enabled", "true", aSandbox, + aTestPrefSettings, aRefPrefSettings); + AddPrefSettings("ref-", "layout.css.servo.enabled", "false", aSandbox, + aTestPrefSettings, aRefPrefSettings); +} + // Note: If you materially change the reftest manifest parsing, // please keep the parser in print-manifest-dirs.py in sync. function ReadManifest(aURL, inherited_status, aFilter) @@ -879,6 +887,10 @@ function ReadManifest(aURL, inherited_status, aFilter) var lineNo = 0; var urlprefix = ""; var defaultTestPrefSettings = [], defaultRefPrefSettings = []; + if (gCompareStyloToGecko) { + AddStyloTestPrefs(sandbox, defaultTestPrefSettings, + defaultRefPrefSettings); + } for (var str of lines) { ++lineNo; if (str.charAt(0) == "#") @@ -913,6 +925,10 @@ function ReadManifest(aURL, inherited_status, aFilter) throw "Error in pref value in manifest file " + aURL.spec + " line " + lineNo; } } + if (gCompareStyloToGecko) { + AddStyloTestPrefs(sandbox, defaultTestPrefSettings, + defaultRefPrefSettings); + } continue; } @@ -1321,16 +1337,6 @@ function StartCurrentURI(aState) var prefs = Components.classes["@mozilla.org/preferences-service;1"]. getService(Components.interfaces.nsIPrefBranch); - if (gCompareStyloToGecko) { - if (gState == 2){ - logger.info("Disabling Servo-backed style system"); - prefs.setBoolPref('layout.css.servo.enabled', false); - } else { - logger.info("Enabling Servo-backed style system"); - prefs.setBoolPref('layout.css.servo.enabled', true); - } - } - var prefSettings = gURLs[0]["prefSettings" + aState]; if (prefSettings.length > 0) { var badPref = undefined; From 814d03f8f08bd7cabfdd72155a72dee730e066c6 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Wed, 22 Feb 2017 17:50:48 -0800 Subject: [PATCH 070/234] servo: Merge #14962 - Remove network requests from image cache thread (from jdm:image_script_load); r=Ms2ger,glennw,emilio The design of initiating network requests from the image cache thread was simple, but it makes it difficult to implement image loading that conforms to the HTML specification. These changes make the implementation of HTMLImageElement responsible for network requests for `` elements, and CSS-based images (background-image, bullets, etc.) are requested by the script thread to ensure that the layout thread does not attempt to retain unsafe pointers to DOM nodes during asynchronous operations. --- - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #7708 - [X] There are tests for these changes Source-Repo: https://github.com/servo/servo Source-Revision: 854d720b21dda68034233a25385c4f2564a4a2d5 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 845215025ea28e20cf0372075841172a4ed5206c --- servo/components/layout/construct.rs | 3 + servo/components/layout/context.rs | 116 ++--- .../components/layout/display_list_builder.rs | 3 +- servo/components/layout/fragment.rs | 9 +- servo/components/layout/query.rs | 11 + servo/components/layout_thread/lib.rs | 79 +--- servo/components/net/image_cache_thread.rs | 399 ++++++++---------- .../net_traits/image_cache_thread.rs | 126 +++--- servo/components/net_traits/lib.rs | 4 +- servo/components/script/document_loader.rs | 7 + servo/components/script/dom/bindings/trace.rs | 4 +- .../script/dom/canvasrenderingcontext2d.rs | 4 +- .../script/dom/htmlcanvaselement.rs | 17 +- .../components/script/dom/htmlimageelement.rs | 235 +++++++++-- servo/components/script/dom/window.rs | 79 +++- servo/components/script/layout_image.rs | 81 ++++ servo/components/script/lib.rs | 1 + servo/components/script/script_thread.rs | 26 +- .../components/script_layout_interface/lib.rs | 18 + .../components/script_layout_interface/rpc.rs | 4 +- .../script_plugins/unrooted_must_root.rs | 1 + servo/components/servo/lib.rs | 3 +- 22 files changed, 748 insertions(+), 482 deletions(-) create mode 100644 servo/components/script/layout_image.rs diff --git a/servo/components/layout/construct.rs b/servo/components/layout/construct.rs index bbfe17d22b73..afdf903c5007 100644 --- a/servo/components/layout/construct.rs +++ b/servo/components/layout/construct.rs @@ -351,11 +351,13 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> } Some(LayoutNodeType::Element(LayoutElementType::HTMLImageElement)) => { let image_info = box ImageFragmentInfo::new(node.image_url(), + node, &self.layout_context); SpecificFragmentInfo::Image(image_info) } Some(LayoutNodeType::Element(LayoutElementType::HTMLObjectElement)) => { let image_info = box ImageFragmentInfo::new(node.object_data(), + node, &self.layout_context); SpecificFragmentInfo::Image(image_info) } @@ -1219,6 +1221,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> let marker_fragments = match node.style(self.style_context()).get_list().list_style_image { Either::First(ref url_value) => { let image_info = box ImageFragmentInfo::new(url_value.url().map(|u| u.clone()), + node, &self.layout_context); vec![Fragment::new(node, SpecificFragmentInfo::Image(image_info), self.layout_context)] } diff --git a/servo/components/layout/context.rs b/servo/components/layout/context.rs index e67e7da6fb17..1dff9f6ea5eb 100644 --- a/servo/components/layout/context.rs +++ b/servo/components/layout/context.rs @@ -5,22 +5,22 @@ //! Data needed by the layout thread. use fnv::FnvHasher; -use gfx::display_list::WebRenderImageInfo; +use gfx::display_list::{WebRenderImageInfo, OpaqueNode}; use gfx::font_cache_thread::FontCacheThread; use gfx::font_context::FontContext; use heapsize::HeapSizeOf; -use ipc_channel::ipc; -use net_traits::image::base::Image; -use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheThread, ImageResponse, ImageState}; +use net_traits::image_cache_thread::{ImageCacheThread, ImageState, CanRequestImages}; use net_traits::image_cache_thread::{ImageOrMetadataAvailable, UsePlaceholder}; +use opaque_node::OpaqueNodeMethods; use parking_lot::RwLock; -use servo_config::opts; +use script_layout_interface::{PendingImage, PendingImageState}; use servo_url::ServoUrl; use std::borrow::{Borrow, BorrowMut}; use std::cell::{RefCell, RefMut}; use std::collections::HashMap; use std::hash::BuildHasherDefault; use std::sync::{Arc, Mutex}; +use std::thread; use style::context::{SharedStyleContext, ThreadLocalStyleContext}; use style::dom::TElement; @@ -82,9 +82,6 @@ pub struct LayoutContext { /// The shared image cache thread. pub image_cache_thread: Mutex, - /// A channel for the image cache to send responses to. - pub image_cache_sender: Mutex, - /// Interface to the font cache thread. pub font_cache_thread: Mutex, @@ -92,6 +89,20 @@ pub struct LayoutContext { pub webrender_image_cache: Arc>>>, + + /// A list of in-progress image loads to be shared with the script thread. + /// A None value means that this layout was not initiated by the script thread. + pub pending_images: Option>> +} + +impl Drop for LayoutContext { + fn drop(&mut self) { + if !thread::panicking() { + if let Some(ref pending_images) = self.pending_images { + assert!(pending_images.lock().unwrap().is_empty()); + } + } + } } impl LayoutContext { @@ -100,71 +111,60 @@ impl LayoutContext { &self.style_context } - fn get_or_request_image_synchronously(&self, url: ServoUrl, use_placeholder: UsePlaceholder) - -> Option> { - debug_assert!(opts::get().output_file.is_some() || opts::get().exit_after_load); + pub fn get_or_request_image_or_meta(&self, + node: OpaqueNode, + url: ServoUrl, + use_placeholder: UsePlaceholder) + -> Option { + //XXXjdm For cases where we do not request an image, we still need to + // ensure the node gets another script-initiated reflow or it + // won't be requested at all. + let can_request = if self.pending_images.is_some() { + CanRequestImages::Yes + } else { + CanRequestImages::No + }; - // See if the image is already available - let result = self.image_cache_thread.lock().unwrap() - .find_image(url.clone(), use_placeholder); - - match result { - Ok(image) => return Some(image), - Err(ImageState::LoadError) => { - // Image failed to load, so just return nothing - return None - } - Err(_) => {} - } - - // If we are emitting an output file, then we need to block on - // image load or we risk emitting an output file missing the image. - let (sync_tx, sync_rx) = ipc::channel().unwrap(); - self.image_cache_thread.lock().unwrap().request_image(url, ImageCacheChan(sync_tx), None); - loop { - match sync_rx.recv() { - Err(_) => return None, - Ok(response) => { - match response.image_response { - ImageResponse::Loaded(image) | ImageResponse::PlaceholderLoaded(image) => { - return Some(image) - } - ImageResponse::None | ImageResponse::MetadataLoaded(_) => {} - } - } - } - } - } - - pub fn get_or_request_image_or_meta(&self, url: ServoUrl, use_placeholder: UsePlaceholder) - -> Option { - // If we are emitting an output file, load the image synchronously. - if opts::get().output_file.is_some() || opts::get().exit_after_load { - return self.get_or_request_image_synchronously(url, use_placeholder) - .map(|img| ImageOrMetadataAvailable::ImageAvailable(img)); - } // See if the image is already available let result = self.image_cache_thread.lock().unwrap() .find_image_or_metadata(url.clone(), - use_placeholder); + use_placeholder, + can_request); match result { Ok(image_or_metadata) => Some(image_or_metadata), // Image failed to load, so just return nothing Err(ImageState::LoadError) => None, - // Not yet requested, async mode - request image or metadata from the cache - Err(ImageState::NotRequested) => { - let sender = self.image_cache_sender.lock().unwrap().clone(); - self.image_cache_thread.lock().unwrap() - .request_image_and_metadata(url, sender, None); + // Not yet requested - request image or metadata from the cache + Err(ImageState::NotRequested(id)) => { + let image = PendingImage { + state: PendingImageState::Unrequested(url), + node: node.to_untrusted_node_address(), + id: id, + }; + self.pending_images.as_ref().unwrap().lock().unwrap().push(image); None } // Image has been requested, is still pending. Return no image for this paint loop. // When the image loads it will trigger a reflow and/or repaint. - Err(ImageState::Pending) => None, + Err(ImageState::Pending(id)) => { + //XXXjdm if self.pending_images is not available, we should make sure that + // this node gets marked dirty again so it gets a script-initiated + // reflow that deals with this properly. + if let Some(ref pending_images) = self.pending_images { + let image = PendingImage { + state: PendingImageState::PendingResponse, + node: node.to_untrusted_node_address(), + id: id, + }; + pending_images.lock().unwrap().push(image); + } + None + } } } pub fn get_webrender_image_for_url(&self, + node: OpaqueNode, url: ServoUrl, use_placeholder: UsePlaceholder) -> Option { @@ -174,7 +174,7 @@ impl LayoutContext { return Some((*existing_webrender_image).clone()) } - match self.get_or_request_image_or_meta(url.clone(), use_placeholder) { + match self.get_or_request_image_or_meta(node, url.clone(), use_placeholder) { Some(ImageOrMetadataAvailable::ImageAvailable(image)) => { let image_info = WebRenderImageInfo::from_image(&*image); if image_info.key.is_none() { diff --git a/servo/components/layout/display_list_builder.rs b/servo/components/layout/display_list_builder.rs index 848188d14a0d..5eb4534a0c5e 100644 --- a/servo/components/layout/display_list_builder.rs +++ b/servo/components/layout/display_list_builder.rs @@ -683,7 +683,8 @@ impl FragmentDisplayListBuilding for Fragment { index: usize) { let background = style.get_background(); let webrender_image = state.layout_context - .get_webrender_image_for_url(image_url.clone(), + .get_webrender_image_for_url(self.node, + image_url.clone(), UsePlaceholder::No); if let Some(webrender_image) = webrender_image { diff --git a/servo/components/layout/fragment.rs b/servo/components/layout/fragment.rs index ec1e87e6dd2c..9cc0efbce6e5 100644 --- a/servo/components/layout/fragment.rs +++ b/servo/components/layout/fragment.rs @@ -367,11 +367,14 @@ impl ImageFragmentInfo { /// /// FIXME(pcwalton): The fact that image fragments store the cache in the fragment makes little /// sense to me. - pub fn new(url: Option, - layout_context: &LayoutContext) + pub fn new(url: Option, + node: &N, + layout_context: &LayoutContext) -> ImageFragmentInfo { let image_or_metadata = url.and_then(|url| { - layout_context.get_or_request_image_or_meta(url, UsePlaceholder::Yes) + layout_context.get_or_request_image_or_meta(node.opaque(), + url, + UsePlaceholder::Yes) }); let (image, metadata) = match image_or_metadata { diff --git a/servo/components/layout/query.rs b/servo/components/layout/query.rs index 5c78a1bc75da..2f26fede59f7 100644 --- a/servo/components/layout/query.rs +++ b/servo/components/layout/query.rs @@ -17,6 +17,7 @@ use gfx_traits::ScrollRootId; use inline::LAST_FRAGMENT_OF_ELEMENT; use ipc_channel::ipc::IpcSender; use opaque_node::OpaqueNodeMethods; +use script_layout_interface::PendingImage; use script_layout_interface::rpc::{ContentBoxResponse, ContentBoxesResponse}; use script_layout_interface::rpc::{HitTestResponse, LayoutRPC}; use script_layout_interface::rpc::{MarginStyleResponse, NodeGeometryResponse}; @@ -27,6 +28,7 @@ use script_traits::LayoutMsg as ConstellationMsg; use script_traits::UntrustedNodeAddress; use sequential; use std::cmp::{min, max}; +use std::mem; use std::ops::Deref; use std::sync::{Arc, Mutex}; use style::computed_values; @@ -89,6 +91,9 @@ pub struct LayoutThreadData { /// Index in a text fragment. We need this do determine the insertion point. pub text_index_response: TextIndexResponse, + + /// A list of images requests that need to be initiated. + pub pending_images: Vec, } pub struct LayoutRPCImpl(pub Arc>); @@ -216,6 +221,12 @@ impl LayoutRPC for LayoutRPCImpl { let rw_data = rw_data.lock().unwrap(); rw_data.text_index_response.clone() } + + fn pending_images(&self) -> Vec { + let &LayoutRPCImpl(ref rw_data) = self; + let mut rw_data = rw_data.lock().unwrap(); + mem::replace(&mut rw_data.pending_images, vec![]) + } } struct UnioningFragmentBorderBoxIterator { diff --git a/servo/components/layout_thread/lib.rs b/servo/components/layout_thread/lib.rs index 8626385a0262..8d6f2377130b 100644 --- a/servo/components/layout_thread/lib.rs +++ b/servo/components/layout_thread/lib.rs @@ -75,7 +75,7 @@ use layout::wrapper::LayoutNodeLayoutData; use layout::wrapper::drop_style_and_layout_data; use layout_traits::LayoutThreadFactory; use msg::constellation_msg::{FrameId, PipelineId}; -use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheResult, ImageCacheThread}; +use net_traits::image_cache_thread::ImageCacheThread; use net_traits::image_cache_thread::UsePlaceholder; use parking_lot::RwLock; use profile_traits::mem::{self, Report, ReportKind, ReportsChan}; @@ -98,6 +98,7 @@ use servo_url::ServoUrl; use std::borrow::ToOwned; use std::collections::HashMap; use std::hash::BuildHasherDefault; +use std::mem as std_mem; use std::ops::{Deref, DerefMut}; use std::process; use std::sync::{Arc, Mutex, MutexGuard}; @@ -137,12 +138,6 @@ pub struct LayoutThread { /// The port on which we receive messages from the constellation. pipeline_port: Receiver, - /// The port on which we receive messages from the image cache - image_cache_receiver: Receiver, - - /// The channel on which the image cache can send messages to ourself. - image_cache_sender: ImageCacheChan, - /// The port on which we receive messages from the font cache thread. font_cache_receiver: Receiver<()>, @@ -404,11 +399,6 @@ impl LayoutThread { // Proxy IPC messages from the pipeline to the layout thread. let pipeline_receiver = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(pipeline_port); - // Ask the router to proxy IPC messages from the image cache thread to the layout thread. - let (ipc_image_cache_sender, ipc_image_cache_receiver) = ipc::channel().unwrap(); - let image_cache_receiver = - ROUTER.route_ipc_receiver_to_new_mpsc_receiver(ipc_image_cache_receiver); - // Ask the router to proxy IPC messages from the font cache thread to the layout thread. let (ipc_font_cache_sender, ipc_font_cache_receiver) = ipc::channel().unwrap(); let font_cache_receiver = @@ -437,8 +427,6 @@ impl LayoutThread { image_cache_thread: image_cache_thread, font_cache_thread: font_cache_thread, first_reflow: true, - image_cache_receiver: image_cache_receiver, - image_cache_sender: ImageCacheChan(ipc_image_cache_sender), font_cache_receiver: font_cache_receiver, font_cache_sender: ipc_font_cache_sender, parallel_traversal: parallel_traversal, @@ -470,6 +458,7 @@ impl LayoutThread { margin_style_response: MarginStyleResponse::empty(), stacking_context_scroll_offsets: HashMap::new(), text_index_response: TextIndexResponse(None), + pending_images: vec![], })), error_reporter: CSSErrorReporter { pipelineid: id, @@ -506,7 +495,8 @@ impl LayoutThread { fn build_layout_context(&self, rw_data: &LayoutThreadData, screen_size_changed: bool, - goal: ReflowGoal) + goal: ReflowGoal, + request_images: bool) -> LayoutContext { let thread_local_style_context_creation_data = ThreadLocalStyleContextCreationInfo::new(self.new_animations_sender.clone()); @@ -530,9 +520,9 @@ impl LayoutThread { default_computed_values: Arc::new(ComputedValues::initial_values().clone()), }, image_cache_thread: Mutex::new(self.image_cache_thread.clone()), - image_cache_sender: Mutex::new(self.image_cache_sender.clone()), font_cache_thread: Mutex::new(self.font_cache_thread.clone()), webrender_image_cache: self.webrender_image_cache.clone(), + pending_images: if request_images { Some(Mutex::new(vec![])) } else { None }, } } @@ -541,14 +531,12 @@ impl LayoutThread { enum Request { FromPipeline(LayoutControlMsg), FromScript(Msg), - FromImageCache, FromFontCache, } let request = { let port_from_script = &self.port; let port_from_pipeline = &self.pipeline_port; - let port_from_image_cache = &self.image_cache_receiver; let port_from_font_cache = &self.font_cache_receiver; select! { msg = port_from_pipeline.recv() => { @@ -557,10 +545,6 @@ impl LayoutThread { msg = port_from_script.recv() => { Request::FromScript(msg.unwrap()) }, - msg = port_from_image_cache.recv() => { - msg.unwrap(); - Request::FromImageCache - }, msg = port_from_font_cache.recv() => { msg.unwrap(); Request::FromFontCache @@ -590,9 +574,6 @@ impl LayoutThread { Request::FromScript(msg) => { self.handle_request_helper(msg, possibly_locked_rw_data) }, - Request::FromImageCache => { - self.repaint(possibly_locked_rw_data) - }, Request::FromFontCache => { let _rw_data = possibly_locked_rw_data.lock(); self.outstanding_web_fonts.fetch_sub(1, Ordering::SeqCst); @@ -603,37 +584,6 @@ impl LayoutThread { } } - /// Repaint the scene, without performing style matching. This is typically - /// used when an image arrives asynchronously and triggers a relayout and - /// repaint. - /// TODO: In the future we could detect if the image size hasn't changed - /// since last time and avoid performing a complete layout pass. - fn repaint<'a, 'b>(&mut self, possibly_locked_rw_data: &mut RwData<'a, 'b>) -> bool { - let mut rw_data = possibly_locked_rw_data.lock(); - - if let Some(mut root_flow) = self.root_flow.clone() { - let flow = flow::mut_base(FlowRef::deref_mut(&mut root_flow)); - flow.restyle_damage.insert(REPAINT); - } - - let reflow_info = Reflow { - goal: ReflowGoal::ForDisplay, - page_clip_rect: max_rect(), - }; - let mut layout_context = self.build_layout_context(&*rw_data, - false, - reflow_info.goal); - - self.perform_post_style_recalc_layout_passes(&reflow_info, - None, - None, - &mut *rw_data, - &mut layout_context); - - - true - } - /// Receives and dispatches messages from other threads. fn handle_request_helper<'a, 'b>(&mut self, request: Msg, @@ -1166,7 +1116,8 @@ impl LayoutThread { // Create a layout context for use throughout the following passes. let mut layout_context = self.build_layout_context(&*rw_data, viewport_size_changed, - data.reflow_info.goal); + data.reflow_info.goal, + true); // NB: Type inference falls apart here for some reason, so we need to be very verbose. :-( let traversal_driver = if self.parallel_flag && self.parallel_traversal.is_some() { @@ -1247,6 +1198,12 @@ impl LayoutThread { query_type: &ReflowQueryType, rw_data: &mut LayoutThreadData, context: &mut LayoutContext) { + let pending_images = match context.pending_images { + Some(ref pending) => std_mem::replace(&mut *pending.lock().unwrap(), vec![]), + None => vec![], + }; + rw_data.pending_images = pending_images; + let mut root_flow = match self.root_flow.clone() { Some(root_flow) => root_flow, None => return, @@ -1367,7 +1324,8 @@ impl LayoutThread { let mut layout_context = self.build_layout_context(&*rw_data, false, - reflow_info.goal); + reflow_info.goal, + false); if let Some(mut root_flow) = self.root_flow.clone() { // Perform an abbreviated style recalc that operates without access to the DOM. @@ -1387,6 +1345,8 @@ impl LayoutThread { None, &mut *rw_data, &mut layout_context); + + assert!(layout_context.pending_images.is_none()); } fn reflow_with_newly_loaded_web_font<'a, 'b>(&mut self, possibly_locked_rw_data: &mut RwData<'a, 'b>) { @@ -1400,7 +1360,8 @@ impl LayoutThread { let mut layout_context = self.build_layout_context(&*rw_data, false, - reflow_info.goal); + reflow_info.goal, + false); // No need to do a style recalc here. if self.root_flow.is_none() { diff --git a/servo/components/net/image_cache_thread.rs b/servo/components/net/image_cache_thread.rs index 51d8324bd481..5beacb8a1a43 100644 --- a/servo/components/net/image_cache_thread.rs +++ b/servo/components/net/image_cache_thread.rs @@ -5,12 +5,11 @@ use immeta::load_from_buf; use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; use ipc_channel::router::ROUTER; -use net_traits::{CoreResourceThread, NetworkError, fetch_async, FetchResponseMsg}; +use net_traits::{NetworkError, FetchResponseMsg}; use net_traits::image::base::{Image, ImageMetadata, PixelFormat, load_from_memory}; -use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheCommand, ImageCacheThread, ImageState}; -use net_traits::image_cache_thread::{ImageCacheResult, ImageOrMetadataAvailable, ImageResponse, UsePlaceholder}; -use net_traits::image_cache_thread::ImageResponder; -use net_traits::request::{Destination, RequestInit, Type as RequestType}; +use net_traits::image_cache_thread::{ImageCacheCommand, ImageCacheThread, ImageState}; +use net_traits::image_cache_thread::{ImageOrMetadataAvailable, ImageResponse, UsePlaceholder}; +use net_traits::image_cache_thread::{ImageResponder, PendingImageId, CanRequestImages}; use servo_config::resource_files::resources_dir_path; use servo_url::ServoUrl; use std::borrow::ToOwned; @@ -58,20 +57,54 @@ fn is_image_opaque(format: webrender_traits::ImageFormat, bytes: &[u8]) -> bool struct PendingLoad { // The bytes loaded so far. Reset to an empty vector once loading // is complete and the buffer has been transmitted to the decoder. - bytes: Vec, + bytes: ImageBytes, // Image metadata, if available. metadata: Option, // Once loading is complete, the result of the operation. result: Option>, - listeners: Vec, + listeners: Vec, // The url being loaded. Do not forget that this may be several Mb // if we are loading a data: url. url: ServoUrl, } +enum ImageBytes { + InProgress(Vec), + Complete(Arc>), +} + +impl ImageBytes { + fn extend_from_slice(&mut self, data: &[u8]) { + match *self { + ImageBytes::InProgress(ref mut bytes) => bytes.extend_from_slice(data), + ImageBytes::Complete(_) => panic!("attempted modification of complete image bytes"), + } + } + + fn mark_complete(&mut self) -> Arc> { + let bytes = { + let own_bytes = match *self { + ImageBytes::InProgress(ref mut bytes) => bytes, + ImageBytes::Complete(_) => panic!("attempted modification of complete image bytes"), + }; + mem::replace(own_bytes, vec![]) + }; + let bytes = Arc::new(bytes); + *self = ImageBytes::Complete(bytes.clone()); + bytes + } + + fn as_slice(&self) -> &[u8] { + match *self { + ImageBytes::InProgress(ref bytes) => &bytes, + ImageBytes::Complete(ref bytes) => &*bytes, + } + } +} + enum LoadResult { Loaded(Image), PlaceholderLoaded(Arc), @@ -81,7 +114,7 @@ enum LoadResult { impl PendingLoad { fn new(url: ServoUrl) -> PendingLoad { PendingLoad { - bytes: vec!(), + bytes: ImageBytes::InProgress(vec!()), metadata: None, result: None, listeners: vec!(), @@ -89,7 +122,7 @@ impl PendingLoad { } } - fn add_listener(&mut self, listener: ImageListener) { + fn add_listener(&mut self, listener: ImageResponder) { self.listeners.push(listener); } } @@ -109,11 +142,12 @@ struct AllPendingLoads { keygen: LoadKeyGenerator, } -// Result of accessing a cache. -#[derive(Eq, PartialEq)] -enum CacheResult { - Hit, // The value was in the cache. - Miss, // The value was not in the cache and needed to be regenerated. +/// Result of accessing a cache. +enum CacheResult<'a> { + /// The value was in the cache. + Hit(LoadKey, &'a mut PendingLoad), + /// The value was not in the cache and needed to be regenerated. + Miss(Option<(LoadKey, &'a mut PendingLoad)>), } impl AllPendingLoads { @@ -131,20 +165,11 @@ impl AllPendingLoads { self.loads.is_empty() } - // get a PendingLoad from its LoadKey. Prefer this to `get_by_url`, - // for performance reasons. + // get a PendingLoad from its LoadKey. fn get_by_key_mut(&mut self, key: &LoadKey) -> Option<&mut PendingLoad> { self.loads.get_mut(key) } - // get a PendingLoad from its url. When possible, prefer `get_by_key_mut`. - fn get_by_url(&self, url: &ServoUrl) -> Option<&PendingLoad> { - self.url_to_load_key.get(url). - and_then(|load_key| - self.loads.get(load_key) - ) - } - fn remove(&mut self, key: &LoadKey) -> Option { self.loads.remove(key). and_then(|pending_load| { @@ -153,13 +178,18 @@ impl AllPendingLoads { }) } - fn get_cached(&mut self, url: ServoUrl) -> (CacheResult, LoadKey, &mut PendingLoad) { + fn get_cached<'a>(&'a mut self, url: ServoUrl, can_request: CanRequestImages) + -> CacheResult<'a> { match self.url_to_load_key.entry(url.clone()) { Occupied(url_entry) => { let load_key = url_entry.get(); - (CacheResult::Hit, *load_key, self.loads.get_mut(load_key).unwrap()) + CacheResult::Hit(*load_key, self.loads.get_mut(load_key).unwrap()) } Vacant(url_entry) => { + if can_request == CanRequestImages::No { + return CacheResult::Miss(None); + } + let load_key = self.keygen.next(); url_entry.insert(load_key); @@ -168,7 +198,7 @@ impl AllPendingLoads { Occupied(_) => unreachable!(), Vacant(load_entry) => { let mut_load = load_entry.insert(pending_load); - (CacheResult::Miss, load_key, mut_load) + CacheResult::Miss(Some((load_key, mut_load))) } } } @@ -182,27 +212,20 @@ impl AllPendingLoads { /// fetched again. struct CompletedLoad { image_response: ImageResponse, + id: PendingImageId, } impl CompletedLoad { - fn new(image_response: ImageResponse) -> CompletedLoad { + fn new(image_response: ImageResponse, id: PendingImageId) -> CompletedLoad { CompletedLoad { image_response: image_response, + id: id, } } } -/// Stores information to notify a client when the state -/// of an image changes. -struct ImageListener { - sender: ImageCacheChan, - responder: Option, - send_metadata_msg: bool, -} - // A key used to communicate during loading. -#[derive(Eq, Hash, PartialEq, Clone, Copy)] -struct LoadKey(u64); +type LoadKey = PendingImageId; struct LoadKeyGenerator { counter: u64 @@ -214,34 +237,9 @@ impl LoadKeyGenerator { counter: 0 } } - fn next(&mut self) -> LoadKey { + fn next(&mut self) -> PendingImageId { self.counter += 1; - LoadKey(self.counter) - } -} - -impl ImageListener { - fn new(sender: ImageCacheChan, responder: Option, send_metadata_msg: bool) -> ImageListener { - ImageListener { - sender: sender, - responder: responder, - send_metadata_msg: send_metadata_msg, - } - } - - fn notify(&self, image_response: ImageResponse) { - if !self.send_metadata_msg { - if let ImageResponse::MetadataLoaded(_) = image_response { - return; - } - } - - let ImageCacheChan(ref sender) = self.sender; - let msg = ImageCacheResult { - responder: self.responder.clone(), - image_response: image_response, - }; - sender.send(msg).ok(); + PendingImageId(self.counter) } } @@ -252,16 +250,11 @@ struct ResourceLoadInfo { /// Implementation of the image cache struct ImageCache { - progress_sender: Sender, - decoder_sender: Sender, // Worker threads for decoding images. thread_pool: ThreadPool, - // Resource thread handle - core_resource_thread: CoreResourceThread, - // Images that are loading over network, or decoding. pending_loads: AllPendingLoads, @@ -284,7 +277,6 @@ struct DecoderMsg { struct Receivers { cmd_receiver: Receiver, decoder_receiver: Receiver, - progress_receiver: Receiver, } impl Receivers { @@ -292,16 +284,12 @@ impl Receivers { fn recv(&self) -> SelectResult { let cmd_receiver = &self.cmd_receiver; let decoder_receiver = &self.decoder_receiver; - let progress_receiver = &self.progress_receiver; select! { msg = cmd_receiver.recv() => { SelectResult::Command(msg.unwrap()) }, msg = decoder_receiver.recv() => { SelectResult::Decoder(msg.unwrap()) - }, - msg = progress_receiver.recv() => { - SelectResult::Progress(msg.unwrap()) } } } @@ -310,7 +298,6 @@ impl Receivers { /// The types of messages that the main image cache thread receives. enum SelectResult { Command(ImageCacheCommand), - Progress(ResourceLoadInfo), Decoder(DecoderMsg), } @@ -347,8 +334,7 @@ fn get_placeholder_image(webrender_api: &webrender_traits::RenderApi) -> io::Res } impl ImageCache { - fn run(core_resource_thread: CoreResourceThread, - webrender_api: webrender_traits::RenderApi, + fn run(webrender_api: webrender_traits::RenderApi, ipc_command_receiver: IpcReceiver) { // Preload the placeholder image, used when images fail to load. let placeholder_image = get_placeholder_image(&webrender_api).ok(); @@ -356,15 +342,12 @@ impl ImageCache { // Ask the router to proxy messages received over IPC to us. let cmd_receiver = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(ipc_command_receiver); - let (progress_sender, progress_receiver) = channel(); let (decoder_sender, decoder_receiver) = channel(); let mut cache = ImageCache { - progress_sender: progress_sender, decoder_sender: decoder_sender, thread_pool: ThreadPool::new(4), pending_loads: AllPendingLoads::new(), completed_loads: HashMap::new(), - core_resource_thread: core_resource_thread, placeholder_image: placeholder_image, webrender_api: webrender_api, }; @@ -372,7 +355,6 @@ impl ImageCache { let receivers = Receivers { cmd_receiver: cmd_receiver, decoder_receiver: decoder_receiver, - progress_receiver: progress_receiver, }; let mut exit_sender: Option> = None; @@ -382,9 +364,6 @@ impl ImageCache { SelectResult::Command(cmd) => { exit_sender = cache.handle_cmd(cmd); } - SelectResult::Progress(msg) => { - cache.handle_progress(msg); - } SelectResult::Decoder(msg) => { cache.handle_decoder(msg); } @@ -406,22 +385,22 @@ impl ImageCache { ImageCacheCommand::Exit(sender) => { return Some(sender); } - ImageCacheCommand::RequestImage(url, result_chan, responder) => { - self.request_image(url, result_chan, responder, false); + ImageCacheCommand::AddListener(id, responder) => { + self.add_listener(id, responder); } - ImageCacheCommand::RequestImageAndMetadata(url, result_chan, responder) => { - self.request_image(url, result_chan, responder, true); - } - ImageCacheCommand::GetImageIfAvailable(url, use_placeholder, consumer) => { - let result = self.get_image_if_available(url, use_placeholder); + ImageCacheCommand::GetImageOrMetadataIfAvailable(url, + use_placeholder, + can_request, + consumer) => { + let result = self.get_image_or_meta_if_available(url, use_placeholder, can_request); + // TODO(#15501): look for opportunities to clean up cache if this send fails. let _ = consumer.send(result); } - ImageCacheCommand::GetImageOrMetadataIfAvailable(url, use_placeholder, consumer) => { - let result = self.get_image_or_meta_if_available(url, use_placeholder); - let _ = consumer.send(result); - } - ImageCacheCommand::StoreDecodeImage(url, image_vector) => { - self.store_decode_image(url, image_vector); + ImageCacheCommand::StoreDecodeImage(id, data) => { + self.handle_progress(ResourceLoadInfo { + action: data, + key: id + }); } }; @@ -433,41 +412,41 @@ impl ImageCache { match (msg.action, msg.key) { (FetchResponseMsg::ProcessRequestBody, _) | (FetchResponseMsg::ProcessRequestEOF, _) => return, - (FetchResponseMsg::ProcessResponse(_), _) => {} + (FetchResponseMsg::ProcessResponse(_response), _) => {} (FetchResponseMsg::ProcessResponseChunk(data), _) => { + debug!("got some data for {:?}", msg.key); let pending_load = self.pending_loads.get_by_key_mut(&msg.key).unwrap(); pending_load.bytes.extend_from_slice(&data); //jmr0 TODO: possibly move to another task? if let None = pending_load.metadata { - if let Ok(metadata) = load_from_buf(&pending_load.bytes) { + if let Ok(metadata) = load_from_buf(&pending_load.bytes.as_slice()) { let dimensions = metadata.dimensions(); let img_metadata = ImageMetadata { width: dimensions.width, - height: dimensions.height }; - pending_load.metadata = Some(img_metadata.clone()); + height: dimensions.height }; for listener in &pending_load.listeners { - listener.notify(ImageResponse::MetadataLoaded(img_metadata.clone()).clone()); + listener.respond(ImageResponse::MetadataLoaded(img_metadata.clone())); } + pending_load.metadata = Some(img_metadata); } } } (FetchResponseMsg::ProcessResponseEOF(result), key) => { + debug!("received EOF for {:?}", key); match result { Ok(()) => { let pending_load = self.pending_loads.get_by_key_mut(&msg.key).unwrap(); pending_load.result = Some(result); - let bytes = mem::replace(&mut pending_load.bytes, vec!()); + let bytes = pending_load.bytes.mark_complete(); let sender = self.decoder_sender.clone(); + debug!("async decoding {} ({:?})", pending_load.url, key); self.thread_pool.execute(move || { - let image = load_from_memory(&bytes); - let msg = DecoderMsg { - key: key, - image: image - }; + let msg = decode_bytes_sync(key, &*bytes); sender.send(msg).unwrap(); }); } Err(_) => { + debug!("processing error for {:?}", key); match self.placeholder_image.clone() { Some(placeholder_image) => { self.complete_load(msg.key, LoadResult::PlaceholderLoaded( @@ -492,7 +471,10 @@ impl ImageCache { // Change state of a url from pending -> loaded. fn complete_load(&mut self, key: LoadKey, mut load_result: LoadResult) { - let pending_load = self.pending_loads.remove(&key).unwrap(); + let pending_load = match self.pending_loads.remove(&key) { + Some(load) => load, + None => return, + }; match load_result { LoadResult::Loaded(ref mut image) => { @@ -518,145 +500,122 @@ impl ImageCache { LoadResult::None => ImageResponse::None, }; - let completed_load = CompletedLoad::new(image_response.clone()); + let completed_load = CompletedLoad::new(image_response.clone(), key); self.completed_loads.insert(pending_load.url.into(), completed_load); for listener in pending_load.listeners { - listener.notify(image_response.clone()); + listener.respond(image_response.clone()); } } - // Request an image from the cache. If the image hasn't been - // loaded/decoded yet, it will be loaded/decoded in the - // background. If send_metadata_msg is set, the channel will be notified - // that image metadata is available, possibly before the image has finished - // loading. - fn request_image(&mut self, - url: ServoUrl, - result_chan: ImageCacheChan, - responder: Option, - send_metadata_msg: bool) { - let image_listener = ImageListener::new(result_chan, responder, send_metadata_msg); - - // Check if already completed - match self.completed_loads.get(&url) { - Some(completed_load) => { - // It's already completed, return a notify straight away - image_listener.notify(completed_load.image_response.clone()); + /// Add a listener for a given image if it is still pending, or notify the + /// listener if the image is complete. + fn add_listener(&mut self, + id: PendingImageId, + listener: ImageResponder) { + if let Some(load) = self.pending_loads.get_by_key_mut(&id) { + if let Some(ref metadata) = load.metadata { + listener.respond(ImageResponse::MetadataLoaded(metadata.clone())); } - None => { - // Check if the load is already pending - let (cache_result, load_key, mut pending_load) = self.pending_loads.get_cached(url.clone()); - pending_load.add_listener(image_listener); - match cache_result { - CacheResult::Miss => { - // A new load request! Request the load from - // the resource thread. - // https://html.spec.whatwg.org/multipage/#update-the-image-data - // step 12. - // - // TODO(emilio): ServoUrl in more places please! - let request = RequestInit { - url: url.clone(), - type_: RequestType::Image, - destination: Destination::Image, - origin: url.clone(), - .. RequestInit::default() - }; + load.add_listener(listener); + return; + } + if let Some(load) = self.completed_loads.values().find(|l| l.id == id) { + listener.respond(load.image_response.clone()); + return; + } + warn!("Couldn't find cached entry for listener {:?}", id); + } - let progress_sender = self.progress_sender.clone(); - fetch_async(request, &self.core_resource_thread, move |action| { - let action = match action { - FetchResponseMsg::ProcessRequestBody | - FetchResponseMsg::ProcessRequestEOF => return, - a => a - }; - progress_sender.send(ResourceLoadInfo { - action: action, - key: load_key, - }).unwrap(); - }); - } - CacheResult::Hit => { - // Request is already on its way. - } + /// Return a completed image if it exists, or None if there is no complete load + /// or the complete load is not fully decoded or is unavailable. + fn get_completed_image_if_available(&self, + url: &ServoUrl, + placeholder: UsePlaceholder) + -> Option> { + self.completed_loads.get(url).map(|completed_load| { + match (&completed_load.image_response, placeholder) { + (&ImageResponse::Loaded(ref image), _) | + (&ImageResponse::PlaceholderLoaded(ref image), UsePlaceholder::Yes) => { + Ok(ImageOrMetadataAvailable::ImageAvailable(image.clone())) + } + (&ImageResponse::PlaceholderLoaded(_), UsePlaceholder::No) | + (&ImageResponse::None, _) | + (&ImageResponse::MetadataLoaded(_), _) => { + Err(ImageState::LoadError) } } - } - } - - fn get_image_if_available(&mut self, - url: ServoUrl, - placeholder: UsePlaceholder, ) - -> Result, ImageState> { - let img_or_metadata = self.get_image_or_meta_if_available(url, placeholder); - match img_or_metadata { - Ok(ImageOrMetadataAvailable::ImageAvailable(image)) => Ok(image), - Ok(ImageOrMetadataAvailable::MetadataAvailable(_)) => Err(ImageState::Pending), - Err(err) => Err(err), - } + }) } + /// Return any available metadata or image for the given URL, or an indication that + /// the image is not yet available if it is in progress, or else reserve a slot in + /// the cache for the URL if the consumer can request images. fn get_image_or_meta_if_available(&mut self, url: ServoUrl, - placeholder: UsePlaceholder) + placeholder: UsePlaceholder, + can_request: CanRequestImages) -> Result { - match self.completed_loads.get(&url) { - Some(completed_load) => { - match (completed_load.image_response.clone(), placeholder) { - (ImageResponse::Loaded(image), _) | - (ImageResponse::PlaceholderLoaded(image), UsePlaceholder::Yes) => { - Ok(ImageOrMetadataAvailable::ImageAvailable(image)) + if let Some(result) = self.get_completed_image_if_available(&url, placeholder) { + debug!("{} is available", url); + return result; + } + + let decoded = { + let result = self.pending_loads.get_cached(url.clone(), can_request); + match result { + CacheResult::Hit(key, pl) => match (&pl.result, &pl.metadata) { + (&Some(Ok(_)), _) => { + debug!("sync decoding {} ({:?})", url, key); + decode_bytes_sync(key, &pl.bytes.as_slice()) } - (ImageResponse::PlaceholderLoaded(_), UsePlaceholder::No) | - (ImageResponse::None, _) | - (ImageResponse::MetadataLoaded(_), _) => { - Err(ImageState::LoadError) + (&None, &Some(ref meta)) => { + debug!("metadata available for {} ({:?})", url, key); + return Ok(ImageOrMetadataAvailable::MetadataAvailable(meta.clone())) } + (&Some(Err(_)), _) | (&None, &None) => { + debug!("{} ({:?}) is still pending", url, key); + return Err(ImageState::Pending(key)); + } + }, + CacheResult::Miss(Some((key, _pl))) => { + debug!("should be requesting {} ({:?})", url, key); + return Err(ImageState::NotRequested(key)); + } + CacheResult::Miss(None) => { + debug!("couldn't find an entry for {}", url); + return Err(ImageState::LoadError); } } - None => { - let pl = match self.pending_loads.get_by_url(&url) { - Some(pl) => pl, - None => return Err(ImageState::NotRequested), - }; + }; - let meta = match pl.metadata { - Some(ref meta) => meta, - None => return Err(ImageState::Pending), - }; - - Ok(ImageOrMetadataAvailable::MetadataAvailable(meta.clone())) - } + // In the case where a decode is ongoing (or waiting in a queue) but we have the + // full response available, we decode the bytes synchronously and ignore the + // async decode when it finishes later. + // TODO: make this behaviour configurable according to the caller's needs. + self.handle_decoder(decoded); + match self.get_completed_image_if_available(&url, placeholder) { + Some(result) => result, + None => Err(ImageState::LoadError), } } - - fn store_decode_image(&mut self, - ref_url: ServoUrl, - loaded_bytes: Vec) { - let (cache_result, load_key, _) = self.pending_loads.get_cached(ref_url.clone()); - assert!(cache_result == CacheResult::Miss); - let action = FetchResponseMsg::ProcessResponseChunk(loaded_bytes); - let _ = self.progress_sender.send(ResourceLoadInfo { - action: action, - key: load_key, - }); - let action = FetchResponseMsg::ProcessResponseEOF(Ok(())); - let _ = self.progress_sender.send(ResourceLoadInfo { - action: action, - key: load_key, - }); - } } /// Create a new image cache. -pub fn new_image_cache_thread(core_resource_thread: CoreResourceThread, - webrender_api: webrender_traits::RenderApi) -> ImageCacheThread { +pub fn new_image_cache_thread(webrender_api: webrender_traits::RenderApi) -> ImageCacheThread { let (ipc_command_sender, ipc_command_receiver) = ipc::channel().unwrap(); thread::Builder::new().name("ImageCacheThread".to_owned()).spawn(move || { - ImageCache::run(core_resource_thread, webrender_api, ipc_command_receiver) + ImageCache::run(webrender_api, ipc_command_receiver) }).expect("Thread spawning failed"); ImageCacheThread::new(ipc_command_sender) } + +fn decode_bytes_sync(key: LoadKey, bytes: &[u8]) -> DecoderMsg { + let image = load_from_memory(bytes); + DecoderMsg { + key: key, + image: image + } +} diff --git a/servo/components/net_traits/image_cache_thread.rs b/servo/components/net_traits/image_cache_thread.rs index 4fb7aedee041..49bd1ea1c8f8 100644 --- a/servo/components/net_traits/image_cache_thread.rs +++ b/servo/components/net_traits/image_cache_thread.rs @@ -2,6 +2,7 @@ * 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/. */ +use FetchResponseMsg; use image::base::{Image, ImageMetadata}; use ipc_channel::ipc::{self, IpcSender}; use servo_url::ServoUrl; @@ -13,27 +14,45 @@ use std::sync::Arc; /// and/or repaint. #[derive(Clone, Deserialize, Serialize)] pub struct ImageResponder { - sender: IpcSender, + id: PendingImageId, + sender: IpcSender, +} + +#[derive(Deserialize, Serialize)] +pub struct PendingImageResponse { + pub response: ImageResponse, + pub id: PendingImageId, } impl ImageResponder { - pub fn new(sender: IpcSender) -> ImageResponder { + pub fn new(sender: IpcSender, id: PendingImageId) -> ImageResponder { ImageResponder { sender: sender, + id: id, } } pub fn respond(&self, response: ImageResponse) { - self.sender.send(response).unwrap() + // This send can fail if thread waiting for this notification has panicked. + // That's not a case that's worth warning about. + // TODO(#15501): are there cases in which we should perform cleanup? + let _ = self.sender.send(PendingImageResponse { + response: response, + id: self.id, + }); } } +/// The unique id for an image that has previously been requested. +#[derive(Copy, Clone, PartialEq, Eq, Deserialize, Serialize, HeapSizeOf, Hash, Debug)] +pub struct PendingImageId(pub u64); + /// The current state of an image in the cache. #[derive(PartialEq, Copy, Clone, Deserialize, Serialize)] pub enum ImageState { - Pending, + Pending(PendingImageId), LoadError, - NotRequested, + NotRequested(PendingImageId), } /// The returned image. @@ -56,45 +75,22 @@ pub enum ImageOrMetadataAvailable { MetadataAvailable(ImageMetadata), } -/// Channel used by the image cache to send results. -#[derive(Clone, Deserialize, Serialize)] -pub struct ImageCacheChan(pub IpcSender); - -/// The result of an image cache command that is returned to the -/// caller. -#[derive(Deserialize, Serialize)] -pub struct ImageCacheResult { - pub responder: Option, - pub image_response: ImageResponse, -} - /// Commands that the image cache understands. #[derive(Deserialize, Serialize)] pub enum ImageCacheCommand { - /// Request an image asynchronously from the cache. Supply a channel - /// to receive the result, and optionally an image responder - /// that is passed to the result channel. - RequestImage(ServoUrl, ImageCacheChan, Option), - - /// Requests an image and a "metadata-ready" notification message asynchronously from the - /// cache. The cache will make an effort to send metadata before the image is completely - /// loaded. Supply a channel to receive the results, and optionally an image responder - /// that is passed to the result channel. - RequestImageAndMetadata(ServoUrl, ImageCacheChan, Option), - - /// Synchronously check the state of an image in the cache. - /// TODO(gw): Profile this on some real world sites and see - /// if it's worth caching the results of this locally in each - /// layout / paint thread. - GetImageIfAvailable(ServoUrl, UsePlaceholder, IpcSender, ImageState>>), - /// Synchronously check the state of an image in the cache. If the image is in a loading /// state and but its metadata has been made available, it will be sent as a response. - GetImageOrMetadataIfAvailable(ServoUrl, UsePlaceholder, IpcSender>), + GetImageOrMetadataIfAvailable(ServoUrl, + UsePlaceholder, + CanRequestImages, + IpcSender>), + + /// Add a new listener for the given pending image. + AddListener(PendingImageId, ImageResponder), /// Instruct the cache to store this data as a newly-complete network request and continue /// decoding the result into pixel data - StoreDecodeImage(ServoUrl, Vec), + StoreDecodeImage(PendingImageId, FetchResponseMsg), /// Clients must wait for a response before shutting down the ResourceThread Exit(IpcSender<()>), @@ -106,6 +102,15 @@ pub enum UsePlaceholder { Yes, } +/// Whether a consumer is in a position to request images or not. This can occur when +/// animations are being processed by the layout thread while the script thread is executing +/// in parallel. +#[derive(Copy, Clone, PartialEq, Deserialize, Serialize)] +pub enum CanRequestImages { + No, + Yes, +} + /// The client side of the image cache thread. This can be safely cloned /// and passed to different threads. #[derive(Clone, Deserialize, Serialize)] @@ -122,52 +127,41 @@ impl ImageCacheThread { } } - /// Asynchronously request an image. See ImageCacheCommand::RequestImage. - pub fn request_image(&self, url: ServoUrl, result_chan: ImageCacheChan, responder: Option) { - let msg = ImageCacheCommand::RequestImage(url, result_chan, responder); - let _ = self.chan.send(msg); - } - - /// Asynchronously request an image and metadata. - /// See ImageCacheCommand::RequestImageAndMetadata - pub fn request_image_and_metadata(&self, - url: ServoUrl, - result_chan: ImageCacheChan, - responder: Option) { - let msg = ImageCacheCommand::RequestImageAndMetadata(url, result_chan, responder); - let _ = self.chan.send(msg); - } - - /// Get the current state of an image. See ImageCacheCommand::GetImageIfAvailable. - pub fn find_image(&self, url: ServoUrl, use_placeholder: UsePlaceholder) -> Result, ImageState> { - let (sender, receiver) = ipc::channel().unwrap(); - let msg = ImageCacheCommand::GetImageIfAvailable(url, use_placeholder, sender); - let _ = self.chan.send(msg); - try!(receiver.recv().map_err(|_| ImageState::LoadError)) - } - /// Get the current state of an image, returning its metadata if available. /// See ImageCacheCommand::GetImageOrMetadataIfAvailable. /// /// FIXME: We shouldn't do IPC for data uris! pub fn find_image_or_metadata(&self, url: ServoUrl, - use_placeholder: UsePlaceholder) + use_placeholder: UsePlaceholder, + can_request: CanRequestImages) -> Result { let (sender, receiver) = ipc::channel().unwrap(); - let msg = ImageCacheCommand::GetImageOrMetadataIfAvailable(url, use_placeholder, sender); + let msg = ImageCacheCommand::GetImageOrMetadataIfAvailable(url, + use_placeholder, + can_request, + sender); let _ = self.chan.send(msg); try!(receiver.recv().map_err(|_| ImageState::LoadError)) } - /// Decode the given image bytes and cache the result for the given URL. - pub fn store_complete_image_bytes(&self, url: ServoUrl, image_data: Vec) { - let msg = ImageCacheCommand::StoreDecodeImage(url, image_data); - let _ = self.chan.send(msg); + /// Add a new listener for the given pending image id. If the image is already present, + /// the responder will still receive the expected response. + pub fn add_listener(&self, id: PendingImageId, responder: ImageResponder) { + let msg = ImageCacheCommand::AddListener(id, responder); + self.chan.send(msg).expect("Image cache thread is not available"); + } + + /// Inform the image cache about a response for a pending request. + pub fn notify_pending_response(&self, id: PendingImageId, data: FetchResponseMsg) { + let msg = ImageCacheCommand::StoreDecodeImage(id, data); + self.chan.send(msg).expect("Image cache thread is not available"); } /// Shutdown the image cache thread. pub fn exit(&self) { + // If the image cache is not available when we're trying to shut it down, + // that is not worth warning about. let (response_chan, response_port) = ipc::channel().unwrap(); let _ = self.chan.send(ImageCacheCommand::Exit(response_chan)); let _ = response_port.recv(); diff --git a/servo/components/net_traits/lib.rs b/servo/components/net_traits/lib.rs index 8f1e004e8b01..d2ffee09887b 100644 --- a/servo/components/net_traits/lib.rs +++ b/servo/components/net_traits/lib.rs @@ -192,7 +192,7 @@ pub trait FetchTaskTarget { fn process_response_eof(&mut self, response: &Response); } -#[derive(Serialize, Deserialize)] +#[derive(Clone, Serialize, Deserialize)] pub enum FilteredMetadata { Basic(Metadata), Cors(Metadata), @@ -200,7 +200,7 @@ pub enum FilteredMetadata { OpaqueRedirect } -#[derive(Serialize, Deserialize)] +#[derive(Clone, Serialize, Deserialize)] pub enum FetchMetadata { Unfiltered(Metadata), Filtered { diff --git a/servo/components/script/document_loader.rs b/servo/components/script/document_loader.rs index 30d83019c5fa..a4ce36a2f575 100644 --- a/servo/components/script/document_loader.rs +++ b/servo/components/script/document_loader.rs @@ -116,6 +116,13 @@ impl DocumentLoader { request: RequestInit, fetch_target: IpcSender) { self.add_blocking_load(load); + self.fetch_async_background(request, fetch_target); + } + + /// Initiate a new fetch that does not block the document load event. + pub fn fetch_async_background(&mut self, + request: RequestInit, + fetch_target: IpcSender) { self.resource_threads.sender().send(CoreResourceMsg::Fetch(request, fetch_target)).unwrap(); } diff --git a/servo/components/script/dom/bindings/trace.rs b/servo/components/script/dom/bindings/trace.rs index 0e605780a20b..4d38b39d333f 100644 --- a/servo/components/script/dom/bindings/trace.rs +++ b/servo/components/script/dom/bindings/trace.rs @@ -62,7 +62,7 @@ use msg::constellation_msg::{FrameId, FrameType, PipelineId}; use net_traits::{Metadata, NetworkError, ReferrerPolicy, ResourceThreads}; use net_traits::filemanager_thread::RelativePos; use net_traits::image::base::{Image, ImageMetadata}; -use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheThread}; +use net_traits::image_cache_thread::{ImageCacheThread, PendingImageId}; use net_traits::request::{Request, RequestInit}; use net_traits::response::{Response, ResponseBody}; use net_traits::response::HttpsState; @@ -320,7 +320,7 @@ unsafe_no_jsmanaged_fields!(bool, f32, f64, String, AtomicBool, AtomicUsize, Uui unsafe_no_jsmanaged_fields!(usize, u8, u16, u32, u64); unsafe_no_jsmanaged_fields!(isize, i8, i16, i32, i64); unsafe_no_jsmanaged_fields!(ServoUrl, ImmutableOrigin, MutableOrigin); -unsafe_no_jsmanaged_fields!(Image, ImageMetadata, ImageCacheChan, ImageCacheThread); +unsafe_no_jsmanaged_fields!(Image, ImageMetadata, ImageCacheThread, PendingImageId); unsafe_no_jsmanaged_fields!(Metadata); unsafe_no_jsmanaged_fields!(NetworkError); unsafe_no_jsmanaged_fields!(Atom, Prefix, LocalName, Namespace, QualName); diff --git a/servo/components/script/dom/canvasrenderingcontext2d.rs b/servo/components/script/dom/canvasrenderingcontext2d.rs index fff339e1cc7a..065b966d9391 100644 --- a/servo/components/script/dom/canvasrenderingcontext2d.rs +++ b/servo/components/script/dom/canvasrenderingcontext2d.rs @@ -429,7 +429,9 @@ impl CanvasRenderingContext2D { let img = match self.request_image_from_cache(url) { ImageResponse::Loaded(img) => img, - ImageResponse::PlaceholderLoaded(_) | ImageResponse::None | ImageResponse::MetadataLoaded(_) => { + ImageResponse::PlaceholderLoaded(_) | + ImageResponse::None | + ImageResponse::MetadataLoaded(_) => { return None; } }; diff --git a/servo/components/script/dom/htmlcanvaselement.rs b/servo/components/script/dom/htmlcanvaselement.rs index b174d2ec9a81..a51463f46749 100644 --- a/servo/components/script/dom/htmlcanvaselement.rs +++ b/servo/components/script/dom/htmlcanvaselement.rs @@ -337,15 +337,20 @@ impl<'a> From<&'a WebGLContextAttributes> for GLContextAttributes { pub mod utils { use dom::window::Window; - use ipc_channel::ipc; - use net_traits::image_cache_thread::{ImageCacheChan, ImageResponse}; + use net_traits::image_cache_thread::{ImageResponse, UsePlaceholder, ImageOrMetadataAvailable}; + use net_traits::image_cache_thread::CanRequestImages; use servo_url::ServoUrl; pub fn request_image_from_cache(window: &Window, url: ServoUrl) -> ImageResponse { let image_cache = window.image_cache_thread(); - let (response_chan, response_port) = ipc::channel().unwrap(); - image_cache.request_image(url.into(), ImageCacheChan(response_chan), None); - let result = response_port.recv().unwrap(); - result.image_response + let response = + image_cache.find_image_or_metadata(url.into(), + UsePlaceholder::No, + CanRequestImages::No); + match response { + Ok(ImageOrMetadataAvailable::ImageAvailable(image)) => + ImageResponse::Loaded(image), + _ => ImageResponse::None, + } } } diff --git a/servo/components/script/dom/htmlimageelement.rs b/servo/components/script/dom/htmlimageelement.rs index ec9f2e1ec808..af98b0134105 100644 --- a/servo/components/script/dom/htmlimageelement.rs +++ b/servo/components/script/dom/htmlimageelement.rs @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use app_units::{Au, AU_PER_PX}; +use document_loader::{LoadType, LoadBlocker}; use dom::activation::Activatable; use dom::attr::Attr; use dom::bindings::cell::DOMRefCell; @@ -16,6 +17,7 @@ use dom::bindings::error::Fallible; use dom::bindings::inheritance::Castable; use dom::bindings::js::{LayoutJS, Root}; use dom::bindings::refcounted::Trusted; +use dom::bindings::reflector::DomObject; use dom::bindings::str::DOMString; use dom::document::Document; use dom::element::{AttributeMutation, Element, RawLayoutElementHelpers}; @@ -34,13 +36,18 @@ use euclid::point::Point2D; use html5ever_atoms::LocalName; use ipc_channel::ipc; use ipc_channel::router::ROUTER; +use net_traits::{FetchResponseListener, FetchMetadata, NetworkError, FetchResponseMsg}; use net_traits::image::base::{Image, ImageMetadata}; -use net_traits::image_cache_thread::{ImageResponder, ImageResponse}; +use net_traits::image_cache_thread::{ImageResponder, ImageResponse, PendingImageId, ImageState}; +use net_traits::image_cache_thread::{UsePlaceholder, ImageOrMetadataAvailable, CanRequestImages}; +use net_traits::image_cache_thread::ImageCacheThread; +use net_traits::request::{RequestInit, Type as RequestType}; +use network_listener::{NetworkListener, PreInvoke}; use num_traits::ToPrimitive; use script_thread::Runnable; use servo_url::ServoUrl; use std::i32; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use style::attr::{AttrValue, LengthOrPercentageOrAuto}; use task_source::TaskSource; @@ -53,10 +60,12 @@ enum State { Broken, } #[derive(JSTraceable, HeapSizeOf)] +#[must_root] struct ImageRequest { state: State, parsed_url: Option, source_url: Option, + blocker: Option, #[ignore_heap_size_of = "Arc"] image: Option>, metadata: Option, @@ -74,7 +83,6 @@ impl HTMLImageElement { } } - struct ImageResponseHandlerRunnable { element: Trusted, image: ImageResponse, @@ -94,75 +102,225 @@ impl Runnable for ImageResponseHandlerRunnable { fn name(&self) -> &'static str { "ImageResponseHandlerRunnable" } fn handler(self: Box) { - // Update the image field let element = self.element.root(); - let (image, metadata, trigger_image_load, trigger_image_error) = match self.image { + element.process_image_response(self.image); + } +} + +/// The context required for asynchronously loading an external image. +struct ImageContext { + /// The element that initiated the request. + elem: Trusted, + /// The initial URL requested. + url: ServoUrl, + /// Indicates whether the request failed, and why + status: Result<(), NetworkError>, + /// The cache ID for this request. + id: PendingImageId, +} + +impl ImageContext { + fn image_cache(&self) -> ImageCacheThread { + let elem = self.elem.root(); + window_from_node(&*elem).image_cache_thread().clone() + } +} + +impl FetchResponseListener for ImageContext { + fn process_request_body(&mut self) {} + fn process_request_eof(&mut self) {} + + fn process_response(&mut self, metadata: Result) { + self.image_cache().notify_pending_response( + self.id, + FetchResponseMsg::ProcessResponse(metadata.clone())); + + let metadata = metadata.ok().map(|meta| { + match meta { + FetchMetadata::Unfiltered(m) => m, + FetchMetadata::Filtered { unsafe_, .. } => unsafe_ + } + }); + + let status_code = metadata.as_ref().and_then(|m| { + m.status.as_ref().map(|&(code, _)| code) + }).unwrap_or(0); + + self.status = match status_code { + 0 => Err(NetworkError::Internal("No http status code received".to_owned())), + 200...299 => Ok(()), // HTTP ok status codes + _ => Err(NetworkError::Internal(format!("HTTP error code {}", status_code))) + }; + } + + fn process_response_chunk(&mut self, payload: Vec) { + if self.status.is_ok() { + self.image_cache().notify_pending_response( + self.id, + FetchResponseMsg::ProcessResponseChunk(payload)); + } + } + + fn process_response_eof(&mut self, response: Result<(), NetworkError>) { + let elem = self.elem.root(); + let document = document_from_node(&*elem); + let image_cache = self.image_cache(); + image_cache.notify_pending_response(self.id, + FetchResponseMsg::ProcessResponseEOF(response)); + document.finish_load(LoadType::Image(self.url.clone())); + } +} + +impl PreInvoke for ImageContext {} + +impl HTMLImageElement { + /// Update the current image with a valid URL. + fn update_image_with_url(&self, img_url: ServoUrl, src: DOMString) { + { + let mut current_request = self.current_request.borrow_mut(); + current_request.parsed_url = Some(img_url.clone()); + current_request.source_url = Some(src); + + LoadBlocker::terminate(&mut current_request.blocker); + let document = document_from_node(self); + current_request.blocker = + Some(LoadBlocker::new(&*document, LoadType::Image(img_url.clone()))); + } + + fn add_cache_listener_for_element(image_cache: &ImageCacheThread, + id: PendingImageId, + elem: &HTMLImageElement) { + let trusted_node = Trusted::new(elem); + let (responder_sender, responder_receiver) = ipc::channel().unwrap(); + + let window = window_from_node(elem); + let task_source = window.networking_task_source(); + let wrapper = window.get_runnable_wrapper(); + ROUTER.add_route(responder_receiver.to_opaque(), box move |message| { + // Return the image via a message to the script thread, which marks the element + // as dirty and triggers a reflow. + let runnable = ImageResponseHandlerRunnable::new( + trusted_node.clone(), message.to().unwrap()); + let _ = task_source.queue_with_wrapper(box runnable, &wrapper); + }); + + image_cache.add_listener(id, ImageResponder::new(responder_sender, id)); + } + + let window = window_from_node(self); + let image_cache = window.image_cache_thread(); + let response = + image_cache.find_image_or_metadata(img_url.clone().into(), + UsePlaceholder::Yes, + CanRequestImages::Yes); + match response { + Ok(ImageOrMetadataAvailable::ImageAvailable(image)) => { + self.process_image_response(ImageResponse::Loaded(image)); + } + + Ok(ImageOrMetadataAvailable::MetadataAvailable(m)) => { + self.process_image_response(ImageResponse::MetadataLoaded(m)); + } + + Err(ImageState::Pending(id)) => { + add_cache_listener_for_element(image_cache, id, self); + } + + Err(ImageState::LoadError) => { + self.process_image_response(ImageResponse::None); + } + + Err(ImageState::NotRequested(id)) => { + add_cache_listener_for_element(image_cache, id, self); + self.request_image(img_url, id); + } + } + } + + fn request_image(&self, img_url: ServoUrl, id: PendingImageId) { + let document = document_from_node(self); + let window = window_from_node(self); + + let context = Arc::new(Mutex::new(ImageContext { + elem: Trusted::new(self), + url: img_url.clone(), + status: Ok(()), + id: id, + })); + + let (action_sender, action_receiver) = ipc::channel().unwrap(); + let listener = NetworkListener { + context: context, + task_source: window.networking_task_source(), + wrapper: Some(window.get_runnable_wrapper()), + }; + ROUTER.add_route(action_receiver.to_opaque(), box move |message| { + listener.notify_fetch(message.to().unwrap()); + }); + + let request = RequestInit { + url: img_url.clone(), + origin: document.url().clone(), + type_: RequestType::Image, + pipeline_id: Some(document.global().pipeline_id()), + .. RequestInit::default() + }; + + document.fetch_async(LoadType::Image(img_url), request, action_sender); + } + + fn process_image_response(&self, image: ImageResponse) { + let (image, metadata, trigger_image_load, trigger_image_error) = match image { ImageResponse::Loaded(image) | ImageResponse::PlaceholderLoaded(image) => { - (Some(image.clone()), Some(ImageMetadata { height: image.height, width: image.width } ), true, false) + (Some(image.clone()), + Some(ImageMetadata { height: image.height, width: image.width }), + true, + false) } ImageResponse::MetadataLoaded(meta) => { (None, Some(meta), false, false) } ImageResponse::None => (None, None, false, true) }; - element.current_request.borrow_mut().image = image; - element.current_request.borrow_mut().metadata = metadata; + self.current_request.borrow_mut().image = image; + self.current_request.borrow_mut().metadata = metadata; // Mark the node dirty - let document = document_from_node(&*element); - element.upcast::().dirty(NodeDamage::OtherNodeDamage); + self.upcast::().dirty(NodeDamage::OtherNodeDamage); // Fire image.onload if trigger_image_load { - element.upcast::().fire_event(atom!("load")); + self.upcast::().fire_event(atom!("load")); } // Fire image.onerror if trigger_image_error { - element.upcast::().fire_event(atom!("error")); + self.upcast::().fire_event(atom!("error")); } + LoadBlocker::terminate(&mut self.current_request.borrow_mut().blocker); + // Trigger reflow - let window = window_from_node(&*document); + let window = window_from_node(self); window.add_pending_reflow(); } -} -impl HTMLImageElement { /// Makes the local `image` member match the status of the `src` attribute and starts /// prefetching the image. This method must be called after `src` is changed. fn update_image(&self, value: Option<(DOMString, ServoUrl)>) { let document = document_from_node(self); let window = document.window(); - let image_cache = window.image_cache_thread(); match value { None => { self.current_request.borrow_mut().parsed_url = None; self.current_request.borrow_mut().source_url = None; + LoadBlocker::terminate(&mut self.current_request.borrow_mut().blocker); self.current_request.borrow_mut().image = None; } Some((src, base_url)) => { let img_url = base_url.join(&src); if let Ok(img_url) = img_url { - self.current_request.borrow_mut().parsed_url = Some(img_url.clone()); - self.current_request.borrow_mut().source_url = Some(src); - - let trusted_node = Trusted::new(self); - let (responder_sender, responder_receiver) = ipc::channel().unwrap(); - let task_source = window.networking_task_source(); - let wrapper = window.get_runnable_wrapper(); - ROUTER.add_route(responder_receiver.to_opaque(), box move |message| { - // Return the image via a message to the script thread, which marks the element - // as dirty and triggers a reflow. - let image_response = message.to().unwrap(); - let runnable = box ImageResponseHandlerRunnable::new( - trusted_node.clone(), image_response); - let _ = task_source.queue_with_wrapper(runnable, &wrapper); - }); - - image_cache.request_image_and_metadata(img_url.into(), - window.image_cache_chan(), - Some(ImageResponder::new(responder_sender))); + self.update_image_with_url(img_url, src); } else { // https://html.spec.whatwg.org/multipage/#update-the-image-data // Step 11 (error substeps) @@ -202,6 +360,7 @@ impl HTMLImageElement { } } } + fn new_inherited(local_name: LocalName, prefix: Option, document: &Document) -> HTMLImageElement { HTMLImageElement { htmlelement: HTMLElement::new_inherited(local_name, prefix, document), @@ -210,14 +369,16 @@ impl HTMLImageElement { parsed_url: None, source_url: None, image: None, - metadata: None + metadata: None, + blocker: None, }), pending_request: DOMRefCell::new(ImageRequest { state: State::Unavailable, parsed_url: None, source_url: None, image: None, - metadata: None + metadata: None, + blocker: None, }), } } diff --git a/servo/components/script/dom/window.rs b/servo/components/script/dom/window.rs index b6392fbdd19c..93cdd1c31d05 100644 --- a/servo/components/script/dom/window.rs +++ b/servo/components/script/dom/window.rs @@ -42,7 +42,7 @@ use dom::location::Location; use dom::mediaquerylist::{MediaQueryList, WeakMediaQueryListVec}; use dom::messageevent::MessageEvent; use dom::navigator::Navigator; -use dom::node::{Node, from_untrusted_node_address, window_from_node}; +use dom::node::{Node, from_untrusted_node_address, window_from_node, NodeDamage}; use dom::performance::Performance; use dom::promise::Promise; use dom::screen::Screen; @@ -52,20 +52,23 @@ use euclid::{Point2D, Rect, Size2D}; use fetch; use gfx_traits::ScrollRootId; use ipc_channel::ipc::{self, IpcSender}; +use ipc_channel::router::ROUTER; use js::jsapi::{HandleObject, HandleValue, JSAutoCompartment, JSContext}; use js::jsapi::{JS_GC, JS_GetRuntime}; use js::jsval::UndefinedValue; use js::rust::Runtime; +use layout_image::fetch_image_for_layout; use msg::constellation_msg::{FrameType, PipelineId}; use net_traits::{ResourceThreads, ReferrerPolicy}; -use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheThread}; +use net_traits::image_cache_thread::{ImageResponder, ImageResponse}; +use net_traits::image_cache_thread::{PendingImageResponse, ImageCacheThread, PendingImageId}; use net_traits::storage_thread::StorageType; use num_traits::ToPrimitive; use open; use profile_traits::mem::ProfilerChan as MemProfilerChan; use profile_traits::time::ProfilerChan as TimeProfilerChan; use rustc_serialize::base64::{FromBase64, STANDARD, ToBase64}; -use script_layout_interface::TrustedNodeAddress; +use script_layout_interface::{TrustedNodeAddress, PendingImageState}; use script_layout_interface::message::{Msg, Reflow, ReflowQueryType, ScriptReflow}; use script_layout_interface::reporter::CSSErrorReporter; use script_layout_interface::rpc::{ContentBoxResponse, ContentBoxesResponse, LayoutRPC}; @@ -73,7 +76,7 @@ use script_layout_interface::rpc::{MarginStyleResponse, NodeScrollRootIdResponse use script_layout_interface::rpc::{ResolvedStyleResponse, TextIndexResponse}; use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, ScriptThreadEventCategory}; use script_thread::{MainThreadScriptChan, MainThreadScriptMsg, Runnable, RunnableWrapper}; -use script_thread::SendableMainThreadScriptChan; +use script_thread::{SendableMainThreadScriptChan, ImageCacheMsg}; use script_traits::{ConstellationControlMsg, LoadData, MozBrowserEvent, UntrustedNodeAddress}; use script_traits::{DocumentState, TimerEvent, TimerEventId}; use script_traits::{ScriptMsg as ConstellationMsg, TimerEventRequest, WindowSizeData, WindowSizeType}; @@ -87,6 +90,7 @@ use std::ascii::AsciiExt; use std::borrow::ToOwned; use std::cell::Cell; use std::collections::{HashMap, HashSet}; +use std::collections::hash_map::Entry; use std::default::Default; use std::io::{Write, stderr, stdout}; use std::mem; @@ -165,7 +169,7 @@ pub struct Window { #[ignore_heap_size_of = "channels are hard"] image_cache_thread: ImageCacheThread, #[ignore_heap_size_of = "channels are hard"] - image_cache_chan: ImageCacheChan, + image_cache_chan: Sender, browsing_context: MutNullableJS, document: MutNullableJS, history: MutNullableJS, @@ -253,7 +257,13 @@ pub struct Window { webvr_thread: Option>, /// A map for storing the previous permission state read results. - permission_state_invocation_results: DOMRefCell> + permission_state_invocation_results: DOMRefCell>, + + /// All of the elements that have an outstanding image request that was + /// initiated by layout during a reflow. They are stored in the script thread + /// to ensure that the element can be marked dirty when the image data becomes + /// available at some point in the future. + pending_layout_images: DOMRefCell>>>, } impl Window { @@ -295,10 +305,6 @@ impl Window { &self.script_chan.0 } - pub fn image_cache_chan(&self) -> ImageCacheChan { - self.image_cache_chan.clone() - } - pub fn parent_info(&self) -> Option<(PipelineId, FrameType)> { self.parent_info } @@ -346,6 +352,28 @@ impl Window { pub fn permission_state_invocation_results(&self) -> &DOMRefCell> { &self.permission_state_invocation_results } + + pub fn pending_image_notification(&self, response: PendingImageResponse) { + //XXXjdm could be more efficient to send the responses to the layout thread, + // rather than making the layout thread talk to the image cache to + // obtain the same data. + let mut images = self.pending_layout_images.borrow_mut(); + let nodes = images.entry(response.id); + let nodes = match nodes { + Entry::Occupied(nodes) => nodes, + Entry::Vacant(_) => return, + }; + for node in nodes.get() { + node.dirty(NodeDamage::OtherNodeDamage); + } + match response.response { + ImageResponse::MetadataLoaded(_) => {} + ImageResponse::Loaded(_) | + ImageResponse::PlaceholderLoaded(_) | + ImageResponse::None => { nodes.remove(); } + } + self.add_pending_reflow(); + } } #[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))] @@ -1168,6 +1196,31 @@ impl Window { self.emit_timeline_marker(marker.end()); } + let pending_images = self.layout_rpc.pending_images(); + for image in pending_images { + let id = image.id; + let js_runtime = self.js_runtime.borrow(); + let js_runtime = js_runtime.as_ref().unwrap(); + let node = from_untrusted_node_address(js_runtime.rt(), image.node); + + if let PendingImageState::Unrequested(ref url) = image.state { + fetch_image_for_layout(url.clone(), &*node, id, self.image_cache_thread.clone()); + } + + let mut images = self.pending_layout_images.borrow_mut(); + let nodes = images.entry(id).or_insert(vec![]); + if nodes.iter().find(|n| &***n as *const _ == &*node as *const _).is_none() { + let (responder, responder_listener) = ipc::channel().unwrap(); + let pipeline = self.upcast::().pipeline_id(); + let image_cache_chan = self.image_cache_chan.clone(); + ROUTER.add_route(responder_listener.to_opaque(), box move |message| { + let _ = image_cache_chan.send((pipeline, message.to().unwrap())); + }); + self.image_cache_thread.add_listener(id, ImageResponder::new(responder, id)); + nodes.push(JS::from_ref(&*node)); + } + } + true } @@ -1227,7 +1280,8 @@ impl Window { let ready_state = document.ReadyState(); - if ready_state == DocumentReadyState::Complete && !reftest_wait { + let pending_images = self.pending_layout_images.borrow().is_empty(); + if ready_state == DocumentReadyState::Complete && !reftest_wait && pending_images { let global_scope = self.upcast::(); let event = ConstellationMsg::SetDocumentState(global_scope.pipeline_id(), DocumentState::Idle); global_scope.constellation_chan().send(event).unwrap(); @@ -1635,7 +1689,7 @@ impl Window { network_task_source: NetworkingTaskSource, history_task_source: HistoryTraversalTaskSource, file_task_source: FileReadingTaskSource, - image_cache_chan: ImageCacheChan, + image_cache_chan: Sender, image_cache_thread: ImageCacheThread, resource_threads: ResourceThreads, bluetooth_thread: IpcSender, @@ -1717,6 +1771,7 @@ impl Window { test_runner: Default::default(), webvr_thread: webvr_thread, permission_state_invocation_results: DOMRefCell::new(HashMap::new()), + pending_layout_images: DOMRefCell::new(HashMap::new()), }; unsafe { diff --git a/servo/components/script/layout_image.rs b/servo/components/script/layout_image.rs new file mode 100644 index 000000000000..d903b435c260 --- /dev/null +++ b/servo/components/script/layout_image.rs @@ -0,0 +1,81 @@ +/* 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/. */ + +//! Infrastructure to initiate network requests for images needed by the layout +//! thread. The script thread needs to be responsible for them because there's +//! no guarantee that the responsible nodes will still exist in the future if the +//! layout thread holds on to them during asynchronous operations. + +use dom::bindings::reflector::DomObject; +use dom::node::{Node, document_from_node}; +use ipc_channel::ipc; +use ipc_channel::router::ROUTER; +use net_traits::{FetchResponseMsg, FetchResponseListener, FetchMetadata, NetworkError}; +use net_traits::image_cache_thread::{ImageCacheThread, PendingImageId}; +use net_traits::request::{Type as RequestType, RequestInit as FetchRequestInit}; +use network_listener::{NetworkListener, PreInvoke}; +use servo_url::ServoUrl; +use std::sync::{Arc, Mutex}; + +struct LayoutImageContext { + id: PendingImageId, + cache: ImageCacheThread, +} + +impl FetchResponseListener for LayoutImageContext { + fn process_request_body(&mut self) {} + fn process_request_eof(&mut self) {} + fn process_response(&mut self, metadata: Result) { + self.cache.notify_pending_response( + self.id, + FetchResponseMsg::ProcessResponse(metadata)); + } + + fn process_response_chunk(&mut self, payload: Vec) { + self.cache.notify_pending_response( + self.id, + FetchResponseMsg::ProcessResponseChunk(payload)); + } + + fn process_response_eof(&mut self, response: Result<(), NetworkError>) { + self.cache.notify_pending_response(self.id, + FetchResponseMsg::ProcessResponseEOF(response)); + } +} + +impl PreInvoke for LayoutImageContext {} + +pub fn fetch_image_for_layout(url: ServoUrl, + node: &Node, + id: PendingImageId, + cache: ImageCacheThread) { + let context = Arc::new(Mutex::new(LayoutImageContext { + id: id, + cache: cache, + })); + + let document = document_from_node(node); + let window = document.window(); + + let (action_sender, action_receiver) = ipc::channel().unwrap(); + let listener = NetworkListener { + context: context, + task_source: window.networking_task_source(), + wrapper: Some(window.get_runnable_wrapper()), + }; + ROUTER.add_route(action_receiver.to_opaque(), box move |message| { + listener.notify_fetch(message.to().unwrap()); + }); + + let request = FetchRequestInit { + url: url, + origin: document.url().clone(), + type_: RequestType::Image, + pipeline_id: Some(document.global().pipeline_id()), + .. FetchRequestInit::default() + }; + + // Layout image loads do not delay the document load event. + document.mut_loader().fetch_async_background(request, action_sender); +} diff --git a/servo/components/script/lib.rs b/servo/components/script/lib.rs index e5c93357bd20..81c7eb0901f3 100644 --- a/servo/components/script/lib.rs +++ b/servo/components/script/lib.rs @@ -110,6 +110,7 @@ pub mod document_loader; #[macro_use] mod dom; pub mod fetch; +mod layout_image; pub mod layout_wrapper; mod mem; mod microtask; diff --git a/servo/components/script/script_thread.rs b/servo/components/script/script_thread.rs index 2ab421c707bb..192923294a66 100644 --- a/servo/components/script/script_thread.rs +++ b/servo/components/script/script_thread.rs @@ -73,7 +73,7 @@ use microtask::{MicrotaskQueue, Microtask}; use msg::constellation_msg::{FrameId, FrameType, PipelineId, PipelineNamespace}; use net_traits::{CoreResourceMsg, FetchMetadata, FetchResponseListener}; use net_traits::{IpcSend, Metadata, ReferrerPolicy, ResourceThreads}; -use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheResult, ImageCacheThread}; +use net_traits::image_cache_thread::{PendingImageResponse, ImageCacheThread}; use net_traits::request::{CredentialsMode, Destination, RequestInit}; use net_traits::storage_thread::StorageType; use network_listener::NetworkListener; @@ -120,6 +120,8 @@ use url::Position; use webdriver_handlers; use webvr_traits::WebVRMsg; +pub type ImageCacheMsg = (PipelineId, PendingImageResponse); + thread_local!(pub static STACK_ROOTS: Cell> = Cell::new(None)); thread_local!(static SCRIPT_THREAD_ROOT: Cell> = Cell::new(None)); @@ -230,7 +232,7 @@ enum MixedMessage { FromConstellation(ConstellationControlMsg), FromScript(MainThreadScriptMsg), FromDevtools(DevtoolScriptControlMsg), - FromImageCache(ImageCacheResult), + FromImageCache((PipelineId, PendingImageResponse)), FromScheduler(TimerEvent) } @@ -444,10 +446,10 @@ pub struct ScriptThread { layout_to_constellation_chan: IpcSender, /// The port on which we receive messages from the image cache - image_cache_port: Receiver, + image_cache_port: Receiver, /// The channel on which the image cache can send messages to ourself. - image_cache_channel: ImageCacheChan, + image_cache_channel: Sender, /// For providing contact with the time profiler. time_profiler_chan: time::ProfilerChan, @@ -646,11 +648,6 @@ impl ScriptThread { let (ipc_devtools_sender, ipc_devtools_receiver) = ipc::channel().unwrap(); let devtools_port = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(ipc_devtools_receiver); - // Ask the router to proxy IPC messages from the image cache thread to us. - let (ipc_image_cache_channel, ipc_image_cache_port) = ipc::channel().unwrap(); - let image_cache_port = - ROUTER.route_ipc_receiver_to_new_mpsc_receiver(ipc_image_cache_port); - let (timer_event_chan, timer_event_port) = channel(); // Ask the router to proxy IPC messages from the control port to us. @@ -658,6 +655,8 @@ impl ScriptThread { let boxed_script_sender = MainThreadScriptChan(chan.clone()).clone(); + let (image_cache_channel, image_cache_port) = channel(); + ScriptThread { documents: DOMRefCell::new(Documents::new()), browsing_contexts: DOMRefCell::new(HashMap::new()), @@ -666,7 +665,7 @@ impl ScriptThread { job_queue_map: Rc::new(JobQueue::new()), image_cache_thread: state.image_cache_thread, - image_cache_channel: ImageCacheChan(ipc_image_cache_channel), + image_cache_channel: image_cache_channel, image_cache_port: image_cache_port, resource_threads: state.resource_threads, @@ -1111,8 +1110,11 @@ impl ScriptThread { } } - fn handle_msg_from_image_cache(&self, msg: ImageCacheResult) { - msg.responder.unwrap().respond(msg.image_response); + fn handle_msg_from_image_cache(&self, (id, response): (PipelineId, PendingImageResponse)) { + let window = self.documents.borrow().find_window(id); + if let Some(ref window) = window { + window.pending_image_notification(response); + } } fn handle_webdriver_msg(&self, pipeline_id: PipelineId, msg: WebDriverScriptCommand) { diff --git a/servo/components/script_layout_interface/lib.rs b/servo/components/script_layout_interface/lib.rs index 87b76763d7d6..1793e06909d3 100644 --- a/servo/components/script_layout_interface/lib.rs +++ b/servo/components/script_layout_interface/lib.rs @@ -43,6 +43,9 @@ use canvas_traits::CanvasMsg; use core::nonzero::NonZero; use ipc_channel::ipc::IpcSender; use libc::c_void; +use net_traits::image_cache_thread::PendingImageId; +use script_traits::UntrustedNodeAddress; +use servo_url::ServoUrl; use std::sync::atomic::AtomicIsize; use style::data::ElementData; @@ -137,3 +140,18 @@ pub fn is_image_data(uri: &str) -> bool { static TYPES: &'static [&'static str] = &["data:image/png", "data:image/gif", "data:image/jpeg"]; TYPES.iter().any(|&type_| uri.starts_with(type_)) } + +/// Whether the pending image needs to be fetched or is waiting on an existing fetch. +pub enum PendingImageState { + Unrequested(ServoUrl), + PendingResponse, +} + +/// The data associated with an image that is not yet present in the image cache. +/// Used by the script thread to hold on to DOM elements that need to be repainted +/// when an image fetch is complete. +pub struct PendingImage { + pub state: PendingImageState, + pub node: UntrustedNodeAddress, + pub id: PendingImageId, +} diff --git a/servo/components/script_layout_interface/rpc.rs b/servo/components/script_layout_interface/rpc.rs index 2fb75f6b9599..78e99571ee73 100644 --- a/servo/components/script_layout_interface/rpc.rs +++ b/servo/components/script_layout_interface/rpc.rs @@ -2,6 +2,7 @@ * 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/. */ +use PendingImage; use app_units::Au; use euclid::point::Point2D; use euclid::rect::Rect; @@ -37,7 +38,8 @@ pub trait LayoutRPC { fn offset_parent(&self) -> OffsetParentResponse; /// Query layout for the resolve values of the margin properties for an element. fn margin_style(&self) -> MarginStyleResponse; - + /// Requests the list of not-yet-loaded images that were encountered in the last reflow. + fn pending_images(&self) -> Vec; fn nodes_from_point(&self, page_point: Point2D, client_point: Point2D) -> Vec; fn text_index(&self) -> TextIndexResponse; diff --git a/servo/components/script_plugins/unrooted_must_root.rs b/servo/components/script_plugins/unrooted_must_root.rs index 660a0c58781b..ad74f6c4b8fe 100644 --- a/servo/components/script_plugins/unrooted_must_root.rs +++ b/servo/components/script_plugins/unrooted_must_root.rs @@ -52,6 +52,7 @@ fn is_unrooted_ty(cx: &LateContext, ty: &ty::TyS, in_new_function: bool) -> bool } else if match_def_path(cx, did.did, &["core", "cell", "Ref"]) || match_def_path(cx, did.did, &["core", "cell", "RefMut"]) || match_def_path(cx, did.did, &["core", "slice", "Iter"]) + || match_def_path(cx, did.did, &["std", "collections", "hash", "map", "Entry"]) || match_def_path(cx, did.did, &["std", "collections", "hash", "map", "OccupiedEntry"]) || match_def_path(cx, did.did, &["std", "collections", "hash", "map", "VacantEntry"]) { // Structures which are semantically similar to an &ptr. diff --git a/servo/components/servo/lib.rs b/servo/components/servo/lib.rs index afda35f1582a..69b9bbeceb84 100644 --- a/servo/components/servo/lib.rs +++ b/servo/components/servo/lib.rs @@ -281,8 +281,7 @@ fn create_constellation(user_agent: Cow<'static, str>, devtools_chan.clone(), time_profiler_chan.clone(), config_dir); - let image_cache_thread = new_image_cache_thread(public_resource_threads.sender(), - webrender_api_sender.create_api()); + let image_cache_thread = new_image_cache_thread(webrender_api_sender.create_api()); let font_cache_thread = FontCacheThread::new(public_resource_threads.sender(), Some(webrender_api_sender.create_api())); From e4420d12688471296ce12b545779a4377b61cdd6 Mon Sep 17 00:00:00 2001 From: "Alfredo.Yang" Date: Tue, 21 Feb 2017 15:30:03 +0800 Subject: [PATCH 071/234] Bug 1331330 - compare rust parser and stagefright sample table. r=kinetik MozReview-Commit-ID: G6ZqSNNo00J --HG-- extra : rebase_source : 858fe82da9f92417c843e2292519a58afa2f82e2 --- media/libstagefright/binding/MP4Metadata.cpp | 38 ++++++++++++++------ 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/media/libstagefright/binding/MP4Metadata.cpp b/media/libstagefright/binding/MP4Metadata.cpp index 2e03b7abc9c5..ccaace08fa93 100644 --- a/media/libstagefright/binding/MP4Metadata.cpp +++ b/media/libstagefright/binding/MP4Metadata.cpp @@ -140,7 +140,7 @@ public: const CryptoFile& Crypto() const; - bool ReadTrackIndex(FallibleTArray& aDest, mozilla::TrackID aTrackID); + bool ReadTrackIndice(mp4parse_byte_data* aIndices, mozilla::TrackID aTrackID); private: void UpdateCrypto(); @@ -363,13 +363,26 @@ MP4Metadata::Crypto() const bool MP4Metadata::ReadTrackIndex(FallibleTArray& aDest, mozilla::TrackID aTrackID) { -#ifdef MOZ_RUST_MP4PARSE - if (mRust && mPreferRust && mRust->ReadTrackIndex(aDest, aTrackID)) { - return true; + bool ret = mStagefright->ReadTrackIndex(aDest, aTrackID); + +#ifndef RELEASE_OR_BETA + if (mRustTestMode && ret && mRust) { + mp4parse_byte_data data = {}; + bool rustRet = mRust->ReadTrackIndice(&data, aTrackID); + MOZ_DIAGNOSTIC_ASSERT(rustRet); + MOZ_DIAGNOSTIC_ASSERT(data.length == aDest.Length()); + for (uint32_t i = 0; i < data.length; i++) { + MOZ_DIAGNOSTIC_ASSERT(data.indices[i].start_offset == aDest[i].start_offset); + MOZ_DIAGNOSTIC_ASSERT(data.indices[i].end_offset == aDest[i].end_offset); + MOZ_DIAGNOSTIC_ASSERT(data.indices[i].start_composition == aDest[i].start_composition); + MOZ_DIAGNOSTIC_ASSERT(data.indices[i].end_composition == aDest[i].end_composition); + MOZ_DIAGNOSTIC_ASSERT(data.indices[i].start_decode == aDest[i].start_decode); + MOZ_DIAGNOSTIC_ASSERT(data.indices[i].sync == aDest[i].sync); + } } - aDest.Clear(); #endif - return mStagefright->ReadTrackIndex(aDest, aTrackID); + + return ret; } static inline bool @@ -391,6 +404,9 @@ ConvertIndex(FallibleTArray& aDest, indice.sync = s_indice.sync; // FIXME: Make this infallible after bug 968520 is done. MOZ_ALWAYS_TRUE(aDest.AppendElement(indice, mozilla::fallible)); + MOZ_LOG(sLog, LogLevel::Debug, ("s_o: %" PRIu64 ", e_o: %" PRIu64 ", s_c: %" PRIu64 ", e_c: %" PRIu64 ", s_d: %" PRIu64 ", sync: %d\n", + indice.start_offset, indice.end_offset, indice.start_composition, indice.end_composition, + indice.start_decode, indice.sync)); } return true; } @@ -851,7 +867,7 @@ MP4MetadataRust::Crypto() const } bool -MP4MetadataRust::ReadTrackIndex(FallibleTArray& aDest, mozilla::TrackID aTrackID) +MP4MetadataRust::ReadTrackIndice(mp4parse_byte_data* aIndices, mozilla::TrackID aTrackID) { uint8_t fragmented = false; auto rv = mp4parse_is_fragmented(mRustParser.get(), aTrackID, &fragmented); @@ -863,10 +879,12 @@ MP4MetadataRust::ReadTrackIndex(FallibleTArray& aDest, mozilla::T return true; } - // For non-fragmented mp4. - NS_WARNING("Not yet implemented"); + rv = mp4parse_get_indice_table(mRustParser.get(), aTrackID, aIndices); + if (rv != MP4PARSE_OK) { + return false; + } - return false; + return true; } /*static*/ bool From a4ed9eb7351266ab1d3a75a57e888dfb809b6b16 Mon Sep 17 00:00:00 2001 From: Shane Caraveo Date: Wed, 22 Feb 2017 18:47:16 -0800 Subject: [PATCH 072/234] Bug 1313459 support CUI areas for browserAction, r=aswan MozReview-Commit-ID: IoPOCv6M0qy --HG-- extra : rebase_source : b032c4e8d1f9fe3cdc79ea9216540b7de51a572a --- .../extensions/ext-browserAction.js | 12 ++++- .../extensions/schemas/browser_action.json | 6 +++ .../test/browser/browser-common.ini | 1 + .../browser/browser_ext_browserAction_area.js | 49 +++++++++++++++++++ 4 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 browser/components/extensions/test/browser/browser_ext_browserAction_area.js diff --git a/browser/components/extensions/ext-browserAction.js b/browser/components/extensions/ext-browserAction.js index 6dbd2663698a..f7562579ccaa 100644 --- a/browser/components/extensions/ext-browserAction.js +++ b/browser/components/extensions/ext-browserAction.js @@ -38,7 +38,14 @@ function isAncestorOrSelf(target, node) { } // WeakMap[Extension -> BrowserAction] -var browserActionMap = new WeakMap(); +const browserActionMap = new WeakMap(); + +const browserAreas = { + "navbar": CustomizableUI.AREA_NAVBAR, + "menupanel": CustomizableUI.AREA_PANEL, + "tabstrip": CustomizableUI.AREA_TABSTRIP, + "personaltoolbar": CustomizableUI.AREA_BOOKMARKS, +}; // Responsible for the browser_action section of the manifest as well // as the associated popup. @@ -62,6 +69,7 @@ function BrowserAction(options, extension) { badgeBackgroundColor: null, icon: IconDetails.normalize({path: options.default_icon}, extension), popup: options.default_popup || "", + area: browserAreas[options.default_area || "navbar"], }; this.browserStyle = options.browser_style || false; @@ -85,7 +93,7 @@ BrowserAction.prototype = { removable: true, label: this.defaults.title || this.extension.name, tooltiptext: this.defaults.title || "", - defaultArea: CustomizableUI.AREA_NAVBAR, + defaultArea: this.defaults.area, onBeforeCreated: document => { let view = document.createElementNS(XUL_NS, "panelview"); diff --git a/browser/components/extensions/schemas/browser_action.json b/browser/components/extensions/schemas/browser_action.json index 1a7da956a13b..575731e68679 100644 --- a/browser/components/extensions/schemas/browser_action.json +++ b/browser/components/extensions/schemas/browser_action.json @@ -31,6 +31,12 @@ "browser_style": { "type": "boolean", "optional": true + }, + "default_area": { + "description": "Defines the location the browserAction will appear by default. The default location is navbar.", + "type": "string", + "enum": ["navbar", "menupanel", "tabstrip", "personaltoolbar"], + "optional": true } }, "optional": true diff --git a/browser/components/extensions/test/browser/browser-common.ini b/browser/components/extensions/test/browser/browser-common.ini index f908835ea766..a4676d81bd49 100644 --- a/browser/components/extensions/test/browser/browser-common.ini +++ b/browser/components/extensions/test/browser/browser-common.ini @@ -24,6 +24,7 @@ support-files = searchSuggestionEngine.sjs ../../../../../toolkit/components/extensions/test/mochitest/head_webrequest.js +[browser_ext_browserAction_area.js] [browser_ext_browserAction_context.js] [browser_ext_browserAction_disabled.js] [browser_ext_browserAction_pageAction_icon.js] diff --git a/browser/components/extensions/test/browser/browser_ext_browserAction_area.js b/browser/components/extensions/test/browser/browser_ext_browserAction_area.js new file mode 100644 index 000000000000..919b00a38147 --- /dev/null +++ b/browser/components/extensions/test/browser/browser_ext_browserAction_area.js @@ -0,0 +1,49 @@ +/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set sts=2 sw=2 et tw=80: */ +"use strict"; + +var browserAreas = { + "navbar": CustomizableUI.AREA_NAVBAR, + "menupanel": CustomizableUI.AREA_PANEL, + "tabstrip": CustomizableUI.AREA_TABSTRIP, + "personaltoolbar": CustomizableUI.AREA_BOOKMARKS, +}; + +function* testInArea(area) { + let manifest = { + "browser_action": { + "browser_style": true, + }, + }; + if (area) { + manifest.browser_action.default_area = area; + } + let extension = ExtensionTestUtils.loadExtension({ + manifest, + }); + yield extension.startup(); + let widget = getBrowserActionWidget(extension); + let placement = CustomizableUI.getPlacementOfWidget(widget.id); + is(placement && placement.area, browserAreas[area || "navbar"], `widget located in correct area`); + yield extension.unload(); +} + +add_task(function* testBrowserActionDefaultArea() { + yield testInArea(); +}); + +add_task(function* testBrowserActionInToolbar() { + yield testInArea("navbar"); +}); + +add_task(function* testBrowserActionInMenuPanel() { + yield testInArea("menupanel"); +}); + +add_task(function* testBrowserActionInTabStrip() { + yield testInArea("tabstrip"); +}); + +add_task(function* testBrowserActionInPersonalToolbar() { + yield testInArea("personaltoolbar"); +}); From 698b61817795d5fc2ddaabe68b6f2c7ed1f28e04 Mon Sep 17 00:00:00 2001 From: "Alfredo.Yang" Date: Wed, 22 Feb 2017 11:38:16 +0800 Subject: [PATCH 073/234] Bug 1340446 - check the rounding error smaller or euqal to one. r=kinetik MozReview-Commit-ID: 4JvuY1yHGRk --HG-- extra : rebase_source : 7274abd9a3e9fba1d7a3daa15fc33b054a6ddded --- media/libstagefright/binding/MP4Metadata.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/media/libstagefright/binding/MP4Metadata.cpp b/media/libstagefright/binding/MP4Metadata.cpp index ccaace08fa93..8d1c39bd2585 100644 --- a/media/libstagefright/binding/MP4Metadata.cpp +++ b/media/libstagefright/binding/MP4Metadata.cpp @@ -374,9 +374,9 @@ MP4Metadata::ReadTrackIndex(FallibleTArray& aDest, mozilla::Track for (uint32_t i = 0; i < data.length; i++) { MOZ_DIAGNOSTIC_ASSERT(data.indices[i].start_offset == aDest[i].start_offset); MOZ_DIAGNOSTIC_ASSERT(data.indices[i].end_offset == aDest[i].end_offset); - MOZ_DIAGNOSTIC_ASSERT(data.indices[i].start_composition == aDest[i].start_composition); - MOZ_DIAGNOSTIC_ASSERT(data.indices[i].end_composition == aDest[i].end_composition); - MOZ_DIAGNOSTIC_ASSERT(data.indices[i].start_decode == aDest[i].start_decode); + MOZ_DIAGNOSTIC_ASSERT(abs(data.indices[i].start_composition - aDest[i].start_composition) <= 1); + MOZ_DIAGNOSTIC_ASSERT(abs(data.indices[i].end_composition - aDest[i].end_composition) <= 1); + MOZ_DIAGNOSTIC_ASSERT(abs(data.indices[i].start_decode - aDest[i].start_decode) <= 1); MOZ_DIAGNOSTIC_ASSERT(data.indices[i].sync == aDest[i].sync); } } From 380f5a71da5a48c3f090cbb2b05de2c5763d2d1f Mon Sep 17 00:00:00 2001 From: Andrew McCreight Date: Wed, 22 Feb 2017 13:32:06 -0800 Subject: [PATCH 074/234] Bug 1341809 - Fix unified build bustage in GroupedHistory.{h,cpp}. r=Ehsan MozReview-Commit-ID: JCZdiiHM41e --HG-- extra : rebase_source : 8616d9d3f6497ad38ced0eca40b581f0e11cdc75 --- dom/base/GroupedSHistory.cpp | 2 ++ dom/base/GroupedSHistory.h | 3 +++ 2 files changed, 5 insertions(+) diff --git a/dom/base/GroupedSHistory.cpp b/dom/base/GroupedSHistory.cpp index 86af599587e4..498de46cfb2f 100644 --- a/dom/base/GroupedSHistory.cpp +++ b/dom/base/GroupedSHistory.cpp @@ -5,6 +5,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "GroupedSHistory.h" + +#include "mozilla/dom/Promise.h" #include "TabParent.h" #include "PartialSHistory.h" diff --git a/dom/base/GroupedSHistory.h b/dom/base/GroupedSHistory.h index 687b99e6e5dd..f02e3c90ce21 100644 --- a/dom/base/GroupedSHistory.h +++ b/dom/base/GroupedSHistory.h @@ -11,6 +11,9 @@ #include "nsIGroupedSHistory.h" #include "nsIPartialSHistory.h" #include "nsTArray.h" +#include "nsCOMArray.h" +#include "nsCOMPtr.h" +#include "nsCycleCollectionParticipant.h" #include "nsWeakReference.h" namespace mozilla { From aae0c127cdaa2ab734f7a7d515c7447ac4898de9 Mon Sep 17 00:00:00 2001 From: Alastor Wu Date: Wed, 22 Feb 2017 15:51:08 +0800 Subject: [PATCH 075/234] Bug 1340191 - reverse the checking condition. r=sebastian Since BBC website puts their audio in another iframe, we can't get the media element to check its duration, so we always return false. The ideal way to fix it is to get every iframe and check its element, but I think it's not very easy to do considering the flexibility of using iframe and the cost time. First, if we want to get the information inside iframe, we need to listen the onload event, but it's async operation. If there are lots iframe, we need to spend lots time to wait every iframe. The worst situation is we got the nested iframe, it would need lots time and effect to wait every iframe loaded and get the element we want. Therefore, I would prefer the workaround which is to reverse the checking condition, that is we only check duration for the main window. MozReview-Commit-ID: F93BjbzRMXO --HG-- extra : rebase_source : 9409649db241b466967ab1e7f467e177c06c728f --- mobile/android/chrome/content/browser.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mobile/android/chrome/content/browser.js b/mobile/android/chrome/content/browser.js index 0243488fd4d8..d2a6e90aa49d 100644 --- a/mobile/android/chrome/content/browser.js +++ b/mobile/android/chrome/content/browser.js @@ -4583,19 +4583,19 @@ Tab.prototype = { let audioElements = this.browser.contentDocument.getElementsByTagName("audio"); for (let audio of audioElements) { - if (audio.paused == inactive && audio.duration > mediaDurationThreshold) { - return true; + if (audio.paused == inactive && audio.duration < mediaDurationThreshold) { + return false; } } let videoElements = this.browser.contentDocument.getElementsByTagName("video"); for (let video of videoElements) { - if (video.paused == inactive && video.duration > mediaDurationThreshold) { - return true; + if (video.paused == inactive && video.duration < mediaDurationThreshold) { + return false; } } - return false; + return true; }, observe: function(aSubject, aTopic, aData) { From 806e31d5b22002f801aa41064699dd5c69104850 Mon Sep 17 00:00:00 2001 From: Phil Ringnalda Date: Wed, 22 Feb 2017 20:27:17 -0800 Subject: [PATCH 076/234] Backed out changeset 437ff32b12ea (bug 1340446) for Mac and Windows build bustage CLOSED TREE --- media/libstagefright/binding/MP4Metadata.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/media/libstagefright/binding/MP4Metadata.cpp b/media/libstagefright/binding/MP4Metadata.cpp index 8d1c39bd2585..ccaace08fa93 100644 --- a/media/libstagefright/binding/MP4Metadata.cpp +++ b/media/libstagefright/binding/MP4Metadata.cpp @@ -374,9 +374,9 @@ MP4Metadata::ReadTrackIndex(FallibleTArray& aDest, mozilla::Track for (uint32_t i = 0; i < data.length; i++) { MOZ_DIAGNOSTIC_ASSERT(data.indices[i].start_offset == aDest[i].start_offset); MOZ_DIAGNOSTIC_ASSERT(data.indices[i].end_offset == aDest[i].end_offset); - MOZ_DIAGNOSTIC_ASSERT(abs(data.indices[i].start_composition - aDest[i].start_composition) <= 1); - MOZ_DIAGNOSTIC_ASSERT(abs(data.indices[i].end_composition - aDest[i].end_composition) <= 1); - MOZ_DIAGNOSTIC_ASSERT(abs(data.indices[i].start_decode - aDest[i].start_decode) <= 1); + MOZ_DIAGNOSTIC_ASSERT(data.indices[i].start_composition == aDest[i].start_composition); + MOZ_DIAGNOSTIC_ASSERT(data.indices[i].end_composition == aDest[i].end_composition); + MOZ_DIAGNOSTIC_ASSERT(data.indices[i].start_decode == aDest[i].start_decode); MOZ_DIAGNOSTIC_ASSERT(data.indices[i].sync == aDest[i].sync); } } From 4f68f40cfe9dd8c4cefdb1dd14fc2e570b244d99 Mon Sep 17 00:00:00 2001 From: Tom Klein Date: Thu, 16 Feb 2017 07:25:54 -0600 Subject: [PATCH 077/234] Bug 1339066 - Don't add a private tab opened while viewing the normal-mode tab strip. r=sebastian MozReview-Commit-ID: AZEZq4boaJW --HG-- extra : rebase_source : de6fad976ce5227af441a0c6386e36658bfe83c8 --- .../org/mozilla/gecko/tabs/TabStripView.java | 4 ++ .../android/tests/browser/robocop/robocop.ini | 1 + .../tests/components/TabStripComponent.java | 5 +++ .../gecko/tests/helpers/GeckoClickHelper.java | 13 ++++++ .../gecko/tests/testTabStripPrivacyMode.java | 42 +++++++++++++++++++ 5 files changed, 65 insertions(+) create mode 100644 mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testTabStripPrivacyMode.java diff --git a/mobile/android/base/java/org/mozilla/gecko/tabs/TabStripView.java b/mobile/android/base/java/org/mozilla/gecko/tabs/TabStripView.java index 20ea7773ccf9..23c68e53eec8 100644 --- a/mobile/android/base/java/org/mozilla/gecko/tabs/TabStripView.java +++ b/mobile/android/base/java/org/mozilla/gecko/tabs/TabStripView.java @@ -90,6 +90,10 @@ public class TabStripView extends RecyclerView { } /* package */ void addTab(Tab tab, int position) { + if (tab.isPrivate() != isPrivate) { + return; + } + adapter.addTab(tab, position); position = position == -1 ? adapter.getItemCount() - 1 : position; if (position == 0 || position == adapter.getItemCount() - 1) { diff --git a/mobile/android/tests/browser/robocop/robocop.ini b/mobile/android/tests/browser/robocop/robocop.ini index c8c4c16647fc..27dba1c8d4ca 100644 --- a/mobile/android/tests/browser/robocop/robocop.ini +++ b/mobile/android/tests/browser/robocop/robocop.ini @@ -106,6 +106,7 @@ skip-if = android_version == "18" [src/org/mozilla/gecko/tests/testReaderModeTitle.java] [src/org/mozilla/gecko/tests/testSessionHistory.java] [src/org/mozilla/gecko/tests/testStateWhileLoading.java] +[src/org/mozilla/gecko/tests/testTabStripPrivacyMode.java] [src/org/mozilla/gecko/tests/testUnifiedTelemetryClientId.java] [src/org/mozilla/gecko/tests/testAccessibleCarets.java] diff --git a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/components/TabStripComponent.java b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/components/TabStripComponent.java index 9966093f6ecb..d93784e11d96 100644 --- a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/components/TabStripComponent.java +++ b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/components/TabStripComponent.java @@ -22,6 +22,11 @@ public class TabStripComponent extends BaseComponent { super(testContext); } + public TabStripComponent assertTabCount(int count) { + fAssertEquals("The tab strip tab count is " + count, count, getTabStripView().getAdapter().getItemCount()); + return this; + } + public void switchToTab(int index) { // The tab strip is only available on tablets DeviceHelper.assertIsTablet(); diff --git a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/helpers/GeckoClickHelper.java b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/helpers/GeckoClickHelper.java index b8d1ef0ceeb6..1b28c573035b 100644 --- a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/helpers/GeckoClickHelper.java +++ b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/helpers/GeckoClickHelper.java @@ -38,6 +38,19 @@ public class GeckoClickHelper { sSolo.clickOnText(StringHelper.get().CONTEXT_MENU_ITEMS_IN_NORMAL_TAB[0]); } + /** + * Long press the link and select "Open Link in New Private Tab" from the context menu. + * + * The link should be positioned at the top of the page, at least 60px high and + * aligned to the middle. + */ + public static void openCentralizedLinkInNewPrivateTab() { + openLinkContextMenu(); + + // Click on "Open Link in New Private Tab" + sSolo.clickOnText(StringHelper.get().CONTEXT_MENU_ITEMS_IN_NORMAL_TAB[1]); + } + private static void openLinkContextMenu() { DisplayMetrics dm = new DisplayMetrics(); sActivity.getWindowManager().getDefaultDisplay().getMetrics(dm); diff --git a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testTabStripPrivacyMode.java b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testTabStripPrivacyMode.java new file mode 100644 index 000000000000..13e1d6df072c --- /dev/null +++ b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/testTabStripPrivacyMode.java @@ -0,0 +1,42 @@ +package org.mozilla.gecko.tests; + +import org.mozilla.gecko.Actions; +import org.mozilla.gecko.tests.helpers.DeviceHelper; +import org.mozilla.gecko.tests.helpers.GeckoClickHelper; +import org.mozilla.gecko.tests.helpers.GeckoHelper; +import org.mozilla.gecko.tests.helpers.NavigationHelper; +import org.mozilla.gecko.tests.helpers.WaitHelper; + +/** + * Make sure that a private tab opened while the tab strip is in normal mode does not get added to + * the tab strip (bug 1339066). + */ +public class testTabStripPrivacyMode extends UITest { + public void testTabStripPrivacyMode() { + if (!DeviceHelper.isTablet()) { + return; + } + + GeckoHelper.blockForReady(); + + final String normalModeUrl = mStringHelper.ROBOCOP_BIG_LINK_URL; + NavigationHelper.enterAndLoadUrl(normalModeUrl); + + final Actions.EventExpecter titleExpecter = mActions.expectGlobalEvent(Actions.EventType.UI, "Content:DOMTitleChanged"); + GeckoClickHelper.openCentralizedLinkInNewPrivateTab(); + + titleExpecter.blockForEvent(); + titleExpecter.unregisterListener(); + // In the passing version of this test the UI shouldn't change at all in response to the + // new private tab, but to prevent a false positive when the private tab does get added to + // the tab strip in error, sleep here to make sure the UI has time to update before we + // check it. + mSolo.sleep(250); + + // Now make sure there's still only one tab in the tab strip, and that it's still the normal + // mode tab. + + mTabStrip.assertTabCount(1); + mToolbar.assertTitle(normalModeUrl); + } + } From af5bd498da61f4362c08928c1972cdfdf7fe6310 Mon Sep 17 00:00:00 2001 From: Aaron Klotz Date: Fri, 17 Feb 2017 17:30:03 -0700 Subject: [PATCH 078/234] Bug 1303060: ipc/mscom changes for handler and payload support; r=jimm MozReview-Commit-ID: 13NFW1pgxix --HG-- extra : rebase_source : 18cc11d4c1dc62bc0ee428608f6cb57e32c4d0af --- ipc/mscom/Aggregation.h | 48 +++++++++ ipc/mscom/IHandlerPayload.h | 35 +++++++ ipc/mscom/Interceptor.cpp | 154 +++++++++++++++++++++++++--- ipc/mscom/Interceptor.h | 32 +++++- ipc/mscom/MainThreadHandoff.cpp | 176 ++++++++++++++++++++++++++++++-- ipc/mscom/MainThreadHandoff.h | 25 ++++- ipc/mscom/Registration.cpp | 8 +- ipc/mscom/Registration.h | 2 +- ipc/mscom/moz.build | 1 + 9 files changed, 449 insertions(+), 32 deletions(-) create mode 100644 ipc/mscom/IHandlerPayload.h diff --git a/ipc/mscom/Aggregation.h b/ipc/mscom/Aggregation.h index 36e56f91a410..3bae2358695a 100644 --- a/ipc/mscom/Aggregation.h +++ b/ipc/mscom/Aggregation.h @@ -9,6 +9,9 @@ #include "mozilla/Attributes.h" +#include +#include + namespace mozilla { namespace mscom { @@ -44,8 +47,53 @@ private: RefCntT& mRefCnt; }; +namespace detail { + +template +class InternalUnknown : public IUnknown +{ +public: + STDMETHODIMP QueryInterface(REFIID aIid, void** aOutInterface) override + { + return This()->InternalQueryInterface(aIid, aOutInterface); + } + + STDMETHODIMP_(ULONG) AddRef() override + { + return This()->InternalAddRef(); + } + + STDMETHODIMP_(ULONG) Release() override + { + return This()->InternalRelease(); + } + +private: + T* This() + { + return reinterpret_cast(reinterpret_cast(this) - + offsetof(T, mInternalUnknown)); + } +}; + +} // namespace detail } // namespace mscom } // namespace mozilla +#define DECLARE_AGGREGATABLE(Type) \ + public: \ + STDMETHODIMP QueryInterface(REFIID riid, void** ppv) override \ + { return mOuter->QueryInterface(riid, ppv); } \ + STDMETHODIMP_(ULONG) AddRef() override \ + { return mOuter->AddRef(); } \ + STDMETHODIMP_(ULONG) Release() override \ + { return mOuter->Release(); } \ + protected: \ + STDMETHODIMP InternalQueryInterface(REFIID riid, void** ppv); \ + STDMETHODIMP_(ULONG) InternalAddRef(); \ + STDMETHODIMP_(ULONG) InternalRelease(); \ + friend class mozilla::mscom::detail::InternalUnknown; \ + mozilla::mscom::detail::InternalUnknown mInternalUnknown + #endif // mozilla_mscom_Aggregation_h diff --git a/ipc/mscom/IHandlerPayload.h b/ipc/mscom/IHandlerPayload.h new file mode 100644 index 000000000000..c2edec331d64 --- /dev/null +++ b/ipc/mscom/IHandlerPayload.h @@ -0,0 +1,35 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_mscom_IHandlerPayload_h +#define mozilla_mscom_IHandlerPayload_h + +#include + +namespace mozilla { +namespace mscom { + +struct HandlerPayload +{ + virtual STDMETHODIMP GetHandler(CLSID* aHandlerClsid) = 0; + virtual STDMETHODIMP GetHandlerPayloadSize(REFIID aIid, + IUnknown* aTarget, + DWORD* aOutPayloadSize) = 0; + virtual STDMETHODIMP WriteHandlerPayload(IStream* aStream, REFIID aIid, + IUnknown* aTarget) = 0; + virtual REFIID MarshalAs(REFIID aIid) = 0; +}; + +struct IHandlerPayload : public IUnknown + , public HandlerPayload +{ + virtual STDMETHODIMP Clone(IHandlerPayload** aOutNewPayload) = 0; +}; + +} // namespace mscom +} // namespace mozilla + +#endif // mozilla_mscom_IHandlerPayload_h diff --git a/ipc/mscom/Interceptor.cpp b/ipc/mscom/Interceptor.cpp index b71030f8b087..369050a83f3d 100644 --- a/ipc/mscom/Interceptor.cpp +++ b/ipc/mscom/Interceptor.cpp @@ -46,6 +46,7 @@ Interceptor::Interceptor(STAUniquePtr aTarget, IInterceptorSink* aSink , mTarget(Move(aTarget)) , mEventSink(aSink) , mMutex("mozilla::mscom::Interceptor::mMutex") + , mStdMarshal(nullptr) { MOZ_ASSERT(aSink); MOZ_ASSERT(!IsProxy(mTarget.get())); @@ -67,6 +68,77 @@ Interceptor::~Interceptor() } } +HRESULT +Interceptor::GetClassForHandler(DWORD aDestContext, void* aDestContextPtr, + CLSID* aHandlerClsid) +{ + if (aDestContextPtr || !aHandlerClsid || + aDestContext == MSHCTX_DIFFERENTMACHINE) { + return E_INVALIDARG; + } + MOZ_ASSERT(mEventSink); + return mEventSink->GetHandler(aHandlerClsid); +} + +HRESULT +Interceptor::GetUnmarshalClass(REFIID riid, void* pv, DWORD dwDestContext, + void* pvDestContext, DWORD mshlflags, + CLSID* pCid) +{ + return mStdMarshal->GetUnmarshalClass(riid, pv, dwDestContext, pvDestContext, + mshlflags, pCid); +} + +HRESULT +Interceptor::GetMarshalSizeMax(REFIID riid, void* pv, DWORD dwDestContext, + void* pvDestContext, DWORD mshlflags, + DWORD* pSize) +{ + HRESULT hr = mStdMarshal->GetMarshalSizeMax(riid, pv, dwDestContext, + pvDestContext, mshlflags, pSize); + if (FAILED(hr)) { + return hr; + } + + DWORD payloadSize = 0; + hr = mEventSink->GetHandlerPayloadSize(riid, mTarget.get(), &payloadSize); + *pSize += payloadSize; + return hr; +} + +HRESULT +Interceptor::MarshalInterface(IStream* pStm, REFIID riid, void* pv, + DWORD dwDestContext, void* pvDestContext, + DWORD mshlflags) +{ + HRESULT hr = mStdMarshal->MarshalInterface(pStm, riid, pv, dwDestContext, + pvDestContext, mshlflags); + if (FAILED(hr)) { + return hr; + } + + return mEventSink->WriteHandlerPayload(pStm, riid, mTarget.get()); +} + +HRESULT +Interceptor::UnmarshalInterface(IStream* pStm, REFIID riid, + void** ppv) +{ + return mStdMarshal->UnmarshalInterface(pStm, riid, ppv); +} + +HRESULT +Interceptor::ReleaseMarshalData(IStream* pStm) +{ + return mStdMarshal->ReleaseMarshalData(pStm); +} + +HRESULT +Interceptor::DisconnectObject(DWORD dwReserved) +{ + return mStdMarshal->DisconnectObject(dwReserved); +} + Interceptor::MapEntry* Interceptor::Lookup(REFIID aIid) { @@ -148,19 +220,22 @@ Interceptor::GetInterceptorForIID(REFIID aIid, void** aOutInterceptor) if (aIid == IID_IUnknown) { // Special case: When we see IUnknown, we just provide a reference to this - *aOutInterceptor = static_cast(this); - AddRef(); + RefPtr intcpt(this); + intcpt.forget(aOutInterceptor); return S_OK; } + REFIID interceptorIid = mEventSink->MarshalAs(aIid); + RefPtr unkInterceptor; IUnknown* interfaceForQILog = nullptr; - // (1) Check to see if we already have an existing interceptor for aIid. + // (1) Check to see if we already have an existing interceptor for + // interceptorIid. { // Scope for lock MutexAutoLock lock(mMutex); - MapEntry* entry = Lookup(aIid); + MapEntry* entry = Lookup(interceptorIid); if (entry) { unkInterceptor = entry->mInterceptor; interfaceForQILog = entry->mTargetInterface; @@ -175,7 +250,7 @@ Interceptor::GetInterceptorForIID(REFIID aIid, void** aOutInterceptor) // was requested. InterceptorLog::QI(S_OK, mTarget.get(), aIid, interfaceForQILog); - return unkInterceptor->QueryInterface(aIid, aOutInterceptor); + return unkInterceptor->QueryInterface(interceptorIid, aOutInterceptor); } // (2) Obtain a new target interface. @@ -188,7 +263,7 @@ Interceptor::GetInterceptorForIID(REFIID aIid, void** aOutInterceptor) STAUniquePtr targetInterface; IUnknown* rawTargetInterface = nullptr; - hr = QueryInterfaceTarget(aIid, (void**)&rawTargetInterface); + hr = QueryInterfaceTarget(interceptorIid, (void**)&rawTargetInterface); targetInterface.reset(rawTargetInterface); InterceptorLog::QI(hr, mTarget.get(), aIid, targetInterface.get()); MOZ_ASSERT(SUCCEEDED(hr) || hr == E_NOINTERFACE); @@ -206,7 +281,8 @@ Interceptor::GetInterceptorForIID(REFIID aIid, void** aOutInterceptor) RefPtr kungFuDeathGrip(static_cast( static_cast(this))); - hr = CreateInterceptor(aIid, kungFuDeathGrip, getter_AddRefs(unkInterceptor)); + hr = CreateInterceptor(interceptorIid, kungFuDeathGrip, + getter_AddRefs(unkInterceptor)); if (FAILED(hr)) { return hr; } @@ -231,7 +307,7 @@ Interceptor::GetInterceptorForIID(REFIID aIid, void** aOutInterceptor) MutexAutoLock lock(mMutex); // We might have raced with another thread, so first check that we don't // already have an entry for this - MapEntry* entry = Lookup(aIid); + MapEntry* entry = Lookup(interceptorIid); if (entry && entry->mInterceptor) { unkInterceptor = entry->mInterceptor; } else { @@ -239,13 +315,13 @@ Interceptor::GetInterceptorForIID(REFIID aIid, void** aOutInterceptor) // refcount for the target interface because we are just moving it into // the map and its refcounting might not be thread-safe. IUnknown* rawTargetInterface = targetInterface.release(); - mInterceptorMap.AppendElement(MapEntry(aIid, + mInterceptorMap.AppendElement(MapEntry(interceptorIid, unkInterceptor, rawTargetInterface)); } } - return unkInterceptor->QueryInterface(aIid, aOutInterceptor); + return unkInterceptor->QueryInterface(interceptorIid, aOutInterceptor); } HRESULT @@ -275,9 +351,63 @@ Interceptor::QueryInterface(REFIID riid, void** ppv) HRESULT Interceptor::ThreadSafeQueryInterface(REFIID aIid, IUnknown** aOutInterface) { + if (aIid == IID_INoMarshal) { + // This entire library is designed around marshaling, so there's no point + // propagating this QI request all over the place! + return E_NOINTERFACE; + } + + if (aIid == IID_IStdMarshalInfo) { + // Do not indicate that this interface is available unless we actually + // support it. We'll check that by looking for a successful call to + // IInterceptorSink::GetHandler() + CLSID dummy; + if (FAILED(mEventSink->GetHandler(&dummy))) { + return E_NOINTERFACE; + } + + RefPtr std(this); + std.forget(aOutInterface); + return S_OK; + } + + if (aIid == IID_IMarshal) { + // Do not indicate that this interface is available unless we actually + // support it. We'll check that by looking for a successful call to + // IInterceptorSink::GetHandler() + CLSID dummy; + if (FAILED(mEventSink->GetHandler(&dummy))) { + return E_NOINTERFACE; + } + + if (!mStdMarshalUnk) { + HRESULT hr = ::CoGetStdMarshalEx(static_cast(this), + SMEXF_SERVER, + getter_AddRefs(mStdMarshalUnk)); + if (FAILED(hr)) { + return hr; + } + } + + if (!mStdMarshal) { + HRESULT hr = mStdMarshalUnk->QueryInterface(IID_IMarshal, + (void**)&mStdMarshal); + if (FAILED(hr)) { + return hr; + } + + // mStdMarshal is weak, so drop its refcount + mStdMarshal->Release(); + } + + RefPtr marshal(this); + marshal.forget(aOutInterface); + return S_OK; + } + if (aIid == IID_IInterceptor) { - *aOutInterface = static_cast(this); - (*aOutInterface)->AddRef(); + RefPtr intcpt(this); + intcpt.forget(aOutInterface); return S_OK; } diff --git a/ipc/mscom/Interceptor.h b/ipc/mscom/Interceptor.h index 6630bb018828..4f6d0e26fec2 100644 --- a/ipc/mscom/Interceptor.h +++ b/ipc/mscom/Interceptor.h @@ -4,16 +4,18 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef mozilla_mscom_interceptor_h -#define mozilla_mscom_interceptor_h +#ifndef mozilla_mscom_Interceptor_h +#define mozilla_mscom_Interceptor_h #include "mozilla/Move.h" #include "mozilla/Mutex.h" #include "nsTArray.h" +#include "mozilla/mscom/IHandlerPayload.h" #include "mozilla/mscom/Ptr.h" #include "mozilla/mscom/WeakRef.h" #include "mozilla/RefPtr.h" +#include #include namespace mozilla { @@ -24,6 +26,7 @@ DEFINE_GUID(IID_IInterceptorSink, 0x8831eb53, 0xa937, 0x42bc, 0x99, 0x21, 0xb3, 0xe1, 0x12, 0x1f, 0xdf, 0x86); struct IInterceptorSink : public ICallFrameEvents + , public HandlerPayload { virtual STDMETHODIMP SetInterceptor(IWeakReference* aInterceptor) = 0; }; @@ -57,6 +60,8 @@ struct IInterceptor : public IUnknown * (the mscom::Interceptor we implement and control). */ class Interceptor final : public WeakReferenceSupport + , public IStdMarshalInfo + , public IMarshal , public IInterceptor { public: @@ -68,6 +73,25 @@ public: STDMETHODIMP_(ULONG) AddRef() override; STDMETHODIMP_(ULONG) Release() override; + // IStdMarshalInfo + STDMETHODIMP GetClassForHandler(DWORD aDestContext, void* aDestContextPtr, + CLSID* aHandlerClsid) override; + + // IMarshal + STDMETHODIMP GetUnmarshalClass(REFIID riid, void* pv, DWORD dwDestContext, + void* pvDestContext, DWORD mshlflags, + CLSID* pCid) override; + STDMETHODIMP GetMarshalSizeMax(REFIID riid, void* pv, DWORD dwDestContext, + void* pvDestContext, DWORD mshlflags, + DWORD* pSize) override; + STDMETHODIMP MarshalInterface(IStream* pStm, REFIID riid, void* pv, + DWORD dwDestContext, void* pvDestContext, + DWORD mshlflags) override; + STDMETHODIMP UnmarshalInterface(IStream* pStm, REFIID riid, + void** ppv) override; + STDMETHODIMP ReleaseMarshalData(IStream* pStm) override; + STDMETHODIMP DisconnectObject(DWORD dwReserved) override; + // IInterceptor STDMETHODIMP GetTargetForIID(REFIID aIid, InterceptorTargetPtr& aTarget) override; STDMETHODIMP GetInterceptorForIID(REFIID aIid, void** aOutInterceptor) override; @@ -100,6 +124,8 @@ private: mozilla::Mutex mMutex; // Guards mInterceptorMap // Using a nsTArray since the # of interfaces is not going to be very high nsTArray mInterceptorMap; + RefPtr mStdMarshalUnk; + IMarshal* mStdMarshal; // WEAK }; template @@ -122,4 +148,4 @@ CreateInterceptor(STAUniquePtr aTargetInterface, } // namespace mscom } // namespace mozilla -#endif // mozilla_mscom_interceptor_h +#endif // mozilla_mscom_Interceptor_h diff --git a/ipc/mscom/MainThreadHandoff.cpp b/ipc/mscom/MainThreadHandoff.cpp index 521bf7f8e8df..1fd9382b6f36 100644 --- a/ipc/mscom/MainThreadHandoff.cpp +++ b/ipc/mscom/MainThreadHandoff.cpp @@ -6,7 +6,9 @@ #include "mozilla/mscom/MainThreadHandoff.h" +#include "mozilla/Attributes.h" #include "mozilla/Move.h" +#include "mozilla/mscom/AgileReference.h" #include "mozilla/mscom/InterceptorLog.h" #include "mozilla/mscom/Registration.h" #include "mozilla/mscom/Utils.h" @@ -15,9 +17,106 @@ #include "nsThreadUtils.h" using mozilla::DebugOnly; +using mozilla::mscom::AgileReference; namespace { +class MOZ_NONHEAP_CLASS InParamWalker : private ICallFrameWalker +{ +public: + InParamWalker() + : mPreHandoff(true) + { + } + + void SetHandoffDone() + { + mPreHandoff = false; + mAgileRefsItr = mAgileRefs.begin(); + } + + HRESULT Walk(ICallFrame* aFrame) + { + MOZ_ASSERT(aFrame); + if (!aFrame) { + return E_INVALIDARG; + } + + return aFrame->WalkFrame(CALLFRAME_WALK_IN, this); + } + +private: + // IUnknown + STDMETHODIMP QueryInterface(REFIID aIid, void** aOutInterface) override + { + if (!aOutInterface) { + return E_INVALIDARG; + } + *aOutInterface = nullptr; + + if (aIid == IID_IUnknown || aIid == IID_ICallFrameWalker) { + *aOutInterface = static_cast(this); + return S_OK; + } + + return E_NOINTERFACE; + } + + STDMETHODIMP_(ULONG) AddRef() override + { + return 2; + } + + STDMETHODIMP_(ULONG) Release() override + { + return 1; + } + + // ICallFrameWalker + STDMETHODIMP OnWalkInterface(REFIID aIid, PVOID* aInterface, BOOL aIn, + BOOL aOut) override + { + MOZ_ASSERT(aIn); + if (!aIn) { + return E_UNEXPECTED; + } + + IUnknown* origInterface = static_cast(*aInterface); + if (!origInterface) { + // Nothing to do + return S_OK; + } + + if (mPreHandoff) { + mAgileRefs.AppendElement(AgileReference(aIid, origInterface)); + return S_OK; + } + + MOZ_ASSERT(mAgileRefsItr != mAgileRefs.end()); + if (mAgileRefsItr == mAgileRefs.end()) { + return E_UNEXPECTED; + } + + HRESULT hr = mAgileRefsItr->Resolve(aIid, aInterface); + MOZ_ASSERT(SUCCEEDED(hr)); + if (SUCCEEDED(hr)) { + ++mAgileRefsItr; + } + + return hr; + } + + InParamWalker(const InParamWalker&) = delete; + InParamWalker(InParamWalker&&) = delete; + InParamWalker& operator=(const InParamWalker&) = delete; + InParamWalker& operator=(InParamWalker&&) = delete; + +private: + bool mPreHandoff; + AutoTArray mAgileRefs; + nsTArray::iterator mAgileRefsItr; +}; + class HandoffRunnable : public mozilla::Runnable { public: @@ -26,10 +125,17 @@ public: , mTargetInterface(aTargetInterface) , mResult(E_UNEXPECTED) { + DebugOnly hr = mInParamWalker.Walk(aCallFrame); + MOZ_ASSERT(SUCCEEDED(hr)); } NS_IMETHOD Run() override { + mInParamWalker.SetHandoffDone(); + // We declare hr a DebugOnly because if mInParamWalker.Walk() fails, then + // mCallFrame->Invoke will fail anyway. + DebugOnly hr = mInParamWalker.Walk(mCallFrame); + MOZ_ASSERT(SUCCEEDED(hr)); mResult = mCallFrame->Invoke(mTargetInterface); return NS_OK; } @@ -40,9 +146,10 @@ public: } private: - ICallFrame* mCallFrame; - IUnknown* mTargetInterface; - HRESULT mResult; + ICallFrame* mCallFrame; + InParamWalker mInParamWalker; + IUnknown* mTargetInterface; + HRESULT mResult; }; } // anonymous namespace @@ -51,14 +158,16 @@ namespace mozilla { namespace mscom { /* static */ HRESULT -MainThreadHandoff::Create(IInterceptorSink** aOutput) +MainThreadHandoff::Create(IHandlerPayload* aHandlerPayload, + IInterceptorSink** aOutput) { - RefPtr handoff(new MainThreadHandoff()); + RefPtr handoff(new MainThreadHandoff(aHandlerPayload)); return handoff->QueryInterface(IID_IInterceptorSink, (void**) aOutput); } -MainThreadHandoff::MainThreadHandoff() +MainThreadHandoff::MainThreadHandoff(IHandlerPayload* aHandlerPayload) : mRefCnt(0) + , mHandlerPayload(aHandlerPayload) { } @@ -143,7 +252,7 @@ MainThreadHandoff::OnCall(ICallFrame* aFrame) return hr; } - // (2) Execute the method call syncrhonously on the main thread + // (2) Execute the method call synchronously on the main thread RefPtr handoffInfo(new HandoffRunnable(aFrame, targetInterface.get())); MainThreadInvoker invoker; @@ -296,6 +405,44 @@ MainThreadHandoff::SetInterceptor(IWeakReference* aInterceptor) return S_OK; } +HRESULT +MainThreadHandoff::GetHandler(CLSID* aHandlerClsid) +{ + if (!mHandlerPayload) { + return E_NOTIMPL; + } + return mHandlerPayload->GetHandler(aHandlerClsid); +} + +HRESULT +MainThreadHandoff::GetHandlerPayloadSize(REFIID aIid, IUnknown* aTarget, + DWORD* aOutPayloadSize) +{ + if (!mHandlerPayload) { + return E_NOTIMPL; + } + return mHandlerPayload->GetHandlerPayloadSize(aIid, aTarget, aOutPayloadSize); +} + +HRESULT +MainThreadHandoff::WriteHandlerPayload(IStream* aStream, REFIID aIid, + IUnknown* aTarget) +{ + if (!mHandlerPayload) { + return E_NOTIMPL; + } + return mHandlerPayload->WriteHandlerPayload(aStream, aIid, aTarget); +} + +REFIID +MainThreadHandoff::MarshalAs(REFIID aIid) +{ + if (!mHandlerPayload) { + return aIid; + } + return mHandlerPayload->MarshalAs(aIid); +} + HRESULT MainThreadHandoff::OnWalkInterface(REFIID aIid, PVOID* aInterface, BOOL aIsInParam, BOOL aIsOutParam) @@ -369,16 +516,27 @@ MainThreadHandoff::OnWalkInterface(REFIID aIid, PVOID* aInterface, } } + RefPtr payload; + if (mHandlerPayload) { + hr = mHandlerPayload->Clone(getter_AddRefs(payload)); + MOZ_ASSERT(SUCCEEDED(hr)); + if (FAILED(hr)) { + return hr; + } + } + // Now create a new MainThreadHandoff wrapper... RefPtr handoff; - hr = MainThreadHandoff::Create(getter_AddRefs(handoff)); + hr = MainThreadHandoff::Create(payload, getter_AddRefs(handoff)); MOZ_ASSERT(SUCCEEDED(hr)); if (FAILED(hr)) { return hr; } + REFIID interceptorIid = payload ? payload->MarshalAs(aIid) : aIid; + RefPtr wrapped; - hr = Interceptor::Create(Move(origInterface), handoff, aIid, + hr = Interceptor::Create(Move(origInterface), handoff, interceptorIid, getter_AddRefs(wrapped)); MOZ_ASSERT(SUCCEEDED(hr)); if (FAILED(hr)) { diff --git a/ipc/mscom/MainThreadHandoff.h b/ipc/mscom/MainThreadHandoff.h index a3ae47e1bfff..104cf8c65dcb 100644 --- a/ipc/mscom/MainThreadHandoff.h +++ b/ipc/mscom/MainThreadHandoff.h @@ -24,15 +24,26 @@ class MainThreadHandoff final : public IInterceptorSink , public ICallFrameWalker { public: - static HRESULT Create(IInterceptorSink** aOutput); + static HRESULT Create(IHandlerPayload* aHandlerPayload, + IInterceptorSink** aOutput); template static HRESULT WrapInterface(STAUniquePtr aTargetInterface, Interface** aOutInterface) + { + return WrapInterface(Move(aTargetInterface), nullptr, + aOutInterface); + } + + template + static HRESULT WrapInterface(STAUniquePtr aTargetInterface, + IHandlerPayload* aHandlerPayload, + Interface** aOutInterface) { MOZ_ASSERT(!IsProxy(aTargetInterface.get())); RefPtr handoff; - HRESULT hr = MainThreadHandoff::Create(getter_AddRefs(handoff)); + HRESULT hr = MainThreadHandoff::Create(aHandlerPayload, + getter_AddRefs(handoff)); if (FAILED(hr)) { return hr; } @@ -49,13 +60,20 @@ public: // IInterceptorSink STDMETHODIMP SetInterceptor(IWeakReference* aInterceptor) override; + STDMETHODIMP GetHandler(CLSID* aHandlerClsid) override; + STDMETHODIMP GetHandlerPayloadSize(REFIID aIid, + IUnknown* aTarget, + DWORD* aOutPayloadSize) override; + STDMETHODIMP WriteHandlerPayload(IStream* aStream, REFIID aIid, + IUnknown* aTarget) override; + REFIID MarshalAs(REFIID aIid) override; // ICallFrameWalker STDMETHODIMP OnWalkInterface(REFIID aIid, PVOID* aInterface, BOOL aIsInParam, BOOL aIsOutParam) override; private: - MainThreadHandoff(); + explicit MainThreadHandoff(IHandlerPayload* aHandlerPayload); ~MainThreadHandoff(); HRESULT FixArrayElements(ICallFrame* aFrame, const ArrayData& aArrayData); @@ -63,6 +81,7 @@ private: private: ULONG mRefCnt; RefPtr mInterceptor; + RefPtr mHandlerPayload; }; } // namespace mscom diff --git a/ipc/mscom/Registration.cpp b/ipc/mscom/Registration.cpp index f39f8b1d9b97..e5136794b1a3 100644 --- a/ipc/mscom/Registration.cpp +++ b/ipc/mscom/Registration.cpp @@ -369,8 +369,8 @@ RegisteredProxy::operator=(RegisteredProxy&& aOther) } HRESULT -RegisteredProxy::GetTypeInfoForInterface(REFIID aIid, - ITypeInfo** aOutTypeInfo) const +RegisteredProxy::GetTypeInfoForGuid(REFGUID aGuid, + ITypeInfo** aOutTypeInfo) const { if (!aOutTypeInfo) { return E_INVALIDARG; @@ -378,7 +378,7 @@ RegisteredProxy::GetTypeInfoForInterface(REFIID aIid, if (!mTypeLib) { return E_UNEXPECTED; } - return mTypeLib->lpVtbl->GetTypeInfoOfGuid(mTypeLib, aIid, aOutTypeInfo); + return mTypeLib->lpVtbl->GetTypeInfoOfGuid(mTypeLib, aGuid, aOutTypeInfo); } static StaticAutoPtr> sRegistry; @@ -418,7 +418,7 @@ RegisteredProxy::Find(REFIID aIid, ITypeInfo** aTypeInfo) } for (auto&& proxy : *sRegistry) { - if (SUCCEEDED(proxy->GetTypeInfoForInterface(aIid, aTypeInfo))) { + if (SUCCEEDED(proxy->GetTypeInfoForGuid(aIid, aTypeInfo))) { return true; } } diff --git a/ipc/mscom/Registration.h b/ipc/mscom/Registration.h index 8cccd0f257fe..9d58502ffc71 100644 --- a/ipc/mscom/Registration.h +++ b/ipc/mscom/Registration.h @@ -36,7 +36,7 @@ public: ~RegisteredProxy(); - HRESULT GetTypeInfoForInterface(REFIID aIid, ITypeInfo** aOutTypeInfo) const; + HRESULT GetTypeInfoForGuid(REFGUID aGuid, ITypeInfo** aOutTypeInfo) const; static bool Find(REFIID aIid, ITypeInfo** aOutTypeInfo); diff --git a/ipc/mscom/moz.build b/ipc/mscom/moz.build index 143d6371be69..2bc554f24568 100644 --- a/ipc/mscom/moz.build +++ b/ipc/mscom/moz.build @@ -29,6 +29,7 @@ if CONFIG['ACCESSIBILITY']: EXPORTS.mozilla.mscom += [ 'ActivationContext.h', 'DispatchForwarder.h', + 'IHandlerPayload.h', 'Interceptor.h', 'InterceptorLog.h', 'MainThreadHandoff.h', From f3b557f70ce1d483f92f5679cc1b1b38a53b7aa3 Mon Sep 17 00:00:00 2001 From: Aaron Klotz Date: Fri, 17 Feb 2017 16:20:51 -0700 Subject: [PATCH 079/234] Bug 1303060: Additions to ipc/mscom for out-of-process components; r=jimm MozReview-Commit-ID: IYjONGbBraG --HG-- extra : rebase_source : a6eb90db7a9c21b91b9e763a15a9a661d41c5e77 --- ipc/mscom/moz.build | 4 + ipc/mscom/oop/Factory.h | 155 +++++++++++++++++ ipc/mscom/oop/Handler.cpp | 339 ++++++++++++++++++++++++++++++++++++++ ipc/mscom/oop/Handler.h | 127 ++++++++++++++ ipc/mscom/oop/Module.cpp | 19 +++ ipc/mscom/oop/Module.h | 39 +++++ ipc/mscom/oop/moz.build | 36 ++++ 7 files changed, 719 insertions(+) create mode 100644 ipc/mscom/oop/Factory.h create mode 100644 ipc/mscom/oop/Handler.cpp create mode 100644 ipc/mscom/oop/Handler.h create mode 100644 ipc/mscom/oop/Module.cpp create mode 100644 ipc/mscom/oop/Module.h create mode 100644 ipc/mscom/oop/moz.build diff --git a/ipc/mscom/moz.build b/ipc/mscom/moz.build index 2bc554f24568..6fdd7489c8ac 100644 --- a/ipc/mscom/moz.build +++ b/ipc/mscom/moz.build @@ -26,6 +26,10 @@ UNIFIED_SOURCES += [ ] if CONFIG['ACCESSIBILITY']: + DIRS += [ + 'oop', + ] + EXPORTS.mozilla.mscom += [ 'ActivationContext.h', 'DispatchForwarder.h', diff --git a/ipc/mscom/oop/Factory.h b/ipc/mscom/oop/Factory.h new file mode 100644 index 000000000000..7ac6ceceb255 --- /dev/null +++ b/ipc/mscom/oop/Factory.h @@ -0,0 +1,155 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_mscom_Factory_h +#define mozilla_mscom_Factory_h + +#if defined(MOZILLA_INTERNAL_API) +#error This code is NOT for internal Gecko use! +#endif // defined(MOZILLA_INTERNAL_API) + +#include "mozilla/Attributes.h" +#include "mozilla/DebugOnly.h" +#include "mozilla/Move.h" +#include "mozilla/RefPtr.h" +#include "mozilla/StaticPtr.h" +#include "Module.h" + +#include +#include + +/* WARNING! The code in this file may be loaded into the address spaces of other + processes! It MUST NOT link against xul.dll or other Gecko binaries! Only + inline code may be included! */ + +namespace mozilla { +namespace mscom { + +template +class MOZ_NONHEAP_CLASS Factory : public IClassFactory +{ + template + HRESULT DoCreate(Args... args) + { + MOZ_DIAGNOSTIC_ASSERT(false, "This should not be executed"); + return E_NOTIMPL; + } + + template + HRESULT DoCreate(HRESULT (*aFnPtr)(IUnknown*, REFIID, void**), Args... args) + { + return aFnPtr(mozilla::Forward(args)...); + } + +public: + // IUnknown + STDMETHODIMP QueryInterface(REFIID aIid, void** aOutInterface) override + { + if (!aOutInterface) { + return E_INVALIDARG; + } + + if (aIid == IID_IUnknown || aIid == IID_IClassFactory) { + RefPtr punk(this); + punk.forget(aOutInterface); + return S_OK; + } + + *aOutInterface = nullptr; + + return E_NOINTERFACE; + } + + STDMETHODIMP_(ULONG) AddRef() override + { + Module::Lock(); + return 2; + } + + STDMETHODIMP_(ULONG) Release() override + { + Module::Unlock(); + return 1; + } + + // IClassFactory + STDMETHODIMP CreateInstance(IUnknown* aOuter, REFIID aIid, + void** aOutInterface) override + { + return DoCreate(&T::Create, aOuter, aIid, aOutInterface); + } + + STDMETHODIMP LockServer(BOOL aLock) override + { + if (aLock) { + Module::Lock(); + } else { + Module::Unlock(); + } + return S_OK; + } +}; + +template +class MOZ_NONHEAP_CLASS SingletonFactory : public Factory +{ +public: + STDMETHODIMP CreateInstance(IUnknown* aOuter, REFIID aIid, + void** aOutInterface) override + { + if (aOuter || !aOutInterface) { + return E_INVALIDARG; + } + + RefPtr obj(sInstance); + if (!obj) { + obj = GetOrCreateSingleton(); + } + + return obj->QueryInterface(aIid, aOutInterface); + } + + RefPtr GetOrCreateSingleton() + { + if (!sInstance) { + RefPtr object; + if (FAILED(T::Create(getter_AddRefs(object)))) { + return nullptr; + } + + sInstance = object.forget(); + } + + return sInstance; + } + + RefPtr GetSingleton() + { + return sInstance; + } + + void ClearSingleton() + { + if (!sInstance) { + return; + } + + DebugOnly hr = ::CoDisconnectObject(sInstance.get(), 0); + MOZ_ASSERT(SUCCEEDED(hr)); + sInstance = nullptr; + } + +private: + static StaticRefPtr sInstance; +}; + +template +StaticRefPtr SingletonFactory::sInstance; + +} // namespace mscom +} // namespace mozilla + +#endif // mozilla_mscom_Factory_h diff --git a/ipc/mscom/oop/Handler.cpp b/ipc/mscom/oop/Handler.cpp new file mode 100644 index 000000000000..d497f21e42b7 --- /dev/null +++ b/ipc/mscom/oop/Handler.cpp @@ -0,0 +1,339 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "Handler.h" +#include "Module.h" + +#include "mozilla/ArrayUtils.h" +#include "nsWindowsHelpers.h" + +#include +#include +#include + +/* WARNING! The code in this file may be loaded into the address spaces of other + processes! It MUST NOT link against xul.dll or other Gecko binaries! Only + inline code may be included! */ + +namespace mozilla { +namespace mscom { + +Handler::Handler(IUnknown* aOuter, HRESULT& aResult) + : mRefCnt(0) + , mOuter(aOuter) + , mUnmarshal(nullptr) + , mHasPayload(false) +{ + if (!aOuter) { + aResult = E_INVALIDARG; + return; + } + + StabilizedRefCount stabilizer(mRefCnt); + + aResult = ::CoGetStdMarshalEx(aOuter, SMEXF_HANDLER, + getter_AddRefs(mInnerUnk)); + if (FAILED(aResult)) { + return; + } + + aResult = mInnerUnk->QueryInterface(IID_IMarshal, (void**)&mUnmarshal); + if (FAILED(aResult)) { + return; + } + + // mInnerMarshal is a weak ref + mUnmarshal->Release(); +} + +HRESULT +Handler::InternalQueryInterface(REFIID riid, void** ppv) +{ + if (!ppv) { + return E_INVALIDARG; + } + + if (riid == IID_IUnknown) { + RefPtr punk(static_cast(&mInternalUnknown)); + punk.forget(ppv); + return S_OK; + } + + if (riid == IID_IMarshal) { + RefPtr ptr(this); + ptr.forget(ppv); + return S_OK; + } + + // Try the handler implementation + HRESULT hr = QueryHandlerInterface(mInnerUnk, riid, ppv); + if (hr != E_NOINTERFACE) { + return hr; + } + + // Now forward to the marshaler's inner + return mInnerUnk->QueryInterface(riid, ppv); +} + +ULONG +Handler::InternalAddRef() +{ + if (!mRefCnt) { + Module::Lock(); + } + return ++mRefCnt; +} + +ULONG +Handler::InternalRelease() +{ + if (--mRefCnt == 0) { + delete this; + Module::Unlock(); + } + return mRefCnt; +} + +HRESULT +Handler::GetUnmarshalClass(REFIID riid, void* pv, DWORD dwDestContext, + void* pvDestContext, DWORD mshlflags, + CLSID* pCid) +{ + return mUnmarshal->GetUnmarshalClass(riid, pv, dwDestContext, pvDestContext, + mshlflags, pCid); +} + +HRESULT +Handler::GetMarshalSizeMax(REFIID riid, void* pv, DWORD dwDestContext, + void* pvDestContext, DWORD mshlflags, + DWORD* pSize) +{ + if (!pSize) { + return E_INVALIDARG; + } + + *pSize = 0; + + RefPtr unkToMarshal; + HRESULT hr; + + REFIID marshalAs = MarshalAs(riid); + if (marshalAs == riid) { + unkToMarshal = static_cast(pv); + } else { + hr = mInnerUnk->QueryInterface(marshalAs, getter_AddRefs(unkToMarshal)); + if (FAILED(hr)) { + return hr; + } + } + + // We do not necessarily want to use the pv that COM is giving us; we may want + // to marshal a different proxy that is more appropriate to what we're + // wrapping... + hr = mUnmarshal->GetMarshalSizeMax(marshalAs, unkToMarshal.get(), + dwDestContext, pvDestContext, + mshlflags, pSize); + if (FAILED(hr)) { + return hr; + } + + if (!HasPayload()) { + return S_OK; + } + + DWORD payloadSize = 0; + hr = GetHandlerPayloadSize(marshalAs, &payloadSize); + if (FAILED(hr)) { + return hr; + } + + *pSize += payloadSize; + return S_OK; +} + +HRESULT +Handler::MarshalInterface(IStream* pStm, REFIID riid, void* pv, + DWORD dwDestContext, void* pvDestContext, + DWORD mshlflags) +{ + // We do not necessarily want to use the pv that COM is giving us; we may want + // to marshal a different proxy that is more appropriate to what we're + // wrapping... + RefPtr unkToMarshal; + HRESULT hr; + + REFIID marshalAs = MarshalAs(riid); + if (marshalAs == riid) { + unkToMarshal = static_cast(pv); + } else { + hr = mInnerUnk->QueryInterface(marshalAs, getter_AddRefs(unkToMarshal)); + if (FAILED(hr)) { + return hr; + } + } + + hr = mUnmarshal->MarshalInterface(pStm, marshalAs, unkToMarshal.get(), + dwDestContext, pvDestContext, mshlflags); + if (FAILED(hr)) { + return hr; + } + + if (!HasPayload()) { + return S_OK; + } + + // Unfortunately when COM re-marshals a proxy that prevouisly had a payload, + // we must re-serialize it. + return WriteHandlerPayload(pStm, marshalAs); +} + +HRESULT +Handler::UnmarshalInterface(IStream* pStm, REFIID riid, void** ppv) +{ + REFIID unmarshalAs = MarshalAs(riid); + HRESULT hr = mUnmarshal->UnmarshalInterface(pStm, unmarshalAs, ppv); + if (FAILED(hr)) { + return hr; + } + + hr = ReadHandlerPayload(pStm, unmarshalAs); + + // This method may be called on the same object multiple times (as new + // interfaces are queried off the proxy). Not all interfaces will necessarily + // refresh the payload, so we set mHasPayload using OR to reflect that fact. + // (Otherwise mHasPayload could be cleared and the handler would think that + // it doesn't have a payload even though it actually does). + mHasPayload |= (hr == S_OK); + + // hr may be S_FALSE, but we don't want to return that + return SUCCEEDED(hr) ? S_OK : hr; +} + +HRESULT +Handler::ReleaseMarshalData(IStream* pStm) +{ + return mUnmarshal->ReleaseMarshalData(pStm); +} + +HRESULT +Handler::DisconnectObject(DWORD dwReserved) +{ + return mUnmarshal->DisconnectObject(dwReserved); +} + +template +static HRESULT +BuildClsidPath(wchar_t (&aPath)[N], REFCLSID aClsid) +{ + const wchar_t kClsid[] = {L'C', L'L', L'S', L'I', L'D', L'\\'}; + const size_t kReqdGuidLen = 39; + static_assert(N >= kReqdGuidLen + mozilla::ArrayLength(kClsid), + "aPath array is too short"); + if (wcsncpy_s(aPath, kClsid, mozilla::ArrayLength(kClsid))) { + return E_INVALIDARG; + } + + int guidConversionResult = + StringFromGUID2(aClsid, &aPath[mozilla::ArrayLength(kClsid)], + N - mozilla::ArrayLength(kClsid)); + if (!guidConversionResult) { + return E_INVALIDARG; + } + + return S_OK; +} + +HRESULT +Handler::Unregister(REFCLSID aClsid) +{ + wchar_t path[256] = {}; + HRESULT hr = BuildClsidPath(path, aClsid); + if (FAILED(hr)) { + return hr; + } + + hr = HRESULT_FROM_WIN32(SHDeleteKey(HKEY_CLASSES_ROOT, path)); + if (FAILED(hr)) { + return hr; + } + + return S_OK; +} + +HRESULT +Handler::Register(REFCLSID aClsid) +{ + wchar_t path[256] = {}; + HRESULT hr = BuildClsidPath(path, aClsid); + if (FAILED(hr)) { + return hr; + } + + HKEY rawClsidKey; + DWORD disposition; + LONG result = RegCreateKeyEx(HKEY_CLASSES_ROOT, path, 0, nullptr, + REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, + nullptr, &rawClsidKey, &disposition); + if (result != ERROR_SUCCESS) { + return HRESULT_FROM_WIN32(result); + } + nsAutoRegKey clsidKey(rawClsidKey); + + if (wcscat_s(path, L"\\InprocHandler32")) { + return E_UNEXPECTED; + } + + HKEY rawInprocHandlerKey; + result = RegCreateKeyEx(HKEY_CLASSES_ROOT, path, 0, nullptr, + REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, + nullptr, &rawInprocHandlerKey, &disposition); + if (result != ERROR_SUCCESS) { + Unregister(aClsid); + return HRESULT_FROM_WIN32(result); + } + nsAutoRegKey inprocHandlerKey(rawInprocHandlerKey); + + wchar_t absLibPath[MAX_PATH + 1] = {}; + HMODULE thisModule; + if (!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | + GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + reinterpret_cast(&Handler::Register), + &thisModule)) { + return HRESULT_FROM_WIN32(GetLastError()); + } + + DWORD size = GetModuleFileName(thisModule, absLibPath, + mozilla::ArrayLength(absLibPath)); + if (!size || (size == mozilla::ArrayLength(absLibPath) && + GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { + DWORD lastError = GetLastError(); + Unregister(aClsid); + return HRESULT_FROM_WIN32(lastError); + } + + result = RegSetValueEx(inprocHandlerKey, L"", 0, REG_EXPAND_SZ, + reinterpret_cast(absLibPath), + sizeof(absLibPath)); + if (result != ERROR_SUCCESS) { + Unregister(aClsid); + return HRESULT_FROM_WIN32(result); + } + + const wchar_t kApartment[] = L"Apartment"; + result = RegSetValueEx(inprocHandlerKey, L"ThreadingModel", 0, REG_SZ, + reinterpret_cast(kApartment), + sizeof(kApartment)); + if (result != ERROR_SUCCESS) { + Unregister(aClsid); + return HRESULT_FROM_WIN32(result); + } + + return S_OK; +} + +} // namespace mscom +} // namespace mozilla + diff --git a/ipc/mscom/oop/Handler.h b/ipc/mscom/oop/Handler.h new file mode 100644 index 000000000000..8353313c11e0 --- /dev/null +++ b/ipc/mscom/oop/Handler.h @@ -0,0 +1,127 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_mscom_Handler_h +#define mozilla_mscom_Handler_h + +#if defined(MOZILLA_INTERNAL_API) +#error This code is NOT for internal Gecko use! +#endif // defined(MOZILLA_INTERNAL_API) + +#include + +#include "mozilla/mscom/Aggregation.h" +#include "mozilla/RefPtr.h" + +/* WARNING! The code in this file may be loaded into the address spaces of other + processes! It MUST NOT link against xul.dll or other Gecko binaries! Only + inline code may be included! */ + +namespace mozilla { +namespace mscom { + +class Handler : public IMarshal +{ +public: + // IMarshal + STDMETHODIMP GetUnmarshalClass(REFIID riid, void* pv, DWORD dwDestContext, + void* pvDestContext, DWORD mshlflags, + CLSID* pCid) override; + STDMETHODIMP GetMarshalSizeMax(REFIID riid, void* pv, DWORD dwDestContext, + void* pvDestContext, DWORD mshlflags, + DWORD* pSize) override; + STDMETHODIMP MarshalInterface(IStream* pStm, REFIID riid, void* pv, + DWORD dwDestContext, void* pvDestContext, + DWORD mshlflags) override; + STDMETHODIMP UnmarshalInterface(IStream* pStm, REFIID riid, + void** ppv) override; + STDMETHODIMP ReleaseMarshalData(IStream* pStm) override; + STDMETHODIMP DisconnectObject(DWORD dwReserved) override; + + /** + * This method allows the handler to return its own interfaces that override + * those interfaces that are exposed by the underlying COM proxy. + * @param aProxyUnknown is the IUnknown of the underlying COM proxy. This is + * provided to give the handler implementation an + * opportunity to acquire interfaces to the underlying + * remote object, if needed. + * @param aIid Interface requested, similar to IUnknown::QueryInterface + * @param aOutInterface Outparam for the resulting interface to return to the + * client. + * @return The usual HRESULT codes similarly to IUnknown::QueryInterface + */ + virtual HRESULT QueryHandlerInterface(IUnknown* aProxyUnknown, REFIID aIid, + void** aOutInterface) = 0; + /** + * Called when the implementer should deserialize data in aStream. + * @return S_OK on success; + * S_FALSE if the deserialization was successful but there was no data; + * HRESULT error code otherwise. + */ + virtual HRESULT ReadHandlerPayload(IStream* aStream, REFIID aIid) + { return S_FALSE; } + + /** + * Unfortunately when COM marshals a proxy, it doesn't implicitly marshal + * the payload that was originally sent with the proxy. We must implement + * that code in the handler in order to make this happen. + */ + + /** + * This function allows the implementer to substitute a different interface + * for marshaling than the one that COM is intending to marshal. For example, + * the implementer might want to marshal a proxy for an interface that is + * derived from the requested interface. + * + * The default implementation is the identity function. + */ + virtual REFIID MarshalAs(REFIID aRequestedIid) { return aRequestedIid; } + + /** + * Called when the implementer must provide the size of the payload. + */ + virtual HRESULT GetHandlerPayloadSize(REFIID aIid, DWORD* aOutPayloadSize) + { + if (!aOutPayloadSize) { + return E_INVALIDARG; + } + *aOutPayloadSize = 0; + return S_OK; + } + + /** + * Called when the implementer should serialize the payload data into aStream. + */ + virtual HRESULT WriteHandlerPayload(IStream* aStream, REFIID aIid) + { + return S_OK; + } + + IUnknown* GetProxy() const { return mInnerUnk; } + + static HRESULT Register(REFCLSID aClsid); + static HRESULT Unregister(REFCLSID aClsid); + +protected: + Handler(IUnknown* aOuter, HRESULT& aResult); + virtual ~Handler() {} + bool HasPayload() const { return mHasPayload; } + IUnknown* GetOuter() const { return mOuter; } + +private: + ULONG mRefCnt; + IUnknown* mOuter; + RefPtr mInnerUnk; + IMarshal* mUnmarshal; // WEAK + bool mHasPayload; + DECLARE_AGGREGATABLE(Handler); +}; + +} // namespace mscom +} // namespace mozilla + +#endif // mozilla_mscom_Handler_h + diff --git a/ipc/mscom/oop/Module.cpp b/ipc/mscom/oop/Module.cpp new file mode 100644 index 000000000000..c0d890d810de --- /dev/null +++ b/ipc/mscom/oop/Module.cpp @@ -0,0 +1,19 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "Module.h" + +#include +#include + +namespace mozilla { +namespace mscom { + +ULONG Module::sRefCount = 0; + +} // namespace mscom +} // namespace mozilla + diff --git a/ipc/mscom/oop/Module.h b/ipc/mscom/oop/Module.h new file mode 100644 index 000000000000..21c8557a7ad9 --- /dev/null +++ b/ipc/mscom/oop/Module.h @@ -0,0 +1,39 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_mscom_Module_h +#define mozilla_mscom_Module_h + +#if defined(MOZILLA_INTERNAL_API) +#error This code is NOT for internal Gecko use! +#endif // defined(MOZILLA_INTERNAL_API) + +#include + +/* WARNING! The code in this file may be loaded into the address spaces of other + processes! It MUST NOT link against xul.dll or other Gecko binaries! Only + inline code may be included! */ + +namespace mozilla { +namespace mscom { + +class Module +{ +public: + static HRESULT CanUnload() { return sRefCount == 0 ? S_OK : S_FALSE; } + + static void Lock() { ++sRefCount; } + static void Unlock() { --sRefCount; } + +private: + static ULONG sRefCount; +}; + +} // namespace mscom +} // namespace mozilla + +#endif // mozilla_mscom_Module_h + diff --git a/ipc/mscom/oop/moz.build b/ipc/mscom/oop/moz.build new file mode 100644 index 000000000000..b2d224ff5bb4 --- /dev/null +++ b/ipc/mscom/oop/moz.build @@ -0,0 +1,36 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +Library('mscom_oop') + +SOURCES += [ + '../ActivationContext.cpp', + '../Registration.cpp', + '../StructStream.cpp', +] + +UNIFIED_SOURCES += [ + 'Handler.cpp', + 'Module.cpp', +] + +OS_LIBS += [ + 'ole32', + 'oleaut32', + 'shlwapi', +] + +LIBRARY_DEFINES['UNICODE'] = True +LIBRARY_DEFINES['_UNICODE'] = True +LIBRARY_DEFINES['MOZ_NO_MOZALLOC'] = True + +DISABLE_STL_WRAPPING = True +NO_EXPAND_LIBS = True +FORCE_STATIC_LIB = True + +# This DLL may be loaded into other processes, so we need static libs for +# Windows 7 and Windows 8. +USE_STATIC_LIBS = True From 68316b419cf3a9b50b0c0c125598493c27b25fdd Mon Sep 17 00:00:00 2001 From: Phil Ringnalda Date: Wed, 22 Feb 2017 21:55:15 -0800 Subject: [PATCH 080/234] Backed out 2 changesets (bug 1303060) for Windows static-analysis bustage CLOSED TREE Backed out changeset 729a1b8c7e47 (bug 1303060) Backed out changeset 604605ca738c (bug 1303060) --- ipc/mscom/Aggregation.h | 48 ----- ipc/mscom/IHandlerPayload.h | 35 ---- ipc/mscom/Interceptor.cpp | 154 ++------------- ipc/mscom/Interceptor.h | 32 +-- ipc/mscom/MainThreadHandoff.cpp | 176 +---------------- ipc/mscom/MainThreadHandoff.h | 25 +-- ipc/mscom/Registration.cpp | 8 +- ipc/mscom/Registration.h | 2 +- ipc/mscom/moz.build | 5 - ipc/mscom/oop/Factory.h | 155 --------------- ipc/mscom/oop/Handler.cpp | 339 -------------------------------- ipc/mscom/oop/Handler.h | 127 ------------ ipc/mscom/oop/Module.cpp | 19 -- ipc/mscom/oop/Module.h | 39 ---- ipc/mscom/oop/moz.build | 36 ---- 15 files changed, 32 insertions(+), 1168 deletions(-) delete mode 100644 ipc/mscom/IHandlerPayload.h delete mode 100644 ipc/mscom/oop/Factory.h delete mode 100644 ipc/mscom/oop/Handler.cpp delete mode 100644 ipc/mscom/oop/Handler.h delete mode 100644 ipc/mscom/oop/Module.cpp delete mode 100644 ipc/mscom/oop/Module.h delete mode 100644 ipc/mscom/oop/moz.build diff --git a/ipc/mscom/Aggregation.h b/ipc/mscom/Aggregation.h index 3bae2358695a..36e56f91a410 100644 --- a/ipc/mscom/Aggregation.h +++ b/ipc/mscom/Aggregation.h @@ -9,9 +9,6 @@ #include "mozilla/Attributes.h" -#include -#include - namespace mozilla { namespace mscom { @@ -47,53 +44,8 @@ private: RefCntT& mRefCnt; }; -namespace detail { - -template -class InternalUnknown : public IUnknown -{ -public: - STDMETHODIMP QueryInterface(REFIID aIid, void** aOutInterface) override - { - return This()->InternalQueryInterface(aIid, aOutInterface); - } - - STDMETHODIMP_(ULONG) AddRef() override - { - return This()->InternalAddRef(); - } - - STDMETHODIMP_(ULONG) Release() override - { - return This()->InternalRelease(); - } - -private: - T* This() - { - return reinterpret_cast(reinterpret_cast(this) - - offsetof(T, mInternalUnknown)); - } -}; - -} // namespace detail } // namespace mscom } // namespace mozilla -#define DECLARE_AGGREGATABLE(Type) \ - public: \ - STDMETHODIMP QueryInterface(REFIID riid, void** ppv) override \ - { return mOuter->QueryInterface(riid, ppv); } \ - STDMETHODIMP_(ULONG) AddRef() override \ - { return mOuter->AddRef(); } \ - STDMETHODIMP_(ULONG) Release() override \ - { return mOuter->Release(); } \ - protected: \ - STDMETHODIMP InternalQueryInterface(REFIID riid, void** ppv); \ - STDMETHODIMP_(ULONG) InternalAddRef(); \ - STDMETHODIMP_(ULONG) InternalRelease(); \ - friend class mozilla::mscom::detail::InternalUnknown; \ - mozilla::mscom::detail::InternalUnknown mInternalUnknown - #endif // mozilla_mscom_Aggregation_h diff --git a/ipc/mscom/IHandlerPayload.h b/ipc/mscom/IHandlerPayload.h deleted file mode 100644 index c2edec331d64..000000000000 --- a/ipc/mscom/IHandlerPayload.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_mscom_IHandlerPayload_h -#define mozilla_mscom_IHandlerPayload_h - -#include - -namespace mozilla { -namespace mscom { - -struct HandlerPayload -{ - virtual STDMETHODIMP GetHandler(CLSID* aHandlerClsid) = 0; - virtual STDMETHODIMP GetHandlerPayloadSize(REFIID aIid, - IUnknown* aTarget, - DWORD* aOutPayloadSize) = 0; - virtual STDMETHODIMP WriteHandlerPayload(IStream* aStream, REFIID aIid, - IUnknown* aTarget) = 0; - virtual REFIID MarshalAs(REFIID aIid) = 0; -}; - -struct IHandlerPayload : public IUnknown - , public HandlerPayload -{ - virtual STDMETHODIMP Clone(IHandlerPayload** aOutNewPayload) = 0; -}; - -} // namespace mscom -} // namespace mozilla - -#endif // mozilla_mscom_IHandlerPayload_h diff --git a/ipc/mscom/Interceptor.cpp b/ipc/mscom/Interceptor.cpp index 369050a83f3d..b71030f8b087 100644 --- a/ipc/mscom/Interceptor.cpp +++ b/ipc/mscom/Interceptor.cpp @@ -46,7 +46,6 @@ Interceptor::Interceptor(STAUniquePtr aTarget, IInterceptorSink* aSink , mTarget(Move(aTarget)) , mEventSink(aSink) , mMutex("mozilla::mscom::Interceptor::mMutex") - , mStdMarshal(nullptr) { MOZ_ASSERT(aSink); MOZ_ASSERT(!IsProxy(mTarget.get())); @@ -68,77 +67,6 @@ Interceptor::~Interceptor() } } -HRESULT -Interceptor::GetClassForHandler(DWORD aDestContext, void* aDestContextPtr, - CLSID* aHandlerClsid) -{ - if (aDestContextPtr || !aHandlerClsid || - aDestContext == MSHCTX_DIFFERENTMACHINE) { - return E_INVALIDARG; - } - MOZ_ASSERT(mEventSink); - return mEventSink->GetHandler(aHandlerClsid); -} - -HRESULT -Interceptor::GetUnmarshalClass(REFIID riid, void* pv, DWORD dwDestContext, - void* pvDestContext, DWORD mshlflags, - CLSID* pCid) -{ - return mStdMarshal->GetUnmarshalClass(riid, pv, dwDestContext, pvDestContext, - mshlflags, pCid); -} - -HRESULT -Interceptor::GetMarshalSizeMax(REFIID riid, void* pv, DWORD dwDestContext, - void* pvDestContext, DWORD mshlflags, - DWORD* pSize) -{ - HRESULT hr = mStdMarshal->GetMarshalSizeMax(riid, pv, dwDestContext, - pvDestContext, mshlflags, pSize); - if (FAILED(hr)) { - return hr; - } - - DWORD payloadSize = 0; - hr = mEventSink->GetHandlerPayloadSize(riid, mTarget.get(), &payloadSize); - *pSize += payloadSize; - return hr; -} - -HRESULT -Interceptor::MarshalInterface(IStream* pStm, REFIID riid, void* pv, - DWORD dwDestContext, void* pvDestContext, - DWORD mshlflags) -{ - HRESULT hr = mStdMarshal->MarshalInterface(pStm, riid, pv, dwDestContext, - pvDestContext, mshlflags); - if (FAILED(hr)) { - return hr; - } - - return mEventSink->WriteHandlerPayload(pStm, riid, mTarget.get()); -} - -HRESULT -Interceptor::UnmarshalInterface(IStream* pStm, REFIID riid, - void** ppv) -{ - return mStdMarshal->UnmarshalInterface(pStm, riid, ppv); -} - -HRESULT -Interceptor::ReleaseMarshalData(IStream* pStm) -{ - return mStdMarshal->ReleaseMarshalData(pStm); -} - -HRESULT -Interceptor::DisconnectObject(DWORD dwReserved) -{ - return mStdMarshal->DisconnectObject(dwReserved); -} - Interceptor::MapEntry* Interceptor::Lookup(REFIID aIid) { @@ -220,22 +148,19 @@ Interceptor::GetInterceptorForIID(REFIID aIid, void** aOutInterceptor) if (aIid == IID_IUnknown) { // Special case: When we see IUnknown, we just provide a reference to this - RefPtr intcpt(this); - intcpt.forget(aOutInterceptor); + *aOutInterceptor = static_cast(this); + AddRef(); return S_OK; } - REFIID interceptorIid = mEventSink->MarshalAs(aIid); - RefPtr unkInterceptor; IUnknown* interfaceForQILog = nullptr; - // (1) Check to see if we already have an existing interceptor for - // interceptorIid. + // (1) Check to see if we already have an existing interceptor for aIid. { // Scope for lock MutexAutoLock lock(mMutex); - MapEntry* entry = Lookup(interceptorIid); + MapEntry* entry = Lookup(aIid); if (entry) { unkInterceptor = entry->mInterceptor; interfaceForQILog = entry->mTargetInterface; @@ -250,7 +175,7 @@ Interceptor::GetInterceptorForIID(REFIID aIid, void** aOutInterceptor) // was requested. InterceptorLog::QI(S_OK, mTarget.get(), aIid, interfaceForQILog); - return unkInterceptor->QueryInterface(interceptorIid, aOutInterceptor); + return unkInterceptor->QueryInterface(aIid, aOutInterceptor); } // (2) Obtain a new target interface. @@ -263,7 +188,7 @@ Interceptor::GetInterceptorForIID(REFIID aIid, void** aOutInterceptor) STAUniquePtr targetInterface; IUnknown* rawTargetInterface = nullptr; - hr = QueryInterfaceTarget(interceptorIid, (void**)&rawTargetInterface); + hr = QueryInterfaceTarget(aIid, (void**)&rawTargetInterface); targetInterface.reset(rawTargetInterface); InterceptorLog::QI(hr, mTarget.get(), aIid, targetInterface.get()); MOZ_ASSERT(SUCCEEDED(hr) || hr == E_NOINTERFACE); @@ -281,8 +206,7 @@ Interceptor::GetInterceptorForIID(REFIID aIid, void** aOutInterceptor) RefPtr kungFuDeathGrip(static_cast( static_cast(this))); - hr = CreateInterceptor(interceptorIid, kungFuDeathGrip, - getter_AddRefs(unkInterceptor)); + hr = CreateInterceptor(aIid, kungFuDeathGrip, getter_AddRefs(unkInterceptor)); if (FAILED(hr)) { return hr; } @@ -307,7 +231,7 @@ Interceptor::GetInterceptorForIID(REFIID aIid, void** aOutInterceptor) MutexAutoLock lock(mMutex); // We might have raced with another thread, so first check that we don't // already have an entry for this - MapEntry* entry = Lookup(interceptorIid); + MapEntry* entry = Lookup(aIid); if (entry && entry->mInterceptor) { unkInterceptor = entry->mInterceptor; } else { @@ -315,13 +239,13 @@ Interceptor::GetInterceptorForIID(REFIID aIid, void** aOutInterceptor) // refcount for the target interface because we are just moving it into // the map and its refcounting might not be thread-safe. IUnknown* rawTargetInterface = targetInterface.release(); - mInterceptorMap.AppendElement(MapEntry(interceptorIid, + mInterceptorMap.AppendElement(MapEntry(aIid, unkInterceptor, rawTargetInterface)); } } - return unkInterceptor->QueryInterface(interceptorIid, aOutInterceptor); + return unkInterceptor->QueryInterface(aIid, aOutInterceptor); } HRESULT @@ -351,63 +275,9 @@ Interceptor::QueryInterface(REFIID riid, void** ppv) HRESULT Interceptor::ThreadSafeQueryInterface(REFIID aIid, IUnknown** aOutInterface) { - if (aIid == IID_INoMarshal) { - // This entire library is designed around marshaling, so there's no point - // propagating this QI request all over the place! - return E_NOINTERFACE; - } - - if (aIid == IID_IStdMarshalInfo) { - // Do not indicate that this interface is available unless we actually - // support it. We'll check that by looking for a successful call to - // IInterceptorSink::GetHandler() - CLSID dummy; - if (FAILED(mEventSink->GetHandler(&dummy))) { - return E_NOINTERFACE; - } - - RefPtr std(this); - std.forget(aOutInterface); - return S_OK; - } - - if (aIid == IID_IMarshal) { - // Do not indicate that this interface is available unless we actually - // support it. We'll check that by looking for a successful call to - // IInterceptorSink::GetHandler() - CLSID dummy; - if (FAILED(mEventSink->GetHandler(&dummy))) { - return E_NOINTERFACE; - } - - if (!mStdMarshalUnk) { - HRESULT hr = ::CoGetStdMarshalEx(static_cast(this), - SMEXF_SERVER, - getter_AddRefs(mStdMarshalUnk)); - if (FAILED(hr)) { - return hr; - } - } - - if (!mStdMarshal) { - HRESULT hr = mStdMarshalUnk->QueryInterface(IID_IMarshal, - (void**)&mStdMarshal); - if (FAILED(hr)) { - return hr; - } - - // mStdMarshal is weak, so drop its refcount - mStdMarshal->Release(); - } - - RefPtr marshal(this); - marshal.forget(aOutInterface); - return S_OK; - } - if (aIid == IID_IInterceptor) { - RefPtr intcpt(this); - intcpt.forget(aOutInterface); + *aOutInterface = static_cast(this); + (*aOutInterface)->AddRef(); return S_OK; } diff --git a/ipc/mscom/Interceptor.h b/ipc/mscom/Interceptor.h index 4f6d0e26fec2..6630bb018828 100644 --- a/ipc/mscom/Interceptor.h +++ b/ipc/mscom/Interceptor.h @@ -4,18 +4,16 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef mozilla_mscom_Interceptor_h -#define mozilla_mscom_Interceptor_h +#ifndef mozilla_mscom_interceptor_h +#define mozilla_mscom_interceptor_h #include "mozilla/Move.h" #include "mozilla/Mutex.h" #include "nsTArray.h" -#include "mozilla/mscom/IHandlerPayload.h" #include "mozilla/mscom/Ptr.h" #include "mozilla/mscom/WeakRef.h" #include "mozilla/RefPtr.h" -#include #include namespace mozilla { @@ -26,7 +24,6 @@ DEFINE_GUID(IID_IInterceptorSink, 0x8831eb53, 0xa937, 0x42bc, 0x99, 0x21, 0xb3, 0xe1, 0x12, 0x1f, 0xdf, 0x86); struct IInterceptorSink : public ICallFrameEvents - , public HandlerPayload { virtual STDMETHODIMP SetInterceptor(IWeakReference* aInterceptor) = 0; }; @@ -60,8 +57,6 @@ struct IInterceptor : public IUnknown * (the mscom::Interceptor we implement and control). */ class Interceptor final : public WeakReferenceSupport - , public IStdMarshalInfo - , public IMarshal , public IInterceptor { public: @@ -73,25 +68,6 @@ public: STDMETHODIMP_(ULONG) AddRef() override; STDMETHODIMP_(ULONG) Release() override; - // IStdMarshalInfo - STDMETHODIMP GetClassForHandler(DWORD aDestContext, void* aDestContextPtr, - CLSID* aHandlerClsid) override; - - // IMarshal - STDMETHODIMP GetUnmarshalClass(REFIID riid, void* pv, DWORD dwDestContext, - void* pvDestContext, DWORD mshlflags, - CLSID* pCid) override; - STDMETHODIMP GetMarshalSizeMax(REFIID riid, void* pv, DWORD dwDestContext, - void* pvDestContext, DWORD mshlflags, - DWORD* pSize) override; - STDMETHODIMP MarshalInterface(IStream* pStm, REFIID riid, void* pv, - DWORD dwDestContext, void* pvDestContext, - DWORD mshlflags) override; - STDMETHODIMP UnmarshalInterface(IStream* pStm, REFIID riid, - void** ppv) override; - STDMETHODIMP ReleaseMarshalData(IStream* pStm) override; - STDMETHODIMP DisconnectObject(DWORD dwReserved) override; - // IInterceptor STDMETHODIMP GetTargetForIID(REFIID aIid, InterceptorTargetPtr& aTarget) override; STDMETHODIMP GetInterceptorForIID(REFIID aIid, void** aOutInterceptor) override; @@ -124,8 +100,6 @@ private: mozilla::Mutex mMutex; // Guards mInterceptorMap // Using a nsTArray since the # of interfaces is not going to be very high nsTArray mInterceptorMap; - RefPtr mStdMarshalUnk; - IMarshal* mStdMarshal; // WEAK }; template @@ -148,4 +122,4 @@ CreateInterceptor(STAUniquePtr aTargetInterface, } // namespace mscom } // namespace mozilla -#endif // mozilla_mscom_Interceptor_h +#endif // mozilla_mscom_interceptor_h diff --git a/ipc/mscom/MainThreadHandoff.cpp b/ipc/mscom/MainThreadHandoff.cpp index 1fd9382b6f36..521bf7f8e8df 100644 --- a/ipc/mscom/MainThreadHandoff.cpp +++ b/ipc/mscom/MainThreadHandoff.cpp @@ -6,9 +6,7 @@ #include "mozilla/mscom/MainThreadHandoff.h" -#include "mozilla/Attributes.h" #include "mozilla/Move.h" -#include "mozilla/mscom/AgileReference.h" #include "mozilla/mscom/InterceptorLog.h" #include "mozilla/mscom/Registration.h" #include "mozilla/mscom/Utils.h" @@ -17,106 +15,9 @@ #include "nsThreadUtils.h" using mozilla::DebugOnly; -using mozilla::mscom::AgileReference; namespace { -class MOZ_NONHEAP_CLASS InParamWalker : private ICallFrameWalker -{ -public: - InParamWalker() - : mPreHandoff(true) - { - } - - void SetHandoffDone() - { - mPreHandoff = false; - mAgileRefsItr = mAgileRefs.begin(); - } - - HRESULT Walk(ICallFrame* aFrame) - { - MOZ_ASSERT(aFrame); - if (!aFrame) { - return E_INVALIDARG; - } - - return aFrame->WalkFrame(CALLFRAME_WALK_IN, this); - } - -private: - // IUnknown - STDMETHODIMP QueryInterface(REFIID aIid, void** aOutInterface) override - { - if (!aOutInterface) { - return E_INVALIDARG; - } - *aOutInterface = nullptr; - - if (aIid == IID_IUnknown || aIid == IID_ICallFrameWalker) { - *aOutInterface = static_cast(this); - return S_OK; - } - - return E_NOINTERFACE; - } - - STDMETHODIMP_(ULONG) AddRef() override - { - return 2; - } - - STDMETHODIMP_(ULONG) Release() override - { - return 1; - } - - // ICallFrameWalker - STDMETHODIMP OnWalkInterface(REFIID aIid, PVOID* aInterface, BOOL aIn, - BOOL aOut) override - { - MOZ_ASSERT(aIn); - if (!aIn) { - return E_UNEXPECTED; - } - - IUnknown* origInterface = static_cast(*aInterface); - if (!origInterface) { - // Nothing to do - return S_OK; - } - - if (mPreHandoff) { - mAgileRefs.AppendElement(AgileReference(aIid, origInterface)); - return S_OK; - } - - MOZ_ASSERT(mAgileRefsItr != mAgileRefs.end()); - if (mAgileRefsItr == mAgileRefs.end()) { - return E_UNEXPECTED; - } - - HRESULT hr = mAgileRefsItr->Resolve(aIid, aInterface); - MOZ_ASSERT(SUCCEEDED(hr)); - if (SUCCEEDED(hr)) { - ++mAgileRefsItr; - } - - return hr; - } - - InParamWalker(const InParamWalker&) = delete; - InParamWalker(InParamWalker&&) = delete; - InParamWalker& operator=(const InParamWalker&) = delete; - InParamWalker& operator=(InParamWalker&&) = delete; - -private: - bool mPreHandoff; - AutoTArray mAgileRefs; - nsTArray::iterator mAgileRefsItr; -}; - class HandoffRunnable : public mozilla::Runnable { public: @@ -125,17 +26,10 @@ public: , mTargetInterface(aTargetInterface) , mResult(E_UNEXPECTED) { - DebugOnly hr = mInParamWalker.Walk(aCallFrame); - MOZ_ASSERT(SUCCEEDED(hr)); } NS_IMETHOD Run() override { - mInParamWalker.SetHandoffDone(); - // We declare hr a DebugOnly because if mInParamWalker.Walk() fails, then - // mCallFrame->Invoke will fail anyway. - DebugOnly hr = mInParamWalker.Walk(mCallFrame); - MOZ_ASSERT(SUCCEEDED(hr)); mResult = mCallFrame->Invoke(mTargetInterface); return NS_OK; } @@ -146,10 +40,9 @@ public: } private: - ICallFrame* mCallFrame; - InParamWalker mInParamWalker; - IUnknown* mTargetInterface; - HRESULT mResult; + ICallFrame* mCallFrame; + IUnknown* mTargetInterface; + HRESULT mResult; }; } // anonymous namespace @@ -158,16 +51,14 @@ namespace mozilla { namespace mscom { /* static */ HRESULT -MainThreadHandoff::Create(IHandlerPayload* aHandlerPayload, - IInterceptorSink** aOutput) +MainThreadHandoff::Create(IInterceptorSink** aOutput) { - RefPtr handoff(new MainThreadHandoff(aHandlerPayload)); + RefPtr handoff(new MainThreadHandoff()); return handoff->QueryInterface(IID_IInterceptorSink, (void**) aOutput); } -MainThreadHandoff::MainThreadHandoff(IHandlerPayload* aHandlerPayload) +MainThreadHandoff::MainThreadHandoff() : mRefCnt(0) - , mHandlerPayload(aHandlerPayload) { } @@ -252,7 +143,7 @@ MainThreadHandoff::OnCall(ICallFrame* aFrame) return hr; } - // (2) Execute the method call synchronously on the main thread + // (2) Execute the method call syncrhonously on the main thread RefPtr handoffInfo(new HandoffRunnable(aFrame, targetInterface.get())); MainThreadInvoker invoker; @@ -405,44 +296,6 @@ MainThreadHandoff::SetInterceptor(IWeakReference* aInterceptor) return S_OK; } -HRESULT -MainThreadHandoff::GetHandler(CLSID* aHandlerClsid) -{ - if (!mHandlerPayload) { - return E_NOTIMPL; - } - return mHandlerPayload->GetHandler(aHandlerClsid); -} - -HRESULT -MainThreadHandoff::GetHandlerPayloadSize(REFIID aIid, IUnknown* aTarget, - DWORD* aOutPayloadSize) -{ - if (!mHandlerPayload) { - return E_NOTIMPL; - } - return mHandlerPayload->GetHandlerPayloadSize(aIid, aTarget, aOutPayloadSize); -} - -HRESULT -MainThreadHandoff::WriteHandlerPayload(IStream* aStream, REFIID aIid, - IUnknown* aTarget) -{ - if (!mHandlerPayload) { - return E_NOTIMPL; - } - return mHandlerPayload->WriteHandlerPayload(aStream, aIid, aTarget); -} - -REFIID -MainThreadHandoff::MarshalAs(REFIID aIid) -{ - if (!mHandlerPayload) { - return aIid; - } - return mHandlerPayload->MarshalAs(aIid); -} - HRESULT MainThreadHandoff::OnWalkInterface(REFIID aIid, PVOID* aInterface, BOOL aIsInParam, BOOL aIsOutParam) @@ -516,27 +369,16 @@ MainThreadHandoff::OnWalkInterface(REFIID aIid, PVOID* aInterface, } } - RefPtr payload; - if (mHandlerPayload) { - hr = mHandlerPayload->Clone(getter_AddRefs(payload)); - MOZ_ASSERT(SUCCEEDED(hr)); - if (FAILED(hr)) { - return hr; - } - } - // Now create a new MainThreadHandoff wrapper... RefPtr handoff; - hr = MainThreadHandoff::Create(payload, getter_AddRefs(handoff)); + hr = MainThreadHandoff::Create(getter_AddRefs(handoff)); MOZ_ASSERT(SUCCEEDED(hr)); if (FAILED(hr)) { return hr; } - REFIID interceptorIid = payload ? payload->MarshalAs(aIid) : aIid; - RefPtr wrapped; - hr = Interceptor::Create(Move(origInterface), handoff, interceptorIid, + hr = Interceptor::Create(Move(origInterface), handoff, aIid, getter_AddRefs(wrapped)); MOZ_ASSERT(SUCCEEDED(hr)); if (FAILED(hr)) { diff --git a/ipc/mscom/MainThreadHandoff.h b/ipc/mscom/MainThreadHandoff.h index 104cf8c65dcb..a3ae47e1bfff 100644 --- a/ipc/mscom/MainThreadHandoff.h +++ b/ipc/mscom/MainThreadHandoff.h @@ -24,26 +24,15 @@ class MainThreadHandoff final : public IInterceptorSink , public ICallFrameWalker { public: - static HRESULT Create(IHandlerPayload* aHandlerPayload, - IInterceptorSink** aOutput); + static HRESULT Create(IInterceptorSink** aOutput); template static HRESULT WrapInterface(STAUniquePtr aTargetInterface, Interface** aOutInterface) - { - return WrapInterface(Move(aTargetInterface), nullptr, - aOutInterface); - } - - template - static HRESULT WrapInterface(STAUniquePtr aTargetInterface, - IHandlerPayload* aHandlerPayload, - Interface** aOutInterface) { MOZ_ASSERT(!IsProxy(aTargetInterface.get())); RefPtr handoff; - HRESULT hr = MainThreadHandoff::Create(aHandlerPayload, - getter_AddRefs(handoff)); + HRESULT hr = MainThreadHandoff::Create(getter_AddRefs(handoff)); if (FAILED(hr)) { return hr; } @@ -60,20 +49,13 @@ public: // IInterceptorSink STDMETHODIMP SetInterceptor(IWeakReference* aInterceptor) override; - STDMETHODIMP GetHandler(CLSID* aHandlerClsid) override; - STDMETHODIMP GetHandlerPayloadSize(REFIID aIid, - IUnknown* aTarget, - DWORD* aOutPayloadSize) override; - STDMETHODIMP WriteHandlerPayload(IStream* aStream, REFIID aIid, - IUnknown* aTarget) override; - REFIID MarshalAs(REFIID aIid) override; // ICallFrameWalker STDMETHODIMP OnWalkInterface(REFIID aIid, PVOID* aInterface, BOOL aIsInParam, BOOL aIsOutParam) override; private: - explicit MainThreadHandoff(IHandlerPayload* aHandlerPayload); + MainThreadHandoff(); ~MainThreadHandoff(); HRESULT FixArrayElements(ICallFrame* aFrame, const ArrayData& aArrayData); @@ -81,7 +63,6 @@ private: private: ULONG mRefCnt; RefPtr mInterceptor; - RefPtr mHandlerPayload; }; } // namespace mscom diff --git a/ipc/mscom/Registration.cpp b/ipc/mscom/Registration.cpp index e5136794b1a3..f39f8b1d9b97 100644 --- a/ipc/mscom/Registration.cpp +++ b/ipc/mscom/Registration.cpp @@ -369,8 +369,8 @@ RegisteredProxy::operator=(RegisteredProxy&& aOther) } HRESULT -RegisteredProxy::GetTypeInfoForGuid(REFGUID aGuid, - ITypeInfo** aOutTypeInfo) const +RegisteredProxy::GetTypeInfoForInterface(REFIID aIid, + ITypeInfo** aOutTypeInfo) const { if (!aOutTypeInfo) { return E_INVALIDARG; @@ -378,7 +378,7 @@ RegisteredProxy::GetTypeInfoForGuid(REFGUID aGuid, if (!mTypeLib) { return E_UNEXPECTED; } - return mTypeLib->lpVtbl->GetTypeInfoOfGuid(mTypeLib, aGuid, aOutTypeInfo); + return mTypeLib->lpVtbl->GetTypeInfoOfGuid(mTypeLib, aIid, aOutTypeInfo); } static StaticAutoPtr> sRegistry; @@ -418,7 +418,7 @@ RegisteredProxy::Find(REFIID aIid, ITypeInfo** aTypeInfo) } for (auto&& proxy : *sRegistry) { - if (SUCCEEDED(proxy->GetTypeInfoForGuid(aIid, aTypeInfo))) { + if (SUCCEEDED(proxy->GetTypeInfoForInterface(aIid, aTypeInfo))) { return true; } } diff --git a/ipc/mscom/Registration.h b/ipc/mscom/Registration.h index 9d58502ffc71..8cccd0f257fe 100644 --- a/ipc/mscom/Registration.h +++ b/ipc/mscom/Registration.h @@ -36,7 +36,7 @@ public: ~RegisteredProxy(); - HRESULT GetTypeInfoForGuid(REFGUID aGuid, ITypeInfo** aOutTypeInfo) const; + HRESULT GetTypeInfoForInterface(REFIID aIid, ITypeInfo** aOutTypeInfo) const; static bool Find(REFIID aIid, ITypeInfo** aOutTypeInfo); diff --git a/ipc/mscom/moz.build b/ipc/mscom/moz.build index 6fdd7489c8ac..143d6371be69 100644 --- a/ipc/mscom/moz.build +++ b/ipc/mscom/moz.build @@ -26,14 +26,9 @@ UNIFIED_SOURCES += [ ] if CONFIG['ACCESSIBILITY']: - DIRS += [ - 'oop', - ] - EXPORTS.mozilla.mscom += [ 'ActivationContext.h', 'DispatchForwarder.h', - 'IHandlerPayload.h', 'Interceptor.h', 'InterceptorLog.h', 'MainThreadHandoff.h', diff --git a/ipc/mscom/oop/Factory.h b/ipc/mscom/oop/Factory.h deleted file mode 100644 index 7ac6ceceb255..000000000000 --- a/ipc/mscom/oop/Factory.h +++ /dev/null @@ -1,155 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_mscom_Factory_h -#define mozilla_mscom_Factory_h - -#if defined(MOZILLA_INTERNAL_API) -#error This code is NOT for internal Gecko use! -#endif // defined(MOZILLA_INTERNAL_API) - -#include "mozilla/Attributes.h" -#include "mozilla/DebugOnly.h" -#include "mozilla/Move.h" -#include "mozilla/RefPtr.h" -#include "mozilla/StaticPtr.h" -#include "Module.h" - -#include -#include - -/* WARNING! The code in this file may be loaded into the address spaces of other - processes! It MUST NOT link against xul.dll or other Gecko binaries! Only - inline code may be included! */ - -namespace mozilla { -namespace mscom { - -template -class MOZ_NONHEAP_CLASS Factory : public IClassFactory -{ - template - HRESULT DoCreate(Args... args) - { - MOZ_DIAGNOSTIC_ASSERT(false, "This should not be executed"); - return E_NOTIMPL; - } - - template - HRESULT DoCreate(HRESULT (*aFnPtr)(IUnknown*, REFIID, void**), Args... args) - { - return aFnPtr(mozilla::Forward(args)...); - } - -public: - // IUnknown - STDMETHODIMP QueryInterface(REFIID aIid, void** aOutInterface) override - { - if (!aOutInterface) { - return E_INVALIDARG; - } - - if (aIid == IID_IUnknown || aIid == IID_IClassFactory) { - RefPtr punk(this); - punk.forget(aOutInterface); - return S_OK; - } - - *aOutInterface = nullptr; - - return E_NOINTERFACE; - } - - STDMETHODIMP_(ULONG) AddRef() override - { - Module::Lock(); - return 2; - } - - STDMETHODIMP_(ULONG) Release() override - { - Module::Unlock(); - return 1; - } - - // IClassFactory - STDMETHODIMP CreateInstance(IUnknown* aOuter, REFIID aIid, - void** aOutInterface) override - { - return DoCreate(&T::Create, aOuter, aIid, aOutInterface); - } - - STDMETHODIMP LockServer(BOOL aLock) override - { - if (aLock) { - Module::Lock(); - } else { - Module::Unlock(); - } - return S_OK; - } -}; - -template -class MOZ_NONHEAP_CLASS SingletonFactory : public Factory -{ -public: - STDMETHODIMP CreateInstance(IUnknown* aOuter, REFIID aIid, - void** aOutInterface) override - { - if (aOuter || !aOutInterface) { - return E_INVALIDARG; - } - - RefPtr obj(sInstance); - if (!obj) { - obj = GetOrCreateSingleton(); - } - - return obj->QueryInterface(aIid, aOutInterface); - } - - RefPtr GetOrCreateSingleton() - { - if (!sInstance) { - RefPtr object; - if (FAILED(T::Create(getter_AddRefs(object)))) { - return nullptr; - } - - sInstance = object.forget(); - } - - return sInstance; - } - - RefPtr GetSingleton() - { - return sInstance; - } - - void ClearSingleton() - { - if (!sInstance) { - return; - } - - DebugOnly hr = ::CoDisconnectObject(sInstance.get(), 0); - MOZ_ASSERT(SUCCEEDED(hr)); - sInstance = nullptr; - } - -private: - static StaticRefPtr sInstance; -}; - -template -StaticRefPtr SingletonFactory::sInstance; - -} // namespace mscom -} // namespace mozilla - -#endif // mozilla_mscom_Factory_h diff --git a/ipc/mscom/oop/Handler.cpp b/ipc/mscom/oop/Handler.cpp deleted file mode 100644 index d497f21e42b7..000000000000 --- a/ipc/mscom/oop/Handler.cpp +++ /dev/null @@ -1,339 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "Handler.h" -#include "Module.h" - -#include "mozilla/ArrayUtils.h" -#include "nsWindowsHelpers.h" - -#include -#include -#include - -/* WARNING! The code in this file may be loaded into the address spaces of other - processes! It MUST NOT link against xul.dll or other Gecko binaries! Only - inline code may be included! */ - -namespace mozilla { -namespace mscom { - -Handler::Handler(IUnknown* aOuter, HRESULT& aResult) - : mRefCnt(0) - , mOuter(aOuter) - , mUnmarshal(nullptr) - , mHasPayload(false) -{ - if (!aOuter) { - aResult = E_INVALIDARG; - return; - } - - StabilizedRefCount stabilizer(mRefCnt); - - aResult = ::CoGetStdMarshalEx(aOuter, SMEXF_HANDLER, - getter_AddRefs(mInnerUnk)); - if (FAILED(aResult)) { - return; - } - - aResult = mInnerUnk->QueryInterface(IID_IMarshal, (void**)&mUnmarshal); - if (FAILED(aResult)) { - return; - } - - // mInnerMarshal is a weak ref - mUnmarshal->Release(); -} - -HRESULT -Handler::InternalQueryInterface(REFIID riid, void** ppv) -{ - if (!ppv) { - return E_INVALIDARG; - } - - if (riid == IID_IUnknown) { - RefPtr punk(static_cast(&mInternalUnknown)); - punk.forget(ppv); - return S_OK; - } - - if (riid == IID_IMarshal) { - RefPtr ptr(this); - ptr.forget(ppv); - return S_OK; - } - - // Try the handler implementation - HRESULT hr = QueryHandlerInterface(mInnerUnk, riid, ppv); - if (hr != E_NOINTERFACE) { - return hr; - } - - // Now forward to the marshaler's inner - return mInnerUnk->QueryInterface(riid, ppv); -} - -ULONG -Handler::InternalAddRef() -{ - if (!mRefCnt) { - Module::Lock(); - } - return ++mRefCnt; -} - -ULONG -Handler::InternalRelease() -{ - if (--mRefCnt == 0) { - delete this; - Module::Unlock(); - } - return mRefCnt; -} - -HRESULT -Handler::GetUnmarshalClass(REFIID riid, void* pv, DWORD dwDestContext, - void* pvDestContext, DWORD mshlflags, - CLSID* pCid) -{ - return mUnmarshal->GetUnmarshalClass(riid, pv, dwDestContext, pvDestContext, - mshlflags, pCid); -} - -HRESULT -Handler::GetMarshalSizeMax(REFIID riid, void* pv, DWORD dwDestContext, - void* pvDestContext, DWORD mshlflags, - DWORD* pSize) -{ - if (!pSize) { - return E_INVALIDARG; - } - - *pSize = 0; - - RefPtr unkToMarshal; - HRESULT hr; - - REFIID marshalAs = MarshalAs(riid); - if (marshalAs == riid) { - unkToMarshal = static_cast(pv); - } else { - hr = mInnerUnk->QueryInterface(marshalAs, getter_AddRefs(unkToMarshal)); - if (FAILED(hr)) { - return hr; - } - } - - // We do not necessarily want to use the pv that COM is giving us; we may want - // to marshal a different proxy that is more appropriate to what we're - // wrapping... - hr = mUnmarshal->GetMarshalSizeMax(marshalAs, unkToMarshal.get(), - dwDestContext, pvDestContext, - mshlflags, pSize); - if (FAILED(hr)) { - return hr; - } - - if (!HasPayload()) { - return S_OK; - } - - DWORD payloadSize = 0; - hr = GetHandlerPayloadSize(marshalAs, &payloadSize); - if (FAILED(hr)) { - return hr; - } - - *pSize += payloadSize; - return S_OK; -} - -HRESULT -Handler::MarshalInterface(IStream* pStm, REFIID riid, void* pv, - DWORD dwDestContext, void* pvDestContext, - DWORD mshlflags) -{ - // We do not necessarily want to use the pv that COM is giving us; we may want - // to marshal a different proxy that is more appropriate to what we're - // wrapping... - RefPtr unkToMarshal; - HRESULT hr; - - REFIID marshalAs = MarshalAs(riid); - if (marshalAs == riid) { - unkToMarshal = static_cast(pv); - } else { - hr = mInnerUnk->QueryInterface(marshalAs, getter_AddRefs(unkToMarshal)); - if (FAILED(hr)) { - return hr; - } - } - - hr = mUnmarshal->MarshalInterface(pStm, marshalAs, unkToMarshal.get(), - dwDestContext, pvDestContext, mshlflags); - if (FAILED(hr)) { - return hr; - } - - if (!HasPayload()) { - return S_OK; - } - - // Unfortunately when COM re-marshals a proxy that prevouisly had a payload, - // we must re-serialize it. - return WriteHandlerPayload(pStm, marshalAs); -} - -HRESULT -Handler::UnmarshalInterface(IStream* pStm, REFIID riid, void** ppv) -{ - REFIID unmarshalAs = MarshalAs(riid); - HRESULT hr = mUnmarshal->UnmarshalInterface(pStm, unmarshalAs, ppv); - if (FAILED(hr)) { - return hr; - } - - hr = ReadHandlerPayload(pStm, unmarshalAs); - - // This method may be called on the same object multiple times (as new - // interfaces are queried off the proxy). Not all interfaces will necessarily - // refresh the payload, so we set mHasPayload using OR to reflect that fact. - // (Otherwise mHasPayload could be cleared and the handler would think that - // it doesn't have a payload even though it actually does). - mHasPayload |= (hr == S_OK); - - // hr may be S_FALSE, but we don't want to return that - return SUCCEEDED(hr) ? S_OK : hr; -} - -HRESULT -Handler::ReleaseMarshalData(IStream* pStm) -{ - return mUnmarshal->ReleaseMarshalData(pStm); -} - -HRESULT -Handler::DisconnectObject(DWORD dwReserved) -{ - return mUnmarshal->DisconnectObject(dwReserved); -} - -template -static HRESULT -BuildClsidPath(wchar_t (&aPath)[N], REFCLSID aClsid) -{ - const wchar_t kClsid[] = {L'C', L'L', L'S', L'I', L'D', L'\\'}; - const size_t kReqdGuidLen = 39; - static_assert(N >= kReqdGuidLen + mozilla::ArrayLength(kClsid), - "aPath array is too short"); - if (wcsncpy_s(aPath, kClsid, mozilla::ArrayLength(kClsid))) { - return E_INVALIDARG; - } - - int guidConversionResult = - StringFromGUID2(aClsid, &aPath[mozilla::ArrayLength(kClsid)], - N - mozilla::ArrayLength(kClsid)); - if (!guidConversionResult) { - return E_INVALIDARG; - } - - return S_OK; -} - -HRESULT -Handler::Unregister(REFCLSID aClsid) -{ - wchar_t path[256] = {}; - HRESULT hr = BuildClsidPath(path, aClsid); - if (FAILED(hr)) { - return hr; - } - - hr = HRESULT_FROM_WIN32(SHDeleteKey(HKEY_CLASSES_ROOT, path)); - if (FAILED(hr)) { - return hr; - } - - return S_OK; -} - -HRESULT -Handler::Register(REFCLSID aClsid) -{ - wchar_t path[256] = {}; - HRESULT hr = BuildClsidPath(path, aClsid); - if (FAILED(hr)) { - return hr; - } - - HKEY rawClsidKey; - DWORD disposition; - LONG result = RegCreateKeyEx(HKEY_CLASSES_ROOT, path, 0, nullptr, - REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, - nullptr, &rawClsidKey, &disposition); - if (result != ERROR_SUCCESS) { - return HRESULT_FROM_WIN32(result); - } - nsAutoRegKey clsidKey(rawClsidKey); - - if (wcscat_s(path, L"\\InprocHandler32")) { - return E_UNEXPECTED; - } - - HKEY rawInprocHandlerKey; - result = RegCreateKeyEx(HKEY_CLASSES_ROOT, path, 0, nullptr, - REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, - nullptr, &rawInprocHandlerKey, &disposition); - if (result != ERROR_SUCCESS) { - Unregister(aClsid); - return HRESULT_FROM_WIN32(result); - } - nsAutoRegKey inprocHandlerKey(rawInprocHandlerKey); - - wchar_t absLibPath[MAX_PATH + 1] = {}; - HMODULE thisModule; - if (!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | - GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, - reinterpret_cast(&Handler::Register), - &thisModule)) { - return HRESULT_FROM_WIN32(GetLastError()); - } - - DWORD size = GetModuleFileName(thisModule, absLibPath, - mozilla::ArrayLength(absLibPath)); - if (!size || (size == mozilla::ArrayLength(absLibPath) && - GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { - DWORD lastError = GetLastError(); - Unregister(aClsid); - return HRESULT_FROM_WIN32(lastError); - } - - result = RegSetValueEx(inprocHandlerKey, L"", 0, REG_EXPAND_SZ, - reinterpret_cast(absLibPath), - sizeof(absLibPath)); - if (result != ERROR_SUCCESS) { - Unregister(aClsid); - return HRESULT_FROM_WIN32(result); - } - - const wchar_t kApartment[] = L"Apartment"; - result = RegSetValueEx(inprocHandlerKey, L"ThreadingModel", 0, REG_SZ, - reinterpret_cast(kApartment), - sizeof(kApartment)); - if (result != ERROR_SUCCESS) { - Unregister(aClsid); - return HRESULT_FROM_WIN32(result); - } - - return S_OK; -} - -} // namespace mscom -} // namespace mozilla - diff --git a/ipc/mscom/oop/Handler.h b/ipc/mscom/oop/Handler.h deleted file mode 100644 index 8353313c11e0..000000000000 --- a/ipc/mscom/oop/Handler.h +++ /dev/null @@ -1,127 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_mscom_Handler_h -#define mozilla_mscom_Handler_h - -#if defined(MOZILLA_INTERNAL_API) -#error This code is NOT for internal Gecko use! -#endif // defined(MOZILLA_INTERNAL_API) - -#include - -#include "mozilla/mscom/Aggregation.h" -#include "mozilla/RefPtr.h" - -/* WARNING! The code in this file may be loaded into the address spaces of other - processes! It MUST NOT link against xul.dll or other Gecko binaries! Only - inline code may be included! */ - -namespace mozilla { -namespace mscom { - -class Handler : public IMarshal -{ -public: - // IMarshal - STDMETHODIMP GetUnmarshalClass(REFIID riid, void* pv, DWORD dwDestContext, - void* pvDestContext, DWORD mshlflags, - CLSID* pCid) override; - STDMETHODIMP GetMarshalSizeMax(REFIID riid, void* pv, DWORD dwDestContext, - void* pvDestContext, DWORD mshlflags, - DWORD* pSize) override; - STDMETHODIMP MarshalInterface(IStream* pStm, REFIID riid, void* pv, - DWORD dwDestContext, void* pvDestContext, - DWORD mshlflags) override; - STDMETHODIMP UnmarshalInterface(IStream* pStm, REFIID riid, - void** ppv) override; - STDMETHODIMP ReleaseMarshalData(IStream* pStm) override; - STDMETHODIMP DisconnectObject(DWORD dwReserved) override; - - /** - * This method allows the handler to return its own interfaces that override - * those interfaces that are exposed by the underlying COM proxy. - * @param aProxyUnknown is the IUnknown of the underlying COM proxy. This is - * provided to give the handler implementation an - * opportunity to acquire interfaces to the underlying - * remote object, if needed. - * @param aIid Interface requested, similar to IUnknown::QueryInterface - * @param aOutInterface Outparam for the resulting interface to return to the - * client. - * @return The usual HRESULT codes similarly to IUnknown::QueryInterface - */ - virtual HRESULT QueryHandlerInterface(IUnknown* aProxyUnknown, REFIID aIid, - void** aOutInterface) = 0; - /** - * Called when the implementer should deserialize data in aStream. - * @return S_OK on success; - * S_FALSE if the deserialization was successful but there was no data; - * HRESULT error code otherwise. - */ - virtual HRESULT ReadHandlerPayload(IStream* aStream, REFIID aIid) - { return S_FALSE; } - - /** - * Unfortunately when COM marshals a proxy, it doesn't implicitly marshal - * the payload that was originally sent with the proxy. We must implement - * that code in the handler in order to make this happen. - */ - - /** - * This function allows the implementer to substitute a different interface - * for marshaling than the one that COM is intending to marshal. For example, - * the implementer might want to marshal a proxy for an interface that is - * derived from the requested interface. - * - * The default implementation is the identity function. - */ - virtual REFIID MarshalAs(REFIID aRequestedIid) { return aRequestedIid; } - - /** - * Called when the implementer must provide the size of the payload. - */ - virtual HRESULT GetHandlerPayloadSize(REFIID aIid, DWORD* aOutPayloadSize) - { - if (!aOutPayloadSize) { - return E_INVALIDARG; - } - *aOutPayloadSize = 0; - return S_OK; - } - - /** - * Called when the implementer should serialize the payload data into aStream. - */ - virtual HRESULT WriteHandlerPayload(IStream* aStream, REFIID aIid) - { - return S_OK; - } - - IUnknown* GetProxy() const { return mInnerUnk; } - - static HRESULT Register(REFCLSID aClsid); - static HRESULT Unregister(REFCLSID aClsid); - -protected: - Handler(IUnknown* aOuter, HRESULT& aResult); - virtual ~Handler() {} - bool HasPayload() const { return mHasPayload; } - IUnknown* GetOuter() const { return mOuter; } - -private: - ULONG mRefCnt; - IUnknown* mOuter; - RefPtr mInnerUnk; - IMarshal* mUnmarshal; // WEAK - bool mHasPayload; - DECLARE_AGGREGATABLE(Handler); -}; - -} // namespace mscom -} // namespace mozilla - -#endif // mozilla_mscom_Handler_h - diff --git a/ipc/mscom/oop/Module.cpp b/ipc/mscom/oop/Module.cpp deleted file mode 100644 index c0d890d810de..000000000000 --- a/ipc/mscom/oop/Module.cpp +++ /dev/null @@ -1,19 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "Module.h" - -#include -#include - -namespace mozilla { -namespace mscom { - -ULONG Module::sRefCount = 0; - -} // namespace mscom -} // namespace mozilla - diff --git a/ipc/mscom/oop/Module.h b/ipc/mscom/oop/Module.h deleted file mode 100644 index 21c8557a7ad9..000000000000 --- a/ipc/mscom/oop/Module.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_mscom_Module_h -#define mozilla_mscom_Module_h - -#if defined(MOZILLA_INTERNAL_API) -#error This code is NOT for internal Gecko use! -#endif // defined(MOZILLA_INTERNAL_API) - -#include - -/* WARNING! The code in this file may be loaded into the address spaces of other - processes! It MUST NOT link against xul.dll or other Gecko binaries! Only - inline code may be included! */ - -namespace mozilla { -namespace mscom { - -class Module -{ -public: - static HRESULT CanUnload() { return sRefCount == 0 ? S_OK : S_FALSE; } - - static void Lock() { ++sRefCount; } - static void Unlock() { --sRefCount; } - -private: - static ULONG sRefCount; -}; - -} // namespace mscom -} // namespace mozilla - -#endif // mozilla_mscom_Module_h - diff --git a/ipc/mscom/oop/moz.build b/ipc/mscom/oop/moz.build deleted file mode 100644 index b2d224ff5bb4..000000000000 --- a/ipc/mscom/oop/moz.build +++ /dev/null @@ -1,36 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -Library('mscom_oop') - -SOURCES += [ - '../ActivationContext.cpp', - '../Registration.cpp', - '../StructStream.cpp', -] - -UNIFIED_SOURCES += [ - 'Handler.cpp', - 'Module.cpp', -] - -OS_LIBS += [ - 'ole32', - 'oleaut32', - 'shlwapi', -] - -LIBRARY_DEFINES['UNICODE'] = True -LIBRARY_DEFINES['_UNICODE'] = True -LIBRARY_DEFINES['MOZ_NO_MOZALLOC'] = True - -DISABLE_STL_WRAPPING = True -NO_EXPAND_LIBS = True -FORCE_STATIC_LIB = True - -# This DLL may be loaded into other processes, so we need static libs for -# Windows 7 and Windows 8. -USE_STATIC_LIBS = True From 1cbd80653d9c19337fa910f1dbace9b585af7b35 Mon Sep 17 00:00:00 2001 From: Alastor Wu Date: Thu, 23 Feb 2017 12:13:49 +0800 Subject: [PATCH 081/234] Bug 1326114 - only do duration checking for active-media. r=sebastian Since we don't want to show the media control for the short sound, so we added the duration checking. And this checking only needs to be run when the media is active, we don't need to check the inactive media. MozReview-Commit-ID: AaVGi77nXJ1 --HG-- extra : rebase_source : c565fe64ec4030f0519eb0a8cfe493e95bae4fe4 --- mobile/android/chrome/content/browser.js | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/mobile/android/chrome/content/browser.js b/mobile/android/chrome/content/browser.js index d2a6e90aa49d..ef898291bb7f 100644 --- a/mobile/android/chrome/content/browser.js +++ b/mobile/android/chrome/content/browser.js @@ -4575,22 +4575,27 @@ Tab.prototype = { // for now anyway. }, - ShouldNotifyMediaPlaybackChange: function(inactive) { - // We don't want to show the media control interface for the short sound - // which duration is smaller than the threshold. The basic unit is second. + ShouldNotifyMediaPlaybackChange: function(activeState) { + // If the media is active, we would check it's duration, because we don't + // want to show the media control interface for the short sound which + // duration is smaller than the threshold. The basic unit is second. // Note : the streaming format's duration is infinite. + if (activeState === "inactive") { + return true; + } + const mediaDurationThreshold = 1.0; let audioElements = this.browser.contentDocument.getElementsByTagName("audio"); for (let audio of audioElements) { - if (audio.paused == inactive && audio.duration < mediaDurationThreshold) { + if (!audio.paused && audio.duration < mediaDurationThreshold) { return false; } } let videoElements = this.browser.contentDocument.getElementsByTagName("video"); for (let video of videoElements) { - if (video.paused == inactive && video.duration < mediaDurationThreshold) { + if (!video.paused && video.duration < mediaDurationThreshold) { return false; } } @@ -4626,14 +4631,13 @@ Tab.prototype = { return; } - let isInactive = (aData === "inactive"); - if (!this.ShouldNotifyMediaPlaybackChange(isInactive)) { + if (!this.ShouldNotifyMediaPlaybackChange(aData)) { return; } let status; if (aTopic == "media-playback") { - status = isInactive ? "end" : "start"; + status = (aData === "inactive") ? "end" : "start"; } else if (aTopic == "media-playback-resumed") { status = "resume"; } From c268fbdbaf3c3738b202aff99e58e8820cee0fe6 Mon Sep 17 00:00:00 2001 From: Alastor Wu Date: Thu, 23 Feb 2017 14:15:45 +0800 Subject: [PATCH 082/234] Bug 1192818 - part1 : dispatch DOMAudioPlaybackStopped when mute the tab. r=baku The root cause of the intermittent fail is because "DOMAudioPlaybackStopped" has no directly relationship with browser.mute()/unmute(). In [1], the "DOMAudioPlaybackStopped" is caused by audio stop playing, not by calling the browser.mute(). If the audio stops playing before calling the wait_for_event(), the test would be time-out. I guess the bug 1302280 is also caused by same reason. So this patch would do two thinngs, 1. dispatch "DOMAudioPlaybackStopped" when we mute tab 2. loop the audio in test file, to make sure the "DOMAudioPlaybackStopped" is dispatched when muting the audio, not the file ended. [1] https://goo.gl/ymUv8P MozReview-Commit-ID: 5RnyBRE73lQ --HG-- extra : rebase_source : 40ad97cbf84da6f5d013d832cb12e3ed88473dfd --- dom/html/HTMLMediaElement.cpp | 2 +- toolkit/content/tests/browser/file_mediaPlayback2.html | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp index 8fe7f368345f..6a30c70d0f61 100644 --- a/dom/html/HTMLMediaElement.cpp +++ b/dom/html/HTMLMediaElement.cpp @@ -996,7 +996,7 @@ private: IsOwnerAudible() const { // Muted or the volume should not be ~0 - if (mOwner->Muted() || (std::fabs(mOwner->Volume()) <= 1e-7)) { + if (mOwner->mMuted || (std::fabs(mOwner->Volume()) <= 1e-7)) { return AudioChannelService::AudibleState::eNotAudible; } diff --git a/toolkit/content/tests/browser/file_mediaPlayback2.html b/toolkit/content/tests/browser/file_mediaPlayback2.html index dffbd299b6af..8b5b07692304 100644 --- a/toolkit/content/tests/browser/file_mediaPlayback2.html +++ b/toolkit/content/tests/browser/file_mediaPlayback2.html @@ -7,6 +7,7 @@ audio.oncanplay = function() { audio.play(); }; audio.src = "audio.ogg"; +audio.loop = true; document.body.appendChild(audio); From 606eb319fa09bbbafa2f8c1cf07dffbd6adcfce5 Mon Sep 17 00:00:00 2001 From: Alastor Wu Date: Thu, 23 Feb 2017 14:15:47 +0800 Subject: [PATCH 083/234] Bug 1192818 - part2 : only dispatch DOMAudioPlaybackStarted when there is audible sound. r=baku The DOMAudioPlaybackStarted event would affect the tabbrowser's attribute, "soundPlaying", and this attribute should indicate whether the tab is audible or not. However, in present codebase, even the tab has "soundplaying", it doens't mean the tab has audible sound, you need to check extra attribute, "muted". After applying this patch, tabbrowser can only own one of the attributes ("soundplaying" or "mute"). These attributes won't exist at the same time, so we can easily know whether the tab is audible by checking "soundPlaying". Let's see an example, step1. playing a playing audio - tab owns "soundPlaying" step2. mute the tab - tab owns "muted" step3. stop audio - tab owns "muted" step4. replay the audio - tab owns "muted" step5. unmute the tab - tab owns "soundPlaying" step6. stop audio - tab owns "" MozReview-Commit-ID: EEKEbAVzsVm --HG-- extra : rebase_source : 823d501e9162ae8b611f2e97dd763c1eec16c2cf --- toolkit/content/widgets/browser.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/toolkit/content/widgets/browser.xml b/toolkit/content/widgets/browser.xml index b12241b9f1df..5e7be24640b9 100644 --- a/toolkit/content/widgets/browser.xml +++ b/toolkit/content/widgets/browser.xml @@ -698,6 +698,9 @@ Date: Thu, 23 Feb 2017 14:15:49 +0800 Subject: [PATCH 084/234] Bug 1192818 - part3 : modify test. r=baku MozReview-Commit-ID: HNXcbFbYfor --HG-- extra : rebase_source : 3033f7c3827acbac33d772e087bebece3487e118 --- .../test/general/browser_audioTabIcon.js | 40 +++++++++++++++---- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/browser/base/content/test/general/browser_audioTabIcon.js b/browser/base/content/test/general/browser_audioTabIcon.js index 039a7666d146..7258adf7b773 100644 --- a/browser/base/content/test/general/browser_audioTabIcon.js +++ b/browser/base/content/test/general/browser_audioTabIcon.js @@ -17,6 +17,15 @@ function* wait_for_tab_playing_event(tab, expectPlaying) { }); } +function* is_audio_playing(tab) { + let browser = tab.linkedBrowser; + let isPlaying = yield ContentTask.spawn(browser, {}, function* () { + let audio = content.document.querySelector("audio"); + return !audio.paused; + }); + return isPlaying; +} + function* play(tab) { let browser = tab.linkedBrowser; yield ContentTask.spawn(browser, {}, function* () { @@ -24,12 +33,16 @@ function* play(tab) { audio.play(); }); + // If the tab has already be muted, it means the tab won't get soundplaying, + // so we don't need to check this attribute. + if (browser.audioMuted) { + return; + } + yield wait_for_tab_playing_event(tab, true); } function* pause(tab, options) { - ok(tab.hasAttribute("soundplaying"), "The tab should have the soundplaying attribute when pause() is called"); - let extendedDelay = options && options.extendedDelay; if (extendedDelay) { // Use 10s to remove possibility of race condition with attr removal. @@ -47,6 +60,12 @@ function* pause(tab, options) { audio.pause(); }); + // If the tab has already be muted, it means the tab won't have soundplaying, + // so we don't need to check this attribute. + if (browser.audioMuted) { + return; + } + if (extendedDelay) { ok(tab.hasAttribute("soundplaying"), "The tab should still have the soundplaying attribute immediately after pausing"); @@ -141,6 +160,13 @@ function* test_mute_tab(tab, icon, expectMuted) { is(gBrowser.selectedTab, activeTab, "Clicking on mute should not change the currently selected tab"); + // If the audio is playing, we should check whether clicking on icon affects + // the media element's playing state. + let isAudioPlaying = yield is_audio_playing(tab); + if (isAudioPlaying) { + yield wait_for_tab_playing_event(tab, !expectMuted); + } + return mutedPromise; } @@ -169,7 +195,7 @@ function* test_muting_using_menu(tab, expectMuted) { yield play(tab); is(toggleMute.hasAttribute("muted"), expectMuted, "Should have the correct state for the muted attribute"); - ok(toggleMute.hasAttribute("soundplaying"), "Should have the soundplaying attribute"); + is(!toggleMute.hasAttribute("soundplaying"), expectMuted, "The value of soundplaying attribute is incorrect"); yield pause(tab); @@ -234,14 +260,14 @@ function* test_playing_icon_on_tab(tab, browser, isPinned) { } function* test_swapped_browser_while_playing(oldTab, newBrowser) { + // The tab was muted so it won't have soundplaying attribute even it's playing. ok(oldTab.hasAttribute("muted"), "Expected the correct muted attribute on the old tab"); is(oldTab.muteReason, null, "Expected the correct muteReason attribute on the old tab"); - ok(oldTab.hasAttribute("soundplaying"), "Expected the correct soundplaying attribute on the old tab"); + ok(!oldTab.hasAttribute("soundplaying"), "Expected the correct soundplaying attribute on the old tab"); let newTab = gBrowser.getTabForBrowser(newBrowser); let AttrChangePromise = BrowserTestUtils.waitForEvent(newTab, "TabAttrModified", false, event => { - return event.detail.changed.includes("soundplaying") && - event.detail.changed.includes("muted"); + return event.detail.changed.includes("muted"); }); gBrowser.swapBrowsersAndCloseOther(newTab, oldTab); @@ -249,7 +275,7 @@ function* test_swapped_browser_while_playing(oldTab, newBrowser) { ok(newTab.hasAttribute("muted"), "Expected the correct muted attribute on the new tab"); is(newTab.muteReason, null, "Expected the correct muteReason property on the new tab"); - ok(newTab.hasAttribute("soundplaying"), "Expected the correct soundplaying attribute on the new tab"); + ok(!newTab.hasAttribute("soundplaying"), "Expected the correct soundplaying attribute on the new tab"); let icon = document.getAnonymousElementByAttribute(newTab, "anonid", "soundplaying-icon"); From ea63f2e3540713a555609a5f4dc714fac4eb37eb Mon Sep 17 00:00:00 2001 From: Alastor Wu Date: Thu, 23 Feb 2017 14:16:44 +0800 Subject: [PATCH 085/234] Bug 1192818 - part4 : only mute media element if there is alive track. r=jwwang If we don't have any alive track in MediaTrackList, we don't need to mute MediaElement. MozReview-Commit-ID: 9vY692O7N0e --HG-- extra : rebase_source : 3abd2fb360385b1975dbffd9dcaf4e395b1afda1 --- dom/html/HTMLMediaElement.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp index 6a30c70d0f61..bdd084002f33 100644 --- a/dom/html/HTMLMediaElement.cpp +++ b/dom/html/HTMLMediaElement.cpp @@ -2039,15 +2039,19 @@ void HTMLMediaElement::NotifyMediaTrackDisabled(MediaTrack* aTrack) (!aTrack->AsVideoTrack() || !aTrack->AsVideoTrack()->Selected())); if (aTrack->AsAudioTrack()) { - bool shouldMute = true; - for (uint32_t i = 0; i < AudioTracks()->Length(); ++i) { - if ((*AudioTracks())[i]->Enabled()) { - shouldMute = false; - break; + // If we don't have any alive track , we don't need to mute MediaElement. + if (AudioTracks()->Length() > 0) { + bool shouldMute = true; + for (uint32_t i = 0; i < AudioTracks()->Length(); ++i) { + if ((*AudioTracks())[i]->Enabled()) { + shouldMute = false; + break; + } + } + + if (shouldMute) { + SetMutedInternal(mMuted | MUTED_BY_AUDIO_TRACK); } - } - if (shouldMute) { - SetMutedInternal(mMuted | MUTED_BY_AUDIO_TRACK); } } else if (aTrack->AsVideoTrack()) { if (mSrcStream) { From 9c347956aedb6f8c4b5e9a406749f15ae89e1812 Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Fri, 10 Feb 2017 17:29:10 +0800 Subject: [PATCH 086/234] Bug 775624 Part 1 - Convert nsReflowStatus to a class mimicking uint32_t. r=dholbert Lay down the foundation for this refactor work so that nsReflowStatus could be converted to bit-fields piece by piece, and each patch can be built (but may not pass tests). This change causes some build warnings, due to some debug logs printing nsReflowStatus as an integer, but that will be fixed by Part 24 later. All the operators related to uint32_t will be removed at the end of this patch series by Part 23. The yoda conditions are swapped in order to build successfully. DisplayReflowExit() incorrectly declares aStatus as uint32_t. Change it to const reference because nsReflowStatus is now a class. MozReview-Commit-ID: 5DOpaP85ywJ --HG-- extra : rebase_source : 53ca0750b5f764fcbf7ba2d00c9ec606aed704c2 --- layout/generic/nsFrame.cpp | 10 +++--- layout/generic/nsFrame.h | 10 +++--- layout/generic/nsIFrame.h | 48 +++++++++++++++++++++++++- layout/tables/nsTableRowGroupFrame.cpp | 2 +- 4 files changed, 58 insertions(+), 12 deletions(-) diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index fdd6dd3aa585..3871bab9cf13 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -10341,7 +10341,7 @@ nsFrame::Trace(const char* aMethod, bool aEnter, nsReflowStatus aStatus) PR_LogPrint("%s: %s %s, status=%scomplete%s", tagbuf, aEnter ? "enter" : "exit", aMethod, NS_FRAME_IS_NOT_COMPLETE(aStatus) ? "not" : "", - (NS_FRAME_REFLOW_NEXTINFLOW & aStatus) ? "+reflow" : ""); + (aStatus & NS_FRAME_REFLOW_NEXTINFLOW) ? "+reflow" : ""); } } @@ -11202,11 +11202,11 @@ void* nsFrame::DisplayIntrinsicSizeEnter(nsIFrame* aFrame, return treeNode; } -void nsFrame::DisplayReflowExit(nsPresContext* aPresContext, - nsIFrame* aFrame, +void nsFrame::DisplayReflowExit(nsPresContext* aPresContext, + nsIFrame* aFrame, ReflowOutput& aMetrics, - nsReflowStatus aStatus, - void* aFrameTreeNode) + const nsReflowStatus& aStatus, + void* aFrameTreeNode) { if (!DR_state->mActive) return; diff --git a/layout/generic/nsFrame.h b/layout/generic/nsFrame.h index dfab2b9b4f2b..6e55924346e2 100644 --- a/layout/generic/nsFrame.h +++ b/layout/generic/nsFrame.h @@ -507,11 +507,11 @@ public: const char* aType); static void* DisplayIntrinsicSizeEnter(nsIFrame* aFrame, const char* aType); - static void DisplayReflowExit(nsPresContext* aPresContext, - nsIFrame* aFrame, - ReflowOutput& aMetrics, - uint32_t aStatus, - void* aFrameTreeNode); + static void DisplayReflowExit(nsPresContext* aPresContext, + nsIFrame* aFrame, + ReflowOutput& aMetrics, + const nsReflowStatus& aStatus, + void* aFrameTreeNode); static void DisplayLayoutExit(nsIFrame* aFrame, void* aFrameTreeNode); static void DisplayIntrinsicISizeExit(nsIFrame* aFrame, diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 638e529f7ebc..bd6eadc75a79 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -230,7 +230,53 @@ enum nsSpread { * * @see #Reflow() */ -typedef uint32_t nsReflowStatus; + +class nsReflowStatus final { +public: + nsReflowStatus() + : mStatus(0) + {} + + nsReflowStatus(uint32_t aStatus) + : mStatus(aStatus) + {} + + uint32_t& operator=(uint32_t aRhs) { + mStatus = aRhs; + return mStatus; + } + + uint32_t operator&(uint32_t aRhs) const { + return mStatus & aRhs; + } + + uint32_t operator&=(uint32_t aRhs) { + return mStatus = mStatus & aRhs; + } + + uint32_t operator|(uint32_t aRhs) const { + return mStatus | aRhs; + } + + uint32_t operator|=(uint32_t aRhs) { + return mStatus = mStatus | aRhs; + } + + uint32_t operator>>(uint32_t aRhs) const { + return mStatus >> aRhs; + } + + bool operator==(uint32_t aRhs) const { + return mStatus == aRhs; + } + + bool operator!=(uint32_t aRhs) const { + return !(*this == aRhs); + } + +private: + uint32_t mStatus; +}; #define NS_FRAME_COMPLETE 0 // Note: not a bit! #define NS_FRAME_NOT_COMPLETE 0x1 diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp index 60596f12b07d..b0f9a47f849f 100644 --- a/layout/tables/nsTableRowGroupFrame.cpp +++ b/layout/tables/nsTableRowGroupFrame.cpp @@ -1391,7 +1391,7 @@ nsTableRowGroupFrame::Reflow(nsPresContext* aPresContext, // not paginated ... we can't split across columns yet. if (aReflowInput.mFlags.mTableIsSplittable && NS_UNCONSTRAINEDSIZE != aReflowInput.AvailableHeight() && - (NS_FRAME_NOT_COMPLETE == aStatus || splitDueToPageBreak || + (aStatus == NS_FRAME_NOT_COMPLETE || splitDueToPageBreak || aDesiredSize.Height() > aReflowInput.AvailableHeight())) { // Nope, find a place to split the row group bool specialReflow = (bool)aReflowInput.mFlags.mSpecialBSizeReflow; From 36df42df351779986799650070520bcf49459502 Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Mon, 13 Feb 2017 15:25:50 +0800 Subject: [PATCH 087/234] Bug 775624 Part 2 - Add bit-fields and methods for frame completion status. r=dholbert MozReview-Commit-ID: B2DEaWYTtAE --HG-- extra : rebase_source : a468e954a7f963b947e5ed1366d6f361ab361bad --- layout/generic/nsIFrame.h | 66 +++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 23 deletions(-) diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index bd6eadc75a79..1c69fb53200c 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -197,27 +197,6 @@ enum nsSpread { //---------------------------------------------------------------------- /** - * Reflow status returned by the reflow methods. There are three - * completion statuses, represented by two bit flags. - * - * NS_FRAME_COMPLETE means the frame is fully complete. - * - * NS_FRAME_NOT_COMPLETE bit flag means the frame does not map all its - * content, and that the parent frame should create a continuing frame. - * If this bit isn't set it means the frame does map all its content. - * This bit is mutually exclusive with NS_FRAME_OVERFLOW_INCOMPLETE. - * - * NS_FRAME_OVERFLOW_INCOMPLETE bit flag means that the frame has - * overflow that is not complete, but its own box is complete. - * (This happens when content overflows a fixed-height box.) - * The reflower should place and size the frame and continue its reflow, - * but needs to create an overflow container as a continuation for this - * frame. See nsContainerFrame.h for more information. - * This bit is mutually exclusive with NS_FRAME_NOT_COMPLETE. - * - * Please use the SET macro for handling - * NS_FRAME_NOT_COMPLETE and NS_FRAME_OVERFLOW_INCOMPLETE. - * * NS_FRAME_REFLOW_NEXTINFLOW bit flag means that the next-in-flow is * dirty, and also needs to be reflowed. This status only makes sense * for a frame that is not complete, i.e. you wouldn't set both @@ -227,16 +206,23 @@ enum nsSpread { * the remaining 24 bits are zero (and available for extensions; however * API's that accept/return nsReflowStatus must not receive/return any * extension bits). - * - * @see #Reflow() */ +// Reflow status returned by the Reflow() methods. class nsReflowStatus final { public: nsReflowStatus() : mStatus(0) + , mIncomplete(false) + , mOverflowIncomplete(false) {} + // Reset all the bit-fields. + void Reset() { + mIncomplete = false; + mOverflowIncomplete = false; + } + nsReflowStatus(uint32_t aStatus) : mStatus(aStatus) {} @@ -274,8 +260,42 @@ public: return !(*this == aRhs); } + // mIncomplete bit flag means the frame does not map all its content, and + // that the parent frame should create a continuing frame. If this bit + // isn't set, it means the frame does map all its content. This bit is + // mutually exclusive with mOverflowIncomplete. + // + // mOverflowIncomplete bit flag means that the frame has overflow that is + // not complete, but its own box is complete. (This happens when content + // overflows a fixed-height box.) The reflower should place and size the + // frame and continue its reflow, but needs to create an overflow + // container as a continuation for this frame. See nsContainerFrame.h for + // more information. This bit is mutually exclusive with mIncomplete. + // + // If both mIncomplete and mOverflowIncomplete are not set, the frame is + // fully complete. + bool IsComplete() const { return !mIncomplete; } + bool IsIncomplete() const { return mIncomplete; } + bool IsOverflowIncomplete() const { return mOverflowIncomplete; } + bool IsFullyComplete() const { + return !IsIncomplete() && !IsOverflowIncomplete(); + } + + void SetIncomplete() { + mIncomplete = true; + mOverflowIncomplete = false; + } + void SetOverflowIncomplete() { + mIncomplete = false; + mOverflowIncomplete = true; + } + private: uint32_t mStatus; + + // Frame completion status bit flags. + bool mIncomplete : 1; + bool mOverflowIncomplete : 1; }; #define NS_FRAME_COMPLETE 0 // Note: not a bit! From b31150930a2f30c16928b77c3eb5a255cd4076a8 Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Sat, 11 Feb 2017 22:17:26 +0800 Subject: [PATCH 088/234] Bug 775624 Part 3 - Remove NS_FRAME_IS_NOT_COMPLETE. r=dholbert This patch is written by the help of the following script. function rename() { find layout\ -type f\ \( -name "*.cpp" -or\ -name "*.h" \)\ -exec sed -i -r "s/$1/$2/g" "{}" \; } rename "NS_FRAME_IS_NOT_COMPLETE\(([a-zA-Z0-9.*]*)\)" "\1.IsIncomplete()" MozReview-Commit-ID: GOd4y2N6dcz --HG-- extra : rebase_source : 412b60e7954118d8443ebf2a786046d7cd38c516 --- layout/generic/BlockReflowInput.cpp | 4 ++-- layout/generic/nsAbsoluteContainingBlock.cpp | 2 +- layout/generic/nsBlockFrame.cpp | 16 ++++++++-------- layout/generic/nsFrame.cpp | 2 +- layout/generic/nsGridContainerFrame.cpp | 4 ++-- layout/generic/nsIFrame.h | 3 --- layout/generic/nsInlineFrame.cpp | 4 ++-- layout/generic/nsLineLayout.cpp | 2 +- layout/generic/nsRubyFrame.cpp | 2 +- layout/tables/nsTableFrame.cpp | 6 +++--- layout/tables/nsTableRowFrame.cpp | 2 +- layout/tables/nsTableRowGroupFrame.cpp | 4 ++-- 12 files changed, 24 insertions(+), 27 deletions(-) diff --git a/layout/generic/BlockReflowInput.cpp b/layout/generic/BlockReflowInput.cpp index bb648f42a458..fbed23eb69ca 100644 --- a/layout/generic/BlockReflowInput.cpp +++ b/layout/generic/BlockReflowInput.cpp @@ -912,7 +912,7 @@ BlockReflowInput::FlowAndPlaceFloat(nsIFrame* aFloat) } if (aFloat->GetPrevInFlow()) floatMargin.BStart(wm) = 0; - if (NS_FRAME_IS_NOT_COMPLETE(reflowStatus)) + if (reflowStatus.IsIncomplete()) floatMargin.BEnd(wm) = 0; // In the case that we're in columns and not splitting floats, we need @@ -980,7 +980,7 @@ BlockReflowInput::FlowAndPlaceFloat(nsIFrame* aFloat) nsFloatManager::CalculateRegionFor(wm, aFloat, floatMargin, ContainerSize()); // if the float split, then take up all of the vertical height - if (NS_FRAME_IS_NOT_COMPLETE(reflowStatus) && + if (reflowStatus.IsIncomplete() && (NS_UNCONSTRAINEDSIZE != ContentBSize())) { region.BSize(wm) = std::max(region.BSize(wm), ContentBSize() - floatPos.B(wm)); diff --git a/layout/generic/nsAbsoluteContainingBlock.cpp b/layout/generic/nsAbsoluteContainingBlock.cpp index 7c48aae92e64..afab87de7e93 100644 --- a/layout/generic/nsAbsoluteContainingBlock.cpp +++ b/layout/generic/nsAbsoluteContainingBlock.cpp @@ -191,7 +191,7 @@ nsAbsoluteContainingBlock::Reflow(nsContainerFrame* aDelegatingFrame, // Abspos frames can't cause their parent to be incomplete, // only overflow incomplete. - if (NS_FRAME_IS_NOT_COMPLETE(reflowStatus)) + if (reflowStatus.IsIncomplete()) NS_FRAME_SET_OVERFLOW_INCOMPLETE(reflowStatus); NS_MergeReflowStatusInto(&aReflowStatus, reflowStatus); diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index ad28c6099c2d..0a549151ad5a 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -263,14 +263,14 @@ RecordReflowStatus(bool aChildIsBlock, nsReflowStatus aFrameReflowStatus) if (NS_INLINE_IS_BREAK_BEFORE(aFrameReflowStatus)) { newS |= 1; } - else if (NS_FRAME_IS_NOT_COMPLETE(aFrameReflowStatus)) { + else if (aFrameReflowStatus.IsIncomplete()) { newS |= 2; } else { newS |= 4; } } - else if (NS_FRAME_IS_NOT_COMPLETE(aFrameReflowStatus)) { + else if (aFrameReflowStatus.IsIncomplete()) { newS |= 8; } else { @@ -1658,7 +1658,7 @@ nsBlockFrame::ComputeFinalSize(const ReflowInput& aReflowInput, } if (IS_TRUE_OVERFLOW_CONTAINER(this)) { - if (NS_FRAME_IS_NOT_COMPLETE(aState.mReflowStatus)) { + if (aState.mReflowStatus.IsIncomplete()) { // Overflow containers can only be overflow complete. // Note that auto height overflow containers have no normal children NS_ASSERTION(finalSize.BSize(wm) == 0, @@ -2683,7 +2683,7 @@ nsBlockFrame::ReflowDirtyLines(BlockReflowInput& aState) } } - if (NS_FRAME_IS_NOT_COMPLETE(aState.mReflowStatus)) { + if (aState.mReflowStatus.IsIncomplete()) { aState.mReflowStatus |= NS_FRAME_REFLOW_NEXTINFLOW; } //XXXfr shouldn't set this flag when nextinflow has no lines } @@ -3635,7 +3635,7 @@ nsBlockFrame::ReflowBlockFrame(BlockReflowInput& aState, nsIFrame* nextFrame = frame->GetNextInFlow(); NS_ASSERTION(nextFrame, "We're supposed to have a next-in-flow by now"); - if (NS_FRAME_IS_NOT_COMPLETE(frameReflowStatus)) { + if (frameReflowStatus.IsIncomplete()) { // If nextFrame used to be an overflow container, make it a normal block if (!madeContinuation && (NS_FRAME_IS_OVERFLOW_CONTAINER & nextFrame->GetStateBits())) { @@ -6276,7 +6276,7 @@ nsBlockFrame::ReflowFloat(BlockReflowInput& aState, if (!NS_FRAME_IS_FULLY_COMPLETE(aReflowStatus) && ShouldAvoidBreakInside(floatRS)) { aReflowStatus = NS_INLINE_LINE_BREAK_BEFORE(); - } else if (NS_FRAME_IS_NOT_COMPLETE(aReflowStatus) && + } else if (aReflowStatus.IsIncomplete() && (NS_UNCONSTRAINEDSIZE == aAdjustedAvailableSpace.BSize(wm))) { // An incomplete reflow status means we should split the float // if the height is constrained (bug 145305). @@ -6291,7 +6291,7 @@ nsBlockFrame::ReflowFloat(BlockReflowInput& aState, // We never split floating first letters; an incomplete state for // such frames simply means that there is more content to be // reflowed on the line. - if (NS_FRAME_IS_NOT_COMPLETE(aReflowStatus)) + if (aReflowStatus.IsIncomplete()) aReflowStatus = NS_FRAME_COMPLETE; } @@ -7408,7 +7408,7 @@ nsBlockFrame::ComputeFinalBSize(const ReflowInput& aReflowInput, computedBSizeLeftOver), aBorderPadding.BEnd(wm)); - if (NS_FRAME_IS_NOT_COMPLETE(*aStatus) && + if (aStatus->IsIncomplete() && aFinalSize.BSize(wm) < aReflowInput.AvailableBSize()) { // We fit in the available space - change status to OVERFLOW_INCOMPLETE. // XXXmats why didn't Reflow report OVERFLOW_INCOMPLETE in the first place? diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 3871bab9cf13..a7d43eb17bc9 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -10340,7 +10340,7 @@ nsFrame::Trace(const char* aMethod, bool aEnter, nsReflowStatus aStatus) GetTagName(this, mContent, sizeof(tagbuf), tagbuf); PR_LogPrint("%s: %s %s, status=%scomplete%s", tagbuf, aEnter ? "enter" : "exit", aMethod, - NS_FRAME_IS_NOT_COMPLETE(aStatus) ? "not" : "", + aStatus.IsIncomplete() ? "not" : "", (aStatus & NS_FRAME_REFLOW_NEXTINFLOW) ? "+reflow" : ""); } } diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index 3717c4d994a9..a158a8b4f82c 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -5653,7 +5653,7 @@ nsGridContainerFrame::ReflowRowsInFragmentainer( aFragmentainer.mToFragmentainerEnd = bEndRow; if (aFragmentainer.mIsAutoBSize) { aBSize = ClampToCSSMaxBSize(bEndRow, aState.mReflowInput, &aStatus); - } else if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) { + } else if (aStatus.IsIncomplete()) { aBSize = NS_CSS_MINMAX(aState.mReflowInput->ComputedBSize(), aState.mReflowInput->ComputedMinBSize(), aState.mReflowInput->ComputedMaxBSize()); @@ -5683,7 +5683,7 @@ nsGridContainerFrame::ReflowRowsInFragmentainer( MOZ_ASSERT_UNREACHABLE("unexpected child reflow status"); } - if (NS_FRAME_IS_NOT_COMPLETE(childStatus)) { + if (childStatus.IsIncomplete()) { incompleteItems.PutEntry(child); } else if (!NS_FRAME_IS_FULLY_COMPLETE(childStatus)) { overflowIncompleteItems.PutEntry(child); diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 1c69fb53200c..9f05f2b04563 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -306,9 +306,6 @@ private: #define NS_FRAME_IS_COMPLETE(status) \ (0 == ((status) & NS_FRAME_NOT_COMPLETE)) -#define NS_FRAME_IS_NOT_COMPLETE(status) \ - (0 != ((status) & NS_FRAME_NOT_COMPLETE)) - #define NS_FRAME_OVERFLOW_IS_INCOMPLETE(status) \ (0 != ((status) & NS_FRAME_OVERFLOW_INCOMPLETE)) diff --git a/layout/generic/nsInlineFrame.cpp b/layout/generic/nsInlineFrame.cpp index dfe7446c6b88..9d3703320193 100644 --- a/layout/generic/nsInlineFrame.cpp +++ b/layout/generic/nsInlineFrame.cpp @@ -688,7 +688,7 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext, bool reflowingFirstLetter = lineLayout->GetFirstLetterStyleOK(); ReflowInlineFrame(aPresContext, aReflowInput, irs, frame, aStatus); done = NS_INLINE_IS_BREAK(aStatus) || - (!reflowingFirstLetter && NS_FRAME_IS_NOT_COMPLETE(aStatus)); + (!reflowingFirstLetter && aStatus.IsIncomplete()); if (done) { if (!irs.mSetParentPointer) { break; @@ -726,7 +726,7 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext, } ReflowInlineFrame(aPresContext, aReflowInput, irs, frame, aStatus); if (NS_INLINE_IS_BREAK(aStatus) || - (!reflowingFirstLetter && NS_FRAME_IS_NOT_COMPLETE(aStatus))) { + (!reflowingFirstLetter && aStatus.IsIncomplete())) { break; } irs.mPrevFrame = frame; diff --git a/layout/generic/nsLineLayout.cpp b/layout/generic/nsLineLayout.cpp index 304d42108568..92f9c13d780b 100644 --- a/layout/generic/nsLineLayout.cpp +++ b/layout/generic/nsLineLayout.cpp @@ -1293,7 +1293,7 @@ nsLineLayout::CanPlaceFrame(PerFrameData* pfd, * For box-decoration-break:clone we apply the end margin on all * continuations (that are not letter frames). */ - if ((NS_FRAME_IS_NOT_COMPLETE(aStatus) || + if ((aStatus.IsIncomplete() || pfd->mFrame->LastInFlow()->GetNextContinuation() || pfd->mFrame->FrameIsNonLastInIBSplit()) && !pfd->mIsLetterFrame && diff --git a/layout/generic/nsRubyFrame.cpp b/layout/generic/nsRubyFrame.cpp index 4a193d3d7a98..28a3c18a51e9 100644 --- a/layout/generic/nsRubyFrame.cpp +++ b/layout/generic/nsRubyFrame.cpp @@ -217,7 +217,7 @@ nsRubyFrame::ReflowSegment(nsPresContext* aPresContext, // text containers paired with it. return; } - if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) { + if (aStatus.IsIncomplete()) { // It always promise that if the status is incomplete, there is a // break occurs. Break before has been processed above. However, // it is possible that break after happens with the frame reflow diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index 4982da25d268..628381777287 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -1942,7 +1942,7 @@ nsTableFrame::Reflow(nsPresContext* aPresContext, ReflowTable(aDesiredSize, aReflowInput, aReflowInput.AvailableBSize(), lastChildReflowed, aStatus); - if (lastChildReflowed && NS_FRAME_IS_NOT_COMPLETE(aStatus)) { + if (lastChildReflowed && aStatus.IsIncomplete()) { // if there is an incomplete child, then set the desired bsize // to include it but not the next one LogicalMargin borderPadding = GetChildAreaOffset(wm, &aReflowInput); @@ -3249,11 +3249,11 @@ nsTableFrame::ReflowChildren(TableReflowInput& aReflowInput, // Remember where we just were in case we end up pushing children prevKidFrame = kidFrame; - MOZ_ASSERT(!NS_FRAME_IS_NOT_COMPLETE(aStatus) || isPaginated, + MOZ_ASSERT(!aStatus.IsIncomplete() || isPaginated, "Table contents should only fragment in paginated contexts"); // Special handling for incomplete children - if (isPaginated && NS_FRAME_IS_NOT_COMPLETE(aStatus)) { + if (isPaginated && aStatus.IsIncomplete()) { nsIFrame* kidNextInFlow = kidFrame->GetNextInFlow(); if (!kidNextInFlow) { // The child doesn't have a next-in-flow so create a continuing diff --git a/layout/tables/nsTableRowFrame.cpp b/layout/tables/nsTableRowFrame.cpp index a39d8452f5b2..e25250982f34 100644 --- a/layout/tables/nsTableRowFrame.cpp +++ b/layout/tables/nsTableRowFrame.cpp @@ -936,7 +936,7 @@ nsTableRowFrame::ReflowChildren(nsPresContext* aPresContext, // allow the table to determine if/how the table needs to be rebalanced // If any of the cells are not complete, then we're not complete - if (NS_FRAME_IS_NOT_COMPLETE(status)) { + if (status.IsIncomplete()) { aStatus = NS_FRAME_NOT_COMPLETE; } } else { diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp index b0f9a47f849f..35dcef0b66b5 100644 --- a/layout/tables/nsTableRowGroupFrame.cpp +++ b/layout/tables/nsTableRowGroupFrame.cpp @@ -1184,7 +1184,7 @@ nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext, oldRowVisualOverflow, false); - if (NS_FRAME_IS_NOT_COMPLETE(aStatus)) { + if (aStatus.IsIncomplete()) { // The row frame is incomplete and all of the rowspan 1 cells' block frames split if ((rowMetrics.Height() <= rowReflowInput.AvailableHeight()) || isTopOfPage) { // The row stays on this page because either it split ok or we're on the top of page. @@ -1323,7 +1323,7 @@ nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext, aStatus = NS_FRAME_NOT_COMPLETE; } } - if (NS_FRAME_IS_NOT_COMPLETE(aStatus) && !contRow) { + if (aStatus.IsIncomplete() && !contRow) { nsTableRowFrame* nextRow = lastRowThisPage->GetNextRow(); if (nextRow) { PushChildren(nextRow, lastRowThisPage); From 99ebdf6cf3c5753d38ac1c20221b07f6e027a690 Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Sat, 11 Feb 2017 22:38:48 +0800 Subject: [PATCH 089/234] Bug 775624 Part 4 - Remove NS_FRAME_IS_FULLY_COMPLETE. r=dholbert This patch is written by the help of the following script. function rename() { find layout\ -type f\ \( -name "*.cpp" -or\ -name "*.h" \)\ -exec sed -i -r "s/$1/$2/g" "{}" \; } rename "NS_FRAME_IS_FULLY_COMPLETE\(([a-zA-Z0-9.*]*)\)" "\1.IsFullyComplete()" MozReview-Commit-ID: GOd4y2N6dcz --HG-- extra : rebase_source : 200639e836cebe26fd77cde21f478fd027e1725f --- layout/forms/nsComboboxControlFrame.cpp | 2 +- layout/forms/nsDateTimeControlFrame.cpp | 2 +- layout/forms/nsNumberControlFrame.cpp | 2 +- layout/forms/nsRangeFrame.cpp | 6 +++--- layout/generic/BlockReflowInput.cpp | 4 ++-- layout/generic/nsAbsoluteContainingBlock.cpp | 2 +- layout/generic/nsBlockFrame.cpp | 20 ++++++++++---------- layout/generic/nsBlockReflowContext.cpp | 2 +- layout/generic/nsCanvasFrame.cpp | 2 +- layout/generic/nsColumnSetFrame.cpp | 8 ++++---- layout/generic/nsContainerFrame.cpp | 6 +++--- layout/generic/nsFrame.cpp | 2 +- layout/generic/nsGridContainerFrame.cpp | 6 +++--- layout/generic/nsIFrame.h | 3 --- layout/generic/nsInlineFrame.cpp | 4 ++-- layout/generic/nsPageContentFrame.cpp | 2 +- layout/generic/nsPageFrame.cpp | 2 +- layout/generic/nsSimplePageSequenceFrame.cpp | 2 +- layout/tables/nsTableFrame.cpp | 2 +- layout/tables/nsTableRowFrame.cpp | 2 +- layout/tables/nsTableRowGroupFrame.cpp | 2 +- 21 files changed, 40 insertions(+), 43 deletions(-) diff --git a/layout/forms/nsComboboxControlFrame.cpp b/layout/forms/nsComboboxControlFrame.cpp index 9376975b3c1d..cc84104ef766 100644 --- a/layout/forms/nsComboboxControlFrame.cpp +++ b/layout/forms/nsComboboxControlFrame.cpp @@ -898,7 +898,7 @@ nsComboboxControlFrame::Reflow(nsPresContext* aPresContext, mButtonFrame->SetRect(buttonRect, containerSize); if (!NS_INLINE_IS_BREAK_BEFORE(aStatus) && - !NS_FRAME_IS_FULLY_COMPLETE(aStatus)) { + !aStatus.IsFullyComplete()) { // This frame didn't fit inside a fragmentation container. Splitting // a nsComboboxControlFrame makes no sense, so we override the status here. aStatus = NS_FRAME_COMPLETE; diff --git a/layout/forms/nsDateTimeControlFrame.cpp b/layout/forms/nsDateTimeControlFrame.cpp index fa22dcebac05..19ae8eccbaed 100644 --- a/layout/forms/nsDateTimeControlFrame.cpp +++ b/layout/forms/nsDateTimeControlFrame.cpp @@ -235,7 +235,7 @@ nsDateTimeControlFrame::Reflow(nsPresContext* aPresContext, ReflowChild(inputAreaFrame, aPresContext, childDesiredSize, childReflowOuput, myWM, childOffset, dummyContainerSize, 0, childStatus); - MOZ_ASSERT(NS_FRAME_IS_FULLY_COMPLETE(childStatus), + MOZ_ASSERT(childStatus.IsFullyComplete(), "We gave our child unconstrained available block-size, " "so it should be complete"); diff --git a/layout/forms/nsNumberControlFrame.cpp b/layout/forms/nsNumberControlFrame.cpp index 2fad5ae93660..5cbc722ea8b4 100644 --- a/layout/forms/nsNumberControlFrame.cpp +++ b/layout/forms/nsNumberControlFrame.cpp @@ -183,7 +183,7 @@ nsNumberControlFrame::Reflow(nsPresContext* aPresContext, ReflowChild(outerWrapperFrame, aPresContext, wrappersDesiredSize, wrapperReflowInput, myWM, wrapperOffset, dummyContainerSize, 0, childStatus); - MOZ_ASSERT(NS_FRAME_IS_FULLY_COMPLETE(childStatus), + MOZ_ASSERT(childStatus.IsFullyComplete(), "We gave our child unconstrained available block-size, " "so it should be complete"); diff --git a/layout/forms/nsRangeFrame.cpp b/layout/forms/nsRangeFrame.cpp index 7aadf7f7d719..55418d3d8ba6 100644 --- a/layout/forms/nsRangeFrame.cpp +++ b/layout/forms/nsRangeFrame.cpp @@ -418,7 +418,7 @@ nsRangeFrame::ReflowAnonymousContent(nsPresContext* aPresContext, ReflowOutput trackDesiredSize(aReflowInput); ReflowChild(trackFrame, aPresContext, trackDesiredSize, trackReflowInput, trackX, trackY, 0, frameStatus); - MOZ_ASSERT(NS_FRAME_IS_FULLY_COMPLETE(frameStatus), + MOZ_ASSERT(frameStatus.IsFullyComplete(), "We gave our child unconstrained height, so it should be complete"); FinishReflowChild(trackFrame, aPresContext, trackDesiredSize, &trackReflowInput, trackX, trackY, 0); @@ -440,7 +440,7 @@ nsRangeFrame::ReflowAnonymousContent(nsPresContext* aPresContext, ReflowOutput thumbDesiredSize(aReflowInput); ReflowChild(thumbFrame, aPresContext, thumbDesiredSize, thumbReflowInput, 0, 0, 0, frameStatus); - MOZ_ASSERT(NS_FRAME_IS_FULLY_COMPLETE(frameStatus), + MOZ_ASSERT(frameStatus.IsFullyComplete(), "We gave our child unconstrained height, so it should be complete"); FinishReflowChild(thumbFrame, aPresContext, thumbDesiredSize, &thumbReflowInput, 0, 0, 0); @@ -466,7 +466,7 @@ nsRangeFrame::ReflowAnonymousContent(nsPresContext* aPresContext, ReflowChild(rangeProgressFrame, aPresContext, progressDesiredSize, progressReflowInput, 0, 0, 0, frameStatus); - MOZ_ASSERT(NS_FRAME_IS_FULLY_COMPLETE(frameStatus), + MOZ_ASSERT(frameStatus.IsFullyComplete(), "We gave our child unconstrained height, so it should be complete"); FinishReflowChild(rangeProgressFrame, aPresContext, progressDesiredSize, &progressReflowInput, 0, 0, 0); diff --git a/layout/generic/BlockReflowInput.cpp b/layout/generic/BlockReflowInput.cpp index fbed23eb69ca..2f47897c1205 100644 --- a/layout/generic/BlockReflowInput.cpp +++ b/layout/generic/BlockReflowInput.cpp @@ -941,7 +941,7 @@ BlockReflowInput::FlowAndPlaceFloat(nsIFrame* aFloat) !mustPlaceFloat && (!mReflowInput.mFlags.mIsTopOfPage || floatPos.B(wm) > 0) && NS_STYLE_PAGE_BREAK_AVOID == aFloat->StyleDisplay()->mBreakInside && - (!NS_FRAME_IS_FULLY_COMPLETE(reflowStatus) || + (!reflowStatus.IsFullyComplete() || aFloat->BSize(wm) + floatMargin.BStartEnd(wm) > ContentBEnd() - floatPos.B(wm)) && !aFloat->GetPrevInFlow()) { @@ -1002,7 +1002,7 @@ BlockReflowInput::FlowAndPlaceFloat(nsIFrame* aFloat) FloatManager()->IncludeInDamage(blockStart, blockEnd); } - if (!NS_FRAME_IS_FULLY_COMPLETE(reflowStatus)) { + if (!reflowStatus.IsFullyComplete()) { mBlock->SplitFloat(*this, aFloat, reflowStatus); } else { MOZ_ASSERT(!aFloat->GetNextInFlow()); diff --git a/layout/generic/nsAbsoluteContainingBlock.cpp b/layout/generic/nsAbsoluteContainingBlock.cpp index afab87de7e93..36185397ce50 100644 --- a/layout/generic/nsAbsoluteContainingBlock.cpp +++ b/layout/generic/nsAbsoluteContainingBlock.cpp @@ -138,7 +138,7 @@ nsAbsoluteContainingBlock::Reflow(nsContainerFrame* aDelegatingFrame, ReflowAbsoluteFrame(aDelegatingFrame, aPresContext, aReflowInput, cb, aFlags, kidFrame, kidStatus, aOverflowAreas); nsIFrame* nextFrame = kidFrame->GetNextInFlow(); - if (!NS_FRAME_IS_FULLY_COMPLETE(kidStatus) && + if (!kidStatus.IsFullyComplete() && aDelegatingFrame->IsFrameOfType(nsIFrame::eCanContainOverflowContainers)) { // Need a continuation if (!nextFrame) { diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index 0a549151ad5a..80a9a7b2ff70 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -1238,8 +1238,8 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext, // If we have a next-in-flow, and that next-in-flow has pushed floats from // this frame from a previous iteration of reflow, then we should not return - // a status of NS_FRAME_IS_FULLY_COMPLETE, since we actually have overflow, - // it's just already been handled. + // a status with IsFullyComplete() equals to true, since we actually have + // overflow, it's just already been handled. // NOTE: This really shouldn't happen, since we _should_ pull back our floats // and reflow them, but just in case it does, this is a safety precaution so @@ -1247,7 +1247,7 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext, // been deleted as part of removing our next-in-flow. // XXXmats maybe this code isn't needed anymore? // XXXmats (layout/generic/crashtests/600100.xhtml doesn't crash without it) - if (NS_FRAME_IS_FULLY_COMPLETE(state.mReflowStatus)) { + if (state.mReflowStatus.IsFullyComplete()) { nsBlockFrame* nif = static_cast(GetNextInFlow()); while (nif) { if (nif->HasPushedFloatsFromPrevContinuation()) { @@ -1272,7 +1272,7 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext, NS_FRAME_SET_INCOMPLETE(state.mReflowStatus); } - if (!NS_FRAME_IS_FULLY_COMPLETE(state.mReflowStatus)) { + if (!state.mReflowStatus.IsFullyComplete()) { if (HasOverflowLines() || HasPushedFloats()) { state.mReflowStatus |= NS_FRAME_REFLOW_NEXTINFLOW; } @@ -3604,7 +3604,7 @@ nsBlockFrame::ReflowBlockFrame(BlockReflowInput& aState, collapsedBEndMargin, overflowAreas, frameReflowStatus); - if (!NS_FRAME_IS_FULLY_COMPLETE(frameReflowStatus) && + if (!frameReflowStatus.IsFullyComplete() && ShouldAvoidBreakInside(aState.mReflowInput)) { *aKeepReflowGoing = false; } @@ -3628,7 +3628,7 @@ nsBlockFrame::ReflowBlockFrame(BlockReflowInput& aState, // Continue the block frame now if it didn't completely fit in // the available space. - if (!NS_FRAME_IS_FULLY_COMPLETE(frameReflowStatus)) { + if (!frameReflowStatus.IsFullyComplete()) { bool madeContinuation = CreateContinuationFor(aState, nullptr, frame); @@ -4240,7 +4240,7 @@ nsBlockFrame::ReflowInlineFrame(BlockReflowInput& aState, } } - if (!NS_FRAME_IS_FULLY_COMPLETE(frameReflowStatus)) { + if (!frameReflowStatus.IsFullyComplete()) { // Create a continuation for the incomplete frame. Note that the // frame may already have a continuation. CreateContinuationFor(aState, aLine, aFrame); @@ -4291,7 +4291,7 @@ nsBlockFrame::SplitFloat(BlockReflowInput& aState, nsIFrame* aFloat, nsReflowStatus aFloatStatus) { - MOZ_ASSERT(!NS_FRAME_IS_FULLY_COMPLETE(aFloatStatus), + MOZ_ASSERT(!aFloatStatus.IsFullyComplete(), "why split the frame if it's fully complete?"); MOZ_ASSERT(aState.mBlock == this); @@ -4639,7 +4639,7 @@ nsBlockFrame::PlaceLine(BlockReflowInput& aState, newBCoord = aState.mBCoord + dy; } - if (!NS_FRAME_IS_FULLY_COMPLETE(aState.mReflowStatus) && + if (!aState.mReflowStatus.IsFullyComplete() && ShouldAvoidBreakInside(aState.mReflowInput)) { aLine->AppendFloats(aState.mCurrentLineFloats); aState.mReflowStatus = NS_INLINE_LINE_BREAK_BEFORE(); @@ -6273,7 +6273,7 @@ nsBlockFrame::ReflowFloat(BlockReflowInput& aState, aReflowStatus, aState); } while (clearanceFrame); - if (!NS_FRAME_IS_FULLY_COMPLETE(aReflowStatus) && + if (!aReflowStatus.IsFullyComplete() && ShouldAvoidBreakInside(floatRS)) { aReflowStatus = NS_INLINE_LINE_BREAK_BEFORE(); } else if (aReflowStatus.IsIncomplete() && diff --git a/layout/generic/nsBlockReflowContext.cpp b/layout/generic/nsBlockReflowContext.cpp index 3be74c929aa0..3a38a5f5b0e2 100644 --- a/layout/generic/nsBlockReflowContext.cpp +++ b/layout/generic/nsBlockReflowContext.cpp @@ -336,7 +336,7 @@ nsBlockReflowContext::ReflowBlock(const LogicalRect& aSpace, // them now. Do not do this when a break-before is signaled because // the frame is going to get reflowed again (and may end up wanting // a next-in-flow where it ends up), unless it is an out of flow frame. - if (NS_FRAME_IS_FULLY_COMPLETE(aFrameReflowStatus)) { + if (aFrameReflowStatus.IsFullyComplete()) { nsIFrame* kidNextInFlow = mFrame->GetNextInFlow(); if (nullptr != kidNextInFlow) { // Remove all of the childs next-in-flows. Make sure that we ask diff --git a/layout/generic/nsCanvasFrame.cpp b/layout/generic/nsCanvasFrame.cpp index eb972c860507..06d280a5dff2 100644 --- a/layout/generic/nsCanvasFrame.cpp +++ b/layout/generic/nsCanvasFrame.cpp @@ -715,7 +715,7 @@ nsCanvasFrame::Reflow(nsPresContext* aPresContext, FinishReflowChild(kidFrame, aPresContext, kidDesiredSize, &kidReflowInput, kidWM, kidPt, containerSize, 0); - if (!NS_FRAME_IS_FULLY_COMPLETE(aStatus)) { + if (!aStatus.IsFullyComplete()) { nsIFrame* nextFrame = kidFrame->GetNextInFlow(); NS_ASSERTION(nextFrame || aStatus & NS_FRAME_REFLOW_NEXTINFLOW, "If it's incomplete and has no nif yet, it must flag a nif reflow."); diff --git a/layout/generic/nsColumnSetFrame.cpp b/layout/generic/nsColumnSetFrame.cpp index 98f10b896b84..be48678823f9 100644 --- a/layout/generic/nsColumnSetFrame.cpp +++ b/layout/generic/nsColumnSetFrame.cpp @@ -683,7 +683,7 @@ nsColumnSetFrame::ReflowChildren(ReflowOutput& aDesiredSize, // Build a continuation column if necessary nsIFrame* kidNextInFlow = child->GetNextInFlow(); - if (NS_FRAME_IS_FULLY_COMPLETE(aStatus) && !NS_FRAME_IS_TRUNCATED(aStatus)) { + if (aStatus.IsFullyComplete() && !NS_FRAME_IS_TRUNCATED(aStatus)) { NS_ASSERTION(!kidNextInFlow, "next in flow should have been deleted"); child = nullptr; break; @@ -828,10 +828,10 @@ nsColumnSetFrame::ReflowChildren(ReflowOutput& aDesiredSize, } #ifdef DEBUG_roc - printf("*** DONE PASS feasible=%d\n", allFit && NS_FRAME_IS_FULLY_COMPLETE(aStatus) + printf("*** DONE PASS feasible=%d\n", allFit && aStatus.IsFullyComplete() && !NS_FRAME_IS_TRUNCATED(aStatus)); #endif - return allFit && NS_FRAME_IS_FULLY_COMPLETE(aStatus) + return allFit && aStatus.IsFullyComplete() && !NS_FRAME_IS_TRUNCATED(aStatus); } @@ -1102,7 +1102,7 @@ nsColumnSetFrame::Reflow(nsPresContext* aPresContext, aStatus = NS_FRAME_COMPLETE; } - NS_ASSERTION(NS_FRAME_IS_FULLY_COMPLETE(aStatus) || + NS_ASSERTION(aStatus.IsFullyComplete() || aReflowInput.AvailableBSize() != NS_UNCONSTRAINEDSIZE, "Column set should be complete if the available block-size is unconstrained"); diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp index 0788a751829b..446e88c93510 100644 --- a/layout/generic/nsContainerFrame.cpp +++ b/layout/generic/nsContainerFrame.cpp @@ -1030,7 +1030,7 @@ nsContainerFrame::ReflowChild(nsIFrame* aKidFrame, // If the child frame is complete, delete any next-in-flows, // but only if the NO_DELETE_NEXT_IN_FLOW flag isn't set. if (!NS_INLINE_IS_BREAK_BEFORE(aStatus) && - NS_FRAME_IS_FULLY_COMPLETE(aStatus) && + aStatus.IsFullyComplete() && !(aFlags & NS_FRAME_NO_DELETE_NEXT_IN_FLOW_CHILD)) { nsIFrame* kidNextInFlow = aKidFrame->GetNextInFlow(); if (kidNextInFlow) { @@ -1073,7 +1073,7 @@ nsContainerFrame::ReflowChild(nsIFrame* aKidFrame, // If the child frame is complete, delete any next-in-flows, // but only if the NO_DELETE_NEXT_IN_FLOW flag isn't set. - if (NS_FRAME_IS_FULLY_COMPLETE(aStatus) && + if (aStatus.IsFullyComplete() && !(aFlags & NS_FRAME_NO_DELETE_NEXT_IN_FLOW_CHILD)) { nsIFrame* kidNextInFlow = aKidFrame->GetNextInFlow(); if (kidNextInFlow) { @@ -1280,7 +1280,7 @@ nsContainerFrame::ReflowOverflowContainerChildren(nsPresContext* aPres wm, pos, containerSize, aFlags); // Handle continuations - if (!NS_FRAME_IS_FULLY_COMPLETE(frameStatus)) { + if (!frameStatus.IsFullyComplete()) { if (frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) { // Abspos frames can't cause their parent to be incomplete, // only overflow incomplete. diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index a7d43eb17bc9..9583b7ea3b1d 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -11225,7 +11225,7 @@ void nsFrame::DisplayReflowExit(nsPresContext* aPresContext, DR_state->PrettyUC(aMetrics.Height(), height, 16); printf("Reflow d=%s,%s", width, height); - if (!NS_FRAME_IS_FULLY_COMPLETE(aStatus)) { + if (!aStatus.IsFullyComplete()) { printf(" status=0x%x", aStatus); } if (aFrame->HasOverflowAreas()) { diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index a158a8b4f82c..0ca809677527 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -5626,7 +5626,7 @@ nsGridContainerFrame::ReflowRowsInFragmentainer( ReflowInFlowChild(child, info, aContainerSize, Some(bSize), &aFragmentainer, aState, aContentArea, aDesiredSize, childStatus); MOZ_ASSERT(NS_INLINE_IS_BREAK_BEFORE(childStatus) || - !NS_FRAME_IS_FULLY_COMPLETE(childStatus) || + !childStatus.IsFullyComplete() || !child->GetNextInFlow(), "fully-complete reflow should destroy any NIFs"); @@ -5685,7 +5685,7 @@ nsGridContainerFrame::ReflowRowsInFragmentainer( if (childStatus.IsIncomplete()) { incompleteItems.PutEntry(child); - } else if (!NS_FRAME_IS_FULLY_COMPLETE(childStatus)) { + } else if (!childStatus.IsFullyComplete()) { overflowIncompleteItems.PutEntry(child); } } @@ -6415,7 +6415,7 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext, if (!prevInFlow) { SharedGridData* sharedGridData = Properties().Get(SharedGridData::Prop()); - if (!NS_FRAME_IS_FULLY_COMPLETE(aStatus)) { + if (!aStatus.IsFullyComplete()) { if (!sharedGridData) { sharedGridData = new SharedGridData; Properties().Set(SharedGridData::Prop(), sharedGridData); diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 9f05f2b04563..511deb4e2bd3 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -309,9 +309,6 @@ private: #define NS_FRAME_OVERFLOW_IS_INCOMPLETE(status) \ (0 != ((status) & NS_FRAME_OVERFLOW_INCOMPLETE)) -#define NS_FRAME_IS_FULLY_COMPLETE(status) \ - (NS_FRAME_IS_COMPLETE(status) && !NS_FRAME_OVERFLOW_IS_INCOMPLETE(status)) - // These macros set or switch incomplete statuses without touching the // NS_FRAME_REFLOW_NEXTINFLOW bit. #define NS_FRAME_SET_INCOMPLETE(status) \ diff --git a/layout/generic/nsInlineFrame.cpp b/layout/generic/nsInlineFrame.cpp index 9d3703320193..50485ec1ed40 100644 --- a/layout/generic/nsInlineFrame.cpp +++ b/layout/generic/nsInlineFrame.cpp @@ -822,7 +822,7 @@ nsInlineFrame::ReflowInlineFrame(nsPresContext* aPresContext, } // Create a next-in-flow if needed. - if (!NS_FRAME_IS_FULLY_COMPLETE(aStatus)) { + if (!aStatus.IsFullyComplete()) { CreateNextInFlow(aFrame); } @@ -847,7 +847,7 @@ nsInlineFrame::ReflowInlineFrame(nsPresContext* aPresContext, return; } - if (!NS_FRAME_IS_FULLY_COMPLETE(aStatus) && !reflowingFirstLetter) { + if (!aStatus.IsFullyComplete() && !reflowingFirstLetter) { nsIFrame* nextFrame = aFrame->GetNextSibling(); if (nextFrame) { PushFrames(aPresContext, nextFrame, aFrame, irs); diff --git a/layout/generic/nsPageContentFrame.cpp b/layout/generic/nsPageContentFrame.cpp index d272fba93a37..b1ab9443a36a 100644 --- a/layout/generic/nsPageContentFrame.cpp +++ b/layout/generic/nsPageContentFrame.cpp @@ -88,7 +88,7 @@ nsPageContentFrame::Reflow(nsPresContext* aPresContext, // Place and size the child FinishReflowChild(frame, aPresContext, aDesiredSize, &kidReflowInput, 0, 0, 0); - NS_ASSERTION(aPresContext->IsDynamic() || !NS_FRAME_IS_FULLY_COMPLETE(aStatus) || + NS_ASSERTION(aPresContext->IsDynamic() || !aStatus.IsFullyComplete() || !frame->GetNextInFlow(), "bad child flow list"); } diff --git a/layout/generic/nsPageFrame.cpp b/layout/generic/nsPageFrame.cpp index ccfd2cc51e33..a6f54531a2e4 100644 --- a/layout/generic/nsPageFrame.cpp +++ b/layout/generic/nsPageFrame.cpp @@ -146,7 +146,7 @@ nsPageFrame::Reflow(nsPresContext* aPresContext, // Place and size the child FinishReflowChild(frame, aPresContext, aDesiredSize, &kidReflowInput, xc, yc, 0); - NS_ASSERTION(!NS_FRAME_IS_FULLY_COMPLETE(aStatus) || + NS_ASSERTION(!aStatus.IsFullyComplete() || !frame->GetNextInFlow(), "bad child flow list"); } PR_PL(("PageFrame::Reflow %p ", this)); diff --git a/layout/generic/nsSimplePageSequenceFrame.cpp b/layout/generic/nsSimplePageSequenceFrame.cpp index 375b5154bff7..386716e5ee98 100644 --- a/layout/generic/nsSimplePageSequenceFrame.cpp +++ b/layout/generic/nsSimplePageSequenceFrame.cpp @@ -283,7 +283,7 @@ nsSimplePageSequenceFrame::Reflow(nsPresContext* aPresContext, // Is the page complete? nsIFrame* kidNextInFlow = kidFrame->GetNextInFlow(); - if (NS_FRAME_IS_FULLY_COMPLETE(status)) { + if (status.IsFullyComplete()) { NS_ASSERTION(!kidNextInFlow, "bad child flow list"); } else if (!kidNextInFlow) { // The page isn't complete and it doesn't have a next-in-flow, so diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index 628381777287..2f2faa7c2dfe 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -3163,7 +3163,7 @@ nsTableFrame::ReflowChildren(TableReflowInput& aReflowInput, childX = rowGroups.Length(); } } - if (isPaginated && !NS_FRAME_IS_FULLY_COMPLETE(aStatus) && + if (isPaginated && !aStatus.IsFullyComplete() && ShouldAvoidBreakInside(aReflowInput.reflowInput)) { aStatus = NS_INLINE_LINE_BREAK_BEFORE(); break; diff --git a/layout/tables/nsTableRowFrame.cpp b/layout/tables/nsTableRowFrame.cpp index e25250982f34..eea58e784e8c 100644 --- a/layout/tables/nsTableRowFrame.cpp +++ b/layout/tables/nsTableRowFrame.cpp @@ -1118,7 +1118,7 @@ nsTableRowFrame::Reflow(nsPresContext* aPresContext, ReflowChildren(aPresContext, aDesiredSize, aReflowInput, *tableFrame, aStatus); - if (aPresContext->IsPaginated() && !NS_FRAME_IS_FULLY_COMPLETE(aStatus) && + if (aPresContext->IsPaginated() && !aStatus.IsFullyComplete() && ShouldAvoidBreakInside(aReflowInput)) { aStatus = NS_INLINE_LINE_BREAK_BEFORE(); } diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp index 35dcef0b66b5..4c7a4e9fd105 100644 --- a/layout/tables/nsTableRowGroupFrame.cpp +++ b/layout/tables/nsTableRowGroupFrame.cpp @@ -1174,7 +1174,7 @@ nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext, rowFrame->DidReflow(aPresContext, nullptr, nsDidReflowStatus::FINISHED); rowFrame->DidResize(); - if (!aRowForcedPageBreak && !NS_FRAME_IS_FULLY_COMPLETE(aStatus) && + if (!aRowForcedPageBreak && !aStatus.IsFullyComplete() && ShouldAvoidBreakInside(aReflowInput)) { aStatus = NS_INLINE_LINE_BREAK_BEFORE(); break; From f7a393e947fb7969281f65b66a9ca87b59221978 Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Sat, 11 Feb 2017 22:45:07 +0800 Subject: [PATCH 090/234] Bug 775624 Part 5 - Remove NS_FRAME_IS_COMPLETE. r=dholbert This patch is written by the help of the following script. function rename() { find layout\ -type f\ \( -name "*.cpp" -or\ -name "*.h" \)\ -exec sed -i -r "s/$1/$2/g" "{}" \; } rename "NS_FRAME_IS_COMPLETE\(([a-zA-Z0-9.*]*)\)" "\1.IsComplete()" MozReview-Commit-ID: GOd4y2N6dcz --HG-- extra : rebase_source : aa8b11d3a756c9e7c521e6ffd70713af0174bd98 --- layout/forms/nsHTMLButtonControlFrame.cpp | 2 +- layout/generic/BlockReflowInput.cpp | 2 +- layout/generic/nsBlockFrame.cpp | 16 ++++++++-------- layout/generic/nsBlockReflowContext.cpp | 2 +- layout/generic/nsContainerFrame.cpp | 2 +- layout/generic/nsFirstLetterFrame.cpp | 2 +- layout/generic/nsFlexContainerFrame.cpp | 6 +++--- layout/generic/nsFrame.cpp | 2 +- layout/generic/nsFrameSetFrame.cpp | 2 +- layout/generic/nsGridContainerFrame.cpp | 14 +++++++------- layout/generic/nsIFrame.h | 3 --- layout/generic/nsInlineFrame.cpp | 4 ++-- layout/generic/nsLineLayout.cpp | 2 +- layout/generic/nsPageContentFrame.cpp | 2 +- layout/generic/nsRubyBaseContainerFrame.cpp | 6 +++--- layout/generic/nsRubyFrame.cpp | 2 +- layout/mathml/nsMathMLContainerFrame.cpp | 2 +- layout/mathml/nsMathMLTokenFrame.cpp | 2 +- layout/mathml/nsMathMLmfencedFrame.cpp | 2 +- layout/mathml/nsMathMLmpaddedFrame.cpp | 2 +- layout/mathml/nsMathMLmrootFrame.cpp | 2 +- layout/tables/nsTableFrame.cpp | 6 +++--- layout/tables/nsTableRowFrame.cpp | 2 +- layout/tables/nsTableRowGroupFrame.cpp | 2 +- 24 files changed, 43 insertions(+), 46 deletions(-) diff --git a/layout/forms/nsHTMLButtonControlFrame.cpp b/layout/forms/nsHTMLButtonControlFrame.cpp index c08d93f5cd0a..da7ef19ee60a 100644 --- a/layout/forms/nsHTMLButtonControlFrame.cpp +++ b/layout/forms/nsHTMLButtonControlFrame.cpp @@ -257,7 +257,7 @@ nsHTMLButtonControlFrame::ReflowButtonContents(nsPresContext* aPresContext, ReflowChild(aFirstKid, aPresContext, contentsDesiredSize, contentsReflowInput, wm, childPos, dummyContainerSize, 0, contentsReflowStatus); - MOZ_ASSERT(NS_FRAME_IS_COMPLETE(contentsReflowStatus), + MOZ_ASSERT(contentsReflowStatus.IsComplete(), "We gave button-contents frame unconstrained available height, " "so it should be complete"); diff --git a/layout/generic/BlockReflowInput.cpp b/layout/generic/BlockReflowInput.cpp index 2f47897c1205..e11776b1657f 100644 --- a/layout/generic/BlockReflowInput.cpp +++ b/layout/generic/BlockReflowInput.cpp @@ -775,7 +775,7 @@ BlockReflowInput::FlowAndPlaceFloat(nsIFrame* aFloat) mBlock->ReflowFloat(*this, adjustedAvailableSpace, aFloat, floatMargin, floatOffsets, false, reflowStatus); floatMarginISize = aFloat->ISize(wm) + floatMargin.IStartEnd(wm); - NS_ASSERTION(NS_FRAME_IS_COMPLETE(reflowStatus), + NS_ASSERTION(reflowStatus.IsComplete(), "letter frames and orthogonal floats with auto block-size " "shouldn't break, and if they do now, then they're breaking " "at the wrong point"); diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index 80a9a7b2ff70..a448aacd57f3 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -1267,7 +1267,7 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext, // If we end in a BR with clear and affected floats continue, // we need to continue, too. if (NS_UNCONSTRAINEDSIZE != reflowInput->AvailableBSize() && - NS_FRAME_IS_COMPLETE(state.mReflowStatus) && + state.mReflowStatus.IsComplete() && state.FloatManager()->ClearContinues(FindTrailingClear())) { NS_FRAME_SET_INCOMPLETE(state.mReflowStatus); } @@ -1472,7 +1472,7 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext, IndentBy(stdout, gNoiseIndent); ListTag(stdout); printf(": status=%x (%scomplete) metrics=%d,%d carriedMargin=%d", - aStatus, NS_FRAME_IS_COMPLETE(aStatus) ? "" : "not ", + aStatus, aStatus.IsComplete() ? "" : "not ", aMetrics.ISize(parentWM), aMetrics.BSize(parentWM), aMetrics.mCarriedOutBEndMargin.get()); if (HasOverflowAreas()) { @@ -1613,7 +1613,7 @@ nsBlockFrame::ComputeFinalSize(const ReflowInput& aReflowInput, ComputeFinalBSize(aReflowInput, &aState.mReflowStatus, aState.mBCoord + nonCarriedOutBDirMargin, borderPadding, finalSize, aState.mConsumedBSize); - if (!NS_FRAME_IS_COMPLETE(aState.mReflowStatus)) { + if (!aState.mReflowStatus.IsComplete()) { // Use the current height; continuations will take up the rest. // Do extend the height to at least consume the available // height, otherwise our left/right borders (for example) won't @@ -1635,7 +1635,7 @@ nsBlockFrame::ComputeFinalSize(const ReflowInput& aReflowInput, // Don't carry out a block-end margin when our BSize is fixed. aMetrics.mCarriedOutBEndMargin.Zero(); } - else if (NS_FRAME_IS_COMPLETE(aState.mReflowStatus)) { + else if (aState.mReflowStatus.IsComplete()) { nscoord contentBSize = blockEndEdgeOfChildren - borderPadding.BStart(wm); nscoord autoBSize = aReflowInput.ApplyMinMaxBSize(contentBSize); if (autoBSize != contentBSize) { @@ -1667,7 +1667,7 @@ nsBlockFrame::ComputeFinalSize(const ReflowInput& aReflowInput, } } else if (aReflowInput.AvailableBSize() != NS_UNCONSTRAINEDSIZE && !NS_INLINE_IS_BREAK_BEFORE(aState.mReflowStatus) && - NS_FRAME_IS_COMPLETE(aState.mReflowStatus)) { + aState.mReflowStatus.IsComplete()) { // Currently only used for grid items, but could be used in other contexts. // The FragStretchBSizeProperty is our expected non-fragmented block-size // we should stretch to (for align-self:stretch etc). In some fragmentation @@ -1684,7 +1684,7 @@ nsBlockFrame::ComputeFinalSize(const ReflowInput& aReflowInput, // Clamp the content size to fit within the margin-box clamp size, if any. if (MOZ_UNLIKELY(aReflowInput.mFlags.mBClampMarginBoxMinSize) && - NS_FRAME_IS_COMPLETE(aState.mReflowStatus)) { + aState.mReflowStatus.IsComplete()) { bool found; nscoord cbSize = Properties().Get(BClampMarginBoxMinSizeProperty(), &found); if (found) { @@ -4228,7 +4228,7 @@ nsBlockFrame::ReflowInlineFrame(BlockReflowInput& aState, } } aLine->SetBreakTypeAfter(breakType); - if (NS_FRAME_IS_COMPLETE(frameReflowStatus)) { + if (frameReflowStatus.IsComplete()) { // Split line, but after the frame just reflowed SplitLine(aState, aLineLayout, aLine, aFrame->GetNextSibling(), aLineReflowStatus); @@ -7416,7 +7416,7 @@ nsBlockFrame::ComputeFinalBSize(const ReflowInput& aReflowInput, NS_FRAME_SET_OVERFLOW_INCOMPLETE(*aStatus); } - if (NS_FRAME_IS_COMPLETE(*aStatus)) { + if (aStatus->IsComplete()) { if (computedBSizeLeftOver > 0 && NS_UNCONSTRAINEDSIZE != aReflowInput.AvailableBSize() && aFinalSize.BSize(wm) > aReflowInput.AvailableBSize()) { diff --git a/layout/generic/nsBlockReflowContext.cpp b/layout/generic/nsBlockReflowContext.cpp index 3a38a5f5b0e2..bf240593f208 100644 --- a/layout/generic/nsBlockReflowContext.cpp +++ b/layout/generic/nsBlockReflowContext.cpp @@ -367,7 +367,7 @@ nsBlockReflowContext::PlaceBlock(const ReflowInput& aReflowInput, // Compute collapsed block-end margin value. WritingMode wm = aReflowInput.GetWritingMode(); WritingMode parentWM = mMetrics.GetWritingMode(); - if (NS_FRAME_IS_COMPLETE(aReflowStatus)) { + if (aReflowStatus.IsComplete()) { aBEndMarginResult = mMetrics.mCarriedOutBEndMargin; aBEndMarginResult.Include(aReflowInput.ComputedLogicalMargin(). ConvertTo(parentWM, wm).BEnd(parentWM)); diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp index 446e88c93510..470d05fcf005 100644 --- a/layout/generic/nsContainerFrame.cpp +++ b/layout/generic/nsContainerFrame.cpp @@ -1287,7 +1287,7 @@ nsContainerFrame::ReflowOverflowContainerChildren(nsPresContext* aPres NS_FRAME_SET_OVERFLOW_INCOMPLETE(frameStatus); } else { - NS_ASSERTION(NS_FRAME_IS_COMPLETE(frameStatus), + NS_ASSERTION(frameStatus.IsComplete(), "overflow container frames can't be incomplete, only overflow-incomplete"); } diff --git a/layout/generic/nsFirstLetterFrame.cpp b/layout/generic/nsFirstLetterFrame.cpp index 74adecf56a5b..ab34947ee176 100644 --- a/layout/generic/nsFirstLetterFrame.cpp +++ b/layout/generic/nsFirstLetterFrame.cpp @@ -268,7 +268,7 @@ nsFirstLetterFrame::Reflow(nsPresContext* aPresContext, if (!NS_INLINE_IS_BREAK_BEFORE(aReflowStatus)) { // Create a continuation or remove existing continuations based on // the reflow completion status. - if (NS_FRAME_IS_COMPLETE(aReflowStatus)) { + if (aReflowStatus.IsComplete()) { if (aReflowInput.mLineLayout) { aReflowInput.mLineLayout->SetFirstLetterStyleOK(false); } diff --git a/layout/generic/nsFlexContainerFrame.cpp b/layout/generic/nsFlexContainerFrame.cpp index 76685a9443b6..ada317c402dd 100644 --- a/layout/generic/nsFlexContainerFrame.cpp +++ b/layout/generic/nsFlexContainerFrame.cpp @@ -1846,7 +1846,7 @@ nsFlexContainerFrame::MeasureAscentAndHeightForFlexItem( // XXXdholbert Once we do pagination / splitting, we'll need to actually // handle incomplete childReflowStatuses. But for now, we give our kids // unconstrained available height, which means they should always complete. - MOZ_ASSERT(NS_FRAME_IS_COMPLETE(childReflowStatus), + MOZ_ASSERT(childReflowStatus.IsComplete(), "We gave flex item unconstrained available height, so it " "should be complete"); @@ -4626,7 +4626,7 @@ nsFlexContainerFrame::DoFlexLayout(nsPresContext* aPresContext, // NOTE: If we're auto-height, we allow our bottom border/padding to push us // over the available height without requesting a continuation, for // consistency with the behavior of "display:block" elements. - if (NS_FRAME_IS_COMPLETE(aStatus)) { + if (aStatus.IsComplete()) { nscoord desiredBSizeWithBEndBP = desiredSizeInFlexWM.BSize(flexWM) + blockEndContainerBP; @@ -4780,7 +4780,7 @@ nsFlexContainerFrame::ReflowFlexItem(nsPresContext* aPresContext, // handle incomplete childReflowStatuses. But for now, we give our kids // unconstrained available height, which means they should always // complete. - MOZ_ASSERT(NS_FRAME_IS_COMPLETE(childReflowStatus), + MOZ_ASSERT(childReflowStatus.IsComplete(), "We gave flex item unconstrained available height, so it " "should be complete"); diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 9583b7ea3b1d..757fe0244ecc 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -9946,7 +9946,7 @@ nsFrame::BoxReflow(nsBoxLayoutState& aState, Reflow(aPresContext, aDesiredSize, reflowInput, status); - NS_ASSERTION(NS_FRAME_IS_COMPLETE(status), "bad status"); + NS_ASSERTION(status.IsComplete(), "bad status"); uint32_t layoutFlags = aState.LayoutFlags(); nsContainerFrame::FinishReflowChild(this, aPresContext, aDesiredSize, diff --git a/layout/generic/nsFrameSetFrame.cpp b/layout/generic/nsFrameSetFrame.cpp index 561c3fda5adc..9d5c513af8f3 100644 --- a/layout/generic/nsFrameSetFrame.cpp +++ b/layout/generic/nsFrameSetFrame.cpp @@ -705,7 +705,7 @@ nsHTMLFramesetFrame::ReflowPlaceChild(nsIFrame* aChild, ReflowChild(aChild, aPresContext, reflowOutput, reflowInput, aOffset.x, aOffset.y, 0, status); - NS_ASSERTION(NS_FRAME_IS_COMPLETE(status), "bad status"); + NS_ASSERTION(status.IsComplete(), "bad status"); // Place and size the child reflowOutput.Width() = aSize.width; diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index 0ca809677527..b528ad0358f8 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -5287,7 +5287,7 @@ nsGridContainerFrame::ReflowInFlowChild(nsIFrame* aChild, // Apply align/justify-self and reflow again if that affects the size. if (MOZ_LIKELY(isGridItem)) { LogicalSize size = childSize.Size(childWM); // from the ReflowChild() - if (NS_FRAME_IS_COMPLETE(aStatus)) { + if (aStatus.IsComplete()) { auto align = childRI.mStylePosition->UsedAlignSelf(containerSC); auto state = aGridItemInfo->mState[eLogicalAxisBlock]; if (state & ItemState::eContentBaseline) { @@ -5348,7 +5348,7 @@ nsGridContainerFrame::ReflowInFragmentainer(GridReflowInput& aState, nsReflowStatus childStatus; ReflowInFlowChild(child, nullptr, aContainerSize, Nothing(), &aFragmentainer, aState, aContentArea, aDesiredSize, childStatus); - MOZ_ASSERT(NS_FRAME_IS_COMPLETE(childStatus), + MOZ_ASSERT(childStatus.IsComplete(), "nsPlaceholderFrame should never need to be fragmented"); } @@ -5516,7 +5516,7 @@ nsGridContainerFrame::ReflowInFragmentainer(GridReflowInput& aState, // If we can't fit all rows then we're at least overflow-incomplete. if (endRow < numRows) { childAvailableSize = bEndRow; - if (NS_FRAME_IS_COMPLETE(aStatus)) { + if (aStatus.IsComplete()) { NS_FRAME_SET_OVERFLOW_INCOMPLETE(aStatus); aStatus |= NS_FRAME_REFLOW_NEXTINFLOW; } @@ -5702,7 +5702,7 @@ nsGridContainerFrame::ReflowRowsInFragmentainer( if (!pushedItems.IsEmpty() || !incompleteItems.IsEmpty() || !overflowIncompleteItems.IsEmpty()) { - if (NS_FRAME_IS_COMPLETE(aStatus)) { + if (aStatus.IsComplete()) { NS_FRAME_SET_OVERFLOW_INCOMPLETE(aStatus); aStatus |= NS_FRAME_REFLOW_NEXTINFLOW; } @@ -5853,7 +5853,7 @@ nsGridContainerFrame::ReflowChildren(GridReflowInput& aState, } ReflowInFlowChild(*aState.mIter, info, containerSize, Nothing(), nullptr, aState, aContentArea, aDesiredSize, aStatus); - MOZ_ASSERT(NS_FRAME_IS_COMPLETE(aStatus), "child should be complete " + MOZ_ASSERT(aStatus.IsComplete(), "child should be complete " "in unconstrained reflow"); } } @@ -6157,7 +6157,7 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext, bSize = std::max(bSize - consumedBSize, 0); // Skip our block-end border if we're INCOMPLETE. - if (!NS_FRAME_IS_COMPLETE(aStatus) && + if (!aStatus.IsComplete() && !gridReflowInput.mSkipSides.BEnd() && StyleBorder()->mBoxDecorationBreak != StyleBoxDecorationBreak::Clone) { @@ -6172,7 +6172,7 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext, // Convert INCOMPLETE -> OVERFLOW_INCOMPLETE and zero bsize if we're an OC. if (HasAnyStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER)) { - if (!NS_FRAME_IS_COMPLETE(aStatus)) { + if (!aStatus.IsComplete()) { NS_FRAME_SET_OVERFLOW_INCOMPLETE(aStatus); aStatus |= NS_FRAME_REFLOW_NEXTINFLOW; } diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 511deb4e2bd3..7889653d6d4f 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -303,9 +303,6 @@ private: #define NS_FRAME_REFLOW_NEXTINFLOW 0x2 #define NS_FRAME_OVERFLOW_INCOMPLETE 0x4 -#define NS_FRAME_IS_COMPLETE(status) \ - (0 == ((status) & NS_FRAME_NOT_COMPLETE)) - #define NS_FRAME_OVERFLOW_IS_INCOMPLETE(status) \ (0 != ((status) & NS_FRAME_OVERFLOW_INCOMPLETE)) diff --git a/layout/generic/nsInlineFrame.cpp b/layout/generic/nsInlineFrame.cpp index 50485ec1ed40..386a3ec5fbe5 100644 --- a/layout/generic/nsInlineFrame.cpp +++ b/layout/generic/nsInlineFrame.cpp @@ -734,7 +734,7 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext, } } - NS_ASSERTION(!NS_FRAME_IS_COMPLETE(aStatus) || !GetOverflowFrames(), + NS_ASSERTION(!aStatus.IsComplete() || !GetOverflowFrames(), "We can't be complete AND have overflow frames!"); // If after reflowing our children they take up no area then make @@ -771,7 +771,7 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext, * chain. For box-decoration-break:clone we always apply the end border and * padding since all continuations have them. */ - if ((NS_FRAME_IS_COMPLETE(aStatus) && + if ((aStatus.IsComplete() && !LastInFlow()->GetNextContinuation() && !FrameIsNonLastInIBSplit()) || boxDecorationBreakClone) { diff --git a/layout/generic/nsLineLayout.cpp b/layout/generic/nsLineLayout.cpp index 92f9c13d780b..df64dff3deb0 100644 --- a/layout/generic/nsLineLayout.cpp +++ b/layout/generic/nsLineLayout.cpp @@ -1072,7 +1072,7 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame, // them now. Do not do this when a break-before is signaled because // the frame is going to get reflowed again (and may end up wanting // a next-in-flow where it ends up). - if (NS_FRAME_IS_COMPLETE(aReflowStatus)) { + if (aReflowStatus.IsComplete()) { nsIFrame* kidNextInFlow = aFrame->GetNextInFlow(); if (nullptr != kidNextInFlow) { // Remove all of the childs next-in-flows. Make sure that we ask diff --git a/layout/generic/nsPageContentFrame.cpp b/layout/generic/nsPageContentFrame.cpp index b1ab9443a36a..1a9b17a42b50 100644 --- a/layout/generic/nsPageContentFrame.cpp +++ b/layout/generic/nsPageContentFrame.cpp @@ -95,7 +95,7 @@ nsPageContentFrame::Reflow(nsPresContext* aPresContext, // Reflow our fixed frames nsReflowStatus fixedStatus = NS_FRAME_COMPLETE; ReflowAbsoluteFrames(aPresContext, aDesiredSize, aReflowInput, fixedStatus); - NS_ASSERTION(NS_FRAME_IS_COMPLETE(fixedStatus), "fixed frames can be truncated, but not incomplete"); + NS_ASSERTION(fixedStatus.IsComplete(), "fixed frames can be truncated, but not incomplete"); // Return our desired size WritingMode wm = aReflowInput.GetWritingMode(); diff --git a/layout/generic/nsRubyBaseContainerFrame.cpp b/layout/generic/nsRubyBaseContainerFrame.cpp index 5c8a83f95492..9a417f27f44d 100644 --- a/layout/generic/nsRubyBaseContainerFrame.cpp +++ b/layout/generic/nsRubyBaseContainerFrame.cpp @@ -405,9 +405,9 @@ nsRubyBaseContainerFrame::Reflow(nsPresContext* aPresContext, // If there exists any span, the columns must either be completely // reflowed, or be not reflowed at all. MOZ_ASSERT(NS_INLINE_IS_BREAK_BEFORE(aStatus) || - NS_FRAME_IS_COMPLETE(aStatus) || !hasSpan); + aStatus.IsComplete() || !hasSpan); if (!NS_INLINE_IS_BREAK_BEFORE(aStatus) && - NS_FRAME_IS_COMPLETE(aStatus) && hasSpan) { + aStatus.IsComplete() && hasSpan) { // Reflow spans RubyReflowInput reflowInput = { false, false, textContainers, aReflowInput, reflowInputs @@ -528,7 +528,7 @@ nsRubyBaseContainerFrame::ReflowColumns(const RubyReflowInput& aReflowInput, return 0; } aStatus = NS_INLINE_LINE_BREAK_AFTER(aStatus); - MOZ_ASSERT(NS_FRAME_IS_COMPLETE(aStatus) || aReflowInput.mAllowLineBreak); + MOZ_ASSERT(aStatus.IsComplete() || aReflowInput.mAllowLineBreak); // If we are on an intra-level whitespace column, null values in // column.mBaseFrame and column.mTextFrames don't represent the diff --git a/layout/generic/nsRubyFrame.cpp b/layout/generic/nsRubyFrame.cpp index 28a3c18a51e9..bea3456eaa04 100644 --- a/layout/generic/nsRubyFrame.cpp +++ b/layout/generic/nsRubyFrame.cpp @@ -171,7 +171,7 @@ nsRubyFrame::Reflow(nsPresContext* aPresContext, if (boxDecorationBreakClone || !GetPrevContinuation()) { aDesiredSize.ISize(lineWM) += borderPadding.IStart(frameWM); } - if (boxDecorationBreakClone || NS_FRAME_IS_COMPLETE(aStatus)) { + if (boxDecorationBreakClone || aStatus.IsComplete()) { aDesiredSize.ISize(lineWM) += borderPadding.IEnd(frameWM); } diff --git a/layout/mathml/nsMathMLContainerFrame.cpp b/layout/mathml/nsMathMLContainerFrame.cpp index ad1b13efded8..7be06f0f37d0 100644 --- a/layout/mathml/nsMathMLContainerFrame.cpp +++ b/layout/mathml/nsMathMLContainerFrame.cpp @@ -894,7 +894,7 @@ nsMathMLContainerFrame::Reflow(nsPresContext* aPresContext, childFrame, availSize); ReflowChild(childFrame, aPresContext, childDesiredSize, childReflowInput, childStatus); - //NS_ASSERTION(NS_FRAME_IS_COMPLETE(childStatus), "bad status"); + //NS_ASSERTION(childStatus.IsComplete(), "bad status"); SaveReflowAndBoundingMetricsFor(childFrame, childDesiredSize, childDesiredSize.mBoundingMetrics); childFrame = childFrame->GetNextSibling(); diff --git a/layout/mathml/nsMathMLTokenFrame.cpp b/layout/mathml/nsMathMLTokenFrame.cpp index 13c4d4aa24b2..99857ea963e6 100644 --- a/layout/mathml/nsMathMLTokenFrame.cpp +++ b/layout/mathml/nsMathMLTokenFrame.cpp @@ -144,7 +144,7 @@ nsMathMLTokenFrame::Reflow(nsPresContext* aPresContext, childFrame, availSize); ReflowChild(childFrame, aPresContext, childDesiredSize, childReflowInput, aStatus); - //NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status"); + //NS_ASSERTION(aStatus.IsComplete(), "bad status"); SaveReflowAndBoundingMetricsFor(childFrame, childDesiredSize, childDesiredSize.mBoundingMetrics); } diff --git a/layout/mathml/nsMathMLmfencedFrame.cpp b/layout/mathml/nsMathMLmfencedFrame.cpp index ca780e649b7f..e0baa1fb36da 100644 --- a/layout/mathml/nsMathMLmfencedFrame.cpp +++ b/layout/mathml/nsMathMLmfencedFrame.cpp @@ -265,7 +265,7 @@ nsMathMLmfencedFrame::Reflow(nsPresContext* aPresContext, childFrame, availSize); ReflowChild(childFrame, aPresContext, childDesiredSize, childReflowInput, childStatus); - //NS_ASSERTION(NS_FRAME_IS_COMPLETE(childStatus), "bad status"); + //NS_ASSERTION(childStatus.IsComplete(), "bad status"); SaveReflowAndBoundingMetricsFor(childFrame, childDesiredSize, childDesiredSize.mBoundingMetrics); diff --git a/layout/mathml/nsMathMLmpaddedFrame.cpp b/layout/mathml/nsMathMLmpaddedFrame.cpp index 5b2e8282fa5d..2d01b466bd05 100644 --- a/layout/mathml/nsMathMLmpaddedFrame.cpp +++ b/layout/mathml/nsMathMLmpaddedFrame.cpp @@ -315,7 +315,7 @@ nsMathMLmpaddedFrame::Reflow(nsPresContext* aPresContext, // Let the base class format our content like an inferred mrow nsMathMLContainerFrame::Reflow(aPresContext, aDesiredSize, aReflowInput, aStatus); - //NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status"); + //NS_ASSERTION(aStatus.IsComplete(), "bad status"); } /* virtual */ nsresult diff --git a/layout/mathml/nsMathMLmrootFrame.cpp b/layout/mathml/nsMathMLmrootFrame.cpp index 4c81bde3d9b6..3d564e8fd8cb 100644 --- a/layout/mathml/nsMathMLmrootFrame.cpp +++ b/layout/mathml/nsMathMLmrootFrame.cpp @@ -196,7 +196,7 @@ nsMathMLmrootFrame::Reflow(nsPresContext* aPresContext, childFrame, availSize); ReflowChild(childFrame, aPresContext, childDesiredSize, childReflowInput, childStatus); - //NS_ASSERTION(NS_FRAME_IS_COMPLETE(childStatus), "bad status"); + //NS_ASSERTION(childStatus.IsComplete(), "bad status"); if (0 == count) { // base baseFrame = childFrame; diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index 2f2faa7c2dfe..3748eb0c584b 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -1929,7 +1929,7 @@ nsTableFrame::Reflow(nsPresContext* aPresContext, } // XXXldb Are all these conditions correct? - if (needToInitiateSpecialReflow && NS_FRAME_IS_COMPLETE(aStatus)) { + if (needToInitiateSpecialReflow && aStatus.IsComplete()) { // XXXldb Do we need to set the IsBResize flag on any reflow states? ReflowInput &mutable_rs = @@ -3172,7 +3172,7 @@ nsTableFrame::ReflowChildren(TableReflowInput& aReflowInput, // the next page if (isPaginated && (NS_INLINE_IS_BREAK_BEFORE(aStatus) || - (NS_FRAME_IS_COMPLETE(aStatus) && + (aStatus.IsComplete() && (NS_UNCONSTRAINEDSIZE != kidReflowInput.AvailableHeight()) && kidReflowInput.AvailableHeight() < desiredSize.Height()))) { if (ShouldAvoidBreakInside(aReflowInput.reflowInput)) { @@ -3233,7 +3233,7 @@ nsTableFrame::ReflowChildren(TableReflowInput& aReflowInput, pageBreak = false; // see if there is a page break after this row group or before the next one - if (NS_FRAME_IS_COMPLETE(aStatus) && isPaginated && + if (aStatus.IsComplete() && isPaginated && (NS_UNCONSTRAINEDSIZE != kidReflowInput.AvailableHeight())) { nsIFrame* nextKid = (childX + 1 < rowGroups.Length()) ? rowGroups[childX + 1] : nullptr; diff --git a/layout/tables/nsTableRowFrame.cpp b/layout/tables/nsTableRowFrame.cpp index eea58e784e8c..b3447338f480 100644 --- a/layout/tables/nsTableRowFrame.cpp +++ b/layout/tables/nsTableRowFrame.cpp @@ -1177,7 +1177,7 @@ nsTableRowFrame::ReflowCellFrame(nsPresContext* aPresContext, ReflowChild(aCellFrame, aPresContext, desiredSize, cellReflowInput, 0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus); - bool fullyComplete = NS_FRAME_IS_COMPLETE(aStatus) && !NS_FRAME_IS_TRUNCATED(aStatus); + bool fullyComplete = aStatus.IsComplete() && !NS_FRAME_IS_TRUNCATED(aStatus); if (fullyComplete) { desiredSize.BSize(wm) = aAvailableBSize; } diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp index 4c7a4e9fd105..8982a3ba020b 100644 --- a/layout/tables/nsTableRowGroupFrame.cpp +++ b/layout/tables/nsTableRowGroupFrame.cpp @@ -1028,7 +1028,7 @@ nsTableRowGroupFrame::SplitSpanningCells(nsPresContext& aPresContext, isTopOfPage, cell, cellAvailBSize, status); aDesiredBSize = std::max(aDesiredBSize, rowPos.y + cellBSize); - if (NS_FRAME_IS_COMPLETE(status)) { + if (status.IsComplete()) { if (cellBSize > cellAvailBSize) { aFirstTruncatedRow = row; if ((row != &aFirstRow) || !aFirstRowIsTopOfPage) { From ba8d9f3b056133e8597fbe9cde553601417bd09f Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Sat, 11 Feb 2017 22:54:26 +0800 Subject: [PATCH 091/234] Bug 775624 Part 6 - Remove NS_FRAME_OVERFLOW_IS_INCOMPLETE. r=dholbert This patch is written by the help of the following script. function rename() { find layout\ -type f\ \( -name "*.cpp" -or\ -name "*.h" \)\ -exec sed -i -r "s/$1/$2/g" "{}" \; } rename "NS_FRAME_OVERFLOW_IS_INCOMPLETE\(([a-zA-Z0-9.*]*)\)" "\1.IsOverflowIncomplete()" MozReview-Commit-ID: GOd4y2N6dcz --HG-- extra : rebase_source : 2945ff0274d91137249eb2b5a053eeec08864a25 --- layout/generic/nsBlockFrame.cpp | 4 ++-- layout/generic/nsCanvasFrame.cpp | 2 +- layout/generic/nsColumnSetFrame.cpp | 2 +- layout/generic/nsContainerFrame.h | 2 +- layout/generic/nsIFrame.h | 3 --- layout/generic/nsRubyFrame.cpp | 2 +- layout/tables/nsTableCellFrame.cpp | 2 +- 7 files changed, 7 insertions(+), 10 deletions(-) diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index a448aacd57f3..43dd7077c62d 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -4303,14 +4303,14 @@ nsBlockFrame::SplitFloat(BlockReflowInput& aState, if (oldParent != this) { ReparentFrame(nextInFlow, oldParent, this); } - if (!NS_FRAME_OVERFLOW_IS_INCOMPLETE(aFloatStatus)) { + if (!aFloatStatus.IsOverflowIncomplete()) { nextInFlow->RemoveStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER); } } else { nextInFlow = aState.mPresContext->PresShell()->FrameConstructor()-> CreateContinuingFrame(aState.mPresContext, aFloat, this); } - if (NS_FRAME_OVERFLOW_IS_INCOMPLETE(aFloatStatus)) { + if (aFloatStatus.IsOverflowIncomplete()) { nextInFlow->AddStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER); } diff --git a/layout/generic/nsCanvasFrame.cpp b/layout/generic/nsCanvasFrame.cpp index 06d280a5dff2..352b3898dbc5 100644 --- a/layout/generic/nsCanvasFrame.cpp +++ b/layout/generic/nsCanvasFrame.cpp @@ -728,7 +728,7 @@ nsCanvasFrame::Reflow(nsPresContext* aPresContext, // aren't any other frames we need to isolate them from // during reflow. } - if (NS_FRAME_OVERFLOW_IS_INCOMPLETE(aStatus)) { + if (aStatus.IsOverflowIncomplete()) { nextFrame->AddStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER); } } diff --git a/layout/generic/nsColumnSetFrame.cpp b/layout/generic/nsColumnSetFrame.cpp index be48678823f9..89bbb996642a 100644 --- a/layout/generic/nsColumnSetFrame.cpp +++ b/layout/generic/nsColumnSetFrame.cpp @@ -703,7 +703,7 @@ nsColumnSetFrame::ReflowChildren(ReflowOutput& aDesiredSize, // Make sure we reflow a next-in-flow when it switches between being // normal or overflow container - if (NS_FRAME_OVERFLOW_IS_INCOMPLETE(aStatus)) { + if (aStatus.IsOverflowIncomplete()) { if (!(kidNextInFlow->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER)) { aStatus |= NS_FRAME_REFLOW_NEXTINFLOW; reflowNext = true; diff --git a/layout/generic/nsContainerFrame.h b/layout/generic/nsContainerFrame.h index a9f6d52dfb93..0eb315cd70c8 100644 --- a/layout/generic/nsContainerFrame.h +++ b/layout/generic/nsContainerFrame.h @@ -376,7 +376,7 @@ public: * them to our overflow container list * 2. Reflows all our overflow container kids * 3. Expands aOverflowRect as necessary to accomodate these children. - * 4. Sets aStatus's NS_FRAME_OVERFLOW_IS_INCOMPLETE flag (along with + * 4. Sets aStatus's mOverflowIncomplete flag (along with * NS_FRAME_REFLOW_NEXTINFLOW as necessary) if any overflow children * are incomplete and * 5. Prepends a list of their continuations to our excess overflow diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 7889653d6d4f..c91302a183b8 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -303,9 +303,6 @@ private: #define NS_FRAME_REFLOW_NEXTINFLOW 0x2 #define NS_FRAME_OVERFLOW_INCOMPLETE 0x4 -#define NS_FRAME_OVERFLOW_IS_INCOMPLETE(status) \ - (0 != ((status) & NS_FRAME_OVERFLOW_INCOMPLETE)) - // These macros set or switch incomplete statuses without touching the // NS_FRAME_REFLOW_NEXTINFLOW bit. #define NS_FRAME_SET_INCOMPLETE(status) \ diff --git a/layout/generic/nsRubyFrame.cpp b/layout/generic/nsRubyFrame.cpp index bea3456eaa04..a4ffa6adfdf5 100644 --- a/layout/generic/nsRubyFrame.cpp +++ b/layout/generic/nsRubyFrame.cpp @@ -165,7 +165,7 @@ nsRubyFrame::Reflow(nsPresContext* aPresContext, ReflowSegment(aPresContext, aReflowInput, baseContainer, aStatus); } // We never handle overflow in ruby. - MOZ_ASSERT(!NS_FRAME_OVERFLOW_IS_INCOMPLETE(aStatus)); + MOZ_ASSERT(!aStatus.IsOverflowIncomplete()); aDesiredSize.ISize(lineWM) = aReflowInput.mLineLayout->EndSpan(this); if (boxDecorationBreakClone || !GetPrevContinuation()) { diff --git a/layout/tables/nsTableCellFrame.cpp b/layout/tables/nsTableCellFrame.cpp index ac7e3e860a48..69454539aa67 100644 --- a/layout/tables/nsTableCellFrame.cpp +++ b/layout/tables/nsTableCellFrame.cpp @@ -957,7 +957,7 @@ nsTableCellFrame::Reflow(nsPresContext* aPresContext, ReflowChild(firstKid, aPresContext, kidSize, kidReflowInput, wm, kidOrigin, containerSize, 0, aStatus); - if (NS_FRAME_OVERFLOW_IS_INCOMPLETE(aStatus)) { + if (aStatus.IsOverflowIncomplete()) { // Don't pass OVERFLOW_INCOMPLETE through tables until they can actually handle it //XXX should paginate overflow as overflow, but not in this patch (bug 379349) NS_FRAME_SET_INCOMPLETE(aStatus); From 14b6536193a21eb70930d02b1933dc8958ab2d48 Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Sat, 11 Feb 2017 23:06:17 +0800 Subject: [PATCH 092/234] Bug 775624 Part 7 - Remove NS_FRAME_SET_INCOMPLETE. r=dholbert This patch is written by the help of the following script. function rename() { find layout\ -type f\ \( -name "*.cpp" -or\ -name "*.h" \)\ -exec sed -i -r "s/$1/$2/g" "{}" \; } rename "NS_FRAME_SET_INCOMPLETE\(\*([a-zA-Z0-9.*]*)\)" "\1->SetIncomplete()" rename "NS_FRAME_SET_INCOMPLETE\(([a-zA-Z0-9.*]*)\)" "\1.SetIncomplete()" MozReview-Commit-ID: GOd4y2N6dcz --HG-- extra : rebase_source : 185f5d6f5a3c8306761860c579eff10d931f3b35 --- layout/generic/nsBlockFrame.cpp | 18 +++++++++--------- layout/generic/nsFlexContainerFrame.cpp | 6 +++--- layout/generic/nsGridContainerFrame.cpp | 12 ++++++------ layout/generic/nsIFrame.h | 3 --- layout/generic/nsInlineFrame.cpp | 4 ++-- layout/generic/nsRubyBaseContainerFrame.cpp | 2 +- layout/tables/nsTableCellFrame.cpp | 2 +- layout/tables/nsTableRowFrame.cpp | 2 +- layout/tables/nsTableRowGroupFrame.cpp | 2 +- 9 files changed, 24 insertions(+), 27 deletions(-) diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index 43dd7077c62d..b89743557b96 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -1269,7 +1269,7 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext, if (NS_UNCONSTRAINEDSIZE != reflowInput->AvailableBSize() && state.mReflowStatus.IsComplete() && state.FloatManager()->ClearContinues(FindTrailingClear())) { - NS_FRAME_SET_INCOMPLETE(state.mReflowStatus); + state.mReflowStatus.SetIncomplete(); } if (!state.mReflowStatus.IsFullyComplete()) { @@ -2578,7 +2578,7 @@ nsBlockFrame::ReflowDirtyLines(BlockReflowInput& aState) if (IS_TRUE_OVERFLOW_CONTAINER(aState.mNextInFlow)) NS_FRAME_SET_OVERFLOW_INCOMPLETE(aState.mReflowStatus); else - NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus); + aState.mReflowStatus.SetIncomplete(); } if (!skipPull && aState.mNextInFlow) { @@ -2655,7 +2655,7 @@ nsBlockFrame::ReflowDirtyLines(BlockReflowInput& aState) if (aState.mReflowInput.WillReflowAgainForClearance()) { line->MarkDirty(); keepGoing = false; - NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus); + aState.mReflowStatus.SetIncomplete(); break; } @@ -3407,7 +3407,7 @@ nsBlockFrame::ReflowBlockFrame(BlockReflowInput& aState, aState.mReflowStatus = NS_INLINE_LINE_BREAK_BEFORE(); } else { PushLines(aState, aLine.prev()); - NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus); + aState.mReflowStatus.SetIncomplete(); } return; } @@ -3584,7 +3584,7 @@ nsBlockFrame::ReflowBlockFrame(BlockReflowInput& aState, aState.mReflowStatus = NS_INLINE_LINE_BREAK_BEFORE(); } else { PushLines(aState, aLine.prev()); - NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus); + aState.mReflowStatus.SetIncomplete(); } } else { @@ -3660,7 +3660,7 @@ nsBlockFrame::ReflowBlockFrame(BlockReflowInput& aState, } PushLines(aState, aLine); - NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus); + aState.mReflowStatus.SetIncomplete(); // If we need to reflow the continuation of the block child, // then we'd better reflow our continuation @@ -3760,7 +3760,7 @@ nsBlockFrame::ReflowBlockFrame(BlockReflowInput& aState, // Push the line that didn't fit and any lines that follow it // to our next-in-flow. PushLines(aState, aLine.prev()); - NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus); + aState.mReflowStatus.SetIncomplete(); } } } @@ -3863,7 +3863,7 @@ nsBlockFrame::PushTruncatedLine(BlockReflowInput& aState, { PushLines(aState, aLine.prev()); *aKeepReflowGoing = false; - NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus); + aState.mReflowStatus.SetIncomplete(); } void @@ -7431,7 +7431,7 @@ nsBlockFrame::ComputeFinalBSize(const ReflowInput& aReflowInput, // border/padding to the next page/column. aFinalSize.BSize(wm) = std::max(aReflowInput.AvailableBSize(), aContentBSize); - NS_FRAME_SET_INCOMPLETE(*aStatus); + aStatus->SetIncomplete(); if (!GetNextInFlow()) *aStatus |= NS_FRAME_REFLOW_NEXTINFLOW; } diff --git a/layout/generic/nsFlexContainerFrame.cpp b/layout/generic/nsFlexContainerFrame.cpp index ada317c402dd..18ef5824a975 100644 --- a/layout/generic/nsFlexContainerFrame.cpp +++ b/layout/generic/nsFlexContainerFrame.cpp @@ -3903,7 +3903,7 @@ ResolveFlexContainerMainSize(const ReflowInput& aReflowInput, // XXXdholbert For now, we don't support pushing children to our next // continuation or splitting children, so "amount of BSize required by // our children" is just the main-size (BSize) of our longest flex line. - NS_FRAME_SET_INCOMPLETE(aStatus); + aStatus.SetIncomplete(); nscoord largestLineOuterSize = GetLargestLineMainSize(aFirstLine); if (largestLineOuterSize <= aAvailableBSizeForContent) { @@ -3963,7 +3963,7 @@ nsFlexContainerFrame::ComputeCrossSize(const ReflowInput& aReflowInput, // XXXdholbert For now, we don't support pushing children to our next // continuation or splitting children, so "amount of BSize required by // our children" is just the sum of our FlexLines' BSizes (cross sizes). - NS_FRAME_SET_INCOMPLETE(aStatus); + aStatus.SetIncomplete(); if (aSumLineCrossSizes <= aAvailableBSizeForContent) { return aAvailableBSizeForContent; } @@ -4638,7 +4638,7 @@ nsFlexContainerFrame::DoFlexLayout(nsPresContext* aPresContext, desiredSizeInFlexWM.BSize(flexWM) = desiredBSizeWithBEndBP; } else { // We couldn't fit bottom border/padding, so we'll need a continuation. - NS_FRAME_SET_INCOMPLETE(aStatus); + aStatus.SetIncomplete(); } } diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index b528ad0358f8..11ab0b64fe4c 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -100,12 +100,12 @@ ClampToCSSMaxBSize(nscoord aSize, const ReflowInput* aReflowInput, if (MOZ_UNLIKELY(maxSize != NS_UNCONSTRAINEDSIZE)) { MOZ_ASSERT(aReflowInput->ComputedMinBSize() <= maxSize); if (aSize < maxSize) { - NS_FRAME_SET_INCOMPLETE(*aStatus); + aStatus->SetIncomplete(); } else { aSize = maxSize; } } else { - NS_FRAME_SET_INCOMPLETE(*aStatus); + aStatus->SetIncomplete(); } return aSize; } @@ -5485,7 +5485,7 @@ nsGridContainerFrame::ReflowInFragmentainer(GridReflowInput& aState, // box-decoration-break:clone then we are technically COMPLETE. There's // no point in creating another zero-bsize fragment in this case. if (newBSize < bSize || !isBDBClone) { - NS_FRAME_SET_INCOMPLETE(aStatus); + aStatus.SetIncomplete(); } bSize = newBSize; } else if (bSize <= bEndRow && startRow + 1 < endRow) { @@ -5499,7 +5499,7 @@ nsGridContainerFrame::ReflowInFragmentainer(GridReflowInput& aState, bSize = ClampToCSSMaxBSize(bSize, aState.mReflowInput); } } - NS_FRAME_SET_INCOMPLETE(aStatus); + aStatus.SetIncomplete(); } else if (endRow < numRows) { bSize = ClampToCSSMaxBSize(bEndRow, aState.mReflowInput, &aStatus); } // else - no break opportunities. @@ -5670,14 +5670,14 @@ nsGridContainerFrame::ReflowRowsInFragmentainer( isRowTopOfPage = isStartRowTopOfPage; overflowIncompleteItems.Clear(); incompleteItems.Clear(); - NS_FRAME_SET_INCOMPLETE(aStatus); + aStatus.SetIncomplete(); continue; } NS_ERROR("got BREAK_BEFORE at top-of-page"); childStatus = NS_FRAME_COMPLETE; } else { NS_ERROR("got BREAK_BEFORE again after growing the row?"); - NS_FRAME_SET_INCOMPLETE(childStatus); + childStatus.SetIncomplete(); } } else if (NS_INLINE_IS_BREAK_AFTER(childStatus)) { MOZ_ASSERT_UNREACHABLE("unexpected child reflow status"); diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index c91302a183b8..f0d30fd31870 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -305,9 +305,6 @@ private: // These macros set or switch incomplete statuses without touching the // NS_FRAME_REFLOW_NEXTINFLOW bit. -#define NS_FRAME_SET_INCOMPLETE(status) \ - status = (status & ~NS_FRAME_OVERFLOW_INCOMPLETE) | NS_FRAME_NOT_COMPLETE - #define NS_FRAME_SET_OVERFLOW_INCOMPLETE(status) \ status = (status & ~NS_FRAME_NOT_COMPLETE) | NS_FRAME_OVERFLOW_INCOMPLETE diff --git a/layout/generic/nsInlineFrame.cpp b/layout/generic/nsInlineFrame.cpp index 386a3ec5fbe5..95c1f3a1505e 100644 --- a/layout/generic/nsInlineFrame.cpp +++ b/layout/generic/nsInlineFrame.cpp @@ -829,7 +829,7 @@ nsInlineFrame::ReflowInlineFrame(nsPresContext* aPresContext, if (NS_INLINE_IS_BREAK_AFTER(aStatus)) { nsIFrame* nextFrame = aFrame->GetNextSibling(); if (nextFrame) { - NS_FRAME_SET_INCOMPLETE(aStatus); + aStatus.SetIncomplete(); PushFrames(aPresContext, nextFrame, aFrame, irs); } else { @@ -838,7 +838,7 @@ nsInlineFrame::ReflowInlineFrame(nsPresContext* aPresContext, nsInlineFrame* nextInFlow = static_cast(GetNextInFlow()); while (nextInFlow) { if (nextInFlow->mFrames.NotEmpty()) { - NS_FRAME_SET_INCOMPLETE(aStatus); + aStatus.SetIncomplete(); break; } nextInFlow = static_cast(nextInFlow->GetNextInFlow()); diff --git a/layout/generic/nsRubyBaseContainerFrame.cpp b/layout/generic/nsRubyBaseContainerFrame.cpp index 9a417f27f44d..2f071ca20cb9 100644 --- a/layout/generic/nsRubyBaseContainerFrame.cpp +++ b/layout/generic/nsRubyBaseContainerFrame.cpp @@ -517,7 +517,7 @@ nsRubyBaseContainerFrame::ReflowColumns(const RubyReflowInput& aReflowInput, reflowStatus = NS_INLINE_LINE_BREAK_BEFORE(); } if (!e.AtEnd() || (GetNextInFlow() && !isComplete)) { - NS_FRAME_SET_INCOMPLETE(aStatus); + aStatus.SetIncomplete(); } if (NS_INLINE_IS_BREAK_BEFORE(reflowStatus)) { diff --git a/layout/tables/nsTableCellFrame.cpp b/layout/tables/nsTableCellFrame.cpp index 69454539aa67..6a9cd02c9a4a 100644 --- a/layout/tables/nsTableCellFrame.cpp +++ b/layout/tables/nsTableCellFrame.cpp @@ -960,7 +960,7 @@ nsTableCellFrame::Reflow(nsPresContext* aPresContext, if (aStatus.IsOverflowIncomplete()) { // Don't pass OVERFLOW_INCOMPLETE through tables until they can actually handle it //XXX should paginate overflow as overflow, but not in this patch (bug 379349) - NS_FRAME_SET_INCOMPLETE(aStatus); + aStatus.SetIncomplete(); printf("Set table cell incomplete %p\n", static_cast(this)); } diff --git a/layout/tables/nsTableRowFrame.cpp b/layout/tables/nsTableRowFrame.cpp index b3447338f480..78584b8d0a8b 100644 --- a/layout/tables/nsTableRowFrame.cpp +++ b/layout/tables/nsTableRowFrame.cpp @@ -1061,7 +1061,7 @@ nsTableRowFrame::ReflowChildren(nsPresContext* aPresContext, nscoord styleBSize = CalcBSizeFromUnpaginatedBSize(*this, wm); if (styleBSize > aReflowInput.AvailableBSize()) { styleBSize = aReflowInput.AvailableBSize(); - NS_FRAME_SET_INCOMPLETE(aStatus); + aStatus.SetIncomplete(); } aDesiredSize.BSize(wm) = std::max(cellMaxBSize, styleBSize); } diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp index 8982a3ba020b..c4478bba3b47 100644 --- a/layout/tables/nsTableRowGroupFrame.cpp +++ b/layout/tables/nsTableRowGroupFrame.cpp @@ -1407,7 +1407,7 @@ nsTableRowGroupFrame::Reflow(nsPresContext* aPresContext, // ReflowChildren should pull up rows from our next-in-flow before returning // a Complete status, but doesn't (bug 804888). if (GetNextInFlow() && GetNextInFlow()->PrincipalChildList().FirstChild()) { - NS_FRAME_SET_INCOMPLETE(aStatus); + aStatus.SetIncomplete(); } SetHasStyleBSize((NS_UNCONSTRAINEDSIZE != aReflowInput.ComputedBSize()) && From b7c479e1c2be44a45d5585ef857468ccc374ab3d Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Sat, 11 Feb 2017 23:18:04 +0800 Subject: [PATCH 093/234] Bug 775624 Part 8 - Remove NS_FRAME_SET_OVERFLOW_INCOMPLETE. r=dholbert This patch is written by the help of the following script. function rename() { find layout\ -type f\ \( -name "*.cpp" -or\ -name "*.h" \)\ -exec sed -i -r "s/$1/$2/g" "{}" \; } rename "NS_FRAME_SET_OVERFLOW_INCOMPLETE\(\*([a-zA-Z0-9.*]*)\)" "\1->SetOverflowIncomplete()" rename "NS_FRAME_SET_OVERFLOW_INCOMPLETE\(([a-zA-Z0-9.*]*)\)" "\1.SetOverflowIncomplete()" MozReview-Commit-ID: EJOIs84vwev --HG-- extra : rebase_source : 59a5ac827f57e7a0e50910f5a813c44560baeb00 --- layout/generic/BlockReflowInput.cpp | 2 +- layout/generic/nsAbsoluteContainingBlock.cpp | 2 +- layout/generic/nsBlockFrame.cpp | 8 ++++---- layout/generic/nsContainerFrame.cpp | 2 +- layout/generic/nsGridContainerFrame.cpp | 6 +++--- layout/generic/nsIFrame.h | 5 ----- 6 files changed, 10 insertions(+), 15 deletions(-) diff --git a/layout/generic/BlockReflowInput.cpp b/layout/generic/BlockReflowInput.cpp index e11776b1657f..32a13f2d07e4 100644 --- a/layout/generic/BlockReflowInput.cpp +++ b/layout/generic/BlockReflowInput.cpp @@ -1053,7 +1053,7 @@ BlockReflowInput::PushFloatPastBreak(nsIFrame *aFloat) DebugOnly rv = mBlock->StealFrame(aFloat); NS_ASSERTION(NS_SUCCEEDED(rv), "StealFrame should succeed"); AppendPushedFloatChain(aFloat); - NS_FRAME_SET_OVERFLOW_INCOMPLETE(mReflowStatus); + mReflowStatus.SetOverflowIncomplete(); } /** diff --git a/layout/generic/nsAbsoluteContainingBlock.cpp b/layout/generic/nsAbsoluteContainingBlock.cpp index 36185397ce50..909ef933cd87 100644 --- a/layout/generic/nsAbsoluteContainingBlock.cpp +++ b/layout/generic/nsAbsoluteContainingBlock.cpp @@ -192,7 +192,7 @@ nsAbsoluteContainingBlock::Reflow(nsContainerFrame* aDelegatingFrame, // Abspos frames can't cause their parent to be incomplete, // only overflow incomplete. if (reflowStatus.IsIncomplete()) - NS_FRAME_SET_OVERFLOW_INCOMPLETE(reflowStatus); + reflowStatus.SetOverflowIncomplete(); NS_MergeReflowStatusInto(&aReflowStatus, reflowStatus); } diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index b89743557b96..645b1a744a30 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -1663,7 +1663,7 @@ nsBlockFrame::ComputeFinalSize(const ReflowInput& aReflowInput, // Note that auto height overflow containers have no normal children NS_ASSERTION(finalSize.BSize(wm) == 0, "overflow containers must be zero-block-size"); - NS_FRAME_SET_OVERFLOW_INCOMPLETE(aState.mReflowStatus); + aState.mReflowStatus.SetOverflowIncomplete(); } } else if (aReflowInput.AvailableBSize() != NS_UNCONSTRAINEDSIZE && !NS_INLINE_IS_BREAK_BEFORE(aState.mReflowStatus) && @@ -2576,7 +2576,7 @@ nsBlockFrame::ReflowDirtyLines(BlockReflowInput& aState) if (skipPull && aState.mNextInFlow) { NS_ASSERTION(heightConstrained, "Height should be constrained here\n"); if (IS_TRUE_OVERFLOW_CONTAINER(aState.mNextInFlow)) - NS_FRAME_SET_OVERFLOW_INCOMPLETE(aState.mReflowStatus); + aState.mReflowStatus.SetOverflowIncomplete(); else aState.mReflowStatus.SetIncomplete(); } @@ -4324,7 +4324,7 @@ nsBlockFrame::SplitFloat(BlockReflowInput& aState, } aState.AppendPushedFloatChain(nextInFlow); - NS_FRAME_SET_OVERFLOW_INCOMPLETE(aState.mReflowStatus); + aState.mReflowStatus.SetOverflowIncomplete(); return NS_OK; } @@ -7413,7 +7413,7 @@ nsBlockFrame::ComputeFinalBSize(const ReflowInput& aReflowInput, // We fit in the available space - change status to OVERFLOW_INCOMPLETE. // XXXmats why didn't Reflow report OVERFLOW_INCOMPLETE in the first place? // XXXmats and why exclude the case when our size == AvailableBSize? - NS_FRAME_SET_OVERFLOW_INCOMPLETE(*aStatus); + aStatus->SetOverflowIncomplete(); } if (aStatus->IsComplete()) { diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp index 470d05fcf005..3851d7249ca6 100644 --- a/layout/generic/nsContainerFrame.cpp +++ b/layout/generic/nsContainerFrame.cpp @@ -1284,7 +1284,7 @@ nsContainerFrame::ReflowOverflowContainerChildren(nsPresContext* aPres if (frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) { // Abspos frames can't cause their parent to be incomplete, // only overflow incomplete. - NS_FRAME_SET_OVERFLOW_INCOMPLETE(frameStatus); + frameStatus.SetOverflowIncomplete(); } else { NS_ASSERTION(frameStatus.IsComplete(), diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index 11ab0b64fe4c..b1a9d3bb1aad 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -5517,7 +5517,7 @@ nsGridContainerFrame::ReflowInFragmentainer(GridReflowInput& aState, if (endRow < numRows) { childAvailableSize = bEndRow; if (aStatus.IsComplete()) { - NS_FRAME_SET_OVERFLOW_INCOMPLETE(aStatus); + aStatus.SetOverflowIncomplete(); aStatus |= NS_FRAME_REFLOW_NEXTINFLOW; } } else { @@ -5703,7 +5703,7 @@ nsGridContainerFrame::ReflowRowsInFragmentainer( !incompleteItems.IsEmpty() || !overflowIncompleteItems.IsEmpty()) { if (aStatus.IsComplete()) { - NS_FRAME_SET_OVERFLOW_INCOMPLETE(aStatus); + aStatus.SetOverflowIncomplete(); aStatus |= NS_FRAME_REFLOW_NEXTINFLOW; } // Iterate the children in normal document order and append them (or a NIF) @@ -6173,7 +6173,7 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext, // Convert INCOMPLETE -> OVERFLOW_INCOMPLETE and zero bsize if we're an OC. if (HasAnyStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER)) { if (!aStatus.IsComplete()) { - NS_FRAME_SET_OVERFLOW_INCOMPLETE(aStatus); + aStatus.SetOverflowIncomplete(); aStatus |= NS_FRAME_REFLOW_NEXTINFLOW; } bSize = 0; diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index f0d30fd31870..66db1e85aed5 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -303,11 +303,6 @@ private: #define NS_FRAME_REFLOW_NEXTINFLOW 0x2 #define NS_FRAME_OVERFLOW_INCOMPLETE 0x4 -// These macros set or switch incomplete statuses without touching the -// NS_FRAME_REFLOW_NEXTINFLOW bit. -#define NS_FRAME_SET_OVERFLOW_INCOMPLETE(status) \ - status = (status & ~NS_FRAME_NOT_COMPLETE) | NS_FRAME_OVERFLOW_INCOMPLETE - // This bit is set, when a break is requested. This bit is orthogonal // to the nsIFrame::nsReflowStatus completion bits. #define NS_INLINE_BREAK 0x0100 From 11579e0ce54dcbe0f1c293e1747b563c52e6a95b Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Mon, 13 Feb 2017 14:56:45 +0800 Subject: [PATCH 094/234] Bug 775624 Part 9 - Convert NS_FRAME_REFLOW_NEXTINFLOW to use bit-field and methods. r=dholbert MozReview-Commit-ID: 1TXOShK62X8 --HG-- extra : rebase_source : df0b26da3aefc239f11c28ccc746062e88ab86a3 --- layout/generic/nsBlockFrame.cpp | 20 ++++++++++---------- layout/generic/nsCanvasFrame.cpp | 2 +- layout/generic/nsColumnSetFrame.cpp | 10 +++++----- layout/generic/nsContainerFrame.cpp | 8 ++++---- layout/generic/nsContainerFrame.h | 2 +- layout/generic/nsFrame.cpp | 2 +- layout/generic/nsGridContainerFrame.cpp | 6 +++--- layout/generic/nsIFrame.h | 23 ++++++++++------------- 8 files changed, 35 insertions(+), 38 deletions(-) diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index 645b1a744a30..5cc026c0bac0 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -1274,7 +1274,7 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext, if (!state.mReflowStatus.IsFullyComplete()) { if (HasOverflowLines() || HasPushedFloats()) { - state.mReflowStatus |= NS_FRAME_REFLOW_NEXTINFLOW; + state.mReflowStatus.SetNextInFlowNeedsReflow(); } #ifdef DEBUG_kipp @@ -2684,7 +2684,7 @@ nsBlockFrame::ReflowDirtyLines(BlockReflowInput& aState) } if (aState.mReflowStatus.IsIncomplete()) { - aState.mReflowStatus |= NS_FRAME_REFLOW_NEXTINFLOW; + aState.mReflowStatus.SetNextInFlowNeedsReflow(); } //XXXfr shouldn't set this flag when nextinflow has no lines } @@ -3650,7 +3650,7 @@ nsBlockFrame::ReflowBlockFrame(BlockReflowInput& aState, mFrames.InsertFrame(nullptr, frame, nextFrame); madeContinuation = true; // needs to be added to mLines nextFrame->RemoveStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER); - frameReflowStatus |= NS_FRAME_REFLOW_NEXTINFLOW; + frameReflowStatus.SetNextInFlowNeedsReflow(); } // Push continuation to a new line, but only if we actually made one. @@ -3664,8 +3664,8 @@ nsBlockFrame::ReflowBlockFrame(BlockReflowInput& aState, // If we need to reflow the continuation of the block child, // then we'd better reflow our continuation - if (frameReflowStatus & NS_FRAME_REFLOW_NEXTINFLOW) { - aState.mReflowStatus |= NS_FRAME_REFLOW_NEXTINFLOW; + if (frameReflowStatus.NextInFlowNeedsReflow()) { + aState.mReflowStatus.SetNextInFlowNeedsReflow(); // We also need to make that continuation's line dirty so // it gets reflowed when we reflow our next in flow. The // nif's line must always be either a line of the nif's @@ -4107,7 +4107,7 @@ nsBlockFrame::DoReflowInlineFrames(BlockReflowInput& aState, if (iter.Next() && iter.GetLine()->IsInline()) { iter.GetLine()->MarkDirty(); if (iter.GetContainer() != this) { - aState.mReflowStatus |= NS_FRAME_REFLOW_NEXTINFLOW; + aState.mReflowStatus.SetNextInFlowNeedsReflow(); } } } @@ -4150,7 +4150,7 @@ nsBlockFrame::ReflowInlineFrame(BlockReflowInput& aState, bool pushedFrame; aLineLayout.ReflowFrame(aFrame, frameReflowStatus, nullptr, pushedFrame); - if (frameReflowStatus & NS_FRAME_REFLOW_NEXTINFLOW) { + if (frameReflowStatus.NextInFlowNeedsReflow()) { aLineLayout.SetDirtyNextLine(); } @@ -6283,8 +6283,8 @@ nsBlockFrame::ReflowFloat(BlockReflowInput& aState, aReflowStatus = NS_FRAME_COMPLETE; } - if (aReflowStatus & NS_FRAME_REFLOW_NEXTINFLOW) { - aState.mReflowStatus |= NS_FRAME_REFLOW_NEXTINFLOW; + if (aReflowStatus.NextInFlowNeedsReflow()) { + aState.mReflowStatus.SetNextInFlowNeedsReflow(); } if (aFloat->GetType() == nsGkAtoms::letterFrame) { @@ -7433,7 +7433,7 @@ nsBlockFrame::ComputeFinalBSize(const ReflowInput& aReflowInput, aContentBSize); aStatus->SetIncomplete(); if (!GetNextInFlow()) - *aStatus |= NS_FRAME_REFLOW_NEXTINFLOW; + aStatus->SetNextInFlowNeedsReflow(); } } } diff --git a/layout/generic/nsCanvasFrame.cpp b/layout/generic/nsCanvasFrame.cpp index 352b3898dbc5..8bb48d772e0a 100644 --- a/layout/generic/nsCanvasFrame.cpp +++ b/layout/generic/nsCanvasFrame.cpp @@ -717,7 +717,7 @@ nsCanvasFrame::Reflow(nsPresContext* aPresContext, if (!aStatus.IsFullyComplete()) { nsIFrame* nextFrame = kidFrame->GetNextInFlow(); - NS_ASSERTION(nextFrame || aStatus & NS_FRAME_REFLOW_NEXTINFLOW, + NS_ASSERTION(nextFrame || aStatus.NextInFlowNeedsReflow(), "If it's incomplete and has no nif yet, it must flag a nif reflow."); if (!nextFrame) { nextFrame = aPresContext->PresShell()->FrameConstructor()-> diff --git a/layout/generic/nsColumnSetFrame.cpp b/layout/generic/nsColumnSetFrame.cpp index 89bbb996642a..885eea948f9d 100644 --- a/layout/generic/nsColumnSetFrame.cpp +++ b/layout/generic/nsColumnSetFrame.cpp @@ -648,7 +648,7 @@ nsColumnSetFrame::ReflowChildren(ReflowOutput& aDesiredSize, ReflowChild(child, PresContext(), kidDesiredSize, kidReflowInput, wm, origin, containerSize, 0, aStatus); - reflowNext = (aStatus & NS_FRAME_REFLOW_NEXTINFLOW) != 0; + reflowNext = aStatus.NextInFlowNeedsReflow(); #ifdef DEBUG_roc printf("*** Reflowed child #%d %p: status = %d, desiredSize=%d,%d CarriedOutBEndMargin=%d\n", @@ -694,7 +694,7 @@ nsColumnSetFrame::ReflowChildren(ReflowOutput& aDesiredSize, // going to put it on our overflow list and let *our* // next in flow handle it. if (!kidNextInFlow) { - NS_ASSERTION(aStatus & NS_FRAME_REFLOW_NEXTINFLOW, + NS_ASSERTION(aStatus.NextInFlowNeedsReflow(), "We have to create a continuation, but the block doesn't want us to reflow it?"); // We need to create a continuing column @@ -705,13 +705,13 @@ nsColumnSetFrame::ReflowChildren(ReflowOutput& aDesiredSize, // normal or overflow container if (aStatus.IsOverflowIncomplete()) { if (!(kidNextInFlow->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER)) { - aStatus |= NS_FRAME_REFLOW_NEXTINFLOW; + aStatus.SetNextInFlowNeedsReflow(); reflowNext = true; kidNextInFlow->AddStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER); } } else if (kidNextInFlow->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER) { - aStatus |= NS_FRAME_REFLOW_NEXTINFLOW; + aStatus.SetNextInFlowNeedsReflow(); reflowNext = true; kidNextInFlow->RemoveStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER); } @@ -727,7 +727,7 @@ nsColumnSetFrame::ReflowChildren(ReflowOutput& aDesiredSize, if (columnCount >= aConfig.mBalanceColCount) { // No more columns allowed here. Stop. - aStatus |= NS_FRAME_REFLOW_NEXTINFLOW; + aStatus.SetNextInFlowNeedsReflow(); kidNextInFlow->AddStateBits(NS_FRAME_IS_DIRTY); // Move any of our leftover columns to our overflow list. Our // next-in-flow will eventually pick them up. diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp index 3851d7249ca6..fe029ccc6895 100644 --- a/layout/generic/nsContainerFrame.cpp +++ b/layout/generic/nsContainerFrame.cpp @@ -1294,8 +1294,8 @@ nsContainerFrame::ReflowOverflowContainerChildren(nsPresContext* aPres // Acquire a next-in-flow, creating it if necessary nsIFrame* nif = frame->GetNextInFlow(); if (!nif) { - NS_ASSERTION(frameStatus & NS_FRAME_REFLOW_NEXTINFLOW, - "Someone forgot a REFLOW_NEXTINFLOW flag"); + NS_ASSERTION(frameStatus.NextInFlowNeedsReflow(), + "Someone forgot a NextInFlowNeedsReflow flag"); nif = aPresContext->PresShell()->FrameConstructor()-> CreateContinuingFrame(aPresContext, frame, this); } @@ -2195,11 +2195,11 @@ nsOverflowContinuationTracker::Insert(nsIFrame* aOverflowCont, } mOverflowContList->InsertFrame(mParent, mPrevOverflowCont, aOverflowCont); - aReflowStatus |= NS_FRAME_REFLOW_NEXTINFLOW; + aReflowStatus.SetNextInFlowNeedsReflow(); } // If we need to reflow it, mark it dirty - if (aReflowStatus & NS_FRAME_REFLOW_NEXTINFLOW) + if (aReflowStatus.NextInFlowNeedsReflow()) aOverflowCont->AddStateBits(NS_FRAME_IS_DIRTY); // It's in our list, just step forward diff --git a/layout/generic/nsContainerFrame.h b/layout/generic/nsContainerFrame.h index 0eb315cd70c8..27287910ff30 100644 --- a/layout/generic/nsContainerFrame.h +++ b/layout/generic/nsContainerFrame.h @@ -377,7 +377,7 @@ public: * 2. Reflows all our overflow container kids * 3. Expands aOverflowRect as necessary to accomodate these children. * 4. Sets aStatus's mOverflowIncomplete flag (along with - * NS_FRAME_REFLOW_NEXTINFLOW as necessary) if any overflow children + * mNextInFlowNeedsReflow as necessary) if any overflow children * are incomplete and * 5. Prepends a list of their continuations to our excess overflow * container list, to be drained into our next-in-flow when it is diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 757fe0244ecc..e1e3a3be58db 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -10341,7 +10341,7 @@ nsFrame::Trace(const char* aMethod, bool aEnter, nsReflowStatus aStatus) PR_LogPrint("%s: %s %s, status=%scomplete%s", tagbuf, aEnter ? "enter" : "exit", aMethod, aStatus.IsIncomplete() ? "not" : "", - (aStatus & NS_FRAME_REFLOW_NEXTINFLOW) ? "+reflow" : ""); + (aStatus.NextInFlowNeedsReflow()) ? "+reflow" : ""); } } diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index b1a9d3bb1aad..cbba7cbbf0dc 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -5518,7 +5518,7 @@ nsGridContainerFrame::ReflowInFragmentainer(GridReflowInput& aState, childAvailableSize = bEndRow; if (aStatus.IsComplete()) { aStatus.SetOverflowIncomplete(); - aStatus |= NS_FRAME_REFLOW_NEXTINFLOW; + aStatus.SetNextInFlowNeedsReflow(); } } else { // Children always have the full size of the rows in this fragment. @@ -5704,7 +5704,7 @@ nsGridContainerFrame::ReflowRowsInFragmentainer( !overflowIncompleteItems.IsEmpty()) { if (aStatus.IsComplete()) { aStatus.SetOverflowIncomplete(); - aStatus |= NS_FRAME_REFLOW_NEXTINFLOW; + aStatus.SetNextInFlowNeedsReflow(); } // Iterate the children in normal document order and append them (or a NIF) // to one of the following frame lists according to their status. @@ -6174,7 +6174,7 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext, if (HasAnyStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER)) { if (!aStatus.IsComplete()) { aStatus.SetOverflowIncomplete(); - aStatus |= NS_FRAME_REFLOW_NEXTINFLOW; + aStatus.SetNextInFlowNeedsReflow(); } bSize = 0; desiredSize.BSize(wm) = bSize + bp.BStartEnd(wm); diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 66db1e85aed5..ca9e2cdd9680 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -195,19 +195,6 @@ enum nsSpread { #define NS_CARRIED_BOTTOM_MARGIN_IS_AUTO 0x2 //---------------------------------------------------------------------- - -/** - * NS_FRAME_REFLOW_NEXTINFLOW bit flag means that the next-in-flow is - * dirty, and also needs to be reflowed. This status only makes sense - * for a frame that is not complete, i.e. you wouldn't set both - * NS_FRAME_COMPLETE and NS_FRAME_REFLOW_NEXTINFLOW. - * - * The low 8 bits of the nsReflowStatus are reserved for future extensions; - * the remaining 24 bits are zero (and available for extensions; however - * API's that accept/return nsReflowStatus must not receive/return any - * extension bits). - */ - // Reflow status returned by the Reflow() methods. class nsReflowStatus final { public: @@ -215,12 +202,14 @@ public: : mStatus(0) , mIncomplete(false) , mOverflowIncomplete(false) + , mNextInFlowNeedsReflow(false) {} // Reset all the bit-fields. void Reset() { mIncomplete = false; mOverflowIncomplete = false; + mNextInFlowNeedsReflow = false; } nsReflowStatus(uint32_t aStatus) @@ -290,12 +279,20 @@ public: mOverflowIncomplete = true; } + // mNextInFlowNeedsReflow bit flag means that the next-in-flow is dirty, + // and also needs to be reflowed. This status only makes sense for a frame + // that is not complete, i.e. you wouldn't set mNextInFlowNeedsReflow when + // IsComplete() is true. + bool NextInFlowNeedsReflow() const { return mNextInFlowNeedsReflow; } + void SetNextInFlowNeedsReflow() { mNextInFlowNeedsReflow = true; } + private: uint32_t mStatus; // Frame completion status bit flags. bool mIncomplete : 1; bool mOverflowIncomplete : 1; + bool mNextInFlowNeedsReflow : 1; }; #define NS_FRAME_COMPLETE 0 // Note: not a bit! From e015259441f3f2acceb97c9d18190d60891ea4eb Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Mon, 20 Feb 2017 14:58:58 +0800 Subject: [PATCH 095/234] Bug 775624 Part 10a - Move ReflowInput::SetTruncated() into nsReflowStatus. r=dholbert Per bug 775624 comment 95, the method modifies only nsReflowStatus, and is lived in ReflowInput only because nsReflowStatus was an uint32_t. So it's better to move it into nsReflowStatus. MozReview-Commit-ID: DSY2u9az67A --HG-- extra : rebase_source : dcf9404d40043a749edcad2cb969f1227a300936 --- layout/generic/ReflowInput.cpp | 18 ------------------ layout/generic/nsFrame.cpp | 18 ++++++++++++++++++ layout/generic/nsIFrame.h | 7 +++++-- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/layout/generic/ReflowInput.cpp b/layout/generic/ReflowInput.cpp index c23d872057b7..b6d1c120482c 100644 --- a/layout/generic/ReflowInput.cpp +++ b/layout/generic/ReflowInput.cpp @@ -3041,24 +3041,6 @@ ReflowInput::ComputeMinMaxValues(const LogicalSize&aCBSize) } } -void -ReflowInput::SetTruncated(const ReflowOutput& aMetrics, - nsReflowStatus* aStatus) const -{ - const WritingMode containerWM = aMetrics.GetWritingMode(); - if (GetWritingMode().IsOrthogonalTo(containerWM)) { - // Orthogonal flows are always reflowed with an unconstrained dimension, - // so should never end up truncated (see ReflowInput::Init()). - *aStatus &= ~NS_FRAME_TRUNCATED; - } else if (AvailableBSize() != NS_UNCONSTRAINEDSIZE && - AvailableBSize() < aMetrics.BSize(containerWM) && - !mFlags.mIsTopOfPage) { - *aStatus |= NS_FRAME_TRUNCATED; - } else { - *aStatus &= ~NS_FRAME_TRUNCATED; - } -} - bool ReflowInput::IsFloating() const { diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index e1e3a3be58db..8709238fae8e 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -188,6 +188,24 @@ IsXULBoxWrapped(const nsIFrame* aFrame) !aFrame->IsXULBoxFrame(); } +void +nsReflowStatus::UpdateTruncated(const ReflowInput& aReflowInput, + const ReflowOutput& aMetrics) +{ + const WritingMode containerWM = aMetrics.GetWritingMode(); + if (aReflowInput.GetWritingMode().IsOrthogonalTo(containerWM)) { + // Orthogonal flows are always reflowed with an unconstrained dimension, + // so should never end up truncated (see ReflowInput::Init()). + mStatus &= ~NS_FRAME_TRUNCATED; + } else if (aReflowInput.AvailableBSize() != NS_UNCONSTRAINEDSIZE && + aReflowInput.AvailableBSize() < aMetrics.BSize(containerWM) && + !aReflowInput.mFlags.mIsTopOfPage) { + mStatus |= NS_FRAME_TRUNCATED; + } else { + mStatus &= ~NS_FRAME_TRUNCATED; + } +} + // Formerly the nsIFrameDebug interface #ifdef DEBUG diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index ca9e2cdd9680..b00680875e6e 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -286,6 +286,9 @@ public: bool NextInFlowNeedsReflow() const { return mNextInFlowNeedsReflow; } void SetNextInFlowNeedsReflow() { mNextInFlowNeedsReflow = true; } + void UpdateTruncated(const mozilla::ReflowInput& aReflowInput, + const mozilla::ReflowOutput& aMetrics); + private: uint32_t mStatus; @@ -357,8 +360,8 @@ private: #define NS_FRAME_TRUNCATED 0x0010 #define NS_FRAME_IS_TRUNCATED(status) \ (0 != ((status) & NS_FRAME_TRUNCATED)) -#define NS_FRAME_SET_TRUNCATION(status, aReflowInput, aMetrics) \ - aReflowInput.SetTruncated(aMetrics, &status); +#define NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aMetrics) \ + aStatus.UpdateTruncated(aReflowInput, aMetrics); // Merge the incompleteness, truncation and NS_FRAME_REFLOW_NEXTINFLOW // status from aSecondary into aPrimary. From a4633d568d2247a517a59732793ca538ca3d7658 Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Mon, 13 Feb 2017 16:16:44 +0800 Subject: [PATCH 096/234] Bug 775624 Part 10b - Convert NS_FRAME_TRUNCATED to use bit-field and methods. r=dholbert NS_FRAME_TRUNCATED will be removed when NS_MergeReflowStatusInto() is removed. MozReview-Commit-ID: 21lit9xSAE1 --HG-- extra : rebase_source : 7933575a2f4d3c8ccff5d717fca1ddd8c7c9e482 --- layout/generic/BlockReflowInput.cpp | 4 ++-- layout/generic/nsColumnSetFrame.cpp | 6 +++--- layout/generic/nsFrame.cpp | 6 +++--- layout/generic/nsIFrame.h | 17 ++++++++++------- layout/tables/nsTableRowFrame.cpp | 2 +- 5 files changed, 19 insertions(+), 16 deletions(-) diff --git a/layout/generic/BlockReflowInput.cpp b/layout/generic/BlockReflowInput.cpp index 32a13f2d07e4..7bc16989a03a 100644 --- a/layout/generic/BlockReflowInput.cpp +++ b/layout/generic/BlockReflowInput.cpp @@ -920,7 +920,7 @@ BlockReflowInput::FlowAndPlaceFloat(nsIFrame* aFloat) // (controlled by the pref "layout.float-fragments-inside-column.enabled") // // Likewise, if none of the float fit, and it needs to be pushed in - // its entirety to the next page (NS_FRAME_IS_TRUNCATED or + // its entirety to the next page (IsTruncated() or // NS_INLINE_IS_BREAK_BEFORE), we need to do the same. if ((ContentBSize() != NS_UNCONSTRAINEDSIZE && !mFlags.mFloatFragmentsInsideColumnEnabled && @@ -928,7 +928,7 @@ BlockReflowInput::FlowAndPlaceFloat(nsIFrame* aFloat) !mustPlaceFloat && aFloat->BSize(wm) + floatMargin.BStartEnd(wm) > ContentBEnd() - floatPos.B(wm)) || - NS_FRAME_IS_TRUNCATED(reflowStatus) || + reflowStatus.IsTruncated() || NS_INLINE_IS_BREAK_BEFORE(reflowStatus)) { PushFloatPastBreak(aFloat); return false; diff --git a/layout/generic/nsColumnSetFrame.cpp b/layout/generic/nsColumnSetFrame.cpp index 885eea948f9d..548c86d5d0bf 100644 --- a/layout/generic/nsColumnSetFrame.cpp +++ b/layout/generic/nsColumnSetFrame.cpp @@ -683,7 +683,7 @@ nsColumnSetFrame::ReflowChildren(ReflowOutput& aDesiredSize, // Build a continuation column if necessary nsIFrame* kidNextInFlow = child->GetNextInFlow(); - if (aStatus.IsFullyComplete() && !NS_FRAME_IS_TRUNCATED(aStatus)) { + if (aStatus.IsFullyComplete() && !aStatus.IsTruncated()) { NS_ASSERTION(!kidNextInFlow, "next in flow should have been deleted"); child = nullptr; break; @@ -829,10 +829,10 @@ nsColumnSetFrame::ReflowChildren(ReflowOutput& aDesiredSize, #ifdef DEBUG_roc printf("*** DONE PASS feasible=%d\n", allFit && aStatus.IsFullyComplete() - && !NS_FRAME_IS_TRUNCATED(aStatus)); + && !aStatus.IsTruncated()); #endif return allFit && aStatus.IsFullyComplete() - && !NS_FRAME_IS_TRUNCATED(aStatus); + && !aStatus.IsTruncated(); } void diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 8709238fae8e..1dd62b4f7f1e 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -196,13 +196,13 @@ nsReflowStatus::UpdateTruncated(const ReflowInput& aReflowInput, if (aReflowInput.GetWritingMode().IsOrthogonalTo(containerWM)) { // Orthogonal flows are always reflowed with an unconstrained dimension, // so should never end up truncated (see ReflowInput::Init()). - mStatus &= ~NS_FRAME_TRUNCATED; + mTruncated = false; } else if (aReflowInput.AvailableBSize() != NS_UNCONSTRAINEDSIZE && aReflowInput.AvailableBSize() < aMetrics.BSize(containerWM) && !aReflowInput.mFlags.mIsTopOfPage) { - mStatus |= NS_FRAME_TRUNCATED; + mTruncated = true; } else { - mStatus &= ~NS_FRAME_TRUNCATED; + mTruncated = false; } } diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index b00680875e6e..29a5b7746a8e 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -203,6 +203,7 @@ public: , mIncomplete(false) , mOverflowIncomplete(false) , mNextInFlowNeedsReflow(false) + , mTruncated(false) {} // Reset all the bit-fields. @@ -210,6 +211,7 @@ public: mIncomplete = false; mOverflowIncomplete = false; mNextInFlowNeedsReflow = false; + mTruncated = false; } nsReflowStatus(uint32_t aStatus) @@ -286,6 +288,12 @@ public: bool NextInFlowNeedsReflow() const { return mNextInFlowNeedsReflow; } void SetNextInFlowNeedsReflow() { mNextInFlowNeedsReflow = true; } + // mTruncated bit flag means that the part of the frame before the first + // possible break point was unable to fit in the available space. + // Therefore, the entire frame should be moved to the next continuation of + // the parent frame. A frame that begins at the top of the page must never + // be truncated. Doing so would likely cause an infinite loop. + bool IsTruncated() const { return mTruncated; } void UpdateTruncated(const mozilla::ReflowInput& aReflowInput, const mozilla::ReflowOutput& aMetrics); @@ -296,6 +304,7 @@ private: bool mIncomplete : 1; bool mOverflowIncomplete : 1; bool mNextInFlowNeedsReflow : 1; + bool mTruncated : 1; }; #define NS_FRAME_COMPLETE 0 // Note: not a bit! @@ -352,14 +361,8 @@ private: ((_completionStatus) | NS_INLINE_BREAK | NS_INLINE_BREAK_AFTER | \ NS_INLINE_MAKE_BREAK_TYPE(StyleClear::Line)) -// A frame is "truncated" if the part of the frame before the first -// possible break point was unable to fit in the available vertical -// space. Therefore, the entire frame should be moved to the next page. -// A frame that begins at the top of the page must never be "truncated". -// Doing so would likely cause an infinite loop. #define NS_FRAME_TRUNCATED 0x0010 -#define NS_FRAME_IS_TRUNCATED(status) \ - (0 != ((status) & NS_FRAME_TRUNCATED)) + #define NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aMetrics) \ aStatus.UpdateTruncated(aReflowInput, aMetrics); diff --git a/layout/tables/nsTableRowFrame.cpp b/layout/tables/nsTableRowFrame.cpp index 78584b8d0a8b..a8fdd2536320 100644 --- a/layout/tables/nsTableRowFrame.cpp +++ b/layout/tables/nsTableRowFrame.cpp @@ -1177,7 +1177,7 @@ nsTableRowFrame::ReflowCellFrame(nsPresContext* aPresContext, ReflowChild(aCellFrame, aPresContext, desiredSize, cellReflowInput, 0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus); - bool fullyComplete = aStatus.IsComplete() && !NS_FRAME_IS_TRUNCATED(aStatus); + bool fullyComplete = aStatus.IsComplete() && !aStatus.IsTruncated(); if (fullyComplete) { desiredSize.BSize(wm) = aAvailableBSize; } From 19a2af32750323f39366caaa53e0741b800f747c Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Mon, 13 Feb 2017 17:15:01 +0800 Subject: [PATCH 097/234] Bug 775624 Part 11 - Convert NS_MergeReflowStatusInto() to a method. r=dholbert Also, remove NS_FRAME_TRUNCATED and NS_FRAME_REFLOW_NEXTINFLOW because both are used only by NS_MergeReflowStatusInto(). MozReview-Commit-ID: LsPOji9j2e --HG-- extra : rebase_source : 7cf1421c066f0f8df3e8402b84ae0f584cad2d11 --- layout/forms/nsFieldSetFrame.cpp | 2 +- layout/generic/nsAbsoluteContainingBlock.cpp | 4 ++-- layout/generic/nsBlockFrame.cpp | 14 ++++++++------ layout/generic/nsColumnSetFrame.cpp | 2 +- layout/generic/nsContainerFrame.cpp | 2 +- layout/generic/nsContainerFrame.h | 4 +++- layout/generic/nsFrame.cpp | 11 ----------- layout/generic/nsGridContainerFrame.cpp | 2 +- layout/generic/nsIFrame.h | 20 ++++++++++++-------- 9 files changed, 29 insertions(+), 32 deletions(-) diff --git a/layout/forms/nsFieldSetFrame.cpp b/layout/forms/nsFieldSetFrame.cpp index 83dd49e03850..2279d3754d35 100644 --- a/layout/forms/nsFieldSetFrame.cpp +++ b/layout/forms/nsFieldSetFrame.cpp @@ -574,7 +574,7 @@ nsFieldSetFrame::Reflow(nsPresContext* aPresContext, // Merge overflow container bounds and status. aDesiredSize.mOverflowAreas.UnionWith(ocBounds); - NS_MergeReflowStatusInto(&aStatus, ocStatus); + aStatus.MergeCompletionStatusFrom(ocStatus); FinishReflowWithAbsoluteFrames(aPresContext, aDesiredSize, aReflowInput, aStatus); diff --git a/layout/generic/nsAbsoluteContainingBlock.cpp b/layout/generic/nsAbsoluteContainingBlock.cpp index 909ef933cd87..b4761ff5fd57 100644 --- a/layout/generic/nsAbsoluteContainingBlock.cpp +++ b/layout/generic/nsAbsoluteContainingBlock.cpp @@ -151,7 +151,7 @@ nsAbsoluteContainingBlock::Reflow(nsContainerFrame* aDelegatingFrame, // See bug 154892. Not sure how to do it "right" yet; probably want // to keep continuations within an nsAbsoluteContainingBlock eventually. tracker.Insert(nextFrame, kidStatus); - NS_MergeReflowStatusInto(&reflowStatus, kidStatus); + reflowStatus.MergeCompletionStatusFrom(kidStatus); } else { // Delete any continuations @@ -194,7 +194,7 @@ nsAbsoluteContainingBlock::Reflow(nsContainerFrame* aDelegatingFrame, if (reflowStatus.IsIncomplete()) reflowStatus.SetOverflowIncomplete(); - NS_MergeReflowStatusInto(&aReflowStatus, reflowStatus); + aReflowStatus.MergeCompletionStatusFrom(reflowStatus); } static inline bool IsFixedPaddingSize(const nsStyleCoord& aCoord) diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index 5cc026c0bac0..e00b6bab4db8 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -1251,9 +1251,11 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext, nsBlockFrame* nif = static_cast(GetNextInFlow()); while (nif) { if (nif->HasPushedFloatsFromPrevContinuation()) { - bool oc = nif->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER; - NS_MergeReflowStatusInto(&state.mReflowStatus, - oc ? NS_FRAME_OVERFLOW_INCOMPLETE : NS_FRAME_NOT_COMPLETE); + if (nif->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER) { + state.mReflowStatus.SetOverflowIncomplete(); + } else { + state.mReflowStatus.SetIncomplete(); + } break; } @@ -1261,8 +1263,8 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext, } } - NS_MergeReflowStatusInto(&state.mReflowStatus, ocStatus); - NS_MergeReflowStatusInto(&state.mReflowStatus, fcStatus); + state.mReflowStatus.MergeCompletionStatusFrom(ocStatus); + state.mReflowStatus.MergeCompletionStatusFrom(fcStatus); // If we end in a BR with clear and affected floats continue, // we need to continue, too. @@ -3719,7 +3721,7 @@ nsBlockFrame::ReflowBlockFrame(BlockReflowInput& aState, // Put it in our overflow list aState.mOverflowTracker->Insert(nextFrame, frameReflowStatus); - NS_MergeReflowStatusInto(&aState.mReflowStatus, frameReflowStatus); + aState.mReflowStatus.MergeCompletionStatusFrom(frameReflowStatus); #ifdef NOISY_BLOCK_DIR_MARGINS ListTag(stdout); diff --git a/layout/generic/nsColumnSetFrame.cpp b/layout/generic/nsColumnSetFrame.cpp index 548c86d5d0bf..a0252797b9b3 100644 --- a/layout/generic/nsColumnSetFrame.cpp +++ b/layout/generic/nsColumnSetFrame.cpp @@ -1108,7 +1108,7 @@ nsColumnSetFrame::Reflow(nsPresContext* aPresContext, // Merge overflow container bounds and status. aDesiredSize.mOverflowAreas.UnionWith(ocBounds); - NS_MergeReflowStatusInto(&aStatus, ocStatus); + aStatus.MergeCompletionStatusFrom(ocStatus); FinishReflowWithAbsoluteFrames(aPresContext, aDesiredSize, aReflowInput, aStatus, false); diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp index fe029ccc6895..edfd2cf07df5 100644 --- a/layout/generic/nsContainerFrame.cpp +++ b/layout/generic/nsContainerFrame.cpp @@ -1309,7 +1309,7 @@ nsContainerFrame::ReflowOverflowContainerChildren(nsPresContext* aPres tracker.Insert(nif, frameStatus); } - NS_MergeReflowStatusInto(&aStatus, frameStatus); + aStatus.MergeCompletionStatusFrom(frameStatus); // At this point it would be nice to assert !frame->GetOverflowRect().IsEmpty(), // but we have some unsplittable frames that, when taller than // availableHeight will push zero-height content into a next-in-flow. diff --git a/layout/generic/nsContainerFrame.h b/layout/generic/nsContainerFrame.h index 27287910ff30..93f20e70ae03 100644 --- a/layout/generic/nsContainerFrame.h +++ b/layout/generic/nsContainerFrame.h @@ -851,7 +851,9 @@ public: NS_PRECONDITION(aChild, "null ptr"); if (aChild == mSentry) { StepForward(); - NS_MergeReflowStatusInto(&aReflowStatus, NS_FRAME_OVERFLOW_INCOMPLETE); + if (aReflowStatus.IsComplete()) { + aReflowStatus.SetOverflowIncomplete(); + } } } diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 1dd62b4f7f1e..31b50f989e48 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -379,17 +379,6 @@ nsIFrame::ContentStatesChanged(mozilla::EventStates aStates) { } -void -NS_MergeReflowStatusInto(nsReflowStatus* aPrimary, nsReflowStatus aSecondary) -{ - *aPrimary |= aSecondary & - (NS_FRAME_NOT_COMPLETE | NS_FRAME_OVERFLOW_INCOMPLETE | - NS_FRAME_TRUNCATED | NS_FRAME_REFLOW_NEXTINFLOW); - if (*aPrimary & NS_FRAME_NOT_COMPLETE) { - *aPrimary &= ~NS_FRAME_OVERFLOW_INCOMPLETE; - } -} - void nsWeakFrame::Init(nsIFrame* aFrame) { diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index cbba7cbbf0dc..83abb143662a 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -5860,7 +5860,7 @@ nsGridContainerFrame::ReflowChildren(GridReflowInput& aState, // Merge overflow container bounds and status. aDesiredSize.mOverflowAreas.UnionWith(ocBounds); - NS_MergeReflowStatusInto(&aStatus, ocStatus); + aStatus.MergeCompletionStatusFrom(ocStatus); if (IsAbsoluteContainer()) { nsFrameList children(GetChildList(GetAbsoluteListID())); diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 29a5b7746a8e..c27a57e9d704 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -297,6 +297,18 @@ public: void UpdateTruncated(const mozilla::ReflowInput& aReflowInput, const mozilla::ReflowOutput& aMetrics); + // Merge the frame completion status bits from aStatus into this. + void MergeCompletionStatusFrom(const nsReflowStatus& aStatus) + { + mIncomplete |= aStatus.mIncomplete; + mOverflowIncomplete |= aStatus.mOverflowIncomplete; + mNextInFlowNeedsReflow |= aStatus.mNextInFlowNeedsReflow; + mTruncated |= aStatus.mTruncated; + if (mIncomplete) { + mOverflowIncomplete = false; + } + } + private: uint32_t mStatus; @@ -309,7 +321,6 @@ private: #define NS_FRAME_COMPLETE 0 // Note: not a bit! #define NS_FRAME_NOT_COMPLETE 0x1 -#define NS_FRAME_REFLOW_NEXTINFLOW 0x2 #define NS_FRAME_OVERFLOW_INCOMPLETE 0x4 // This bit is set, when a break is requested. This bit is orthogonal @@ -361,16 +372,9 @@ private: ((_completionStatus) | NS_INLINE_BREAK | NS_INLINE_BREAK_AFTER | \ NS_INLINE_MAKE_BREAK_TYPE(StyleClear::Line)) -#define NS_FRAME_TRUNCATED 0x0010 - #define NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aMetrics) \ aStatus.UpdateTruncated(aReflowInput, aMetrics); -// Merge the incompleteness, truncation and NS_FRAME_REFLOW_NEXTINFLOW -// status from aSecondary into aPrimary. -void NS_MergeReflowStatusInto(nsReflowStatus* aPrimary, - nsReflowStatus aSecondary); - //---------------------------------------------------------------------- /** From 56ebb6291007ad2d74da30515456dfc8b1ba146a Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Tue, 14 Feb 2017 11:52:53 +0800 Subject: [PATCH 098/234] Bug 775624 Part 12 - Add bit-fields for inline break status, and convert NS_INLINE_LINE_BREAK_BEFORE. r=dholbert NS_INLINE_LINE_BREAK_BEFORE() was replaced by the help of the following script. function rename() { find layout\ -type f\ \( -name "*.cpp" -or\ -name "*.h" \)\ -exec sed -i -r "s/$1/$2/g" "{}" \; } rename " = NS_INLINE_LINE_BREAK_BEFORE\(\);" ".SetInlineLineBreakBeforeAndReset();" MozReview-Commit-ID: mz6L8zay7q --HG-- extra : rebase_source : fddffa1288c7a52c7245aec0839a65f8d1d3f008 --- layout/generic/nsBlockFrame.cpp | 14 +++---- layout/generic/nsGridContainerFrame.cpp | 6 +-- layout/generic/nsIFrame.h | 45 ++++++++++++++------- layout/generic/nsLineLayout.cpp | 2 +- layout/generic/nsRubyBaseContainerFrame.cpp | 6 +-- layout/generic/nsTextFrame.cpp | 2 +- layout/tables/nsTableFrame.cpp | 4 +- layout/tables/nsTableRowFrame.cpp | 2 +- layout/tables/nsTableRowGroupFrame.cpp | 4 +- 9 files changed, 50 insertions(+), 35 deletions(-) diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index e00b6bab4db8..443530f62ee6 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -3406,7 +3406,7 @@ nsBlockFrame::ReflowBlockFrame(BlockReflowInput& aState, aState.mPrevBEndMargin = incomingMargin; *aKeepReflowGoing = false; if (ShouldAvoidBreakInside(aState.mReflowInput)) { - aState.mReflowStatus = NS_INLINE_LINE_BREAK_BEFORE(); + aState.mReflowStatus.SetInlineLineBreakBeforeAndReset(); } else { PushLines(aState, aLine.prev()); aState.mReflowStatus.SetIncomplete(); @@ -3583,7 +3583,7 @@ nsBlockFrame::ReflowBlockFrame(BlockReflowInput& aState, // None of the child block fits. *aKeepReflowGoing = false; if (ShouldAvoidBreakInside(aState.mReflowInput)) { - aState.mReflowStatus = NS_INLINE_LINE_BREAK_BEFORE(); + aState.mReflowStatus.SetInlineLineBreakBeforeAndReset(); } else { PushLines(aState, aLine.prev()); aState.mReflowStatus.SetIncomplete(); @@ -3757,7 +3757,7 @@ nsBlockFrame::ReflowBlockFrame(BlockReflowInput& aState, // If it's our very first line *or* we're not at the top of the page // and we have page-break-inside:avoid, then we need to be pushed to // our parent's next-in-flow. - aState.mReflowStatus = NS_INLINE_LINE_BREAK_BEFORE(); + aState.mReflowStatus.SetInlineLineBreakBeforeAndReset(); } else { // Push the line that didn't fit and any lines that follow it // to our next-in-flow. @@ -4644,7 +4644,7 @@ nsBlockFrame::PlaceLine(BlockReflowInput& aState, if (!aState.mReflowStatus.IsFullyComplete() && ShouldAvoidBreakInside(aState.mReflowInput)) { aLine->AppendFloats(aState.mCurrentLineFloats); - aState.mReflowStatus = NS_INLINE_LINE_BREAK_BEFORE(); + aState.mReflowStatus.SetInlineLineBreakBeforeAndReset(); return true; } @@ -4655,7 +4655,7 @@ nsBlockFrame::PlaceLine(BlockReflowInput& aState, NS_ASSERTION(aState.mCurrentLine == aLine, "oops"); if (ShouldAvoidBreakInside(aState.mReflowInput)) { // All our content doesn't fit, start on the next page. - aState.mReflowStatus = NS_INLINE_LINE_BREAK_BEFORE(); + aState.mReflowStatus.SetInlineLineBreakBeforeAndReset(); } else { // Push aLine and all of its children and anything else that // follows to our next-in-flow. @@ -6277,7 +6277,7 @@ nsBlockFrame::ReflowFloat(BlockReflowInput& aState, if (!aReflowStatus.IsFullyComplete() && ShouldAvoidBreakInside(floatRS)) { - aReflowStatus = NS_INLINE_LINE_BREAK_BEFORE(); + aReflowStatus.SetInlineLineBreakBeforeAndReset(); } else if (aReflowStatus.IsIncomplete() && (NS_UNCONSTRAINEDSIZE == aAdjustedAvailableSpace.BSize(wm))) { // An incomplete reflow status means we should split the float @@ -7423,7 +7423,7 @@ nsBlockFrame::ComputeFinalBSize(const ReflowInput& aReflowInput, NS_UNCONSTRAINEDSIZE != aReflowInput.AvailableBSize() && aFinalSize.BSize(wm) > aReflowInput.AvailableBSize()) { if (ShouldAvoidBreakInside(aReflowInput)) { - *aStatus = NS_INLINE_LINE_BREAK_BEFORE(); + aStatus->SetInlineLineBreakBeforeAndReset(); return; } // We don't fit and we consumed some of the computed height, diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index 83abb143662a..886459a9ff3f 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -5388,7 +5388,7 @@ nsGridContainerFrame::ReflowInFragmentainer(GridReflowInput& aState, // Propagate break-before on the first row to the container unless we're // already at top-of-page. if ((itemStartRow == 0 && !isTopOfPage) || avoidBreakInside) { - aStatus = NS_INLINE_LINE_BREAK_BEFORE(); + aStatus.SetInlineLineBreakBeforeAndReset(); return aState.mFragBStart; } if ((itemStartRow > startRow || @@ -5427,7 +5427,7 @@ nsGridContainerFrame::ReflowInFragmentainer(GridReflowInput& aState, // Honor break-inside:avoid if we can't fit all rows. if (avoidBreakInside && endRow < numRows) { - aStatus = NS_INLINE_LINE_BREAK_BEFORE(); + aStatus.SetInlineLineBreakBeforeAndReset(); return aState.mFragBStart; } @@ -5463,7 +5463,7 @@ nsGridContainerFrame::ReflowInFragmentainer(GridReflowInput& aState, bool overflow = bSize + bpBEnd > childAvailableSize; if (overflow) { if (avoidBreakInside) { - aStatus = NS_INLINE_LINE_BREAK_BEFORE(); + aStatus.SetInlineLineBreakBeforeAndReset(); return aState.mFragBStart; } bool breakAfterLastRow = endRow == numRows && aFragmentainer.mCanBreakAtEnd; diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index c27a57e9d704..4ae1fe199d6f 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -197,21 +197,29 @@ enum nsSpread { //---------------------------------------------------------------------- // Reflow status returned by the Reflow() methods. class nsReflowStatus final { + using StyleClear = mozilla::StyleClear; + public: nsReflowStatus() : mStatus(0) + , mBreakType(StyleClear::None) , mIncomplete(false) , mOverflowIncomplete(false) , mNextInFlowNeedsReflow(false) , mTruncated(false) + , mInlineBreak(false) + , mInlineBreakAfter(false) {} // Reset all the bit-fields. void Reset() { + mBreakType = StyleClear::None; mIncomplete = false; mOverflowIncomplete = false; mNextInFlowNeedsReflow = false; mTruncated = false; + mInlineBreak = false; + mInlineBreakAfter = false; } nsReflowStatus(uint32_t aStatus) @@ -309,28 +317,43 @@ public: } } + // mInlineBreak bit flag means a break is requested. + + // Suppose a break is requested. When mInlineBreakAfter is set, the break + // should occur after the frame just reflowed; when mInlineBreakAfter is + // clear, the break should occur before the frame just reflowed. + + // Set the inline line-break-before status, and reset other bit flags. The + // break type is StyleClear::Line. Note that other frame completion status + // isn't expected to matter after calling this method. + void SetInlineLineBreakBeforeAndReset() { + Reset(); + mBreakType = StyleClear::Line; + mInlineBreak = true; + mInlineBreakAfter = false; + } + private: uint32_t mStatus; + StyleClear mBreakType; + // Frame completion status bit flags. bool mIncomplete : 1; bool mOverflowIncomplete : 1; bool mNextInFlowNeedsReflow : 1; bool mTruncated : 1; + + // Inline break status bit flags. + bool mInlineBreak : 1; + bool mInlineBreakAfter : 1; }; #define NS_FRAME_COMPLETE 0 // Note: not a bit! #define NS_FRAME_NOT_COMPLETE 0x1 #define NS_FRAME_OVERFLOW_INCOMPLETE 0x4 -// This bit is set, when a break is requested. This bit is orthogonal -// to the nsIFrame::nsReflowStatus completion bits. #define NS_INLINE_BREAK 0x0100 - -// When a break is requested, this bit when set indicates that the -// break should occur after the frame just reflowed; when the bit is -// clear the break should occur before the frame just reflowed. -#define NS_INLINE_BREAK_BEFORE 0x0000 #define NS_INLINE_BREAK_AFTER 0x0200 // The type of break requested can be found in these bits. @@ -356,14 +379,6 @@ private: #define NS_INLINE_MAKE_BREAK_TYPE(_type) (static_cast(_type) << 12) -// Construct a line-break-before status. Note that there is no -// completion status for a line-break before because we *know* that -// the frame will be reflowed later and hence its current completion -// status doesn't matter. -#define NS_INLINE_LINE_BREAK_BEFORE() \ - (NS_INLINE_BREAK | NS_INLINE_BREAK_BEFORE | \ - NS_INLINE_MAKE_BREAK_TYPE(StyleClear::Line)) - // Take a completion status and add to it the desire to have a // line-break after. For this macro we do need the completion status // because the user of the status will need to know whether to diff --git a/layout/generic/nsLineLayout.cpp b/layout/generic/nsLineLayout.cpp index df64dff3deb0..13145d63d04c 100644 --- a/layout/generic/nsLineLayout.cpp +++ b/layout/generic/nsLineLayout.cpp @@ -1418,7 +1418,7 @@ nsLineLayout::CanPlaceFrame(PerFrameData* pfd, #ifdef NOISY_CAN_PLACE_FRAME printf(" ==> didn't fit\n"); #endif - aStatus = NS_INLINE_LINE_BREAK_BEFORE(); + aStatus.SetInlineLineBreakBeforeAndReset(); return false; } diff --git a/layout/generic/nsRubyBaseContainerFrame.cpp b/layout/generic/nsRubyBaseContainerFrame.cpp index 2f071ca20cb9..4b4a8e0f35fd 100644 --- a/layout/generic/nsRubyBaseContainerFrame.cpp +++ b/layout/generic/nsRubyBaseContainerFrame.cpp @@ -514,7 +514,7 @@ nsRubyBaseContainerFrame::ReflowColumns(const RubyReflowInput& aReflowInput, // Skip to the next column and mark break before. e.Next(); e.GetColumn(column); - reflowStatus = NS_INLINE_LINE_BREAK_BEFORE(); + reflowStatus.SetInlineLineBreakBeforeAndReset(); } if (!e.AtEnd() || (GetNextInFlow() && !isComplete)) { aStatus.SetIncomplete(); @@ -524,7 +524,7 @@ nsRubyBaseContainerFrame::ReflowColumns(const RubyReflowInput& aReflowInput, if (!columnIndex || !aReflowInput.mAllowLineBreak) { // If no column has been placed yet, or we have any span, // the whole container should be in the next line. - aStatus = NS_INLINE_LINE_BREAK_BEFORE(); + aStatus.SetInlineLineBreakBeforeAndReset(); return 0; } aStatus = NS_INLINE_LINE_BREAK_AFTER(aStatus); @@ -598,7 +598,7 @@ nsRubyBaseContainerFrame::ReflowOneColumn(const RubyReflowInput& aReflowInput, if (istart > baseReflowInput.AvailableISize() || baseReflowInput.mLineLayout->NotifyOptionalBreakPosition( aColumn.mBaseFrame, 0, true, breakPriority)) { - aStatus = NS_INLINE_LINE_BREAK_BEFORE(); + aStatus.SetInlineLineBreakBeforeAndReset(); return 0; } } diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index a33c4e0bf636..cf136cfb9614 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -9550,7 +9550,7 @@ nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth, if (charsFit == 0 && length > 0 && !usedHyphenation) { // Couldn't place any text - aStatus = NS_INLINE_LINE_BREAK_BEFORE(); + aStatus.SetInlineLineBreakBeforeAndReset(); } else if (contentLength > 0 && mContentOffset + contentLength - 1 == newLineOffset) { // Ends in \n aStatus = NS_INLINE_LINE_BREAK_AFTER(aStatus); diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index 3748eb0c584b..892f901318cf 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -3165,7 +3165,7 @@ nsTableFrame::ReflowChildren(TableReflowInput& aReflowInput, } if (isPaginated && !aStatus.IsFullyComplete() && ShouldAvoidBreakInside(aReflowInput.reflowInput)) { - aStatus = NS_INLINE_LINE_BREAK_BEFORE(); + aStatus.SetInlineLineBreakBeforeAndReset(); break; } // see if the rowgroup did not fit on this page might be pushed on @@ -3176,7 +3176,7 @@ nsTableFrame::ReflowChildren(TableReflowInput& aReflowInput, (NS_UNCONSTRAINEDSIZE != kidReflowInput.AvailableHeight()) && kidReflowInput.AvailableHeight() < desiredSize.Height()))) { if (ShouldAvoidBreakInside(aReflowInput.reflowInput)) { - aStatus = NS_INLINE_LINE_BREAK_BEFORE(); + aStatus.SetInlineLineBreakBeforeAndReset(); break; } // if we are on top of the page place with dataloss diff --git a/layout/tables/nsTableRowFrame.cpp b/layout/tables/nsTableRowFrame.cpp index a8fdd2536320..5dbffdad7099 100644 --- a/layout/tables/nsTableRowFrame.cpp +++ b/layout/tables/nsTableRowFrame.cpp @@ -1120,7 +1120,7 @@ nsTableRowFrame::Reflow(nsPresContext* aPresContext, if (aPresContext->IsPaginated() && !aStatus.IsFullyComplete() && ShouldAvoidBreakInside(aReflowInput)) { - aStatus = NS_INLINE_LINE_BREAK_BEFORE(); + aStatus.SetInlineLineBreakBeforeAndReset(); } // Just set our isize to what was available. diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp index c4478bba3b47..64152230d286 100644 --- a/layout/tables/nsTableRowGroupFrame.cpp +++ b/layout/tables/nsTableRowGroupFrame.cpp @@ -1176,7 +1176,7 @@ nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext, if (!aRowForcedPageBreak && !aStatus.IsFullyComplete() && ShouldAvoidBreakInside(aReflowInput)) { - aStatus = NS_INLINE_LINE_BREAK_BEFORE(); + aStatus.SetInlineLineBreakBeforeAndReset(); break; } @@ -1242,7 +1242,7 @@ nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext, if (!rowIsOnPage) { NS_ASSERTION(!contRow, "We should not have created a continuation if none of this row fits"); if (!aRowForcedPageBreak && ShouldAvoidBreakInside(aReflowInput)) { - aStatus = NS_INLINE_LINE_BREAK_BEFORE(); + aStatus.SetInlineLineBreakBeforeAndReset(); break; } if (prevRowFrame) { From d1e11eca370add33d9ba271b9eb48f70c6ebc17d Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Tue, 14 Feb 2017 11:52:53 +0800 Subject: [PATCH 099/234] Bug 775624 Part 13 - Convert NS_INLINE_LINE_BREAK_AFTER to a method. r=dholbert NS_INLINE_MAKE_BREAK_TYPE is used only in BRFrame. Delete it, too. MozReview-Commit-ID: GC4vF0GFsAD --HG-- extra : rebase_source : d7727fe41410a8998142d9ded8dcd8ae9c2a780f --- layout/generic/BRFrame.cpp | 4 ++-- layout/generic/nsGridContainerFrame.cpp | 2 +- layout/generic/nsIFrame.h | 18 ++++++++---------- layout/generic/nsLineLayout.cpp | 2 +- layout/generic/nsRubyBaseContainerFrame.cpp | 4 ++-- layout/generic/nsRubyFrame.cpp | 4 +++- layout/generic/nsTextFrame.cpp | 4 ++-- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/layout/generic/BRFrame.cpp b/layout/generic/BRFrame.cpp index 91aa9c72689b..04c85446d473 100644 --- a/layout/generic/BRFrame.cpp +++ b/layout/generic/BRFrame.cpp @@ -154,8 +154,8 @@ BRFrame::Reflow(nsPresContext* aPresContext, breakType = StyleClear::Line; } - aStatus = NS_INLINE_BREAK | NS_INLINE_BREAK_AFTER | - NS_INLINE_MAKE_BREAK_TYPE(breakType); + aStatus.Reset(); + aStatus.SetInlineLineBreakAfter(breakType); ll->SetLineEndsInBR(true); } else { diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index 886459a9ff3f..1bc857a656fd 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -5413,7 +5413,7 @@ nsGridContainerFrame::ReflowInFragmentainer(GridReflowInput& aState, } else { // Propagate break-after on the last row to the container, we may still // find a break-before on this row though (and reset aStatus). - aStatus = NS_INLINE_LINE_BREAK_AFTER(aStatus); // tentative + aStatus.SetInlineLineBreakAfter(); // tentative } } } diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 4ae1fe199d6f..37fcc366b470 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -333,6 +333,14 @@ public: mInlineBreakAfter = false; } + // Set the inline line-break-after status. The break type can be changed + // via the optional aBreakType param. + void SetInlineLineBreakAfter(StyleClear aBreakType = StyleClear::Line) { + mBreakType = aBreakType; + mInlineBreak = true; + mInlineBreakAfter = true; + } + private: uint32_t mStatus; @@ -377,16 +385,6 @@ private: #define NS_INLINE_GET_BREAK_TYPE(_status) \ (static_cast(((_status) >> 12) & 0xF)) -#define NS_INLINE_MAKE_BREAK_TYPE(_type) (static_cast(_type) << 12) - -// Take a completion status and add to it the desire to have a -// line-break after. For this macro we do need the completion status -// because the user of the status will need to know whether to -// continue the frame or not. -#define NS_INLINE_LINE_BREAK_AFTER(_completionStatus) \ - ((_completionStatus) | NS_INLINE_BREAK | NS_INLINE_BREAK_AFTER | \ - NS_INLINE_MAKE_BREAK_TYPE(StyleClear::Line)) - #define NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aMetrics) \ aStatus.UpdateTruncated(aReflowInput, aMetrics); diff --git a/layout/generic/nsLineLayout.cpp b/layout/generic/nsLineLayout.cpp index 13145d63d04c..14c52d2eb252 100644 --- a/layout/generic/nsLineLayout.cpp +++ b/layout/generic/nsLineLayout.cpp @@ -1136,7 +1136,7 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame, optionalBreakAfterFits, gfxBreakPriority::eNormalBreak)) { // If this returns true then we are being told to actually break here. - aReflowStatus = NS_INLINE_LINE_BREAK_AFTER(aReflowStatus); + aReflowStatus.SetInlineLineBreakAfter(); } } } diff --git a/layout/generic/nsRubyBaseContainerFrame.cpp b/layout/generic/nsRubyBaseContainerFrame.cpp index 4b4a8e0f35fd..5951bc3184c7 100644 --- a/layout/generic/nsRubyBaseContainerFrame.cpp +++ b/layout/generic/nsRubyBaseContainerFrame.cpp @@ -527,7 +527,7 @@ nsRubyBaseContainerFrame::ReflowColumns(const RubyReflowInput& aReflowInput, aStatus.SetInlineLineBreakBeforeAndReset(); return 0; } - aStatus = NS_INLINE_LINE_BREAK_AFTER(aStatus); + aStatus.SetInlineLineBreakAfter(); MOZ_ASSERT(aStatus.IsComplete() || aReflowInput.mAllowLineBreak); // If we are on an intra-level whitespace column, null values in @@ -565,7 +565,7 @@ nsRubyBaseContainerFrame::ReflowColumns(const RubyReflowInput& aReflowInput, // segment has been completely reflowed. In those cases, we do // not need to push anything. MOZ_ASSERT(e.AtEnd()); - aStatus = NS_INLINE_LINE_BREAK_AFTER(aStatus); + aStatus.SetInlineLineBreakAfter(); } return icoord; diff --git a/layout/generic/nsRubyFrame.cpp b/layout/generic/nsRubyFrame.cpp index a4ffa6adfdf5..2753809165c7 100644 --- a/layout/generic/nsRubyFrame.cpp +++ b/layout/generic/nsRubyFrame.cpp @@ -209,7 +209,9 @@ nsRubyFrame::ReflowSegment(nsPresContext* aPresContext, if (aBaseContainer != mFrames.FirstChild()) { // Some segments may have been reflowed before, hence it is not // a break-before for the ruby container. - aStatus = NS_INLINE_LINE_BREAK_AFTER(NS_FRAME_NOT_COMPLETE); + aStatus.Reset(); + aStatus.SetInlineLineBreakAfter(); + aStatus.SetIncomplete(); PushChildren(aBaseContainer, aBaseContainer->GetPrevSibling()); aReflowInput.mLineLayout->SetDirtyNextLine(); } diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index cf136cfb9614..2ed7f37b6af1 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -9553,10 +9553,10 @@ nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth, aStatus.SetInlineLineBreakBeforeAndReset(); } else if (contentLength > 0 && mContentOffset + contentLength - 1 == newLineOffset) { // Ends in \n - aStatus = NS_INLINE_LINE_BREAK_AFTER(aStatus); + aStatus.SetInlineLineBreakAfter(); aLineLayout.SetLineEndsInBR(true); } else if (breakAfter) { - aStatus = NS_INLINE_LINE_BREAK_AFTER(aStatus); + aStatus.SetInlineLineBreakAfter(); } if (completedFirstLetter) { aLineLayout.SetFirstLetterStyleOK(false); From 1c0431a402117ee79b0b05a6734164d5dded0e3a Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Tue, 14 Feb 2017 15:58:03 +0800 Subject: [PATCH 100/234] Bug 775624 Part 14 - Convert NS_INLINE_GET_BREAK_TYPE to a method. r=dholbert MozReview-Commit-ID: CAYlv21gPpR --HG-- extra : rebase_source : f1d44d9ccac983f2051f09f17bf662b5bfad76e3 --- layout/generic/nsBlockFrame.cpp | 2 +- layout/generic/nsIFrame.h | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index 443530f62ee6..ad9ce5628a10 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -4188,7 +4188,7 @@ nsBlockFrame::ReflowInlineFrame(BlockReflowInput& aState, *aLineReflowStatus = LineReflowStatus::Stop; // XXX what should aLine's break-type be set to in all these cases? - StyleClear breakType = NS_INLINE_GET_BREAK_TYPE(frameReflowStatus); + StyleClear breakType = frameReflowStatus.BreakType(); MOZ_ASSERT(StyleClear::None != breakType || StyleClear::None != aState.mFloatBreakType, "bad break type"); diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 37fcc366b470..565d07ebbd01 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -322,6 +322,7 @@ public: // Suppose a break is requested. When mInlineBreakAfter is set, the break // should occur after the frame just reflowed; when mInlineBreakAfter is // clear, the break should occur before the frame just reflowed. + StyleClear BreakType() const { return mBreakType; } // Set the inline line-break-before status, and reset other bit flags. The // break type is StyleClear::Line. Note that other frame completion status @@ -382,9 +383,6 @@ private: #define NS_INLINE_IS_BREAK_BEFORE(_status) \ (NS_INLINE_BREAK == ((_status) & (NS_INLINE_BREAK|NS_INLINE_BREAK_AFTER))) -#define NS_INLINE_GET_BREAK_TYPE(_status) \ - (static_cast(((_status) >> 12) & 0xF)) - #define NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aMetrics) \ aStatus.UpdateTruncated(aReflowInput, aMetrics); From 19221f0474c590afa08601b65f2191d1bb517bb5 Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Tue, 14 Feb 2017 16:05:24 +0800 Subject: [PATCH 101/234] Bug 775624 Part 15 - Remove NS_INLINE_BREAK_TYPE_MASK. r=dholbert MozReview-Commit-ID: BjDou96ojUd --HG-- extra : rebase_source : 238d8c80e2dcc347101b8941bca01e4a2f6304c6 --- layout/generic/nsIFrame.h | 3 --- layout/generic/nsInlineFrame.cpp | 7 ++++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 565d07ebbd01..fad52442c94b 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -365,9 +365,6 @@ private: #define NS_INLINE_BREAK 0x0100 #define NS_INLINE_BREAK_AFTER 0x0200 -// The type of break requested can be found in these bits. -#define NS_INLINE_BREAK_TYPE_MASK 0xF000 - // Set when a break was induced by completion of a first-letter #define NS_INLINE_BREAK_FIRST_LETTER_COMPLETE 0x10000 diff --git a/layout/generic/nsInlineFrame.cpp b/layout/generic/nsInlineFrame.cpp index 95c1f3a1505e..d0d40ff234bb 100644 --- a/layout/generic/nsInlineFrame.cpp +++ b/layout/generic/nsInlineFrame.cpp @@ -809,9 +809,10 @@ nsInlineFrame::ReflowInlineFrame(nsPresContext* aPresContext, // Change break-before status into break-after since we have // already placed at least one child frame. This preserves the // break-type so that it can be propagated upward. - aStatus = NS_FRAME_NOT_COMPLETE | - NS_INLINE_BREAK | NS_INLINE_BREAK_AFTER | - (aStatus & NS_INLINE_BREAK_TYPE_MASK); + StyleClear oldBreakType = aStatus.BreakType(); + aStatus.Reset(); + aStatus.SetIncomplete(); + aStatus.SetInlineLineBreakAfter(oldBreakType); PushFrames(aPresContext, aFrame, irs.mPrevFrame, irs); } else { From d5c6d28836fddfafbe200cc7f1eeb9c389208771 Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Tue, 14 Feb 2017 16:05:24 +0800 Subject: [PATCH 102/234] Bug 775624 Part 16 - Convert NS_INLINE_IS_BREAK_BEFORE to a method. r=dholbert MozReview-Commit-ID: 8vxRpqbZNnk --HG-- extra : rebase_source : 195e2da23d64da9e9a888968a45eaae2e6539585 --- layout/forms/nsComboboxControlFrame.cpp | 2 +- layout/generic/BlockReflowInput.cpp | 6 +++--- layout/generic/nsBlockFrame.cpp | 10 +++++----- layout/generic/nsBlockReflowContext.cpp | 4 ++-- layout/generic/nsContainerFrame.cpp | 2 +- layout/generic/nsFirstLetterFrame.cpp | 2 +- layout/generic/nsGridContainerFrame.cpp | 6 +++--- layout/generic/nsIFrame.h | 4 +--- layout/generic/nsInlineFrame.cpp | 4 ++-- layout/generic/nsLineLayout.cpp | 4 ++-- layout/generic/nsRubyBaseContainerFrame.cpp | 10 +++++----- layout/generic/nsRubyFrame.cpp | 2 +- .../css-grid/grid-fragmentation-006-ref.html | 12 ++++++------ .../css-grid/grid-fragmentation-006.html | 12 ++++++------ .../css-grid/grid-fragmentation-007.html | 12 ++++++------ .../css-grid/grid-fragmentation-019.html | 12 ++++++------ .../css-grid/grid-fragmentation-022.html | 12 ++++++------ .../css-grid/grid-fragmentation-023.html | 12 ++++++------ .../css-grid/grid-fragmentation-024.html | 16 ++++++++-------- .../css-grid/grid-fragmentation-025.html | 16 ++++++++-------- .../css-grid/grid-fragmentation-027.html | 16 ++++++++-------- .../css-grid/grid-fragmentation-028.html | 16 ++++++++-------- .../css-grid/grid-fragmentation-030-ref.html | 14 +++++++------- .../css-grid/grid-fragmentation-030.html | 14 +++++++------- .../css-grid/grid-fragmentation-031-ref.html | 14 +++++++------- .../css-grid/grid-fragmentation-031.html | 14 +++++++------- layout/tables/nsTableFrame.cpp | 2 +- layout/tables/nsTableRowGroupFrame.cpp | 2 +- 28 files changed, 125 insertions(+), 127 deletions(-) diff --git a/layout/forms/nsComboboxControlFrame.cpp b/layout/forms/nsComboboxControlFrame.cpp index cc84104ef766..5708c24b42d0 100644 --- a/layout/forms/nsComboboxControlFrame.cpp +++ b/layout/forms/nsComboboxControlFrame.cpp @@ -897,7 +897,7 @@ nsComboboxControlFrame::Reflow(nsPresContext* aPresContext, mButtonFrame->SetRect(buttonRect, containerSize); - if (!NS_INLINE_IS_BREAK_BEFORE(aStatus) && + if (!aStatus.IsInlineBreakBefore() && !aStatus.IsFullyComplete()) { // This frame didn't fit inside a fragmentation container. Splitting // a nsComboboxControlFrame makes no sense, so we override the status here. diff --git a/layout/generic/BlockReflowInput.cpp b/layout/generic/BlockReflowInput.cpp index 7bc16989a03a..e2336ff4c6a5 100644 --- a/layout/generic/BlockReflowInput.cpp +++ b/layout/generic/BlockReflowInput.cpp @@ -920,8 +920,8 @@ BlockReflowInput::FlowAndPlaceFloat(nsIFrame* aFloat) // (controlled by the pref "layout.float-fragments-inside-column.enabled") // // Likewise, if none of the float fit, and it needs to be pushed in - // its entirety to the next page (IsTruncated() or - // NS_INLINE_IS_BREAK_BEFORE), we need to do the same. + // its entirety to the next page (IsTruncated() or IsInlineBreakBefore()), + // we need to do the same. if ((ContentBSize() != NS_UNCONSTRAINEDSIZE && !mFlags.mFloatFragmentsInsideColumnEnabled && adjustedAvailableSpace.BSize(wm) == NS_UNCONSTRAINEDSIZE && @@ -929,7 +929,7 @@ BlockReflowInput::FlowAndPlaceFloat(nsIFrame* aFloat) aFloat->BSize(wm) + floatMargin.BStartEnd(wm) > ContentBEnd() - floatPos.B(wm)) || reflowStatus.IsTruncated() || - NS_INLINE_IS_BREAK_BEFORE(reflowStatus)) { + reflowStatus.IsInlineBreakBefore()) { PushFloatPastBreak(aFloat); return false; } diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index ad9ce5628a10..f93e6b20ebc5 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -260,7 +260,7 @@ RecordReflowStatus(bool aChildIsBlock, nsReflowStatus aFrameReflowStatus) // Compute new status uint32_t newS = record[index]; if (NS_INLINE_IS_BREAK(aFrameReflowStatus)) { - if (NS_INLINE_IS_BREAK_BEFORE(aFrameReflowStatus)) { + if (aFrameReflowStatus.IsInlineBreakBefore()) { newS |= 1; } else if (aFrameReflowStatus.IsIncomplete()) { @@ -1668,7 +1668,7 @@ nsBlockFrame::ComputeFinalSize(const ReflowInput& aReflowInput, aState.mReflowStatus.SetOverflowIncomplete(); } } else if (aReflowInput.AvailableBSize() != NS_UNCONSTRAINEDSIZE && - !NS_INLINE_IS_BREAK_BEFORE(aState.mReflowStatus) && + !aState.mReflowStatus.IsInlineBreakBefore() && aState.mReflowStatus.IsComplete()) { // Currently only used for grid items, but could be used in other contexts. // The FragStretchBSizeProperty is our expected non-fragmented block-size @@ -3579,7 +3579,7 @@ nsBlockFrame::ReflowBlockFrame(BlockReflowInput& aState, RecordReflowStatus(true, frameReflowStatus); #endif - if (NS_INLINE_IS_BREAK_BEFORE(frameReflowStatus)) { + if (frameReflowStatus.IsInlineBreakBefore()) { // None of the child block fits. *aKeepReflowGoing = false; if (ShouldAvoidBreakInside(aState.mReflowInput)) { @@ -4078,7 +4078,7 @@ nsBlockFrame::DoReflowInlineFrames(BlockReflowInput& aState, LineReflowStatus::RedoNoPull != lineReflowStatus) { // If we are propagating out a break-before status then there is // no point in placing the line. - if (!NS_INLINE_IS_BREAK_BEFORE(aState.mReflowStatus)) { + if (!aState.mReflowStatus.IsInlineBreakBefore()) { if (!PlaceLine(aState, aLineLayout, aLine, aFloatStateBeforeLine, aFloatAvailableSpace.mRect, aAvailableSpaceBSize, aKeepReflowGoing)) { @@ -4192,7 +4192,7 @@ nsBlockFrame::ReflowInlineFrame(BlockReflowInput& aState, MOZ_ASSERT(StyleClear::None != breakType || StyleClear::None != aState.mFloatBreakType, "bad break type"); - if (NS_INLINE_IS_BREAK_BEFORE(frameReflowStatus)) { + if (frameReflowStatus.IsInlineBreakBefore()) { // Break-before cases. if (aFrame == aLine->mFirstChild) { // If we break before the first frame on the line then we must diff --git a/layout/generic/nsBlockReflowContext.cpp b/layout/generic/nsBlockReflowContext.cpp index bf240593f208..222e0e3cdbee 100644 --- a/layout/generic/nsBlockReflowContext.cpp +++ b/layout/generic/nsBlockReflowContext.cpp @@ -307,7 +307,7 @@ nsBlockReflowContext::ReflowBlock(const LogicalRect& aSpace, mOuterReflowInput.mFloatManager->Translate(-tI, -tB); #ifdef DEBUG - if (!NS_INLINE_IS_BREAK_BEFORE(aFrameReflowStatus)) { + if (!aFrameReflowStatus.IsInlineBreakBefore()) { if ((CRAZY_SIZE(mMetrics.ISize(mWritingMode)) || CRAZY_SIZE(mMetrics.BSize(mWritingMode))) && !mFrame->GetParent()->IsCrazySizeAssertSuppressed()) { @@ -330,7 +330,7 @@ nsBlockReflowContext::ReflowBlock(const LogicalRect& aSpace, mMetrics.SetOverflowAreasToDesiredBounds(); } - if (!NS_INLINE_IS_BREAK_BEFORE(aFrameReflowStatus) || + if (!aFrameReflowStatus.IsInlineBreakBefore() || (mFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) { // If frame is complete and has a next-in-flow, we need to delete // them now. Do not do this when a break-before is signaled because diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp index edfd2cf07df5..015d008489a7 100644 --- a/layout/generic/nsContainerFrame.cpp +++ b/layout/generic/nsContainerFrame.cpp @@ -1029,7 +1029,7 @@ nsContainerFrame::ReflowChild(nsIFrame* aKidFrame, // If the child frame is complete, delete any next-in-flows, // but only if the NO_DELETE_NEXT_IN_FLOW flag isn't set. - if (!NS_INLINE_IS_BREAK_BEFORE(aStatus) && + if (!aStatus.IsInlineBreakBefore() && aStatus.IsFullyComplete() && !(aFlags & NS_FRAME_NO_DELETE_NEXT_IN_FLOW_CHILD)) { nsIFrame* kidNextInFlow = aKidFrame->GetNextInFlow(); diff --git a/layout/generic/nsFirstLetterFrame.cpp b/layout/generic/nsFirstLetterFrame.cpp index ab34947ee176..91dcf19aa2d5 100644 --- a/layout/generic/nsFirstLetterFrame.cpp +++ b/layout/generic/nsFirstLetterFrame.cpp @@ -265,7 +265,7 @@ nsFirstLetterFrame::Reflow(nsPresContext* aPresContext, } } - if (!NS_INLINE_IS_BREAK_BEFORE(aReflowStatus)) { + if (!aReflowStatus.IsInlineBreakBefore()) { // Create a continuation or remove existing continuations based on // the reflow completion status. if (aReflowStatus.IsComplete()) { diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index 1bc857a656fd..3ba70935afc4 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -5625,16 +5625,16 @@ nsGridContainerFrame::ReflowRowsInFragmentainer( GridLineSide::eAfterGridGap); ReflowInFlowChild(child, info, aContainerSize, Some(bSize), &aFragmentainer, aState, aContentArea, aDesiredSize, childStatus); - MOZ_ASSERT(NS_INLINE_IS_BREAK_BEFORE(childStatus) || + MOZ_ASSERT(childStatus.IsInlineBreakBefore() || !childStatus.IsFullyComplete() || !child->GetNextInFlow(), "fully-complete reflow should destroy any NIFs"); - if (NS_INLINE_IS_BREAK_BEFORE(childStatus)) { + if (childStatus.IsInlineBreakBefore()) { MOZ_ASSERT(!child->GetPrevInFlow(), "continuations should never report BREAK_BEFORE status"); MOZ_ASSERT(!aFragmentainer.mIsTopOfPage, - "got NS_INLINE_IS_BREAK_BEFORE at top of page"); + "got IsInlineBreakBefore() at top of page"); if (!didGrowRow) { if (rowCanGrow) { // Grow this row and restart with the next row as |aEndRow|. diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index fad52442c94b..2ed5179f0847 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -322,6 +322,7 @@ public: // Suppose a break is requested. When mInlineBreakAfter is set, the break // should occur after the frame just reflowed; when mInlineBreakAfter is // clear, the break should occur before the frame just reflowed. + bool IsInlineBreakBefore() const { return mInlineBreak && !mInlineBreakAfter; } StyleClear BreakType() const { return mBreakType; } // Set the inline line-break-before status, and reset other bit flags. The @@ -377,9 +378,6 @@ private: #define NS_INLINE_IS_BREAK_AFTER(_status) \ (0 != ((_status) & NS_INLINE_BREAK_AFTER)) -#define NS_INLINE_IS_BREAK_BEFORE(_status) \ - (NS_INLINE_BREAK == ((_status) & (NS_INLINE_BREAK|NS_INLINE_BREAK_AFTER))) - #define NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aMetrics) \ aStatus.UpdateTruncated(aReflowInput, aMetrics); diff --git a/layout/generic/nsInlineFrame.cpp b/layout/generic/nsInlineFrame.cpp index d0d40ff234bb..ff74b9d99948 100644 --- a/layout/generic/nsInlineFrame.cpp +++ b/layout/generic/nsInlineFrame.cpp @@ -803,8 +803,8 @@ nsInlineFrame::ReflowInlineFrame(nsPresContext* aPresContext, bool reflowingFirstLetter = lineLayout->GetFirstLetterStyleOK(); bool pushedFrame; lineLayout->ReflowFrame(aFrame, aStatus, nullptr, pushedFrame); - - if (NS_INLINE_IS_BREAK_BEFORE(aStatus)) { + + if (aStatus.IsInlineBreakBefore()) { if (aFrame != mFrames.FirstChild()) { // Change break-before status into break-after since we have // already placed at least one child frame. This preserves the diff --git a/layout/generic/nsLineLayout.cpp b/layout/generic/nsLineLayout.cpp index 14c52d2eb252..7393da29ae9c 100644 --- a/layout/generic/nsLineLayout.cpp +++ b/layout/generic/nsLineLayout.cpp @@ -1028,7 +1028,7 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame, #ifdef DEBUG // Note: break-before means ignore the reflow metrics since the // frame will be reflowed another time. - if (!NS_INLINE_IS_BREAK_BEFORE(aReflowStatus)) { + if (!aReflowStatus.IsInlineBreakBefore()) { if ((CRAZY_SIZE(reflowOutput.ISize(lineWM)) || CRAZY_SIZE(reflowOutput.BSize(lineWM))) && !LineContainerFrame()->GetParent()->IsCrazySizeAssertSuppressed()) { @@ -1067,7 +1067,7 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame, *aMetrics = reflowOutput; } - if (!NS_INLINE_IS_BREAK_BEFORE(aReflowStatus)) { + if (!aReflowStatus.IsInlineBreakBefore()) { // If frame is complete and has a next-in-flow, we need to delete // them now. Do not do this when a break-before is signaled because // the frame is going to get reflowed again (and may end up wanting diff --git a/layout/generic/nsRubyBaseContainerFrame.cpp b/layout/generic/nsRubyBaseContainerFrame.cpp index 5951bc3184c7..88606c8fcb44 100644 --- a/layout/generic/nsRubyBaseContainerFrame.cpp +++ b/layout/generic/nsRubyBaseContainerFrame.cpp @@ -404,9 +404,9 @@ nsRubyBaseContainerFrame::Reflow(nsPresContext* aPresContext, // If there exists any span, the columns must either be completely // reflowed, or be not reflowed at all. - MOZ_ASSERT(NS_INLINE_IS_BREAK_BEFORE(aStatus) || + MOZ_ASSERT(aStatus.IsInlineBreakBefore() || aStatus.IsComplete() || !hasSpan); - if (!NS_INLINE_IS_BREAK_BEFORE(aStatus) && + if (!aStatus.IsInlineBreakBefore() && aStatus.IsComplete() && hasSpan) { // Reflow spans RubyReflowInput reflowInput = { @@ -480,7 +480,7 @@ nsRubyBaseContainerFrame::ReflowColumns(const RubyReflowInput& aReflowInput, for (; !e.AtEnd(); e.Next()) { e.GetColumn(column); icoord += ReflowOneColumn(aReflowInput, columnIndex, column, reflowStatus); - if (!NS_INLINE_IS_BREAK_BEFORE(reflowStatus)) { + if (!reflowStatus.IsInlineBreakBefore()) { columnIndex++; } if (NS_INLINE_IS_BREAK(reflowStatus)) { @@ -504,7 +504,7 @@ nsRubyBaseContainerFrame::ReflowColumns(const RubyReflowInput& aReflowInput, break; } icoord += ReflowOneColumn(aReflowInput, columnIndex, column, reflowStatus); - if (!NS_INLINE_IS_BREAK_BEFORE(reflowStatus)) { + if (!reflowStatus.IsInlineBreakBefore()) { columnIndex++; } } @@ -520,7 +520,7 @@ nsRubyBaseContainerFrame::ReflowColumns(const RubyReflowInput& aReflowInput, aStatus.SetIncomplete(); } - if (NS_INLINE_IS_BREAK_BEFORE(reflowStatus)) { + if (reflowStatus.IsInlineBreakBefore()) { if (!columnIndex || !aReflowInput.mAllowLineBreak) { // If no column has been placed yet, or we have any span, // the whole container should be in the next line. diff --git a/layout/generic/nsRubyFrame.cpp b/layout/generic/nsRubyFrame.cpp index 2753809165c7..e58138f57af3 100644 --- a/layout/generic/nsRubyFrame.cpp +++ b/layout/generic/nsRubyFrame.cpp @@ -205,7 +205,7 @@ nsRubyFrame::ReflowSegment(nsPresContext* aPresContext, aReflowInput.mLineLayout->ReflowFrame(aBaseContainer, aStatus, &baseMetrics, pushedFrame); - if (NS_INLINE_IS_BREAK_BEFORE(aStatus)) { + if (aStatus.IsInlineBreakBefore()) { if (aBaseContainer != mFrames.FirstChild()) { // Some segments may have been reflowed before, hence it is not // a break-before for the ruby container. diff --git a/layout/reftests/css-grid/grid-fragmentation-006-ref.html b/layout/reftests/css-grid/grid-fragmentation-006-ref.html index 56808bfdfe3a..598d50ae898a 100644 --- a/layout/reftests/css-grid/grid-fragmentation-006-ref.html +++ b/layout/reftests/css-grid/grid-fragmentation-006-ref.html @@ -47,7 +47,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; } -
+
@@ -68,14 +68,14 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
-
+
@@ -86,7 +86,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -94,7 +94,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -102,7 +102,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
diff --git a/layout/reftests/css-grid/grid-fragmentation-006.html b/layout/reftests/css-grid/grid-fragmentation-006.html index f7d51d5d3e7f..ccb22d3bbb33 100644 --- a/layout/reftests/css-grid/grid-fragmentation-006.html +++ b/layout/reftests/css-grid/grid-fragmentation-006.html @@ -46,7 +46,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; } -
+
@@ -67,35 +67,35 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
-
+
-
+
-
+
-
+
diff --git a/layout/reftests/css-grid/grid-fragmentation-007.html b/layout/reftests/css-grid/grid-fragmentation-007.html index 90b8b32e6a2b..1e2e2d6e47bd 100644 --- a/layout/reftests/css-grid/grid-fragmentation-007.html +++ b/layout/reftests/css-grid/grid-fragmentation-007.html @@ -46,7 +46,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; } -
+
@@ -55,7 +55,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -64,7 +64,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -73,7 +73,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -82,7 +82,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -91,7 +91,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
diff --git a/layout/reftests/css-grid/grid-fragmentation-019.html b/layout/reftests/css-grid/grid-fragmentation-019.html index 8746e0bb3c2c..b8f9f1805fa9 100644 --- a/layout/reftests/css-grid/grid-fragmentation-019.html +++ b/layout/reftests/css-grid/grid-fragmentation-019.html @@ -47,7 +47,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; } -
+
@@ -56,7 +56,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -65,7 +65,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -74,7 +74,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -83,7 +83,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -92,7 +92,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
diff --git a/layout/reftests/css-grid/grid-fragmentation-022.html b/layout/reftests/css-grid/grid-fragmentation-022.html index d96bfa4dab8b..ac31a2ac8e2a 100644 --- a/layout/reftests/css-grid/grid-fragmentation-022.html +++ b/layout/reftests/css-grid/grid-fragmentation-022.html @@ -46,7 +46,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; } -
+
@@ -55,7 +55,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -64,7 +64,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -73,7 +73,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -82,7 +82,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -91,7 +91,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
diff --git a/layout/reftests/css-grid/grid-fragmentation-023.html b/layout/reftests/css-grid/grid-fragmentation-023.html index 4a667d5ff0df..fb85c5ad4fef 100644 --- a/layout/reftests/css-grid/grid-fragmentation-023.html +++ b/layout/reftests/css-grid/grid-fragmentation-023.html @@ -47,7 +47,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; } -
+
@@ -56,7 +56,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -65,7 +65,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -74,7 +74,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -83,7 +83,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -92,7 +92,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
diff --git a/layout/reftests/css-grid/grid-fragmentation-024.html b/layout/reftests/css-grid/grid-fragmentation-024.html index 43b9692a2dcb..2cc4a9dfdc20 100644 --- a/layout/reftests/css-grid/grid-fragmentation-024.html +++ b/layout/reftests/css-grid/grid-fragmentation-024.html @@ -47,7 +47,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; } -
+
@@ -56,7 +56,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -65,7 +65,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -74,7 +74,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -83,7 +83,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -92,7 +92,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -101,7 +101,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -111,7 +111,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
diff --git a/layout/reftests/css-grid/grid-fragmentation-025.html b/layout/reftests/css-grid/grid-fragmentation-025.html index 6741fe78f1eb..0a601d95f394 100644 --- a/layout/reftests/css-grid/grid-fragmentation-025.html +++ b/layout/reftests/css-grid/grid-fragmentation-025.html @@ -47,7 +47,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; } -
+
@@ -56,7 +56,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -65,7 +65,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -74,7 +74,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -83,7 +83,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -92,7 +92,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -101,7 +101,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -111,7 +111,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
diff --git a/layout/reftests/css-grid/grid-fragmentation-027.html b/layout/reftests/css-grid/grid-fragmentation-027.html index c7bf664f5f13..6115075bf2f5 100644 --- a/layout/reftests/css-grid/grid-fragmentation-027.html +++ b/layout/reftests/css-grid/grid-fragmentation-027.html @@ -48,7 +48,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; } -
+
@@ -57,7 +57,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -66,7 +66,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -75,7 +75,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -84,7 +84,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -93,7 +93,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -102,7 +102,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -112,7 +112,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
diff --git a/layout/reftests/css-grid/grid-fragmentation-028.html b/layout/reftests/css-grid/grid-fragmentation-028.html index b8fdb18ae6d4..bebf8d0df713 100644 --- a/layout/reftests/css-grid/grid-fragmentation-028.html +++ b/layout/reftests/css-grid/grid-fragmentation-028.html @@ -47,7 +47,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; } -
+
@@ -56,7 +56,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -65,7 +65,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -74,7 +74,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -83,7 +83,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -92,7 +92,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -101,7 +101,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -111,7 +111,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
diff --git a/layout/reftests/css-grid/grid-fragmentation-030-ref.html b/layout/reftests/css-grid/grid-fragmentation-030-ref.html index 311f9e9ea3c2..f51066fe6f9f 100644 --- a/layout/reftests/css-grid/grid-fragmentation-030-ref.html +++ b/layout/reftests/css-grid/grid-fragmentation-030-ref.html @@ -43,7 +43,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; } -
+
@@ -52,7 +52,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -61,7 +61,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -70,7 +70,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -79,7 +79,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -88,7 +88,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -97,7 +97,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
diff --git a/layout/reftests/css-grid/grid-fragmentation-030.html b/layout/reftests/css-grid/grid-fragmentation-030.html index 6dec52168e37..0a9f426bc1d0 100644 --- a/layout/reftests/css-grid/grid-fragmentation-030.html +++ b/layout/reftests/css-grid/grid-fragmentation-030.html @@ -46,7 +46,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; } -
+
@@ -55,7 +55,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -64,7 +64,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -73,7 +73,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -82,7 +82,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -91,7 +91,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -100,7 +100,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
diff --git a/layout/reftests/css-grid/grid-fragmentation-031-ref.html b/layout/reftests/css-grid/grid-fragmentation-031-ref.html index 78f9a21d4812..e151ce51215a 100644 --- a/layout/reftests/css-grid/grid-fragmentation-031-ref.html +++ b/layout/reftests/css-grid/grid-fragmentation-031-ref.html @@ -46,7 +46,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; } -
+
@@ -55,7 +55,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -65,7 +65,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -74,7 +74,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -83,7 +83,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -92,7 +92,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -101,7 +101,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
diff --git a/layout/reftests/css-grid/grid-fragmentation-031.html b/layout/reftests/css-grid/grid-fragmentation-031.html index 10f8f52e3751..f922beb6e74f 100644 --- a/layout/reftests/css-grid/grid-fragmentation-031.html +++ b/layout/reftests/css-grid/grid-fragmentation-031.html @@ -46,7 +46,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; } -
+
@@ -55,7 +55,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -64,7 +64,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -73,7 +73,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -82,7 +82,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -91,7 +91,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
@@ -100,7 +100,7 @@ i { display:block; height:10px; margin-top:7px; background:blue; }
-
+
diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index 892f901318cf..1b8296619d67 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -3171,7 +3171,7 @@ nsTableFrame::ReflowChildren(TableReflowInput& aReflowInput, // see if the rowgroup did not fit on this page might be pushed on // the next page if (isPaginated && - (NS_INLINE_IS_BREAK_BEFORE(aStatus) || + (aStatus.IsInlineBreakBefore() || (aStatus.IsComplete() && (NS_UNCONSTRAINEDSIZE != kidReflowInput.AvailableHeight()) && kidReflowInput.AvailableHeight() < desiredSize.Height()))) { diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp index 64152230d286..3341303c30e8 100644 --- a/layout/tables/nsTableRowGroupFrame.cpp +++ b/layout/tables/nsTableRowGroupFrame.cpp @@ -1211,7 +1211,7 @@ nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext, // reflowed with a constrained height yet (we will find out when SplitSpanningCells is // called below) if (rowMetrics.Height() > availSize.height || - (NS_INLINE_IS_BREAK_BEFORE(aStatus) && !aRowForcedPageBreak)) { + (aStatus.IsInlineBreakBefore() && !aRowForcedPageBreak)) { // cases (1) and (2) if (isTopOfPage) { // We're on top of the page, so keep the row on this page. There will be data loss. From 8f66d2167b48bf860165910265c3b03279f95f56 Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Tue, 14 Feb 2017 16:22:04 +0800 Subject: [PATCH 103/234] Bug 775624 Part 17 - Convert NS_INLINE_IS_BREAK_AFTER to a method. r=dholbert MozReview-Commit-ID: CD9uuOC3CzP --HG-- extra : rebase_source : e7a12a1b37f591ba33e4ed8e73502f7cddf5d619 --- layout/generic/nsBlockFrame.cpp | 2 +- layout/generic/nsGridContainerFrame.cpp | 2 +- layout/generic/nsIFrame.h | 5 +---- layout/generic/nsInlineFrame.cpp | 2 +- layout/generic/nsRubyBaseContainerFrame.cpp | 4 ++-- layout/generic/nsRubyFrame.cpp | 2 +- 6 files changed, 7 insertions(+), 10 deletions(-) diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index f93e6b20ebc5..382ae25b5e28 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -4234,7 +4234,7 @@ nsBlockFrame::ReflowInlineFrame(BlockReflowInput& aState, // Split line, but after the frame just reflowed SplitLine(aState, aLineLayout, aLine, aFrame->GetNextSibling(), aLineReflowStatus); - if (NS_INLINE_IS_BREAK_AFTER(frameReflowStatus) && + if (frameReflowStatus.IsInlineBreakAfter() && !aLineLayout.GetLineEndsInBR()) { aLineLayout.SetDirtyNextLine(); } diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index 3ba70935afc4..70caa106ceeb 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -5679,7 +5679,7 @@ nsGridContainerFrame::ReflowRowsInFragmentainer( NS_ERROR("got BREAK_BEFORE again after growing the row?"); childStatus.SetIncomplete(); } - } else if (NS_INLINE_IS_BREAK_AFTER(childStatus)) { + } else if (childStatus.IsInlineBreakAfter()) { MOZ_ASSERT_UNREACHABLE("unexpected child reflow status"); } diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 2ed5179f0847..681110bb977c 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -323,6 +323,7 @@ public: // should occur after the frame just reflowed; when mInlineBreakAfter is // clear, the break should occur before the frame just reflowed. bool IsInlineBreakBefore() const { return mInlineBreak && !mInlineBreakAfter; } + bool IsInlineBreakAfter() const { return mInlineBreak && mInlineBreakAfter; } StyleClear BreakType() const { return mBreakType; } // Set the inline line-break-before status, and reset other bit flags. The @@ -364,7 +365,6 @@ private: #define NS_FRAME_OVERFLOW_INCOMPLETE 0x4 #define NS_INLINE_BREAK 0x0100 -#define NS_INLINE_BREAK_AFTER 0x0200 // Set when a break was induced by completion of a first-letter #define NS_INLINE_BREAK_FIRST_LETTER_COMPLETE 0x10000 @@ -375,9 +375,6 @@ private: #define NS_INLINE_IS_BREAK(_status) \ (0 != ((_status) & NS_INLINE_BREAK)) -#define NS_INLINE_IS_BREAK_AFTER(_status) \ - (0 != ((_status) & NS_INLINE_BREAK_AFTER)) - #define NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aMetrics) \ aStatus.UpdateTruncated(aReflowInput, aMetrics); diff --git a/layout/generic/nsInlineFrame.cpp b/layout/generic/nsInlineFrame.cpp index ff74b9d99948..cfeb33cbf207 100644 --- a/layout/generic/nsInlineFrame.cpp +++ b/layout/generic/nsInlineFrame.cpp @@ -827,7 +827,7 @@ nsInlineFrame::ReflowInlineFrame(nsPresContext* aPresContext, CreateNextInFlow(aFrame); } - if (NS_INLINE_IS_BREAK_AFTER(aStatus)) { + if (aStatus.IsInlineBreakAfter()) { nsIFrame* nextFrame = aFrame->GetNextSibling(); if (nextFrame) { aStatus.SetIncomplete(); diff --git a/layout/generic/nsRubyBaseContainerFrame.cpp b/layout/generic/nsRubyBaseContainerFrame.cpp index 88606c8fcb44..c183a5f0d673 100644 --- a/layout/generic/nsRubyBaseContainerFrame.cpp +++ b/layout/generic/nsRubyBaseContainerFrame.cpp @@ -509,7 +509,7 @@ nsRubyBaseContainerFrame::ReflowColumns(const RubyReflowInput& aReflowInput, } } - if (!e.AtEnd() && NS_INLINE_IS_BREAK_AFTER(reflowStatus)) { + if (!e.AtEnd() && reflowStatus.IsInlineBreakAfter()) { // The current column has been successfully placed. // Skip to the next column and mark break before. e.Next(); @@ -559,7 +559,7 @@ nsRubyBaseContainerFrame::ReflowColumns(const RubyReflowInput& aReflowInput, textFrame, textFrame->GetPrevSibling()); } } - } else if (NS_INLINE_IS_BREAK_AFTER(reflowStatus)) { + } else if (reflowStatus.IsInlineBreakAfter()) { // |reflowStatus| being break after here may only happen when // there is a break after the column just pulled, or the whole // segment has been completely reflowed. In those cases, we do diff --git a/layout/generic/nsRubyFrame.cpp b/layout/generic/nsRubyFrame.cpp index e58138f57af3..84030b6869eb 100644 --- a/layout/generic/nsRubyFrame.cpp +++ b/layout/generic/nsRubyFrame.cpp @@ -224,7 +224,7 @@ nsRubyFrame::ReflowSegment(nsPresContext* aPresContext, // break occurs. Break before has been processed above. However, // it is possible that break after happens with the frame reflow // completed. It happens if there is a force break at the end. - MOZ_ASSERT(NS_INLINE_IS_BREAK_AFTER(aStatus)); + MOZ_ASSERT(aStatus.IsInlineBreakAfter()); // Find the previous sibling which we will // insert new continuations after. nsIFrame* lastChild; From 65116ee49c155dae465948a56f32ecf757bad192 Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Tue, 14 Feb 2017 16:33:37 +0800 Subject: [PATCH 104/234] Bug 775624 Part 18 - Convert NS_INLINE_IS_BREAK to a method. r=dholbert MozReview-Commit-ID: 7Tw1BUjOYgg --HG-- extra : rebase_source : 907596f5a59dea709063d1f329a2155a430f41fc --- layout/generic/nsBlockFrame.cpp | 4 ++-- layout/generic/nsIFrame.h | 9 +-------- layout/generic/nsInlineFrame.cpp | 4 ++-- layout/generic/nsRubyBaseContainerFrame.cpp | 12 ++++++------ layout/generic/nsRubyFrame.cpp | 2 +- 5 files changed, 12 insertions(+), 19 deletions(-) diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index 382ae25b5e28..383ae7bc2166 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -259,7 +259,7 @@ RecordReflowStatus(bool aChildIsBlock, nsReflowStatus aFrameReflowStatus) // Compute new status uint32_t newS = record[index]; - if (NS_INLINE_IS_BREAK(aFrameReflowStatus)) { + if (aFrameReflowStatus.IsInlineBreak()) { if (aFrameReflowStatus.IsInlineBreakBefore()) { newS |= 1; } @@ -4181,7 +4181,7 @@ nsBlockFrame::ReflowInlineFrame(BlockReflowInput& aState, // block or we are an inline. This makes a total of 10 cases // (fortunately, there is some overlap). aLine->SetBreakTypeAfter(StyleClear::None); - if (NS_INLINE_IS_BREAK(frameReflowStatus) || + if (frameReflowStatus.IsInlineBreak() || StyleClear::None != aState.mFloatBreakType) { // Always abort the line reflow (because a line break is the // minimal amount of break we do). diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 681110bb977c..7ac7f243b2ff 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -318,6 +318,7 @@ public: } // mInlineBreak bit flag means a break is requested. + bool IsInlineBreak() const { return mInlineBreak; } // Suppose a break is requested. When mInlineBreakAfter is set, the break // should occur after the frame just reflowed; when mInlineBreakAfter is @@ -364,17 +365,9 @@ private: #define NS_FRAME_NOT_COMPLETE 0x1 #define NS_FRAME_OVERFLOW_INCOMPLETE 0x4 -#define NS_INLINE_BREAK 0x0100 - // Set when a break was induced by completion of a first-letter #define NS_INLINE_BREAK_FIRST_LETTER_COMPLETE 0x10000 -//---------------------------------------- -// Macros that use those bits - -#define NS_INLINE_IS_BREAK(_status) \ - (0 != ((_status) & NS_INLINE_BREAK)) - #define NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aMetrics) \ aStatus.UpdateTruncated(aReflowInput, aMetrics); diff --git a/layout/generic/nsInlineFrame.cpp b/layout/generic/nsInlineFrame.cpp index cfeb33cbf207..e0a8fca6a637 100644 --- a/layout/generic/nsInlineFrame.cpp +++ b/layout/generic/nsInlineFrame.cpp @@ -687,7 +687,7 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext, if (!done) { bool reflowingFirstLetter = lineLayout->GetFirstLetterStyleOK(); ReflowInlineFrame(aPresContext, aReflowInput, irs, frame, aStatus); - done = NS_INLINE_IS_BREAK(aStatus) || + done = aStatus.IsInlineBreak() || (!reflowingFirstLetter && aStatus.IsIncomplete()); if (done) { if (!irs.mSetParentPointer) { @@ -725,7 +725,7 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext, break; } ReflowInlineFrame(aPresContext, aReflowInput, irs, frame, aStatus); - if (NS_INLINE_IS_BREAK(aStatus) || + if (aStatus.IsInlineBreak() || (!reflowingFirstLetter && aStatus.IsIncomplete())) { break; } diff --git a/layout/generic/nsRubyBaseContainerFrame.cpp b/layout/generic/nsRubyBaseContainerFrame.cpp index c183a5f0d673..81f6e361c7a9 100644 --- a/layout/generic/nsRubyBaseContainerFrame.cpp +++ b/layout/generic/nsRubyBaseContainerFrame.cpp @@ -399,7 +399,7 @@ nsRubyBaseContainerFrame::Reflow(nsPresContext* aPresContext, // container could be non-zero because of non-empty ruby annotations. // XXX When bug 765861 gets fixed, this warning should be upgraded. NS_WARNING_ASSERTION( - NS_INLINE_IS_BREAK(aStatus) || isize == lineSpanSize || mFrames.IsEmpty(), + aStatus.IsInlineBreak() || isize == lineSpanSize || mFrames.IsEmpty(), "bad isize"); // If there exists any span, the columns must either be completely @@ -483,7 +483,7 @@ nsRubyBaseContainerFrame::ReflowColumns(const RubyReflowInput& aReflowInput, if (!reflowStatus.IsInlineBreakBefore()) { columnIndex++; } - if (NS_INLINE_IS_BREAK(reflowStatus)) { + if (reflowStatus.IsInlineBreak()) { break; } // We are not handling overflow here. @@ -492,7 +492,7 @@ nsRubyBaseContainerFrame::ReflowColumns(const RubyReflowInput& aReflowInput, bool isComplete = false; PullFrameState pullFrameState(this, aReflowInput.mTextContainers); - while (!NS_INLINE_IS_BREAK(reflowStatus)) { + while (!reflowStatus.IsInlineBreak()) { // We are not handling overflow here. MOZ_ASSERT(reflowStatus == NS_FRAME_COMPLETE); @@ -640,7 +640,7 @@ nsRubyBaseContainerFrame::ReflowOneColumn(const RubyReflowInput& aReflowInput, nsLineLayout* lineLayout = textReflowInputs[i]->mLineLayout; nscoord textIStart = lineLayout->GetCurrentICoord(); lineLayout->ReflowFrame(textFrame, reflowStatus, nullptr, pushedFrame); - if (MOZ_UNLIKELY(NS_INLINE_IS_BREAK(reflowStatus) || pushedFrame)) { + if (MOZ_UNLIKELY(reflowStatus.IsInlineBreak() || pushedFrame)) { MOZ_ASSERT_UNREACHABLE( "Any line break inside ruby box should have been suppressed"); // For safety, always drain the overflow list, so that @@ -662,7 +662,7 @@ nsRubyBaseContainerFrame::ReflowOneColumn(const RubyReflowInput& aReflowInput, nscoord baseIStart = lineLayout->GetCurrentICoord(); lineLayout->ReflowFrame(aColumn.mBaseFrame, reflowStatus, nullptr, pushedFrame); - if (MOZ_UNLIKELY(NS_INLINE_IS_BREAK(reflowStatus) || pushedFrame)) { + if (MOZ_UNLIKELY(reflowStatus.IsInlineBreak() || pushedFrame)) { MOZ_ASSERT_UNREACHABLE( "Any line break inside ruby box should have been suppressed"); // For safety, always drain the overflow list, so that @@ -828,7 +828,7 @@ nsRubyBaseContainerFrame::ReflowSpans(const RubyReflowInput& aReflowInput) MOZ_ASSERT(lineLayout->GetCurrentICoord() == 0, "border/padding of rtc should have been suppressed"); lineLayout->ReflowFrame(rtFrame, reflowStatus, nullptr, pushedFrame); - MOZ_ASSERT(!NS_INLINE_IS_BREAK(reflowStatus) && !pushedFrame, + MOZ_ASSERT(!reflowStatus.IsInlineBreak() && !pushedFrame, "Any line break inside ruby box should has been suppressed"); spanISize = std::max(spanISize, lineLayout->GetCurrentICoord()); } diff --git a/layout/generic/nsRubyFrame.cpp b/layout/generic/nsRubyFrame.cpp index 84030b6869eb..43f5a635b55a 100644 --- a/layout/generic/nsRubyFrame.cpp +++ b/layout/generic/nsRubyFrame.cpp @@ -147,7 +147,7 @@ nsRubyFrame::Reflow(nsPresContext* aPresContext, for (RubySegmentEnumerator e(this); !e.AtEnd(); e.Next()) { ReflowSegment(aPresContext, aReflowInput, e.GetBaseContainer(), aStatus); - if (NS_INLINE_IS_BREAK(aStatus)) { + if (aStatus.IsInlineBreak()) { // A break occurs when reflowing the segment. // Don't continue reflowing more segments. break; From 37d27159afd16709ffb9d3b22a0d1860bf5a05d8 Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Tue, 14 Feb 2017 17:09:37 +0800 Subject: [PATCH 105/234] Bug 775624 Part 19 - Convert NS_INLINE_BREAK_FIRST_LETTER_COMPLETE to use bit-field and methods. r=dholbert MozReview-Commit-ID: k1CSWJNMns --HG-- extra : rebase_source : 1aa775a1e835f3d001f8b2093d0c4fb9f6651630 --- layout/generic/nsBlockFrame.cpp | 2 +- layout/generic/nsIFrame.h | 11 ++++++++--- layout/generic/nsTextFrame.cpp | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index 383ae7bc2166..e308561914e5 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -4255,7 +4255,7 @@ nsBlockFrame::ReflowInlineFrame(BlockReflowInput& aState, // If we just ended a first-letter frame or reflowed a placeholder then // don't split the line and don't stop the line reflow... // But if we are going to stop anyways we'd better split the line. - if ((!(frameReflowStatus & NS_INLINE_BREAK_FIRST_LETTER_COMPLETE) && + if ((!frameReflowStatus.FirstLetterComplete() && nsGkAtoms::placeholderFrame != aFrame->GetType()) || *aLineReflowStatus == LineReflowStatus::Stop) { // Split line after the current frame diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 7ac7f243b2ff..7bc1fe40e62d 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -209,6 +209,7 @@ public: , mTruncated(false) , mInlineBreak(false) , mInlineBreakAfter(false) + , mFirstLetterComplete(false) {} // Reset all the bit-fields. @@ -220,6 +221,7 @@ public: mTruncated = false; mInlineBreak = false; mInlineBreakAfter = false; + mFirstLetterComplete = false; } nsReflowStatus(uint32_t aStatus) @@ -345,6 +347,11 @@ public: mInlineBreakAfter = true; } + // mFirstLetterComplete bit flag means the break was induced by + // completion of a first-letter. + bool FirstLetterComplete() const { return mFirstLetterComplete; } + void SetFirstLetterComplete() { mFirstLetterComplete = true; } + private: uint32_t mStatus; @@ -359,15 +366,13 @@ private: // Inline break status bit flags. bool mInlineBreak : 1; bool mInlineBreakAfter : 1; + bool mFirstLetterComplete : 1; }; #define NS_FRAME_COMPLETE 0 // Note: not a bit! #define NS_FRAME_NOT_COMPLETE 0x1 #define NS_FRAME_OVERFLOW_INCOMPLETE 0x4 -// Set when a break was induced by completion of a first-letter -#define NS_INLINE_BREAK_FIRST_LETTER_COMPLETE 0x10000 - #define NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aMetrics) \ aStatus.UpdateTruncated(aReflowInput, aMetrics); diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index 2ed7f37b6af1..bdd34208e222 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -9560,7 +9560,7 @@ nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth, } if (completedFirstLetter) { aLineLayout.SetFirstLetterStyleOK(false); - aStatus |= NS_INLINE_BREAK_FIRST_LETTER_COMPLETE; + aStatus.SetFirstLetterComplete(); } // Updated the cached NewlineProperty, or delete it. From 19c8d3d9bf0e952200a22206cc8b5b5c2a3458da Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Tue, 14 Feb 2017 17:22:09 +0800 Subject: [PATCH 106/234] Bug 775624 Part 20 - Remove NS_FRAME_OVERFLOW_INCOMPLETE. r=dholbert MozReview-Commit-ID: ATzg0IdIjd8 --HG-- extra : rebase_source : f5e1e9a6e2ba8231962824c044a49e3abe64ab4f --- layout/generic/nsColumnSetFrame.cpp | 9 ++++++--- layout/generic/nsContainerFrame.h | 4 ++-- layout/generic/nsIFrame.h | 1 - 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/layout/generic/nsColumnSetFrame.cpp b/layout/generic/nsColumnSetFrame.cpp index a0252797b9b3..80c4aa12394c 100644 --- a/layout/generic/nsColumnSetFrame.cpp +++ b/layout/generic/nsColumnSetFrame.cpp @@ -584,9 +584,12 @@ nsColumnSetFrame::ReflowChildren(ReflowOutput& aDesiredSize, // If this is the last frame then make sure we get the right status nsIFrame* kidNext = child->GetNextSibling(); if (kidNext) { - aStatus = (kidNext->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER) - ? NS_FRAME_OVERFLOW_INCOMPLETE - : NS_FRAME_NOT_COMPLETE; + aStatus.Reset(); + if (kidNext->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER) { + aStatus.SetOverflowIncomplete(); + } else { + aStatus.SetIncomplete(); + } } else { aStatus = mLastFrameStatus; } diff --git a/layout/generic/nsContainerFrame.h b/layout/generic/nsContainerFrame.h index 93f20e70ae03..a815196420dd 100644 --- a/layout/generic/nsContainerFrame.h +++ b/layout/generic/nsContainerFrame.h @@ -328,7 +328,7 @@ public: * list (to be drained by the next-in-flow when it calls * ReflowOverflowContainerChildren). The parent continues reflow as if * the frame was complete once it ran out of computed height, but returns - * either an NS_FRAME_NOT_COMPLETE or NS_FRAME_OVERFLOW_INCOMPLETE reflow + * with either the mIncomplete or mOverflowIncomplete bit set in reflow * status to request a next-in-flow. The parent's next-in-flow is then * responsible for calling ReflowOverflowContainerChildren to (drain and) * reflow these overflow continuations. Overflow containers do not affect @@ -839,7 +839,7 @@ public: /** * This function should be called for each child that isn't reflowed. - * It increments our walker and sets the NS_FRAME_OVERFLOW_INCOMPLETE + * It increments our walker and sets the mOverflowIncomplete * reflow flag if it encounters an overflow continuation so that our * next-in-flow doesn't get prematurely deleted. It MUST be called on * each unreflowed child that has an overflow container continuation; diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 7bc1fe40e62d..4b85a2e70fcd 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -371,7 +371,6 @@ private: #define NS_FRAME_COMPLETE 0 // Note: not a bit! #define NS_FRAME_NOT_COMPLETE 0x1 -#define NS_FRAME_OVERFLOW_INCOMPLETE 0x4 #define NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aMetrics) \ aStatus.UpdateTruncated(aReflowInput, aMetrics); From f19bfc4b93e24348f39db20774474ce25aa22798 Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Tue, 14 Feb 2017 17:30:56 +0800 Subject: [PATCH 107/234] Bug 775624 Part 21 - Remove NS_FRAME_NOT_COMPLETE. r=dholbert To preserve the semantics, Reset() is called to clear other bits in the status prior to set the incomplete bit. Though some of them might not be necessary. MozReview-Commit-ID: InNDwcpp28A --HG-- extra : rebase_source : 833e44a5dbb447d82c67f715cd5b0b2e97a5c62d --- layout/generic/nsFrame.cpp | 5 ++--- layout/generic/nsIFrame.h | 3 +-- layout/generic/nsImageFrame.cpp | 3 ++- layout/generic/nsInlineFrame.cpp | 3 ++- layout/generic/nsTextFrame.cpp | 6 ++++-- layout/tables/nsTableFrame.cpp | 9 ++++++--- layout/tables/nsTableRowFrame.cpp | 6 ++++-- layout/tables/nsTableRowGroupFrame.cpp | 17 +++++++++++------ 8 files changed, 32 insertions(+), 20 deletions(-) diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 31b50f989e48..a85fbdc6711c 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -6759,13 +6759,12 @@ nsFrame::IsFrameTreeTooDeep(const ReflowInput& aReflowInput, aMetrics.mCarriedOutBEndMargin.Zero(); aMetrics.mOverflowAreas.Clear(); + aStatus.Reset(); if (GetNextInFlow()) { // Reflow depth might vary between reflows, so we might have // successfully reflowed and split this frame before. If so, we // shouldn't delete its continuations. - aStatus = NS_FRAME_NOT_COMPLETE; - } else { - aStatus = NS_FRAME_COMPLETE; + aStatus.SetIncomplete(); } return true; diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 4b85a2e70fcd..eef7bef7ba3d 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -370,7 +370,6 @@ private: }; #define NS_FRAME_COMPLETE 0 // Note: not a bit! -#define NS_FRAME_NOT_COMPLETE 0x1 #define NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aMetrics) \ aStatus.UpdateTruncated(aReflowInput, aMetrics); @@ -2349,7 +2348,7 @@ public: * frame state will be cleared. * * XXX This doesn't make sense. If the frame is reflowed but not complete, then - * the status should be NS_FRAME_NOT_COMPLETE and not NS_FRAME_COMPLETE + * the status should have mIncomplete bit set. * XXX Don't we want the semantics to dictate that we only call this once for * a given reflow? */ diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index 63e1123c147e..c1294c054c42 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -1012,7 +1012,8 @@ nsImageFrame::Reflow(nsPresContext* aPresContext, // our desired height was greater than 0, so to avoid infinite // splitting, use 1 pixel as the min aMetrics.Height() = std::max(nsPresContext::CSSPixelsToAppUnits(1), aReflowInput.AvailableHeight()); - aStatus = NS_FRAME_NOT_COMPLETE; + aStatus.Reset(); + aStatus.SetIncomplete(); } aMetrics.SetOverflowAreasToDesiredBounds(); diff --git a/layout/generic/nsInlineFrame.cpp b/layout/generic/nsInlineFrame.cpp index e0a8fca6a637..155ebac70cc1 100644 --- a/layout/generic/nsInlineFrame.cpp +++ b/layout/generic/nsInlineFrame.cpp @@ -720,7 +720,8 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext, #endif if (nullptr == frame) { if (!isComplete) { - aStatus = NS_FRAME_NOT_COMPLETE; + aStatus.Reset(); + aStatus.SetIncomplete(); } break; } diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index bdd34208e222..6ce38190a823 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -9545,8 +9545,10 @@ nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth, } // Compute reflow status - aStatus = contentLength == maxContentLength - ? NS_FRAME_COMPLETE : NS_FRAME_NOT_COMPLETE; + aStatus.Reset(); + if (contentLength != maxContentLength) { + aStatus.SetIncomplete(); + } if (charsFit == 0 && length > 0 && !usedHyphenation) { // Couldn't place any text diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index 1b8296619d67..75ea3f361f70 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -3098,7 +3098,8 @@ nsTableFrame::ReflowChildren(TableReflowInput& aReflowInput, tfoot->SetRepeatable(false); } PushChildren(rowGroups, childX); - aStatus = NS_FRAME_NOT_COMPLETE; + aStatus.Reset(); + aStatus.SetIncomplete(); break; } @@ -3194,7 +3195,8 @@ nsTableFrame::ReflowChildren(TableReflowInput& aReflowInput, else if (tfoot && tfoot->IsRepeatable()) { tfoot->SetRepeatable(false); } - aStatus = NS_FRAME_NOT_COMPLETE; + aStatus.Reset(); + aStatus.SetIncomplete(); PushChildren(rowGroups, childX + 1); aLastChildReflowed = kidFrame; break; @@ -3209,7 +3211,8 @@ nsTableFrame::ReflowChildren(TableReflowInput& aReflowInput, else if (tfoot && tfoot->IsRepeatable()) { tfoot->SetRepeatable(false); } - aStatus = NS_FRAME_NOT_COMPLETE; + aStatus.Reset(); + aStatus.SetIncomplete(); PushChildren(rowGroups, childX); aLastChildReflowed = prevKidFrame; break; diff --git a/layout/tables/nsTableRowFrame.cpp b/layout/tables/nsTableRowFrame.cpp index 5dbffdad7099..d3e02e6d7d0d 100644 --- a/layout/tables/nsTableRowFrame.cpp +++ b/layout/tables/nsTableRowFrame.cpp @@ -937,7 +937,8 @@ nsTableRowFrame::ReflowChildren(nsPresContext* aPresContext, // allow the table to determine if/how the table needs to be rebalanced // If any of the cells are not complete, then we're not complete if (status.IsIncomplete()) { - aStatus = NS_FRAME_NOT_COMPLETE; + aStatus.Reset(); + aStatus.SetIncomplete(); } } else { if (iCoord != origKidNormalPosition.I(wm)) { @@ -1026,7 +1027,8 @@ nsTableRowFrame::ReflowChildren(nsPresContext* aPresContext, iCoord += kidFrame->ISize(wm); if (kidFrame->GetNextInFlow()) { - aStatus = NS_FRAME_NOT_COMPLETE; + aStatus.Reset(); + aStatus.SetIncomplete(); } } ConsiderChildOverflow(aDesiredSize.mOverflowAreas, kidFrame); diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp index 3341303c30e8..4b502c25d9c5 100644 --- a/layout/tables/nsTableRowGroupFrame.cpp +++ b/layout/tables/nsTableRowGroupFrame.cpp @@ -1218,7 +1218,8 @@ nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext, // Push the row frame that follows nsTableRowFrame* nextRowFrame = rowFrame->GetNextRow(); if (nextRowFrame) { - aStatus = NS_FRAME_NOT_COMPLETE; + aStatus.Reset(); + aStatus.SetIncomplete(); } aDesiredSize.Height() += rowMetrics.Height(); if (prevRowFrame) @@ -1249,7 +1250,8 @@ nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext, spanningRowBottom = prevRowFrame->GetNormalRect().YMost(); lastRowThisPage = prevRowFrame; isTopOfPage = (lastRowThisPage == firstRowThisPage) && aReflowInput.mFlags.mIsTopOfPage; - aStatus = NS_FRAME_NOT_COMPLETE; + aStatus.Reset(); + aStatus.SetIncomplete(); } else { // We can't push children, so let our parent reflow us again with more space @@ -1289,7 +1291,8 @@ nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext, contRow = nullptr; nsTableRowFrame* oldLastRowThisPage = lastRowThisPage; lastRowThisPage = rowBefore; - aStatus = NS_FRAME_NOT_COMPLETE; + aStatus.Reset(); + aStatus.SetIncomplete(); // Call SplitSpanningCells again with rowBefore as the last row on the page SplitSpanningCells(*aPresContext, aReflowInput, *aTableFrame, @@ -1320,7 +1323,8 @@ nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext, else { aDesiredSize.Height() = std::max(aDesiredSize.Height(), bMost); if (contRow) { - aStatus = NS_FRAME_NOT_COMPLETE; + aStatus.Reset(); + aStatus.SetIncomplete(); } } if (aStatus.IsIncomplete() && !contRow) { @@ -1338,7 +1342,8 @@ nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext, nsTableRowFrame* nextRow = rowFrame->GetNextRow(); if (nextRow && nsTableFrame::PageBreakAfter(rowFrame, nextRow)) { PushChildren(nextRow, rowFrame); - aStatus = NS_FRAME_NOT_COMPLETE; + aStatus.Reset(); + aStatus.SetIncomplete(); break; } } @@ -1391,7 +1396,7 @@ nsTableRowGroupFrame::Reflow(nsPresContext* aPresContext, // not paginated ... we can't split across columns yet. if (aReflowInput.mFlags.mTableIsSplittable && NS_UNCONSTRAINEDSIZE != aReflowInput.AvailableHeight() && - (aStatus == NS_FRAME_NOT_COMPLETE || splitDueToPageBreak || + (aStatus.IsIncomplete() || splitDueToPageBreak || aDesiredSize.Height() > aReflowInput.AvailableHeight())) { // Nope, find a place to split the row group bool specialReflow = (bool)aReflowInput.mFlags.mSpecialBSizeReflow; From 8f840dc92366962111d07fd92b32b286a5b58255 Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Tue, 14 Feb 2017 17:55:48 +0800 Subject: [PATCH 108/234] Bug 775624 Part 22 - Remove NS_FRAME_COMPLETE. r=dholbert This patch is written by the following script with some manual adjustment to the comment in nsRubyTextContainerFrame.cpp and nsRubyFrame.cpp, and nsColumnSetFrame's constructor. function rename() { find layout\ -type f\ \( -name "*.cpp" -or\ -name "*.h" \)\ -exec sed -i -r "s/$1/$2/g" "{}" \; } rename "nsReflowStatus *([a-zA-Z0-9]*) = NS_FRAME_COMPLETE" "nsReflowStatus \1" rename "([a-zA-Z0-9.*]*) *= NS_FRAME_COMPLETE;" "\1.Reset();" rename "([a-zA-Z0-9.*]*) == NS_FRAME_COMPLETE" "\1.IsEmpty()" MozReview-Commit-ID: 9tqQAHvdQex --HG-- extra : rebase_source : 3119776946dc2c8350098b7bf9f3ceff29bdffb5 --- layout/base/PresShell.cpp | 2 +- layout/forms/nsComboboxControlFrame.cpp | 4 ++-- layout/forms/nsDateTimeControlFrame.cpp | 2 +- layout/forms/nsFieldSetFrame.cpp | 4 ++-- layout/forms/nsFormControlFrame.cpp | 2 +- layout/forms/nsHTMLButtonControlFrame.cpp | 4 ++-- layout/forms/nsMeterFrame.cpp | 2 +- layout/forms/nsNumberControlFrame.cpp | 2 +- layout/forms/nsProgressFrame.cpp | 2 +- layout/forms/nsRangeFrame.cpp | 2 +- layout/forms/nsTextControlFrame.cpp | 2 +- layout/generic/BRFrame.cpp | 2 +- layout/generic/BlockReflowInput.cpp | 2 +- layout/generic/ViewportFrame.cpp | 2 +- layout/generic/nsAbsoluteContainingBlock.cpp | 4 ++-- layout/generic/nsBackdropFrame.cpp | 2 +- layout/generic/nsBlockFrame.cpp | 12 ++++++------ layout/generic/nsBulletFrame.cpp | 2 +- layout/generic/nsCanvasFrame.cpp | 2 +- layout/generic/nsColumnSetFrame.cpp | 10 +++++----- layout/generic/nsFlexContainerFrame.cpp | 2 +- layout/generic/nsFrame.cpp | 6 +++--- layout/generic/nsFrameSetFrame.cpp | 8 ++++---- layout/generic/nsGfxScrollFrame.cpp | 2 +- layout/generic/nsGridContainerFrame.cpp | 10 +++++----- layout/generic/nsHTMLCanvasFrame.cpp | 2 +- layout/generic/nsIFrame.h | 13 +++++++++++-- layout/generic/nsImageFrame.cpp | 2 +- layout/generic/nsInlineFrame.cpp | 2 +- layout/generic/nsLeafFrame.cpp | 2 +- layout/generic/nsPageContentFrame.cpp | 4 ++-- layout/generic/nsPageFrame.cpp | 4 ++-- layout/generic/nsPlaceholderFrame.cpp | 2 +- layout/generic/nsPluginFrame.cpp | 6 +++--- layout/generic/nsRubyBaseContainerFrame.cpp | 10 +++++----- layout/generic/nsRubyFrame.cpp | 10 +++++----- layout/generic/nsRubyTextContainerFrame.cpp | 4 ++-- layout/generic/nsSimplePageSequenceFrame.cpp | 2 +- layout/generic/nsSubDocumentFrame.cpp | 2 +- layout/generic/nsTextFrame.cpp | 6 +++--- layout/generic/nsVideoFrame.cpp | 2 +- layout/mathml/nsMathMLContainerFrame.cpp | 2 +- layout/mathml/nsMathMLSelectedFrame.cpp | 2 +- layout/mathml/nsMathMLTokenFrame.cpp | 2 +- layout/mathml/nsMathMLmfencedFrame.cpp | 2 +- layout/mathml/nsMathMLmrootFrame.cpp | 4 ++-- layout/mathml/nsMathMLmspaceFrame.cpp | 2 +- layout/svg/nsSVGForeignObjectFrame.cpp | 2 +- layout/svg/nsSVGOuterSVGFrame.cpp | 2 +- layout/tables/nsTableCellFrame.cpp | 2 +- layout/tables/nsTableColFrame.cpp | 2 +- layout/tables/nsTableColGroupFrame.cpp | 2 +- layout/tables/nsTableFrame.cpp | 6 +++--- layout/tables/nsTableRowFrame.cpp | 2 +- layout/tables/nsTableRowGroupFrame.cpp | 8 ++++---- layout/tables/nsTableWrapperFrame.cpp | 2 +- layout/xul/nsBoxFrame.cpp | 4 ++-- layout/xul/nsLeafBoxFrame.cpp | 2 +- 58 files changed, 112 insertions(+), 103 deletions(-) diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp index f95badaa36a3..acbfee206365 100644 --- a/layout/base/PresShell.cpp +++ b/layout/base/PresShell.cpp @@ -9217,7 +9217,7 @@ PresShell::DoReflow(nsIFrame* target, bool aInterruptible) NS_ASSERTION(target == rootFrame || desiredSize.ScrollableOverflow().IsEqualEdges(boundsRelativeToTarget), "non-root reflow roots must not have scrollable overflow"); - NS_ASSERTION(status == NS_FRAME_COMPLETE, + NS_ASSERTION(status.IsEmpty(), "reflow roots should never split"); target->SetSize(boundsRelativeToTarget.Size()); diff --git a/layout/forms/nsComboboxControlFrame.cpp b/layout/forms/nsComboboxControlFrame.cpp index 5708c24b42d0..dc90e8bf77b2 100644 --- a/layout/forms/nsComboboxControlFrame.cpp +++ b/layout/forms/nsComboboxControlFrame.cpp @@ -901,7 +901,7 @@ nsComboboxControlFrame::Reflow(nsPresContext* aPresContext, !aStatus.IsFullyComplete()) { // This frame didn't fit inside a fragmentation container. Splitting // a nsComboboxControlFrame makes no sense, so we override the status here. - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); } } @@ -1328,7 +1328,7 @@ nsComboboxDisplayFrame::Reflow(nsPresContext* aPresContext, } state.SetComputedISize(computedISize); nsBlockFrame::Reflow(aPresContext, aDesiredSize, state, aStatus); - aStatus = NS_FRAME_COMPLETE; // this type of frame can't be split + aStatus.Reset(); // this type of frame can't be split } void diff --git a/layout/forms/nsDateTimeControlFrame.cpp b/layout/forms/nsDateTimeControlFrame.cpp index 19ae8eccbaed..7611f536693c 100644 --- a/layout/forms/nsDateTimeControlFrame.cpp +++ b/layout/forms/nsDateTimeControlFrame.cpp @@ -293,7 +293,7 @@ nsDateTimeControlFrame::Reflow(nsPresContext* aPresContext, FinishAndStoreOverflow(&aDesiredSize); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS, ("exit nsDateTimeControlFrame::Reflow: size=%d,%d", diff --git a/layout/forms/nsFieldSetFrame.cpp b/layout/forms/nsFieldSetFrame.cpp index 2279d3754d35..32f1cc38ac81 100644 --- a/layout/forms/nsFieldSetFrame.cpp +++ b/layout/forms/nsFieldSetFrame.cpp @@ -339,10 +339,10 @@ nsFieldSetFrame::Reflow(nsPresContext* aPresContext, "Should have a precomputed inline-size!"); // Initialize OUT parameter - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); nsOverflowAreas ocBounds; - nsReflowStatus ocStatus = NS_FRAME_COMPLETE; + nsReflowStatus ocStatus; if (GetPrevInFlow()) { ReflowOverflowContainerChildren(aPresContext, aReflowInput, ocBounds, 0, ocStatus); diff --git a/layout/forms/nsFormControlFrame.cpp b/layout/forms/nsFormControlFrame.cpp index a31f2c541e19..8acecb40cbbe 100644 --- a/layout/forms/nsFormControlFrame.cpp +++ b/layout/forms/nsFormControlFrame.cpp @@ -131,7 +131,7 @@ nsFormControlFrame::Reflow(nsPresContext* aPresContext, RegUnRegAccessKey(static_cast(this), true); } - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); aDesiredSize.SetSize(aReflowInput.GetWritingMode(), aReflowInput.ComputedSizeWithBorderPadding()); diff --git a/layout/forms/nsHTMLButtonControlFrame.cpp b/layout/forms/nsHTMLButtonControlFrame.cpp index da7ef19ee60a..7f1eb85d37cb 100644 --- a/layout/forms/nsHTMLButtonControlFrame.cpp +++ b/layout/forms/nsHTMLButtonControlFrame.cpp @@ -214,13 +214,13 @@ nsHTMLButtonControlFrame::Reflow(nsPresContext* aPresContext, // else, we ignore child overflow -- anything that overflows beyond our // own border-box will get clipped when painting. - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); FinishReflowWithAbsoluteFrames(aPresContext, aDesiredSize, aReflowInput, aStatus); // We're always complete and we don't support overflow containers // so we shouldn't have a next-in-flow ever. - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); MOZ_ASSERT(!GetNextInFlow()); NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize); diff --git a/layout/forms/nsMeterFrame.cpp b/layout/forms/nsMeterFrame.cpp index 6ef362820f71..ff25cce4b84c 100644 --- a/layout/forms/nsMeterFrame.cpp +++ b/layout/forms/nsMeterFrame.cpp @@ -128,7 +128,7 @@ nsMeterFrame::Reflow(nsPresContext* aPresContext, ConsiderChildOverflow(aDesiredSize.mOverflowAreas, barFrame); FinishAndStoreOverflow(&aDesiredSize); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize); } diff --git a/layout/forms/nsNumberControlFrame.cpp b/layout/forms/nsNumberControlFrame.cpp index 5cbc722ea8b4..90146771c409 100644 --- a/layout/forms/nsNumberControlFrame.cpp +++ b/layout/forms/nsNumberControlFrame.cpp @@ -242,7 +242,7 @@ nsNumberControlFrame::Reflow(nsPresContext* aPresContext, FinishAndStoreOverflow(&aDesiredSize); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize); } diff --git a/layout/forms/nsProgressFrame.cpp b/layout/forms/nsProgressFrame.cpp index 6d6db7a1fdb9..c931c705dc44 100644 --- a/layout/forms/nsProgressFrame.cpp +++ b/layout/forms/nsProgressFrame.cpp @@ -137,7 +137,7 @@ nsProgressFrame::Reflow(nsPresContext* aPresContext, FinishAndStoreOverflow(&aDesiredSize); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize); } diff --git a/layout/forms/nsRangeFrame.cpp b/layout/forms/nsRangeFrame.cpp index 55418d3d8ba6..c6065c7f6c58 100644 --- a/layout/forms/nsRangeFrame.cpp +++ b/layout/forms/nsRangeFrame.cpp @@ -363,7 +363,7 @@ nsRangeFrame::Reflow(nsPresContext* aPresContext, FinishAndStoreOverflow(&aDesiredSize); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize); } diff --git a/layout/forms/nsTextControlFrame.cpp b/layout/forms/nsTextControlFrame.cpp index 3cfbc1e4ace0..cee4bbc5cb08 100644 --- a/layout/forms/nsTextControlFrame.cpp +++ b/layout/forms/nsTextControlFrame.cpp @@ -541,7 +541,7 @@ nsTextControlFrame::Reflow(nsPresContext* aPresContext, // take into account css properties that affect overflow handling FinishAndStoreOverflow(&aDesiredSize); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize); } diff --git a/layout/generic/BRFrame.cpp b/layout/generic/BRFrame.cpp index 04c85446d473..672c6f565f49 100644 --- a/layout/generic/BRFrame.cpp +++ b/layout/generic/BRFrame.cpp @@ -159,7 +159,7 @@ BRFrame::Reflow(nsPresContext* aPresContext, ll->SetLineEndsInBR(true); } else { - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); } aMetrics.SetSize(wm, finalSize); diff --git a/layout/generic/BlockReflowInput.cpp b/layout/generic/BlockReflowInput.cpp index e2336ff4c6a5..3d89b7535651 100644 --- a/layout/generic/BlockReflowInput.cpp +++ b/layout/generic/BlockReflowInput.cpp @@ -104,7 +104,7 @@ BlockReflowInput::BlockReflowInput(const ReflowInput& aReflowInput, FloatManager()->GetTranslation(mFloatManagerI, mFloatManagerB); FloatManager()->PushState(&mFloatManagerStateBefore); // never popped - mReflowStatus = NS_FRAME_COMPLETE; + mReflowStatus.Reset(); mNextInFlow = static_cast(mBlock->GetNextInFlow()); diff --git a/layout/generic/ViewportFrame.cpp b/layout/generic/ViewportFrame.cpp index 74374b30e0e1..a8638621f96e 100644 --- a/layout/generic/ViewportFrame.cpp +++ b/layout/generic/ViewportFrame.cpp @@ -290,7 +290,7 @@ ViewportFrame::Reflow(nsPresContext* aPresContext, NS_FRAME_TRACE_REFLOW_IN("ViewportFrame::Reflow"); // Initialize OUT parameters - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); // Because |Reflow| sets ComputedBSize() on the child to our // ComputedBSize(). diff --git a/layout/generic/nsAbsoluteContainingBlock.cpp b/layout/generic/nsAbsoluteContainingBlock.cpp index b4761ff5fd57..1f893f89eedc 100644 --- a/layout/generic/nsAbsoluteContainingBlock.cpp +++ b/layout/generic/nsAbsoluteContainingBlock.cpp @@ -119,7 +119,7 @@ nsAbsoluteContainingBlock::Reflow(nsContainerFrame* aDelegatingFrame, AbsPosReflowFlags aFlags, nsOverflowAreas* aOverflowAreas) { - nsReflowStatus reflowStatus = NS_FRAME_COMPLETE; + nsReflowStatus reflowStatus; const bool reflowAll = aReflowInput.ShouldReflowAllKids(); const bool isGrid = !!(aFlags & AbsPosReflowFlags::eIsGridContainerCB); @@ -132,7 +132,7 @@ nsAbsoluteContainingBlock::Reflow(nsContainerFrame* aDelegatingFrame, !!(aFlags & AbsPosReflowFlags::eCBHeightChanged)); if (kidNeedsReflow && !aPresContext->HasPendingInterrupt()) { // Reflow the frame - nsReflowStatus kidStatus = NS_FRAME_COMPLETE; + nsReflowStatus kidStatus; const nsRect& cb = isGrid ? nsGridContainerFrame::GridItemCB(kidFrame) : aContainingBlock; ReflowAbsoluteFrame(aDelegatingFrame, aPresContext, aReflowInput, cb, diff --git a/layout/generic/nsBackdropFrame.cpp b/layout/generic/nsBackdropFrame.cpp index 687c5b2e3666..0ddc7842edab 100644 --- a/layout/generic/nsBackdropFrame.cpp +++ b/layout/generic/nsBackdropFrame.cpp @@ -92,5 +92,5 @@ nsBackdropFrame::Reflow(nsPresContext* aPresContext, nscoord isize = aReflowInput.ComputedISize() + borderPadding.IStartEnd(wm); nscoord bsize = aReflowInput.ComputedBSize() + borderPadding.BStartEnd(wm); aDesiredSize.SetSize(wm, LogicalSize(wm, isize, bsize)); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); } diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index e308561914e5..f60466d2ed55 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -1195,7 +1195,7 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext, // Handle paginated overflow (see nsContainerFrame.h) nsOverflowAreas ocBounds; - nsReflowStatus ocStatus = NS_FRAME_COMPLETE; + nsReflowStatus ocStatus; if (GetPrevInFlow()) { ReflowOverflowContainerChildren(aPresContext, *reflowInput, ocBounds, 0, ocStatus); @@ -1209,7 +1209,7 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext, // Drain & handle pushed floats DrainPushedFloats(); nsOverflowAreas fcBounds; - nsReflowStatus fcStatus = NS_FRAME_COMPLETE; + nsReflowStatus fcStatus; ReflowPushedFloats(state, fcBounds, fcStatus); // If we're not dirty (which means we'll mark everything dirty later) @@ -3458,7 +3458,7 @@ nsBlockFrame::ReflowBlockFrame(BlockReflowInput& aState, aState.mReflowInput.mDiscoveredClearance; } - frameReflowStatus = NS_FRAME_COMPLETE; + frameReflowStatus.Reset(); brc.ReflowBlock(availSpace, applyBStartMargin, aState.mPrevBEndMargin, clearance, aState.IsAdjacentWithTop(), aLine.get(), *blockHtmlRI, frameReflowStatus, aState); @@ -6215,7 +6215,7 @@ nsBlockFrame::ReflowFloat(BlockReflowInput& aState, NS_PRECONDITION(aFloat->GetStateBits() & NS_FRAME_OUT_OF_FLOW, "aFloat must be an out-of-flow frame"); // Reflow the float. - aReflowStatus = NS_FRAME_COMPLETE; + aReflowStatus.Reset(); WritingMode wm = aState.mReflowInput.GetWritingMode(); #ifdef NOISY_FLOAT @@ -6282,7 +6282,7 @@ nsBlockFrame::ReflowFloat(BlockReflowInput& aState, (NS_UNCONSTRAINEDSIZE == aAdjustedAvailableSpace.BSize(wm))) { // An incomplete reflow status means we should split the float // if the height is constrained (bug 145305). - aReflowStatus = NS_FRAME_COMPLETE; + aReflowStatus.Reset(); } if (aReflowStatus.NextInFlowNeedsReflow()) { @@ -6294,7 +6294,7 @@ nsBlockFrame::ReflowFloat(BlockReflowInput& aState, // such frames simply means that there is more content to be // reflowed on the line. if (aReflowStatus.IsIncomplete()) - aReflowStatus = NS_FRAME_COMPLETE; + aReflowStatus.Reset(); } // Capture the margin and offsets information for the caller diff --git a/layout/generic/nsBulletFrame.cpp b/layout/generic/nsBulletFrame.cpp index 65ecdde454c7..372d6a2ec33f 100644 --- a/layout/generic/nsBulletFrame.cpp +++ b/layout/generic/nsBulletFrame.cpp @@ -1063,7 +1063,7 @@ nsBulletFrame::Reflow(nsPresContext* aPresContext, // 397294). aMetrics.SetOverflowAreasToDesiredBounds(); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aMetrics); } diff --git a/layout/generic/nsCanvasFrame.cpp b/layout/generic/nsCanvasFrame.cpp index 8bb48d772e0a..0bee60dd302f 100644 --- a/layout/generic/nsCanvasFrame.cpp +++ b/layout/generic/nsCanvasFrame.cpp @@ -649,7 +649,7 @@ nsCanvasFrame::Reflow(nsPresContext* aPresContext, NS_FRAME_TRACE_REFLOW_IN("nsCanvasFrame::Reflow"); // Initialize OUT parameter - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); nsCanvasFrame* prevCanvasFrame = static_cast (GetPrevInFlow()); diff --git a/layout/generic/nsColumnSetFrame.cpp b/layout/generic/nsColumnSetFrame.cpp index 80c4aa12394c..7809f72605b1 100644 --- a/layout/generic/nsColumnSetFrame.cpp +++ b/layout/generic/nsColumnSetFrame.cpp @@ -32,8 +32,8 @@ NS_NewColumnSetFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, nsFrame NS_IMPL_FRAMEARENA_HELPERS(nsColumnSetFrame) nsColumnSetFrame::nsColumnSetFrame(nsStyleContext* aContext) - : nsContainerFrame(aContext), mLastBalanceBSize(NS_INTRINSICSIZE), - mLastFrameStatus(NS_FRAME_COMPLETE) + : nsContainerFrame(aContext) + , mLastBalanceBSize(NS_INTRINSICSIZE) { } @@ -1036,7 +1036,7 @@ nsColumnSetFrame::Reflow(nsPresContext* aPresContext, DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); // Initialize OUT parameter - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); // Our children depend on our block-size if we have a fixed block-size. if (aReflowInput.ComputedBSize() != NS_AUTOHEIGHT) { @@ -1057,7 +1057,7 @@ nsColumnSetFrame::Reflow(nsPresContext* aPresContext, #endif nsOverflowAreas ocBounds; - nsReflowStatus ocStatus = NS_FRAME_COMPLETE; + nsReflowStatus ocStatus; if (GetPrevInFlow()) { ReflowOverflowContainerChildren(aPresContext, aReflowInput, ocBounds, 0, ocStatus); @@ -1102,7 +1102,7 @@ nsColumnSetFrame::Reflow(nsPresContext* aPresContext, aReflowInput.AvailableBSize() == NS_UNCONSTRAINEDSIZE) { // In this situation, we might be lying about our reflow status, because // our last kid (the one that got interrupted) was incomplete. Fix that. - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); } NS_ASSERTION(aStatus.IsFullyComplete() || diff --git a/layout/generic/nsFlexContainerFrame.cpp b/layout/generic/nsFlexContainerFrame.cpp index 18ef5824a975..70b2ad7290c8 100644 --- a/layout/generic/nsFlexContainerFrame.cpp +++ b/layout/generic/nsFlexContainerFrame.cpp @@ -4329,7 +4329,7 @@ nsFlexContainerFrame::DoFlexLayout(nsPresContext* aPresContext, nsTArray& aStruts, const FlexboxAxisTracker& aAxisTracker) { - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); LinkedList lines; nsTArray placeholderKids; diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index a85fbdc6711c..fa97d7449a23 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -5724,7 +5724,7 @@ nsFrame::Reflow(nsPresContext* aPresContext, MarkInReflow(); DO_GLOBAL_REFLOW_COUNT("nsFrame"); aDesiredSize.ClearSize(); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize); } @@ -9740,7 +9740,7 @@ nsFrame::DoXULLayout(nsBoxLayoutState& aState) AddStateBits(NS_FRAME_IN_REFLOW); // Set up a |reflowStatus| to pass into ReflowAbsoluteFrames // (just a dummy value; hopefully that's OK) - nsReflowStatus reflowStatus = NS_FRAME_COMPLETE; + nsReflowStatus reflowStatus; ReflowAbsoluteFrames(aState.PresContext(), desiredSize, reflowInput, reflowStatus); RemoveStateBits(NS_FRAME_IN_REFLOW); @@ -9777,7 +9777,7 @@ nsFrame::BoxReflow(nsBoxLayoutState& aState, #endif nsBoxLayoutMetrics *metrics = BoxMetrics(); - nsReflowStatus status = NS_FRAME_COMPLETE; + nsReflowStatus status; WritingMode wm = aDesiredSize.GetWritingMode(); bool needsReflow = NS_SUBTREE_DIRTY(this); diff --git a/layout/generic/nsFrameSetFrame.cpp b/layout/generic/nsFrameSetFrame.cpp index 9d5c513af8f3..a41633e857d4 100644 --- a/layout/generic/nsFrameSetFrame.cpp +++ b/layout/generic/nsFrameSetFrame.cpp @@ -849,7 +849,7 @@ nsHTMLFramesetFrame::Reflow(nsPresContext* aPresContext, // If the number of cols or rows has changed, the frame for the frameset // will be re-created. if (mNumRows != rows || mNumCols != cols) { - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); mDrag.UnSet(); NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize); return; @@ -1084,7 +1084,7 @@ nsHTMLFramesetFrame::Reflow(nsPresContext* aPresContext, mChildBorderColors.reset(); } - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); mDrag.UnSet(); aDesiredSize.SetOverflowAreasToDesiredBounds(); @@ -1394,7 +1394,7 @@ nsHTMLFramesetBorderFrame::Reflow(nsPresContext* aPresContext, SizeToAvailSize(aReflowInput, aDesiredSize); aDesiredSize.SetOverflowAreasToDesiredBounds(); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); } class nsDisplayFramesetBorder : public nsDisplayItem { @@ -1609,7 +1609,7 @@ nsHTMLFramesetBlankFrame::Reflow(nsPresContext* aPresContext, SizeToAvailSize(aReflowInput, aDesiredSize); aDesiredSize.SetOverflowAreasToDesiredBounds(); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); } class nsDisplayFramesetBlank : public nsDisplayItem { diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index 9ca009289a0f..6e676f7fbdac 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -1106,7 +1106,7 @@ nsHTMLScrollFrame::Reflow(nsPresContext* aPresContext, mHelper.UpdatePrevScrolledRect(); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize); mHelper.PostOverflowEvent(); } diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index 70caa106ceeb..4f271b392e82 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -5321,7 +5321,7 @@ nsGridContainerFrame::ReflowInFragmentainer(GridReflowInput& aState, Fragmentainer& aFragmentainer, const nsSize& aContainerSize) { - MOZ_ASSERT(aStatus == NS_FRAME_COMPLETE); + MOZ_ASSERT(aStatus.IsEmpty()); MOZ_ASSERT(aState.mReflowInput); // Collect our grid items and sort them in row order. Collect placeholders @@ -5397,7 +5397,7 @@ nsGridContainerFrame::ReflowInFragmentainer(GridReflowInput& aState, endRow = itemStartRow; isForcedBreak = true; // reset any BREAK_AFTER we found on an earlier item - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); break; // we're done since the items are sorted in row order } } @@ -5674,7 +5674,7 @@ nsGridContainerFrame::ReflowRowsInFragmentainer( continue; } NS_ERROR("got BREAK_BEFORE at top-of-page"); - childStatus = NS_FRAME_COMPLETE; + childStatus.Reset(); } else { NS_ERROR("got BREAK_BEFORE again after growing the row?"); childStatus.SetIncomplete(); @@ -5824,9 +5824,9 @@ nsGridContainerFrame::ReflowChildren(GridReflowInput& aState, { MOZ_ASSERT(aState.mReflowInput); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); nsOverflowAreas ocBounds; - nsReflowStatus ocStatus = NS_FRAME_COMPLETE; + nsReflowStatus ocStatus; if (GetPrevInFlow()) { ReflowOverflowContainerChildren(PresContext(), *aState.mReflowInput, ocBounds, 0, ocStatus, diff --git a/layout/generic/nsHTMLCanvasFrame.cpp b/layout/generic/nsHTMLCanvasFrame.cpp index bad3a710f8de..e41a8195260d 100644 --- a/layout/generic/nsHTMLCanvasFrame.cpp +++ b/layout/generic/nsHTMLCanvasFrame.cpp @@ -257,7 +257,7 @@ nsHTMLCanvasFrame::Reflow(nsPresContext* aPresContext, NS_PRECONDITION(mState & NS_FRAME_IN_REFLOW, "frame is not in reflow"); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); WritingMode wm = aReflowInput.GetWritingMode(); LogicalSize finalSize(wm, diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index eef7bef7ba3d..7c4914288b55 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -261,6 +261,17 @@ public: return !(*this == aRhs); } + // Return true if all flags are cleared. + bool IsEmpty() const { + return (!mIncomplete && + !mOverflowIncomplete && + !mNextInFlowNeedsReflow && + !mTruncated && + !mInlineBreak && + !mInlineBreakAfter && + !mFirstLetterComplete); + } + // mIncomplete bit flag means the frame does not map all its content, and // that the parent frame should create a continuing frame. If this bit // isn't set, it means the frame does map all its content. This bit is @@ -369,8 +380,6 @@ private: bool mFirstLetterComplete : 1; }; -#define NS_FRAME_COMPLETE 0 // Note: not a bit! - #define NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aMetrics) \ aStatus.UpdateTruncated(aReflowInput, aMetrics); diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index c1294c054c42..0d34bb33c420 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -959,7 +959,7 @@ nsImageFrame::Reflow(nsPresContext* aPresContext, NS_PRECONDITION(mState & NS_FRAME_IN_REFLOW, "frame is not in reflow"); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); // see if we have a frozen size (i.e. a fixed width and height) if (HaveFixedSize(aReflowInput)) { diff --git a/layout/generic/nsInlineFrame.cpp b/layout/generic/nsInlineFrame.cpp index 155ebac70cc1..5dc9ebf0e2da 100644 --- a/layout/generic/nsInlineFrame.cpp +++ b/layout/generic/nsInlineFrame.cpp @@ -574,7 +574,7 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext, ReflowOutput& aMetrics, nsReflowStatus& aStatus) { - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); nsLineLayout* lineLayout = aReflowInput.mLineLayout; bool inFirstLine = aReflowInput.mLineLayout->GetInFirstLine(); diff --git a/layout/generic/nsLeafFrame.cpp b/layout/generic/nsLeafFrame.cpp index 634eee04b018..adebc60698ce 100644 --- a/layout/generic/nsLeafFrame.cpp +++ b/layout/generic/nsLeafFrame.cpp @@ -85,7 +85,7 @@ nsLeafFrame::DoReflow(nsPresContext* aPresContext, WritingMode wm = aReflowInput.GetWritingMode(); aMetrics.SetSize(wm, aReflowInput.ComputedSizeWithBorderPadding()); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS, ("exit nsLeafFrame::DoReflow: size=%d,%d", diff --git a/layout/generic/nsPageContentFrame.cpp b/layout/generic/nsPageContentFrame.cpp index 1a9b17a42b50..7047e4a724c9 100644 --- a/layout/generic/nsPageContentFrame.cpp +++ b/layout/generic/nsPageContentFrame.cpp @@ -28,7 +28,7 @@ nsPageContentFrame::Reflow(nsPresContext* aPresContext, MarkInReflow(); DO_GLOBAL_REFLOW_COUNT("nsPageContentFrame"); DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); - aStatus = NS_FRAME_COMPLETE; // initialize out parameter + aStatus.Reset(); // initialize out parameter if (GetPrevInFlow() && (GetStateBits() & NS_FRAME_FIRST_REFLOW)) { nsresult rv = aPresContext->PresShell()->FrameConstructor() @@ -93,7 +93,7 @@ nsPageContentFrame::Reflow(nsPresContext* aPresContext, } // Reflow our fixed frames - nsReflowStatus fixedStatus = NS_FRAME_COMPLETE; + nsReflowStatus fixedStatus; ReflowAbsoluteFrames(aPresContext, aDesiredSize, aReflowInput, fixedStatus); NS_ASSERTION(fixedStatus.IsComplete(), "fixed frames can be truncated, but not incomplete"); diff --git a/layout/generic/nsPageFrame.cpp b/layout/generic/nsPageFrame.cpp index a6f54531a2e4..c24b4d15ff5a 100644 --- a/layout/generic/nsPageFrame.cpp +++ b/layout/generic/nsPageFrame.cpp @@ -58,7 +58,7 @@ nsPageFrame::Reflow(nsPresContext* aPresContext, MarkInReflow(); DO_GLOBAL_REFLOW_COUNT("nsPageFrame"); DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); - aStatus = NS_FRAME_COMPLETE; // initialize out parameter + aStatus.Reset(); // initialize out parameter NS_ASSERTION(mFrames.FirstChild() && nsGkAtoms::pageContentFrame == mFrames.FirstChild()->GetType(), @@ -731,7 +731,7 @@ nsPageBreakFrame::Reflow(nsPresContext* aPresContext, // Note: not using NS_FRAME_FIRST_REFLOW here, since it's not clear whether // DidReflow will always get called before the next Reflow() call. mHaveReflowed = true; - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); } nsIAtom* diff --git a/layout/generic/nsPlaceholderFrame.cpp b/layout/generic/nsPlaceholderFrame.cpp index d30e504e5920..d6c355db002d 100644 --- a/layout/generic/nsPlaceholderFrame.cpp +++ b/layout/generic/nsPlaceholderFrame.cpp @@ -147,7 +147,7 @@ nsPlaceholderFrame::Reflow(nsPresContext* aPresContext, DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); aDesiredSize.ClearSize(); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize); } diff --git a/layout/generic/nsPluginFrame.cpp b/layout/generic/nsPluginFrame.cpp index 292522b1e071..e65bd06cf5e4 100644 --- a/layout/generic/nsPluginFrame.cpp +++ b/layout/generic/nsPluginFrame.cpp @@ -506,13 +506,13 @@ nsPluginFrame::Reflow(nsPresContext* aPresContext, // arrived. Otherwise there may be PARAMs or other stuff that the // plugin needs to see that haven't arrived yet. if (!GetContent()->IsDoneAddingChildren()) { - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); return; } // if we are printing or print previewing, bail for now if (aPresContext->Medium() == nsGkAtoms::print) { - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); return; } @@ -531,7 +531,7 @@ nsPluginFrame::Reflow(nsPresContext* aPresContext, aPresContext->PresShell()->PostReflowCallback(this); } - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aMetrics); } diff --git a/layout/generic/nsRubyBaseContainerFrame.cpp b/layout/generic/nsRubyBaseContainerFrame.cpp index 81f6e361c7a9..5b48e214f8c9 100644 --- a/layout/generic/nsRubyBaseContainerFrame.cpp +++ b/layout/generic/nsRubyBaseContainerFrame.cpp @@ -307,7 +307,7 @@ nsRubyBaseContainerFrame::Reflow(nsPresContext* aPresContext, MarkInReflow(); DO_GLOBAL_REFLOW_COUNT("nsRubyBaseContainerFrame"); DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); if (!aReflowInput.mLineLayout) { NS_ASSERTION( @@ -470,8 +470,8 @@ nsRubyBaseContainerFrame::ReflowColumns(const RubyReflowInput& aReflowInput, const uint32_t rtcCount = aReflowInput.mTextContainers.Length(); nscoord icoord = lineLayout->GetCurrentICoord(); MOZ_ASSERT(icoord == 0, "border/padding of rbc should have been suppressed"); - nsReflowStatus reflowStatus = NS_FRAME_COMPLETE; - aStatus = NS_FRAME_COMPLETE; + nsReflowStatus reflowStatus; + aStatus.Reset(); uint32_t columnIndex = 0; RubyColumn column; @@ -487,14 +487,14 @@ nsRubyBaseContainerFrame::ReflowColumns(const RubyReflowInput& aReflowInput, break; } // We are not handling overflow here. - MOZ_ASSERT(reflowStatus == NS_FRAME_COMPLETE); + MOZ_ASSERT(reflowStatus.IsEmpty()); } bool isComplete = false; PullFrameState pullFrameState(this, aReflowInput.mTextContainers); while (!reflowStatus.IsInlineBreak()) { // We are not handling overflow here. - MOZ_ASSERT(reflowStatus == NS_FRAME_COMPLETE); + MOZ_ASSERT(reflowStatus.IsEmpty()); // Try pull some frames from next continuations. This call replaces // frames in |column| with the frame pulled in each level. diff --git a/layout/generic/nsRubyFrame.cpp b/layout/generic/nsRubyFrame.cpp index 43f5a635b55a..fb5bf26c1084 100644 --- a/layout/generic/nsRubyFrame.cpp +++ b/layout/generic/nsRubyFrame.cpp @@ -116,7 +116,7 @@ nsRubyFrame::Reflow(nsPresContext* aPresContext, if (!aReflowInput.mLineLayout) { NS_ASSERTION(aReflowInput.mLineLayout, "No line layout provided to RubyFrame reflow method."); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); return; } @@ -143,7 +143,7 @@ nsRubyFrame::Reflow(nsPresContext* aPresContext, aReflowInput.mLineLayout->BeginSpan(this, &aReflowInput, startEdge, availableISize, &mBaseline); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); for (RubySegmentEnumerator e(this); !e.AtEnd(); e.Next()) { ReflowSegment(aPresContext, aReflowInput, e.GetBaseContainer(), aStatus); @@ -155,7 +155,7 @@ nsRubyFrame::Reflow(nsPresContext* aPresContext, } ContinuationTraversingState pullState(this); - while (aStatus == NS_FRAME_COMPLETE) { + while (aStatus.IsEmpty()) { nsRubyBaseContainerFrame* baseContainer = PullOneSegment(aReflowInput.mLineLayout, pullState); if (!baseContainer) { @@ -305,10 +305,10 @@ nsRubyFrame::ReflowSegment(nsPresContext* aPresContext, textReflowInput.mLineLayout = aReflowInput.mLineLayout; textContainer->Reflow(aPresContext, textMetrics, textReflowInput, textReflowStatus); - // Ruby text containers always return NS_FRAME_COMPLETE even when + // Ruby text containers always return complete reflow status even when // they have continuations, because the breaking has already been // handled when reflowing the base containers. - NS_ASSERTION(textReflowStatus == NS_FRAME_COMPLETE, + NS_ASSERTION(textReflowStatus.IsEmpty(), "Ruby text container must not break itself inside"); // The metrics is initialized with reflow state of this ruby frame, // hence the writing-mode is tied to rubyWM instead of rtcWM. diff --git a/layout/generic/nsRubyTextContainerFrame.cpp b/layout/generic/nsRubyTextContainerFrame.cpp index e91f1151fa28..c9192ca7eb9d 100644 --- a/layout/generic/nsRubyTextContainerFrame.cpp +++ b/layout/generic/nsRubyTextContainerFrame.cpp @@ -130,10 +130,10 @@ nsRubyTextContainerFrame::Reflow(nsPresContext* aPresContext, DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); // Although a ruby text container may have continuations, returning - // NS_FRAME_COMPLETE here is still safe, since its parent, ruby frame, + // complete reflow status is still safe, since its parent, ruby frame, // ignores the status, and continuations of the ruby base container // will take care of our continuations. - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); WritingMode lineWM = aReflowInput.mLineLayout->GetWritingMode(); nscoord minBCoord = nscoord_MAX; diff --git a/layout/generic/nsSimplePageSequenceFrame.cpp b/layout/generic/nsSimplePageSequenceFrame.cpp index 386716e5ee98..0c1ec36a0320 100644 --- a/layout/generic/nsSimplePageSequenceFrame.cpp +++ b/layout/generic/nsSimplePageSequenceFrame.cpp @@ -156,7 +156,7 @@ nsSimplePageSequenceFrame::Reflow(nsPresContext* aPresContext, DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); NS_FRAME_TRACE_REFLOW_IN("nsSimplePageSequenceFrame::Reflow"); - aStatus = NS_FRAME_COMPLETE; // we're always complete + aStatus.Reset(); // we're always complete // Don't do incremental reflow until we've taught tables how to do // it right in paginated mode. diff --git a/layout/generic/nsSubDocumentFrame.cpp b/layout/generic/nsSubDocumentFrame.cpp index 37da921080c8..d239f1bcb454 100644 --- a/layout/generic/nsSubDocumentFrame.cpp +++ b/layout/generic/nsSubDocumentFrame.cpp @@ -752,7 +752,7 @@ nsSubDocumentFrame::Reflow(nsPresContext* aPresContext, "Shouldn't have unconstrained stuff here " "thanks to ComputeAutoSize"); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); NS_ASSERTION(mContent->GetPrimaryFrame() == this, "Shouldn't happen"); diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index 6ce38190a823..62b2470e5441 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -8984,7 +8984,7 @@ nsTextFrame::Reflow(nsPresContext* aPresContext, // but not inside a cell. For now, just don't reflow. if (!aReflowInput.mLineLayout) { ClearMetrics(aMetrics); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); return; } @@ -9060,7 +9060,7 @@ nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth, // We don't need to reflow if there is no content. if (!maxContentLength) { ClearMetrics(aMetrics); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); return; } @@ -9217,7 +9217,7 @@ nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth, if (!mTextRun) { ClearMetrics(aMetrics); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); return; } diff --git a/layout/generic/nsVideoFrame.cpp b/layout/generic/nsVideoFrame.cpp index c1c7a578e2a0..6119ee73e0f5 100644 --- a/layout/generic/nsVideoFrame.cpp +++ b/layout/generic/nsVideoFrame.cpp @@ -296,7 +296,7 @@ nsVideoFrame::Reflow(nsPresContext* aPresContext, NS_PRECONDITION(mState & NS_FRAME_IN_REFLOW, "frame is not in reflow"); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); const WritingMode myWM = aReflowInput.GetWritingMode(); nscoord contentBoxBSize = aReflowInput.ComputedBSize(); diff --git a/layout/mathml/nsMathMLContainerFrame.cpp b/layout/mathml/nsMathMLContainerFrame.cpp index 7be06f0f37d0..0853f1b48e3f 100644 --- a/layout/mathml/nsMathMLContainerFrame.cpp +++ b/layout/mathml/nsMathMLContainerFrame.cpp @@ -950,7 +950,7 @@ nsMathMLContainerFrame::Reflow(nsPresContext* aPresContext, // Place children now by re-adjusting the origins to align the baselines FinalizeReflow(drawTarget, aDesiredSize); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize); } diff --git a/layout/mathml/nsMathMLSelectedFrame.cpp b/layout/mathml/nsMathMLSelectedFrame.cpp index 2378d076320d..fba8092db6f9 100644 --- a/layout/mathml/nsMathMLSelectedFrame.cpp +++ b/layout/mathml/nsMathMLSelectedFrame.cpp @@ -140,7 +140,7 @@ nsMathMLSelectedFrame::Reflow(nsPresContext* aPresContext, { MarkInReflow(); mPresentationData.flags &= ~NS_MATHML_ERROR; - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); aDesiredSize.ClearSize(); aDesiredSize.SetBlockStartAscent(0); mBoundingMetrics = nsBoundingMetrics(); diff --git a/layout/mathml/nsMathMLTokenFrame.cpp b/layout/mathml/nsMathMLTokenFrame.cpp index 99857ea963e6..0ac72a936a3b 100644 --- a/layout/mathml/nsMathMLTokenFrame.cpp +++ b/layout/mathml/nsMathMLTokenFrame.cpp @@ -152,7 +152,7 @@ nsMathMLTokenFrame::Reflow(nsPresContext* aPresContext, // place and size children FinalizeReflow(aReflowInput.mRenderingContext->GetDrawTarget(), aDesiredSize); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize); } diff --git a/layout/mathml/nsMathMLmfencedFrame.cpp b/layout/mathml/nsMathMLmfencedFrame.cpp index e0baa1fb36da..fe093281e129 100644 --- a/layout/mathml/nsMathMLmfencedFrame.cpp +++ b/layout/mathml/nsMathMLmfencedFrame.cpp @@ -446,7 +446,7 @@ nsMathMLmfencedFrame::Reflow(nsPresContext* aPresContext, // Set our overflow area GatherAndStoreOverflow(&aDesiredSize); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize); } diff --git a/layout/mathml/nsMathMLmrootFrame.cpp b/layout/mathml/nsMathMLmrootFrame.cpp index 3d564e8fd8cb..fea24e00209f 100644 --- a/layout/mathml/nsMathMLmrootFrame.cpp +++ b/layout/mathml/nsMathMLmrootFrame.cpp @@ -216,7 +216,7 @@ nsMathMLmrootFrame::Reflow(nsPresContext* aPresContext, // report an error, encourage people to get their markups in order ReportChildCountError(); ReflowError(drawTarget, aDesiredSize); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize); // Call DidReflow() for the child frames we successfully did reflow. DidReflowChildren(mFrames.FirstChild(), childFrame); @@ -354,7 +354,7 @@ nsMathMLmrootFrame::Reflow(nsPresContext* aPresContext, mReference.x = 0; mReference.y = aDesiredSize.BlockStartAscent(); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize); } diff --git a/layout/mathml/nsMathMLmspaceFrame.cpp b/layout/mathml/nsMathMLmspaceFrame.cpp index 54f2f325a7d2..05fcd9d1418a 100644 --- a/layout/mathml/nsMathMLmspaceFrame.cpp +++ b/layout/mathml/nsMathMLmspaceFrame.cpp @@ -115,7 +115,7 @@ nsMathMLmspaceFrame::Reflow(nsPresContext* aPresContext, // Also return our bounding metrics aDesiredSize.mBoundingMetrics = mBoundingMetrics; - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize); } diff --git a/layout/svg/nsSVGForeignObjectFrame.cpp b/layout/svg/nsSVGForeignObjectFrame.cpp index afa5912d2ced..1fcf54a77711 100644 --- a/layout/svg/nsSVGForeignObjectFrame.cpp +++ b/layout/svg/nsSVGForeignObjectFrame.cpp @@ -158,7 +158,7 @@ nsSVGForeignObjectFrame::Reflow(nsPresContext* aPresContext, aReflowInput.ComputedBSize()); aDesiredSize.SetSize(wm, finalSize); aDesiredSize.SetOverflowAreasToDesiredBounds(); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); } void diff --git a/layout/svg/nsSVGOuterSVGFrame.cpp b/layout/svg/nsSVGOuterSVGFrame.cpp index 46fd127f9c30..cd890bb764d7 100644 --- a/layout/svg/nsSVGOuterSVGFrame.cpp +++ b/layout/svg/nsSVGOuterSVGFrame.cpp @@ -369,7 +369,7 @@ nsSVGOuterSVGFrame::Reflow(nsPresContext* aPresContext, NS_PRECONDITION(mState & NS_FRAME_IN_REFLOW, "frame is not in reflow"); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); aDesiredSize.Width() = aReflowInput.ComputedWidth() + aReflowInput.ComputedPhysicalBorderPadding().LeftRight(); diff --git a/layout/tables/nsTableCellFrame.cpp b/layout/tables/nsTableCellFrame.cpp index 6a9cd02c9a4a..3a1a57ec1b26 100644 --- a/layout/tables/nsTableCellFrame.cpp +++ b/layout/tables/nsTableCellFrame.cpp @@ -876,7 +876,7 @@ nsTableCellFrame::Reflow(nsPresContext* aPresContext, // see if a special bsize reflow needs to occur due to having a pct height nsTableFrame::CheckRequestSpecialBSizeReflow(aReflowInput); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); WritingMode wm = aReflowInput.GetWritingMode(); LogicalSize availSize(wm, aReflowInput.AvailableISize(), aReflowInput.AvailableBSize()); diff --git a/layout/tables/nsTableColFrame.cpp b/layout/tables/nsTableColFrame.cpp index caef2158b94b..fd7d69708af7 100644 --- a/layout/tables/nsTableColFrame.cpp +++ b/layout/tables/nsTableColFrame.cpp @@ -118,7 +118,7 @@ nsTableColFrame::Reflow(nsPresContext* aPresContext, if (collapseCol) { GetTableFrame()->SetNeedToCollapse(true); } - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize); } diff --git a/layout/tables/nsTableColGroupFrame.cpp b/layout/tables/nsTableColGroupFrame.cpp index ff8879a0b004..a0a2fbf88d81 100644 --- a/layout/tables/nsTableColGroupFrame.cpp +++ b/layout/tables/nsTableColGroupFrame.cpp @@ -379,7 +379,7 @@ nsTableColGroupFrame::Reflow(nsPresContext* aPresContext, } aDesiredSize.ClearSize(); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize); } diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index 75ea3f361f70..0bf87da6c81d 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -1844,7 +1844,7 @@ nsTableFrame::Reflow(nsPresContext* aPresContext, bool isPaginated = aPresContext->IsPaginated(); WritingMode wm = aReflowInput.GetWritingMode(); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); if (!GetPrevInFlow() && !mTableLayoutStrategy) { NS_ERROR("strategy should have been created in Init"); return; @@ -2047,7 +2047,7 @@ nsTableFrame::FixupPositionedTableParts(nsPresContext* aPresContext, ReflowInput reflowInput(aPresContext, positionedPart, aReflowInput.mRenderingContext, availSize, ReflowInput::DUMMY_PARENT_REFLOW_STATE); - nsReflowStatus reflowStatus = NS_FRAME_COMPLETE; + nsReflowStatus reflowStatus; // Reflow absolutely-positioned descendants of the positioned part. // FIXME: Unconditionally using NS_UNCONSTRAINEDSIZE for the bsize and @@ -3022,7 +3022,7 @@ nsTableFrame::ReflowChildren(TableReflowInput& aReflowInput, nsIFrame*& aLastChildReflowed, nsOverflowAreas& aOverflowAreas) { - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); aLastChildReflowed = nullptr; nsIFrame* prevKidFrame = nullptr; diff --git a/layout/tables/nsTableRowFrame.cpp b/layout/tables/nsTableRowFrame.cpp index d3e02e6d7d0d..ff5cfaa546f8 100644 --- a/layout/tables/nsTableRowFrame.cpp +++ b/layout/tables/nsTableRowFrame.cpp @@ -803,7 +803,7 @@ nsTableRowFrame::ReflowChildren(nsPresContext* aPresContext, nsTableFrame& aTableFrame, nsReflowStatus& aStatus) { - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); // XXXldb Should we be checking constrained bsize instead? const bool isPaginated = aPresContext->IsPaginated(); diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp index 4b502c25d9c5..9328e33d4d67 100644 --- a/layout/tables/nsTableRowGroupFrame.cpp +++ b/layout/tables/nsTableRowGroupFrame.cpp @@ -1256,7 +1256,7 @@ nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext, else { // We can't push children, so let our parent reflow us again with more space aDesiredSize.Height() = rowRect.YMost(); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); break; } } @@ -1276,7 +1276,7 @@ nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext, else { // We can't push children, so let our parent reflow us again with more space aDesiredSize.Height() = rowRect.YMost(); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); UndoContinuedRow(aPresContext, contRow); contRow = nullptr; } @@ -1313,7 +1313,7 @@ nsTableRowGroupFrame::SplitRowGroup(nsPresContext* aPresContext, else { // Let our parent reflow us again with more space aDesiredSize.Height() = rowRect.YMost(); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); UndoContinuedRow(aPresContext, contRow); contRow = nullptr; } @@ -1368,7 +1368,7 @@ nsTableRowGroupFrame::Reflow(nsPresContext* aPresContext, DO_GLOBAL_REFLOW_COUNT("nsTableRowGroupFrame"); DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); // Row geometry may be going to change so we need to invalidate any row cursor. ClearRowCursor(); diff --git a/layout/tables/nsTableWrapperFrame.cpp b/layout/tables/nsTableWrapperFrame.cpp index e44652a73309..aad66ce61259 100644 --- a/layout/tables/nsTableWrapperFrame.cpp +++ b/layout/tables/nsTableWrapperFrame.cpp @@ -855,7 +855,7 @@ nsTableWrapperFrame::Reflow(nsPresContext* aPresContext, // Initialize out parameters aDesiredSize.ClearSize(); - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); if (!HasAnyStateBits(NS_FRAME_FIRST_REFLOW)) { // Set up our kids. They're already present, on an overflow list, diff --git a/layout/xul/nsBoxFrame.cpp b/layout/xul/nsBoxFrame.cpp index 63ecb835c686..dd9e5dd3e640 100644 --- a/layout/xul/nsBoxFrame.cpp +++ b/layout/xul/nsBoxFrame.cpp @@ -658,7 +658,7 @@ nsBoxFrame::Reflow(nsPresContext* aPresContext, #endif - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); // create the layout state nsBoxLayoutState state(aPresContext, aReflowInput.mRenderingContext, @@ -944,7 +944,7 @@ nsBoxFrame::DoXULLayout(nsBoxLayoutState& aState) AddStateBits(NS_FRAME_IN_REFLOW); // Set up a |reflowStatus| to pass into ReflowAbsoluteFrames // (just a dummy value; hopefully that's OK) - nsReflowStatus reflowStatus = NS_FRAME_COMPLETE; + nsReflowStatus reflowStatus; ReflowAbsoluteFrames(aState.PresContext(), desiredSize, reflowInput, reflowStatus); RemoveStateBits(NS_FRAME_IN_REFLOW); diff --git a/layout/xul/nsLeafBoxFrame.cpp b/layout/xul/nsLeafBoxFrame.cpp index 6d1783c11c64..7e7939462dd3 100644 --- a/layout/xul/nsLeafBoxFrame.cpp +++ b/layout/xul/nsLeafBoxFrame.cpp @@ -235,7 +235,7 @@ nsLeafBoxFrame::Reflow(nsPresContext* aPresContext, #endif - aStatus = NS_FRAME_COMPLETE; + aStatus.Reset(); // create the layout state nsBoxLayoutState state(aPresContext, aReflowInput.mRenderingContext); From 10070b1da2bb5e940657e430fb72b2811beb452d Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Tue, 14 Feb 2017 18:01:11 +0800 Subject: [PATCH 109/234] Bug 775624 Part 23 - Remove constructor and all operators related to uint32_t. r=dholbert MozReview-Commit-ID: FEVYMhcpPS0 --HG-- extra : rebase_source : 504328a609feaf7816e22e0f0c87aa8be6813558 --- layout/generic/nsIFrame.h | 42 +-------------------------------------- 1 file changed, 1 insertion(+), 41 deletions(-) diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 7c4914288b55..69e8302255f2 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -201,8 +201,7 @@ class nsReflowStatus final { public: nsReflowStatus() - : mStatus(0) - , mBreakType(StyleClear::None) + : mBreakType(StyleClear::None) , mIncomplete(false) , mOverflowIncomplete(false) , mNextInFlowNeedsReflow(false) @@ -224,43 +223,6 @@ public: mFirstLetterComplete = false; } - nsReflowStatus(uint32_t aStatus) - : mStatus(aStatus) - {} - - uint32_t& operator=(uint32_t aRhs) { - mStatus = aRhs; - return mStatus; - } - - uint32_t operator&(uint32_t aRhs) const { - return mStatus & aRhs; - } - - uint32_t operator&=(uint32_t aRhs) { - return mStatus = mStatus & aRhs; - } - - uint32_t operator|(uint32_t aRhs) const { - return mStatus | aRhs; - } - - uint32_t operator|=(uint32_t aRhs) { - return mStatus = mStatus | aRhs; - } - - uint32_t operator>>(uint32_t aRhs) const { - return mStatus >> aRhs; - } - - bool operator==(uint32_t aRhs) const { - return mStatus == aRhs; - } - - bool operator!=(uint32_t aRhs) const { - return !(*this == aRhs); - } - // Return true if all flags are cleared. bool IsEmpty() const { return (!mIncomplete && @@ -364,8 +326,6 @@ public: void SetFirstLetterComplete() { mFirstLetterComplete = true; } private: - uint32_t mStatus; - StyleClear mBreakType; // Frame completion status bit flags. From cd607fcae645f1c8e24ef662969ed8513a02f9cf Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Tue, 14 Feb 2017 18:41:41 +0800 Subject: [PATCH 110/234] Bug 775624 Part 24 - Implement operator<< for nsReflowStatus to use mozilla::ToString. r=dholbert To print log in nsBlockFrame, run "GECKO_BLOCK_DEBUG_FLAGS=reflow ./mach run". Here is a sample nsReflowStatus string: [Complete=Y,NIF=N,Truncated=N,Break=N,FirstLetter=Y]. MozReview-Commit-ID: 4voGcXfJlN7 --HG-- extra : rebase_source : f84ba1ef47e30513674e578fab37b66a8b2a1ab3 --- layout/generic/nsBlockFrame.cpp | 8 ++++---- layout/generic/nsFrame.cpp | 29 ++++++++++++++++++++++++++- layout/generic/nsIFrame.h | 6 ++++++ layout/generic/nsSubDocumentFrame.cpp | 4 ++-- 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index f60466d2ed55..769be702a707 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -1473,8 +1473,8 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext, if (gNoisyReflow) { IndentBy(stdout, gNoiseIndent); ListTag(stdout); - printf(": status=%x (%scomplete) metrics=%d,%d carriedMargin=%d", - aStatus, aStatus.IsComplete() ? "" : "not ", + printf(": status=%s metrics=%d,%d carriedMargin=%d", + ToString(aStatus).c_str(), aMetrics.ISize(parentWM), aMetrics.BSize(parentWM), aMetrics.mCarriedOutBEndMargin.get()); if (HasOverflowAreas()) { @@ -2745,8 +2745,8 @@ nsBlockFrame::ReflowDirtyLines(BlockReflowInput& aState) if (gNoisyReflow) { IndentBy(stdout, gNoiseIndent - 1); ListTag(stdout); - printf(": done reflowing dirty lines (status=%x)\n", - aState.mReflowStatus); + printf(": done reflowing dirty lines (status=%s)\n", + ToString(aState.mReflowStatus).c_str()); } #endif } diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index fa97d7449a23..b961a548c9b1 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -209,6 +209,33 @@ nsReflowStatus::UpdateTruncated(const ReflowInput& aReflowInput, // Formerly the nsIFrameDebug interface #ifdef DEBUG +std::ostream& operator<<(std::ostream& aStream, + const nsReflowStatus& aStatus) +{ + char complete = 'Y'; + if (aStatus.IsIncomplete()) { + complete = 'N'; + } else if (aStatus.IsOverflowIncomplete()) { + complete = 'O'; + } + + char brk = 'N'; + if (aStatus.IsInlineBreakBefore()) { + brk = 'B'; + } else if (aStatus.IsInlineBreakAfter()) { + brk = 'A'; + } + + aStream << "[" + << "Complete=" << complete << "," + << "NIF=" << (aStatus.NextInFlowNeedsReflow() ? 'Y' : 'N') << "," + << "Truncated=" << (aStatus.IsTruncated() ? 'Y' : 'N') << "," + << "Break=" << brk << "," + << "FirstLetter=" << (aStatus.FirstLetterComplete() ? 'Y' : 'N') + << "]"; + return aStream; +} + static bool gShowFrameBorders = false; void nsFrame::ShowFrameBorders(bool aEnable) @@ -11232,7 +11259,7 @@ void nsFrame::DisplayReflowExit(nsPresContext* aPresContext, printf("Reflow d=%s,%s", width, height); if (!aStatus.IsFullyComplete()) { - printf(" status=0x%x", aStatus); + printf(" status=%s", ToString(aStatus).c_str()); } if (aFrame->HasOverflowAreas()) { DR_state->PrettyUC(aMetrics.VisualOverflow().x, x, 16); diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 69e8302255f2..d0173eda03b0 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -343,6 +343,12 @@ private: #define NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aMetrics) \ aStatus.UpdateTruncated(aReflowInput, aMetrics); +#ifdef DEBUG +// Convert nsReflowStatus to a human-readable string. +std::ostream& +operator<<(std::ostream& aStream, const nsReflowStatus& aStatus); +#endif + //---------------------------------------------------------------------- /** diff --git a/layout/generic/nsSubDocumentFrame.cpp b/layout/generic/nsSubDocumentFrame.cpp index d239f1bcb454..c816474c7328 100644 --- a/layout/generic/nsSubDocumentFrame.cpp +++ b/layout/generic/nsSubDocumentFrame.cpp @@ -805,8 +805,8 @@ nsSubDocumentFrame::Reflow(nsPresContext* aPresContext, } NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS, - ("exit nsSubDocumentFrame::Reflow: size=%d,%d status=%x", - aDesiredSize.Width(), aDesiredSize.Height(), aStatus)); + ("exit nsSubDocumentFrame::Reflow: size=%d,%d status=%s", + aDesiredSize.Width(), aDesiredSize.Height(), ToString(aStatus).c_str())); NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize); } From c6d5934ada8168df90f949f4432e9382f430b51a Mon Sep 17 00:00:00 2001 From: John Lin Date: Tue, 21 Feb 2017 17:17:34 +0800 Subject: [PATCH 111/234] Bug 1340041 - make callbacks no-op for dying CodecProxy. r=jchen MozReview-Commit-ID: CJPwRNp78HP --HG-- extra : rebase_source : 33fbd5f8f50ac19827a5adbf22fcdc5129f123d7 --- .../org/mozilla/gecko/media/CodecProxy.java | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) 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 990b8827fa4f..5473ad619536 100644 --- a/mobile/android/base/java/org/mozilla/gecko/media/CodecProxy.java +++ b/mobile/android/base/java/org/mozilla/gecko/media/CodecProxy.java @@ -40,6 +40,13 @@ public final class CodecProxy { void onError(boolean fatal); } + private static Callbacks sNoOpCallbacks = new Callbacks() { + public void onInputExhausted() { } + public void onOutputFormatChanged(MediaFormat format) { } + public void onOutput(Sample output) { output.dispose(); } + public void onError(boolean fatal) { } + }; + @WrapForJNI public static class NativeCallbacks extends JNIObject implements Callbacks { public native void onInputExhausted(); @@ -52,7 +59,7 @@ public final class CodecProxy { } private class CallbacksForwarder extends ICodecCallbacks.Stub { - private final Callbacks mCallbacks; + private Callbacks mCallbacks; private boolean mEndOfInput; CallbacksForwarder(Callbacks callbacks) { @@ -60,19 +67,19 @@ public final class CodecProxy { } @Override - public void onInputExhausted() throws RemoteException { + public synchronized void onInputExhausted() throws RemoteException { if (!mEndOfInput) { mCallbacks.onInputExhausted(); } } @Override - public void onOutputFormatChanged(FormatParam format) throws RemoteException { + public synchronized void onOutputFormatChanged(FormatParam format) throws RemoteException { mCallbacks.onOutputFormatChanged(format.asFormat()); } @Override - public void onOutput(Sample sample) throws RemoteException { + public synchronized void onOutput(Sample sample) throws RemoteException { if (mOutputSurface != null) { // Don't render to surface just yet. Callback will make that happen when it's time. mSurfaceOutputs.offer(sample); @@ -90,13 +97,17 @@ public final class CodecProxy { reportError(fatal); } - private void reportError(boolean fatal) { + private synchronized void reportError(boolean fatal) { mCallbacks.onError(fatal); } private void setEndOfInput(boolean end) { mEndOfInput = end; } + + private synchronized void cancel() { + mCallbacks = sNoOpCallbacks; + } } @WrapForJNI @@ -219,6 +230,8 @@ public final class CodecProxy { @WrapForJNI public synchronized boolean release() { + mCallbacks.cancel(); + if (mRemote == null) { Log.w(LOGTAG, "codec already ended"); return true; From a11bfd53bde91d754ae6bcab22e82c8f5930e9e2 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 23 Feb 2017 02:09:57 -0500 Subject: [PATCH 112/234] Bug 1341988. Reenable a bunch of stylo reftests that were disabled for reasons that are not relevant anymore. r=bz MozReview-Commit-ID: CLqLHexhBX3 --HG-- extra : rebase_source : 07dfb89d0651240362395494fdd7ee94363430b6 --- .../test/reftest/filters/reftest-stylo.list | 2 +- dom/canvas/test/reftest/reftest-stylo.list | 2 +- dom/plugins/test/reftest/reftest-stylo.list | 6 +- editor/reftests/reftest-stylo.list | 86 ++--- .../apz/test/reftest/reftest-stylo.list | 8 +- gfx/tests/reftest/reftest-stylo.list | 2 +- .../reftest/bmp/bmpsuite/g/reftest-stylo.list | 6 +- .../async-scrolling/reftest-stylo.list | 4 +- .../reftests/backgrounds/reftest-stylo.list | 28 +- .../backgrounds/vector/reftest-stylo.list | 2 +- .../reftests/bidi/dirAuto/reftest-stylo.list | 4 +- .../reftests/bidi/numeral/reftest-stylo.list | 6 +- layout/reftests/bidi/reftest-stylo.list | 46 +-- .../reftests/border-image/reftest-stylo.list | 4 +- .../reftests/border-radius/reftest-stylo.list | 4 +- .../box-properties/reftest-stylo.list | 4 +- layout/reftests/box-shadow/reftest-stylo.list | 12 +- layout/reftests/box-sizing/reftest-stylo.list | 2 +- layout/reftests/bugs/reftest-stylo.list | 304 +++++++++--------- layout/reftests/canvas/reftest-stylo.list | 10 +- layout/reftests/columns/reftest-stylo.list | 6 +- .../reftests/counter-style/reftest-stylo.list | 4 +- .../css-animations/reftest-stylo.list | 32 +- layout/reftests/css-break/reftest-stylo.list | 2 +- layout/reftests/css-calc/reftest-stylo.list | 2 +- .../css-disabled/output/reftest-stylo.list | 2 +- .../reftests/css-display/reftest-stylo.list | 14 +- .../css-enabled/output/reftest-stylo.list | 2 +- .../reftests/css-gradients/reftest-stylo.list | 8 +- layout/reftests/css-grid/reftest-stylo.list | 6 +- .../default-style/reftest-stylo.list | 2 +- .../css-invalid/input/reftest-stylo.list | 12 +- .../css-invalid/output/reftest-stylo.list | 4 +- .../css-placeholder/input/reftest-stylo.list | 2 +- .../css-placeholder/reftest-stylo.list | 2 +- .../textarea/reftest-stylo.list | 4 +- layout/reftests/css-ruby/reftest-stylo.list | 18 +- layout/reftests/css-sizing/reftest-stylo.list | 4 +- .../button-submit/reftest-stylo.list | 2 +- .../input-image/reftest-stylo.list | 2 +- .../input-submit/reftest-stylo.list | 2 +- .../css-transitions/reftest-stylo.list | 6 +- .../default-style/reftest-stylo.list | 4 +- .../css-ui-invalid/input/reftest-stylo.list | 12 +- .../css-ui-invalid/output/reftest-stylo.list | 4 +- .../css-ui-valid/input/reftest-stylo.list | 12 +- .../css-ui-valid/output/reftest-stylo.list | 4 +- .../css-valid/input/reftest-stylo.list | 12 +- .../css-valid/output/reftest-stylo.list | 4 +- .../css-valuesandunits/reftest-stylo.list | 10 +- layout/reftests/cssom/reftest-stylo.list | 4 +- layout/reftests/datalist/reftest-stylo.list | 2 +- .../details-summary/reftest-stylo.list | 6 +- layout/reftests/dom/reftest-stylo.list | 8 +- .../reftests/first-letter/reftest-stylo.list | 8 +- layout/reftests/first-line/reftest-stylo.list | 2 +- layout/reftests/flexbox/reftest-stylo.list | 4 +- layout/reftests/font-face/reftest-stylo.list | 14 +- .../reftests/font-matching/reftest-stylo.list | 20 +- .../reftests/forms/button/reftest-stylo.list | 20 +- .../forms/fieldset/reftest-stylo.list | 4 +- .../forms/input/checkbox/reftest-stylo.list | 11 +- .../forms/input/datetime/reftest-stylo.list | 14 +- .../forms/input/file/reftest-stylo.list | 12 +- .../forms/input/number/reftest-stylo.list | 14 +- .../forms/input/percentage/reftest-stylo.list | 2 +- .../forms/input/radio/reftest-stylo.list | 3 - .../forms/input/range/reftest-stylo.list | 6 +- .../forms/input/text/reftest-stylo.list | 8 +- .../meter/default-style/reftest-stylo.list | 4 +- .../reftests/forms/meter/reftest-stylo.list | 60 ++-- .../reftests/forms/output/reftest-stylo.list | 12 +- .../forms/placeholder/reftest-stylo.list | 2 +- .../forms/progress/reftest-stylo.list | 62 ++-- .../reftests/forms/select/reftest-stylo.list | 8 +- .../forms/textarea/reftest-stylo.list | 24 +- .../reftests/image-element/reftest-stylo.list | 4 +- layout/reftests/image-rect/reftest-stylo.list | 2 +- layout/reftests/image/reftest-stylo.list | 6 +- layout/reftests/inline/reftest-stylo.list | 6 +- .../reftests/invalidation/reftest-stylo.list | 12 +- .../margin-collapsing/reftest-stylo.list | 60 ++-- layout/reftests/mathml/reftest-stylo.list | 6 +- .../reftests/native-theme/reftest-stylo.list | 4 +- layout/reftests/pagination/reftest-stylo.list | 8 +- .../pixel-rounding/reftest-stylo.list | 2 +- .../reftest-stylo.list | 2 +- .../position-relative/reftest-stylo.list | 2 +- layout/reftests/printing/reftest-stylo.list | 4 +- .../reftest-sanity/reftest-stylo.list | 16 +- .../reftests/svg/as-image/reftest-stylo.list | 84 ++--- .../filters/css-filters/reftest-stylo.list | 2 +- .../reftests/svg/filters/reftest-stylo.list | 2 +- layout/reftests/svg/reftest-stylo.list | 6 +- layout/reftests/svg/sizing/reftest-stylo.list | 1 - layout/reftests/tab-size/reftest-stylo.list | 6 +- .../table-anonymous-boxes/reftest-stylo.list | 20 +- .../table-bordercollapse/reftest-stylo.list | 2 +- layout/reftests/table-dom/reftest-stylo.list | 8 +- .../reftests/table-width/reftest-stylo.list | 4 +- .../text-decoration/reftest-stylo.list | 32 +- .../reftests/text-indent/reftest-stylo.list | 14 +- .../reftests/text-overflow/reftest-stylo.list | 20 +- .../reftests/text-shadow/reftest-stylo.list | 6 +- layout/reftests/text/reftest-stylo.list | 78 ++--- .../reftests/transform-3d/reftest-stylo.list | 36 +-- layout/reftests/transform/reftest-stylo.list | 24 +- layout/reftests/unicode/reftest-stylo.list | 4 +- .../reftests/view-source/reftest-stylo.list | 2 +- .../w3c-css/received/reftest-stylo.list | 8 +- .../submitted/images3/reftest-stylo.list | 18 +- .../submitted/masking/reftest-stylo.list | 2 +- .../w3c-css/submitted/ruby/reftest-stylo.list | 6 +- .../submitted/text3/reftest-stylo.list | 4 +- .../submitted/transforms/reftest-stylo.list | 4 +- .../submitted/values3/reftest-stylo.list | 2 +- layout/reftests/webkit-box/reftest-stylo.list | 12 +- .../writing-mode/abspos/reftest-stylo.list | 6 +- .../reftests/writing-mode/reftest-stylo.list | 132 ++++---- .../writing-mode/tables/reftest-stylo.list | 8 +- layout/reftests/z-index/reftest-stylo.list | 2 +- widget/reftests/reftest-stylo.list | 8 +- 122 files changed, 883 insertions(+), 890 deletions(-) diff --git a/dom/canvas/test/reftest/filters/reftest-stylo.list b/dom/canvas/test/reftest/filters/reftest-stylo.list index 315a400ad544..99aa50843a02 100644 --- a/dom/canvas/test/reftest/filters/reftest-stylo.list +++ b/dom/canvas/test/reftest/filters/reftest-stylo.list @@ -2,7 +2,7 @@ default-preferences pref(canvas.filters.enabled,true) fails asserts-if(stylo,2) == default-color.html default-color.html # bug 1324700 -# == drop-shadow.html drop-shadow.html +fails asserts-if(stylo,2) == drop-shadow.html drop-shadow.html # bug 1324700 fails asserts-if(stylo,2) == drop-shadow-transformed.html drop-shadow-transformed.html # bug 1324700 fails asserts-if(stylo,2) == global-alpha.html global-alpha.html # bug 1324700 fails asserts-if(stylo,2) == global-composite-operation.html global-composite-operation.html # bug 1324700 diff --git a/dom/canvas/test/reftest/reftest-stylo.list b/dom/canvas/test/reftest/reftest-stylo.list index b60a9a995e83..bdac41c56053 100644 --- a/dom/canvas/test/reftest/reftest-stylo.list +++ b/dom/canvas/test/reftest/reftest-stylo.list @@ -59,7 +59,7 @@ skip-if(Android) == webgl-color-test.html?frame=1&aa&________&premult&alpha webg skip-if(Android) == webgl-color-test.html?frame=1&__&preserve&premult&alpha webgl-color-test.html?frame=1&__&preserve&premult&alpha skip-if(Android) == webgl-color-test.html?frame=1&aa&preserve&premult&alpha webgl-color-test.html?frame=1&aa&preserve&premult&alpha -# == webgl-color-test.html?frame=6&__&________&_______&_____ webgl-color-test.html?frame=6&__&________&_______&_____ +== webgl-color-test.html?frame=6&__&________&_______&_____ webgl-color-test.html?frame=6&__&________&_______&_____ skip-if(Android) == webgl-color-test.html?frame=6&aa&________&_______&_____ webgl-color-test.html?frame=6&aa&________&_______&_____ skip-if(Android) == webgl-color-test.html?frame=6&__&preserve&_______&_____ webgl-color-test.html?frame=6&__&preserve&_______&_____ skip-if(Android) == webgl-color-test.html?frame=6&aa&preserve&_______&_____ webgl-color-test.html?frame=6&aa&preserve&_______&_____ diff --git a/dom/plugins/test/reftest/reftest-stylo.list b/dom/plugins/test/reftest/reftest-stylo.list index 253ad9479f85..9e2fa91f72f7 100644 --- a/dom/plugins/test/reftest/reftest-stylo.list +++ b/dom/plugins/test/reftest/reftest-stylo.list @@ -1,7 +1,7 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing # basic sanity checking -# == plugin-sanity.html plugin-sanity.html -# == plugin-sanity.html plugin-sanity.html +fails == plugin-sanity.html plugin-sanity.html # Bug 1341095 +fails == plugin-sanity.html plugin-sanity.html # Bug 1341095 == plugin-alpha-zindex.html plugin-alpha-zindex.html == plugin-alpha-opacity.html plugin-alpha-opacity.html == windowless-clipping-1.html windowless-clipping-1.html @@ -15,7 +15,7 @@ == plugin-canvas-alpha-zindex.html plugin-canvas-alpha-zindex.html fails == plugin-transform-alpha-zindex.html plugin-transform-alpha-zindex.html == plugin-busy-alpha-zindex.html plugin-busy-alpha-zindex.html -# == plugin-background.html plugin-background.html +== plugin-background.html plugin-background.html == plugin-background-1-step.html plugin-background-1-step.html == plugin-background-2-step.html plugin-background-2-step.html == plugin-background-5-step.html plugin-background-5-step.html diff --git a/editor/reftests/reftest-stylo.list b/editor/reftests/reftest-stylo.list index e60b3fd3f56c..33d510999c90 100644 --- a/editor/reftests/reftest-stylo.list +++ b/editor/reftests/reftest-stylo.list @@ -19,31 +19,31 @@ fails == emptypasswd-1.html emptypasswd-1.html fails == emptypasswd-2.html emptypasswd-2.html fails == caret_on_positioned.html caret_on_positioned.html fails == spellcheck-input-disabled.html spellcheck-input-disabled.html -# == spellcheck-input-attr-before.html spellcheck-input-attr-before.html -# == spellcheck-input-attr-before.html spellcheck-input-attr-before.html -# == spellcheck-input-attr-after.html spellcheck-input-attr-after.html -# == spellcheck-input-attr-after.html spellcheck-input-attr-after.html -# == spellcheck-input-attr-inherit.html spellcheck-input-attr-inherit.html -# == spellcheck-input-attr-inherit.html spellcheck-input-attr-inherit.html -# == spellcheck-input-attr-dynamic.html spellcheck-input-attr-dynamic.html -# == spellcheck-input-attr-dynamic.html spellcheck-input-attr-dynamic.html -# == spellcheck-input-attr-dynamic-inherit.html spellcheck-input-attr-dynamic-inherit.html -# == spellcheck-input-attr-dynamic-inherit.html spellcheck-input-attr-dynamic-inherit.html -# == spellcheck-input-property-dynamic.html spellcheck-input-property-dynamic.html -# == spellcheck-input-property-dynamic.html spellcheck-input-property-dynamic.html -# == spellcheck-input-property-dynamic-inherit.html spellcheck-input-property-dynamic-inherit.html -# == spellcheck-input-property-dynamic-inherit.html spellcheck-input-property-dynamic-inherit.html -# == spellcheck-input-attr-dynamic-override.html spellcheck-input-attr-dynamic-override.html -# == spellcheck-input-attr-dynamic-override.html spellcheck-input-attr-dynamic-override.html -# == spellcheck-input-attr-dynamic-override-inherit.html spellcheck-input-attr-dynamic-override-inherit.html -# == spellcheck-input-attr-dynamic-override-inherit.html spellcheck-input-attr-dynamic-override-inherit.html -# == spellcheck-input-property-dynamic-override.html spellcheck-input-property-dynamic-override.html -# == spellcheck-input-property-dynamic-override.html spellcheck-input-property-dynamic-override.html -# == spellcheck-input-property-dynamic-override-inherit.html spellcheck-input-property-dynamic-override-inherit.html -# == spellcheck-input-property-dynamic-override-inherit.html spellcheck-input-property-dynamic-override-inherit.html -# == spellcheck-textarea-attr.html spellcheck-textarea-attr.html +fails == spellcheck-input-attr-before.html spellcheck-input-attr-before.html +fails == spellcheck-input-attr-before.html spellcheck-input-attr-before.html +fails == spellcheck-input-attr-after.html spellcheck-input-attr-after.html +fails == spellcheck-input-attr-after.html spellcheck-input-attr-after.html +fails == spellcheck-input-attr-inherit.html spellcheck-input-attr-inherit.html +fails == spellcheck-input-attr-inherit.html spellcheck-input-attr-inherit.html +fails == spellcheck-input-attr-dynamic.html spellcheck-input-attr-dynamic.html +fails == spellcheck-input-attr-dynamic.html spellcheck-input-attr-dynamic.html +fails == spellcheck-input-attr-dynamic-inherit.html spellcheck-input-attr-dynamic-inherit.html +fails == spellcheck-input-attr-dynamic-inherit.html spellcheck-input-attr-dynamic-inherit.html +fails == spellcheck-input-property-dynamic.html spellcheck-input-property-dynamic.html +fails == spellcheck-input-property-dynamic.html spellcheck-input-property-dynamic.html +fails == spellcheck-input-property-dynamic-inherit.html spellcheck-input-property-dynamic-inherit.html +fails == spellcheck-input-property-dynamic-inherit.html spellcheck-input-property-dynamic-inherit.html +fails == spellcheck-input-attr-dynamic-override.html spellcheck-input-attr-dynamic-override.html +fails == spellcheck-input-attr-dynamic-override.html spellcheck-input-attr-dynamic-override.html +fails == spellcheck-input-attr-dynamic-override-inherit.html spellcheck-input-attr-dynamic-override-inherit.html +fails == spellcheck-input-attr-dynamic-override-inherit.html spellcheck-input-attr-dynamic-override-inherit.html +fails == spellcheck-input-property-dynamic-override.html spellcheck-input-property-dynamic-override.html +fails == spellcheck-input-property-dynamic-override.html spellcheck-input-property-dynamic-override.html +fails == spellcheck-input-property-dynamic-override-inherit.html spellcheck-input-property-dynamic-override-inherit.html +fails == spellcheck-input-property-dynamic-override-inherit.html spellcheck-input-property-dynamic-override-inherit.html +fails == spellcheck-textarea-attr.html spellcheck-textarea-attr.html #the random-if(Android) tests pass on android native, but fail on android-xul, see bug 728942 -# == spellcheck-textarea-attr.html spellcheck-textarea-attr.html +fails == spellcheck-textarea-attr.html spellcheck-textarea-attr.html fails needs-focus == spellcheck-textarea-focused.html spellcheck-textarea-focused.html fails needs-focus == spellcheck-textarea-focused-reframe.html spellcheck-textarea-focused-reframe.html fails needs-focus == spellcheck-textarea-focused-notreadonly.html spellcheck-textarea-focused-notreadonly.html @@ -63,8 +63,8 @@ fails needs-focus == caret_on_textarea_lastline.html caret_on_textarea_lastline. fails needs-focus == input-text-onfocus-reframe.html input-text-onfocus-reframe.html fails needs-focus == input-text-notheme-onfocus-reframe.html input-text-notheme-onfocus-reframe.html fails needs-focus == caret_after_reframe.html caret_after_reframe.html -# == nobogusnode-1.html nobogusnode-1.html -# == nobogusnode-2.html nobogusnode-2.html +== nobogusnode-1.html nobogusnode-1.html +== nobogusnode-2.html nobogusnode-2.html fails == spellcheck-hyphen-valid.html spellcheck-hyphen-valid.html fails == spellcheck-hyphen-invalid.html spellcheck-hyphen-invalid.html fails == spellcheck-slash-valid.html spellcheck-slash-valid.html @@ -82,8 +82,8 @@ fails needs-focus == spellcheck-non-latin-hebrew.html spellcheck-non-latin-hebre fails needs-focus == spellcheck-non-latin-japanese.html spellcheck-non-latin-japanese.html fails needs-focus == spellcheck-non-latin-korean.html spellcheck-non-latin-korean.html fails == unneeded_scroll.html unneeded_scroll.html -# == caret_on_presshell_reinit.html caret_on_presshell_reinit.html -# == caret_on_presshell_reinit-2.html caret_on_presshell_reinit-2.html +== caret_on_presshell_reinit.html caret_on_presshell_reinit.html +== caret_on_presshell_reinit-2.html caret_on_presshell_reinit-2.html fails == 642800.html 642800.html fails == selection_visibility_after_reframe.html selection_visibility_after_reframe.html fails == selection_visibility_after_reframe-2.html selection_visibility_after_reframe-2.html @@ -106,33 +106,33 @@ fails == 388980-1.html 388980-1.html fails needs-focus == spellcheck-superscript-1.html spellcheck-superscript-1.html fails == spellcheck-superscript-2.html spellcheck-superscript-2.html == 824080-1.html 824080-1.html -# == 824080-2.html 824080-2.html -# == 824080-3.html 824080-3.html +== 824080-2.html 824080-2.html +== 824080-3.html 824080-3.html # needs-focus == 824080-2.html 824080-2.html -# == 824080-4.html 824080-4.html -# == 824080-5.html 824080-5.html +== 824080-4.html 824080-4.html +== 824080-5.html 824080-5.html # needs-focus == 824080-4.html 824080-4.html # needs-focus == 824080-6.html 824080-6.html fails needs-focus pref(layout.accessiblecaret.enabled,false) pref(layout.accessiblecaret.enabled_on_touch,false) == 824080-7.html 824080-7.html # needs-focus == 824080-6.html 824080-6.html # Bug 674927: copy spellcheck-textarea tests to contenteditable -# == spellcheck-contenteditable-attr.html spellcheck-contenteditable-attr.html -# == spellcheck-contenteditable-attr.html spellcheck-contenteditable-attr.html +== spellcheck-contenteditable-attr.html spellcheck-contenteditable-attr.html +== spellcheck-contenteditable-attr.html spellcheck-contenteditable-attr.html # needs-focus == spellcheck-contenteditable-focused.html spellcheck-contenteditable-focused.html # needs-focus == spellcheck-contenteditable-focused-reframe.html spellcheck-contenteditable-focused-reframe.html == spellcheck-contenteditable-nofocus.html spellcheck-contenteditable-nofocus.html -# == spellcheck-contenteditable-disabled.html spellcheck-contenteditable-disabled.html -# == spellcheck-contenteditable-disabled-partial.html spellcheck-contenteditable-disabled-partial.html -# == spellcheck-contenteditable-attr-inherit.html spellcheck-contenteditable-attr-inherit.html -# == spellcheck-contenteditable-attr-dynamic.html spellcheck-contenteditable-attr-dynamic.html -# == spellcheck-contenteditable-attr-dynamic-inherit.html spellcheck-contenteditable-attr-dynamic-inherit.html +== spellcheck-contenteditable-disabled.html spellcheck-contenteditable-disabled.html +== spellcheck-contenteditable-disabled-partial.html spellcheck-contenteditable-disabled-partial.html +== spellcheck-contenteditable-attr-inherit.html spellcheck-contenteditable-attr-inherit.html +== spellcheck-contenteditable-attr-dynamic.html spellcheck-contenteditable-attr-dynamic.html +== spellcheck-contenteditable-attr-dynamic-inherit.html spellcheck-contenteditable-attr-dynamic-inherit.html == spellcheck-contenteditable-property-dynamic.html spellcheck-contenteditable-property-dynamic.html -# == spellcheck-contenteditable-property-dynamic-inherit.html spellcheck-contenteditable-property-dynamic-inherit.html -# == spellcheck-contenteditable-attr-dynamic-override.html spellcheck-contenteditable-attr-dynamic-override.html +== spellcheck-contenteditable-property-dynamic-inherit.html spellcheck-contenteditable-property-dynamic-inherit.html +== spellcheck-contenteditable-attr-dynamic-override.html spellcheck-contenteditable-attr-dynamic-override.html == spellcheck-contenteditable-attr-dynamic-override-inherit.html spellcheck-contenteditable-attr-dynamic-override-inherit.html -# == spellcheck-contenteditable-property-dynamic-override.html spellcheck-contenteditable-property-dynamic-override.html +== spellcheck-contenteditable-property-dynamic-override.html spellcheck-contenteditable-property-dynamic-override.html == spellcheck-contenteditable-property-dynamic-override-inherit.html spellcheck-contenteditable-property-dynamic-override-inherit.html -# == 911201.html 911201.html +== 911201.html 911201.html fails needs-focus == 969773.html 969773.html fails == 997805.html 997805.html fails == 1088158.html 1088158.html diff --git a/gfx/layers/apz/test/reftest/reftest-stylo.list b/gfx/layers/apz/test/reftest/reftest-stylo.list index a5f214578cda..6d5da793654e 100644 --- a/gfx/layers/apz/test/reftest/reftest-stylo.list +++ b/gfx/layers/apz/test/reftest/reftest-stylo.list @@ -4,9 +4,9 @@ fuzzy-if(Android,1,2) skip-if(!Android) pref(apz.allow_zooming,true) == async-scrollbar-1-v.html async-scrollbar-1-v.html fuzzy-if(Android,4,5) skip-if(!Android) pref(apz.allow_zooming,true) == async-scrollbar-1-h.html async-scrollbar-1-h.html fuzzy-if(Android,3,5) skip-if(!Android) pref(apz.allow_zooming,true) == async-scrollbar-1-vh.html async-scrollbar-1-vh.html -# == async-scrollbar-1-v-rtl.html async-scrollbar-1-v-rtl.html -# == async-scrollbar-1-h-rtl.html async-scrollbar-1-h-rtl.html -# == async-scrollbar-1-vh-rtl.html async-scrollbar-1-vh-rtl.html +fuzzy-if(Android,1,2) skip-if(!Android) pref(apz.allow_zooming,true) == async-scrollbar-1-v-rtl.html async-scrollbar-1-v-rtl.html +fuzzy-if(Android,4,5) skip-if(!Android) pref(apz.allow_zooming,true) == async-scrollbar-1-h-rtl.html async-scrollbar-1-h-rtl.html +fuzzy-if(Android,3,7) skip-if(!Android) pref(apz.allow_zooming,true) == async-scrollbar-1-vh-rtl.html async-scrollbar-1-vh-rtl.html # Different async zoom levels. Since the scrollthumb gets async-scaled in the # compositor, the border-radius ends of the scrollthumb are going to be a little @@ -15,6 +15,6 @@ fails == async-scrollbar-zoom-1.html async-scrollbar-zoom-1.html fails == async-scrollbar-zoom-2.html async-scrollbar-zoom-2.html # Meta-viewport tag support -# == initial-scale-1.html initial-scale-1.html +skip-if(!Android) pref(apz.allow_zooming,true) == initial-scale-1.html initial-scale-1.html skip-if(!asyncPan) == frame-reconstruction-scroll-clamping.html frame-reconstruction-scroll-clamping.html diff --git a/gfx/tests/reftest/reftest-stylo.list b/gfx/tests/reftest/reftest-stylo.list index 191b1f67c6b5..d9fae27a822e 100644 --- a/gfx/tests/reftest/reftest-stylo.list +++ b/gfx/tests/reftest/reftest-stylo.list @@ -1,7 +1,7 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing # 468496-1 will also detect bugs in video drivers. == 468496-1.html 468496-1.html -# == 611498-1.html 611498-1.html +skip-if(stylo) == 611498-1.html 611498-1.html # Bug 1302946 fails == 709477-1.html 709477-1.html skip-if(!asyncPan) == 1086723.html 1086723.html fails == 853889-1.html 853889-1.html diff --git a/image/test/reftest/bmp/bmpsuite/g/reftest-stylo.list b/image/test/reftest/bmp/bmpsuite/g/reftest-stylo.list index dfbd0f1531e6..56199b8b6752 100644 --- a/image/test/reftest/bmp/bmpsuite/g/reftest-stylo.list +++ b/image/test/reftest/bmp/bmpsuite/g/reftest-stylo.list @@ -77,18 +77,18 @@ # "A 16-bit image with the default color format: 5 bits each for red, green, and # blue, and 1 unused bit. The whitest colors should (I assume) be displayed as # pure white: (255,255,255), not (248,248,248)." -# == rgb16.bmp rgb16.bmp +== rgb16.bmp rgb16.bmp # BMP: bihsize=40, 127 x 64, bpp=16, compression=3, colors=0 # "A 16-bit image with a BITFIELDS segment indicating 5 red, 6 green, and 5 blue # bits. This is a standard 16-bit format, even supported by old versions of # Windows that don’t support any other non-default 16-bit formats. The whitest # colors should be displayed as pure white: (255,255,255), not (248,252,248)." -# == rgb16.bmp rgb16.bmp +== rgb16.bmp rgb16.bmp # BMP: bihsize=40, 127 x 64, bpp=16, compression=3, colors=256 # "A 16-bit image with both a BITFIELDS segment and a palette." -# == rgb16.bmp rgb16.bmp +== rgb16.bmp rgb16.bmp # BMP: bihsize=40, 127 x 64, bpp=24, compression=0, colors=0 # "A perfectly ordinary 24-bit (truecolor) image." diff --git a/layout/reftests/async-scrolling/reftest-stylo.list b/layout/reftests/async-scrolling/reftest-stylo.list index 72f7bd5aa274..ea29ead6d327 100644 --- a/layout/reftests/async-scrolling/reftest-stylo.list +++ b/layout/reftests/async-scrolling/reftest-stylo.list @@ -12,7 +12,7 @@ fails == bg-fixed-child-no-culling-1.html bg-fixed-child-no-culling-1.html == bg-fixed-child-no-culling-2.html bg-fixed-child-no-culling-2.html fuzzy-if(Android,2,4000) fuzzy-if(browserIsRemote&&cocoaWidget,2,179524) fuzzy-if(browserIsRemote&&winWidget,1,74590) fuzzy-if(gtkWidget&&layersGPUAccelerated,1,3528) skip-if(!asyncPan) == bg-fixed-transformed-image.html bg-fixed-transformed-image.html == element-1.html element-1.html -# == iframe-1.html iframe-1.html +== iframe-1.html iframe-1.html == nested-1.html nested-1.html == nested-2.html nested-2.html == position-fixed-1.html position-fixed-1.html @@ -30,7 +30,7 @@ fails == position-fixed-transformed-1.html position-fixed-transformed-1.html skip-if(!asyncPan) == sticky-pos-scrollable-3.html sticky-pos-scrollable-3.html fails == fixed-pos-scrollable-1.html fixed-pos-scrollable-1.html == culling-1.html culling-1.html -# == position-fixed-iframe-1.html position-fixed-iframe-1.html +== position-fixed-iframe-1.html position-fixed-iframe-1.html == position-fixed-iframe-2.html position-fixed-iframe-2.html fuzzy-if(skiaContent,1,11300) skip-if(!asyncPan) == position-fixed-in-scroll-container.html position-fixed-in-scroll-container.html == position-fixed-inside-sticky-1.html position-fixed-inside-sticky-1.html diff --git a/layout/reftests/backgrounds/reftest-stylo.list b/layout/reftests/backgrounds/reftest-stylo.list index 55980996c02a..c83c291c5d28 100644 --- a/layout/reftests/backgrounds/reftest-stylo.list +++ b/layout/reftests/backgrounds/reftest-stylo.list @@ -16,7 +16,7 @@ fails == viewport-translucent-color-3.html viewport-translucent-color-3.html fails == translucent-color-2.html translucent-color-2.html fuzzy-if(skiaContent,1,1024) == translucent-color-3.html translucent-color-3.html == translucent-color-ref.html translucent-color-ref.html -# == root-element-display-none-1.html root-element-display-none-1.html +== root-element-display-none-1.html root-element-display-none-1.html fails == continuous-inline-1a.html continuous-inline-1a.html fails == continuous-inline-1b.html continuous-inline-1b.html fails == continuous-inline-1c.html continuous-inline-1c.html @@ -41,8 +41,8 @@ fails == continuous-inline-5b.html continuous-inline-5b.html == background-position-1f.html background-position-1f.html == background-position-2a.html background-position-2a.html == background-position-2b.html background-position-2b.html -# == background-position-2c.html background-position-2c.html -# == background-position-2d.html background-position-2d.html +== background-position-2c.html background-position-2c.html +== background-position-2d.html background-position-2d.html == background-position-3a.html background-position-3a.html == background-position-3b.html background-position-3b.html == background-position-3c.html background-position-3c.html @@ -92,11 +92,11 @@ fails == continuous-inline-5b.html continuous-inline-5b.html == background-size-zoom-no-repeat.html background-size-zoom-no-repeat.html -# == background-size-contain-clip-padding.html background-size-contain-clip-padding.html +== background-size-contain-clip-padding.html background-size-contain-clip-padding.html == background-size-contain-clip-border.html background-size-contain-clip-border.html == background-size-contain-position-fifty-fifty.html background-size-contain-position-fifty-fifty.html == background-size-contain-clip-padding-origin-border.html background-size-contain-clip-padding-origin-border.html -# == background-size-contain-clip-padding-origin-border-padding.html background-size-contain-clip-padding-origin-border-padding.html +== background-size-contain-clip-padding-origin-border-padding.html background-size-contain-clip-padding-origin-border-padding.html == background-layers-1a.html background-layers-1a.html == background-layers-1b.html background-layers-1b.html @@ -138,11 +138,11 @@ fuzzy(2,83) == fixed-bg-border-radius.html fixed-bg-border-radius.html fails HTTP == root-background-1.html root-background-1.html fails HTTP == root-background-1.html root-background-1.html -# == really-big-background.html really-big-background.html -# == body-background.html body-background.html -# == table-background.html table-background.html +fails == really-big-background.html really-big-background.html # Bug 1341690 +fails == body-background.html body-background.html # Bug 1339711 +fails == table-background.html table-background.html # Bug 1339711 fails == table-background-print.html table-background-print.html -# == div-background.html div-background.html +== div-background.html div-background.html == background-repeat-1-ref.html background-repeat-1-ref.html @@ -179,11 +179,11 @@ fails == background-tiling-zoom-1.html background-tiling-zoom-1.html skip-if(!cocoaWidget) == background-repeat-resampling.html background-repeat-resampling.html -# == background-clip-text-1a.html background-clip-text-1a.html -# == background-clip-text-1b.html background-clip-text-1b.html -# == background-clip-text-1c.html background-clip-text-1c.html -# == background-clip-text-1d.html background-clip-text-1d.html -# == background-clip-text-1e.html background-clip-text-1e.html +== background-clip-text-1a.html background-clip-text-1a.html +== background-clip-text-1b.html background-clip-text-1b.html +== background-clip-text-1c.html background-clip-text-1c.html +== background-clip-text-1d.html background-clip-text-1d.html +== background-clip-text-1e.html background-clip-text-1e.html # pref(layout.css.background-clip-text.enabled,false) == background-clip-text-1a.html background-clip-text-1a.html # pref(layout.css.background-clip-text.enabled,true) == background-clip-text-2.html background-clip-text-2.html diff --git a/layout/reftests/backgrounds/vector/reftest-stylo.list b/layout/reftests/backgrounds/vector/reftest-stylo.list index bb71586fbaf7..7aca88f64207 100644 --- a/layout/reftests/backgrounds/vector/reftest-stylo.list +++ b/layout/reftests/backgrounds/vector/reftest-stylo.list @@ -201,5 +201,5 @@ include empty/reftest-stylo.list == wide--cover--percent-width-percent-height.html wide--cover--percent-width-percent-height.html == wide--cover--percent-width-percent-height-viewbox.html wide--cover--percent-width-percent-height-viewbox.html -# == diagonal-percentage-vector-background.html diagonal-percentage-vector-background.html +== diagonal-percentage-vector-background.html diagonal-percentage-vector-background.html == no-aspect-ratio-wide.html no-aspect-ratio-wide.html diff --git a/layout/reftests/bidi/dirAuto/reftest-stylo.list b/layout/reftests/bidi/dirAuto/reftest-stylo.list index d7f715fe4780..994952d0fc49 100644 --- a/layout/reftests/bidi/dirAuto/reftest-stylo.list +++ b/layout/reftests/bidi/dirAuto/reftest-stylo.list @@ -42,8 +42,8 @@ fails == dynamicDirAuto-setLTR-InvalidDir3.html dynamicDirAuto-setLTR-InvalidDir fails == dynamicDirAuto-setLTR-InvalidDir4.html dynamicDirAuto-setLTR-InvalidDir4.html fails == dynamicDirAuto-setLTR-InvalidDir5.html dynamicDirAuto-setLTR-InvalidDir5.html fails == dynamicDirAuto-setLTR-InvalidDir6.html dynamicDirAuto-setLTR-InvalidDir6.html -# == dynamicDirAuto-setLTR-InvalidDir7.html dynamicDirAuto-setLTR-InvalidDir7.html -# == dynamicDirAuto-setLTR-InvalidDir7.html dynamicDirAuto-setLTR-InvalidDir7.html +fails == dynamicDirAuto-setLTR-InvalidDir7.html dynamicDirAuto-setLTR-InvalidDir7.html # Bug 1340696, bug 1341086 +fails == dynamicDirAuto-setLTR-InvalidDir7.html dynamicDirAuto-setLTR-InvalidDir7.html # Bug 1340696, bug 1341086 fails == dynamicDirAuto-setRTL-Auto1.html dynamicDirAuto-setRTL-Auto1.html fails == dynamicDirAuto-setRTL-Auto2.html dynamicDirAuto-setRTL-Auto2.html fails == dynamicDirAuto-setRTL-Auto3.html dynamicDirAuto-setRTL-Auto3.html diff --git a/layout/reftests/bidi/numeral/reftest-stylo.list b/layout/reftests/bidi/numeral/reftest-stylo.list index 0db187ff5f58..c0e26b48b9b8 100644 --- a/layout/reftests/bidi/numeral/reftest-stylo.list +++ b/layout/reftests/bidi/numeral/reftest-stylo.list @@ -35,9 +35,9 @@ pref(bidi.numeral,2) == bug441782-2.html bug441782-2.html pref(bidi.numeral,3) == bug441782-2.html bug441782-2.html pref(bidi.numeral,4) == bug441782-2.html bug441782-2.html # pref(bidi.numeral,0) == bug441782-3.html bug441782-3.html -# == bug441782-3.html bug441782-3.html -# == bug441782-3.html bug441782-3.html -# == bug441782-3.html bug441782-3.html +== bug441782-3.html bug441782-3.html +== bug441782-3.html bug441782-3.html +== bug441782-3.html bug441782-3.html # pref(bidi.numeral,4) == bug441782-3.html bug441782-3.html pref(bidi.numeral,0) == bug441782-4.html bug441782-4.html pref(bidi.numeral,1) == bug441782-4.html bug441782-4.html diff --git a/layout/reftests/bidi/reftest-stylo.list b/layout/reftests/bidi/reftest-stylo.list index 45144ebe6096..dfeef3c29ad3 100644 --- a/layout/reftests/bidi/reftest-stylo.list +++ b/layout/reftests/bidi/reftest-stylo.list @@ -57,13 +57,13 @@ fails == 83958-2b.html 83958-2b.html fails == 115921-2.html 115921-2.html == 151407-1.html 151407-1.html == 151407-1a.html 151407-1a.html -# == 151407-2-ltr.html 151407-2-ltr.html -# == 151407-2-rtl.html 151407-2-rtl.html +== 151407-2-ltr.html 151407-2-ltr.html +== 151407-2-rtl.html 151407-2-rtl.html == 151407-2-auto.html 151407-2-auto.html == 151407-2-empty.html 151407-2-empty.html == 151407-2-foopy.html 151407-2-foopy.html -# == 151407-3-ltr.html 151407-3-ltr.html -# == 151407-3-rtl.html 151407-3-rtl.html +== 151407-3-ltr.html 151407-3-ltr.html +== 151407-3-rtl.html 151407-3-rtl.html == 151407-3-auto.html 151407-3-auto.html == 151407-3-foopy.html 151407-3-foopy.html == 229367-1.html 229367-1.html @@ -79,7 +79,7 @@ fails == 263359-4.html 263359-4.html fails == 267459-1.html 267459-1.html fails == 267459-2.html 267459-2.html == 299065-1.html 299065-1.html -# == 305643-1.html 305643-1.html +== 305643-1.html 305643-1.html fails asserts-if(stylo,7) == 332655-1.html 332655-1.html # bug 1335314 fails asserts-if(stylo,7) == 332655-2.html 332655-2.html # bug 1335314 fails == 381279-1.html 381279-1.html @@ -93,7 +93,7 @@ fails == 413928-2.html 413928-2.html == 425338-1b.html 425338-1b.html == 489517-1.html 489517-1.html == 489887-1.html 489887-1.html -# == 492231-1.html 492231-1.html +== 492231-1.html 492231-1.html == 496006-1.html 496006-1.html == 503269-1.html 503269-1.html == 503957-1.html 503957-1.html @@ -148,28 +148,28 @@ fuzzy-if(xulRuntime.widgetToolkit=="gtk3",1,11) == 869833-1.xul 869833-1.xul == 922530-1.html 922530-1.html == 922550-1.html 922550-1.html == 1067268-1.html 1067268-1.html -# == 1069941-inline-bidi-border-1.html 1069941-inline-bidi-border-1.html +== 1069941-inline-bidi-border-1.html 1069941-inline-bidi-border-1.html == 1069941-inline-bidi-margin-1.html 1069941-inline-bidi-margin-1.html == 1155359-1.xul 1155359-1.xul == 1157726-1.html 1157726-1.html == 1161752.html 1161752.html == 1161752-5-embed.html 1161752-5-embed.html -# == brackets-1a-ltr.html brackets-1a-ltr.html -# == brackets-1a-rtl.html brackets-1a-rtl.html -# == brackets-1b-ltr.html brackets-1b-ltr.html -# == brackets-1b-rtl.html brackets-1b-rtl.html -# == brackets-1c-ltr.html brackets-1c-ltr.html -# == brackets-1c-rtl.html brackets-1c-rtl.html -# == brackets-2a-ltr.html brackets-2a-ltr.html -# == brackets-2a-rtl.html brackets-2a-rtl.html -# == brackets-2b-ltr.html brackets-2b-ltr.html -# == brackets-2b-rtl.html brackets-2b-rtl.html -# == brackets-2c-ltr.html brackets-2c-ltr.html -# == brackets-2c-rtl.html brackets-2c-rtl.html -# == brackets-3a-ltr.html brackets-3a-ltr.html -# == brackets-3a-rtl.html brackets-3a-rtl.html -# == brackets-3b-ltr.html brackets-3b-ltr.html -# == brackets-3b-rtl.html brackets-3b-rtl.html +== brackets-1a-ltr.html brackets-1a-ltr.html +== brackets-1a-rtl.html brackets-1a-rtl.html +== brackets-1b-ltr.html brackets-1b-ltr.html +== brackets-1b-rtl.html brackets-1b-rtl.html +== brackets-1c-ltr.html brackets-1c-ltr.html +== brackets-1c-rtl.html brackets-1c-rtl.html +== brackets-2a-ltr.html brackets-2a-ltr.html +== brackets-2a-rtl.html brackets-2a-rtl.html +== brackets-2b-ltr.html brackets-2b-ltr.html +== brackets-2b-rtl.html brackets-2b-rtl.html +== brackets-2c-ltr.html brackets-2c-ltr.html +== brackets-2c-rtl.html brackets-2c-rtl.html +== brackets-3a-ltr.html brackets-3a-ltr.html +== brackets-3a-rtl.html brackets-3a-rtl.html +== brackets-3b-ltr.html brackets-3b-ltr.html +== brackets-3b-rtl.html brackets-3b-rtl.html fails == 1217833-1.html 1217833-1.html fails == 1217833-2.html 1217833-2.html == 1231175-1.html 1231175-1.html diff --git a/layout/reftests/border-image/reftest-stylo.list b/layout/reftests/border-image/reftest-stylo.list index adb3fa9ed9d3..9dad1e7c9b35 100644 --- a/layout/reftests/border-image/reftest-stylo.list +++ b/layout/reftests/border-image/reftest-stylo.list @@ -14,9 +14,9 @@ fails == transparent-image-1.html transparent-image-1.html fails == repeat-image-1.html repeat-image-1.html fails == 470250-1.html 470250-1.html fails == 470250-2.html 470250-2.html -# == different-h-v-1.html different-h-v-1.html +fails == different-h-v-1.html different-h-v-1.html # Bug 1341703 fails == different-h-v-2.html different-h-v-2.html -# == different-h-v-1.html different-h-v-1.html +fails == different-h-v-1.html different-h-v-1.html # Bug 1341703 fails == center-scaling-1.html center-scaling-1.html fails == center-scaling-2.html center-scaling-2.html fails == center-scaling-3.html center-scaling-3.html diff --git a/layout/reftests/border-radius/reftest-stylo.list b/layout/reftests/border-radius/reftest-stylo.list index 719cf9e4f816..51db27534195 100644 --- a/layout/reftests/border-radius/reftest-stylo.list +++ b/layout/reftests/border-radius/reftest-stylo.list @@ -65,7 +65,7 @@ fuzzy-if(true,1,33) fuzzy-if(d2d,48,350) fuzzy-if(cocoaWidget,1,332) fuzzy-if(An == inherit-1.html inherit-1.html # Table elements -# == table-collapse-1.html table-collapse-1.html +== table-collapse-1.html table-collapse-1.html # when border-collapse: collapse fuzzy-if(skiaContent,1,116) == invalidate-1a.html invalidate-1a.html @@ -85,7 +85,7 @@ fails == corner-joins-1.xhtml corner-joins-1.xhtml == zero-radius-clip-1.html zero-radius-clip-1.html -# == iframe-1.html iframe-1.html +== iframe-1.html iframe-1.html # Test for antialiasing gaps between background and border fuzzy-if(gtkWidget,1,9) fuzzy-if(winWidget&&!d2d,1,9) fuzzy-if(d2d,5,40) fuzzy-if(Android||skiaContent,1,9) == curved-border-background-nogap.html curved-border-background-nogap.html diff --git a/layout/reftests/box-properties/reftest-stylo.list b/layout/reftests/box-properties/reftest-stylo.list index 53b6c6da4c52..e27d961c28f6 100644 --- a/layout/reftests/box-properties/reftest-stylo.list +++ b/layout/reftests/box-properties/reftest-stylo.list @@ -17,9 +17,9 @@ fails == box-sizing-1.html box-sizing-1.html fails == box-sizing-2.html box-sizing-2.html fails == box-sizing-3.html box-sizing-3.html fails == box-sizing-4.html box-sizing-4.html -# == box-sizing-minmax-height.html box-sizing-minmax-height.html +== box-sizing-minmax-height.html box-sizing-minmax-height.html == box-sizing-minmax-width.html box-sizing-minmax-width.html -# == box-sizing-mozbox-minmax-height.html box-sizing-mozbox-minmax-height.html +== box-sizing-mozbox-minmax-height.html box-sizing-mozbox-minmax-height.html fails == abspos-non-replaced-width-offset-margin.html abspos-non-replaced-width-offset-margin.html fails == abspos-replaced-width-offset-margin.html abspos-replaced-width-offset-margin.html fails HTTP(..) == CSS21-t100301.xhtml CSS21-t100301.xhtml diff --git a/layout/reftests/box-shadow/reftest-stylo.list b/layout/reftests/box-shadow/reftest-stylo.list index 2e7f55a4e71c..180121a98dbb 100644 --- a/layout/reftests/box-shadow/reftest-stylo.list +++ b/layout/reftests/box-shadow/reftest-stylo.list @@ -1,10 +1,10 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing == boxshadow-basic.html boxshadow-basic.html -# == boxshadow-blur.html boxshadow-blur.html -# == boxshadow-blur.html boxshadow-blur.html +== boxshadow-blur.html boxshadow-blur.html +== boxshadow-blur.html boxshadow-blur.html fails random == boxshadow-blur-2.html boxshadow-blur-2.html fails random == boxshadow-blur-2.html boxshadow-blur-2.html -# == boxshadow-multiple.html boxshadow-multiple.html +== boxshadow-multiple.html boxshadow-multiple.html == boxshadow-spread.html boxshadow-spread.html fails == tableboxshadow-basic.html tableboxshadow-basic.html fails == tableboxshadow-trshadow.html tableboxshadow-trshadow.html @@ -33,12 +33,12 @@ fails == boxshadow-rotated.html boxshadow-rotated.html # fuzzy due to blur going inside, but as long as it's essentially black instead of a light gray its ok. fuzzy(12,9445) fuzzy-if(d2d,13,10926) == boxshadow-inset-large-offset.html boxshadow-inset-large-offset.html -# == overflow-not-scrollable-1.html overflow-not-scrollable-1.html -# == overflow-not-scrollable-1.html overflow-not-scrollable-1.html +== overflow-not-scrollable-1.html overflow-not-scrollable-1.html +== overflow-not-scrollable-1.html overflow-not-scrollable-1.html == overflow-not-scrollable-2.html overflow-not-scrollable-2.html fails == 611574-1.html 611574-1.html fails == 611574-2.html 611574-2.html -# == fieldset.html fieldset.html +== fieldset.html fieldset.html fuzzy-if(winWidget,5,30) fuzzy-if(skiaContent,16,10) == fieldset-inset.html fieldset-inset.html == 1178575.html 1178575.html == 1178575-2.html 1178575-2.html diff --git a/layout/reftests/box-sizing/reftest-stylo.list b/layout/reftests/box-sizing/reftest-stylo.list index 21eb9279892c..14f2843972ad 100644 --- a/layout/reftests/box-sizing/reftest-stylo.list +++ b/layout/reftests/box-sizing/reftest-stylo.list @@ -14,4 +14,4 @@ == intrinsic-1m.html intrinsic-1m.html == intrinsic-1n.html intrinsic-1n.html == intrinsic-1o.html intrinsic-1o.html -# == computed-size-reporting.html computed-size-reporting.html +== computed-size-reporting.html computed-size-reporting.html diff --git a/layout/reftests/bugs/reftest-stylo.list b/layout/reftests/bugs/reftest-stylo.list index 62b01fd998d4..af7eee635c27 100644 --- a/layout/reftests/bugs/reftest-stylo.list +++ b/layout/reftests/bugs/reftest-stylo.list @@ -3,7 +3,7 @@ # logical order for the tests for each bug). fails == 105-1.html 105-1.html fails == 647-1.html 647-1.html -# == 9458-basic-1.html 9458-basic-1.html +== 9458-basic-1.html 9458-basic-1.html fails == 9458-valign-1.html 9458-valign-1.html fails == 9458-valign-2.html 9458-valign-2.html == 9458-height-1.html 9458-height-1.html @@ -12,7 +12,7 @@ fails == 9458-valign-2.html 9458-valign-2.html == 9458-width-1b.html 9458-width-1b.html == 9458-width-2a.html 9458-width-2a.html == 9458-width-2b.html 9458-width-2b.html -# == 9458-zorder-1.html 9458-zorder-1.html +== 9458-zorder-1.html 9458-zorder-1.html == 9458-zorder-2.html 9458-zorder-2.html == 9458-zorder-3.html 9458-zorder-3.html == 9458-zorder-4.html 9458-zorder-4.html @@ -21,7 +21,7 @@ fails == 10036-1.html 10036-1.html fails == 10209-1.html 10209-1.html HTTP(..) == 10209-2.html 10209-2.html asserts(2) skip-if(!cocoaWidget) HTTP(..) == 10209-3.html 10209-3.html -# == 18217-basic-1.html 18217-basic-1.html +== 18217-basic-1.html 18217-basic-1.html == 18217-basic-2a.html 18217-basic-2a.html == 18217-basic-2b.html 18217-basic-2b.html fails == 18217-valign-1.html 18217-valign-1.html @@ -31,7 +31,7 @@ fails == 18217-valign-1.html 18217-valign-1.html == 18217-width-1b.html 18217-width-1b.html == 18217-width-2a.html 18217-width-2a.html == 18217-width-2b.html 18217-width-2b.html -# == 18217-zorder-1.html 18217-zorder-1.html +== 18217-zorder-1.html 18217-zorder-1.html == 18217-zorder-2.html 18217-zorder-2.html == 18217-zorder-3.html 18217-zorder-3.html == 18217-zorder-4.html 18217-zorder-4.html @@ -39,18 +39,18 @@ fails == 18217-valign-1.html 18217-valign-1.html fails == 23604-1.html 23604-1.html fails == 23604-2.html 23604-2.html == 24998-1.html 24998-1.html -# == 25888-1l.html 25888-1l.html -# == 25888-1l.html 25888-1l.html -# == 25888-1r.html 25888-1r.html -# == 25888-1r.html 25888-1r.html +== 25888-1l.html 25888-1l.html +== 25888-1l.html 25888-1l.html +== 25888-1r.html 25888-1r.html +== 25888-1r.html 25888-1r.html == 25888-2l.html 25888-2l.html == 25888-2r.html 25888-2r.html == 25888-3l.html 25888-3l.html == 25888-3r.html 25888-3r.html -# == 25888-1l-block.html 25888-1l-block.html -# == 25888-1l-block.html 25888-1l-block.html -# == 25888-1r-block.html 25888-1r-block.html -# == 25888-1r-block.html 25888-1r-block.html +== 25888-1l-block.html 25888-1l-block.html +== 25888-1l-block.html 25888-1l-block.html +== 25888-1r-block.html 25888-1r-block.html +== 25888-1r-block.html 25888-1r-block.html == 25888-2l-block.html 25888-2l-block.html == 25888-2r-block.html 25888-2r-block.html == 25888-3l-block.html 25888-3l-block.html @@ -74,8 +74,8 @@ fails == 40596-1j.html 40596-1j.html == 50630-1c.html 50630-1c.html == 50630-2.html 50630-2.html == 50630-3.html 50630-3.html -# == 50630-4.html 50630-4.html -# == 50630-4.html 50630-4.html +== 50630-4.html 50630-4.html +== 50630-4.html 50630-4.html == 50630-5.html 50630-5.html == 67752-1.html 67752-1.html == 67752-2.html 67752-2.html @@ -86,8 +86,8 @@ fails == 81947-1.html 81947-1.html fails == 82711-1.html 82711-1.html fails == 82711-2.html 82711-2.html fails == 82711-3.html 82711-3.html -# == 82711-1-ref.html 82711-1-ref.html -# == 82711-1-ref.html 82711-1-ref.html +fails == 82711-1-ref.html 82711-1-ref.html # Bug 1341697, Bug 1341637 +fails == 82711-1-ref.html 82711-1-ref.html # Bug 1341697, Bug 1341637 fails == 82711-2-ref.html 82711-2-ref.html fails == 84400-1.html 84400-1.html fails == 84400-2.html 84400-2.html @@ -95,16 +95,16 @@ fails == 84400-2.html 84400-2.html fails == 97777-2.html 97777-2.html == 98223-1.html 98223-1.html == 98223-2.html 98223-2.html -# == 99850-1a.html 99850-1a.html # bug 1337695 -# == 99850-1b.html 99850-1b.html # bug 1337695 +skip-if(stylo) == 99850-1a.html 99850-1a.html # bug 1337695 +skip-if(stylo) == 99850-1b.html 99850-1b.html # bug 1337695 fails == 99850-1c.html 99850-1c.html -# == 99850-1d.html 99850-1d.html # bug 1337695 +skip-if(stylo) == 99850-1d.html 99850-1d.html # bug 1337695 == 105030-1.html 105030-1.html == 109735-1.html 109735-1.html == 116882-1.html 116882-1.html == 120834-1a.html 120834-1a.html == 120834-2a.html 120834-2a.html -# == 120834-2b.html 120834-2b.html +== 120834-2b.html 120834-2b.html == 120834-2c.html 120834-2c.html == 120834-2d.html 120834-2d.html == 120834-2e.html 120834-2e.html @@ -150,9 +150,9 @@ fails == 163504-2b.html 163504-2b.html fails == 175190-1.html 175190-1.html fails == 179596-1a.html 179596-1a.html fails == 179596-1b.html 179596-1b.html -# == 179596-2.html 179596-2.html -# == 179596-2.html 179596-2.html -# == 179596-2.html 179596-2.html +== 179596-2.html 179596-2.html +== 179596-2.html 179596-2.html +== 179596-2.html 179596-2.html fails == 180085-1.html 180085-1.html fails == 180085-2.html 180085-2.html fails == 185388-1.html 185388-1.html @@ -212,7 +212,7 @@ fails == 223809-1.html 223809-1.html == 228856-1.html 228856-1.html == 228856-2.html 228856-2.html == 229591-1.html 229591-1.html -# == 231823-1.html 231823-1.html +fails == 231823-1.html 231823-1.html == 232990-1a.xhtml 232990-1a.xhtml == 232990-1b.xhtml 232990-1b.xhtml fails == 233094-1.html 233094-1.html @@ -302,17 +302,17 @@ fails == 280708-1a.html 280708-1a.html fails == 280708-1b.html 280708-1b.html fails == 281241-1.html 281241-1.html fails == 281241-2.xhtml 281241-2.xhtml -# == 283686-1.html 283686-1.html +== 283686-1.html 283686-1.html == 283686-2.html 283686-2.html -# == 283686-3.html 283686-3.html +== 283686-3.html 283686-3.html fails == 289384-1.xhtml 289384-1.xhtml -# == 289480.html#top 289480.html#top +skip-if(stylo) == 289480.html#top 289480.html#top # Bug 1341705 fails == 290129-1.html 290129-1.html fails == 291078-1.html 291078-1.html == 291078-2.html 291078-2.html == 291262-1.html 291262-1.html -# == 294306-1.html 294306-1.html -# == 294306-1.html 294306-1.html +== 294306-1.html 294306-1.html +== 294306-1.html 294306-1.html fails == 296361-1.html 296361-1.html == 296904-1.html 296904-1.html fails == 299136-1.html 299136-1.html @@ -346,8 +346,8 @@ fails == 307102-3.html 307102-3.html == 311366-unknown-block-3.html 311366-unknown-block-3.html == 311366-unknown-block-2.html 311366-unknown-block-2.html == 311366-unknown-inline-2.html 311366-unknown-inline-2.html -# == 311822-1.html 311822-1.html -# == 311822-1.html 311822-1.html +fails == 311822-1.html 311822-1.html # bug 1341712, bug 1341714 +fails == 311822-1.html 311822-1.html # bug 1341712, bug 1341714 fails == 315620-1a.html 315620-1a.html == 315620-1b.html 315620-1b.html fails == 315620-2a.xhtml 315620-2a.xhtml @@ -434,9 +434,9 @@ random == 328829-1.xhtml 328829-1.xhtml == 329359-1.html 329359-1.html fails == 331809-1.html 331809-1.html == 332360.html 332360.html -# == 332360-ltr.html 332360-ltr.html +== 332360-ltr.html 332360-ltr.html == 332360-width.html 332360-width.html -# == 332360-width-ltr.html 332360-width-ltr.html +== 332360-width-ltr.html 332360-width-ltr.html fails == 332557-1.html 332557-1.html == 332975-1.html 332975-1.html == 333970-1.html 333970-1.html @@ -470,8 +470,8 @@ fails == 347496-1.xhtml 347496-1.xhtml == 347912-1.html 347912-1.html fails == 348049-1.xhtml 348049-1.xhtml fails == 348516-1.html 348516-1.html -# == 348516-2.html 348516-2.html -# == 348516-2.html 348516-2.html +fails == 348516-2.html 348516-2.html # Bug 1321769? +fails == 348516-2.html 348516-2.html # Bug 1321769? fails == 348516-3.html 348516-3.html == 348597-1.html 348597-1.html == 348809-1a.html 348809-1a.html @@ -531,17 +531,17 @@ fails == 359869-1.html 359869-1.html fails == 359903-1.html 359903-1.html fails == 359903-2.html 359903-2.html == 360065-1.html 360065-1.html -# == 360746-1.html 360746-1.html +asserts-if(stylo,1) == 360746-1.html 360746-1.html # Bug 1341721 == 360757-1a.html 360757-1a.html == 360757-1b.html 360757-1b.html == 361091-1.html 361091-1.html fails == 362594-1a.html 362594-1a.html fails == 362594-1b.html 362594-1b.html fails == 362594-1c.html 362594-1c.html -# == 362594-2a.html 362594-2a.html -# == 362594-2a.html 362594-2a.html -# == 362594-2b.html 362594-2b.html -# == 362594-2b.html 362594-2b.html +fails == 362594-2a.html 362594-2a.html # Bug 1341651 +fails == 362594-2a.html 362594-2a.html # Bug 1341651 +fails == 362594-2b.html 362594-2b.html # Bug 1341651 +fails == 362594-2b.html 362594-2b.html # Bug 1341651 fails == 362594-2c.html 362594-2c.html fails == 362901-1.html 362901-1.html == 363247-1.html 363247-1.html @@ -550,8 +550,8 @@ fails == 363329-2.html 363329-2.html fails == 363370-1.html 363370-1.html fails == 363402-1.html 363402-1.html == 363637-1.html 363637-1.html -# == 363706-1.html 363706-1.html -# == 363706-1.html 363706-1.html +fails == 363706-1.html 363706-1.html # Bug 1324348 +fails == 363706-1.html 363706-1.html # Bug 1324348 fails == 363728-1.html 363728-1.html == 363728-2.html 363728-2.html fails == 363858-1.html 363858-1.html @@ -608,7 +608,7 @@ fails pref(layout.css.box-decoration-break.enabled,true) == 368020-5.html 368020 fails asserts(4-8) == 368155-negative-margins-1.html 368155-negative-margins-1.html # we can't test this because there's antialiasing involved, and our comparison # is too exact -# == 368247-1.html 368247-1.html +== 368247-1.html 368247-1.html == 368247-2.html 368247-2.html == 368504-1.html 368504-1.html fails == 368504-2.html 368504-2.html @@ -625,10 +625,10 @@ fails == 368651-1.html 368651-1.html fails == 369975-1.html 369975-1.html == 370353-1.html 370353-1.html fails == 370422-1.html 370422-1.html -# == 370525-1.html 370525-1.html -# == 370525-1.html 370525-1.html -# == 370525-2.html 370525-2.html -# == 370525-2.html 370525-2.html +== 370525-1.html 370525-1.html +== 370525-1.html 370525-1.html +== 370525-2.html 370525-2.html +== 370525-2.html 370525-2.html == 370525-rowspan-1a.html 370525-rowspan-1a.html == 370525-rowspan-1b.html 370525-rowspan-1b.html == 370525-rowspan-1c.html 370525-rowspan-1c.html @@ -704,8 +704,8 @@ fails == 379361-2.html 379361-2.html fails == 379361-3.html 379361-3.html == 379461-1.xhtml 379461-1.xhtml == 379461-2.xhtml 379461-2.xhtml -# == 379461-3-container-xhtml.html 379461-3-container-xhtml.html -# == 379461-3-container-xhtml.html 379461-3-container-xhtml.html +fails == 379461-3-container-xhtml.html 379461-3-container-xhtml.html # Bug 1341095 +fails == 379461-3-container-xhtml.html 379461-3-container-xhtml.html # Bug 1341095 == 380004-1.html 380004-1.html == 380227-1.html 380227-1.html fails == 380825-1.html 380825-1.html @@ -753,9 +753,9 @@ fails test-pref(layout.float-fragments-inside-column.enabled,true) == 386147-1.h == 386401-1.html 386401-1.html == 386401-2.html 386401-2.html == 386401-3.html 386401-3.html -# == 386470-1a.html 386470-1a.html +fails == 386470-1a.html 386470-1a.html # Bug 1341725 fails == 386470-1b.html 386470-1b.html -# == 386470-1c.html 386470-1c.html +fails == 386470-1c.html 386470-1c.html # Bug 1341725 == 386920-1.html 386920-1.html == 387201-1.html 387201-1.html == 387201-2.html 387201-2.html @@ -769,8 +769,8 @@ fails == 386470-1b.html 386470-1b.html == 387876-3b.html 387876-3b.html == 388026-1.html 388026-1.html fails == 389074-1.html 389074-1.html -# == 389224-1.html 389224-1.html -# == 389224-2.html 389224-2.html +== 389224-1.html 389224-1.html +fails == 389224-2.html 389224-2.html # Bug 1341728 fails == 389468-1.html 389468-1.html == 389623-1.html 389623-1.html == 389636-1.html 389636-1.html @@ -808,7 +808,7 @@ fails == 393490-1.html 393490-1.html fuzzy-if(skiaContent,1,500) == 393760-2.xml 393760-2.xml == 394111-1.html 394111-1.html == 394534-1.html 394534-1.html -# == 394676-1.xhtml 394676-1.xhtml +skip-if(stylo) == 394676-1.xhtml 394676-1.xhtml # Bug 1341719 fails == 395107-1.html 395107-1.html fails == 395107-2.html 395107-2.html fails == 395107-3.html 395107-3.html @@ -887,7 +887,7 @@ fails == 403656-3.html 403656-3.html == 403656-5.html 403656-5.html #== 403657-1.html 403657-1.html fails == 403733-1.html 403733-1.html -# == 403962-1.xhtml 403962-1.xhtml +fails == 403962-1.xhtml 403962-1.xhtml # Bug 1290276 == 404030-1.html 404030-1.html == 404030-1-notref.html 404030-1-notref.html == 404030-1-notref2.html 404030-1-notref2.html @@ -911,7 +911,7 @@ fails == 405305-1.html 405305-1.html == 405517-1.xhtml 405517-1.xhtml == 405577-1.html 405577-1.html == 405584-1.html 405584-1.html -# == 405952-1.html 405952-1.html +fails == 405952-1.html 405952-1.html # Bug 1321769? == 406484-1.html 406484-1.html == 406568-1.html 406568-1.html fails == 407016-1-a.html 407016-1-a.html @@ -1045,9 +1045,9 @@ random-if(gtkWidget) == 424074-1-ref2.xul 424074-1-ref2.xul == 424631-1.html 424631-1.html == 424710-1.html 424710-1.html fails == 424766-1.html 424766-1.html -# == 425972-1.html 425972-1.html +== 425972-1.html 425972-1.html == 425972-2.html 425972-2.html -# == 425972-1.html 425972-1.html +== 425972-1.html 425972-1.html fails == 426629-1.html 426629-1.html asserts(3-6) == 427017-1.xhtml 427017-1.xhtml == 427129-scrollframe.html 427129-scrollframe.html @@ -1062,39 +1062,39 @@ fails == 427730-1.html 427730-1.html fails == 428521-1a.html 428521-1a.html fails == 428521-1b.html 428521-1b.html fails == 428521-1c.html 428521-1c.html -# == 428810-1a-ltr.html 428810-1a-ltr.html -# == 428810-1b-ltr.html 428810-1b-ltr.html -# == 428810-1c-ltr.html 428810-1c-ltr.html -# == 428810-1d-ltr.html 428810-1d-ltr.html +== 428810-1a-ltr.html 428810-1a-ltr.html +== 428810-1b-ltr.html 428810-1b-ltr.html +== 428810-1c-ltr.html 428810-1c-ltr.html +== 428810-1d-ltr.html 428810-1d-ltr.html == 428810-1-ltr-ref.html 428810-1-ltr-ref.html -# == 428810-2a-ltr.html 428810-2a-ltr.html -# == 428810-2b-ltr.html 428810-2b-ltr.html -# == 428810-2e-ltr.html 428810-2e-ltr.html -# == 428810-2f-ltr.html 428810-2f-ltr.html +== 428810-2a-ltr.html 428810-2a-ltr.html +== 428810-2b-ltr.html 428810-2b-ltr.html +== 428810-2e-ltr.html 428810-2e-ltr.html +== 428810-2f-ltr.html 428810-2f-ltr.html == 428810-2-ltr-ref.html 428810-2-ltr-ref.html -# == 428810-3a-ltr.html 428810-3a-ltr.html -# == 428810-3b-ltr.html 428810-3b-ltr.html -# == 428810-3e-ltr.html 428810-3e-ltr.html -# == 428810-3f-ltr.html 428810-3f-ltr.html +== 428810-3a-ltr.html 428810-3a-ltr.html +== 428810-3b-ltr.html 428810-3b-ltr.html +== 428810-3e-ltr.html 428810-3e-ltr.html +== 428810-3f-ltr.html 428810-3f-ltr.html == 428810-3-ltr-ref.html 428810-3-ltr-ref.html -# == 428810-1a-rtl.html 428810-1a-rtl.html -# == 428810-1b-rtl.html 428810-1b-rtl.html -# == 428810-1c-rtl.html 428810-1c-rtl.html -# == 428810-1d-rtl.html 428810-1d-rtl.html -# == 428810-1-rtl-ref.html 428810-1-rtl-ref.html -# == 428810-1-rtl-ref.html 428810-1-rtl-ref.html -# == 428810-2a-rtl.html 428810-2a-rtl.html -# == 428810-2b-rtl.html 428810-2b-rtl.html -# == 428810-2e-rtl.html 428810-2e-rtl.html -# == 428810-2f-rtl.html 428810-2f-rtl.html -# == 428810-2-rtl-ref.html 428810-2-rtl-ref.html -# == 428810-2-rtl-ref.html 428810-2-rtl-ref.html -# == 428810-3a-rtl.html 428810-3a-rtl.html -# == 428810-3b-rtl.html 428810-3b-rtl.html -# == 428810-3e-rtl.html 428810-3e-rtl.html -# == 428810-3f-rtl.html 428810-3f-rtl.html -# == 428810-3-rtl-ref.html 428810-3-rtl-ref.html -# == 428810-3-rtl-ref.html 428810-3-rtl-ref.html +== 428810-1a-rtl.html 428810-1a-rtl.html +== 428810-1b-rtl.html 428810-1b-rtl.html +== 428810-1c-rtl.html 428810-1c-rtl.html +== 428810-1d-rtl.html 428810-1d-rtl.html +== 428810-1-rtl-ref.html 428810-1-rtl-ref.html +== 428810-1-rtl-ref.html 428810-1-rtl-ref.html +== 428810-2a-rtl.html 428810-2a-rtl.html +== 428810-2b-rtl.html 428810-2b-rtl.html +== 428810-2e-rtl.html 428810-2e-rtl.html +== 428810-2f-rtl.html 428810-2f-rtl.html +== 428810-2-rtl-ref.html 428810-2-rtl-ref.html +== 428810-2-rtl-ref.html 428810-2-rtl-ref.html +== 428810-3a-rtl.html 428810-3a-rtl.html +== 428810-3b-rtl.html 428810-3b-rtl.html +== 428810-3e-rtl.html 428810-3e-rtl.html +== 428810-3f-rtl.html 428810-3f-rtl.html +== 428810-3-rtl-ref.html 428810-3-rtl-ref.html +== 428810-3-rtl-ref.html 428810-3-rtl-ref.html == 428810-1a-ltr-insets.html 428810-1a-ltr-insets.html == 428810-1b-ltr-insets.html 428810-1b-ltr-insets.html == 428810-1c-ltr-insets.html 428810-1c-ltr-insets.html @@ -1114,20 +1114,20 @@ fails == 428521-1c.html 428521-1c.html == 428810-1b-rtl-insets.html 428810-1b-rtl-insets.html == 428810-1c-rtl-insets.html 428810-1c-rtl-insets.html == 428810-1d-rtl-insets.html 428810-1d-rtl-insets.html -# == 428810-1-rtl-insets-ref.html 428810-1-rtl-insets-ref.html -# == 428810-1-rtl-insets-ref.html 428810-1-rtl-insets-ref.html +== 428810-1-rtl-insets-ref.html 428810-1-rtl-insets-ref.html +== 428810-1-rtl-insets-ref.html 428810-1-rtl-insets-ref.html == 428810-2a-rtl-insets.html 428810-2a-rtl-insets.html == 428810-2b-rtl-insets.html 428810-2b-rtl-insets.html == 428810-2e-rtl-insets.html 428810-2e-rtl-insets.html == 428810-2f-rtl-insets.html 428810-2f-rtl-insets.html -# == 428810-2-rtl-insets-ref.html 428810-2-rtl-insets-ref.html -# == 428810-2-rtl-insets-ref.html 428810-2-rtl-insets-ref.html +== 428810-2-rtl-insets-ref.html 428810-2-rtl-insets-ref.html +== 428810-2-rtl-insets-ref.html 428810-2-rtl-insets-ref.html == 428810-3a-rtl-insets.html 428810-3a-rtl-insets.html == 428810-3b-rtl-insets.html 428810-3b-rtl-insets.html == 428810-3e-rtl-insets.html 428810-3e-rtl-insets.html == 428810-3f-rtl-insets.html 428810-3f-rtl-insets.html -# == 428810-3-rtl-insets-ref.html 428810-3-rtl-insets-ref.html -# == 428810-3-rtl-insets-ref.html 428810-3-rtl-insets-ref.html +== 428810-3-rtl-insets-ref.html 428810-3-rtl-insets-ref.html +== 428810-3-rtl-insets-ref.html 428810-3-rtl-insets-ref.html fails == 430412-1.html 430412-1.html == 430813-1.html 430813-1.html == 430813-2.html 430813-2.html @@ -1191,7 +1191,7 @@ fails == 451168-1.html 451168-1.html == 451876-2.html 451876-2.html == 452915-1.html 452915-1.html == 452964-1.html 452964-1.html -# == 454361.html 454361.html +== 454361.html 454361.html == 455105-1.html 455105-1.html == 455105-2.html 455105-2.html fails == 455171-5.html 455171-5.html @@ -1277,18 +1277,18 @@ fails == 474417-1.html 474417-1.html == 475986-3a.html 475986-3a.html == 475986-3b.html 475986-3b.html == 475986-4.html 475986-4.html -# == 475986-1-ref.html 475986-1-ref.html -# == 475986-1-ref.html 475986-1-ref.html +== 475986-1-ref.html 475986-1-ref.html +== 475986-1-ref.html 475986-1-ref.html == 475986-2-ref.html 475986-2-ref.html == 476063-1.html 476063-1.html fails == 476063-2.html 476063-2.html fails == 476063-3.html 476063-3.html == 476063-4.xhtml 476063-4.xhtml == 476357-1.html 476357-1.html -# == 476598-1a.html 476598-1a.html -# == 476598-1a.html 476598-1a.html -# == 476598-1b.html 476598-1b.html -# == 476598-1b.html 476598-1b.html +fails == 476598-1a.html 476598-1a.html # Bug 1341785 +fails == 476598-1a.html 476598-1a.html # Bug 1341785 +fails == 476598-1b.html 476598-1b.html # Bug 1341785 +fails == 476598-1b.html 476598-1b.html # Bug 1341785 == 476598-1-ref.html 476598-1-ref.html == 476856-1.html 476856-1.html random-if(d2d) == 478377-1.xul 478377-1.xul @@ -1313,7 +1313,7 @@ fails == 478811-4.html 478811-4.html == 480880-1e.html 480880-1e.html == 480880-2a.html 480880-2a.html == 480880-2b.html 480880-2b.html -# == 480880-2c.html 480880-2c.html +== 480880-2c.html 480880-2c.html fails-if(Android) == 481024-1a.html 481024-1a.html fails-if(Android) == 481024-1b.html 481024-1b.html fails-if(Android) == 481024-1c.html 481024-1c.html @@ -1353,7 +1353,7 @@ fails == 486065-1.html 486065-1.html == 489868-1.svg 489868-1.svg == 490173-1.html 490173-1.html fails == 490173-2.html 490173-2.html -# == 490176-1.html 490176-1.html +== 490176-1.html 490176-1.html == 490177-1.svg 490177-1.svg fails == 490182-1a.html 490182-1a.html fails == 490182-1b.html 490182-1b.html @@ -1377,7 +1377,7 @@ fails == 495354-1b.xhtml 495354-1b.xhtml == 495385-2a.html 495385-2a.html == 495385-2b.html 495385-2b.html == 495385-2c.html 495385-2c.html -# == 495385-2d.html 495385-2d.html +== 495385-2d.html 495385-2d.html == 495385-2e.html 495385-2e.html fails pref(dom.use_xbl_scopes_for_remote_xul,true) == 495385-2f.xhtml 495385-2f.xhtml == 495385-2g.html 495385-2g.html @@ -1475,7 +1475,7 @@ fails == 538909-1.html 538909-1.html == 539323-3.html 539323-3.html fails == 539880-1.html 539880-1.html fails == 539880-1-dynamic.html 539880-1-dynamic.html -# == 539949-1.html#test2 539949-1.html#test2 +skip-if(stylo) == 539949-1.html#test2 539949-1.html#test2 # load fails??? fails == 541382-1.html 541382-1.html == 541406-1.html 541406-1.html fails needs-focus == 542116-1.html 542116-1.html @@ -1483,7 +1483,7 @@ fails needs-focus == 542116-2.html 542116-2.html needs-focus == 542116-3.html 542116-3.html == 542317-1.html 542317-1.html == 542620-1.html 542620-1.html -# == 545049-1.html 545049-1.html +fails == 545049-1.html 545049-1.html # Bug 1341785 == 546033-1.html 546033-1.html == 546071-1.html 546071-1.html == 549184-1.html 549184-1.html @@ -1554,9 +1554,9 @@ fails needs-focus == 568441.html 568441.html == 571281-1b.html 571281-1b.html == 571281-1c.html 571281-1c.html == 571347-1a.html 571347-1a.html -# == 571347-1b.html 571347-1b.html -# == 571347-2a.html 571347-2a.html -# == 571347-2b.html 571347-2b.html +== 571347-1b.html 571347-1b.html +== 571347-2a.html 571347-2a.html +== 571347-2b.html 571347-2b.html fails == 571347-2c.html 571347-2c.html == 571347-2d.html 571347-2d.html fails == 571347-3.html 571347-3.html @@ -1600,7 +1600,7 @@ fails == 593544-1.html 593544-1.html == 594624-1.html 594624-1.html fails == 594737-1.html 594737-1.html fails == 597721-1.html 597721-1.html -# == 598726-1.html 598726-1.html +skip-if(stylo) == 598726-1.html 598726-1.html # Bug 1302946 == 599113-1.html 599113-1.html == 599476.html 599476.html == 599882-1a.html 599882-1a.html @@ -1625,15 +1625,15 @@ fails == 608636-1.html 608636-1.html == 608756-1b.html 608756-1b.html asserts-if(stylo,4) == 608756-2.html 608756-2.html # bug 1324633 == 609272-1.html 609272-1.html -# == 613433-1.html 613433-1.html -# == 613433-1.html 613433-1.html -# == 613433-1.html 613433-1.html -# == 613433-2.html 613433-2.html -# == 613433-2.html 613433-2.html -# == 613433-2.html 613433-2.html -# == 613433-3.html 613433-3.html -# == 613433-3.html 613433-3.html -# == 613433-3.html 613433-3.html +fails == 613433-1.html 613433-1.html +fails == 613433-1.html 613433-1.html +fails == 613433-1.html 613433-1.html +fails == 613433-2.html 613433-2.html +fails == 613433-2.html 613433-2.html +fails == 613433-2.html 613433-2.html +fails == 613433-3.html 613433-3.html +fails == 613433-3.html 613433-3.html +fails == 613433-3.html 613433-3.html == 614272-1.svg 614272-1.svg fails HTTP(..) == 615121-1.html 615121-1.html fails HTTP(..) == 615121-2.html 615121-2.html @@ -1654,10 +1654,10 @@ fails == 622585-1.html 622585-1.html == 631352-1.html 631352-1.html == 632423-1.html 632423-1.html skip-if(Android) random-if(winWidget||OSX==1010) == 632781-verybig.html 632781-verybig.html -# == 632781-normalsize.html 632781-normalsize.html +== 632781-normalsize.html 632781-normalsize.html == 633344-1.html 633344-1.html fails == 634232-1.html 634232-1.html -# == 635302-1.html 635302-1.html +skip-if(stylo) == 635302-1.html 635302-1.html # Too intermittent. == 635373-1.html 635373-1.html == 635373-2.html 635373-2.html == 635373-3.html 635373-3.html @@ -1813,8 +1813,8 @@ fails == 966510-1.html 966510-1.html fails == 966510-2.html 966510-2.html fuzzy-if(skiaContent,1,123) == 978911-1.svg 978911-1.svg == 983084-1.html 983084-1.html -# == 983084-2.html 983084-2.html -# == 983084-3.html 983084-3.html +skip-if(stylo) == 983084-2.html 983084-2.html # Bug 1302946 +skip-if(stylo) == 983084-3.html 983084-3.html # Bug 1302946 fails == 983691-1.html 983691-1.html HTTP(..) == 983985-1.html 983985-1.html fails HTTP(..) == 983985-2.html 983985-2.html @@ -1861,7 +1861,7 @@ test-pref(layout.testing.overlay-scrollbars.always-visible,false) == 1081072-1.h == 1103258-1.html 1103258-1.html == 1105137-1.html 1105137-1.html fails == 1116480-1-fakeitalic-overflow.html 1116480-1-fakeitalic-overflow.html -# == 1111753-1.html 1111753-1.html +skip-if(stylo) == 1111753-1.html 1111753-1.html # Bug 1302946 fails == 1114526-1.html 1114526-1.html fuzzy-if(skiaContent,1,800000) == 1119117-1a.html 1119117-1a.html fuzzy-if(skiaContent,1,800000) == 1119117-1b.html 1119117-1b.html @@ -1872,10 +1872,10 @@ skip == 1121748-2.html 1121748-2.html == 1127107-1a-nowrap.html 1127107-1a-nowrap.html == 1127107-1b-pre.html 1127107-1b-pre.html == 1127107-2-capitalize.html 1127107-2-capitalize.html -# == 1127679-1a-inline-flex-relpos.html 1127679-1a-inline-flex-relpos.html +== 1127679-1a-inline-flex-relpos.html 1127679-1a-inline-flex-relpos.html == 1128354-1.html 1128354-1.html -# == 1130231-1-button-padding-rtl.html 1130231-1-button-padding-rtl.html -# == 1130231-2-button-padding-rtl.html 1130231-2-button-padding-rtl.html +fails == 1130231-1-button-padding-rtl.html 1130231-1-button-padding-rtl.html +fails == 1130231-2-button-padding-rtl.html 1130231-2-button-padding-rtl.html # The 1133905-*.html reftests only make sense on platforms where both APZ and # are enabled. # (Note: bug 1308702 covers these tests' failures on Android) @@ -1903,33 +1903,33 @@ skip-if(!Android) fails-if(Android) == 1133905-3-vh.html 1133905-3-vh.html skip-if(!Android) == 1133905-4-vh.html 1133905-4-vh.html skip-if(!Android) fails-if(Android) == 1133905-5-vh.html 1133905-5-vh.html skip-if(!Android) fails-if(Android) == 1133905-6-vh.html 1133905-6-vh.html -# == 1133905-1-rtl.html 1133905-1-rtl.html -# == 1133905-2-rtl.html 1133905-2-rtl.html -# == 1133905-3-rtl.html 1133905-3-rtl.html -# == 1133905-4-rtl.html 1133905-4-rtl.html -# == 1133905-5-rtl.html 1133905-5-rtl.html -# == 1133905-6-rtl.html 1133905-6-rtl.html -# == 1133905-1-v-rtl.html 1133905-1-v-rtl.html -# == 1133905-2-v-rtl.html 1133905-2-v-rtl.html -# == 1133905-3-v-rtl.html 1133905-3-v-rtl.html -# == 1133905-4-v-rtl.html 1133905-4-v-rtl.html -# == 1133905-5-v-rtl.html 1133905-5-v-rtl.html -# == 1133905-6-v-rtl.html 1133905-6-v-rtl.html -# == 1133905-1-h-rtl.html 1133905-1-h-rtl.html -# == 1133905-2-h-rtl.html 1133905-2-h-rtl.html -# == 1133905-3-h-rtl.html 1133905-3-h-rtl.html -# == 1133905-4-h-rtl.html 1133905-4-h-rtl.html -# == 1133905-5-h-rtl.html 1133905-5-h-rtl.html -# == 1133905-6-h-rtl.html 1133905-6-h-rtl.html -# == 1133905-1-vh-rtl.html 1133905-1-vh-rtl.html -# == 1133905-2-vh-rtl.html 1133905-2-vh-rtl.html -# == 1133905-3-vh-rtl.html 1133905-3-vh-rtl.html -# == 1133905-4-vh-rtl.html 1133905-4-vh-rtl.html -# == 1133905-5-vh-rtl.html 1133905-5-vh-rtl.html -# == 1133905-6-vh-rtl.html 1133905-6-vh-rtl.html +== 1133905-1-rtl.html 1133905-1-rtl.html +== 1133905-2-rtl.html 1133905-2-rtl.html +== 1133905-3-rtl.html 1133905-3-rtl.html +== 1133905-4-rtl.html 1133905-4-rtl.html +== 1133905-5-rtl.html 1133905-5-rtl.html +== 1133905-6-rtl.html 1133905-6-rtl.html +fails == 1133905-1-v-rtl.html 1133905-1-v-rtl.html # Bug 1341095 +fails == 1133905-2-v-rtl.html 1133905-2-v-rtl.html # Bug 1341095 +fails == 1133905-3-v-rtl.html 1133905-3-v-rtl.html # Bug 1341095 +fails == 1133905-4-v-rtl.html 1133905-4-v-rtl.html # Bug 1341095 +fails == 1133905-5-v-rtl.html 1133905-5-v-rtl.html # Bug 1341095 +fails == 1133905-6-v-rtl.html 1133905-6-v-rtl.html # Bug 1341095 +== 1133905-1-h-rtl.html 1133905-1-h-rtl.html +== 1133905-2-h-rtl.html 1133905-2-h-rtl.html +== 1133905-3-h-rtl.html 1133905-3-h-rtl.html +== 1133905-4-h-rtl.html 1133905-4-h-rtl.html +== 1133905-5-h-rtl.html 1133905-5-h-rtl.html +== 1133905-6-h-rtl.html 1133905-6-h-rtl.html +fails == 1133905-1-vh-rtl.html 1133905-1-vh-rtl.html # Bug 1341095 +fails == 1133905-2-vh-rtl.html 1133905-2-vh-rtl.html # Bug 1341095 +fails == 1133905-3-vh-rtl.html 1133905-3-vh-rtl.html # Bug 1341095 +fails == 1133905-4-vh-rtl.html 1133905-4-vh-rtl.html # Bug 1341095 +fails == 1133905-5-vh-rtl.html 1133905-5-vh-rtl.html # Bug 1341095 +fails == 1133905-6-vh-rtl.html 1133905-6-vh-rtl.html # Bug 1341095 == 1150021-1.xul 1150021-1.xul fails == 1151145-1.html 1151145-1.html -# == 1151306-1.html 1151306-1.html +== 1151306-1.html 1151306-1.html == 1153845-1.html 1153845-1.html fails == 1155828-1.html 1155828-1.html == 1156129-1.html 1156129-1.html diff --git a/layout/reftests/canvas/reftest-stylo.list b/layout/reftests/canvas/reftest-stylo.list index eb08875612d7..254a08170899 100644 --- a/layout/reftests/canvas/reftest-stylo.list +++ b/layout/reftests/canvas/reftest-stylo.list @@ -1,5 +1,5 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing -# == default-size.html default-size.html +== default-size.html default-size.html fails == size-1.html size-1.html == empty-transaction-1.html empty-transaction-1.html @@ -31,8 +31,8 @@ fails asserts-if(stylo,1) == text-rtl-alignment-test.html text-rtl-alignment-tes asserts-if(stylo,1) == text-horzline-with-bottom.html text-horzline-with-bottom.html # bug 1324700 fails-if(azureSkia&&OSX>=1008) asserts-if(stylo,1) == text-horzline-with-top.html text-horzline-with-top.html # bug 1324700 -# == text-big-stroke.html text-big-stroke.html -# == text-big-stroke.html text-big-stroke.html +fails asserts-if(stylo,1) == text-big-stroke.html text-big-stroke.html # Bug 1324700 +fails asserts-if(stylo,1) == text-big-stroke.html text-big-stroke.html # Bug 1324700 fails asserts-if(stylo,1) == text-context-state-test.html text-context-state-test.html # bug 1324700 fails asserts-if(stylo,1) == text-font-inherit.html text-font-inherit.html # bug 1324700 @@ -42,8 +42,8 @@ fails asserts-if(stylo,1) == text-no-frame-test.html text-no-frame-test.html # b fails asserts-if(stylo,1) == text-no-frame-2-test.html text-no-frame-2-test.html # bug 1324700 fails asserts-if(stylo,1) == text-not-in-doc-test.html text-not-in-doc-test.html # bug 1324700 -# == text-bidi-ltr-test.html text-bidi-ltr-test.html -# == text-bidi-ltr-test.html text-bidi-ltr-test.html +fails asserts-if(stylo,1) == text-bidi-ltr-test.html text-bidi-ltr-test.html # Bug 1324700 +fails asserts-if(stylo,1) == text-bidi-ltr-test.html text-bidi-ltr-test.html # Bug 1324700 fails asserts-if(stylo,1) == text-bidi-rtl-test.html text-bidi-rtl-test.html # bug 1324700 fails asserts-if(stylo,4) == text-font-lang.html text-font-lang.html # bug 1324700 diff --git a/layout/reftests/columns/reftest-stylo.list b/layout/reftests/columns/reftest-stylo.list index ea8974a70b5c..c50e6b9f34a9 100644 --- a/layout/reftests/columns/reftest-stylo.list +++ b/layout/reftests/columns/reftest-stylo.list @@ -1,5 +1,5 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing -# == basic-1.html basic-1.html +== basic-1.html basic-1.html == pref-width-1a.html pref-width-1a.html == pref-width-1b.html pref-width-1b.html == pref-width-1c.html pref-width-1c.html @@ -18,7 +18,7 @@ fails == column-balancing-001.html column-balancing-001.html fails == column-balancing-002.html column-balancing-002.html fails == column-balancing-003.html column-balancing-003.html fails == column-balancing-004.html column-balancing-004.html -# == column-box-alignment-rtl.html column-box-alignment-rtl.html +== column-box-alignment-rtl.html column-box-alignment-rtl.html fails HTTP(..) == columnfill-balance.html columnfill-balance.html fails == columnfill-auto.html columnfill-auto.html fails HTTP(..) == columnfill-auto-2.html columnfill-auto-2.html @@ -26,7 +26,7 @@ fails HTTP(..) == columnfill-auto-3.html columnfill-auto-3.html fails == columnrule-basic.html columnrule-basic.html fails == columnrule-complex.html columnrule-complex.html == columnrule-linestyles.html columnrule-linestyles.html -# == columnrule-padding.html columnrule-padding.html +== columnrule-padding.html columnrule-padding.html fails == columnfill-overflow.html columnfill-overflow.html == margin-collapsing-bug616722-1.html margin-collapsing-bug616722-1.html == margin-collapsing-bug616722-2.html margin-collapsing-bug616722-2.html diff --git a/layout/reftests/counter-style/reftest-stylo.list b/layout/reftests/counter-style/reftest-stylo.list index c225c6ab8b20..b478b9b1d410 100644 --- a/layout/reftests/counter-style/reftest-stylo.list +++ b/layout/reftests/counter-style/reftest-stylo.list @@ -18,14 +18,14 @@ fails == descriptor-prefix.html descriptor-prefix.html fails == descriptor-suffix.html descriptor-suffix.html fails == descriptor-range.html descriptor-range.html fails == descriptor-pad.html descriptor-pad.html -# == descriptor-fallback.html descriptor-fallback.html +fails == descriptor-fallback.html descriptor-fallback.html # Bug 1328319 fails == descriptor-symbols.html descriptor-symbols.html fails == descriptor-negative-invalid.html descriptor-negative-invalid.html fails == descriptor-prefix-invalid.html descriptor-prefix-invalid.html fails == descriptor-suffix-invalid.html descriptor-suffix-invalid.html fails == descriptor-range-invalid.html descriptor-range-invalid.html fails == descriptor-pad-invalid.html descriptor-pad-invalid.html -# == descriptor-fallback.html descriptor-fallback.html +fails == descriptor-fallback.html descriptor-fallback.html fails == descriptor-symbols-invalid.html descriptor-symbols-invalid.html fails == name-case-sensitivity.html name-case-sensitivity.html fails == dependent-builtin.html dependent-builtin.html diff --git a/layout/reftests/css-animations/reftest-stylo.list b/layout/reftests/css-animations/reftest-stylo.list index b970b757fddc..55799ad3e362 100644 --- a/layout/reftests/css-animations/reftest-stylo.list +++ b/layout/reftests/css-animations/reftest-stylo.list @@ -1,34 +1,34 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing -# == screen-animations.html screen-animations.html -# == screen-animations.html screen-animations.html -# == print-no-animations.html print-no-animations.html -# == print-no-animations.html print-no-animations.html -# == animate-opacity.html animate-opacity.html +skip-if(stylo) == screen-animations.html screen-animations.html # Too intermittent. +skip-if(stylo) == screen-animations.html screen-animations.html # Too intermittent. +== print-no-animations.html print-no-animations.html +== print-no-animations.html print-no-animations.html +skip-if(stylo) == animate-opacity.html animate-opacity.html # Too intermittent. skip-if(stylo) == animate-preserves3d.html animate-preserves3d.html # bug 1324620 -# == in-visibility-hidden-animation.html in-visibility-hidden-animation.html -# == in-visibility-hidden-animation-pseudo-element.html in-visibility-hidden-animation-pseudo-element.html -# == partially-out-of-view-animation.html partially-out-of-view-animation.html -# == animate-display-table-opacity.html animate-display-table-opacity.html +== in-visibility-hidden-animation.html in-visibility-hidden-animation.html +fails == in-visibility-hidden-animation-pseudo-element.html in-visibility-hidden-animation-pseudo-element.html # Bug 1331047 +== partially-out-of-view-animation.html partially-out-of-view-animation.html +skip-if(stylo) == animate-display-table-opacity.html animate-display-table-opacity.html # Too intermittent. # We need to run 100% opacity test case when OMTA is disabled to check that the animation creates a stacking context even if the animation is not running on the compositor # test-pref(layers.offmainthreadcomposition.async-animations,false) == stacking-context-opacity-1-animation.html stacking-context-opacity-1-animation.html # We need to run transform:none test case when OMTA is disabled to check that the animation creates a stacking context even if the animation is not running on the compositor # test-pref(layers.offmainthreadcomposition.async-animations,false) == stacking-context-transform-none-animation.html stacking-context-transform-none-animation.html -# == no-stacking-context-opacity-removing-animation-in-delay.html no-stacking-context-opacity-removing-animation-in-delay.html -# == no-stacking-context-transform-removing-animation-in-delay.html no-stacking-context-transform-removing-animation-in-delay.html -# == stacking-context-lose-opacity-1.html stacking-context-lose-opacity-1.html +== no-stacking-context-opacity-removing-animation-in-delay.html no-stacking-context-opacity-removing-animation-in-delay.html +== no-stacking-context-transform-removing-animation-in-delay.html no-stacking-context-transform-removing-animation-in-delay.html +== stacking-context-lose-opacity-1.html stacking-context-lose-opacity-1.html == stacking-context-lose-transform-none.html stacking-context-lose-transform-none.html -# == stacking-context-opacity-win-in-delay.html stacking-context-opacity-win-in-delay.html +== stacking-context-opacity-win-in-delay.html stacking-context-opacity-win-in-delay.html == stacking-context-opacity-win-in-delay-on-main-thread.html stacking-context-opacity-win-in-delay-on-main-thread.html == stacking-context-opacity-wins-over-transition.html stacking-context-opacity-wins-over-transition.html == stacking-context-transform-win-in-delay.html stacking-context-transform-win-in-delay.html == stacking-context-transform-win-in-delay-on-main-thread.html stacking-context-transform-win-in-delay-on-main-thread.html == stacking-context-transform-wins-over-transition.html stacking-context-transform-wins-over-transition.html -# == stacking-context-opacity-1-animation.html stacking-context-opacity-1-animation.html +== stacking-context-opacity-1-animation.html stacking-context-opacity-1-animation.html == stacking-context-opacity-1-with-fill-backwards.html stacking-context-opacity-1-with-fill-backwards.html == stacking-context-opacity-1-with-fill-forwards.html stacking-context-opacity-1-with-fill-forwards.html == stacking-context-paused-on-opacity-1.html stacking-context-paused-on-opacity-1.html == stacking-context-paused-on-transform-none.html stacking-context-paused-on-transform-none.html -# == stacking-context-transform-none-animation.html stacking-context-transform-none-animation.html +== stacking-context-transform-none-animation.html stacking-context-transform-none-animation.html fails == stacking-context-transform-none-animation-on-svg.html stacking-context-transform-none-animation-on-svg.html == stacking-context-transform-none-animation-with-backface-visibility.html stacking-context-transform-none-animation-with-backface-visibility.html == stacking-context-transform-none-animation-with-preserve-3d.html stacking-context-transform-none-animation-with-preserve-3d.html @@ -39,6 +39,6 @@ fails == stacking-context-transform-none-animation-on-svg.html stacking-context- == stacking-context-transform-none-in-delay.html stacking-context-transform-none-in-delay.html == stacking-context-transform-removing-important-in-delay.html stacking-context-transform-removing-important-in-delay.html fails == background-position-in-delay.html background-position-in-delay.html -# == background-position-after-finish.html background-position-after-finish.html +== background-position-after-finish.html background-position-after-finish.html fails == background-position-running.html background-position-running.html fails == background-position-important.html background-position-important.html diff --git a/layout/reftests/css-break/reftest-stylo.list b/layout/reftests/css-break/reftest-stylo.list index 8c8048791129..a21d3222de4f 100644 --- a/layout/reftests/css-break/reftest-stylo.list +++ b/layout/reftests/css-break/reftest-stylo.list @@ -5,7 +5,7 @@ fails == box-decoration-break-1.html box-decoration-break-1.html fails == box-decoration-break-with-inset-box-shadow-1.html box-decoration-break-with-inset-box-shadow-1.html fails == box-decoration-break-with-outset-box-shadow-1.html box-decoration-break-with-outset-box-shadow-1.html fails == box-decoration-break-border-image.html box-decoration-break-border-image.html -# == box-decoration-break-block-border-padding.html box-decoration-break-block-border-padding.html +== box-decoration-break-block-border-padding.html box-decoration-break-block-border-padding.html == box-decoration-break-block-margin.html box-decoration-break-block-margin.html fails == box-decoration-break-first-letter.html box-decoration-break-first-letter.html == box-decoration-break-with-bidi.html box-decoration-break-with-bidi.html diff --git a/layout/reftests/css-calc/reftest-stylo.list b/layout/reftests/css-calc/reftest-stylo.list index a4e327e1b6dd..38ba1df4dfbc 100644 --- a/layout/reftests/css-calc/reftest-stylo.list +++ b/layout/reftests/css-calc/reftest-stylo.list @@ -1,3 +1,3 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing fails == background-image-gradient-1.html background-image-gradient-1.html -# == line-height-1.html line-height-1.html +fails == line-height-1.html line-height-1.html # Bug 1341095 diff --git a/layout/reftests/css-disabled/output/reftest-stylo.list b/layout/reftests/css-disabled/output/reftest-stylo.list index 5ffe49ac380f..68e7140dd57d 100644 --- a/layout/reftests/css-disabled/output/reftest-stylo.list +++ b/layout/reftests/css-disabled/output/reftest-stylo.list @@ -1,2 +1,2 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing -# == output.html output.html +== output.html output.html diff --git a/layout/reftests/css-display/reftest-stylo.list b/layout/reftests/css-display/reftest-stylo.list index 66ae381bc855..36c703fa2571 100644 --- a/layout/reftests/css-display/reftest-stylo.list +++ b/layout/reftests/css-display/reftest-stylo.list @@ -6,24 +6,24 @@ fails == display-contents-acid.html display-contents-acid.html # fuzzy-if(Android,8,604) == display-contents-acid-dyn-1.html display-contents-acid-dyn-1.html fails == display-contents-acid-dyn-2.html display-contents-acid-dyn-2.html # bug 1337700 fails == display-contents-acid-dyn-3.html display-contents-acid-dyn-3.html -# == display-contents-generated-content.html display-contents-generated-content.html -# == display-contents-generated-content-2.html display-contents-generated-content-2.html +skip-if(stylo) == display-contents-generated-content.html display-contents-generated-content.html # Bug 1341083 +skip-if(stylo) == display-contents-generated-content-2.html display-contents-generated-content-2.html # Bug 1341083 fails == display-contents-style-inheritance-1.html display-contents-style-inheritance-1.html fails == display-contents-style-inheritance-1-stylechange.html display-contents-style-inheritance-1-stylechange.html -# == display-contents-style-inheritance-1-dom-mutations.html display-contents-style-inheritance-1-dom-mutations.html +skip-if(stylo) == display-contents-style-inheritance-1-dom-mutations.html display-contents-style-inheritance-1-dom-mutations.html # Bug 1341083? == display-contents-tables.xhtml display-contents-tables.xhtml == display-contents-tables-2.xhtml display-contents-tables-2.xhtml == display-contents-tables-3.xhtml display-contents-tables-3.xhtml == display-contents-visibility-hidden.html display-contents-visibility-hidden.html == display-contents-visibility-hidden-2.html display-contents-visibility-hidden-2.html -# == display-contents-495385-2d.html display-contents-495385-2d.html +== display-contents-495385-2d.html display-contents-495385-2d.html fails == display-contents-xbl.xhtml display-contents-xbl.xhtml # fuzzy-if(Android,7,1186) pref(dom.webcomponents.enabled,true) == display-contents-shadow-dom-1.html display-contents-shadow-dom-1.html == display-contents-xbl-2.xul display-contents-xbl-2.xul asserts(2) == display-contents-xbl-3.xul display-contents-xbl-3.xul -# == display-contents-xbl-4.xul display-contents-xbl-4.xul -# == display-contents-fieldset.html display-contents-fieldset.html +skip-if(stylo) == display-contents-xbl-4.xul display-contents-xbl-4.xul # Too intermittent. +skip-if(stylo) == display-contents-fieldset.html display-contents-fieldset.html # Bug 1341083 asserts(2-10) == display-contents-xbl-5.xul display-contents-xbl-5.xul -# == display-contents-list-item-child.html display-contents-list-item-child.html # disabled for bug 1340607 +skip-if(stylo) == display-contents-list-item-child.html display-contents-list-item-child.html # disabled for bug 1340607 == display-contents-writing-mode-1.html display-contents-writing-mode-1.html fails == display-contents-writing-mode-2.html display-contents-writing-mode-2.html diff --git a/layout/reftests/css-enabled/output/reftest-stylo.list b/layout/reftests/css-enabled/output/reftest-stylo.list index 5ffe49ac380f..68e7140dd57d 100644 --- a/layout/reftests/css-enabled/output/reftest-stylo.list +++ b/layout/reftests/css-enabled/output/reftest-stylo.list @@ -1,2 +1,2 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing -# == output.html output.html +== output.html output.html diff --git a/layout/reftests/css-gradients/reftest-stylo.list b/layout/reftests/css-gradients/reftest-stylo.list index 216cca5c4d3c..4973cc6c7742 100644 --- a/layout/reftests/css-gradients/reftest-stylo.list +++ b/layout/reftests/css-gradients/reftest-stylo.list @@ -57,7 +57,7 @@ fails == linear-zero-length-1a.html linear-zero-length-1a.html fails == linear-zero-length-1b.html linear-zero-length-1b.html fails == linear-zero-length-1c.html linear-zero-length-1c.html == nostops.html nostops.html -# == onestop.html onestop.html +== onestop.html onestop.html fuzzy-if(!contentSameGfxBackendAsCanvas,1,5884) fuzzy-if(cocoaWidget,9,87824) fuzzy-if(azureSkiaGL,6,88024) random-if(d2d) fuzzy-if(skiaContent,4,6000) == radial-1a.html radial-1a.html fuzzy-if(!contentSameGfxBackendAsCanvas,1,5884) fuzzy-if(cocoaWidget,9,87824) fuzzy-if(azureSkiaGL,6,88024) random-if(d2d) fuzzy-if(skiaContent,4,6000) == radial-1b.html radial-1b.html fails == radial-1c.html radial-1c.html @@ -137,12 +137,12 @@ fails == height-dependence-1.html height-dependence-1.html fails == height-dependence-2.html height-dependence-2.html fails == height-dependence-3.html height-dependence-3.html -# == linear-onestopposition-1.html linear-onestopposition-1.html -# == linear-onestopposition-1.html linear-onestopposition-1.html +fails == linear-onestopposition-1.html linear-onestopposition-1.html +fails == linear-onestopposition-1.html linear-onestopposition-1.html == radial-onestopposition-1a.html radial-onestopposition-1a.html == radial-onestopposition-1b.html radial-onestopposition-1b.html fails == radial-onestopposition-1c.html radial-onestopposition-1c.html -# == repeating-linear-onestopposition-1.html repeating-linear-onestopposition-1.html +== repeating-linear-onestopposition-1.html repeating-linear-onestopposition-1.html == repeating-radial-onestopposition-1a.html repeating-radial-onestopposition-1a.html == repeating-radial-onestopposition-1b.html repeating-radial-onestopposition-1b.html fails == repeating-radial-onestopposition-1c.html repeating-radial-onestopposition-1c.html diff --git a/layout/reftests/css-grid/reftest-stylo.list b/layout/reftests/css-grid/reftest-stylo.list index e8d2070de23d..d379a9240316 100644 --- a/layout/reftests/css-grid/reftest-stylo.list +++ b/layout/reftests/css-grid/reftest-stylo.list @@ -100,8 +100,8 @@ fails == grid-item-intrinsic-ratio-stretch-004.html grid-item-intrinsic-ratio-st fails == grid-item-intrinsic-ratio-stretch-005.html grid-item-intrinsic-ratio-stretch-005.html fails == grid-item-intrinsic-ratio-stretch-006.html grid-item-intrinsic-ratio-stretch-006.html fails == grid-item-intrinsic-ratio-stretch-007.html grid-item-intrinsic-ratio-stretch-007.html -# == grid-item-intrinsic-ratio-normal-001.html grid-item-intrinsic-ratio-normal-001.html -# == grid-item-intrinsic-ratio-normal-002.html grid-item-intrinsic-ratio-normal-002.html +fails == grid-item-intrinsic-ratio-normal-001.html grid-item-intrinsic-ratio-normal-001.html +fails == grid-item-intrinsic-ratio-normal-002.html grid-item-intrinsic-ratio-normal-002.html fails == grid-item-intrinsic-ratio-normal-003.html grid-item-intrinsic-ratio-normal-003.html fails == grid-item-intrinsic-ratio-normal-004.html grid-item-intrinsic-ratio-normal-004.html fails == grid-item-intrinsic-ratio-normal-005.html grid-item-intrinsic-ratio-normal-005.html @@ -271,4 +271,4 @@ skip == grid-fragmentation-dyn2-030.html grid-fragmentation-dyn2-030.html skip == grid-fragmentation-dyn2-031.html grid-fragmentation-dyn2-031.html fails == bug1306106.html bug1306106.html fails == grid-percent-intrinsic-sizing-001.html grid-percent-intrinsic-sizing-001.html -# == grid-percent-intrinsic-sizing-002.html grid-percent-intrinsic-sizing-002.html +skip-if(stylo) == grid-percent-intrinsic-sizing-002.html grid-percent-intrinsic-sizing-002.html # Why does this fail to load? diff --git a/layout/reftests/css-invalid/default-style/reftest-stylo.list b/layout/reftests/css-invalid/default-style/reftest-stylo.list index 06fa289143c3..abe9ba3bd2ec 100644 --- a/layout/reftests/css-invalid/default-style/reftest-stylo.list +++ b/layout/reftests/css-invalid/default-style/reftest-stylo.list @@ -3,4 +3,4 @@ fails == input.html input.html fails == button.html button.html fails == textarea.html textarea.html fails == select.html select.html -# == fieldset.html fieldset.html +fails == fieldset.html fieldset.html # Bug 1340696 diff --git a/layout/reftests/css-invalid/input/reftest-stylo.list b/layout/reftests/css-invalid/input/reftest-stylo.list index b3cdd3fb2eaf..46c8e65f9f94 100644 --- a/layout/reftests/css-invalid/input/reftest-stylo.list +++ b/layout/reftests/css-invalid/input/reftest-stylo.list @@ -22,12 +22,12 @@ fails == input-type-invalid.html input-type-invalid.html fails == input-disabled-fieldset-1.html input-disabled-fieldset-1.html fails == input-disabled-fieldset-2.html input-disabled-fieldset-2.html fails == input-fieldset-legend.html input-fieldset-legend.html -# == input-radio-required.html input-radio-required.html -# == input-radio-customerror.html input-radio-customerror.html -# == input-radio-dyn-valid-1.html input-radio-dyn-valid-1.html -# == input-radio-dyn-valid-2.html input-radio-dyn-valid-2.html -# == input-radio-nogroup-required-valid.html input-radio-nogroup-required-valid.html -# == input-radio-nogroup-required-invalid.html input-radio-nogroup-required-invalid.html +fails == input-radio-required.html input-radio-required.html +fails == input-radio-customerror.html input-radio-customerror.html +== input-radio-dyn-valid-1.html input-radio-dyn-valid-1.html +== input-radio-dyn-valid-2.html input-radio-dyn-valid-2.html +fails == input-radio-nogroup-required-valid.html input-radio-nogroup-required-valid.html +== input-radio-nogroup-required-invalid.html input-radio-nogroup-required-invalid.html fails == input-radio-focus-click.html input-radio-focus-click.html fails == input-submit.html input-submit.html fails == input-image.html input-image.html diff --git a/layout/reftests/css-invalid/output/reftest-stylo.list b/layout/reftests/css-invalid/output/reftest-stylo.list index 6b7885a46794..be538070d119 100644 --- a/layout/reftests/css-invalid/output/reftest-stylo.list +++ b/layout/reftests/css-invalid/output/reftest-stylo.list @@ -1,3 +1,3 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing -# == output-valid.html output-valid.html -# == output-invalid.html output-invalid.html +== output-valid.html output-valid.html +fails == output-invalid.html output-invalid.html diff --git a/layout/reftests/css-placeholder/input/reftest-stylo.list b/layout/reftests/css-placeholder/input/reftest-stylo.list index 9b28a73b29bb..e754d694fdfa 100644 --- a/layout/reftests/css-placeholder/input/reftest-stylo.list +++ b/layout/reftests/css-placeholder/input/reftest-stylo.list @@ -9,7 +9,7 @@ # ::value (bug 648643), depending of the ::value behaviour (it could change the # caret colour and the text colour or just the text colour). -# == placeholder-simple.html placeholder-simple.html +fails == placeholder-simple.html placeholder-simple.html # needs-focus == placeholder-focus.html placeholder-focus.html fails needs-focus == placeholder-blur.html placeholder-blur.html fails == placeholder-value.html placeholder-value.html diff --git a/layout/reftests/css-placeholder/reftest-stylo.list b/layout/reftests/css-placeholder/reftest-stylo.list index 24c64249eae9..544e7b66385a 100644 --- a/layout/reftests/css-placeholder/reftest-stylo.list +++ b/layout/reftests/css-placeholder/reftest-stylo.list @@ -4,5 +4,5 @@ include textarea/reftest-stylo.list fails == css-restrictions.html css-restrictions.html fails == css-simple-styling.html css-simple-styling.html -# == css-background.html css-background.html +fails == css-background.html css-background.html fails == ignore-pseudo-class.html ignore-pseudo-class.html diff --git a/layout/reftests/css-placeholder/textarea/reftest-stylo.list b/layout/reftests/css-placeholder/textarea/reftest-stylo.list index 27716dac72ac..469ae6d0fca7 100644 --- a/layout/reftests/css-placeholder/textarea/reftest-stylo.list +++ b/layout/reftests/css-placeholder/textarea/reftest-stylo.list @@ -9,7 +9,7 @@ # ::value (bug 648643), depending of the ::value behaviour (it could change the # caret colour and the text colour or just the text colour). -# == placeholder-simple.html placeholder-simple.html +fails == placeholder-simple.html placeholder-simple.html # needs-focus == placeholder-focus.html placeholder-focus.html fails needs-focus == placeholder-blur.html placeholder-blur.html fails == placeholder-value.html placeholder-value.html @@ -20,7 +20,7 @@ fails == placeholder-value-set.html placeholder-value-set.html fails == placeholder-value-unset.html placeholder-value-unset.html fails == placeholder-value-reset.html placeholder-value-reset.html fails == placeholdershown.html placeholdershown.html -# == css-resize.html css-resize.html +fails == css-resize.html css-resize.html fails == css-display.html css-display.html # We can't check except by verifying that the output is different. # Same reasons as focus issues explained above. diff --git a/layout/reftests/css-ruby/reftest-stylo.list b/layout/reftests/css-ruby/reftest-stylo.list index dd8154f748ee..183e614ce304 100644 --- a/layout/reftests/css-ruby/reftest-stylo.list +++ b/layout/reftests/css-ruby/reftest-stylo.list @@ -13,9 +13,9 @@ fails == box-properties-4.html box-properties-4.html == dynamic-insertion-1.html dynamic-insertion-1.html == dynamic-insertion-2.html dynamic-insertion-2.html fails == dynamic-insertion-3.html dynamic-insertion-3.html -# == dynamic-removal-1.html dynamic-removal-1.html -# == dynamic-removal-2.html dynamic-removal-2.html -# == dynamic-removal-3.html dynamic-removal-3.html +== dynamic-removal-1.html dynamic-removal-1.html +== dynamic-removal-2.html dynamic-removal-2.html +== dynamic-removal-3.html dynamic-removal-3.html == float-handling.html float-handling.html fails test-pref(dom.meta-viewport.enabled,true) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == inflated-ruby-1.html inflated-ruby-1.html == intra-level-whitespace-1.html intra-level-whitespace-1.html @@ -28,12 +28,12 @@ fails == justification-2.html justification-2.html fails == lang-specific-style-1.html lang-specific-style-1.html == line-breaking-1.html line-breaking-1.html fails == line-breaking-2.html line-breaking-2.html -# == line-break-suppression-1.html line-break-suppression-1.html -# == line-break-suppression-2.html line-break-suppression-2.html -# == line-break-suppression-3.html line-break-suppression-3.html +skip-if(stylo) == line-break-suppression-1.html line-break-suppression-1.html +skip-if(stylo) == line-break-suppression-2.html line-break-suppression-2.html +skip-if(stylo) == line-break-suppression-3.html line-break-suppression-3.html == line-break-suppression-4.html line-break-suppression-4.html == line-break-suppression-5.html line-break-suppression-5.html -# == line-height-1.html line-height-1.html +skip-if(stylo) == line-height-1.html line-height-1.html == line-height-2.html line-height-2.html == line-height-3.html line-height-3.html == line-height-4.html line-height-4.html @@ -54,5 +54,5 @@ fails == ruby-position-vertical-rl.html ruby-position-vertical-rl.html == ruby-span-1.html ruby-span-1.html fails == ruby-whitespace-1.html ruby-whitespace-1.html == ruby-whitespace-2.html ruby-whitespace-2.html -# == bug1181890.html bug1181890.html -# == bug1181890.html bug1181890.html +skip-if(stylo) == bug1181890.html bug1181890.html +skip-if(stylo) == bug1181890.html bug1181890.html diff --git a/layout/reftests/css-sizing/reftest-stylo.list b/layout/reftests/css-sizing/reftest-stylo.list index d391457ac129..ea058ba0a917 100644 --- a/layout/reftests/css-sizing/reftest-stylo.list +++ b/layout/reftests/css-sizing/reftest-stylo.list @@ -1,5 +1,5 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing == min-intrinsic-with-percents-across-img-cases.html min-intrinsic-with-percents-across-img-cases.html fails == min-intrinsic-with-percents-across-elements.html min-intrinsic-with-percents-across-elements.html -# == min-intrinsic-with-max-width-percents-across-form-controls.html min-intrinsic-with-max-width-percents-across-form-controls.html -# == min-intrinsic-with-width-percents-across-form-controls.html min-intrinsic-with-width-percents-across-form-controls.html +skip-if(stylo) == min-intrinsic-with-max-width-percents-across-form-controls.html min-intrinsic-with-max-width-percents-across-form-controls.html # Bug 1341086, Bug 1341973 +skip-if(stylo) == min-intrinsic-with-width-percents-across-form-controls.html min-intrinsic-with-width-percents-across-form-controls.html # Bug 1341086 diff --git a/layout/reftests/css-submit-invalid/button-submit/reftest-stylo.list b/layout/reftests/css-submit-invalid/button-submit/reftest-stylo.list index eb3fb7bb6f2d..7d1fb9c5bb0c 100644 --- a/layout/reftests/css-submit-invalid/button-submit/reftest-stylo.list +++ b/layout/reftests/css-submit-invalid/button-submit/reftest-stylo.list @@ -13,5 +13,5 @@ fails == add-submit-control.html add-submit-control.html fails == remove-submit-control.html remove-submit-control.html fails == change-type-submit-control.html change-type-submit-control.html fails == change-type-not-submit-control.html change-type-not-submit-control.html -# == self-invalid.html self-invalid.html +== self-invalid.html self-invalid.html fails == remove-form.html remove-form.html diff --git a/layout/reftests/css-submit-invalid/input-image/reftest-stylo.list b/layout/reftests/css-submit-invalid/input-image/reftest-stylo.list index eb3fb7bb6f2d..7d1fb9c5bb0c 100644 --- a/layout/reftests/css-submit-invalid/input-image/reftest-stylo.list +++ b/layout/reftests/css-submit-invalid/input-image/reftest-stylo.list @@ -13,5 +13,5 @@ fails == add-submit-control.html add-submit-control.html fails == remove-submit-control.html remove-submit-control.html fails == change-type-submit-control.html change-type-submit-control.html fails == change-type-not-submit-control.html change-type-not-submit-control.html -# == self-invalid.html self-invalid.html +== self-invalid.html self-invalid.html fails == remove-form.html remove-form.html diff --git a/layout/reftests/css-submit-invalid/input-submit/reftest-stylo.list b/layout/reftests/css-submit-invalid/input-submit/reftest-stylo.list index eb3fb7bb6f2d..14770ba327f8 100644 --- a/layout/reftests/css-submit-invalid/input-submit/reftest-stylo.list +++ b/layout/reftests/css-submit-invalid/input-submit/reftest-stylo.list @@ -13,5 +13,5 @@ fails == add-submit-control.html add-submit-control.html fails == remove-submit-control.html remove-submit-control.html fails == change-type-submit-control.html change-type-submit-control.html fails == change-type-not-submit-control.html change-type-not-submit-control.html -# == self-invalid.html self-invalid.html +fails == self-invalid.html self-invalid.html fails == remove-form.html remove-form.html diff --git a/layout/reftests/css-transitions/reftest-stylo.list b/layout/reftests/css-transitions/reftest-stylo.list index 3beb4168812c..c9b0fafb188c 100644 --- a/layout/reftests/css-transitions/reftest-stylo.list +++ b/layout/reftests/css-transitions/reftest-stylo.list @@ -5,6 +5,6 @@ fails == transitions-inline-rewrap-1.html transitions-inline-rewrap-1.html == transitions-inline-rewrap-2.html transitions-inline-rewrap-2.html fails == stacking-context-opacity-lose-to-animation.html stacking-context-opacity-lose-to-animation.html fails == stacking-context-transform-lose-to-animation.html stacking-context-transform-lose-to-animation.html -# == stacking-context-opacity-wins-over-important-style.html stacking-context-opacity-wins-over-important-style.html -# == stacking-context-transform-wins-over-important-style.html stacking-context-transform-wins-over-important-style.html -# == transition-and-animation-with-different-durations.html transition-and-animation-with-different-durations.html +fails == stacking-context-opacity-wins-over-important-style.html stacking-context-opacity-wins-over-important-style.html # Bug 1302946? +fails == stacking-context-transform-wins-over-important-style.html stacking-context-transform-wins-over-important-style.html # Bug 1302946? +skip-if(stylo) == transition-and-animation-with-different-durations.html transition-and-animation-with-different-durations.html # Bug 1302946? diff --git a/layout/reftests/css-ui-invalid/default-style/reftest-stylo.list b/layout/reftests/css-ui-invalid/default-style/reftest-stylo.list index ed5b80f415e0..3a6015ef47df 100644 --- a/layout/reftests/css-ui-invalid/default-style/reftest-stylo.list +++ b/layout/reftests/css-ui-invalid/default-style/reftest-stylo.list @@ -3,8 +3,8 @@ fails == input.html input.html fails == button.html button.html fails == textarea.html textarea.html fails == select.html select.html -# == fieldset.html fieldset.html -# == output.html output.html +fails == fieldset.html fieldset.html # Bug 1340696 +fails == output.html output.html # Bug 1341739 fails == input-focus.html input-focus.html fails needs-focus == button-focus.html button-focus.html fails needs-focus == textarea-focus.html textarea-focus.html diff --git a/layout/reftests/css-ui-invalid/input/reftest-stylo.list b/layout/reftests/css-ui-invalid/input/reftest-stylo.list index fba61ec58d06..f80bbfcf1646 100644 --- a/layout/reftests/css-ui-invalid/input/reftest-stylo.list +++ b/layout/reftests/css-ui-invalid/input/reftest-stylo.list @@ -33,11 +33,11 @@ fails == input-fieldset-legend.html input-fieldset-legend.html == input-radio-required-invalid-default.html input-radio-required-invalid-default.html fails == input-file-required-invalid-changed.html input-file-required-invalid-changed.html fails == input-file-required-invalid-default.html input-file-required-invalid-default.html -# == input-radio-required.html input-radio-required.html -# == input-radio-customerror.html input-radio-customerror.html -# == input-radio-dyn-valid-1.html input-radio-dyn-valid-1.html -# == input-radio-dyn-valid-2.html input-radio-dyn-valid-2.html -# == input-radio-nogroup-required-valid.html input-radio-nogroup-required-valid.html -# == input-radio-nogroup-required-invalid.html input-radio-nogroup-required-invalid.html +== input-radio-required.html input-radio-required.html +== input-radio-customerror.html input-radio-customerror.html +== input-radio-dyn-valid-1.html input-radio-dyn-valid-1.html +== input-radio-dyn-valid-2.html input-radio-dyn-valid-2.html +== input-radio-nogroup-required-valid.html input-radio-nogroup-required-valid.html +== input-radio-nogroup-required-invalid.html input-radio-nogroup-required-invalid.html fails == input-novalidate.html input-novalidate.html # input type='hidden' shouldn't show diff --git a/layout/reftests/css-ui-invalid/output/reftest-stylo.list b/layout/reftests/css-ui-invalid/output/reftest-stylo.list index f546d9eec2ef..6f7b92aecbea 100644 --- a/layout/reftests/css-ui-invalid/output/reftest-stylo.list +++ b/layout/reftests/css-ui-invalid/output/reftest-stylo.list @@ -1,4 +1,4 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing -# == output-valid.html output-valid.html -# == output-invalid.html output-invalid.html +== output-valid.html output-valid.html +fails == output-invalid.html output-invalid.html # Bug 1341739 == output-novalidate.html output-novalidate.html diff --git a/layout/reftests/css-ui-valid/input/reftest-stylo.list b/layout/reftests/css-ui-valid/input/reftest-stylo.list index 9b1d5eb813ac..b7b0230c8eeb 100644 --- a/layout/reftests/css-ui-valid/input/reftest-stylo.list +++ b/layout/reftests/css-ui-valid/input/reftest-stylo.list @@ -32,11 +32,11 @@ fails == input-fieldset-legend.html input-fieldset-legend.html == input-checkbox-valid-default.html input-checkbox-valid-default.html fails == input-file-valid-changed.html input-file-valid-changed.html fails == input-file-valid-default.html input-file-valid-default.html -# == input-radio-required.html input-radio-required.html -# == input-radio-customerror.html input-radio-customerror.html -# == input-radio-dyn-valid-1.html input-radio-dyn-valid-1.html -# == input-radio-dyn-valid-2.html input-radio-dyn-valid-2.html -# == input-radio-nogroup-required-valid.html input-radio-nogroup-required-valid.html -# == input-radio-nogroup-required-invalid.html input-radio-nogroup-required-invalid.html +== input-radio-required.html input-radio-required.html +== input-radio-customerror.html input-radio-customerror.html +== input-radio-dyn-valid-1.html input-radio-dyn-valid-1.html +== input-radio-dyn-valid-2.html input-radio-dyn-valid-2.html +== input-radio-nogroup-required-valid.html input-radio-nogroup-required-valid.html +== input-radio-nogroup-required-invalid.html input-radio-nogroup-required-invalid.html fails == input-novalidate.html input-novalidate.html # input type='hidden' shouldn't show diff --git a/layout/reftests/css-ui-valid/output/reftest-stylo.list b/layout/reftests/css-ui-valid/output/reftest-stylo.list index f546d9eec2ef..c1226ea44168 100644 --- a/layout/reftests/css-ui-valid/output/reftest-stylo.list +++ b/layout/reftests/css-ui-valid/output/reftest-stylo.list @@ -1,4 +1,4 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing -# == output-valid.html output-valid.html -# == output-invalid.html output-invalid.html +fails == output-valid.html output-valid.html # Bug 1341739 +== output-invalid.html output-invalid.html == output-novalidate.html output-novalidate.html diff --git a/layout/reftests/css-valid/input/reftest-stylo.list b/layout/reftests/css-valid/input/reftest-stylo.list index 628c87622d1a..ab0b69a98c95 100644 --- a/layout/reftests/css-valid/input/reftest-stylo.list +++ b/layout/reftests/css-valid/input/reftest-stylo.list @@ -22,12 +22,12 @@ fails == input-type-invalid.html input-type-invalid.html fails == input-disabled-fieldset-1.html input-disabled-fieldset-1.html fails == input-disabled-fieldset-2.html input-disabled-fieldset-2.html fails == input-fieldset-legend.html input-fieldset-legend.html -# == input-radio-required.html input-radio-required.html -# == input-radio-customerror.html input-radio-customerror.html -# == input-radio-dyn-valid-1.html input-radio-dyn-valid-1.html -# == input-radio-dyn-valid-2.html input-radio-dyn-valid-2.html -# == input-radio-nogroup-required-valid.html input-radio-nogroup-required-valid.html -# == input-radio-nogroup-required-invalid.html input-radio-nogroup-required-invalid.html +== input-radio-required.html input-radio-required.html +== input-radio-customerror.html input-radio-customerror.html +== input-radio-dyn-valid-1.html input-radio-dyn-valid-1.html +== input-radio-dyn-valid-2.html input-radio-dyn-valid-2.html +== input-radio-nogroup-required-valid.html input-radio-nogroup-required-valid.html # Bug 1341739 +== input-radio-nogroup-required-invalid.html input-radio-nogroup-required-invalid.html fails == input-submit.html input-submit.html fails == input-image.html input-image.html # input type='hidden' shouldn't show diff --git a/layout/reftests/css-valid/output/reftest-stylo.list b/layout/reftests/css-valid/output/reftest-stylo.list index 6b7885a46794..bdfebdd28e62 100644 --- a/layout/reftests/css-valid/output/reftest-stylo.list +++ b/layout/reftests/css-valid/output/reftest-stylo.list @@ -1,3 +1,3 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing -# == output-valid.html output-valid.html -# == output-invalid.html output-invalid.html +fails == output-valid.html output-valid.html # Bug 341739 +== output-invalid.html output-invalid.html diff --git a/layout/reftests/css-valuesandunits/reftest-stylo.list b/layout/reftests/css-valuesandunits/reftest-stylo.list index e73973b67e19..19cfba577ac8 100644 --- a/layout/reftests/css-valuesandunits/reftest-stylo.list +++ b/layout/reftests/css-valuesandunits/reftest-stylo.list @@ -1,16 +1,16 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing -# == unit-rem-div-fontsize.html unit-rem-div-fontsize.html +== unit-rem-div-fontsize.html unit-rem-div-fontsize.html == unit-rem-div-width-inner.html unit-rem-div-width-inner.html == unit-rem-div-width-outer.html unit-rem-div-width-outer.html == unit-rem-iframe.html unit-rem-iframe.html -# == unit-rem-root-fontsize.html unit-rem-root-fontsize.html -# == unit-rem-root-fontsize.html unit-rem-root-fontsize.html +== unit-rem-root-fontsize.html unit-rem-root-fontsize.html +== unit-rem-root-fontsize.html unit-rem-root-fontsize.html fails == unit-rem-root-width.html unit-rem-root-width.html == unit-rem.svg unit-rem.svg fails == unit-vh-vw.html unit-vh-vw.html fails == unit-vh-vw-zoom.html unit-vh-vw-zoom.html -# == unit-vh-vw-overflow-auto.html unit-vh-vw-overflow-auto.html +fails == unit-vh-vw-overflow-auto.html unit-vh-vw-overflow-auto.html fails == unit-vh-vw-overflow-scroll.html unit-vh-vw-overflow-scroll.html fails == unit-vh-vw-overflow-scroll-x.html unit-vh-vw-overflow-scroll-x.html fails == unit-vh-vw-overflow-scroll-y.html unit-vh-vw-overflow-scroll-y.html -# == unit-vh-vw-overflow-auto.html unit-vh-vw-overflow-auto.html +fails == unit-vh-vw-overflow-auto.html unit-vh-vw-overflow-auto.html diff --git a/layout/reftests/cssom/reftest-stylo.list b/layout/reftests/cssom/reftest-stylo.list index 3cd8c8e5b339..efc8ab6b78fe 100644 --- a/layout/reftests/cssom/reftest-stylo.list +++ b/layout/reftests/cssom/reftest-stylo.list @@ -1,3 +1,3 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing -# == computed-style-cross-window.html computed-style-cross-window.html -# == inline-style-null.html inline-style-null.html +== computed-style-cross-window.html computed-style-cross-window.html +== inline-style-null.html inline-style-null.html diff --git a/layout/reftests/datalist/reftest-stylo.list b/layout/reftests/datalist/reftest-stylo.list index d94da2ca1a54..fab81b72144e 100644 --- a/layout/reftests/datalist/reftest-stylo.list +++ b/layout/reftests/datalist/reftest-stylo.list @@ -1,3 +1,3 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing -# == datalist-simple.html datalist-simple.html +== datalist-simple.html datalist-simple.html == datalist-errors.html datalist-errors.html diff --git a/layout/reftests/details-summary/reftest-stylo.list b/layout/reftests/details-summary/reftest-stylo.list index 9f60fb3230f7..a8b2a5cd906e 100644 --- a/layout/reftests/details-summary/reftest-stylo.list +++ b/layout/reftests/details-summary/reftest-stylo.list @@ -4,9 +4,9 @@ fails == multiple-summary.html multiple-summary.html fails == open-multiple-summary.html open-multiple-summary.html fails == summary-not-first-child.html summary-not-first-child.html fails == open-summary-not-first-child.html open-summary-not-first-child.html -# == open-summary-block-style.html open-summary-block-style.html -# == open-summary-inline-style.html open-summary-inline-style.html -# == open-summary-table-cell-style.html open-summary-table-cell-style.html +== open-summary-block-style.html open-summary-block-style.html +== open-summary-inline-style.html open-summary-inline-style.html +== open-summary-table-cell-style.html open-summary-table-cell-style.html fails == no-summary.html no-summary.html fails == open-no-summary.html open-no-summary.html == summary-not-in-details.html summary-not-in-details.html diff --git a/layout/reftests/dom/reftest-stylo.list b/layout/reftests/dom/reftest-stylo.list index 2cb924d7d8e2..97206d09f09a 100644 --- a/layout/reftests/dom/reftest-stylo.list +++ b/layout/reftests/dom/reftest-stylo.list @@ -5,13 +5,13 @@ == appendsingle.html appendsingle.html # append several elements -# == appendmultiple.html appendmultiple.html +== appendmultiple.html appendmultiple.html # insert a single element == insertsingle.html insertsingle.html # insert several elements -# == insertmultiple.html insertmultiple.html +== insertmultiple.html insertmultiple.html # insert multiple nodes to a parent and one of its children == inserttoparentandchild-1.html inserttoparentandchild-1.html @@ -27,9 +27,9 @@ # multiple range inserts == insertmultiplemultiple-1.html insertmultiplemultiple-1.html # a range insert and an append -# == insertmultiplemultiple-2.html insertmultiplemultiple-2.html +== insertmultiplemultiple-2.html insertmultiplemultiple-2.html # multiple range inserts and an append -# == insertmultiplemultiple-2.html insertmultiplemultiple-2.html +== insertmultiplemultiple-2.html insertmultiplemultiple-2.html # testing bindings that have multiple insertion points fails == multipleinsertionpoints-ref2.xhtml multipleinsertionpoints-ref2.xhtml diff --git a/layout/reftests/first-letter/reftest-stylo.list b/layout/reftests/first-letter/reftest-stylo.list index 02383d6065f6..2e6d808705db 100644 --- a/layout/reftests/first-letter/reftest-stylo.list +++ b/layout/reftests/first-letter/reftest-stylo.list @@ -1,6 +1,6 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing # basic functionality -# == basic-1.html basic-1.html +== basic-1.html basic-1.html == basic-2.html basic-2.html # parent style context correct @@ -34,7 +34,7 @@ fails == dynamic-1.html dynamic-1.html == 23605-5.html 23605-5.html == 23605-6.html 23605-6.html == 229764-1.html 229764-1.html -# == 229764-2.html 229764-2.html +fails == 229764-2.html 229764-2.html # Bug 1324618 == 329069-1.html 329069-1.html == 329069-2.html 329069-2.html == 329069-3.html 329069-3.html @@ -71,5 +71,5 @@ fails HTTP(..) == indic-clusters-1.html indic-clusters-1.html == overflow-float-nooverflow.html overflow-float-nooverflow.html == overflow-float-overflow.html overflow-float-overflow.html == overflow-inline-nooverflow.html overflow-inline-nooverflow.html -# == overflow-inline-overflow.html overflow-inline-overflow.html -# == overflow-inline-overflow.html overflow-inline-overflow.html +fails == overflow-inline-overflow.html overflow-inline-overflow.html # Bug 1321769? +fails == overflow-inline-overflow.html overflow-inline-overflow.html # Bug 1321769? diff --git a/layout/reftests/first-line/reftest-stylo.list b/layout/reftests/first-line/reftest-stylo.list index 1d2c4de4e83e..7542ff6964e2 100644 --- a/layout/reftests/first-line/reftest-stylo.list +++ b/layout/reftests/first-line/reftest-stylo.list @@ -1,6 +1,6 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing # basic functionality -# == basic-1.html basic-1.html +fails == basic-1.html basic-1.html # Bug 1324619 # handling of out-of-flows when ::first-line happens == out-of-flow-1a.html out-of-flow-1a.html diff --git a/layout/reftests/flexbox/reftest-stylo.list b/layout/reftests/flexbox/reftest-stylo.list index 4302b8715edf..1608dcc57abc 100644 --- a/layout/reftests/flexbox/reftest-stylo.list +++ b/layout/reftests/flexbox/reftest-stylo.list @@ -77,10 +77,10 @@ fails == flexbox-position-absolute-1.xhtml flexbox-position-absolute-1.xhtml fails == flexbox-position-absolute-2.xhtml flexbox-position-absolute-2.xhtml fails == flexbox-position-absolute-3.xhtml flexbox-position-absolute-3.xhtml == flexbox-position-absolute-4.xhtml flexbox-position-absolute-4.xhtml -# == flexbox-position-fixed-3.xhtml flexbox-position-fixed-3.xhtml +fails == flexbox-position-fixed-3.xhtml flexbox-position-fixed-3.xhtml fails == flexbox-position-fixed-1.xhtml flexbox-position-fixed-1.xhtml fails == flexbox-position-fixed-2.xhtml flexbox-position-fixed-2.xhtml -# == flexbox-position-fixed-3.xhtml flexbox-position-fixed-3.xhtml +fails == flexbox-position-fixed-3.xhtml flexbox-position-fixed-3.xhtml == flexbox-position-fixed-4.xhtml flexbox-position-fixed-4.xhtml # Tests for inline content in a flexbox that gets wrapped in an anonymous block diff --git a/layout/reftests/font-face/reftest-stylo.list b/layout/reftests/font-face/reftest-stylo.list index a7983a5b4227..ef50bf5aff21 100644 --- a/layout/reftests/font-face/reftest-stylo.list +++ b/layout/reftests/font-face/reftest-stylo.list @@ -26,14 +26,14 @@ fails HTTP(..) == src-list-format-4.html src-list-format-4.html fails HTTP(..) == src-list-format-5.html src-list-format-5.html fails HTTP(..) == src-list-format-6.html src-list-format-6.html # assumes AAT fonts are only supported on MacOS -# == src-list-format-7.html src-list-format-7.html -# == src-list-format-7.html src-list-format-7.html +fails == src-list-format-7.html src-list-format-7.html +fails == src-list-format-7.html src-list-format-7.html fails == src-list-local-full.html src-list-local-full.html fails == src-list-local-full-quotes.html src-list-local-full-quotes.html fails HTTP(..) == src-list-local-fallback.html src-list-local-fallback.html # data url tests (these don't need the HTTP server) -# == src-list-data-1.html src-list-data-1.html +fails == src-list-data-1.html src-list-data-1.html fails == src-list-data-2.html src-list-data-2.html fails == src-list-data-3.html src-list-data-3.html fails == src-list-data-4.html src-list-data-4.html @@ -83,7 +83,7 @@ fails HTTP(..) == unicoderange-4.html unicoderange-4.html # HTTP(..) == disable-sheet-4.html disable-sheet-4.html # HTTP(..) == disable-sheet-5.html disable-sheet-5.html fails HTTP(..) == sheet-set-base-1.html sheet-set-base-1.html -# == sheet-set-switch-1.html sheet-set-switch-1.html +skip-if(stylo) == sheet-set-switch-1.html sheet-set-switch-1.html # times out? # HTTP(..) == insert-rule-1a.html insert-rule-1a.html # HTTP(..) == insert-rule-1b.html insert-rule-1b.html # HTTP(..) == delete-rule-1.html delete-rule-1.html @@ -158,9 +158,9 @@ HTTP(..) == font-error-404-1.html font-error-404-1.html fails HTTP(..) == font-redirect.html font-redirect.html # Tests for potential regressions from bug 879963 -# == dynamic-duplicate-rule-1a.html dynamic-duplicate-rule-1a.html -# == dynamic-duplicate-rule-1b.html dynamic-duplicate-rule-1b.html -# == dynamic-duplicate-rule-1c.html dynamic-duplicate-rule-1c.html +== dynamic-duplicate-rule-1a.html dynamic-duplicate-rule-1a.html +== dynamic-duplicate-rule-1b.html dynamic-duplicate-rule-1b.html +== dynamic-duplicate-rule-1c.html dynamic-duplicate-rule-1c.html # Test for COLR and CPAL support fails HTTP(..) == color-1a.html color-1a.html diff --git a/layout/reftests/font-matching/reftest-stylo.list b/layout/reftests/font-matching/reftest-stylo.list index 7a84104a6886..a703ae49b6d7 100644 --- a/layout/reftests/font-matching/reftest-stylo.list +++ b/layout/reftests/font-matching/reftest-stylo.list @@ -9,32 +9,32 @@ fails == synthetic-bold-2.html synthetic-bold-2.html == defaultfont-bold.html defaultfont-bold.html == defaultfont-italic.html defaultfont-italic.html == defaultfont-oblique.html defaultfont-oblique.html -# == defaultfont-bolditalic.html defaultfont-bolditalic.html -# == defaultfont-bolditalic.html defaultfont-bolditalic.html +== defaultfont-bolditalic.html defaultfont-bolditalic.html +== defaultfont-bolditalic.html defaultfont-bolditalic.html == defaultjapanese-bold.html defaultjapanese-bold.html == defaultjapanese-italic.html defaultjapanese-italic.html == defaultjapanese-oblique.html defaultjapanese-oblique.html -# == defaultjapanese-bolditalic.html defaultjapanese-bolditalic.html -# == defaultjapanese-bolditalic.html defaultjapanese-bolditalic.html +== defaultjapanese-bolditalic.html defaultjapanese-bolditalic.html +== defaultjapanese-bolditalic.html defaultjapanese-bolditalic.html == impact-bold.html impact-bold.html == impact-italic.html impact-italic.html == impact-oblique.html impact-oblique.html -# == impact-bolditalic.html impact-bolditalic.html -# == impact-bolditalic.html impact-bolditalic.html +== impact-bolditalic.html impact-bolditalic.html +== impact-bolditalic.html impact-bolditalic.html == arialunicode-bold.html arialunicode-bold.html == arialunicode-italic.html arialunicode-italic.html == arialunicode-oblique.html arialunicode-oblique.html -# == arialunicode-bolditalic.html arialunicode-bolditalic.html -# == arialunicode-bolditalic.html arialunicode-bolditalic.html +== arialunicode-bolditalic.html arialunicode-bolditalic.html +== arialunicode-bolditalic.html arialunicode-bolditalic.html == lucidaconsole-bold.html lucidaconsole-bold.html == lucidaconsole-italic.html lucidaconsole-italic.html == lucidaconsole-oblique.html lucidaconsole-oblique.html -# == lucidaconsole-bolditalic.html lucidaconsole-bolditalic.html -# == lucidaconsole-bolditalic.html lucidaconsole-bolditalic.html +== lucidaconsole-bolditalic.html lucidaconsole-bolditalic.html +== lucidaconsole-bolditalic.html lucidaconsole-bolditalic.html # checking that we don't match fullnames, psnames (see bug 538103) == arial-variations-1.html arial-variations-1.html diff --git a/layout/reftests/forms/button/reftest-stylo.list b/layout/reftests/forms/button/reftest-stylo.list index 96e0e00bfbac..df080e46a4c9 100644 --- a/layout/reftests/forms/button/reftest-stylo.list +++ b/layout/reftests/forms/button/reftest-stylo.list @@ -1,8 +1,8 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing -# == first-letter-1.html first-letter-1.html -# == first-letter-1.html first-letter-1.html +fails == first-letter-1.html first-letter-1.html # Bug 1341086 +fails == first-letter-1.html first-letter-1.html # Bug 1341086 -# == max-height.html max-height.html +fails == max-height.html max-height.html # Bug 1341086 fails == min-height.html min-height.html # Android is off ever-so-slightly on the points where the text @@ -15,7 +15,7 @@ fails == overflow-areas-1.html overflow-areas-1.html fuzzy-if(Android,125,20) == percent-height-child.html percent-height-child.html fuzzy-if(Android,125,20) == percent-width-child.html percent-width-child.html -# == vertical-centering.html vertical-centering.html +== vertical-centering.html vertical-centering.html fails == line-height-button-0.5.html line-height-button-0.5.html fails == line-height-button-1.5.html line-height-button-1.5.html @@ -32,11 +32,11 @@ fails == disabled-4.html disabled-4.html fails == disabled-5.html disabled-5.html fails == disabled-6.html disabled-6.html -# == width-auto-size-em-ltr.html width-auto-size-em-ltr.html -# == width-auto-size-ltr.html width-auto-size-ltr.html -# == width-exact-fit-ltr.html width-exact-fit-ltr.html -# == width-auto-size-em-rtl.html width-auto-size-em-rtl.html -# == width-auto-size-rtl.html width-auto-size-rtl.html -# == width-exact-fit-rtl.html width-exact-fit-rtl.html +== width-auto-size-em-ltr.html width-auto-size-em-ltr.html +== width-auto-size-ltr.html width-auto-size-ltr.html +fails == width-exact-fit-ltr.html width-exact-fit-ltr.html # Bug 1341086 +== width-auto-size-em-rtl.html width-auto-size-em-rtl.html +== width-auto-size-rtl.html width-auto-size-rtl.html +fails == width-exact-fit-rtl.html width-exact-fit-rtl.html # Bug 1341086 fails == display-grid-flex-columnset.html display-grid-flex-columnset.html == 1317351.html 1317351.html diff --git a/layout/reftests/forms/fieldset/reftest-stylo.list b/layout/reftests/forms/fieldset/reftest-stylo.list index 8228d7e60f38..3b8bd345f490 100644 --- a/layout/reftests/forms/fieldset/reftest-stylo.list +++ b/layout/reftests/forms/fieldset/reftest-stylo.list @@ -14,14 +14,14 @@ fails == relpos-legend-4.html relpos-legend-4.html fails == sticky-legend-1.html sticky-legend-1.html fuzzy-if(skiaContent,1,40768) == abs-pos-child-sizing.html abs-pos-child-sizing.html fails == overflow-hidden.html overflow-hidden.html -# == legend-rtl.html legend-rtl.html +fails == legend-rtl.html legend-rtl.html # Bug 1340696 fails == fieldset-grid-001.html fieldset-grid-001.html fails == fieldset-flexbox-001.html fieldset-flexbox-001.html fails == fieldset-min-width-1a.html fieldset-min-width-1a.html fails == fieldset-min-width-1b.html fieldset-min-width-1b.html fails == fieldset-min-width-2a.html fieldset-min-width-2a.html fails == fieldset-min-width-2b.html fieldset-min-width-2b.html -# == legend-overlapping-right-border-1.html legend-overlapping-right-border-1.html +fails == legend-overlapping-right-border-1.html legend-overlapping-right-border-1.html # Bug 1340696 fails == fieldset-border-image-1a.html fieldset-border-image-1a.html fails == fieldset-border-image-1b.html fieldset-border-image-1b.html fails == fieldset-border-image-2a.html fieldset-border-image-2a.html diff --git a/layout/reftests/forms/input/checkbox/reftest-stylo.list b/layout/reftests/forms/input/checkbox/reftest-stylo.list index 4fc7027374d9..7590d49b0297 100644 --- a/layout/reftests/forms/input/checkbox/reftest-stylo.list +++ b/layout/reftests/forms/input/checkbox/reftest-stylo.list @@ -1,15 +1,12 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing == label-dynamic.html label-dynamic.html fails-if(Android) == radio-stretched.html radio-stretched.html -# == checked.html checked.html == checked-native.html checked-native.html -# == checked.html checked.html -# == checked-notref.html checked-notref.html == checked-native.html checked-native.html == checked-native-notref.html checked-native-notref.html -# == indeterminate-checked.html indeterminate-checked.html -# == indeterminate-unchecked.html indeterminate-unchecked.html -# == indeterminate-native-checked.html indeterminate-native-checked.html -# == indeterminate-native-unchecked.html indeterminate-native-unchecked.html +== indeterminate-checked.html indeterminate-checked.html +== indeterminate-unchecked.html indeterminate-unchecked.html +== indeterminate-native-checked.html indeterminate-native-checked.html +== indeterminate-native-unchecked.html indeterminate-native-unchecked.html == indeterminate-selector.html indeterminate-selector.html skip-if(!gtkWidget) == gtk-theme-width-height.html gtk-theme-width-height.html diff --git a/layout/reftests/forms/input/datetime/reftest-stylo.list b/layout/reftests/forms/input/datetime/reftest-stylo.list index 623423cdbe50..cc2694a38be6 100644 --- a/layout/reftests/forms/input/datetime/reftest-stylo.list +++ b/layout/reftests/forms/input/datetime/reftest-stylo.list @@ -2,13 +2,13 @@ default-preferences pref(dom.forms.datetime,true) # not valid on Android where type=time looks like type=text -# == time-simple-unthemed.html time-simple-unthemed.html -# == time-large-font.html time-large-font.html -# == time-width-height.html time-width-height.html -# == time-border.html time-border.html +fails == time-simple-unthemed.html time-simple-unthemed.html # Bug 1340696 +fails == time-large-font.html time-large-font.html # Bug 1340696 +fails == time-width-height.html time-width-height.html # Bug 1340696 +fails == time-border.html time-border.html # Bug 1340696 # only valid on Android where type=number looks the same as type=text -# == time-simple-unthemed.html time-simple-unthemed.html +fails == time-simple-unthemed.html time-simple-unthemed.html # Bug 1340696 # type change -# == to-time-from-other-type-unthemed.html to-time-from-other-type-unthemed.html -# == from-time-to-other-type-unthemed.html from-time-to-other-type-unthemed.html +fails == to-time-from-other-type-unthemed.html to-time-from-other-type-unthemed.html # Bug 1340696 +== from-time-to-other-type-unthemed.html from-time-to-other-type-unthemed.html diff --git a/layout/reftests/forms/input/file/reftest-stylo.list b/layout/reftests/forms/input/file/reftest-stylo.list index 6383e6506e93..a08fab114996 100644 --- a/layout/reftests/forms/input/file/reftest-stylo.list +++ b/layout/reftests/forms/input/file/reftest-stylo.list @@ -1,8 +1,8 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing -# == simple.html simple.html -# == rtl.html rtl.html -# == size.html size.html -# == background.html background.html -# == style.html style.html +fails == simple.html simple.html # Bug 1341086 +fails == rtl.html rtl.html # Bug 1341086 +fails == size.html size.html # Bug 1341086 +fails == background.html background.html # Bug 1341086 +fails == style.html style.html # Bug 1341086 fails == width-clip.html width-clip.html -# == color-inherit.html color-inherit.html +fails == color-inherit.html color-inherit.html # Bug 1341086 diff --git a/layout/reftests/forms/input/number/reftest-stylo.list b/layout/reftests/forms/input/number/reftest-stylo.list index ac29a5fb90e4..bc9444bc6ebb 100644 --- a/layout/reftests/forms/input/number/reftest-stylo.list +++ b/layout/reftests/forms/input/number/reftest-stylo.list @@ -9,23 +9,23 @@ default-preferences pref(dom.forms.number,true) skip-if(!Android) == number-same-as-text-unthemed.html number-same-as-text-unthemed.html # should look the same as type=text, except for the spin box -# == number-similar-to-text-unthemed.html number-similar-to-text-unthemed.html -# == number-similar-to-text-unthemed-rtl.html number-similar-to-text-unthemed-rtl.html -# == number-similar-to-text-unthemed-vertical-lr.html number-similar-to-text-unthemed-vertical-lr.html -# == number-similar-to-text-unthemed-vertical-rl.html number-similar-to-text-unthemed-vertical-rl.html +== number-similar-to-text-unthemed.html number-similar-to-text-unthemed.html +== number-similar-to-text-unthemed-rtl.html number-similar-to-text-unthemed-rtl.html +== number-similar-to-text-unthemed-vertical-lr.html number-similar-to-text-unthemed-vertical-lr.html +== number-similar-to-text-unthemed-vertical-rl.html number-similar-to-text-unthemed-vertical-rl.html # dynamic type changes: fails == to-number-from-other-type-unthemed-1.html to-number-from-other-type-unthemed-1.html -# == from-number-to-other-type-unthemed-1.html from-number-to-other-type-unthemed-1.html +== from-number-to-other-type-unthemed-1.html from-number-to-other-type-unthemed-1.html # dynamic value changes: # fuzzy-if(skiaContent,2,13) == show-value.html show-value.html # disabled -# == number-disabled.html number-disabled.html +== number-disabled.html number-disabled.html # auto width: -# == number-auto-width-1.html number-auto-width-1.html +== number-auto-width-1.html number-auto-width-1.html # min-height/max-height tests: fails == number-min-height-1.html number-min-height-1.html diff --git a/layout/reftests/forms/input/percentage/reftest-stylo.list b/layout/reftests/forms/input/percentage/reftest-stylo.list index 42c91a3f8e94..d6a97260565b 100644 --- a/layout/reftests/forms/input/percentage/reftest-stylo.list +++ b/layout/reftests/forms/input/percentage/reftest-stylo.list @@ -1,2 +1,2 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing -# == padding.html padding.html +fails == padding.html padding.html # Bug 1340696 diff --git a/layout/reftests/forms/input/radio/reftest-stylo.list b/layout/reftests/forms/input/radio/reftest-stylo.list index 9d400c092997..49132400ee00 100644 --- a/layout/reftests/forms/input/radio/reftest-stylo.list +++ b/layout/reftests/forms/input/radio/reftest-stylo.list @@ -1,9 +1,6 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing == label-dynamic.html label-dynamic.html -# == checked.html checked.html == checked-native.html checked-native.html -# == checked.html checked.html -# == checked-notref.html checked-notref.html == checked-native.html checked-native.html == checked-native-notref.html checked-native-notref.html skip-if(!gtkWidget) == gtk-theme-width-height.html gtk-theme-width-height.html diff --git a/layout/reftests/forms/input/range/reftest-stylo.list b/layout/reftests/forms/input/range/reftest-stylo.list index c6d217495484..d08e16f827ce 100644 --- a/layout/reftests/forms/input/range/reftest-stylo.list +++ b/layout/reftests/forms/input/range/reftest-stylo.list @@ -1,9 +1,9 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing # sanity checks: -# == not-other-type-unthemed-1.html not-other-type-unthemed-1.html -# == not-other-type-unthemed-1.html not-other-type-unthemed-1.html -# == not-other-type-unthemed-1.html not-other-type-unthemed-1.html +== not-other-type-unthemed-1.html not-other-type-unthemed-1.html +== not-other-type-unthemed-1.html not-other-type-unthemed-1.html +== not-other-type-unthemed-1.html not-other-type-unthemed-1.html # dynamic type changes: fails == to-range-from-other-type-unthemed-1.html to-range-from-other-type-unthemed-1.html diff --git a/layout/reftests/forms/input/text/reftest-stylo.list b/layout/reftests/forms/input/text/reftest-stylo.list index 195706dedd43..0227a3a913a4 100644 --- a/layout/reftests/forms/input/text/reftest-stylo.list +++ b/layout/reftests/forms/input/text/reftest-stylo.list @@ -1,11 +1,11 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing -# == bounds-1.html bounds-1.html +== bounds-1.html bounds-1.html fails == size-1.html size-1.html fails == size-2.html size-2.html fails HTTP(..) == baseline-1.html baseline-1.html HTTP(..) == centering-1.xul centering-1.xul == dynamic-height-1.xul dynamic-height-1.xul fails == select.html select.html -# == intrinsic-size.html intrinsic-size.html -# == line-height-0.5.html line-height-0.5.html -# == line-height-1.5.html line-height-1.5.html +fails == intrinsic-size.html intrinsic-size.html +fails == line-height-0.5.html line-height-0.5.html +fails == line-height-1.5.html line-height-1.5.html diff --git a/layout/reftests/forms/meter/default-style/reftest-stylo.list b/layout/reftests/forms/meter/default-style/reftest-stylo.list index c622e0952ab1..4585af8e7388 100644 --- a/layout/reftests/forms/meter/default-style/reftest-stylo.list +++ b/layout/reftests/forms/meter/default-style/reftest-stylo.list @@ -1,3 +1,3 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing -# == default-style.html default-style.html -# == default-style-dyn.html default-style-dyn.html +fails == default-style.html default-style.html +fails == default-style-dyn.html default-style-dyn.html diff --git a/layout/reftests/forms/meter/reftest-stylo.list b/layout/reftests/forms/meter/reftest-stylo.list index 915038e0dae9..df8e397307ae 100644 --- a/layout/reftests/forms/meter/reftest-stylo.list +++ b/layout/reftests/forms/meter/reftest-stylo.list @@ -1,44 +1,44 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing -# == values.html values.html -# == values-rtl.html values-rtl.html -# == margin-padding.html margin-padding.html -# == margin-padding-rtl.html margin-padding-rtl.html -# == bar-pseudo-element.html bar-pseudo-element.html -# == bar-pseudo-element-rtl.html bar-pseudo-element-rtl.html +== values.html values.html +== values-rtl.html values-rtl.html +== margin-padding.html margin-padding.html +== margin-padding-rtl.html margin-padding-rtl.html +fails == bar-pseudo-element.html bar-pseudo-element.html # Bug 1341095 +== bar-pseudo-element-rtl.html bar-pseudo-element-rtl.html # vertical tests -# == values-vertical.html values-vertical.html -# == values-vertical-rtl.html values-vertical-rtl.html -# == margin-padding-vertical.html margin-padding-vertical.html -# == margin-padding-vertical-rtl.html margin-padding-vertical-rtl.html -# == bar-pseudo-element-vertical.html bar-pseudo-element-vertical.html -# == bar-pseudo-element-vertical-rtl.html bar-pseudo-element-vertical-rtl.html +== values-vertical.html values-vertical.html +== values-vertical-rtl.html values-vertical-rtl.html +== margin-padding-vertical.html margin-padding-vertical.html +== margin-padding-vertical-rtl.html margin-padding-vertical-rtl.html +fails == bar-pseudo-element-vertical.html bar-pseudo-element-vertical.html # Bug 1341095 +== bar-pseudo-element-vertical-rtl.html bar-pseudo-element-vertical-rtl.html # The following test is disabled but kept in the repository because the # transformations will not behave exactly the same for and two divs. # However, it would be possible to manually check those. -# == transformations.html transformations.html +fails == transformations.html transformations.html # Bug 1341785 # default style include default-style/reftest-stylo.list # Tests for bugs: -# == block-invalidate.html block-invalidate.html -# == in-cells.html in-cells.html -# == max-height.html max-height.html +fails == block-invalidate.html block-invalidate.html +== in-cells.html in-cells.html +fails == max-height.html max-height.html # Tests for block and inline orientation in combination with writing-mode -# == meter-orient-vertical.html meter-orient-vertical.html -# == meter-orient-horizontal.html meter-orient-horizontal.html -# == meter-orient-block.html meter-orient-block.html -# == meter-orient-inline.html meter-orient-inline.html -# == meter-vlr.html meter-vlr.html -# == meter-vlr-orient-block.html meter-vlr-orient-block.html -# == meter-vlr-orient-inline.html meter-vlr-orient-inline.html -# == meter-vlr-orient-horizontal.html meter-vlr-orient-horizontal.html -# == meter-vlr-orient-vertical.html meter-vlr-orient-vertical.html -# == meter-vrl.html meter-vrl.html -# == meter-vrl-orient-block.html meter-vrl-orient-block.html -# == meter-vrl-orient-inline.html meter-vrl-orient-inline.html -# == meter-vrl-orient-horizontal.html meter-vrl-orient-horizontal.html -# == meter-vrl-orient-vertical.html meter-vrl-orient-vertical.html +fails == meter-orient-vertical.html meter-orient-vertical.html +fails == meter-orient-horizontal.html meter-orient-horizontal.html +fails == meter-orient-block.html meter-orient-block.html +fails == meter-orient-inline.html meter-orient-inline.html +fails == meter-vlr.html meter-vlr.html +fails == meter-vlr-orient-block.html meter-vlr-orient-block.html +fails == meter-vlr-orient-inline.html meter-vlr-orient-inline.html +fails == meter-vlr-orient-horizontal.html meter-vlr-orient-horizontal.html +fails == meter-vlr-orient-vertical.html meter-vlr-orient-vertical.html +fails == meter-vrl.html meter-vrl.html +fails == meter-vrl-orient-block.html meter-vrl-orient-block.html +fails == meter-vrl-orient-inline.html meter-vrl-orient-inline.html +fails == meter-vrl-orient-horizontal.html meter-vrl-orient-horizontal.html +fails == meter-vrl-orient-vertical.html meter-vrl-orient-vertical.html diff --git a/layout/reftests/forms/output/reftest-stylo.list b/layout/reftests/forms/output/reftest-stylo.list index 2da3ac1c4407..4a2b18b1ee7a 100644 --- a/layout/reftests/forms/output/reftest-stylo.list +++ b/layout/reftests/forms/output/reftest-stylo.list @@ -1,8 +1,8 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing -# == output-1.html output-1.html +== output-1.html output-1.html == output-2.html output-2.html -# == output-3.html output-3.html -# == output-4.html output-4.html -# == output-5.html output-5.html -# == output-6.html output-6.html -# == output-7.html output-7.html +== output-3.html output-3.html +fails == output-4.html output-4.html +== output-5.html output-5.html +== output-6.html output-6.html +== output-7.html output-7.html diff --git a/layout/reftests/forms/placeholder/reftest-stylo.list b/layout/reftests/forms/placeholder/reftest-stylo.list index 35cc1b201779..8f2b6bc03d72 100644 --- a/layout/reftests/forms/placeholder/reftest-stylo.list +++ b/layout/reftests/forms/placeholder/reftest-stylo.list @@ -32,5 +32,5 @@ random-if(winWidget) == placeholder-19.xul placeholder-19.xul # needs-focus == placeholder-20.html placeholder-20.html # needs-focus == placeholder-21.html placeholder-21.html fails needs-focus == placeholder-22.html placeholder-22.html -# == placeholder-rtl.html placeholder-rtl.html +fails == placeholder-rtl.html placeholder-rtl.html # Bug 1340696 fails pref(dom.placeholder.show_on_focus,false) needs-focus == placeholder-focus-pref.html placeholder-focus-pref.html diff --git a/layout/reftests/forms/progress/reftest-stylo.list b/layout/reftests/forms/progress/reftest-stylo.list index 579dc823d7ec..2c9fd8f1367e 100644 --- a/layout/reftests/forms/progress/reftest-stylo.list +++ b/layout/reftests/forms/progress/reftest-stylo.list @@ -1,43 +1,43 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing -# == values.html values.html -# == values-rtl.html values-rtl.html -# == margin-padding.html margin-padding.html -# == margin-padding-rtl.html margin-padding-rtl.html -# == bar-pseudo-element.html bar-pseudo-element.html -# == bar-pseudo-element-rtl.html bar-pseudo-element-rtl.html -# == indeterminate-style-width.html indeterminate-style-width.html +fails == values.html values.html +fails == values-rtl.html values-rtl.html +fails == margin-padding.html margin-padding.html +fails == margin-padding-rtl.html margin-padding-rtl.html +fails == bar-pseudo-element.html bar-pseudo-element.html +fails == bar-pseudo-element-rtl.html bar-pseudo-element-rtl.html +fails == indeterminate-style-width.html indeterminate-style-width.html # vertical tests -# == values-vertical.html values-vertical.html -# == values-vertical-rtl.html values-vertical-rtl.html -# == margin-padding-vertical.html margin-padding-vertical.html -# == margin-padding-vertical-rtl.html margin-padding-vertical-rtl.html -# == bar-pseudo-element-vertical.html bar-pseudo-element-vertical.html -# == bar-pseudo-element-vertical-rtl.html bar-pseudo-element-vertical-rtl.html -# == indeterminate-style-height.html indeterminate-style-height.html +fails == values-vertical.html values-vertical.html +fails == values-vertical-rtl.html values-vertical-rtl.html +fails == margin-padding-vertical.html margin-padding-vertical.html +fails == margin-padding-vertical-rtl.html margin-padding-vertical-rtl.html +fails == bar-pseudo-element-vertical.html bar-pseudo-element-vertical.html +fails == bar-pseudo-element-vertical-rtl.html bar-pseudo-element-vertical-rtl.html +fails == indeterminate-style-height.html indeterminate-style-height.html # The following test is disabled but kept in the repository because the # transformations will not behave exactly the same for and two divs. # However, it would be possible to manually check those. -# == transformations.html transformations.html +fails == transformations.html transformations.html # Tests for bugs: -# == block-invalidate.html block-invalidate.html -# == in-cells.html in-cells.html -# == max-height.html max-height.html +fails == block-invalidate.html block-invalidate.html +fails == in-cells.html in-cells.html +== max-height.html max-height.html # Tests for block and inline orientation in combination with writing-mode -# == progress-orient-horizontal.html progress-orient-horizontal.html +fails == progress-orient-horizontal.html progress-orient-horizontal.html fails-if(!cocoaWidget||OSX==1010) == progress-orient-vertical.html progress-orient-vertical.html -# == progress-orient-block.html progress-orient-block.html -# == progress-orient-inline.html progress-orient-inline.html -# == progress-vlr.html progress-vlr.html -# == progress-vlr-orient-block.html progress-vlr-orient-block.html -# == progress-vlr-orient-inline.html progress-vlr-orient-inline.html -# == progress-vlr-orient-horizontal.html progress-vlr-orient-horizontal.html -# == progress-vlr-orient-vertical.html progress-vlr-orient-vertical.html -# == progress-vrl.html progress-vrl.html -# == progress-vrl-orient-block.html progress-vrl-orient-block.html -# == progress-vrl-orient-inline.html progress-vrl-orient-inline.html -# == progress-vrl-orient-horizontal.html progress-vrl-orient-horizontal.html -# == progress-vrl-orient-vertical.html progress-vrl-orient-vertical.html +fails == progress-orient-block.html progress-orient-block.html +fails == progress-orient-inline.html progress-orient-inline.html +fails == progress-vlr.html progress-vlr.html +fails == progress-vlr-orient-block.html progress-vlr-orient-block.html +fails == progress-vlr-orient-inline.html progress-vlr-orient-inline.html +fails == progress-vlr-orient-horizontal.html progress-vlr-orient-horizontal.html +fails == progress-vlr-orient-vertical.html progress-vlr-orient-vertical.html +fails == progress-vrl.html progress-vrl.html +fails == progress-vrl-orient-block.html progress-vrl-orient-block.html +fails == progress-vrl-orient-inline.html progress-vrl-orient-inline.html +fails == progress-vrl-orient-horizontal.html progress-vrl-orient-horizontal.html +fails == progress-vrl-orient-vertical.html progress-vrl-orient-vertical.html diff --git a/layout/reftests/forms/select/reftest-stylo.list b/layout/reftests/forms/select/reftest-stylo.list index 1f40ea2da396..64e1239b08d6 100644 --- a/layout/reftests/forms/select/reftest-stylo.list +++ b/layout/reftests/forms/select/reftest-stylo.list @@ -1,9 +1,9 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing -# == out-of-bounds-selectedindex.html out-of-bounds-selectedindex.html -# == multiple.html multiple.html +fails == out-of-bounds-selectedindex.html out-of-bounds-selectedindex.html +fails == multiple.html multiple.html fails == boguskids.html boguskids.html -# == dynamic-boguskids.html dynamic-boguskids.html -# == option-children.html option-children.html +fails == dynamic-boguskids.html dynamic-boguskids.html +fails == option-children.html option-children.html fuzzy(1,4) == padding-button-placement.html padding-button-placement.html # HTTP(../..) == vertical-centering.html vertical-centering.html fails == 997709-2.html 997709-2.html diff --git a/layout/reftests/forms/textarea/reftest-stylo.list b/layout/reftests/forms/textarea/reftest-stylo.list index ba01f0a250c5..789554b19883 100644 --- a/layout/reftests/forms/textarea/reftest-stylo.list +++ b/layout/reftests/forms/textarea/reftest-stylo.list @@ -1,15 +1,15 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing -# == resize.html resize.html +fails == resize.html resize.html # an offset seems to apply to the native resizer on windows so skip this test for now -# == resize-background.html resize-background.html -# == ltr.html ltr.html -# == ltr-scrollbar.html ltr-scrollbar.html -# == in-ltr-doc-scrollbar.html in-ltr-doc-scrollbar.html -# == ltr.html ltr.html -# == rtl.html rtl.html -# == rtl.html rtl.html -# == rtl.html rtl.html -# == rtl.html rtl.html +fails == resize-background.html resize-background.html +fails == ltr.html ltr.html +fails == ltr-scrollbar.html ltr-scrollbar.html +fails == in-ltr-doc-scrollbar.html in-ltr-doc-scrollbar.html +fails == ltr.html ltr.html +fails == rtl.html rtl.html +fails == rtl.html rtl.html +fails == rtl.html rtl.html +fails == rtl.html rtl.html fails == setvalue-framereconstruction-1.html setvalue-framereconstruction-1.html -# == padding-scrollbar-placement.html padding-scrollbar-placement.html -# == various-cols.html various-cols.html +fails == padding-scrollbar-placement.html padding-scrollbar-placement.html +fails == various-cols.html various-cols.html diff --git a/layout/reftests/image-element/reftest-stylo.list b/layout/reftests/image-element/reftest-stylo.list index 3664787df71b..3f1d2dc5b5aa 100644 --- a/layout/reftests/image-element/reftest-stylo.list +++ b/layout/reftests/image-element/reftest-stylo.list @@ -6,9 +6,9 @@ fails == mozsetimageelement-01.html mozsetimageelement-01.html == mozsetimageelement-02.html mozsetimageelement-02.html == image-outside-document-invalidate.html image-outside-document-invalidate.html == canvas-outside-document-invalidate-01.html canvas-outside-document-invalidate-01.html -# == canvas-outside-document-invalidate-02.html canvas-outside-document-invalidate-02.html +skip-if(stylo) == canvas-outside-document-invalidate-02.html canvas-outside-document-invalidate-02.html # Bug 1324700 #fails with Skia due to Skia bug http://code.google.com/p/skia/issues/detail?id=568 -# == element-paint-simple.html element-paint-simple.html +fails == element-paint-simple.html element-paint-simple.html # Bug 1341761 fails == element-paint-repeated.html element-paint-repeated.html fails == element-paint-recursion.html element-paint-recursion.html fails HTTP(..) == element-paint-continuation.html element-paint-continuation.html diff --git a/layout/reftests/image-rect/reftest-stylo.list b/layout/reftests/image-rect/reftest-stylo.list index 798ff82120d9..58af986eecd2 100644 --- a/layout/reftests/image-rect/reftest-stylo.list +++ b/layout/reftests/image-rect/reftest-stylo.list @@ -13,5 +13,5 @@ fails == background-zoom-1.html background-zoom-1.html fails == background-zoom-2.html background-zoom-2.html fails == background-zoom-3.html background-zoom-3.html fails == background-zoom-4.html background-zoom-4.html -# == dom-api-computed-style.html dom-api-computed-style.html +fails == dom-api-computed-style.html dom-api-computed-style.html # Bug 1341763 fails == dom-api.html dom-api.html diff --git a/layout/reftests/image/reftest-stylo.list b/layout/reftests/image/reftest-stylo.list index 387ea9b8e7c4..b3ab0d18f5fc 100644 --- a/layout/reftests/image/reftest-stylo.list +++ b/layout/reftests/image/reftest-stylo.list @@ -71,8 +71,8 @@ fails == image-orientation-generated-content.html?180&flip image-orientation-gen fails == image-orientation-generated-content.html?270&flip image-orientation-generated-content.html?270&flip # Tests that image-orientation does not apply to decorative images: -# == image-orientation-background.html?from-image image-orientation-background.html?from-image -# == image-orientation-background.html?90&flip image-orientation-background.html?90&flip +== image-orientation-background.html?from-image image-orientation-background.html?from-image +== image-orientation-background.html?90&flip image-orientation-background.html?90&flip fails == image-orientation-border-image.html?from-image image-orientation-border-image.html?from-image fails == image-orientation-border-image.html?90&flip image-orientation-border-image.html?90&flip fails == image-orientation-list-style-image.html?from-image image-orientation-list-style-image.html?from-image @@ -100,7 +100,7 @@ fails == image-orientation-list-style-image.html?90&flip image-orientation-list- == image-orientation-generated-content-ref.html?90 image-orientation-generated-content-ref.html?90 == image-orientation-generated-content-ref.html?180 image-orientation-generated-content-ref.html?180 == image-orientation-generated-content-ref.html?270 image-orientation-generated-content-ref.html?270 -# == image-orientation-dynamic.html image-orientation-dynamic.html +fails == image-orientation-dynamic.html image-orientation-dynamic.html # Bug 1341758 # tests fails == image-srcset-basic-selection-0.1x.html image-srcset-basic-selection-0.1x.html diff --git a/layout/reftests/inline/reftest-stylo.list b/layout/reftests/inline/reftest-stylo.list index 17dabfcb56d8..eab7c51d04fb 100644 --- a/layout/reftests/inline/reftest-stylo.list +++ b/layout/reftests/inline/reftest-stylo.list @@ -2,8 +2,8 @@ == zero-inline-block-margin-left.html zero-inline-block-margin-left.html == zero-inline-block-margin-right.html zero-inline-block-margin-right.html == zero-inline-block-margin-ref.html zero-inline-block-margin-ref.html -# == inline-block-width.html inline-block-width.html -# == inline-block-padding.html inline-block-padding.html +== inline-block-width.html inline-block-width.html +== inline-block-padding.html inline-block-padding.html == inline-block-margin.html inline-block-margin.html -# == inline-block-width.html inline-block-width.html +== inline-block-width.html inline-block-width.html == inline-block-baseline.html inline-block-baseline.html diff --git a/layout/reftests/invalidation/reftest-stylo.list b/layout/reftests/invalidation/reftest-stylo.list index fe5b51c8c31d..2583b22681d9 100644 --- a/layout/reftests/invalidation/reftest-stylo.list +++ b/layout/reftests/invalidation/reftest-stylo.list @@ -1,6 +1,6 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing == table-repaint-a.html table-repaint-a.html -# == table-repaint-b.html table-repaint-b.html +== table-repaint-b.html table-repaint-b.html == table-repaint-c.html table-repaint-c.html == table-repaint-d.html table-repaint-d.html == 540247-1.xul 540247-1.xul @@ -9,7 +9,7 @@ fails == 1243409-1.html 1243409-1.html fails == test-image-layers.html test-image-layers.html fails == test-image-layers-multiple-displayitem.html test-image-layers-multiple-displayitem.html pref(layout.animated-image-layers.enabled,true) skip-if(Android||gtkWidget) == test-animated-image-layers.html test-animated-image-layers.html -# == test-animated-image-layers-background.html test-animated-image-layers-background.html +skip-if(stylo) == test-animated-image-layers-background.html test-animated-image-layers-background.html == box-shadow-border-radius.html box-shadow-border-radius.html == filter-userspace-offset.svg?offsetContainer=rect filter-userspace-offset.svg?offsetContainer=rect == filter-userspace-offset.svg?offsetContainer=use filter-userspace-offset.svg?offsetContainer=use @@ -49,8 +49,8 @@ fails == transform-floating-point-invalidation.html transform-floating-point-inv fails == transform-floating-point-invalidation.html?reverse transform-floating-point-invalidation.html?reverse fails == nudge-to-integer-invalidation.html nudge-to-integer-invalidation.html fails == nudge-to-integer-invalidation.html?reverse nudge-to-integer-invalidation.html?reverse -# == clipped-animated-transform-1.html clipped-animated-transform-1.html -# == paintedlayer-recycling-1.html paintedlayer-recycling-1.html +fails == clipped-animated-transform-1.html clipped-animated-transform-1.html +fails == paintedlayer-recycling-1.html paintedlayer-recycling-1.html fails == paintedlayer-recycling-2.html paintedlayer-recycling-2.html fails pref(layers.single-tile.enabled,false) == paintedlayer-recycling-3.html paintedlayer-recycling-3.html fails == paintedlayer-recycling-4.html paintedlayer-recycling-4.html @@ -72,8 +72,8 @@ fails pref(layers.single-tile.enabled,false) == fast-scrolling.html fast-scrolli == background-position-1.html background-position-1.html == background-position-2a.html background-position-2a.html == background-position-2b.html background-position-2b.html -# == background-position-2c.html background-position-2c.html -# == background-position-2d.html background-position-2d.html +== background-position-2c.html background-position-2c.html +== background-position-2d.html background-position-2d.html == background-position-2e.html background-position-2e.html == background-position-2f.html background-position-2f.html == zero-opacity-animation.html zero-opacity-animation.html diff --git a/layout/reftests/margin-collapsing/reftest-stylo.list b/layout/reftests/margin-collapsing/reftest-stylo.list index 59d9d7c1de52..7b1c70975d66 100644 --- a/layout/reftests/margin-collapsing/reftest-stylo.list +++ b/layout/reftests/margin-collapsing/reftest-stylo.list @@ -10,14 +10,14 @@ # "Horizontal margins never collapse." # Horizontal margins of inline boxes do not collapse. # The norefs for these tests depict margins that incorrectly collapsed. -# == inline-horizontal-1.html inline-horizontal-1.html -# == inline-horizontal-1.html inline-horizontal-1.html -# == inline-horizontal-2.html inline-horizontal-2.html -# == inline-horizontal-2.html inline-horizontal-2.html -# == inline-horizontal-1-dyn.html inline-horizontal-1-dyn.html -# == inline-horizontal-1-dyn.html inline-horizontal-1-dyn.html -# == inline-horizontal-2-dyn.html inline-horizontal-2-dyn.html -# == inline-horizontal-2-dyn.html inline-horizontal-2-dyn.html +== inline-horizontal-1.html inline-horizontal-1.html +== inline-horizontal-1.html inline-horizontal-1.html +== inline-horizontal-2.html inline-horizontal-2.html +== inline-horizontal-2.html inline-horizontal-2.html +== inline-horizontal-1-dyn.html inline-horizontal-1-dyn.html +== inline-horizontal-1-dyn.html inline-horizontal-1-dyn.html +== inline-horizontal-2-dyn.html inline-horizontal-2-dyn.html +== inline-horizontal-2-dyn.html inline-horizontal-2-dyn.html # Horizontal margins of block boxes do not collapse. # These block boxes are actually floats - in CSS 2.1 there is no other # method to create horizontally adjacent block boxes. @@ -38,19 +38,19 @@ == block-horizontal-4-dyn.html block-horizontal-4-dyn.html == block-horizontal-4-dyn.html block-horizontal-4-dyn.html # Horizontal margins of inline-block boxes do not collapse. -# == inline-block-horizontal-1.html inline-block-horizontal-1.html -# == inline-block-horizontal-1.html inline-block-horizontal-1.html -# == inline-block-horizontal-2.html inline-block-horizontal-2.html -# == inline-block-horizontal-2.html inline-block-horizontal-2.html -# == inline-block-horizontal-1-dyn.html inline-block-horizontal-1-dyn.html -# == inline-block-horizontal-1-dyn.html inline-block-horizontal-1-dyn.html -# == inline-block-horizontal-2-dyn.html inline-block-horizontal-2-dyn.html -# == inline-block-horizontal-2-dyn.html inline-block-horizontal-2-dyn.html +== inline-block-horizontal-1.html inline-block-horizontal-1.html +== inline-block-horizontal-1.html inline-block-horizontal-1.html +== inline-block-horizontal-2.html inline-block-horizontal-2.html +== inline-block-horizontal-2.html inline-block-horizontal-2.html +== inline-block-horizontal-1-dyn.html inline-block-horizontal-1-dyn.html +== inline-block-horizontal-1-dyn.html inline-block-horizontal-1-dyn.html +== inline-block-horizontal-2-dyn.html inline-block-horizontal-2-dyn.html +== inline-block-horizontal-2-dyn.html inline-block-horizontal-2-dyn.html # Horizontal margins of inline-tables do not collapse. -# == inline-table-horizontal-1.html inline-table-horizontal-1.html -# == inline-table-horizontal-1.html inline-table-horizontal-1.html -# == inline-table-horizontal-1-dyn.html inline-table-horizontal-1-dyn.html -# == inline-table-horizontal-1-dyn.html inline-table-horizontal-1-dyn.html +== inline-table-horizontal-1.html inline-table-horizontal-1.html +== inline-table-horizontal-1.html inline-table-horizontal-1.html +== inline-table-horizontal-1-dyn.html inline-table-horizontal-1-dyn.html +== inline-table-horizontal-1-dyn.html inline-table-horizontal-1-dyn.html # "In CSS, the adjoining margins of two or more boxes # (which might or might not be siblings) can combine to form a single margin. # Margins that combine this way are said to collapse, @@ -576,16 +576,16 @@ == block-overflow-1.html block-overflow-1.html == block-overflow-2.html block-overflow-2.html == block-overflow-2.html block-overflow-2.html -# == block-overflow-3.html block-overflow-3.html -# == block-overflow-3.html block-overflow-3.html -# == block-overflow-4.html block-overflow-4.html -# == block-overflow-4.html block-overflow-4.html +fails == block-overflow-3.html block-overflow-3.html # Bug 1321769? +fails == block-overflow-3.html block-overflow-3.html # Bug 1321769? +fails == block-overflow-4.html block-overflow-4.html # Bug 1321769? +fails == block-overflow-4.html block-overflow-4.html # Bug 1321769? == block-overflow-5a.html block-overflow-5a.html == block-overflow-5a.html block-overflow-5a.html == block-overflow-5b.html block-overflow-5b.html == block-overflow-5b.html block-overflow-5b.html -# == block-overflow-5c.html block-overflow-5c.html -# == block-overflow-5c.html block-overflow-5c.html +fails == block-overflow-5c.html block-overflow-5c.html # Bug 1321769? +fails == block-overflow-5c.html block-overflow-5c.html # Bug 1321769? == block-overflow-5d.html block-overflow-5d.html == block-overflow-5d.html block-overflow-5d.html == block-overflow-1-dyn.html block-overflow-1-dyn.html @@ -668,11 +668,11 @@ fails == block-overflow-5c-dyn.html block-overflow-5c-dyn.html # CSS 2 definition of 'top' and 'bottom' (which is different from CSS 2.1's). # Since Bug # alias for the CSS 2.1 values 'top' and 'bottom' respectively. -# == table-caption-top-1.html table-caption-top-1.html +== table-caption-top-1.html table-caption-top-1.html == table-caption-top-2.html table-caption-top-2.html == table-caption-top-outside-1.html table-caption-top-outside-1.html == table-caption-top-outside-2.html table-caption-top-outside-2.html -# == table-caption-bottom-1.html table-caption-bottom-1.html +== table-caption-bottom-1.html table-caption-bottom-1.html == table-caption-bottom-2.html table-caption-bottom-2.html == table-caption-bottom-outside-1.html table-caption-bottom-outside-1.html == table-caption-bottom-outside-2.html table-caption-bottom-outside-2.html @@ -730,8 +730,8 @@ fails == block-overflow-5c-dyn.html block-overflow-5c-dyn.html == inline-block-sibling-1c-dyn.html inline-block-sibling-1c-dyn.html == inline-block-sibling-2-dyn.html inline-block-sibling-2-dyn.html == inline-block-child-1.html inline-block-child-1.html -# == inline-block-child-2.html inline-block-child-2.html -# == inline-block-child-2.html inline-block-child-2.html +== inline-block-child-2.html inline-block-child-2.html +== inline-block-child-2.html inline-block-child-2.html == inline-block-child-3.html inline-block-child-3.html == inline-block-child-1-dyn.html inline-block-child-1-dyn.html == inline-block-child-2-dyn.html inline-block-child-2-dyn.html diff --git a/layout/reftests/mathml/reftest-stylo.list b/layout/reftests/mathml/reftest-stylo.list index fdc5bc832f92..15d103ac94d8 100644 --- a/layout/reftests/mathml/reftest-stylo.list +++ b/layout/reftests/mathml/reftest-stylo.list @@ -186,14 +186,14 @@ fails == mtable-columnalign-multi-mtable-dynamic.html mtable-columnalign-multi-m fails == maction-selection.html maction-selection.html fails == maction-dynamic-embellished-op.html maction-dynamic-embellished-op.html fails == maction-dynamic-1.html maction-dynamic-1.html -# == maction-dynamic-2.html maction-dynamic-2.html +fails == maction-dynamic-2.html maction-dynamic-2.html fails == mo-lspace-rspace.html mo-lspace-rspace.html fails == mo-lspace-rspace-2.html mo-lspace-rspace-2.html fails == mo-lspace-rspace-3.html mo-lspace-rspace-3.html fails == mo-lspace-rspace-4.html mo-lspace-rspace-4.html fails == mo-invisibleoperators.html mo-invisibleoperators.html fails == mo-invisibleoperators-2.html mo-invisibleoperators-2.html -# == mo-glyph-size.html mo-glyph-size.html +== mo-glyph-size.html mo-glyph-size.html fails == maction-dynamic-3.html maction-dynamic-3.html == whitespace-trim-1.html whitespace-trim-1.html fails == whitespace-trim-2.html whitespace-trim-2.html @@ -246,7 +246,7 @@ fails == menclose-3-madruwb.html menclose-3-madruwb.html fails == menclose-3-radical.html menclose-3-radical.html fails == menclose-3-default.html menclose-3-default.html fails == menclose-3-invalid.html menclose-3-invalid.html -# == menclose-3-multiple.html menclose-3-multiple.html +== menclose-3-multiple.html menclose-3-multiple.html fails == menclose-3-unknown.html menclose-3-unknown.html == menclose-4.html menclose-4.html fails == menclose-5-actuarial.html menclose-5-actuarial.html diff --git a/layout/reftests/native-theme/reftest-stylo.list b/layout/reftests/native-theme/reftest-stylo.list index b256eed7c925..2ab01d11734c 100644 --- a/layout/reftests/native-theme/reftest-stylo.list +++ b/layout/reftests/native-theme/reftest-stylo.list @@ -48,10 +48,10 @@ fails == box-shadow-listbox.html box-shadow-listbox.html fails == box-shadow-combobox.html box-shadow-combobox.html # RTL mirroring tests -# == checkbox-not-mirrored-when-rtl.html checkbox-not-mirrored-when-rtl.html +== checkbox-not-mirrored-when-rtl.html checkbox-not-mirrored-when-rtl.html skip-if(!cocoaWidget) == menulist-mirrored-when-rtl.xul menulist-mirrored-when-rtl.xul skip-if(!cocoaWidget) == searchfield-mirrored-when-rtl.xul searchfield-mirrored-when-rtl.xul -# == select-mirrored-when-rtl.html select-mirrored-when-rtl.html +fails == select-mirrored-when-rtl.html select-mirrored-when-rtl.html == resizer-bottomend.xul resizer-bottomend.xul random-if(d2d) == resizer-bottomend.xul resizer-bottomend.xul diff --git a/layout/reftests/pagination/reftest-stylo.list b/layout/reftests/pagination/reftest-stylo.list index 645262904714..95d429f68492 100644 --- a/layout/reftests/pagination/reftest-stylo.list +++ b/layout/reftests/pagination/reftest-stylo.list @@ -67,9 +67,9 @@ fails == table-caption-splitaftercaption-4.html table-caption-splitaftercaption- fails == table-caption-splitaftercaption-5.html table-caption-splitaftercaption-5.html fails == table-caption-splitaftercaption-6.html table-caption-splitaftercaption-6.html fails == table-caption-splitaftercaption-7.html table-caption-splitaftercaption-7.html -# == table-caption-splitaftercaption-8.html table-caption-splitaftercaption-8.html -# == table-caption-splitaftercaption-9.html table-caption-splitaftercaption-9.html -# == table-caption-splitaftercaption-10.html table-caption-splitaftercaption-10.html -# == table-caption-splitaftercaption-11.html table-caption-splitaftercaption-11.html +fails == table-caption-splitaftercaption-8.html table-caption-splitaftercaption-8.html # Bug 1341648 +fails == table-caption-splitaftercaption-9.html table-caption-splitaftercaption-9.html # Bug 1341648 +fails == table-caption-splitaftercaption-10.html table-caption-splitaftercaption-10.html # Bug 1341648 +fails == table-caption-splitaftercaption-11.html table-caption-splitaftercaption-11.html # Bug 1341648 == column-balancing-break-inside-avoid-2.html column-balancing-break-inside-avoid-2.html fails == combobox-page-break-inside.html combobox-page-break-inside.html diff --git a/layout/reftests/pixel-rounding/reftest-stylo.list b/layout/reftests/pixel-rounding/reftest-stylo.list index 99cb29eca5ae..26134b6e7fe4 100644 --- a/layout/reftests/pixel-rounding/reftest-stylo.list +++ b/layout/reftests/pixel-rounding/reftest-stylo.list @@ -178,7 +178,7 @@ fails == border-image-width-0.html border-image-width-0.html fails == border-image-width-4.html border-image-width-4.html fails == border-image-width-9.html border-image-width-9.html -# == iframe-1.html iframe-1.html +fails == iframe-1.html iframe-1.html # Bug 1341769 fails == viewport-units-rounding-1.html viewport-units-rounding-1.html == viewport-units-rounding-2.html viewport-units-rounding-2.html diff --git a/layout/reftests/position-dynamic-changes/reftest-stylo.list b/layout/reftests/position-dynamic-changes/reftest-stylo.list index 84bb3fded294..ce452f4002d7 100644 --- a/layout/reftests/position-dynamic-changes/reftest-stylo.list +++ b/layout/reftests/position-dynamic-changes/reftest-stylo.list @@ -8,4 +8,4 @@ include relative/reftest-stylo.list == multiple-changes.html multiple-changes.html == shrink-wrap.html shrink-wrap.html == max-width.html max-width.html -# == min-width.html min-width.html +== min-width.html min-width.html diff --git a/layout/reftests/position-relative/reftest-stylo.list b/layout/reftests/position-relative/reftest-stylo.list index 5b5f461b3e1a..e0824d6ac3e7 100644 --- a/layout/reftests/position-relative/reftest-stylo.list +++ b/layout/reftests/position-relative/reftest-stylo.list @@ -1,5 +1,5 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing -# == table-collapse-1.html table-collapse-1.html +== table-collapse-1.html table-collapse-1.html == table-collapse-2.html table-collapse-2.html == table-collapse-3.html table-collapse-3.html == table-collapse-4.html table-collapse-4.html diff --git a/layout/reftests/printing/reftest-stylo.list b/layout/reftests/printing/reftest-stylo.list index 90e68858768d..a91d2d2d2948 100644 --- a/layout/reftests/printing/reftest-stylo.list +++ b/layout/reftests/printing/reftest-stylo.list @@ -20,11 +20,11 @@ fails == 626395-1b.html 626395-1b.html fails == 626395-2b.html 626395-2b.html == 626395-2c.html 626395-2c.html fails == 626395-2d.html 626395-2d.html -# == 652178-1.html 652178-1.html +== 652178-1.html 652178-1.html fails == 115199-1.html 115199-1.html == 115199-2a.html 115199-2a.html == 115199-2b.html 115199-2b.html -# == 652178-1.html 652178-1.html +== 652178-1.html 652178-1.html == 745025-1.html 745025-1.html fails == 820496-1.html 820496-1.html diff --git a/layout/reftests/reftest-sanity/reftest-stylo.list b/layout/reftests/reftest-sanity/reftest-stylo.list index a6e9fd0e300b..e41ecdde07c6 100644 --- a/layout/reftests/reftest-sanity/reftest-stylo.list +++ b/layout/reftests/reftest-sanity/reftest-stylo.list @@ -1,7 +1,7 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing == data:text/html, data:text/html, == data:text/plain, data:text/plain, -# == data:text/plain,HELLO data:text/plain,HELLO +fails == data:text/plain,HELLO data:text/plain,HELLO # Bug 1341637 # these tests make sure async reftests work: == test-async.xul test-async.xul @@ -31,7 +31,7 @@ HTTP == blank.html blank.html HTTP == about:blank about:blank # same for data: == default.html default.html -# == data:text/html,
Text
data:text/html,
Text
+== data:text/html,
Text
data:text/html,
Text
HTTP == default.html default.html # HTTP == data:text/html,
Text
data:text/html,
Text
== blank.html blank.html @@ -79,15 +79,15 @@ include default-preferences-tests-stylo.list == page-width-3.9in.html page-width-3.9in.html == page-width-4.1in.html page-width-4.1in.html == page-width-auto.html page-width-auto.html -# == page-height-2in.html page-height-2in.html -# == page-height-2in.html page-height-2in.html +== page-height-2in.html page-height-2in.html +== page-height-2in.html page-height-2in.html == page-height-2.1in.html page-height-2.1in.html # Check that tests that need focus are skipped when it's not available needs-focus load needs-focus.html # Bug 632636 -# == data:text/plain,HELLO data:text/plain,HELLO +fails == data:text/plain,HELLO data:text/plain,HELLO # Bug 1341637 needs-focus == data:text/plain, data:text/plain, # Sanity check of viewport+displayport overrides @@ -172,8 +172,8 @@ default-preferences == async-zoom-2.html async-zoom-2.html # reftest-opaque-layer -# == reftest-opaque-layer-pass.html reftest-opaque-layer-pass.html -# == reftest-opaque-layer-pass.html reftest-opaque-layer-pass.html +fails == reftest-opaque-layer-pass.html reftest-opaque-layer-pass.html # Bug 1341095 +fails == reftest-opaque-layer-pass.html reftest-opaque-layer-pass.html # Bug 1341095 == about:blank about:blank fails == reftest-opaque-layer-fail.html reftest-opaque-layer-fail.html @@ -187,7 +187,7 @@ fails == reftest-opaque-layer-fail.html reftest-opaque-layer-fail.html # reftest-opaque-layer and reftest-wait fails == reftest-opaque-layer-wait-pass.html reftest-opaque-layer-wait-pass.html -# == reftest-opaque-layer-wait-pass.html reftest-opaque-layer-wait-pass.html +fails == reftest-opaque-layer-wait-pass.html reftest-opaque-layer-wait-pass.html fails == reftest-opaque-layer-wait-fail.html reftest-opaque-layer-wait-fail.html fails == reftest-opaque-layer-wait-fail.html reftest-opaque-layer-wait-fail.html diff --git a/layout/reftests/svg/as-image/reftest-stylo.list b/layout/reftests/svg/as-image/reftest-stylo.list index 8963e32037e5..0b6d36fe65cf 100644 --- a/layout/reftests/svg/as-image/reftest-stylo.list +++ b/layout/reftests/svg/as-image/reftest-stylo.list @@ -166,48 +166,48 @@ HTTP == svg-stylesheet-external-1.html svg-stylesheet-external-1.html fails == svg-border-image-repaint-1.html svg-border-image-repaint-1.html # Tests for image-orientation with a viewbox and an intrinsic size: -# == image-orientation-viewbox-and-size.html?0 image-orientation-viewbox-and-size.html?0 -# == image-orientation-viewbox-and-size.html?90 image-orientation-viewbox-and-size.html?90 -# == image-orientation-viewbox-and-size.html?180 image-orientation-viewbox-and-size.html?180 -# == image-orientation-viewbox-and-size.html?270 image-orientation-viewbox-and-size.html?270 -# == image-orientation-viewbox-and-size.html?0&flip image-orientation-viewbox-and-size.html?0&flip -# == image-orientation-viewbox-and-size.html?90&flip image-orientation-viewbox-and-size.html?90&flip -# == image-orientation-viewbox-and-size.html?180&flip image-orientation-viewbox-and-size.html?180&flip -# == image-orientation-viewbox-and-size.html?270&flip image-orientation-viewbox-and-size.html?270&flip +== image-orientation-viewbox-and-size.html?0 image-orientation-viewbox-and-size.html?0 +fails == image-orientation-viewbox-and-size.html?90 image-orientation-viewbox-and-size.html?90 # Bug 1341758 +fails == image-orientation-viewbox-and-size.html?180 image-orientation-viewbox-and-size.html?180 # Bug 1341758 +fails == image-orientation-viewbox-and-size.html?270 image-orientation-viewbox-and-size.html?270 # Bug 1341758 +fails == image-orientation-viewbox-and-size.html?0&flip image-orientation-viewbox-and-size.html?0&flip # Bug 1341758 +fails == image-orientation-viewbox-and-size.html?90&flip image-orientation-viewbox-and-size.html?90&flip # Bug 1341758 +fails == image-orientation-viewbox-and-size.html?180&flip image-orientation-viewbox-and-size.html?180&flip # Bug 1341758 +fails == image-orientation-viewbox-and-size.html?270&flip image-orientation-viewbox-and-size.html?270&flip # Bug 1341758 # Tests for image-orientation with a viewbox and no intrinsic size: -# == image-orientation-viewbox-no-size.html?0 image-orientation-viewbox-no-size.html?0 -# == image-orientation-viewbox-no-size.html?90 image-orientation-viewbox-no-size.html?90 -# == image-orientation-viewbox-no-size.html?180 image-orientation-viewbox-no-size.html?180 -# == image-orientation-viewbox-no-size.html?270 image-orientation-viewbox-no-size.html?270 -# == image-orientation-viewbox-no-size.html?0&flip image-orientation-viewbox-no-size.html?0&flip -# == image-orientation-viewbox-no-size.html?90&flip image-orientation-viewbox-no-size.html?90&flip -# == image-orientation-viewbox-no-size.html?180&flip image-orientation-viewbox-no-size.html?180&flip -# == image-orientation-viewbox-no-size.html?270&flip image-orientation-viewbox-no-size.html?270&flip +== image-orientation-viewbox-no-size.html?0 image-orientation-viewbox-no-size.html?0 +fails == image-orientation-viewbox-no-size.html?90 image-orientation-viewbox-no-size.html?90 # Bug 1341758 +fails == image-orientation-viewbox-no-size.html?180 image-orientation-viewbox-no-size.html?180 # Bug 1341758 +fails == image-orientation-viewbox-no-size.html?270 image-orientation-viewbox-no-size.html?270 # Bug 1341758 +fails == image-orientation-viewbox-no-size.html?0&flip image-orientation-viewbox-no-size.html?0&flip # Bug 1341758 +fails == image-orientation-viewbox-no-size.html?90&flip image-orientation-viewbox-no-size.html?90&flip # Bug 1341758 +fails == image-orientation-viewbox-no-size.html?180&flip image-orientation-viewbox-no-size.html?180&flip # Bug 1341758 +fails == image-orientation-viewbox-no-size.html?270&flip image-orientation-viewbox-no-size.html?270&flip # Bug 1341758 # Tests for image-orientation with no viewbox and an intrinsic size: -# == image-orientation-no-viewbox-and-size.html?0 image-orientation-no-viewbox-and-size.html?0 -# == image-orientation-no-viewbox-and-size.html?90 image-orientation-no-viewbox-and-size.html?90 -# == image-orientation-no-viewbox-and-size.html?180 image-orientation-no-viewbox-and-size.html?180 -# == image-orientation-no-viewbox-and-size.html?270 image-orientation-no-viewbox-and-size.html?270 -# == image-orientation-no-viewbox-and-size.html?0&flip image-orientation-no-viewbox-and-size.html?0&flip -# == image-orientation-no-viewbox-and-size.html?90&flip image-orientation-no-viewbox-and-size.html?90&flip -# == image-orientation-no-viewbox-and-size.html?180&flip image-orientation-no-viewbox-and-size.html?180&flip -# == image-orientation-no-viewbox-and-size.html?270&flip image-orientation-no-viewbox-and-size.html?270&flip +== image-orientation-no-viewbox-and-size.html?0 image-orientation-no-viewbox-and-size.html?0 +fails == image-orientation-no-viewbox-and-size.html?90 image-orientation-no-viewbox-and-size.html?90 # Bug 1341758 +fails == image-orientation-no-viewbox-and-size.html?180 image-orientation-no-viewbox-and-size.html?180 # Bug 1341758 +fails == image-orientation-no-viewbox-and-size.html?270 image-orientation-no-viewbox-and-size.html?270 # Bug 1341758 +fails == image-orientation-no-viewbox-and-size.html?0&flip image-orientation-no-viewbox-and-size.html?0&flip # Bug 1341758 +fails == image-orientation-no-viewbox-and-size.html?90&flip image-orientation-no-viewbox-and-size.html?90&flip # Bug 1341758 +fails == image-orientation-no-viewbox-and-size.html?180&flip image-orientation-no-viewbox-and-size.html?180&flip # Bug 1341758 +fails == image-orientation-no-viewbox-and-size.html?270&flip image-orientation-no-viewbox-and-size.html?270&flip # Bug 1341758 # Tests for image-orientation with no viewbox and no intrinsic size: -# == image-orientation-no-viewbox-no-size.html?0 image-orientation-no-viewbox-no-size.html?0 -# == image-orientation-no-viewbox-no-size.html?90 image-orientation-no-viewbox-no-size.html?90 -# == image-orientation-no-viewbox-no-size.html?180 image-orientation-no-viewbox-no-size.html?180 -# == image-orientation-no-viewbox-no-size.html?270 image-orientation-no-viewbox-no-size.html?270 -# == image-orientation-no-viewbox-no-size.html?0&flip image-orientation-no-viewbox-no-size.html?0&flip -# == image-orientation-no-viewbox-no-size.html?90&flip image-orientation-no-viewbox-no-size.html?90&flip -# == image-orientation-no-viewbox-no-size.html?180&flip image-orientation-no-viewbox-no-size.html?180&flip -# == image-orientation-no-viewbox-no-size.html?270&flip image-orientation-no-viewbox-no-size.html?270&flip +== image-orientation-no-viewbox-no-size.html?0 image-orientation-no-viewbox-no-size.html?0 +fails == image-orientation-no-viewbox-no-size.html?90 image-orientation-no-viewbox-no-size.html?90 # Bug 1341758 +fails == image-orientation-no-viewbox-no-size.html?180 image-orientation-no-viewbox-no-size.html?180 # Bug 1341758 +fails == image-orientation-no-viewbox-no-size.html?270 image-orientation-no-viewbox-no-size.html?270 # Bug 1341758 +fails == image-orientation-no-viewbox-no-size.html?0&flip image-orientation-no-viewbox-no-size.html?0&flip # Bug 1341758 +fails == image-orientation-no-viewbox-no-size.html?90&flip image-orientation-no-viewbox-no-size.html?90&flip # Bug 1341758 +fails == image-orientation-no-viewbox-no-size.html?180&flip image-orientation-no-viewbox-no-size.html?180&flip # Bug 1341758 +fails == image-orientation-no-viewbox-no-size.html?270&flip image-orientation-no-viewbox-no-size.html?270&flip # Bug 1341758 # Test that 'image-orientation: from-image' has no effect, since SVGs don't have EXIF data. -# == image-orientation-viewbox-and-size.html?from-image image-orientation-viewbox-and-size.html?from-image -# == image-orientation-viewbox-no-size.html?from-image image-orientation-viewbox-no-size.html?from-image +== image-orientation-viewbox-and-size.html?from-image image-orientation-viewbox-and-size.html?from-image +== image-orientation-viewbox-no-size.html?from-image image-orientation-viewbox-no-size.html?from-image # Sanity checks for the image-orientation tests. Ensures that the various # combinations of rotations and flips actually look different from each other. @@ -229,14 +229,14 @@ fails == svg-border-image-repaint-1.html svg-border-image-repaint-1.html == nonuniform-scale-3d.html?1.0&0.5&0.5 nonuniform-scale-3d.html?1.0&0.5&0.5 # Sanity checks that nonuniform scales don't devolve to uniform scales. -# == nonuniform-scale-2d.html?0.3&1.0 nonuniform-scale-2d.html?0.3&1.0 -# == nonuniform-scale-2d.html?0.3&1.0 nonuniform-scale-2d.html?0.3&1.0 -# == nonuniform-scale-2d.html?1.0&0.3 nonuniform-scale-2d.html?1.0&0.3 -# == nonuniform-scale-2d.html?1.0&0.3 nonuniform-scale-2d.html?1.0&0.3 -# == nonuniform-scale-3d.html?0.3&1.0&0.3 nonuniform-scale-3d.html?0.3&1.0&0.3 -# == nonuniform-scale-3d.html?0.3&1.0&0.3 nonuniform-scale-3d.html?0.3&1.0&0.3 -# == nonuniform-scale-3d.html?1.0&0.3&0.3 nonuniform-scale-3d.html?1.0&0.3&0.3 -# == nonuniform-scale-3d.html?1.0&0.3&0.3 nonuniform-scale-3d.html?1.0&0.3&0.3 +== nonuniform-scale-2d.html?0.3&1.0 nonuniform-scale-2d.html?0.3&1.0 +== nonuniform-scale-2d.html?0.3&1.0 nonuniform-scale-2d.html?0.3&1.0 +== nonuniform-scale-2d.html?1.0&0.3 nonuniform-scale-2d.html?1.0&0.3 +== nonuniform-scale-2d.html?1.0&0.3 nonuniform-scale-2d.html?1.0&0.3 +== nonuniform-scale-3d.html?0.3&1.0&0.3 nonuniform-scale-3d.html?0.3&1.0&0.3 +== nonuniform-scale-3d.html?0.3&1.0&0.3 nonuniform-scale-3d.html?0.3&1.0&0.3 +== nonuniform-scale-3d.html?1.0&0.3&0.3 nonuniform-scale-3d.html?1.0&0.3&0.3 +== nonuniform-scale-3d.html?1.0&0.3&0.3 nonuniform-scale-3d.html?1.0&0.3&0.3 # Test for preserveAspectRatio with no-longer-supported "defer" keyword == defer-unsupported-1.svg defer-unsupported-1.svg diff --git a/layout/reftests/svg/filters/css-filters/reftest-stylo.list b/layout/reftests/svg/filters/css-filters/reftest-stylo.list index 18d122341fbf..0a8422162604 100644 --- a/layout/reftests/svg/filters/css-filters/reftest-stylo.list +++ b/layout/reftests/svg/filters/css-filters/reftest-stylo.list @@ -27,7 +27,7 @@ default-preferences pref(layout.css.filters.enabled,true) == contrast-percent.html contrast-percent.html == contrast-reduce.html contrast-reduce.html == contrast-zero.html contrast-zero.html -# == drop-shadow.html drop-shadow.html +== drop-shadow.html drop-shadow.html == drop-shadow-default-color.html drop-shadow-default-color.html == drop-shadow-negative-offset.html drop-shadow-negative-offset.html == grayscale.html grayscale.html diff --git a/layout/reftests/svg/filters/reftest-stylo.list b/layout/reftests/svg/filters/reftest-stylo.list index 4286d3dd3040..480aed4c58c5 100644 --- a/layout/reftests/svg/filters/reftest-stylo.list +++ b/layout/reftests/svg/filters/reftest-stylo.list @@ -42,7 +42,7 @@ skip-if(d2d) fuzzy-if(skiaContent,1,6400) == feFlood-2.svg feFlood-2.svg fuzzy(1,6400) fuzzy-if(skiaContent,1,6404) == feGaussianBlur-1.svg feGaussianBlur-1.svg == feGaussianBlur-2.svg feGaussianBlur-2.svg -# == feGaussianBlur-3.svg feGaussianBlur-3.svg +== feGaussianBlur-3.svg feGaussianBlur-3.svg == feGaussianBlur-4.svg feGaussianBlur-4.svg == feGaussianBlur-5.svg feGaussianBlur-5.svg == feGaussianBlur-6.svg feGaussianBlur-6.svg diff --git a/layout/reftests/svg/reftest-stylo.list b/layout/reftests/svg/reftest-stylo.list index c480075285e3..5f7cbf20e156 100644 --- a/layout/reftests/svg/reftest-stylo.list +++ b/layout/reftests/svg/reftest-stylo.list @@ -285,7 +285,7 @@ fuzzy-if(skiaContent,3,5) == pattern-scale-01c.svg pattern-scale-01c.svg # This test depends on :visited styles (which are asynchronous), so we run # it in layout/style/test/test_visited_reftests.html instead of using the # reftest harness. -# == pseudo-classes-02.svg pseudo-classes-02.svg +== pseudo-classes-02.svg pseudo-classes-02.svg == radialGradient-basic-01.svg radialGradient-basic-01.svg == radialGradient-basic-02.svg radialGradient-basic-02.svg fuzzy-if(cocoaWidget,4,15982) fuzzy-if(winWidget,4,92) fuzzy-if(skiaContent,4,60) == radialGradient-basic-03.svg radialGradient-basic-03.svg @@ -296,7 +296,7 @@ fuzzy-if(skiaContent,1,3600) == rect-01.svg rect-01.svg == rect-04.svg rect-04.svg == rect-with-rx-and-ry-01.svg rect-with-rx-and-ry-01.svg == rect-with-rx-or-ry-01.svg rect-with-rx-or-ry-01.svg -# == rootElement-null-01.svg rootElement-null-01.svg +== rootElement-null-01.svg rootElement-null-01.svg == script-empty-01.svg script-empty-01.svg == selector-01.svg selector-01.svg == stroke-linecap-circle-ellipse-01.svg stroke-linecap-circle-ellipse-01.svg @@ -433,7 +433,7 @@ pref(layout.css.mix-blend-mode.enabled,true) == blend-normal.svg blend-normal.sv #skip-if(Android) pref(layout.css.mix-blend-mode.enabled,true) == blend-saturation.svg blend-saturation.svg #skip-if(Android) pref(layout.css.mix-blend-mode.enabled,true) == blend-screen.svg blend-screen.svg #skip-if(Android) pref(layout.css.mix-blend-mode.enabled,true) == blend-soft-light.svg blend-soft-light.svg -# == blend-difference-stacking.html blend-difference-stacking.html +== blend-difference-stacking.html blend-difference-stacking.html # test case for Fragment URLs # https://drafts.csswg.org/css-values/#local-urls diff --git a/layout/reftests/svg/sizing/reftest-stylo.list b/layout/reftests/svg/sizing/reftest-stylo.list index 818a9f24a4a9..2f3c9f315f76 100644 --- a/layout/reftests/svg/sizing/reftest-stylo.list +++ b/layout/reftests/svg/sizing/reftest-stylo.list @@ -309,5 +309,4 @@ fails == dynamic--inline-css-width.xhtml dynamic--inline-css-width.xhtml fails == dynamic--inline-resize-window-height.xhtml dynamic--inline-resize-window-height.xhtml fails == dynamic--inline-resize-window-width.xhtml dynamic--inline-resize-window-width.xhtml random-if(Android) == dynamic--object-svg-unloaded.xhtml dynamic--object-svg-unloaded.xhtml -# == == diff --git a/layout/reftests/tab-size/reftest-stylo.list b/layout/reftests/tab-size/reftest-stylo.list index 8b634b1df769..993aba2769f5 100644 --- a/layout/reftests/tab-size/reftest-stylo.list +++ b/layout/reftests/tab-size/reftest-stylo.list @@ -1,10 +1,10 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing -# == tab-size-8.html tab-size-8.html -# == tab-size-8.html tab-size-8.html +fails == tab-size-8.html tab-size-8.html # Bug 1341637 +fails == tab-size-8.html tab-size-8.html # Bug 1341637 fails == tab-size-4.html tab-size-4.html fails == tab-size-4-span.html tab-size-4-span.html fails == tab-size-4-spanoffset.html tab-size-4-spanoffset.html -# == tab-size-4-multiple.html tab-size-4-multiple.html +fails == tab-size-4-multiple.html tab-size-4-multiple.html # Bug 1341637 fails == tab-size-1.html tab-size-1.html fails == tab-size-0.html tab-size-0.html fails == tab-size-negative.html tab-size-negative.html diff --git a/layout/reftests/table-anonymous-boxes/reftest-stylo.list b/layout/reftests/table-anonymous-boxes/reftest-stylo.list index 719504235dbf..46635656df14 100644 --- a/layout/reftests/table-anonymous-boxes/reftest-stylo.list +++ b/layout/reftests/table-anonymous-boxes/reftest-stylo.list @@ -8,10 +8,10 @@ fails == 156888-2.html 156888-2.html == 203923-1.html 203923-1.html == 203923-2.html 203923-2.html == 208305-1.html 208305-1.html -# == 208305-2.html 208305-2.html +== 208305-2.html 208305-2.html == 208305-3.html 208305-3.html -# == 208305-4.html 208305-4.html -# == 277995-1.html 277995-1.html +== 208305-4.html 208305-4.html +== 277995-1.html 277995-1.html fails == 293576-1.html 293576-1.html == 302113-1.html 302113-1.html fails == 315146-1.xhtml 315146-1.xhtml @@ -21,7 +21,7 @@ fails == 338735-1.html 338735-1.html fails == 339388-1a.html 339388-1a.html fails == 339388-1b.html 339388-1b.html == 363326-1.html 363326-1.html -# == 368932-1.html 368932-1.html +== 368932-1.html 368932-1.html == 371054-1.html 371054-1.html fails == 372641-1a.xhtml 372641-1a.xhtml fails == 372641-1b.xhtml 372641-1b.xhtml @@ -47,8 +47,8 @@ fails == infer-table-around-headers-footers-3.html infer-table-around-headers-fo fails == infer-rows-inside-rowgroups.html infer-rows-inside-rowgroups.html fails == infer-table-row-cell.html infer-table-row-cell.html fails == infer-table.html infer-table.html -# == 3-tables-ref.html 3-tables-ref.html -# == 3-tables-ref.html 3-tables-ref.html +fails == 3-tables-ref.html 3-tables-ref.html # Bug 1341775 +fails == 3-tables-ref.html 3-tables-ref.html # Bug 1341775 fails == blocks-divide-tables-1.html blocks-divide-tables-1.html fails == blocks-divide-tables-2.html blocks-divide-tables-2.html fails == infer-cells-1.html infer-cells-1.html @@ -59,9 +59,9 @@ fails == cols-test-1.html cols-test-1.html fails == cols-test-2.html cols-test-2.html fails == cols-test-3.html cols-test-3.html fails == dynamic-abs-pos-tbody.html dynamic-abs-pos-tbody.html -# == dynamic-removal-1.html dynamic-removal-1.html -# == dynamic-removal-2.html dynamic-removal-2.html -# == dynamic-removal-3.html dynamic-removal-3.html +fails == dynamic-removal-1.html dynamic-removal-1.html # Bug 1341775 +fails == dynamic-removal-2.html dynamic-removal-2.html # Bug 1341775 +fails == dynamic-removal-3.html dynamic-removal-3.html # Bug 1341775 fails == dynamic-removal-4.html dynamic-removal-4.html fails == dynamic-removal-5.html dynamic-removal-5.html fails == dynamic-removal-6.html dynamic-removal-6.html @@ -88,7 +88,7 @@ fails == dynamic-switch-inline-to-cell-3.html dynamic-switch-inline-to-cell-3.ht fails == dynamic-switch-inline-to-cell-4.html dynamic-switch-inline-to-cell-4.html fails == dynamic-switch-inline-to-cell-5.html dynamic-switch-inline-to-cell-5.html fails == white-space-1.html white-space-1.html -# == white-space-2.html white-space-2.html +fails == white-space-2.html white-space-2.html # Bug 1341775 fails == white-space-3.html white-space-3.html fails == white-space-4.html white-space-4.html fails == white-space-5.html white-space-5.html diff --git a/layout/reftests/table-bordercollapse/reftest-stylo.list b/layout/reftests/table-bordercollapse/reftest-stylo.list index ec106a549ed1..23f6f52c6b59 100644 --- a/layout/reftests/table-bordercollapse/reftest-stylo.list +++ b/layout/reftests/table-bordercollapse/reftest-stylo.list @@ -96,7 +96,7 @@ fails == bordercolor-3.html bordercolor-3.html fails == bordercolor-4.html bordercolor-4.html == empty-toprow.html empty-toprow.html == double_borders.html double_borders.html -# == border-collapse-rtl.html border-collapse-rtl.html +== border-collapse-rtl.html border-collapse-rtl.html # Fuzzy because for some reason the corner beveling is antialiased differently. # So get 40 pixels of fuzz, 20 at each beveled corner (because the border width # is 20px). diff --git a/layout/reftests/table-dom/reftest-stylo.list b/layout/reftests/table-dom/reftest-stylo.list index 6d9104b811c7..a5afa82ed20c 100644 --- a/layout/reftests/table-dom/reftest-stylo.list +++ b/layout/reftests/table-dom/reftest-stylo.list @@ -21,10 +21,10 @@ fails == deleteRowsRebuild1a.html deleteRowsRebuild1a.html fails == deleteRowsShrink1.html deleteRowsShrink1.html fails == deleteTbodyExpand1.html deleteTbodyExpand1.html fails == deleteTbodyRebuild1.html deleteTbodyRebuild1.html -# == insertCaptionsAndRows1.html insertCaptionsAndRows1.html -# == insertCaptionsAndRows2.html insertCaptionsAndRows2.html -# == insertCaptionsAndRows3.html insertCaptionsAndRows3.html -# == insertCaptionsAndRows4.html insertCaptionsAndRows4.html +== insertCaptionsAndRows1.html insertCaptionsAndRows1.html +== insertCaptionsAndRows2.html insertCaptionsAndRows2.html +== insertCaptionsAndRows3.html insertCaptionsAndRows3.html +== insertCaptionsAndRows4.html insertCaptionsAndRows4.html fails == insertCellsExpand1.html insertCellsExpand1.html fails == insertCellsExpand2.html insertCellsExpand2.html fails == insertCellsExpandZeroRowspan.html insertCellsExpandZeroRowspan.html diff --git a/layout/reftests/table-width/reftest-stylo.list b/layout/reftests/table-width/reftest-stylo.list index 88ec03cdcdf4..3ae87d060345 100644 --- a/layout/reftests/table-width/reftest-stylo.list +++ b/layout/reftests/table-width/reftest-stylo.list @@ -3,7 +3,7 @@ fails == spacing-invariance-quirks-min.html spacing-invariance-quirks-min.html fails == spacing-invariance-quirks-pref.html spacing-invariance-quirks-pref.html fails == spacing-invariance-standards-min.html spacing-invariance-standards-min.html fails == spacing-invariance-standards-pref.html spacing-invariance-standards-pref.html -# == min-width.html min-width.html +== min-width.html min-width.html == pref-width.html pref-width.html == min-width-ref.html min-width-ref.html == percent-large.html percent-large.html @@ -38,7 +38,7 @@ fails == percent-small-nested.html percent-small-nested.html == percent-truncation-3.html percent-truncation-3.html fails == balancing-1.html balancing-1.html == balancing-2.html balancing-2.html -# == cellpadding.html cellpadding.html +fails == cellpadding.html cellpadding.html # Bug 1341648, bug 1341651 fails == cellspacing.html cellspacing.html fails == percent-basis.html percent-basis.html == default-box-sizing-separate-standards.html default-box-sizing-separate-standards.html diff --git a/layout/reftests/text-decoration/reftest-stylo.list b/layout/reftests/text-decoration/reftest-stylo.list index e8f54a0d6936..6d0f4a906891 100644 --- a/layout/reftests/text-decoration/reftest-stylo.list +++ b/layout/reftests/text-decoration/reftest-stylo.list @@ -69,24 +69,24 @@ fails == underline-style-inline-wavy-quirks.html underline-style-inline-wavy-qui == underline-style-inline-dashed-standards.html underline-style-inline-dashed-standards.html == underline-style-inline-double-standards.html underline-style-inline-double-standards.html == underline-style-inline-wavy-standards.html underline-style-inline-wavy-standards.html -# == underline-block-quirks.html underline-block-quirks.html -# == underline-block-quirks.html underline-block-quirks.html -# == underline-inline-block-quirks.html underline-inline-block-quirks.html -# == underline-inline-block-quirks.html underline-inline-block-quirks.html -# == underline-table-caption-quirks.html underline-table-caption-quirks.html -# == underline-table-caption-quirks.html underline-table-caption-quirks.html -# == underline-table-cell-quirks.html underline-table-cell-quirks.html -# == underline-table-cell-quirks.html underline-table-cell-quirks.html +== underline-block-quirks.html underline-block-quirks.html +== underline-block-quirks.html underline-block-quirks.html +fails == underline-inline-block-quirks.html underline-inline-block-quirks.html # Bug 1341781 +fails == underline-inline-block-quirks.html underline-inline-block-quirks.html # Bug 1341781 +fails == underline-table-caption-quirks.html underline-table-caption-quirks.html # Bug 1341781 +fails == underline-table-caption-quirks.html underline-table-caption-quirks.html # Bug 1341781 +fails == underline-table-cell-quirks.html underline-table-cell-quirks.html # Bug 1341781 +fails == underline-table-cell-quirks.html underline-table-cell-quirks.html # Bug 1341781 == underline-block-propagation-quirks.html underline-block-propagation-quirks.html fails == underline-block-propagation-2-quirks.html underline-block-propagation-2-quirks.html -# == underline-block-standards.html underline-block-standards.html -# == underline-block-standards.html underline-block-standards.html -# == underline-inline-block-standards.html underline-inline-block-standards.html -# == underline-inline-block-standards.html underline-inline-block-standards.html -# == underline-table-caption-standards.html underline-table-caption-standards.html -# == underline-table-caption-standards.html underline-table-caption-standards.html -# == underline-table-cell-standards.html underline-table-cell-standards.html -# == underline-table-cell-standards.html underline-table-cell-standards.html +== underline-block-standards.html underline-block-standards.html +== underline-block-standards.html underline-block-standards.html +== underline-inline-block-standards.html underline-inline-block-standards.html +== underline-inline-block-standards.html underline-inline-block-standards.html +fails == underline-table-caption-standards.html underline-table-caption-standards.html # Bug 1341651 +fails == underline-table-caption-standards.html underline-table-caption-standards.html # Bug 1341651 +fails == underline-table-cell-standards.html underline-table-cell-standards.html # Bug 1341651 +fails == underline-table-cell-standards.html underline-table-cell-standards.html # Bug 1341651 == underline-block-propagation-standards.html underline-block-propagation-standards.html fails == underline-block-propagation-2-standards.html underline-block-propagation-2-standards.html == text-decoration-zorder-1-standards.html text-decoration-zorder-1-standards.html diff --git a/layout/reftests/text-indent/reftest-stylo.list b/layout/reftests/text-indent/reftest-stylo.list index 43da5dfee422..903ba2564a03 100644 --- a/layout/reftests/text-indent/reftest-stylo.list +++ b/layout/reftests/text-indent/reftest-stylo.list @@ -4,15 +4,15 @@ # Also need to test intrinsic widths (bug 368155). -# == text-indent-single-line-100.html text-indent-single-line-100.html -# == text-indent-single-line-100.html text-indent-single-line-100.html +== text-indent-single-line-100.html text-indent-single-line-100.html +== text-indent-single-line-100.html text-indent-single-line-100.html == text-indent-single-line-0.html text-indent-single-line-0.html == text-indent-single-line-percent.html text-indent-single-line-percent.html -# == text-indent-single-line-indent-inline.html text-indent-single-line-indent-inline.html -# == text-indent-single-line-indent-inline.html text-indent-single-line-indent-inline.html -# == text-indent-multiple-line.html text-indent-multiple-line.html -# == text-indent-multiple-line.html text-indent-multiple-line.html -# == text-indent-multiple-line.html text-indent-multiple-line.html +== text-indent-single-line-indent-inline.html text-indent-single-line-indent-inline.html +== text-indent-single-line-indent-inline.html text-indent-single-line-indent-inline.html +== text-indent-multiple-line.html text-indent-multiple-line.html +== text-indent-multiple-line.html text-indent-multiple-line.html +== text-indent-multiple-line.html text-indent-multiple-line.html == text-indent-intrinsic-pref.html text-indent-intrinsic-pref.html == text-indent-intrinsic-min.html text-indent-intrinsic-min.html == text-indent-negative-intrinsic-pref.html text-indent-negative-intrinsic-pref.html diff --git a/layout/reftests/text-overflow/reftest-stylo.list b/layout/reftests/text-overflow/reftest-stylo.list index b4a4cb7aa37e..b0caa0635007 100644 --- a/layout/reftests/text-overflow/reftest-stylo.list +++ b/layout/reftests/text-overflow/reftest-stylo.list @@ -3,13 +3,13 @@ fails == ellipsis-font-fallback.html ellipsis-font-fallback.html fails == line-clipping.html line-clipping.html fails == marker-basic.html marker-basic.html fails HTTP(..) == marker-string.html marker-string.html -# == bidi-simple.html bidi-simple.html +fails == bidi-simple.html bidi-simple.html # Bug 1321769? fails == bidi-simple-scrolled.html bidi-simple-scrolled.html fails == scroll-rounding.html scroll-rounding.html fuzzy(2,453) fuzzy-if(skiaContent,9,2100) fails-if(gtkWidget) HTTP(..) == anonymous-block.html anonymous-block.html fails HTTP(..) == false-marker-overlap.html false-marker-overlap.html fails HTTP(..) == visibility-hidden.html visibility-hidden.html -# == block-padding.html block-padding.html +fails == block-padding.html block-padding.html # Bug 1321769? fails HTTP(..) == quirks-decorations.html quirks-decorations.html fails HTTP(..) == quirks-line-height.html quirks-line-height.html fails HTTP(..) == standards-decorations.html standards-decorations.html @@ -27,11 +27,11 @@ fuzzy(1,2616) skip-if(Android) fuzzy-if(asyncPan&&!layersGPUAccelerated,102,1235 fails HTTP(..) == combobox-zoom.html combobox-zoom.html # The vertical-text pref setting can be removed after bug 1138384 lands -# == vertical-decorations-1.html vertical-decorations-1.html -# == vertical-decorations-2.html vertical-decorations-2.html -# == vertical-decorations-1.html vertical-decorations-1.html -# == vertical-decorations-2.html vertical-decorations-2.html -# == vertical-decorations-3.html vertical-decorations-3.html -# == vertical-decorations-4.html vertical-decorations-4.html -# == vertical-decorations-3.html vertical-decorations-3.html -# == vertical-decorations-4.html vertical-decorations-4.html +fails == vertical-decorations-1.html vertical-decorations-1.html # Bug 1341724 +fails == vertical-decorations-2.html vertical-decorations-2.html # Bug 1341724 +fails == vertical-decorations-1.html vertical-decorations-1.html # Bug 1341724 +fails == vertical-decorations-2.html vertical-decorations-2.html # Bug 1341724 +== vertical-decorations-3.html vertical-decorations-3.html +== vertical-decorations-4.html vertical-decorations-4.html +== vertical-decorations-3.html vertical-decorations-3.html +== vertical-decorations-4.html vertical-decorations-4.html diff --git a/layout/reftests/text-shadow/reftest-stylo.list b/layout/reftests/text-shadow/reftest-stylo.list index dedfbfaff156..c3f25f0e1657 100644 --- a/layout/reftests/text-shadow/reftest-stylo.list +++ b/layout/reftests/text-shadow/reftest-stylo.list @@ -12,7 +12,7 @@ fails HTTP(..) == blur-opacity.html blur-opacity.html == basic-negcoord.html basic-negcoord.html == basic-opacity.html basic-opacity.html == blur.html blur.html -# == color-inherit.html color-inherit.html +== color-inherit.html color-inherit.html == color-parserorder.html color-parserorder.html == decorations-multiple-zorder.html decorations-multiple-zorder.html == multiple-noblur.html multiple-noblur.html @@ -22,8 +22,8 @@ fails HTTP(..) == blur-opacity.html blur-opacity.html == textindent.html textindent.html == lineoverflow.html lineoverflow.html -# == overflow-not-scrollable-1.html overflow-not-scrollable-1.html -# == overflow-not-scrollable-1.html overflow-not-scrollable-1.html +== overflow-not-scrollable-1.html overflow-not-scrollable-1.html +== overflow-not-scrollable-1.html overflow-not-scrollable-1.html == overflow-not-scrollable-2.html overflow-not-scrollable-2.html needs-focus == text-shadow-selected-1.html text-shadow-selected-1.html diff --git a/layout/reftests/text/reftest-stylo.list b/layout/reftests/text/reftest-stylo.list index f55128b2cb6c..5d4c32190f3e 100644 --- a/layout/reftests/text/reftest-stylo.list +++ b/layout/reftests/text/reftest-stylo.list @@ -11,7 +11,7 @@ fails HTTP(..) == font-selection-generic-1.html font-selection-generic-1.html # This currently fails because line spacing does not respect font-size-adjust # in the "obvious" way, but it is unclear what the behavior should really be; # see bug -# == font-size-adjust-03.html font-size-adjust-03.html +== font-size-adjust-03.html font-size-adjust-03.html fails == justification-1.html justification-1.html == justification-2a.html justification-2a.html == justification-2b.html justification-2b.html @@ -68,7 +68,7 @@ HTTP(..) == synthetic-bold-papyrus-01.html synthetic-bold-papyrus-01.html == text-align-last-end.html text-align-last-end.html == text-align-last-center.html text-align-last-center.html == text-align-last-justify.html text-align-last-justify.html -# == text-align-last-justify-rtl.html text-align-last-justify-rtl.html +== text-align-last-justify-rtl.html text-align-last-justify-rtl.html # # Default values: # text-align defaults to start. text-align-last defaults to auto, which is @@ -83,35 +83,35 @@ HTTP(..) == synthetic-bold-papyrus-01.html synthetic-bold-papyrus-01.html # All combinations of text-align and text-align-last should give different results # This only tests the combinations with the same value for text-align and # different values for text-align-last -# == text-align-start-last-start.html text-align-start-last-start.html -# == text-align-start-last-start.html text-align-start-last-start.html -# == text-align-start-last-start.html text-align-start-last-start.html -# == text-align-start-last-end.html text-align-start-last-end.html -# == text-align-start-last-end.html text-align-start-last-end.html +== text-align-start-last-start.html text-align-start-last-start.html +== text-align-start-last-start.html text-align-start-last-start.html +== text-align-start-last-start.html text-align-start-last-start.html +== text-align-start-last-end.html text-align-start-last-end.html +== text-align-start-last-end.html text-align-start-last-end.html == text-align-start-last-center.html text-align-start-last-center.html -# == text-align-end-last-start.html text-align-end-last-start.html -# == text-align-end-last-start.html text-align-end-last-start.html -# == text-align-end-last-start.html text-align-end-last-start.html -# == text-align-end-last-end.html text-align-end-last-end.html -# == text-align-end-last-end.html text-align-end-last-end.html +== text-align-end-last-start.html text-align-end-last-start.html +== text-align-end-last-start.html text-align-end-last-start.html +== text-align-end-last-start.html text-align-end-last-start.html +== text-align-end-last-end.html text-align-end-last-end.html +== text-align-end-last-end.html text-align-end-last-end.html == text-align-end-last-center.html text-align-end-last-center.html -# == text-align-center-last-start.html text-align-center-last-start.html -# == text-align-center-last-start.html text-align-center-last-start.html -# == text-align-center-last-start.html text-align-center-last-start.html -# == text-align-center-last-end.html text-align-center-last-end.html -# == text-align-center-last-end.html text-align-center-last-end.html +== text-align-center-last-start.html text-align-center-last-start.html +== text-align-center-last-start.html text-align-center-last-start.html +== text-align-center-last-start.html text-align-center-last-start.html +== text-align-center-last-end.html text-align-center-last-end.html +== text-align-center-last-end.html text-align-center-last-end.html == text-align-center-last-center.html text-align-center-last-center.html -# == text-align-justify-last-start.html text-align-justify-last-start.html -# == text-align-justify-last-start.html text-align-justify-last-start.html -# == text-align-justify-last-start.html text-align-justify-last-start.html -# == text-align-justify-last-end.html text-align-justify-last-end.html -# == text-align-justify-last-end.html text-align-justify-last-end.html +== text-align-justify-last-start.html text-align-justify-last-start.html +== text-align-justify-last-start.html text-align-justify-last-start.html +== text-align-justify-last-start.html text-align-justify-last-start.html +== text-align-justify-last-end.html text-align-justify-last-end.html +== text-align-justify-last-end.html text-align-justify-last-end.html == text-align-justify-last-center.html text-align-justify-last-center.html == text-align-left-in-rtl-block.html text-align-left-in-rtl-block.html fails HTTP(..) == variation-selector-unsupported-1.html variation-selector-unsupported-1.html == white-space-1a.html white-space-1a.html == white-space-1b.html white-space-1b.html -# == white-space-2.html white-space-2.html +== white-space-2.html white-space-2.html == wordbreak-1.html wordbreak-1.html == wordbreak-2.html wordbreak-2.html == wordbreak-3.html wordbreak-3.html @@ -135,12 +135,12 @@ fails == wordwrap-06.html wordwrap-06.html fails == overflowwrap-06.html overflowwrap-06.html == wordwrap-07.html wordwrap-07.html == overflowwrap-07.html overflowwrap-07.html -# == wordwrap-08.html wordwrap-08.html -# == wordwrap-08.html wordwrap-08.html -# == wordwrap-09.html wordwrap-09.html -# == overflowwrap-09.html overflowwrap-09.html -# == wordwrap-09.html wordwrap-09.html -# == overflowwrap-09.html overflowwrap-09.html +fails == wordwrap-08.html wordwrap-08.html # Bug 1341637, bug 1321769? +fails == wordwrap-08.html wordwrap-08.html # Bug 1341637, bug 1321769? +fails == wordwrap-09.html wordwrap-09.html # Bug 1341637, bug 1321769? +fails == overflowwrap-09.html overflowwrap-09.html # Bug 1341637, bug 1321769? +fails == wordwrap-09.html wordwrap-09.html # Bug 1341637, bug 1321769? +fails == overflowwrap-09.html overflowwrap-09.html # Bug 1341637, bug 1321769? == wordwrap-10.html wordwrap-10.html == overflowwrap-10.html overflowwrap-10.html fails == word-spacing-01.html word-spacing-01.html @@ -193,11 +193,11 @@ fails HTTP(..) == 1170688.html 1170688.html == emoji-02.html emoji-02.html # Bug 727276: tests with variation selectors 15 and 16 to control emoji rendering style -# == emoji-03.html emoji-03.html +== emoji-03.html emoji-03.html # the next two will fail on OS X 10.6 because no color emoji font is present, # and also on Android platforms until we have color emoji fonts there. # Tests rely on bundled EmojiOne Mozilla to pass on Windows <8.1 and Linux. -# == emoji-03.html emoji-03.html +== emoji-03.html emoji-03.html fails-if(OSX==1006||Android) == emoji-04.html emoji-04.html == emoji-05.html emoji-05.html @@ -242,8 +242,8 @@ fails HTTP(..) == graphite-bidi-1.html graphite-bidi-1.html fails HTTP(..) == graphite-surrogate-selection.html graphite-surrogate-selection.html # Tests for hyphenation with hyphens property -# == auto-hyphenation-1.html auto-hyphenation-1.html -# == auto-hyphenation-1.html auto-hyphenation-1.html +== auto-hyphenation-1.html auto-hyphenation-1.html +== auto-hyphenation-1.html auto-hyphenation-1.html == auto-hyphenation-1a.html auto-hyphenation-1a.html == auto-hyphenation-2.html auto-hyphenation-2.html == auto-hyphenation-3.html auto-hyphenation-3.html @@ -254,8 +254,8 @@ fails == auto-hyphenation-5.html auto-hyphenation-5.html == auto-hyphenation-8.html auto-hyphenation-8.html == auto-hyphenation-9.html auto-hyphenation-9.html == auto-hyphenation-10.html auto-hyphenation-10.html -# == auto-hyphenation-xmllang-1.xhtml auto-hyphenation-xmllang-1.xhtml -# == auto-hyphenation-xmllang-1.xhtml auto-hyphenation-xmllang-1.xhtml +fails == auto-hyphenation-xmllang-1.xhtml auto-hyphenation-xmllang-1.xhtml # Bug 1341714 +fails == auto-hyphenation-xmllang-1.xhtml auto-hyphenation-xmllang-1.xhtml # Bug 1341714 fails == auto-hyphenation-xmllang-1a.xhtml auto-hyphenation-xmllang-1a.xhtml fails == auto-hyphenation-xmllang-2.xhtml auto-hyphenation-xmllang-2.xhtml == auto-hyphenation-xmllang-3.xhtml auto-hyphenation-xmllang-3.xhtml @@ -279,9 +279,9 @@ fails == auto-hyphenation-xmllang-14a.xhtml auto-hyphenation-xmllang-14a.xhtml == auto-hyphenation-ca-1.html auto-hyphenation-ca-1.html == auto-hyphenation-cy-1.html auto-hyphenation-cy-1.html == auto-hyphenation-da-1.html auto-hyphenation-da-1.html -# == auto-hyphenation-de-1901-1.html auto-hyphenation-de-1901-1.html +== auto-hyphenation-de-1901-1.html auto-hyphenation-de-1901-1.html == auto-hyphenation-de-1996-1.html auto-hyphenation-de-1996-1.html -# == auto-hyphenation-de-1901-1.html auto-hyphenation-de-1901-1.html +== auto-hyphenation-de-1901-1.html auto-hyphenation-de-1901-1.html == auto-hyphenation-de-ch-1.html auto-hyphenation-de-ch-1.html == auto-hyphenation-eo-1.html auto-hyphenation-eo-1.html == auto-hyphenation-es-1.html auto-hyphenation-es-1.html @@ -308,8 +308,8 @@ fails == auto-hyphenation-pl-1.html auto-hyphenation-pl-1.html == auto-hyphenation-sh-1.html auto-hyphenation-sh-1.html == auto-hyphenation-sl-1.html auto-hyphenation-sl-1.html == auto-hyphenation-sr-1.html auto-hyphenation-sr-1.html -# == auto-hyphenation-sv-1.html auto-hyphenation-sv-1.html -# == auto-hyphenation-sv-1.html auto-hyphenation-sv-1.html +== auto-hyphenation-sv-1.html auto-hyphenation-sv-1.html +== auto-hyphenation-sv-1.html auto-hyphenation-sv-1.html == auto-hyphenation-tr-1.html auto-hyphenation-tr-1.html == auto-hyphenation-uk-1.html auto-hyphenation-uk-1.html diff --git a/layout/reftests/transform-3d/reftest-stylo.list b/layout/reftests/transform-3d/reftest-stylo.list index f1847af46dcc..259346123948 100644 --- a/layout/reftests/transform-3d/reftest-stylo.list +++ b/layout/reftests/transform-3d/reftest-stylo.list @@ -1,5 +1,5 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing -# == scalez-1a.html scalez-1a.html +fails == scalez-1a.html scalez-1a.html fails == rotatey-1a.html rotatey-1a.html fails == rotatex-1a.html rotatex-1a.html # Check that scaleZ(-1) rotateX(180deg) is the same as rotateY(180deg) @@ -11,7 +11,7 @@ fails == rotatex-perspective-1b.html rotatex-perspective-1b.html # -moz-perspective should only apply to child elements fails == rotatex-perspective-1c.html rotatex-perspective-1c.html fails == rotatex-perspective-3a.html rotatex-perspective-3a.html -# == scalez-1a.html scalez-1a.html +fails == scalez-1a.html scalez-1a.html fails == preserve3d-1a.html preserve3d-1a.html fails == preserve3d-1b.html preserve3d-1b.html fails == preserve3d-clipped.html preserve3d-clipped.html @@ -43,10 +43,10 @@ fails == perspective-clipping-1.html perspective-clipping-1.html fails == perspective-origin-1a.html perspective-origin-1a.html fails == perspective-origin-1b.html perspective-origin-1b.html fails == perspective-origin-2a.html perspective-origin-2a.html -# == perspective-origin-3a.html perspective-origin-3a.html +== perspective-origin-3a.html perspective-origin-3a.html fails == perspective-origin-4a.html perspective-origin-4a.html == perspective-zindex.html perspective-zindex.html -# == perspective-zindex-2.html perspective-zindex-2.html +== perspective-zindex-2.html perspective-zindex-2.html fails == sorting-1a.html sorting-1a.html # Parallel planes, different z depth fails == sorting-2a.html sorting-2a.html @@ -57,11 +57,11 @@ fails == sorting-3a.html sorting-3a.html fails == rotatex-transformorigin-1a.html rotatex-transformorigin-1a.html fails == overflow-hidden-1a.html overflow-hidden-1a.html fails == transform-style-flat-1a.html transform-style-flat-1a.html -# == willchange-containing-block.html?willchange willchange-containing-block.html?willchange -# == willchange-containing-block.html?willchange willchange-containing-block.html?willchange +fails == willchange-containing-block.html?willchange willchange-containing-block.html?willchange +fails == willchange-containing-block.html?willchange willchange-containing-block.html?willchange fails == scroll-perspective-1.html scroll-perspective-1.html # Bugs -# == 1035611-1.html 1035611-1.html +== 1035611-1.html 1035611-1.html == 1157984-1.html 1157984-1.html fails == animate-cube-radians.html animate-cube-radians.html fails == animate-cube-radians-zoom.html animate-cube-radians-zoom.html @@ -70,15 +70,15 @@ fails == animate-cube-degrees.html animate-cube-degrees.html fails == animate-cube-degrees-zoom.html animate-cube-degrees-zoom.html fails == animate-cube-degrees-ref.html animate-cube-degrees-ref.html fuzzy-if(gtkWidget,128,100) fuzzy-if(Android||OSX==1010||(gtkWidget&&layersGPUAccelerated),143,100) fuzzy-if(winWidget||OSX<1010,141,100) == preserves3d-nested.html preserves3d-nested.html -# == animate-preserve3d-parent.html animate-preserve3d-parent.html -# == animate-preserve3d-child.html animate-preserve3d-child.html -# == animate-backface-hidden.html animate-backface-hidden.html -# == 1245450-1.html 1245450-1.html -# == opacity-preserve3d-1.html opacity-preserve3d-1.html -# == opacity-preserve3d-2.html opacity-preserve3d-2.html -# == opacity-preserve3d-3.html opacity-preserve3d-3.html -# == opacity-preserve3d-4.html opacity-preserve3d-4.html +== animate-preserve3d-parent.html animate-preserve3d-parent.html +== animate-preserve3d-child.html animate-preserve3d-child.html +== animate-backface-hidden.html animate-backface-hidden.html +== 1245450-1.html 1245450-1.html +== opacity-preserve3d-1.html opacity-preserve3d-1.html +== opacity-preserve3d-2.html opacity-preserve3d-2.html +== opacity-preserve3d-3.html opacity-preserve3d-3.html +== opacity-preserve3d-4.html opacity-preserve3d-4.html == snap-perspective-1.html snap-perspective-1.html -# == mask-layer-1.html mask-layer-1.html -# == mask-layer-2.html mask-layer-2.html -# == mask-layer-3.html mask-layer-3.html +== mask-layer-1.html mask-layer-1.html +== mask-layer-2.html mask-layer-2.html +== mask-layer-3.html mask-layer-3.html diff --git a/layout/reftests/transform/reftest-stylo.list b/layout/reftests/transform/reftest-stylo.list index 143abb2bc56f..0bd7f28c4fce 100644 --- a/layout/reftests/transform/reftest-stylo.list +++ b/layout/reftests/transform/reftest-stylo.list @@ -4,20 +4,20 @@ # this test. fails == singular-1a.html singular-1a.html # Multiple transforms should act identically to nested divs. -# == compound-1a.html compound-1a.html -# == compound-1a.html compound-1a.html -# == dynamic-inherit-1.html dynamic-inherit-1.html +fails == compound-1a.html compound-1a.html # Bug 1341785 +fails == compound-1a.html compound-1a.html # Bug 1341785 +fails == dynamic-inherit-1.html dynamic-inherit-1.html # Bug 1341785 == dynamic-addremove-1a.html dynamic-addremove-1a.html == dynamic-addremove-1b.html dynamic-addremove-1b.html == dynamic-addremove-1c.html dynamic-addremove-1c.html == dynamic-addremove-2.html dynamic-addremove-2.html # translatex should act like position: relative -# == translatex-1a.html translatex-1a.html +fails == translatex-1a.html translatex-1a.html # Bug 1341785 fails == translatex-1b.html translatex-1b.html fails == translatex-1c.html translatex-1c.html fails == translatex-1d.html translatex-1d.html fails == translatex-1e.html translatex-1e.html -# == translatex-1a.html translatex-1a.html +fails == translatex-1a.html translatex-1a.html # Bug 1341785 # translatey should act like position: relative fails == translatey-1a.html translatey-1a.html fails == translatey-1b.html translatey-1b.html @@ -84,9 +84,9 @@ fails == origin-name-3b.html origin-name-3b.html # Snapping still applies after 90 degree rotations. == snapping-1.html snapping-1.html # SVG effects should work on transforms. -# == transform-svg-1a.xhtml transform-svg-1a.xhtml -# == transform-svg-2a.xhtml transform-svg-2a.xhtml -# == transform-svg-2a.xhtml transform-svg-2a.xhtml +fails == transform-svg-1a.xhtml transform-svg-1a.xhtml +fails == transform-svg-2a.xhtml transform-svg-2a.xhtml +fails == transform-svg-2a.xhtml transform-svg-2a.xhtml # skew should allow a mix of one and two parameters. fails == skew-1a.html skew-1a.html fails == skew-1b.html skew-1b.html @@ -113,7 +113,7 @@ fails == scale-1b.html scale-1b.html fails == descendant-1.html descendant-1.html fails == propagate-inherit-boolean.html propagate-inherit-boolean.html # Ensure you can't move outside an iframe -# == iframe-1.html iframe-1.html +fails == iframe-1.html iframe-1.html # Bugs fails == 601894-1.html 601894-1.html fails == 601894-2.html 601894-2.html @@ -136,8 +136,8 @@ pref(svg.transform-box.enabled,true) == transform-box-svg-2b.svg transform-box-s == transform-origin-svg-2b.svg transform-origin-svg-2b.svg # Bug 1122526 skip-if(stylo) == animate-layer-scale-inherit-1.html animate-layer-scale-inherit-1.html # bug 1324620 -# == animate-layer-scale-inherit-2.html animate-layer-scale-inherit-2.html -# == animate-layer-scale-inherit-3.html animate-layer-scale-inherit-3.html +skip-if(stylo) == animate-layer-scale-inherit-2.html animate-layer-scale-inherit-2.html # Too intermittent. +== animate-layer-scale-inherit-3.html animate-layer-scale-inherit-3.html # Bug 1301500 == dynamic-add-without-change-cb-1.html dynamic-add-without-change-cb-1.html -# == table-overflowed-by-animation.html table-overflowed-by-animation.html +skip-if(stylo) == table-overflowed-by-animation.html table-overflowed-by-animation.html diff --git a/layout/reftests/unicode/reftest-stylo.list b/layout/reftests/unicode/reftest-stylo.list index d9e6767b34ba..b0ab3b27835a 100644 --- a/layout/reftests/unicode/reftest-stylo.list +++ b/layout/reftests/unicode/reftest-stylo.list @@ -2,7 +2,7 @@ fails == unicode-attribute-selector.html unicode-attribute-selector.html fails == unicode-element-selector.html unicode-element-selector.html fails == unicode-lang.html unicode-lang.html -# == unicode-media-query-media-type.html unicode-media-query-media-type.html -# == unicode-media-query-query.html unicode-media-query-query.html +== unicode-media-query-media-type.html unicode-media-query-media-type.html +== unicode-media-query-query.html unicode-media-query-query.html fails == unicode-pseudo-selector.html unicode-pseudo-selector.html fails == langattribute.html langattribute.html diff --git a/layout/reftests/view-source/reftest-stylo.list b/layout/reftests/view-source/reftest-stylo.list index 6c2232a9fe3b..7b4a3255e4a7 100644 --- a/layout/reftests/view-source/reftest-stylo.list +++ b/layout/reftests/view-source/reftest-stylo.list @@ -1,2 +1,2 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing -# == view-source-image.html view-source-image.html +== view-source-image.html view-source-image.html diff --git a/layout/reftests/w3c-css/received/reftest-stylo.list b/layout/reftests/w3c-css/received/reftest-stylo.list index c44ff9748e9b..19644d6b9e42 100644 --- a/layout/reftests/w3c-css/received/reftest-stylo.list +++ b/layout/reftests/w3c-css/received/reftest-stylo.list @@ -230,9 +230,9 @@ fails == css-values-3/vh-calc-support-pct.html css-values-3/vh-calc-support-pct. fails == css-values-3/vh-calc-support.html css-values-3/vh-calc-support.html fails == css-values-3/vh-em-inherit.html css-values-3/vh-em-inherit.html fails == css-values-3/vh-inherit.html css-values-3/vh-inherit.html -# == css-values-3/vh-interpolate-pct.html css-values-3/vh-interpolate-pct.html -# == css-values-3/vh-interpolate-px.html css-values-3/vh-interpolate-px.html -# == css-values-3/vh-interpolate-vh.html css-values-3/vh-interpolate-vh.html +fails == css-values-3/vh-interpolate-pct.html css-values-3/vh-interpolate-pct.html +fails == css-values-3/vh-interpolate-px.html css-values-3/vh-interpolate-px.html +fails == css-values-3/vh-interpolate-vh.html css-values-3/vh-interpolate-vh.html fails == css-values-3/vh-support-atviewport.html css-values-3/vh-support-atviewport.html == css-values-3/vh-support-margin.html css-values-3/vh-support-margin.html == css-values-3/vh-support-transform-origin.html css-values-3/vh-support-transform-origin.html @@ -240,7 +240,7 @@ fails == css-values-3/vh-support-atviewport.html css-values-3/vh-support-atviewp fails == css-values-3/vh-support.html css-values-3/vh-support.html == css-values-3/vh-zero-support.html css-values-3/vh-zero-support.html fails == css-values-3/vh_not_refreshing_on_chrome.html css-values-3/vh_not_refreshing_on_chrome.html -# == css-values-3/vh_not_refreshing_on_chrome_iframe.html css-values-3/vh_not_refreshing_on_chrome_iframe.html +skip-if(stylo) == css-values-3/vh_not_refreshing_on_chrome_iframe.html css-values-3/vh_not_refreshing_on_chrome_iframe.html # Why does this fail to load? fails needs-focus == selectors-4/focus-within-001.html selectors-4/focus-within-001.html fails needs-focus == selectors-4/focus-within-002.html selectors-4/focus-within-002.html fails needs-focus == selectors-4/focus-within-003.html selectors-4/focus-within-003.html diff --git a/layout/reftests/w3c-css/submitted/images3/reftest-stylo.list b/layout/reftests/w3c-css/submitted/images3/reftest-stylo.list index 01131d99f048..1aeccc4f644f 100644 --- a/layout/reftests/w3c-css/submitted/images3/reftest-stylo.list +++ b/layout/reftests/w3c-css/submitted/images3/reftest-stylo.list @@ -32,24 +32,24 @@ fails == object-fit-cover-png-002i.html object-fit-cover-png-002i.html # fails == object-fit-cover-png-002o.html object-fit-cover-png-002o.html fails == object-fit-cover-png-002p.html object-fit-cover-png-002p.html == object-fit-none-png-001c.html object-fit-none-png-001c.html -# == object-fit-none-png-001e.html object-fit-none-png-001e.html +skip-if(stylo) == object-fit-none-png-001e.html object-fit-none-png-001e.html # Too intermittent. == object-fit-none-png-001i.html object-fit-none-png-001i.html -# == object-fit-none-png-001o.html object-fit-none-png-001o.html +skip-if(stylo) == object-fit-none-png-001o.html object-fit-none-png-001o.html # Too intermittent. fails == object-fit-none-png-001p.html object-fit-none-png-001p.html == object-fit-none-png-002c.html object-fit-none-png-002c.html -# == object-fit-none-png-002e.html object-fit-none-png-002e.html +skip-if(stylo) == object-fit-none-png-002e.html object-fit-none-png-002e.html # Too intermittent. == object-fit-none-png-002i.html object-fit-none-png-002i.html -# == object-fit-none-png-002o.html object-fit-none-png-002o.html +skip-if(stylo) == object-fit-none-png-002o.html object-fit-none-png-002o.html # Too intermittent. fails == object-fit-none-png-002p.html object-fit-none-png-002p.html == object-fit-scale-down-png-001c.html object-fit-scale-down-png-001c.html -# == object-fit-scale-down-png-001e.html object-fit-scale-down-png-001e.html +skip-if(stylo) == object-fit-scale-down-png-001e.html object-fit-scale-down-png-001e.html # Too intermittent. == object-fit-scale-down-png-001i.html object-fit-scale-down-png-001i.html -# == object-fit-scale-down-png-001o.html object-fit-scale-down-png-001o.html +== object-fit-scale-down-png-001o.html object-fit-scale-down-png-001o.html fails == object-fit-scale-down-png-001p.html object-fit-scale-down-png-001p.html == object-fit-scale-down-png-002c.html object-fit-scale-down-png-002c.html -# == object-fit-scale-down-png-002e.html object-fit-scale-down-png-002e.html +skip-if(stylo) == object-fit-scale-down-png-002e.html object-fit-scale-down-png-002e.html # Too intermittent. == object-fit-scale-down-png-002i.html object-fit-scale-down-png-002i.html -# == object-fit-scale-down-png-002o.html object-fit-scale-down-png-002o.html +skip-if(stylo) == object-fit-scale-down-png-002o.html object-fit-scale-down-png-002o.html # Too intermittent. fails == object-fit-scale-down-png-002p.html object-fit-scale-down-png-002p.html # Tests for 'object-fit' / 'object-position' with an SVG image @@ -163,7 +163,7 @@ fails == object-fit-scale-down-svg-002p.html object-fit-scale-down-svg-002p.html fails == object-fit-scale-down-svg-003p.html object-fit-scale-down-svg-003p.html == object-fit-scale-down-svg-004e.html object-fit-scale-down-svg-004e.html == object-fit-scale-down-svg-004i.html object-fit-scale-down-svg-004i.html -# == object-fit-scale-down-svg-004o.html object-fit-scale-down-svg-004o.html +== object-fit-scale-down-svg-004o.html object-fit-scale-down-svg-004o.html fails == object-fit-scale-down-svg-004p.html object-fit-scale-down-svg-004p.html == object-fit-scale-down-svg-005e.html object-fit-scale-down-svg-005e.html == object-fit-scale-down-svg-005i.html object-fit-scale-down-svg-005i.html diff --git a/layout/reftests/w3c-css/submitted/masking/reftest-stylo.list b/layout/reftests/w3c-css/submitted/masking/reftest-stylo.list index c1bfc23e36c6..677ae5e874e5 100644 --- a/layout/reftests/w3c-css/submitted/masking/reftest-stylo.list +++ b/layout/reftests/w3c-css/submitted/masking/reftest-stylo.list @@ -68,7 +68,7 @@ fails == mask-size-auto-auto.html mask-size-auto-auto.html fails == mask-size-auto-length.html mask-size-auto-length.html fails == mask-size-auto-percent.html mask-size-auto-percent.html fails == mask-size-contain-clip-border.html mask-size-contain-clip-border.html -# == mask-size-contain-clip-padding.html mask-size-contain-clip-padding.html +fails == mask-size-contain-clip-padding.html mask-size-contain-clip-padding.html fails == mask-size-contain-position-fifty-fifty.html mask-size-contain-position-fifty-fifty.html fails == mask-size-contain.html mask-size-contain.html fails == mask-size-cover.html mask-size-cover.html diff --git a/layout/reftests/w3c-css/submitted/ruby/reftest-stylo.list b/layout/reftests/w3c-css/submitted/ruby/reftest-stylo.list index 90bfc908abf2..84104276521a 100644 --- a/layout/reftests/w3c-css/submitted/ruby/reftest-stylo.list +++ b/layout/reftests/w3c-css/submitted/ruby/reftest-stylo.list @@ -1,10 +1,10 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing # Tests for inlinizing block-level boxes -# == ruby-inlinize-blocks-001.html ruby-inlinize-blocks-001.html +skip-if(stylo) == ruby-inlinize-blocks-001.html ruby-inlinize-blocks-001.html # Bug 1323716 fails == ruby-inlinize-blocks-002.html ruby-inlinize-blocks-002.html == ruby-inlinize-blocks-003.html ruby-inlinize-blocks-003.html -# == ruby-inlinize-blocks-004.html ruby-inlinize-blocks-004.html -# == ruby-inlinize-blocks-005.html ruby-inlinize-blocks-005.html +skip-if(stylo) == ruby-inlinize-blocks-004.html ruby-inlinize-blocks-004.html # Bug 1323716 +skip-if(stylo) == ruby-inlinize-blocks-005.html ruby-inlinize-blocks-005.html # Bug 1323716 # Tests for autohiding base-identical annotations == ruby-autohide-001.html ruby-autohide-001.html diff --git a/layout/reftests/w3c-css/submitted/text3/reftest-stylo.list b/layout/reftests/w3c-css/submitted/text3/reftest-stylo.list index d08d37b15f84..96d4b930d357 100644 --- a/layout/reftests/w3c-css/submitted/text3/reftest-stylo.list +++ b/layout/reftests/w3c-css/submitted/text3/reftest-stylo.list @@ -3,7 +3,7 @@ fails == text-align-match-parent-01.html text-align-match-parent-01.html fails == text-align-match-parent-02.html text-align-match-parent-02.html fails == text-align-match-parent-03.html text-align-match-parent-03.html fails == text-align-match-parent-04.html text-align-match-parent-04.html -# == text-align-match-parent-root-ltr.html text-align-match-parent-root-ltr.html -# == text-align-match-parent-root-rtl.html text-align-match-parent-root-rtl.html +== text-align-match-parent-root-ltr.html text-align-match-parent-root-ltr.html +== text-align-match-parent-root-rtl.html text-align-match-parent-root-rtl.html fails == text-word-spacing-001.html text-word-spacing-001.html diff --git a/layout/reftests/w3c-css/submitted/transforms/reftest-stylo.list b/layout/reftests/w3c-css/submitted/transforms/reftest-stylo.list index 1a00079b529e..6ab706d2fa70 100644 --- a/layout/reftests/w3c-css/submitted/transforms/reftest-stylo.list +++ b/layout/reftests/w3c-css/submitted/transforms/reftest-stylo.list @@ -1,5 +1,5 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing == transform-containing-block-dynamic-1a.html transform-containing-block-dynamic-1a.html == transform-containing-block-dynamic-1b.html transform-containing-block-dynamic-1b.html -# == perspective-containing-block-dynamic-1a.html perspective-containing-block-dynamic-1a.html -# == perspective-containing-block-dynamic-1b.html perspective-containing-block-dynamic-1b.html +== perspective-containing-block-dynamic-1a.html perspective-containing-block-dynamic-1a.html +== perspective-containing-block-dynamic-1b.html perspective-containing-block-dynamic-1b.html diff --git a/layout/reftests/w3c-css/submitted/values3/reftest-stylo.list b/layout/reftests/w3c-css/submitted/values3/reftest-stylo.list index 1cc453bdb17c..e315e1a91601 100644 --- a/layout/reftests/w3c-css/submitted/values3/reftest-stylo.list +++ b/layout/reftests/w3c-css/submitted/values3/reftest-stylo.list @@ -1,5 +1,5 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing -# == calc-background-linear-gradient-1.html calc-background-linear-gradient-1.html +== calc-background-linear-gradient-1.html calc-background-linear-gradient-1.html == calc-background-image-gradient-1.html calc-background-image-gradient-1.html == calc-background-position-1.html calc-background-position-1.html == calc-background-size-1.html calc-background-size-1.html diff --git a/layout/reftests/webkit-box/reftest-stylo.list b/layout/reftests/webkit-box/reftest-stylo.list index d92b3fb6da5a..130f5282969e 100644 --- a/layout/reftests/webkit-box/reftest-stylo.list +++ b/layout/reftests/webkit-box/reftest-stylo.list @@ -8,17 +8,17 @@ default-preferences pref(layout.css.prefixes.webkit,true) # WebKit/Blink on them. (The reference case represents the WebKit/Blink # rendering.) We could probably make them pass by implementing some quirks, if # it turns out that the web depends on WebKit/Blink's behavior in these cases. -# == webkit-box-anon-flex-items-1a.html webkit-box-anon-flex-items-1a.html -# == webkit-box-anon-flex-items-1b.html webkit-box-anon-flex-items-1b.html -# == webkit-box-anon-flex-items-2.html webkit-box-anon-flex-items-2.html +fails == webkit-box-anon-flex-items-1a.html webkit-box-anon-flex-items-1a.html +fails == webkit-box-anon-flex-items-1b.html webkit-box-anon-flex-items-1b.html +== webkit-box-anon-flex-items-2.html webkit-box-anon-flex-items-2.html fails == webkit-box-anon-flex-items-3.html webkit-box-anon-flex-items-3.html # Tests for "-webkit-box" & "-webkit-inline-box" as display values: fails == webkit-display-values-1.html webkit-display-values-1.html # Tests for "-webkit-box-align" (cross-axis alignment): -# == webkit-box-align-horiz-1a.html webkit-box-align-horiz-1a.html -# == webkit-box-align-horiz-1b.html webkit-box-align-horiz-1b.html +== webkit-box-align-horiz-1a.html webkit-box-align-horiz-1a.html +== webkit-box-align-horiz-1b.html webkit-box-align-horiz-1b.html fails == webkit-box-align-vert-1.html webkit-box-align-vert-1.html # Tests for "-webkit-box-direction": @@ -26,7 +26,7 @@ fails == webkit-box-direction-1.html webkit-box-direction-1.html fails == webkit-box-direction-2.html webkit-box-direction-2.html # Tests for "-webkit-box-flex" (flexibility of items) -# == webkit-box-flex-1.html webkit-box-flex-1.html +== webkit-box-flex-1.html webkit-box-flex-1.html # Tests for "-webkit-box-ordinal-group" fails == webkit-box-ordinal-group-1.html webkit-box-ordinal-group-1.html diff --git a/layout/reftests/writing-mode/abspos/reftest-stylo.list b/layout/reftests/writing-mode/abspos/reftest-stylo.list index 44b9f982057a..62b0834585e3 100644 --- a/layout/reftests/writing-mode/abspos/reftest-stylo.list +++ b/layout/reftests/writing-mode/abspos/reftest-stylo.list @@ -6,9 +6,9 @@ # Frequent Windows 7 load failed: timed out waiting for test to complete (waiting for onload scripts to complete), bug 1167155 and friends # Even though the whole reftest-stylo.list here is skipped, it doesn't actually work because reftests match the last # **-if, which means even though we tried to skip this list,the fuzzy-if still matched forcing us to run the test. -# == s71-abs-pos-non-replaced-vlr-003.xht s71-abs-pos-non-replaced-vlr-003.xht -# == s71-abs-pos-non-replaced-vlr-005.xht s71-abs-pos-non-replaced-vlr-005.xht -# == s71-abs-pos-non-replaced-vlr-007.xht s71-abs-pos-non-replaced-vlr-007.xht +== s71-abs-pos-non-replaced-vlr-003.xht s71-abs-pos-non-replaced-vlr-003.xht +== s71-abs-pos-non-replaced-vlr-005.xht s71-abs-pos-non-replaced-vlr-005.xht +== s71-abs-pos-non-replaced-vlr-007.xht s71-abs-pos-non-replaced-vlr-007.xht fails == s71-abs-pos-non-replaced-vlr-009.xht s71-abs-pos-non-replaced-vlr-009.xht fails == s71-abs-pos-non-replaced-vlr-011.xht s71-abs-pos-non-replaced-vlr-011.xht fails == s71-abs-pos-non-replaced-vlr-013.xht s71-abs-pos-non-replaced-vlr-013.xht diff --git a/layout/reftests/writing-mode/reftest-stylo.list b/layout/reftests/writing-mode/reftest-stylo.list index 08562b7c90de..4b9c57d74b0f 100644 --- a/layout/reftests/writing-mode/reftest-stylo.list +++ b/layout/reftests/writing-mode/reftest-stylo.list @@ -2,33 +2,33 @@ # This directory contains tests for vertical text and logical layout coordinates. fails HTTP(..) == 1079154-1-vertical-rl-columns.html 1079154-1-vertical-rl-columns.html -# == 1082844.html 1082844.html +== 1082844.html 1082844.html fails HTTP(..) == 1083748.html 1083748.html fails HTTP(..) == 1083848-1-inline-border.html 1083848-1-inline-border.html # HTTP(..) == 1083848-2-inline-background.html 1083848-2-inline-background.html fails == 1083848-3-inline-background-repeat.html 1083848-3-inline-background-repeat.html -# == 1083892-1.html 1083892-1.html +== 1083892-1.html 1083892-1.html == 1086883-1a.html 1086883-1a.html == 1086883-1b.html 1086883-1b.html -# == 1088025-1.html 1088025-1.html -# == 1089388-1.html 1089388-1.html -# == 1089388-2.html 1089388-2.html -# == 1090159-1.html 1090159-1.html -# == 1090168-1.html 1090168-1.html -# == 1090168-1.html 1090168-1.html +== 1088025-1.html 1088025-1.html +== 1089388-1.html 1089388-1.html +== 1089388-2.html 1089388-2.html +== 1090159-1.html 1090159-1.html +fails asserts-if(stylo,1) == 1090168-1.html 1090168-1.html +fails asserts-if(stylo,1) == 1090168-1.html 1090168-1.html fails asserts-if(stylo,1) == 1090168-2.html 1090168-2.html # bug 1324700 fails asserts-if(stylo,1) == 1090168-3.html 1090168-3.html # bug 1324700 -# == 1091058-1.html 1091058-1.html +== 1091058-1.html 1091058-1.html fails == 1094434-1.html 1094434-1.html fails == 1094434-2.html 1094434-2.html == 1094914-1a.html 1094914-1a.html == 1094914-1b.html 1094914-1b.html == 1096224-1a.html 1096224-1a.html == 1096224-1b.html 1096224-1b.html -# == 1102175-1a.html 1102175-1a.html -# == 1102175-1b.html 1102175-1b.html -# == 1103613-1.html 1103613-1.html -# == 1105268-1-min-max-dimensions.html 1105268-1-min-max-dimensions.html +== 1102175-1a.html 1102175-1a.html +== 1102175-1b.html 1102175-1b.html +== 1103613-1.html 1103613-1.html +== 1105268-1-min-max-dimensions.html 1105268-1-min-max-dimensions.html == 1105268-2-min-max-dimensions.html 1105268-2-min-max-dimensions.html == 1106669-1-intrinsic-for-container.html 1106669-1-intrinsic-for-container.html == 1108923-1-percentage-margins.html 1108923-1-percentage-margins.html @@ -37,12 +37,12 @@ fails == 1115916-1-vertical-metrics.html 1115916-1-vertical-metrics.html fails == 1117210-1-vertical-baseline-snap.html 1117210-1-vertical-baseline-snap.html fails == 1117227-1-text-overflow.html 1117227-1-text-overflow.html == 1122366-1-margin-collapse.html 1122366-1-margin-collapse.html -# == 1124636-1-fieldset-max-height.html 1124636-1-fieldset-max-height.html +fails == 1124636-1-fieldset-max-height.html 1124636-1-fieldset-max-height.html fails == 1124636-2-fieldset-min-height.html 1124636-2-fieldset-min-height.html -# == ua-style-sheet-margin-1.html ua-style-sheet-margin-1.html -# == ua-style-sheet-margin-2.html ua-style-sheet-margin-2.html -# == ua-style-sheet-margin-3.html ua-style-sheet-margin-3.html +== ua-style-sheet-margin-1.html ua-style-sheet-margin-1.html +== ua-style-sheet-margin-2.html ua-style-sheet-margin-2.html +== ua-style-sheet-margin-3.html ua-style-sheet-margin-3.html fails == ua-style-sheet-margin-4.html ua-style-sheet-margin-4.html fails == ua-style-sheet-margin-5.html ua-style-sheet-margin-5.html fails == ua-style-sheet-margin-6.html ua-style-sheet-margin-6.html @@ -50,25 +50,25 @@ fails == ua-style-sheet-margin-7.html ua-style-sheet-margin-7.html == ua-style-sheet-margin-8.html ua-style-sheet-margin-8.html fails == ua-style-sheet-margin-9.html ua-style-sheet-margin-9.html fails == ua-style-sheet-margin-10.html ua-style-sheet-margin-10.html -# == ua-style-sheet-margin-11.html ua-style-sheet-margin-11.html -# == ua-style-sheet-margin-12.html ua-style-sheet-margin-12.html +== ua-style-sheet-margin-11.html ua-style-sheet-margin-11.html +== ua-style-sheet-margin-12.html ua-style-sheet-margin-12.html fails == ua-style-sheet-margin-13.html ua-style-sheet-margin-13.html == ua-style-sheet-margin-14.html ua-style-sheet-margin-14.html -# == ua-style-sheet-border-1.html ua-style-sheet-border-1.html -# == ua-style-sheet-border-2.html ua-style-sheet-border-2.html -# == ua-style-sheet-border-3.html ua-style-sheet-border-3.html -# == ua-style-sheet-border-4.html ua-style-sheet-border-4.html -# == ua-style-sheet-border-5.html ua-style-sheet-border-5.html +== ua-style-sheet-border-1.html ua-style-sheet-border-1.html +== ua-style-sheet-border-2.html ua-style-sheet-border-2.html +== ua-style-sheet-border-3.html ua-style-sheet-border-3.html +== ua-style-sheet-border-4.html ua-style-sheet-border-4.html +== ua-style-sheet-border-5.html ua-style-sheet-border-5.html fails == ua-style-sheet-size-1.html ua-style-sheet-size-1.html fails == ua-style-sheet-size-2.html ua-style-sheet-size-2.html -# == ua-style-sheet-fieldset-1.html ua-style-sheet-fieldset-1.html -# == ua-style-sheet-textarea-1.html ua-style-sheet-textarea-1.html -# == ua-style-sheet-textarea-1.html ua-style-sheet-textarea-1.html -# == ua-style-sheet-textarea-1.html ua-style-sheet-textarea-1.html -# == ua-style-sheet-checkbox-radio-1.html ua-style-sheet-checkbox-radio-1.html -# == ua-style-sheet-button-1.html ua-style-sheet-button-1.html -# == ua-style-sheet-button-1.html ua-style-sheet-button-1.html +fails == ua-style-sheet-fieldset-1.html ua-style-sheet-fieldset-1.html +fails == ua-style-sheet-textarea-1.html ua-style-sheet-textarea-1.html +fails == ua-style-sheet-textarea-1.html ua-style-sheet-textarea-1.html +fails == ua-style-sheet-textarea-1.html ua-style-sheet-textarea-1.html +== ua-style-sheet-checkbox-radio-1.html ua-style-sheet-checkbox-radio-1.html +fails == ua-style-sheet-button-1.html ua-style-sheet-button-1.html +fails == ua-style-sheet-button-1.html ua-style-sheet-button-1.html fails == ua-style-sheet-input-color-1.html ua-style-sheet-input-color-1.html # fuzzy-if(gtkWidget,1,15) == ua-style-sheet-input-number-1.html ua-style-sheet-input-number-1.html @@ -102,14 +102,14 @@ fails == ua-style-sheet-input-color-1.html ua-style-sheet-input-color-1.html # HTTP(..) == 1127488-align-end-vertical-lr-ltr.html 1127488-align-end-vertical-lr-ltr.html # HTTP(..) == 1127488-align-left-vertical-lr-ltr.html 1127488-align-left-vertical-lr-ltr.html # HTTP(..) == 1127488-align-right-vertical-lr-ltr.html 1127488-align-right-vertical-lr-ltr.html -# == 1130907-intrinsic-sizing-1.html 1130907-intrinsic-sizing-1.html +== 1130907-intrinsic-sizing-1.html 1130907-intrinsic-sizing-1.html == 1130907-intrinsic-sizing-2.html 1130907-intrinsic-sizing-2.html == 1131013-vertical-bidi.html 1131013-vertical-bidi.html -# == 1133945-1-vertical-align.html 1133945-1-vertical-align.html +== 1133945-1-vertical-align.html 1133945-1-vertical-align.html == 1134744-radio-checkbox-baseline-1.html 1134744-radio-checkbox-baseline-1.html fails == 1134849-orthogonal-inline.html 1134849-orthogonal-inline.html fails == 1135361-ruby-justify-1.html 1135361-ruby-justify-1.html -# == 1136557-1-nested-spans.html 1136557-1-nested-spans.html +== 1136557-1-nested-spans.html 1136557-1-nested-spans.html == 1136557-2-nested-spans.html 1136557-2-nested-spans.html == 1136557-3-nested-spans.html 1136557-3-nested-spans.html fails == 1138356-1-button-contents-alignment.html 1138356-1-button-contents-alignment.html @@ -124,33 +124,33 @@ fails test-pref(dom.meta-viewport.enabled,true) test-pref(font.size.inflation.em # test-pref(dom.meta-viewport.enabled,true) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == font-inflation-1c.html font-inflation-1c.html fails test-pref(dom.meta-viewport.enabled,true) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == font-inflation-1d.html font-inflation-1d.html -# == 1144501-1a-block-end-margin-orthogonal-size.html 1144501-1a-block-end-margin-orthogonal-size.html -# == 1144501-1b-block-end-margin-orthogonal-size.html 1144501-1b-block-end-margin-orthogonal-size.html -# == 1147834-relative-overconstrained-horizontal-tb-ltr.html 1147834-relative-overconstrained-horizontal-tb-ltr.html -# == 1147834-relative-overconstrained-horizontal-tb-rtl.html 1147834-relative-overconstrained-horizontal-tb-rtl.html -# == 1147834-relative-overconstrained-vertical-lr-ltr.html 1147834-relative-overconstrained-vertical-lr-ltr.html -# == 1147834-relative-overconstrained-vertical-lr-rtl.html 1147834-relative-overconstrained-vertical-lr-rtl.html -# == 1147834-relative-overconstrained-vertical-rl-ltr.html 1147834-relative-overconstrained-vertical-rl-ltr.html -# == 1147834-relative-overconstrained-vertical-rl-rtl.html 1147834-relative-overconstrained-vertical-rl-rtl.html -# == 1151993-1-orthogonal-block-size.html 1151993-1-orthogonal-block-size.html -# == 1152941-1-orthogonal-blocksize-overflow.html 1152941-1-orthogonal-blocksize-overflow.html +== 1144501-1a-block-end-margin-orthogonal-size.html 1144501-1a-block-end-margin-orthogonal-size.html +== 1144501-1b-block-end-margin-orthogonal-size.html 1144501-1b-block-end-margin-orthogonal-size.html +== 1147834-relative-overconstrained-horizontal-tb-ltr.html 1147834-relative-overconstrained-horizontal-tb-ltr.html +== 1147834-relative-overconstrained-horizontal-tb-rtl.html 1147834-relative-overconstrained-horizontal-tb-rtl.html +== 1147834-relative-overconstrained-vertical-lr-ltr.html 1147834-relative-overconstrained-vertical-lr-ltr.html +== 1147834-relative-overconstrained-vertical-lr-rtl.html 1147834-relative-overconstrained-vertical-lr-rtl.html +== 1147834-relative-overconstrained-vertical-rl-ltr.html 1147834-relative-overconstrained-vertical-rl-ltr.html +== 1147834-relative-overconstrained-vertical-rl-rtl.html 1147834-relative-overconstrained-vertical-rl-rtl.html +== 1151993-1-orthogonal-block-size.html 1151993-1-orthogonal-block-size.html +== 1152941-1-orthogonal-blocksize-overflow.html 1152941-1-orthogonal-blocksize-overflow.html == 1156021-text-indent-percent.html 1156021-text-indent-percent.html -# == 1157752-upright-bidi.html 1157752-upright-bidi.html -# == 1157758-1-vertical-arabic.html 1157758-1-vertical-arabic.html -# == 1158549-1-vertical-block-size-constraints.html 1158549-1-vertical-block-size-constraints.html +== 1157752-upright-bidi.html 1157752-upright-bidi.html +== 1157758-1-vertical-arabic.html 1157758-1-vertical-arabic.html +== 1158549-1-vertical-block-size-constraints.html 1158549-1-vertical-block-size-constraints.html == 1163238-orthogonal-auto-margins.html 1163238-orthogonal-auto-margins.html -# == 1172774-percent-margin-1.html 1172774-percent-margin-1.html -# == 1172774-percent-margin-2.html 1172774-percent-margin-2.html -# == 1172774-percent-margin-3.html 1172774-percent-margin-3.html -# == 1172774-percent-margin-4.html 1172774-percent-margin-4.html -# == 1172774-percent-padding-1.html 1172774-percent-padding-1.html -# == 1172774-percent-padding-2.html 1172774-percent-padding-2.html -# == 1172774-percent-padding-3.html 1172774-percent-padding-3.html -# == 1172774-percent-padding-4.html 1172774-percent-padding-4.html +skip-if(stylo) == 1172774-percent-margin-1.html 1172774-percent-margin-1.html +skip-if(stylo) == 1172774-percent-margin-2.html 1172774-percent-margin-2.html +skip-if(stylo) == 1172774-percent-margin-3.html 1172774-percent-margin-3.html +skip-if(stylo) == 1172774-percent-margin-4.html 1172774-percent-margin-4.html +skip-if(stylo) == 1172774-percent-padding-1.html 1172774-percent-padding-1.html +skip-if(stylo) == 1172774-percent-padding-2.html 1172774-percent-padding-2.html +skip-if(stylo) == 1172774-percent-padding-3.html 1172774-percent-padding-3.html +skip-if(stylo) == 1172774-percent-padding-4.html 1172774-percent-padding-4.html fails == 1174450-intrinsic-sizing.html 1174450-intrinsic-sizing.html fails == 1175789-underline-overline-1.html 1175789-underline-overline-1.html -# == 1188061-1-nsChangeHint_ClearAncestorIntrinsics.html 1188061-1-nsChangeHint_ClearAncestorIntrinsics.html -# == 1188061-2-nsChangeHint_UpdateComputedBSize.html 1188061-2-nsChangeHint_UpdateComputedBSize.html +== 1188061-1-nsChangeHint_ClearAncestorIntrinsics.html 1188061-1-nsChangeHint_ClearAncestorIntrinsics.html +== 1188061-2-nsChangeHint_UpdateComputedBSize.html 1188061-2-nsChangeHint_UpdateComputedBSize.html # tests involving sideways-lr mode fails == 1193519-sideways-lr-1.html 1193519-sideways-lr-1.html @@ -162,19 +162,19 @@ fails == 1193519-sideways-lr-decoration-1.html 1193519-sideways-lr-decoration-1. fails == 1196887-1-computed-display-inline-block.html 1196887-1-computed-display-inline-block.html fails == 1205787-legacy-svg-values-1.html 1205787-legacy-svg-values-1.html -# == 1216747-1.html 1216747-1.html -# == 1216747-1.html 1216747-1.html +fails == 1216747-1.html 1216747-1.html +fails == 1216747-1.html 1216747-1.html -# == 1243125-1-floats-overflowing.html 1243125-1-floats-overflowing.html +== 1243125-1-floats-overflowing.html 1243125-1-floats-overflowing.html fails == 1248248-1-orientation-break-glyphrun.html 1248248-1-orientation-break-glyphrun.html -# == 1302734-bidi-plaintext-1a.html 1302734-bidi-plaintext-1a.html -# == 1302734-bidi-plaintext-1b.html 1302734-bidi-plaintext-1b.html -# == 1302734-bidi-plaintext-2a.html 1302734-bidi-plaintext-2a.html -# == 1302734-bidi-plaintext-2b.html 1302734-bidi-plaintext-2b.html -# == 1302734-bidi-plaintext-2c.html 1302734-bidi-plaintext-2c.html -# == 1302734-bidi-plaintext-2d.html 1302734-bidi-plaintext-2d.html +== 1302734-bidi-plaintext-1a.html 1302734-bidi-plaintext-1a.html +== 1302734-bidi-plaintext-1b.html 1302734-bidi-plaintext-1b.html +== 1302734-bidi-plaintext-2a.html 1302734-bidi-plaintext-2a.html +== 1302734-bidi-plaintext-2b.html 1302734-bidi-plaintext-2b.html +== 1302734-bidi-plaintext-2c.html 1302734-bidi-plaintext-2c.html +== 1302734-bidi-plaintext-2d.html 1302734-bidi-plaintext-2d.html fails == 1302389-scrolled-rect-1a.html 1302389-scrolled-rect-1a.html fails == 1302389-scrolled-rect-1b.html 1302389-scrolled-rect-1b.html diff --git a/layout/reftests/writing-mode/tables/reftest-stylo.list b/layout/reftests/writing-mode/tables/reftest-stylo.list index 1635419fa5a4..60fae65d9b4f 100644 --- a/layout/reftests/writing-mode/tables/reftest-stylo.list +++ b/layout/reftests/writing-mode/tables/reftest-stylo.list @@ -75,10 +75,10 @@ fails == wm-row-progression-005.xht wm-row-progression-005.xht fails == wm-row-progression-006.xht wm-row-progression-006.xht fails == wm-row-progression-007.xht wm-row-progression-007.xht -# == table-caption-top-1.html table-caption-top-1.html -# == table-caption-bottom-1.html table-caption-bottom-1.html -# == table-caption-left-1.html table-caption-left-1.html -# == table-caption-right-1.html table-caption-right-1.html +== table-caption-top-1.html table-caption-top-1.html +== table-caption-bottom-1.html table-caption-bottom-1.html +== table-caption-left-1.html table-caption-left-1.html +== table-caption-right-1.html table-caption-right-1.html fuzzy-if(stylo,1,7400) == border-collapse-bevels-1a.html border-collapse-bevels-1a.html fuzzy-if(stylo,1,7400) fuzzy-if(cocoaWidget,23,162) == border-collapse-bevels-1b.html border-collapse-bevels-1b.html diff --git a/layout/reftests/z-index/reftest-stylo.list b/layout/reftests/z-index/reftest-stylo.list index 30d0d6ce416c..bb6c64679192 100644 --- a/layout/reftests/z-index/reftest-stylo.list +++ b/layout/reftests/z-index/reftest-stylo.list @@ -2,7 +2,7 @@ fails == 480053-1.html 480053-1.html == z-index-1.html z-index-1.html == stacking-context-yes.html stacking-context-yes.html -# == stacking-context-perspective.html stacking-context-perspective.html +== stacking-context-perspective.html stacking-context-perspective.html == stacking-context-backface-visibility.html stacking-context-backface-visibility.html fails == overlayscrollbar-sorting-ref-visible.html overlayscrollbar-sorting-ref-visible.html diff --git a/widget/reftests/reftest-stylo.list b/widget/reftests/reftest-stylo.list index d9147c2d58d0..2a6f577bacd6 100644 --- a/widget/reftests/reftest-stylo.list +++ b/widget/reftests/reftest-stylo.list @@ -1,7 +1,7 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing skip-if(!cocoaWidget) == 507947.html 507947.html -# == progressbar-fallback-default-style.html progressbar-fallback-default-style.html -# == meter-native-style.html meter-native-style.html -# == meter-vertical-native-style.html meter-vertical-native-style.html -# == meter-fallback-default-style.html meter-fallback-default-style.html +fails == progressbar-fallback-default-style.html progressbar-fallback-default-style.html +fails == meter-native-style.html meter-native-style.html +fails == meter-vertical-native-style.html meter-vertical-native-style.html +fails == meter-fallback-default-style.html meter-fallback-default-style.html load 664925.xhtml From 1c30442333d842d3d79478cb529c28af496e8253 Mon Sep 17 00:00:00 2001 From: vwvww Date: Wed, 22 Feb 2017 21:19:08 -0800 Subject: [PATCH 113/234] servo: Merge #15690 - Add 'use statements with extraneous spaces' tidy check (from vwvww:issue_14898); r=Wafflespeanut Add 'use statements with extraneous spaces' tidy check I added simple check routine for 'use statements with extraneous spaces' and codes that breaks the check routine in rust_tidy.rs. * Added a code that using 'use statements with extraneous spaces' code in rust_tidy.rs * Added assertion code in test_tidy.py. * check_rust function in tidy.py now recognizes the simple case in the 'use statements with extraneous spaces'. * Ran tidy check on rust code and modified a code(tests/unit/style/parsing/inherited_text.rs) that is not passing on this new tidy check. TODO: this code has to be refactored to support more general cases, such as tab or newline. - [X] `./mach build -d` does not report any errors - [X] ./mach test-tidy does not report any errors - [X] These changes fix #14898 (github issue number if applicable). - [X] These changes do not require tests because ./mach test-tidy itself is the test for the code. Source-Repo: https://github.com/servo/servo Source-Revision: b34fdf62341a01abb8da021f07071c5eb8b06622 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 7785f02199a3c54165b88801a7e7abdaec43b78e --- servo/python/tidy/servo_tidy/tidy.py | 4 ++++ servo/python/tidy/servo_tidy_tests/rust_tidy.rs | 1 + servo/python/tidy/servo_tidy_tests/test_tidy.py | 2 ++ servo/tests/unit/style/parsing/inherited_text.rs | 2 +- 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/servo/python/tidy/servo_tidy/tidy.py b/servo/python/tidy/servo_tidy/tidy.py index 9b59b08e473c..ae929d45c3ce 100644 --- a/servo/python/tidy/servo_tidy/tidy.py +++ b/servo/python/tidy/servo_tidy/tidy.py @@ -612,6 +612,10 @@ def check_rust(file_name, lines): indent = len(original_line) - len(line) if not line.endswith(";") and '{' in line: yield (idx + 1, "use statement spans multiple lines") + if '{ ' in line: + yield (idx + 1, "extra space after {") + if ' }' in line: + yield (idx + 1, "extra space before }") # strip "use" from the begin and ";" from the end current_use = line[4:-1] if prev_use: diff --git a/servo/python/tidy/servo_tidy_tests/rust_tidy.rs b/servo/python/tidy/servo_tidy_tests/rust_tidy.rs index 25da55e5bf85..e7efa2c0cbb4 100644 --- a/servo/python/tidy/servo_tidy_tests/rust_tidy.rs +++ b/servo/python/tidy/servo_tidy_tests/rust_tidy.rs @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use app_units::Au; +use azure::azure_hl::{ AntialiasMode, Color, ColorPattern, CompositionOp }; use azure::azure_hl::{AntialiasMode, Color, ColorPattern, CompositionOp}; use euclid::size::Size2D; diff --git a/servo/python/tidy/servo_tidy_tests/test_tidy.py b/servo/python/tidy/servo_tidy_tests/test_tidy.py index f9ccf889ec0d..91f1c54ab552 100644 --- a/servo/python/tidy/servo_tidy_tests/test_tidy.py +++ b/servo/python/tidy/servo_tidy_tests/test_tidy.py @@ -95,6 +95,8 @@ class CheckTidiness(unittest.TestCase): def test_rust(self): errors = tidy.collect_errors_for_files(iterFile('rust_tidy.rs'), [], [tidy.check_rust], print_text=False) + self.assertEqual('extra space after {', errors.next()[2]) + self.assertEqual('extra space before }', errors.next()[2]) self.assertEqual('use statement spans multiple lines', errors.next()[2]) self.assertEqual('missing space before }', errors.next()[2]) self.assertTrue('use statement is not in alphabetical order' in errors.next()[2]) diff --git a/servo/tests/unit/style/parsing/inherited_text.rs b/servo/tests/unit/style/parsing/inherited_text.rs index c8cea6aac293..366497cf9690 100644 --- a/servo/tests/unit/style/parsing/inherited_text.rs +++ b/servo/tests/unit/style/parsing/inherited_text.rs @@ -74,7 +74,7 @@ fn text_emphasis_style_longhand_should_parse_properly() { #[test] fn test_text_emphasis_position() { use style::properties::longhands::text_emphasis_position; - use style::properties::longhands::text_emphasis_position::{HorizontalWritingModeValue, VerticalWritingModeValue }; + use style::properties::longhands::text_emphasis_position::{HorizontalWritingModeValue, VerticalWritingModeValue}; use style::properties::longhands::text_emphasis_position::SpecifiedValue; let over_right = parse_longhand!(text_emphasis_position, "over right"); From 959d5215d6c180de4adcff67723bd2372e463b49 Mon Sep 17 00:00:00 2001 From: Jan Beich Date: Wed, 11 Jan 2017 16:50:18 +0000 Subject: [PATCH 114/234] Bug 1330240 - Limit -Wthread-safety to WebRTC due to lack of annotations. r=cpeterson,froydnj,jesup MozReview-Commit-ID: HuoXFwZkdYo --HG-- extra : rebase_source : 8f07a7a6de6d794b26b0f2b18eb95452d65c8f40 --- build/moz.configure/warnings.configure | 3 --- media/webrtc/trunk/webrtc/build/common.gypi | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/moz.configure/warnings.configure b/build/moz.configure/warnings.configure index 219ca0036651..2f1b255ddc8b 100644 --- a/build/moz.configure/warnings.configure +++ b/build/moz.configure/warnings.configure @@ -78,9 +78,6 @@ check_and_add_gcc_warning('-Werror=non-literal-null-conversion', # catches string literals used in boolean expressions check_and_add_gcc_warning('-Wstring-conversion') -# catches inconsistent use of mutexes -check_and_add_gcc_warning('-Wthread-safety') - # we inline 'new' and 'delete' in mozalloc check_and_add_gcc_warning('-Wno-inline-new-delete', cxx_compiler) diff --git a/media/webrtc/trunk/webrtc/build/common.gypi b/media/webrtc/trunk/webrtc/build/common.gypi index 970269b73afa..2b01f38788c7 100644 --- a/media/webrtc/trunk/webrtc/build/common.gypi +++ b/media/webrtc/trunk/webrtc/build/common.gypi @@ -326,6 +326,9 @@ '-Wimplicit-fallthrough', '-Wthread-safety', ], + 'cflags_mozilla': [ + '-Wthread-safety', + ], }], ], }], From 305e4f9553bf2b59ddb6869128d39b36df2cf657 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Wed, 22 Feb 2017 12:43:41 -0500 Subject: [PATCH 115/234] Bug 1312981, bug 1313136 - Skip browser_capture_doorhanger_window_open.js on Linux for frequent failures. --HG-- extra : rebase_source : a4f5a1cb1e4717b15a6f65f66abb3c02acb07e77 --- toolkit/components/passwordmgr/test/browser/browser.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/toolkit/components/passwordmgr/test/browser/browser.ini b/toolkit/components/passwordmgr/test/browser/browser.ini index 8d434f81ee6c..837fce97f2bd 100644 --- a/toolkit/components/passwordmgr/test/browser/browser.ini +++ b/toolkit/components/passwordmgr/test/browser/browser.ini @@ -38,6 +38,7 @@ support-files = support-files = subtst_notifications_11.html subtst_notifications_11_popup.html +skip-if = os == "linux" # Bug 1312981, bug 1313136 [browser_context_menu_autocomplete_interaction.js] [browser_username_select_dialog.js] support-files = From 5aaba51ccbaaa99fe323e5ac6a86fa5d436504fa Mon Sep 17 00:00:00 2001 From: Honza Bambas Date: Wed, 22 Feb 2017 06:53:00 -0500 Subject: [PATCH 116/234] Bug 1340581 - Add some release-grade assertions to mozilla::Tokenizer to catch string overflows. r=froydnj --HG-- extra : rebase_source : 2c2553e08061c5b3db915b2edcb19716aeac1cce --- xpcom/ds/Tokenizer.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/xpcom/ds/Tokenizer.cpp b/xpcom/ds/Tokenizer.cpp index 4ed183ec6248..94536c938e01 100644 --- a/xpcom/ds/Tokenizer.cpp +++ b/xpcom/ds/Tokenizer.cpp @@ -272,6 +272,8 @@ Tokenizer::Claim(nsDependentCSubstring& aResult, ClaimInclusion aInclusion) nsACString::const_char_iterator close = aInclusion == EXCLUDE_LAST ? mRollback : mCursor; + + MOZ_RELEASE_ASSERT(close >= mRecord, "Overflow!"); aResult.Rebind(mRecord, close - mRecord); } @@ -376,6 +378,7 @@ TokenizerBase::Parse(Token& aToken) const return mEnd; } + MOZ_RELEASE_ASSERT(mEnd >= mCursor, "Overflow!"); nsACString::size_type available = mEnd - mCursor; uint32_t longestCustom = 0; @@ -563,6 +566,10 @@ TokenizerBase::IsCustom(const nsACString::const_char_iterator & caret, *aLongest = std::max(*aLongest, aCustomToken.mCustom.Length()); } + // This is not very likely to happen according to how we call this method + // and since it's on a hot path, it's just a diagnostic assert, + // not a release assert. + MOZ_DIAGNOSTIC_ASSERT(mEnd >= caret, "Overflow?"); uint32_t inputLength = mEnd - caret; if (aCustomToken.mCustom.Length() > inputLength) { return false; @@ -623,6 +630,7 @@ void TokenizerBase::Token::AssignFragment(nsACString::const_char_iterator begin, nsACString::const_char_iterator end) { + MOZ_RELEASE_ASSERT(end >= begin, "Overflow!"); mFragment.Rebind(begin, end - begin); } From 72f7c608742ecb78a477ef2b5c0bb3a1640598e2 Mon Sep 17 00:00:00 2001 From: Patrick McManus Date: Mon, 20 Feb 2017 17:15:36 -0500 Subject: [PATCH 117/234] Bug 1341128 - high level HTTP Channel Success Telemetry r=dragana r=bsmedberg --HG-- extra : rebase_source : 22e7e39821c8b1f704b11e27979a02041bce8be2 --- netwerk/protocol/http/nsHttpChannel.cpp | 38 ++++++++++++++++++++ netwerk/protocol/http/nsHttpChannel.h | 3 ++ netwerk/protocol/http/nsHttpTransaction.h | 2 +- toolkit/components/telemetry/Histograms.json | 9 +++++ 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index 58fd90137267..117799d01d74 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -283,6 +283,7 @@ nsHttpChannel::nsHttpChannel() , mPinCacheContent(0) , mIsCorsPreflightDone(0) , mStronglyFramed(false) + , mUsedNetwork(0) , mPushedStream(nullptr) , mLocalBlocklist(false) , mWarningReporter(nullptr) @@ -824,6 +825,7 @@ nsHttpChannel::SetupTransaction() nsresult rv; + mUsedNetwork = 1; if (mCaps & NS_HTTP_ALLOW_PIPELINING) { // // disable pipelining if: @@ -6942,6 +6944,42 @@ nsHttpChannel::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult st } } + // HTTP_CHANNEL_DISPOSITION TELEMETRY + enum ChannelDisposition + { + kHttpCanceled = 0, + kHttpDisk = 1, + kHttpNetOK = 2, + kHttpNetEarlyFail = 3, + kHttpNetLateFail = 4, + kHttpsCanceled = 8, + kHttpsDisk = 9, + kHttpsNetOK = 10, + kHttpsNetEarlyFail = 11, + kHttpsNetLateFail = 12 + } chanDisposition = kHttpCanceled; + + // HTTP 0.9 is more likely to be an error than really 0.9, so count it that way + if (mCanceled) { + chanDisposition = kHttpCanceled; + } else if (!mUsedNetwork) { + chanDisposition = kHttpDisk; + } else if (NS_SUCCEEDED(status) && + mResponseHead && + mResponseHead->Version() != NS_HTTP_VERSION_0_9) { + chanDisposition = kHttpNetOK; + } else if (!mTransferSize) { + chanDisposition = kHttpNetEarlyFail; + } else { + chanDisposition = kHttpNetLateFail; + } + if (IsHTTPS()) { + // shift http to https disposition enums + chanDisposition = static_cast(chanDisposition + kHttpsCanceled); + } + LOG((" nsHttpChannel::OnStopRequest ChannelDisposition %d\n", chanDisposition)); + Telemetry::Accumulate(Telemetry::HTTP_CHANNEL_DISPOSITION, chanDisposition); + // if needed, check cache entry has all data we expect if (mCacheEntry && mCachePump && mConcurrentCacheAccess && contentComplete) { diff --git a/netwerk/protocol/http/nsHttpChannel.h b/netwerk/protocol/http/nsHttpChannel.h index 1142c9be4e1a..4460cb595d60 100644 --- a/netwerk/protocol/http/nsHttpChannel.h +++ b/netwerk/protocol/http/nsHttpChannel.h @@ -591,6 +591,9 @@ private: // by chunking, content-length, or h2 end-stream framing uint32_t mStronglyFramed : 1; + // true if an HTTP transaction is created for the socket thread + uint32_t mUsedNetwork : 1; + nsTArray mRedirectFuncStack; // Needed for accurate DNS timing diff --git a/netwerk/protocol/http/nsHttpTransaction.h b/netwerk/protocol/http/nsHttpTransaction.h index 972758f9933e..fb92a797c1be 100644 --- a/netwerk/protocol/http/nsHttpTransaction.h +++ b/netwerk/protocol/http/nsHttpTransaction.h @@ -257,7 +257,7 @@ private: int64_t mContentLength; // equals -1 if unknown int64_t mContentRead; // count of consumed content bytes - int64_t mTransferSize; // count of received bytes + Atomic mTransferSize; // count of received bytes // After a 304/204 or other "no-content" style response we will skip over // up to MAX_INVALID_RESPONSE_BODY_SZ bytes when looking for the next diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index 757af7379c30..3ed49cd37594 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -2352,6 +2352,15 @@ "alert_emails": ["necko@mozilla.com", "hurley@mozilla.com"], "bug_numbers": [1296280] }, + "HTTP_CHANNEL_DISPOSITION" : { + "alert_emails": ["necko@mozilla.com"], + "bug_numbers": [1341128], + "expires_in_version": "60", + "kind": "enumerated", + "n_values": 16, + "releaseChannelCollection": "opt-out", + "description": "Channel Disposition: 0=Cancel, 1=Disk, 2=NetOK, 3=NetEarlyFail, 4=NetlateFail, +8 for HTTPS" + }, "HTTP_CONNECTION_ENTRY_CACHE_HIT_1" : { "expires_in_version": "never", "kind": "boolean", From 8e74a46ec639429b145bfef25be2656d33aadb29 Mon Sep 17 00:00:00 2001 From: Alexander Surkov Date: Wed, 22 Feb 2017 13:45:21 -0500 Subject: [PATCH 118/234] Bug 1321384 - add diagnostics to Accessible::Move, r=eeejay --- accessible/generic/Accessible.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/accessible/generic/Accessible.cpp b/accessible/generic/Accessible.cpp index 7ff2f82836d4..7df209d17321 100644 --- a/accessible/generic/Accessible.cpp +++ b/accessible/generic/Accessible.cpp @@ -2163,12 +2163,13 @@ Accessible::RemoveChild(Accessible* aChild) void Accessible::MoveChild(uint32_t aNewIndex, Accessible* aChild) { - MOZ_ASSERT(aChild, "No child was given"); - MOZ_ASSERT(aChild->mParent == this, "A child from different subtree was given"); - MOZ_ASSERT(aChild->mIndexInParent != -1, "Unbound child was given"); - MOZ_ASSERT(static_cast(aChild->mIndexInParent) != aNewIndex, + MOZ_DIAGNOSTIC_ASSERT(aChild, "No child was given"); + MOZ_DIAGNOSTIC_ASSERT(aChild->mParent == this, "A child from different subtree was given"); + MOZ_DIAGNOSTIC_ASSERT(aChild->mIndexInParent != -1, "Unbound child was given"); + MOZ_DIAGNOSTIC_ASSERT(aChild->mParent->GetChildAt(aChild->mIndexInParent) == aChild, "Wrong index in parent"); + MOZ_DIAGNOSTIC_ASSERT(static_cast(aChild->mIndexInParent) != aNewIndex, "No move, same index"); - MOZ_ASSERT(aNewIndex <= mChildren.Length(), "Wrong new index was given"); + MOZ_DIAGNOSTIC_ASSERT(aNewIndex <= mChildren.Length(), "Wrong new index was given"); RefPtr hideEvent = new AccHideEvent(aChild, false); if (mDoc->Controller()->QueueMutationEvent(hideEvent)) { From cf967e212ec796d37deaf5ac324dc69e145f8d69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bargull?= Date: Wed, 22 Feb 2017 06:19:11 -0800 Subject: [PATCH 119/234] Bug 1338916 - Disable Array.prototype.values tests from test262 when Array.prototype.values is not present. r=shu --HG-- extra : rebase_source : 6cc0479e942635561d70eb35b449a2c1db9748e4 --- js/src/tests/jstests.list | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/js/src/tests/jstests.list b/js/src/tests/jstests.list index eb21a5f3328c..332acd651433 100644 --- a/js/src/tests/jstests.list +++ b/js/src/tests/jstests.list @@ -31,6 +31,14 @@ skip script test262/language/expressions/yield/iter-value-specified.js skip script test262/language/expressions/yield/iter-value-unspecified.js +######################################################################### +# Test262 tests disabled when features are only conditionally available # +######################################################################### + +skip-if(!Array.prototype.values) script test262/built-ins/Array/prototype/Symbol.iterator.js +skip-if(!Array.prototype.values) include test262/built-ins/Array/prototype/values/jstests.list + + ##################################### # Test262 tests disabled on browser # ##################################### From 3c1d8fd7b1399618f8d3d31281f0292bb84ddf31 Mon Sep 17 00:00:00 2001 From: Honza Bambas Date: Wed, 22 Feb 2017 09:10:00 -0500 Subject: [PATCH 120/234] Bug 1322355 - Cancel http:// channel when secure update (redirect) to https:// is vetoed to avoid duplicate OnStartRequest notification + added logs. r=michal --HG-- extra : rebase_source : edb97c1bdfd700ed75c57d1af0018f63428036f0 --- netwerk/protocol/http/HttpBaseChannel.cpp | 8 ++++++++ .../http/HttpChannelParentListener.cpp | 8 ++++++++ netwerk/protocol/http/nsHttpChannel.cpp | 19 +++++++++++++++---- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/HttpBaseChannel.cpp index a48191ff7f40..976cacfe69d6 100644 --- a/netwerk/protocol/http/HttpBaseChannel.cpp +++ b/netwerk/protocol/http/HttpBaseChannel.cpp @@ -2087,6 +2087,12 @@ HttpBaseChannel::GetRequestSucceeded(bool *aValue) NS_IMETHODIMP HttpBaseChannel::RedirectTo(nsIURI *targetURI) { + NS_ENSURE_ARG(targetURI); + + nsAutoCString spec; + targetURI->GetAsciiSpec(spec); + LOG(("HttpBaseChannel::RedirectTo [this=%p, uri=%s]", this, spec.get())); + // We cannot redirect after OnStartRequest of the listener // has been called, since to redirect we have to switch channels // and the dance with OnStartRequest et al has to start over. @@ -2970,6 +2976,8 @@ HttpBaseChannel::ReleaseListeners() void HttpBaseChannel::DoNotifyListener() { + LOG(("HttpBaseChannel::DoNotifyListener this=%p", this)); + if (mListener) { MOZ_ASSERT(!mOnStartRequestCalled, "We should not call OnStartRequest twice"); diff --git a/netwerk/protocol/http/HttpChannelParentListener.cpp b/netwerk/protocol/http/HttpChannelParentListener.cpp index c793903af1bf..5800f8f44653 100644 --- a/netwerk/protocol/http/HttpChannelParentListener.cpp +++ b/netwerk/protocol/http/HttpChannelParentListener.cpp @@ -30,6 +30,8 @@ HttpChannelParentListener::HttpChannelParentListener(HttpChannelParent* aInitial , mShouldIntercept(false) , mShouldSuspendIntercept(false) { + LOG(("HttpChannelParentListener::HttpChannelParentListener [this=%p, next=%p]", + this, aInitialChannel)); } HttpChannelParentListener::~HttpChannelParentListener() @@ -160,6 +162,9 @@ HttpChannelParentListener::AsyncOnChannelRedirect( uint32_t redirectFlags, nsIAsyncVerifyRedirectCallback* callback) { + LOG(("HttpChannelParentListener::AsyncOnChannelRedirect [this=%p, old=%p, new=%p, flags=%u]", + this, oldChannel, newChannel, redirectFlags)); + nsresult rv; nsCOMPtr activeRedirectingChannel = @@ -193,6 +198,9 @@ HttpChannelParentListener::AsyncOnChannelRedirect( NS_IMETHODIMP HttpChannelParentListener::OnRedirectResult(bool succeeded) { + LOG(("HttpChannelParentListener::OnRedirectResult [this=%p, suc=%d]", + this, succeeded)); + nsresult rv; nsCOMPtr redirectChannel; diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index 117799d01d74..a13e751c08f8 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -1269,6 +1269,8 @@ EnsureMIMEOfScript(nsIURI* aURI, nsHttpResponseHead* aResponseHead, nsILoadInfo* nsresult nsHttpChannel::CallOnStartRequest() { + LOG(("nsHttpChannel::CallOnStartRequest [this=%p]", this)); + MOZ_RELEASE_ASSERT(!(mRequireCORSPreflight && mInterceptCache != INTERCEPTED) || mIsCorsPreflightDone, @@ -1362,7 +1364,7 @@ nsHttpChannel::CallOnStartRequest() } } - LOG((" calling mListener->OnStartRequest\n")); + LOG((" calling mListener->OnStartRequest [this=%p, listener=%p]\n", this, mListener.get())); if (mListener) { MOZ_ASSERT(!mOnStartRequestCalled, "We should not call OsStartRequest twice"); @@ -2154,6 +2156,9 @@ nsHttpChannel::ContinueProcessResponse1() nsresult nsHttpChannel::ContinueProcessResponse2(nsresult rv) { + LOG(("nsHttpChannel::ContinueProcessResponse1 [this=%p, rv=%" PRIx32 "]", + this, static_cast(rv))); + if (NS_SUCCEEDED(rv)) { // redirectTo() has passed through, we don't want to go on with // this channel. It will now be canceled by the redirect handling @@ -2411,6 +2416,8 @@ nsHttpChannel::ProcessNormal() nsresult nsHttpChannel::ContinueProcessNormal(nsresult rv) { + LOG(("nsHttpChannel::ContinueProcessNormal [this=%p]", this)); + if (NS_FAILED(rv)) { // Fill the failure status here, we have failed to fall back, thus we // have to report our status as failed. @@ -2648,6 +2655,8 @@ nsHttpChannel::StartRedirectChannelToURI(nsIURI *upgradedURI, uint32_t flags) nsresult nsHttpChannel::ContinueAsyncRedirectChannelToURI(nsresult rv) { + LOG(("nsHttpChannel::ContinueAsyncRedirectChannelToURI [this=%p]", this)); + // Since we handle mAPIRedirectToURI also after on-examine-response handler // rather drop it here to avoid any redirect loops, even just hypothetical. mAPIRedirectToURI = nullptr; @@ -2657,17 +2666,17 @@ nsHttpChannel::ContinueAsyncRedirectChannelToURI(nsresult rv) } if (NS_FAILED(rv)) { - // Fill the failure status here, the update to https had been vetoed + // Cancel the channel here, the update to https had been vetoed // but from the security reasons we have to discard the whole channel // load. - mStatus = rv; + Cancel(rv); } if (mLoadGroup) { mLoadGroup->RemoveRequest(this, nullptr, mStatus); } - if (NS_FAILED(rv)) { + if (NS_FAILED(rv) && !mCachePump && !mTransactionPump) { // We have to manually notify the listener because there is not any pump // that would call our OnStart/StopRequest after resume from waiting for // the redirect callback. @@ -6749,6 +6758,8 @@ nsHttpChannel::ContinueOnStartRequest2(nsresult result) nsresult nsHttpChannel::ContinueOnStartRequest3(nsresult result) { + LOG(("nsHttpChannel::ContinueOnStartRequest3 [this=%p]", this)); + if (mFallingBack) return NS_OK; From 81628820f612455f66dabf1a333022c3ec38f49b Mon Sep 17 00:00:00 2001 From: David Parks Date: Fri, 20 Jan 2017 16:03:44 -0800 Subject: [PATCH 121/234] Bug 1284897 - Add opcodes to nsWindowsDllInterceptor for GetSaveFileNameW, GetOpenFileNameW and ImmReleaseContext. r=aklotz This includes a near-jump CALL instruction in x64, which expands to a far-jump CALL with a 64-bit address as inline data. This requires us to abandon the method where we memcpy the code block into the trampoline and, instead, build the trampoline function as we go. --HG-- extra : rebase_source : 7f90ce5ba1a82dff731aff1ac17117c684b7b2cf --- xpcom/build/nsWindowsDllInterceptor.h | 406 +++++++++++++++----------- 1 file changed, 228 insertions(+), 178 deletions(-) diff --git a/xpcom/build/nsWindowsDllInterceptor.h b/xpcom/build/nsWindowsDllInterceptor.h index 98c81fce6a59..81ef9bf55319 100644 --- a/xpcom/build/nsWindowsDllInterceptor.h +++ b/xpcom/build/nsWindowsDllInterceptor.h @@ -70,6 +70,12 @@ #include +#define COPY_CODES(NBYTES) do { \ + memcpy(&tramp[nTrampBytes], &origBytes[nOrigBytes], NBYTES); \ + nOrigBytes += NBYTES; \ + nTrampBytes += NBYTES; \ +} while (0) + namespace mozilla { namespace internal { @@ -543,7 +549,8 @@ protected: enum JumpType { Je, - Jmp + Jmp, + Call }; struct JumpPatch { @@ -557,14 +564,6 @@ protected: { } - void AddJumpPatch(size_t aHookOffset, intptr_t aAbsJumpAddress, - JumpType aType = JumpType::Jmp) - { - mHookOffset = aHookOffset; - mJumpAddress = aAbsJumpAddress; - mType = aType; - } - size_t GenerateJump(uint8_t* aCode) { size_t offset = mHookOffset; @@ -575,20 +574,26 @@ protected: offset += 2; } - // JMP [RIP+0] - aCode[offset] = 0xff; - aCode[offset + 1] = 0x25; - *reinterpret_cast(aCode + offset + 2) = 0; - - // Jump table - *reinterpret_cast(aCode + offset + 2 + 4) = mJumpAddress; - - return offset + 2 + 4 + 8; - } - - bool HasJumpPatch() const - { - return !!mJumpAddress; + // Near call/jmp, absolute indirect, address given in r/m32 + if (mType == JumpType::Call) { + // CALL [RIP+0] + aCode[offset] = 0xff; + aCode[offset + 1] = 0x15; + // The offset to jump destination -- ie it is placed 2 bytes after the offset. + *reinterpret_cast(aCode + offset + 2) = 2; + aCode[offset + 2 + 4] = 0xeb; // JMP +8 (jump over mJumpAddress) + aCode[offset + 2 + 4 + 1] = 8; + *reinterpret_cast(aCode + offset + 2 + 4 + 2) = mJumpAddress; + return offset + 2 + 4 + 2 + 8; + } else { + // JMP [RIP+0] + aCode[offset] = 0xff; + aCode[offset + 1] = 0x25; + // The offset to jump destination is 0 + *reinterpret_cast(aCode + offset + 2) = 0; + *reinterpret_cast(aCode + offset + 2 + 4) = mJumpAddress; + return offset + 2 + 4 + 8; + } } size_t mHookOffset; @@ -672,186 +677,226 @@ protected: return; } + // We keep the address of the original function in the first bytes of + // the trampoline buffer + *((void**)tramp) = aOrigFunction; + tramp += sizeof(void*); + byteptr_t origBytes = (byteptr_t)aOrigFunction; - int nBytes = 0; + // # of bytes of the original function that we can overwrite. + int nOrigBytes = 0; #if defined(_M_IX86) int pJmp32 = -1; - while (nBytes < 5) { + while (nOrigBytes < 5) { // Understand some simple instructions that might be found in a // prologue; we might need to extend this as necessary. // // Note! If we ever need to understand jump instructions, we'll // need to rewrite the displacement argument. unsigned char prefixGroups; - int numPrefixBytes = CountPrefixBytes(origBytes, nBytes, &prefixGroups); + int numPrefixBytes = CountPrefixBytes(origBytes, nOrigBytes, &prefixGroups); if (numPrefixBytes < 0 || (prefixGroups & (ePrefixGroup3 | ePrefixGroup4))) { // Either the prefix sequence was bad, or there are prefixes that // we don't currently support (groups 3 and 4) return; } - nBytes += numPrefixBytes; - if (origBytes[nBytes] >= 0x88 && origBytes[nBytes] <= 0x8B) { + nOrigBytes += numPrefixBytes; + if (origBytes[nOrigBytes] >= 0x88 && + origBytes[nOrigBytes] <= 0x8B) { // various MOVs - ++nBytes; - int len = CountModRmSib(origBytes + nBytes); + ++nOrigBytes; + int len = CountModRmSib(origBytes + nOrigBytes); if (len < 0) { return; } - nBytes += len; - } else if (origBytes[nBytes] == 0xA1) { + nOrigBytes += len; + } else if (origBytes[nOrigBytes] == 0xA1) { // MOV eax, [seg:offset] - nBytes += 5; - } else if (origBytes[nBytes] == 0xB8) { + nOrigBytes += 5; + } else if (origBytes[nOrigBytes] == 0xB8) { // MOV 0xB8: http://ref.x86asm.net/coder32.html#xB8 - nBytes += 5; - } else if (origBytes[nBytes] == 0x83) { + nOrigBytes += 5; + } else if (origBytes[nOrigBytes] == 0x33 && + (origBytes[nOrigBytes+1] & kMaskMod) == kModReg) { + // XOR r32, r32 + nOrigBytes += 2; + } else if ((origBytes[nOrigBytes] & 0xf8) == 0x40) { + // INC r32 + nOrigBytes += 1; + } else if (origBytes[nOrigBytes] == 0x83) { // ADD|ODR|ADC|SBB|AND|SUB|XOR|CMP r/m, imm8 - unsigned char b = origBytes[nBytes + 1]; + unsigned char b = origBytes[nOrigBytes + 1]; if ((b & 0xc0) == 0xc0) { // ADD|ODR|ADC|SBB|AND|SUB|XOR|CMP r, imm8 - nBytes += 3; + nOrigBytes += 3; } else { // bail return; } - } else if (origBytes[nBytes] == 0x68) { + } else if (origBytes[nOrigBytes] == 0x68) { // PUSH with 4-byte operand - nBytes += 5; - } else if ((origBytes[nBytes] & 0xf0) == 0x50) { + nOrigBytes += 5; + } else if ((origBytes[nOrigBytes] & 0xf0) == 0x50) { // 1-byte PUSH/POP - nBytes++; - } else if (origBytes[nBytes] == 0x6A) { + nOrigBytes++; + } else if (origBytes[nOrigBytes] == 0x6A) { // PUSH imm8 - nBytes += 2; - } else if (origBytes[nBytes] == 0xe9) { - pJmp32 = nBytes; + nOrigBytes += 2; + } else if (origBytes[nOrigBytes] == 0xe9) { + pJmp32 = nOrigBytes; // jmp 32bit offset - nBytes += 5; - } else if (origBytes[nBytes] == 0xff && origBytes[nBytes + 1] == 0x25) { + nOrigBytes += 5; + } else if (origBytes[nOrigBytes] == 0xff && + origBytes[nOrigBytes + 1] == 0x25) { // jmp [disp32] - nBytes += 6; + nOrigBytes += 6; + } else if (origBytes[nOrigBytes] == 0xc2) { + // ret imm16. We can't handle this but it happens. We don't ASSERT but we do fail to hook. +#if defined(MOZILLA_INTERNAL_API) + NS_WARNING("Cannot hook method -- RET opcode found"); +#endif + return; } else { //printf ("Unknown x86 instruction byte 0x%02x, aborting trampoline\n", origBytes[nBytes]); return; } } + + // The trampoline is a copy of the instructions that we just traced, + // followed by a jump that we add below. + memcpy(tramp, aOrigFunction, nOrigBytes); #elif defined(_M_X64) - JumpPatch jump; + // The number of bytes used by the trampoline. + int nTrampBytes = 0; + bool foundJmp = false; - while (nBytes < 13) { - - // if found JMP 32bit offset, next bytes must be NOP or INT3 - if (jump.HasJumpPatch()) { - if (origBytes[nBytes] == 0x90 || origBytes[nBytes] == 0xcc) { - nBytes++; + while (nOrigBytes < 13) { + // If we found JMP 32bit offset, we require that the next bytes must + // be NOP or INT3. There is no reason to copy them. + // TODO: This used to trigger for Je as well. Now that I allow + // instructions after CALL and JE, I don't think I need that. + // The only real value of this condition is that if code follows a JMP + // then its _probably_ the target of a JMP somewhere else and we + // will be overwriting it, which would be tragic. This seems + // highly unlikely. + if (foundJmp) { + if (origBytes[nOrigBytes] == 0x90 || origBytes[nOrigBytes] == 0xcc) { + nOrigBytes++; continue; } return; } - if (origBytes[nBytes] == 0x0f) { - nBytes++; - if (origBytes[nBytes] == 0x1f) { + if (origBytes[nOrigBytes] == 0x0f) { + COPY_CODES(1); + if (origBytes[nOrigBytes] == 0x1f) { // nop (multibyte) - nBytes++; - if ((origBytes[nBytes] & 0xc0) == 0x40 && - (origBytes[nBytes] & 0x7) == 0x04) { - nBytes += 3; + COPY_CODES(1); + if ((origBytes[nOrigBytes] & 0xc0) == 0x40 && + (origBytes[nOrigBytes] & 0x7) == 0x04) { + COPY_CODES(3); } else { return; } - } else if (origBytes[nBytes] == 0x05) { + } else if (origBytes[nOrigBytes] == 0x05) { // syscall - nBytes++; - } else if (origBytes[nBytes] == 0x84) { + COPY_CODES(1); + } else if (origBytes[nOrigBytes] == 0x84) { // je rel32 - jump.AddJumpPatch(nBytes - 1, - (intptr_t) - origBytes + nBytes + 5 + - *(reinterpret_cast(origBytes + - nBytes + 1)), - JumpType::Je); - nBytes += 5; + JumpPatch jump(nTrampBytes - 1, // overwrite the 0x0f we copied above + (intptr_t)(origBytes + nOrigBytes + 5 + + *(reinterpret_cast(origBytes + nOrigBytes + 1))), + JumpType::Je); + nTrampBytes = jump.GenerateJump(tramp); + nOrigBytes += 5; } else { return; } - } else if (origBytes[nBytes] == 0x40 || - origBytes[nBytes] == 0x41) { + } else if (origBytes[nOrigBytes] == 0x40 || + origBytes[nOrigBytes] == 0x41) { // Plain REX or REX.B - nBytes++; - - if ((origBytes[nBytes] & 0xf0) == 0x50) { + COPY_CODES(1); + if ((origBytes[nOrigBytes] & 0xf0) == 0x50) { // push/pop with Rx register - nBytes++; - } else if (origBytes[nBytes] >= 0xb8 && origBytes[nBytes] <= 0xbf) { + COPY_CODES(1); + } else if (origBytes[nOrigBytes] >= 0xb8 && origBytes[nOrigBytes] <= 0xbf) { // mov r32, imm32 - nBytes += 5; + COPY_CODES(5); } else { return; } - } else if (origBytes[nBytes] == 0x45) { + } else if (origBytes[nOrigBytes] == 0x45) { // REX.R & REX.B - nBytes++; + COPY_CODES(1); - if (origBytes[nBytes] == 0x33) { + if (origBytes[nOrigBytes] == 0x33) { // xor r32, r32 - nBytes += 2; + COPY_CODES(2); } else { return; } - } else if ((origBytes[nBytes] & 0xfb) == 0x48) { + } else if ((origBytes[nOrigBytes] & 0xfb) == 0x48) { // REX.W | REX.WR - nBytes++; + COPY_CODES(1); - if (origBytes[nBytes] == 0x81 && - (origBytes[nBytes + 1] & 0xf8) == 0xe8) { + if (origBytes[nOrigBytes] == 0x81 && + (origBytes[nOrigBytes + 1] & 0xf8) == 0xe8) { // sub r, dword - nBytes += 6; - } else if (origBytes[nBytes] == 0x83 && - (origBytes[nBytes + 1] & 0xf8) == 0xe8) { + COPY_CODES(6); + } else if (origBytes[nOrigBytes] == 0x83 && + (origBytes[nOrigBytes + 1] & 0xf8) == 0xe8) { // sub r, byte - nBytes += 3; - } else if (origBytes[nBytes] == 0x83 && - (origBytes[nBytes + 1] & 0xf8) == 0x60) { + COPY_CODES(3); + } else if (origBytes[nOrigBytes] == 0x83 && + (origBytes[nOrigBytes + 1] & (kMaskMod|kMaskReg)) == kModReg) { + // add r, byte + COPY_CODES(3); + } else if (origBytes[nOrigBytes] == 0x83 && + (origBytes[nOrigBytes + 1] & 0xf8) == 0x60) { // and [r+d], imm8 - nBytes += 5; - } else if (origBytes[nBytes] == 0x85) { + COPY_CODES(5); + } else if (origBytes[nOrigBytes] == 0x2b && + (origBytes[nOrigBytes + 1] & kMaskMod) == kModReg) { + // sub r64, r64 + COPY_CODES(2); + } else if (origBytes[nOrigBytes] == 0x85) { // 85 /r => TEST r/m32, r32 - if ((origBytes[nBytes + 1] & 0xc0) == 0xc0) { - nBytes += 2; + if ((origBytes[nOrigBytes + 1] & 0xc0) == 0xc0) { + COPY_CODES(2); } else { return; } - } else if ((origBytes[nBytes] & 0xfd) == 0x89) { - ++nBytes; + } else if ((origBytes[nOrigBytes] & 0xfd) == 0x89) { + COPY_CODES(1); // MOV r/m64, r64 | MOV r64, r/m64 - int len = CountModRmSib(origBytes + nBytes); + int len = CountModRmSib(origBytes + nOrigBytes); if (len < 0) { return; } - nBytes += len; - } else if (origBytes[nBytes] == 0xc7) { + COPY_CODES(len); + } else if (origBytes[nOrigBytes] == 0xc7) { // MOV r/m64, imm32 - if (origBytes[nBytes + 1] == 0x44) { + if (origBytes[nOrigBytes + 1] == 0x44) { // MOV [r64+disp8], imm32 // ModR/W + SIB + disp8 + imm32 - nBytes += 8; + COPY_CODES(8); } else { return; } - } else if (origBytes[nBytes] == 0xff) { + } else if (origBytes[nOrigBytes] == 0xff) { // JMP /4 - if ((origBytes[nBytes + 1] & 0xc0) == 0x0 && - (origBytes[nBytes + 1] & 0x07) == 0x5) { + if ((origBytes[nOrigBytes + 1] & 0xc0) == 0x0 && + (origBytes[nOrigBytes + 1] & 0x07) == 0x5) { // [rip+disp32] // convert JMP 32bit offset to JMP 64bit direct - jump.AddJumpPatch(nBytes - 1, - *reinterpret_cast( - origBytes + nBytes + 6 + - *reinterpret_cast(origBytes + nBytes + - 2))); - nBytes += 6; + JumpPatch jump(nTrampBytes - 1, // overwrite the REX.W/REX.WR we copied above + *reinterpret_cast(origBytes + nOrigBytes + 6 + + *reinterpret_cast(origBytes + nOrigBytes + 2)), + JumpType::Jmp); + nTrampBytes = jump.GenerateJump(tramp); + nOrigBytes += 6; + foundJmp = true; } else { // not support yet! return; @@ -860,91 +905,107 @@ protected: // not support yet! return; } - } else if (origBytes[nBytes] == 0x66) { + } else if (origBytes[nOrigBytes] == 0x66) { // operand override prefix - nBytes += 1; + COPY_CODES(1); // This is the same as the x86 version - if (origBytes[nBytes] >= 0x88 && origBytes[nBytes] <= 0x8B) { + if (origBytes[nOrigBytes] >= 0x88 && origBytes[nOrigBytes] <= 0x8B) { // various MOVs - unsigned char b = origBytes[nBytes + 1]; + unsigned char b = origBytes[nOrigBytes + 1]; if (((b & 0xc0) == 0xc0) || (((b & 0xc0) == 0x00) && ((b & 0x07) != 0x04) && ((b & 0x07) != 0x05))) { // REG=r, R/M=r or REG=r, R/M=[r] - nBytes += 2; + COPY_CODES(2); } else if ((b & 0xc0) == 0x40) { if ((b & 0x07) == 0x04) { // REG=r, R/M=[SIB + disp8] - nBytes += 4; + COPY_CODES(4); } else { // REG=r, R/M=[r + disp8] - nBytes += 3; + COPY_CODES(3); } } else { // complex MOV, bail return; } } - } else if ((origBytes[nBytes] & 0xf0) == 0x50) { + } else if ((origBytes[nOrigBytes] & 0xf0) == 0x50) { // 1-byte push/pop - nBytes++; - } else if (origBytes[nBytes] == 0x65) { + COPY_CODES(1); + } else if (origBytes[nOrigBytes] == 0x65) { // GS prefix // // The entry of GetKeyState on Windows 10 has the following code. // 65 48 8b 04 25 30 00 00 00 mov rax,qword ptr gs:[30h] // (GS prefix + REX + MOV (0x8b) ...) - if (origBytes[nBytes + 1] == 0x48 && - (origBytes[nBytes + 2] >= 0x88 && origBytes[nBytes + 2] <= 0x8b)) { - nBytes += 3; - int len = CountModRmSib(origBytes + nBytes); + if (origBytes[nOrigBytes + 1] == 0x48 && + (origBytes[nOrigBytes + 2] >= 0x88 && origBytes[nOrigBytes + 2] <= 0x8b)) { + COPY_CODES(3); + int len = CountModRmSib(origBytes + nOrigBytes); if (len < 0) { // no way to support this yet. return; } - nBytes += len; + COPY_CODES(len); } else { return; } - } else if (origBytes[nBytes] == 0x90) { + } else if (origBytes[nOrigBytes] == 0x90) { // nop - nBytes++; - } else if (origBytes[nBytes] == 0xb8) { + COPY_CODES(1); + } else if (origBytes[nOrigBytes] == 0xb8) { // MOV 0xB8: http://ref.x86asm.net/coder32.html#xB8 - nBytes += 5; - } else if (origBytes[nBytes] == 0x33) { + COPY_CODES(5); + } else if (origBytes[nOrigBytes] == 0x33) { // xor r32, r/m32 - nBytes += 2; - } else if (origBytes[nBytes] == 0xf6) { + COPY_CODES(2); + } else if (origBytes[nOrigBytes] == 0xf6) { // test r/m8, imm8 (used by ntdll on Windows 10 x64) // (no flags are affected by near jmp since there is no task switch, // so it is ok for a jmp to be written immediately after a test) BYTE subOpcode = 0; - int nModRmSibBytes = CountModRmSib(&origBytes[nBytes + 1], &subOpcode); + int nModRmSibBytes = CountModRmSib(&origBytes[nOrigBytes + 1], &subOpcode); if (nModRmSibBytes < 0 || subOpcode != 0) { // Unsupported return; } - nBytes += 2 + nModRmSibBytes; - } else if (origBytes[nBytes] == 0xc3) { + COPY_CODES(2 + nModRmSibBytes); + } else if (origBytes[nOrigBytes] == 0xd1 && + (origBytes[nOrigBytes+1] & kMaskMod) == kModReg) { + // bit shifts/rotates : (SA|SH|RO|RC)(R|L) r32 + // (e.g. 0xd1 0xe0 is SAL, 0xd1 0xc8 is ROR) + COPY_CODES(2); + } else if (origBytes[nOrigBytes] == 0xc3) { // ret - nBytes++; - } else if (origBytes[nBytes] == 0xcc) { + COPY_CODES(1); + } else if (origBytes[nOrigBytes] == 0xcc) { // int 3 - nBytes++; - } else if (origBytes[nBytes] == 0xe9) { - // jmp 32bit offset - jump.AddJumpPatch(nBytes, - // convert JMP 32bit offset to JMP 64bit direct - (intptr_t) - origBytes + nBytes + 5 + - *(reinterpret_cast(origBytes + nBytes + 1))); - nBytes += 5; - } else if (origBytes[nBytes] == 0xff) { - nBytes++; - if ((origBytes[nBytes] & 0xf8) == 0xf0) { + COPY_CODES(1); + } else if (origBytes[nOrigBytes] == 0xe8 || + origBytes[nOrigBytes] == 0xe9) { + // CALL (0xe8) or JMP (0xe9) 32bit offset + foundJmp = origBytes[nOrigBytes] == 0xe9; + JumpPatch jump(nTrampBytes, + (intptr_t)(origBytes + nOrigBytes + 5 + + *(reinterpret_cast(origBytes + nOrigBytes + 1))), + origBytes[nOrigBytes] == 0xe8 ? JumpType::Call : JumpType::Jmp); + nTrampBytes = jump.GenerateJump(tramp); + nOrigBytes += 5; + } else if (origBytes[nOrigBytes] == 0xff) { + COPY_CODES(1); + if ((origBytes[nOrigBytes] & (kMaskMod|kMaskReg)) == 0xf0) { // push r64 - nBytes++; + COPY_CODES(1); + } else if (origBytes[nOrigBytes] == 0x25) { + // jmp absolute indirect m32 + foundJmp = true; + int32_t offset = *(reinterpret_cast(origBytes + nOrigBytes + 1)); + int64_t* ptrToJmpDest = reinterpret_cast(origBytes + nOrigBytes + 5 + offset); + intptr_t jmpDest = static_cast(*ptrToJmpDest); + JumpPatch jump(nTrampBytes, jmpDest, JumpType::Jmp); + nTrampBytes = jump.GenerateJump(tramp); + nOrigBytes += 5; } else { return; } @@ -956,20 +1017,13 @@ protected: #error "Unknown processor type" #endif - if (nBytes > 100) { + if (nOrigBytes > 100) { //printf ("Too big!"); return; } - // We keep the address of the original function in the first bytes of - // the trampoline buffer - *((void**)tramp) = aOrigFunction; - tramp += sizeof(void*); - - memcpy(tramp, aOrigFunction, nBytes); - - // OrigFunction+N, the target of the trampoline - byteptr_t trampDest = origBytes + nBytes; + // target address of the final jmp instruction in the trampoline + byteptr_t trampDest = origBytes + nOrigBytes; #if defined(_M_IX86) if (pJmp32 >= 0) { @@ -978,20 +1032,16 @@ protected: // Adjust jump target displacement to jump location in the trampoline. *((intptr_t*)(tramp + pJmp32 + 1)) += origBytes - tramp; } else { - tramp[nBytes] = 0xE9; // jmp - *((intptr_t*)(tramp + nBytes + 1)) = - (intptr_t)trampDest - (intptr_t)(tramp + nBytes + 5); // target displacement + tramp[nOrigBytes] = 0xE9; // jmp + *((intptr_t*)(tramp + nOrigBytes + 1)) = + (intptr_t)trampDest - (intptr_t)(tramp + nOrigBytes + 5); // target displacement } #elif defined(_M_X64) - // If JMP/JE opcode found, we don't insert to trampoline jump - if (jump.HasJumpPatch()) { - size_t offset = jump.GenerateJump(tramp); - if (jump.mType != JumpType::Jmp) { - JumpPatch patch(offset, reinterpret_cast(trampDest)); - patch.GenerateJump(tramp); - } - } else { - JumpPatch patch(nBytes, reinterpret_cast(trampDest)); + // If the we found a Jmp, we don't need to add another instruction. However, + // if we found a _conditional_ jump or a CALL (or no control operations + // at all) then we still need to run the rest of aOriginalFunction. + if (!foundJmp) { + JumpPatch patch(nTrampBytes, reinterpret_cast(trampDest)); patch.GenerateJump(tramp); } #endif @@ -1000,7 +1050,7 @@ protected: *aOutTramp = tramp; // ensure we can modify the original code - AutoVirtualProtect protect(aOrigFunction, nBytes, PAGE_EXECUTE_READWRITE); + AutoVirtualProtect protect(aOrigFunction, nOrigBytes, PAGE_EXECUTE_READWRITE); if (!protect.Protect()) { //printf ("VirtualProtectEx failed! %d\n", GetLastError()); return; From 21bf9d1a88c0d9113de9302c1072974167aa9921 Mon Sep 17 00:00:00 2001 From: David Parks Date: Tue, 7 Feb 2017 12:00:45 -0800 Subject: [PATCH 122/234] Bug 1284897 - Add missing hooked methods to TestDllInterceptor. r=aklotz Added ASSERTions to nsWindowsDllInterceptor in case of a failed detour hook, with an exception for the RET opcode that appears in ImmReleaseContext. Added documentation about TestDllInterceptor. --HG-- extra : rebase_source : a3c6fe0949f5503979a062bdaa5f35526ddee73b --- toolkit/xre/test/win/TestDllInterceptor.cpp | 9 ++++- xpcom/build/nsWindowsDllInterceptor.h | 42 ++++++++++++++++++++- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/toolkit/xre/test/win/TestDllInterceptor.cpp b/toolkit/xre/test/win/TestDllInterceptor.cpp index 57d68ea779a7..c03554e89d61 100644 --- a/toolkit/xre/test/win/TestDllInterceptor.cpp +++ b/toolkit/xre/test/win/TestDllInterceptor.cpp @@ -209,15 +209,20 @@ int main() TestHook("kernel32.dll", "VirtualAlloc") && TestHook("kernel32.dll", "MapViewOfFile") && TestHook("gdi32.dll", "CreateDIBSection") && - TestHook("kernel32.dll", "CreateFileW") && + TestHook("kernel32.dll", "CreateFileW") && // see Bug 1316415 #endif + TestHook("kernel32.dll", "CreateFileA") && TestDetour("user32.dll", "CreateWindowExW") && TestHook("user32.dll", "InSendMessageEx") && TestHook("imm32.dll", "ImmGetContext") && + // TestHook("imm32.dll", "ImmReleaseContext") && // see Bug 1316415 TestHook("imm32.dll", "ImmGetCompositionStringW") && TestHook("imm32.dll", "ImmSetCandidateWindow") && + TestHook("imm32.dll", "ImmNotifyIME") && + TestHook("comdlg32.dll", "GetSaveFileNameW") && + TestHook("comdlg32.dll", "GetOpenFileNameW") && #ifdef _M_X64 - TestHook("user32.dll", "GetKeyState") && + TestHook("user32.dll", "GetKeyState") && // see Bug 1316415 #endif MaybeTestHook(ShouldTestTipTsf(), "tiptsf.dll", "ProcessCaretEvents") && #ifdef _M_IX86 diff --git a/xpcom/build/nsWindowsDllInterceptor.h b/xpcom/build/nsWindowsDllInterceptor.h index 81ef9bf55319..4e00635fa043 100644 --- a/xpcom/build/nsWindowsDllInterceptor.h +++ b/xpcom/build/nsWindowsDllInterceptor.h @@ -700,6 +700,7 @@ protected: if (numPrefixBytes < 0 || (prefixGroups & (ePrefixGroup3 | ePrefixGroup4))) { // Either the prefix sequence was bad, or there are prefixes that // we don't currently support (groups 3 and 4) + MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence"); return; } nOrigBytes += numPrefixBytes; @@ -709,6 +710,7 @@ protected: ++nOrigBytes; int len = CountModRmSib(origBytes + nOrigBytes); if (len < 0) { + MOZ_ASSERT_UNREACHABLE("Unrecognized MOV opcode sequence"); return; } nOrigBytes += len; @@ -733,6 +735,7 @@ protected: nOrigBytes += 3; } else { // bail + MOZ_ASSERT_UNREACHABLE("Unrecognized bit opcode sequence"); return; } } else if (origBytes[nOrigBytes] == 0x68) { @@ -759,7 +762,8 @@ protected: #endif return; } else { - //printf ("Unknown x86 instruction byte 0x%02x, aborting trampoline\n", origBytes[nBytes]); + //printf ("Unknown x86 instruction byte 0x%02x, aborting trampoline\n", origBytes[nOrigBytes]); + MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence"); return; } } @@ -786,6 +790,7 @@ protected: nOrigBytes++; continue; } + MOZ_ASSERT_UNREACHABLE("Opcode sequence includes commands after JMP"); return; } if (origBytes[nOrigBytes] == 0x0f) { @@ -797,6 +802,7 @@ protected: (origBytes[nOrigBytes] & 0x7) == 0x04) { COPY_CODES(3); } else { + MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence"); return; } } else if (origBytes[nOrigBytes] == 0x05) { @@ -811,6 +817,7 @@ protected: nTrampBytes = jump.GenerateJump(tramp); nOrigBytes += 5; } else { + MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence"); return; } } else if (origBytes[nOrigBytes] == 0x40 || @@ -824,6 +831,7 @@ protected: // mov r32, imm32 COPY_CODES(5); } else { + MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence"); return; } } else if (origBytes[nOrigBytes] == 0x45) { @@ -834,6 +842,7 @@ protected: // xor r32, r32 COPY_CODES(2); } else { + MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence"); return; } } else if ((origBytes[nOrigBytes] & 0xfb) == 0x48) { @@ -865,6 +874,7 @@ protected: if ((origBytes[nOrigBytes + 1] & 0xc0) == 0xc0) { COPY_CODES(2); } else { + MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence"); return; } } else if ((origBytes[nOrigBytes] & 0xfd) == 0x89) { @@ -872,6 +882,7 @@ protected: // MOV r/m64, r64 | MOV r64, r/m64 int len = CountModRmSib(origBytes + nOrigBytes); if (len < 0) { + MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence"); return; } COPY_CODES(len); @@ -882,6 +893,7 @@ protected: // ModR/W + SIB + disp8 + imm32 COPY_CODES(8); } else { + MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence"); return; } } else if (origBytes[nOrigBytes] == 0xff) { @@ -899,10 +911,12 @@ protected: foundJmp = true; } else { // not support yet! + MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence"); return; } } else { // not support yet! + MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence"); return; } } else if (origBytes[nOrigBytes] == 0x66) { @@ -927,6 +941,7 @@ protected: } } else { // complex MOV, bail + MOZ_ASSERT_UNREACHABLE("Unrecognized MOV opcode sequence"); return; } } @@ -945,10 +960,12 @@ protected: int len = CountModRmSib(origBytes + nOrigBytes); if (len < 0) { // no way to support this yet. + MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence"); return; } COPY_CODES(len); } else { + MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence"); return; } } else if (origBytes[nOrigBytes] == 0x90) { @@ -968,6 +985,7 @@ protected: int nModRmSibBytes = CountModRmSib(&origBytes[nOrigBytes + 1], &subOpcode); if (nModRmSibBytes < 0 || subOpcode != 0) { // Unsupported + MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence"); return; } COPY_CODES(2 + nModRmSibBytes); @@ -1007,9 +1025,11 @@ protected: nTrampBytes = jump.GenerateJump(tramp); nOrigBytes += 5; } else { + MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence"); return; } } else { + MOZ_ASSERT_UNREACHABLE("Unrecognized opcode sequence"); return; } } @@ -1145,6 +1165,16 @@ public: } } + /** + * Hook/detour the method aName from the DLL we set in Init so that it calls + * aHookDest instead. Returns the original method pointer in aOrigFunc + * and returns true if successful. + * + * IMPORTANT: If you use this method, please add your case to the + * TestDllInterceptor in order to detect future failures. Even if this + * succeeds now, updates to the hooked DLL could cause it to fail in + * the future. + */ bool AddHook(const char* aName, intptr_t aHookDest, void** aOrigFunc) { // Use a nop space patch if possible, otherwise fall back to a detour. @@ -1161,6 +1191,16 @@ public: return AddDetour(aName, aHookDest, aOrigFunc); } + /** + * Detour the method aName from the DLL we set in Init so that it calls + * aHookDest instead. Returns the original method pointer in aOrigFunc + * and returns true if successful. + * + * IMPORTANT: If you use this method, please add your case to the + * TestDllInterceptor in order to detect future failures. Even if this + * succeeds now, updates to the detoured DLL could cause it to fail in + * the future. + */ bool AddDetour(const char* aName, intptr_t aHookDest, void** aOrigFunc) { // Generally, code should not call this method directly. Use AddHook unless From 26437f4ecdc16377619e5288c63f257304dd05f3 Mon Sep 17 00:00:00 2001 From: David Parks Date: Tue, 14 Feb 2017 15:08:40 -0800 Subject: [PATCH 123/234] Bug 1284897 - Add mechanism to libsandbox_s to track names of files that have been given special sandbox access permissions (PermissionsService). r=bobowen, r=glandium Hook this into the browser via the XREAppData. This patch does not include the changes to Chromium source code. --HG-- extra : rebase_source : 4d5637bcdbeae605b0b99e9192598d48f371b698 --- browser/app/nsBrowserApp.cpp | 3 + .../sandbox/win/permissionsService.cpp | 136 ++++++++++++++++++ .../sandbox/win/permissionsService.h | 78 ++++++++++ security/sandbox/moz.build | 3 + .../sandbox/win/SandboxInitialization.cpp | 6 + security/sandbox/win/SandboxInitialization.h | 4 + .../win/src/sandboxpermissions/moz.build | 22 +++ .../sandboxpermissions/sandboxPermissions.cpp | 41 ++++++ .../sandboxpermissions/sandboxPermissions.h | 57 ++++++++ toolkit/xre/Bootstrap.h | 7 + toolkit/xre/nsAppRunner.cpp | 6 + xpcom/build/XREAppData.h | 6 + xpcom/glue/XREAppData.cpp | 1 + 13 files changed, 370 insertions(+) create mode 100644 security/sandbox/chromium-shim/sandbox/win/permissionsService.cpp create mode 100644 security/sandbox/chromium-shim/sandbox/win/permissionsService.h create mode 100644 security/sandbox/win/src/sandboxpermissions/moz.build create mode 100644 security/sandbox/win/src/sandboxpermissions/sandboxPermissions.cpp create mode 100644 security/sandbox/win/src/sandboxpermissions/sandboxPermissions.h diff --git a/browser/app/nsBrowserApp.cpp b/browser/app/nsBrowserApp.cpp index d6a6fff66748..6a5945307d47 100644 --- a/browser/app/nsBrowserApp.cpp +++ b/browser/app/nsBrowserApp.cpp @@ -217,6 +217,8 @@ static int do_main(int argc, char* argv[], char* envp[]) #if defined(XP_WIN) && defined(MOZ_SANDBOX) sandbox::BrokerServices* brokerServices = sandboxing::GetInitializedBrokerServices(); + sandboxing::PermissionsService* permissionsService = + sandboxing::GetPermissionsService(); #if defined(MOZ_CONTENT_SANDBOX) if (!brokerServices) { Output("Couldn't initialize the broker services.\n"); @@ -224,6 +226,7 @@ static int do_main(int argc, char* argv[], char* envp[]) } #endif config.sandboxBrokerServices = brokerServices; + config.sandboxPermissionsService = permissionsService; #endif #ifdef LIBFUZZER diff --git a/security/sandbox/chromium-shim/sandbox/win/permissionsService.cpp b/security/sandbox/chromium-shim/sandbox/win/permissionsService.cpp new file mode 100644 index 000000000000..13db7ca4ee84 --- /dev/null +++ b/security/sandbox/chromium-shim/sandbox/win/permissionsService.cpp @@ -0,0 +1,136 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* SandboxPermissions.cpp - Special permissions granted to sandboxed processes */ + +#include "permissionsService.h" +#include +#include + +namespace mozilla { +namespace sandboxing { + +static const std::wstring ZONE_IDENTIFIER_STR(L":ZONE.IDENTIFIER"); +static const std::wstring ZONE_ID_DATA_STR(L":ZONE.IDENTIFIER:$DATA"); + +bool +StringEndsWith(const std::wstring& str, const std::wstring& strEnding) +{ + if (strEnding.size() > str.size()) { + return false; + } + return std::equal(strEnding.rbegin(), strEnding.rend(), str.rbegin()); +} + +// Converts NT device internal filenames to normal user-space by stripping +// the prefixes and suffixes from the file name. +std::wstring +GetPlainFileName(const wchar_t* aNTFileName) +{ + while (*aNTFileName == L'\\' || *aNTFileName == L'.' || + *aNTFileName == L'?' || *aNTFileName == L':' ) { + ++aNTFileName; + } + std::wstring nameCopy(aNTFileName); + std::transform(nameCopy.begin(), nameCopy.end(), nameCopy.begin(), towupper); + if (StringEndsWith(nameCopy, ZONE_ID_DATA_STR)) { + nameCopy = nameCopy.substr(0, nameCopy.size() - ZONE_ID_DATA_STR.size()); + } else if (StringEndsWith(nameCopy, ZONE_IDENTIFIER_STR)) { + nameCopy = nameCopy.substr(0, nameCopy.size() - ZONE_IDENTIFIER_STR.size()); + } + return nameCopy; +} + +/* static */ PermissionsService* +PermissionsService::GetInstance() +{ + static PermissionsService sPermissionsService; + return &sPermissionsService; +} + +PermissionsService::PermissionsService() : + mFileAccessViolationFunc(nullptr) +{ +} + +void +PermissionsService::GrantFileAccess(uint32_t aProcessId, + const wchar_t* aFilename, + bool aPermitWrite) +{ + FilePermissionMap& permissions = mProcessFilePermissions[aProcessId]; + std::wstring filename = GetPlainFileName(aFilename); + permissions[filename] |= aPermitWrite; +} + +void +PermissionsService::SetFileAccessViolationFunc(FileAccessViolationFunc aFavFunc) +{ + mFileAccessViolationFunc = aFavFunc; +} + +void +PermissionsService::ReportBlockedFile(bool aNeedsWrite) +{ + if (mFileAccessViolationFunc) { + mFileAccessViolationFunc(aNeedsWrite); + } +} + +bool +PermissionsService::UserGrantedFileAccess(uint32_t aProcessId, + const wchar_t* aFilename, + uint32_t aAccess, + uint32_t aDisposition) +{ + // There are 3 types of permissions: + // * Those available w/ read-only permission + // * Those available w/ read-only AND read-write permission + // * Those always forbidden. + const uint32_t FORBIDDEN_FLAGS = + FILE_EXECUTE | FILE_LIST_DIRECTORY | FILE_TRAVERSE | STANDARD_RIGHTS_EXECUTE; + const uint32_t NEEDS_WRITE_FLAGS = + FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | + DELETE | STANDARD_RIGHTS_WRITE; + bool needsWrite = + (aAccess & NEEDS_WRITE_FLAGS) || (aDisposition != FILE_OPEN); + + if (aAccess & FORBIDDEN_FLAGS) { + ReportBlockedFile(needsWrite); + return false; + } + + auto permissions = mProcessFilePermissions.find(aProcessId); + if (permissions == mProcessFilePermissions.end()) { + ReportBlockedFile(needsWrite); + return false; // process has no special file access at all + } + + std::wstring filename = GetPlainFileName(aFilename); + auto itPermission = permissions->second.find(filename); + if (itPermission == permissions->second.end()) { + ReportBlockedFile(needsWrite); + return false; // process has no access to this file + } + + // We have read permission. Check for write permission if requested. + if (!needsWrite || itPermission->second) { + return true; + } + + // We needed write access but didn't have it. + ReportBlockedFile(needsWrite); + return false; +} + +void +PermissionsService::RemovePermissionsForProcess(uint32_t aProcessId) +{ + mProcessFilePermissions.erase(aProcessId); +} + +} // namespace sandboxing +} // namespace mozilla diff --git a/security/sandbox/chromium-shim/sandbox/win/permissionsService.h b/security/sandbox/chromium-shim/sandbox/win/permissionsService.h new file mode 100644 index 000000000000..8e8eefdb8c14 --- /dev/null +++ b/security/sandbox/chromium-shim/sandbox/win/permissionsService.h @@ -0,0 +1,78 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_sandboxing_permissionsService_h +#define mozilla_sandboxing_permissionsService_h + +#include + +namespace mozilla { +namespace sandboxing { + +/* + * Represents additional permissions granted to sandboxed processes. + * The members are virtual so that the object can be created in any + * library that links with libsandbox_s and then shared with and used + * by libXUL, which does not link with libsandbox_s. + */ +class PermissionsService +{ +public: + static PermissionsService* GetInstance(); + + /* + * Allow future access to aFilename by the plugin process. + */ + virtual void GrantFileAccess(uint32_t aProcessId, const wchar_t* aFilename, + bool aPermitWrite); + + /* + * Type of callback function that the sandbox uses to report file + * accesses that were denied. + * Parameter is a boolean indicating the access request was read-only + * (false) or read-write (true) + */ + typedef void (*FileAccessViolationFunc)(bool); + + /* + * Sets the callback function that is called whenever a file access is + * denied by the sandbox. + */ + virtual void SetFileAccessViolationFunc(FileAccessViolationFunc aFavFunc); + + /* + * Returns true if the user has granted the sandboxed plugin process the + * requested permission to open the file. + * Calls aFavFunc with file info if the file access was blocked. + */ + virtual bool UserGrantedFileAccess(uint32_t aProcessId, const wchar_t* aFilename, + uint32_t aAccess, uint32_t aDisposition); + + /* + * Clears all special file access for the given plugin process. + */ + virtual void RemovePermissionsForProcess(uint32_t aProcessId); + +private: + PermissionsService(); + void ReportBlockedFile(bool aNeedsWrite); + + // Maps from filenames to a boolean indicating read-only permission (false) or + // read-write permission (true). + typedef std::unordered_map FilePermissionMap; + + // Maps from process ID to map of user-granted file permissions for + // that process. + typedef std::unordered_map ProcessFilePermissionMap; + + ProcessFilePermissionMap mProcessFilePermissions; + FileAccessViolationFunc mFileAccessViolationFunc; +}; + +} // namespace sandboxing +} // namespace mozilla + +#endif // mozilla_sandboxing_permissionsService_h diff --git a/security/sandbox/moz.build b/security/sandbox/moz.build index 1420d6498af9..2c93a7fda5ca 100644 --- a/security/sandbox/moz.build +++ b/security/sandbox/moz.build @@ -19,6 +19,7 @@ elif CONFIG['OS_ARCH'] == 'WINNT': DIRS += [ 'win/src/sandboxbroker', + 'win/src/sandboxpermissions', 'win/src/sandboxtarget', ] @@ -29,6 +30,7 @@ elif CONFIG['OS_ARCH'] == 'WINNT': EXPORTS.mozilla.sandboxing += [ 'chromium-shim/sandbox/win/loggingCallbacks.h', 'chromium-shim/sandbox/win/loggingTypes.h', + 'chromium-shim/sandbox/win/permissionsService.h', 'chromium-shim/sandbox/win/sandboxLogging.h', 'win/SandboxInitialization.h', ] @@ -36,6 +38,7 @@ elif CONFIG['OS_ARCH'] == 'WINNT': SOURCES += [ 'chromium-shim/base/files/file_path.cpp', 'chromium-shim/base/logging.cpp', + 'chromium-shim/sandbox/win/permissionsService.cpp', 'chromium-shim/sandbox/win/sandboxLogging.cpp', 'chromium/base/at_exit.cc', 'chromium/base/base_switches.cc', diff --git a/security/sandbox/win/SandboxInitialization.cpp b/security/sandbox/win/SandboxInitialization.cpp index e587c2598307..9b773955c781 100644 --- a/security/sandbox/win/SandboxInitialization.cpp +++ b/security/sandbox/win/SandboxInitialization.cpp @@ -7,6 +7,7 @@ #include "SandboxInitialization.h" #include "sandbox/win/src/sandbox_factory.h" +#include "mozilla/sandboxing/permissionsService.h" namespace mozilla { namespace sandboxing { @@ -77,5 +78,10 @@ GetInitializedBrokerServices() return sInitializedBrokerServices; } +PermissionsService* GetPermissionsService() +{ + return PermissionsService::GetInstance(); +} + } // sandboxing } // mozilla diff --git a/security/sandbox/win/SandboxInitialization.h b/security/sandbox/win/SandboxInitialization.h index e5be08904f41..8ef926fb91f4 100644 --- a/security/sandbox/win/SandboxInitialization.h +++ b/security/sandbox/win/SandboxInitialization.h @@ -21,6 +21,8 @@ namespace mozilla { // sandbox for our namespace painful. namespace sandboxing { +class PermissionsService; + /** * Initializes (if required) and returns the Chromium sandbox TargetServices. * @@ -41,6 +43,8 @@ void LowerSandbox(); */ sandbox::BrokerServices* GetInitializedBrokerServices(); +PermissionsService* GetPermissionsService(); + } // sandboxing } // mozilla diff --git a/security/sandbox/win/src/sandboxpermissions/moz.build b/security/sandbox/win/src/sandboxpermissions/moz.build new file mode 100644 index 000000000000..5a802b79c11e --- /dev/null +++ b/security/sandbox/win/src/sandboxpermissions/moz.build @@ -0,0 +1,22 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +SOURCES += [ + 'sandboxPermissions.cpp', +] + +EXPORTS += [ + 'sandboxPermissions.h', +] + +for var in ('UNICODE', '_UNICODE'): + DEFINES[var] = True + +LOCAL_INCLUDES += [ + '/security/sandbox/win', +] + +FINAL_LIBRARY = 'xul' diff --git a/security/sandbox/win/src/sandboxpermissions/sandboxPermissions.cpp b/security/sandbox/win/src/sandboxpermissions/sandboxPermissions.cpp new file mode 100644 index 000000000000..68668ec12f93 --- /dev/null +++ b/security/sandbox/win/src/sandboxpermissions/sandboxPermissions.cpp @@ -0,0 +1,41 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "sandboxPermissions.h" +#include "mozilla/Assertions.h" +#include "mozilla/sandboxing/permissionsService.h" + +namespace mozilla +{ + +sandboxing::PermissionsService* SandboxPermissions::sPermissionsService = nullptr; + +void +SandboxPermissions::Initialize(sandboxing::PermissionsService* aPermissionsService, + FileAccessViolationFunc aFileAccessViolationFunc) +{ + sPermissionsService = aPermissionsService; + sPermissionsService->SetFileAccessViolationFunc(aFileAccessViolationFunc); +} + +void +SandboxPermissions::GrantFileAccess(uint32_t aProcessId, const wchar_t* aFilename, + bool aPermitWrite) +{ + MOZ_ASSERT(sPermissionsService, "Must initialize sandbox PermissionsService"); + sPermissionsService->GrantFileAccess(aProcessId, aFilename, aPermitWrite); +} + +void +SandboxPermissions::RemovePermissionsForProcess(uint32_t aProcessId) +{ + if (!sPermissionsService) { + return; // No permissions service was initialized + } + sPermissionsService->RemovePermissionsForProcess(aProcessId); +} + +} // namespace mozilla diff --git a/security/sandbox/win/src/sandboxpermissions/sandboxPermissions.h b/security/sandbox/win/src/sandboxpermissions/sandboxPermissions.h new file mode 100644 index 000000000000..4e71e51670a4 --- /dev/null +++ b/security/sandbox/win/src/sandboxpermissions/sandboxPermissions.h @@ -0,0 +1,57 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_sandboxing_sandboxPermissions_h +#define mozilla_sandboxing_sandboxPermissions_h + +#include +#include + +namespace mozilla { + +namespace sandboxing { + class PermissionsService; +} + +/* + * This object wraps a PermissionsService object. This object is available + * in libXUL but PermissionsService is not. + */ +class SandboxPermissions +{ +public: + /* + * Type of callback function that the sandbox uses to report file + * accesses that were denied. + * Parameter is a boolean indicating the access request was read-only + * (false) or read-write (true) + */ + typedef void (*FileAccessViolationFunc)(bool); + + /* + * Prepare this object by providing it with the internal permissions service. + */ + static void Initialize(sandboxing::PermissionsService* aPermissionsService, + FileAccessViolationFunc aFileAccessViolationFunc); + + /* + * Allow future access to aFilename by the process with the given ID. + */ + void GrantFileAccess(uint32_t aProcessId, const wchar_t* aFilename, + bool aPermitWrite); + + /* + * Clears all special file access for the given process. + */ + void RemovePermissionsForProcess(uint32_t aProcessId); + +private: + static sandboxing::PermissionsService* sPermissionsService; +}; + +} // mozilla + +#endif // mozilla_sandboxing_sandboxPermissions_h diff --git a/toolkit/xre/Bootstrap.h b/toolkit/xre/Bootstrap.h index e0a8d02e6776..7d80999eac1a 100644 --- a/toolkit/xre/Bootstrap.h +++ b/toolkit/xre/Bootstrap.h @@ -31,11 +31,18 @@ class BrokerServices; namespace mozilla { +#if defined(XP_WIN) && defined(MOZ_SANDBOX) +namespace sandboxing { +class PermissionsService; +} +#endif + struct BootstrapConfig { #if defined(XP_WIN) && defined(MOZ_SANDBOX) /* Chromium sandbox BrokerServices. */ sandbox::BrokerServices* sandboxBrokerServices; + sandboxing::PermissionsService* sandboxPermissionsService; #endif /* Pointer to static XRE AppData from application.ini.h */ const StaticXREAppData* appData; diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index a4b5997eb004..07e1d6e6161b 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -215,6 +215,7 @@ #include "mozilla/SandboxInfo.h" #elif defined(XP_WIN) #include "SandboxBroker.h" +#include "SandboxPermissions.h" #endif #endif @@ -3319,6 +3320,10 @@ XREMain::XRE_mainInit(bool* aExitFlag) NS_WARNING("Failed to initialize broker services, sandboxed processes will " "fail to start."); } + if (mAppData->sandboxPermissionsService) { + SandboxPermissions::Initialize(mAppData->sandboxPermissionsService, + nullptr); + } #endif #ifdef XP_MACOSX @@ -4607,6 +4612,7 @@ XREMain::XRE_main(int argc, char* argv[], const BootstrapConfig& aConfig) #if defined(XP_WIN) && defined(MOZ_SANDBOX) mAppData->sandboxBrokerServices = aConfig.sandboxBrokerServices; + mAppData->sandboxPermissionsService = aConfig.sandboxPermissionsService; #endif mozilla::IOInterposerInit ioInterposerGuard; diff --git a/xpcom/build/XREAppData.h b/xpcom/build/XREAppData.h index b94946fec2e8..df3e6b8d1e50 100644 --- a/xpcom/build/XREAppData.h +++ b/xpcom/build/XREAppData.h @@ -17,6 +17,11 @@ namespace sandbox { class BrokerServices; } +namespace mozilla { +namespace sandboxing { +class PermissionsService; +} +} #endif namespace mozilla { @@ -194,6 +199,7 @@ public: * Chromium sandbox BrokerServices. */ sandbox::BrokerServices* sandboxBrokerServices = nullptr; + mozilla::sandboxing::PermissionsService* sandboxPermissionsService; #endif }; diff --git a/xpcom/glue/XREAppData.cpp b/xpcom/glue/XREAppData.cpp index 8aef2e16c043..130ef4ec2d17 100644 --- a/xpcom/glue/XREAppData.cpp +++ b/xpcom/glue/XREAppData.cpp @@ -49,6 +49,7 @@ XREAppData::operator=(const XREAppData& aOther) UAName = aOther.UAName; #if defined(XP_WIN) && defined(MOZ_SANDBOX) sandboxBrokerServices = aOther.sandboxBrokerServices; + sandboxPermissionsService = aOther.sandboxPermissionsService; #endif return *this; } From 7f64ae96ea1b5185317b8c76b11dbb3e9079bc2a Mon Sep 17 00:00:00 2001 From: David Parks Date: Fri, 20 Jan 2017 08:27:57 -0800 Subject: [PATCH 124/234] Bug 1284897 - Add mechanism to libsandbox_s to track names of files that have been given special sandbox access permissions (PermissionsService). r=bobowen Hook this into the browser via the XREAppData. This patch contains only the changes to Chromium source code. --HG-- extra : rebase_source : f1ddd3bdfb52cef0a2dc8bfbae4ba5c78e7fd7eb --- .../sandbox/win/src/filesystem_dispatcher.cc | 22 +++++++++++++++++++ .../win/src/filesystem_interception.cc | 6 ----- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/security/sandbox/chromium/sandbox/win/src/filesystem_dispatcher.cc b/security/sandbox/chromium/sandbox/win/src/filesystem_dispatcher.cc index 6f96be2402c3..f3f84c690cd6 100644 --- a/security/sandbox/chromium/sandbox/win/src/filesystem_dispatcher.cc +++ b/security/sandbox/chromium/sandbox/win/src/filesystem_dispatcher.cc @@ -17,6 +17,8 @@ #include "sandbox/win/src/sandbox.h" #include "sandbox/win/src/sandbox_nt_util.h" +#include "mozilla/sandboxing/permissionsService.h" + namespace sandbox { FilesystemDispatcher::FilesystemDispatcher(PolicyBase* policy_base) @@ -115,6 +117,16 @@ bool FilesystemDispatcher::NtCreateFile(IPCInfo* ipc, // knows what to do. EvalResult result = policy_base_->EvalPolicy(IPC_NTCREATEFILE_TAG, params.GetBase()); + + // If the policies forbid access (any result other than ASK_BROKER), + // then check for user-granted access to file. + if (ASK_BROKER != result && + mozilla::sandboxing::PermissionsService::GetInstance()-> + UserGrantedFileAccess(ipc->client_info->process_id, filename, + desired_access, create_disposition)) { + result = ASK_BROKER; + } + HANDLE handle; ULONG_PTR io_information = 0; NTSTATUS nt_status; @@ -162,6 +174,16 @@ bool FilesystemDispatcher::NtOpenFile(IPCInfo* ipc, // knows what to do. EvalResult result = policy_base_->EvalPolicy(IPC_NTOPENFILE_TAG, params.GetBase()); + + // If the policies forbid access (any result other than ASK_BROKER), + // then check for user-granted access to file. + if (ASK_BROKER != result && + mozilla::sandboxing::PermissionsService::GetInstance()->UserGrantedFileAccess( + ipc->client_info->process_id, filename, + desired_access, create_disposition)) { + result = ASK_BROKER; + } + HANDLE handle; ULONG_PTR io_information = 0; NTSTATUS nt_status; diff --git a/security/sandbox/chromium/sandbox/win/src/filesystem_interception.cc b/security/sandbox/chromium/sandbox/win/src/filesystem_interception.cc index 1da2b43db364..85e85e29cfb9 100644 --- a/security/sandbox/chromium/sandbox/win/src/filesystem_interception.cc +++ b/security/sandbox/chromium/sandbox/win/src/filesystem_interception.cc @@ -70,9 +70,6 @@ NTSTATUS WINAPI TargetNtCreateFile(NtCreateFileFunction orig_CreateFile, params[OpenFile::OPTIONS] = ParamPickerMake(options_uint32); params[OpenFile::BROKER] = ParamPickerMake(broker); - if (!QueryBroker(IPC_NTCREATEFILE_TAG, params.GetBase())) - break; - SharedMemIPCClient ipc(memory); CrossCallReturn answer = {0}; // The following call must match in the parameters with @@ -153,9 +150,6 @@ NTSTATUS WINAPI TargetNtOpenFile(NtOpenFileFunction orig_OpenFile, PHANDLE file, params[OpenFile::OPTIONS] = ParamPickerMake(options_uint32); params[OpenFile::BROKER] = ParamPickerMake(broker); - if (!QueryBroker(IPC_NTOPENFILE_TAG, params.GetBase())) - break; - SharedMemIPCClient ipc(memory); CrossCallReturn answer = {0}; ResultCode code = CrossCall(ipc, IPC_NTOPENFILE_TAG, name, attributes, From d1cbd41a41c7541733e2d292e45266540ff3528d Mon Sep 17 00:00:00 2001 From: Johan Lorenzo Date: Thu, 16 Feb 2017 18:51:25 +0100 Subject: [PATCH 125/234] Bug 1337825 - Jamun: Change android-api-15-{l10n,nightly} to l10n bumped file r=aki Also adds missing files MozReview-Commit-ID: C0G6bE6wmK4 --- taskcluster/ci/l10n/kind.yml | 2 +- taskcluster/ci/nightly-l10n/kind.yml | 2 +- .../multi_locale/jamun_android-armv6.json | 28 ++++++ .../multi_locale/jamun_android-x86.json | 28 ++++++ .../configs/multi_locale/jamun_android.json | 27 ++++++ .../mozharness/configs/single_locale/jamun.py | 35 +++++++ .../single_locale/jamun_android-api-15.py | 94 +++++++++++++++++++ 7 files changed, 214 insertions(+), 2 deletions(-) create mode 100644 testing/mozharness/configs/multi_locale/jamun_android-armv6.json create mode 100644 testing/mozharness/configs/multi_locale/jamun_android-x86.json create mode 100644 testing/mozharness/configs/multi_locale/jamun_android.json create mode 100644 testing/mozharness/configs/single_locale/jamun.py create mode 100644 testing/mozharness/configs/single_locale/jamun_android-api-15.py diff --git a/taskcluster/ci/l10n/kind.yml b/taskcluster/ci/l10n/kind.yml index 0904b70dc046..e2adb679782c 100644 --- a/taskcluster/ci/l10n/kind.yml +++ b/taskcluster/ci/l10n/kind.yml @@ -27,7 +27,7 @@ job-template: locales-file: by-build-platform: default: browser/locales/all-locales - android-api-15-l10n: mobile/android/locales/all-locales + android-api-15-l10n: mobile/locales/l10n-changesets.json run-time: by-build-platform: default: 36000 diff --git a/taskcluster/ci/nightly-l10n/kind.yml b/taskcluster/ci/nightly-l10n/kind.yml index f0970fb39dd1..6ae5bd0629da 100644 --- a/taskcluster/ci/nightly-l10n/kind.yml +++ b/taskcluster/ci/nightly-l10n/kind.yml @@ -26,7 +26,7 @@ job-template: locales-file: by-build-platform: default: browser/locales/all-locales - android-api-15-nightly: mobile/android/locales/all-locales + android-api-15-nightly: mobile/locales/l10n-changesets.json chunks: 6 run-time: by-build-platform: diff --git a/testing/mozharness/configs/multi_locale/jamun_android-armv6.json b/testing/mozharness/configs/multi_locale/jamun_android-armv6.json new file mode 100644 index 000000000000..2de82ad87b91 --- /dev/null +++ b/testing/mozharness/configs/multi_locale/jamun_android-armv6.json @@ -0,0 +1,28 @@ +{ + "work_dir": ".", + "log_name": "multilocale", + "objdir": "obj-firefox", + "locales_file": "build/mobile/locales/l10n-changesets.json", + "locales_dir": "mobile/android/locales", + "ignore_locales": ["en-US", "multi"], + "repos": [{ + "repo": "https://hg.mozilla.org/jamun", + "branch": "default", + "dest": "build" + },{ + "repo": "https://hg.mozilla.org/build/buildbot-configs", + "branch": "production", + "dest": "build/configs" + },{ + "repo": "https://hg.mozilla.org/build/tools", + "branch": "default", + "dest": "tools" + }], + "vcs_share_base": "/builds/hg-shared", + "hg_l10n_base": "https://hg.mozilla.org/releases/l10n/mozilla-aurora", + "hg_l10n_tag": "default", + "l10n_dir": "mozilla-aurora", + "merge_locales": true, + "mozilla_dir": "build", + "mozconfig": "build/mobile/android/config/mozconfigs/android-armv6/nightly" +} diff --git a/testing/mozharness/configs/multi_locale/jamun_android-x86.json b/testing/mozharness/configs/multi_locale/jamun_android-x86.json new file mode 100644 index 000000000000..f843d27ed263 --- /dev/null +++ b/testing/mozharness/configs/multi_locale/jamun_android-x86.json @@ -0,0 +1,28 @@ +{ + "work_dir": ".", + "log_name": "multilocale", + "objdir": "obj-firefox", + "locales_file": "build/mobile/locales/l10n-changesets.json", + "locales_dir": "mobile/android/locales", + "ignore_locales": ["en-US", "multi"], + "repos": [{ + "repo": "https://hg.mozilla.org/jamun", + "branch": "default", + "dest": "build" + },{ + "repo": "https://hg.mozilla.org/build/buildbot-configs", + "branch": "production", + "dest": "build/configs" + },{ + "repo": "https://hg.mozilla.org/build/tools", + "branch": "default", + "dest": "tools" + }], + "vcs_share_base": "/builds/hg-shared", + "hg_l10n_base": "https://hg.mozilla.org/releases/l10n/mozilla-aurora", + "hg_l10n_tag": "default", + "l10n_dir": "mozilla-aurora", + "merge_locales": true, + "mozilla_dir": "build", + "mozconfig": "build/mobile/android/config/mozconfigs/android-x86/nightly" +} diff --git a/testing/mozharness/configs/multi_locale/jamun_android.json b/testing/mozharness/configs/multi_locale/jamun_android.json new file mode 100644 index 000000000000..dced5bfa9c46 --- /dev/null +++ b/testing/mozharness/configs/multi_locale/jamun_android.json @@ -0,0 +1,27 @@ +{ + "work_dir": ".", + "log_name": "multilocale", + "objdir": "obj-firefox", + "locales_file": "build/mobile/locales/l10n-changesets.json", + "locales_dir": "mobile/android/locales", + "ignore_locales": ["en-US", "multi"], + "repos": [{ + "repo": "https://hg.mozilla.org/jamun", + "branch": "default", + "dest": "build" + },{ + "repo": "https://hg.mozilla.org/build/buildbot-configs", + "branch": "production", + "dest": "build/configs" + },{ + "repo": "https://hg.mozilla.org/build/tools", + "branch": "default", + "dest": "tools" + }], + "vcs_share_base": "/builds/hg-shared", + "hg_l10n_base": "https://hg.mozilla.org/releases/l10n/mozilla-aurora", + "hg_l10n_tag": "default", + "l10n_dir": "mozilla-aurora", + "merge_locales": true, + "mozilla_dir": "build" +} diff --git a/testing/mozharness/configs/single_locale/jamun.py b/testing/mozharness/configs/single_locale/jamun.py new file mode 100644 index 000000000000..905ca162e215 --- /dev/null +++ b/testing/mozharness/configs/single_locale/jamun.py @@ -0,0 +1,35 @@ +import os + +config = { + "nightly_build": True, + "branch": "jamun", + "en_us_binary_url": "http://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central", + "update_channel": "nightly-jamun", + "latest_mar_dir": '/pub/firefox/nightly/latest-jamun-l10n', + + # l10n + "hg_l10n_base": "https://hg.mozilla.org/releases/l10n/mozilla-aurora", + + # mar + "mar_tools_url": os.environ.get( + "MAR_TOOLS_URL", + # Buildbot l10n fetches from ftp rather than setting an environ var + "http://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/latest-mozilla-central/mar-tools/%(platform)s" + ), + + # repositories + "mozilla_dir": "jamun", + "repos": [{ + "vcs": "hg", + "repo": "https://hg.mozilla.org/build/tools", + "branch": "default", + "dest": "tools", + }, { + "vcs": "hg", + "repo": "https://hg.mozilla.org/projects/jamun", + "revision": "%(revision)s", + "dest": "jamun", + }], + # purge options + 'is_automation': True, +} diff --git a/testing/mozharness/configs/single_locale/jamun_android-api-15.py b/testing/mozharness/configs/single_locale/jamun_android-api-15.py new file mode 100644 index 000000000000..4c9fafcd0dd5 --- /dev/null +++ b/testing/mozharness/configs/single_locale/jamun_android-api-15.py @@ -0,0 +1,94 @@ +import os + +BRANCH = "jamun" +MOZILLA_DIR = BRANCH +EN_US_BINARY_URL = None # No build has been uploaded to archive.m.o + +config = { + "branch": BRANCH, + "log_name": "single_locale", + "objdir": "obj-l10n", + "is_automation": True, + "buildbot_json_path": "buildprops.json", + "force_clobber": True, + "clobberer_url": "https://api.pub.build.mozilla.org/clobberer/lastclobber", + "locales_file": "%s/mobile/locales/l10n-changesets.json" % MOZILLA_DIR, + "locales_dir": "mobile/android/locales", + "ignore_locales": ["en-US"], + "nightly_build": True, + 'balrog_credentials_file': 'oauth.txt', + "tools_repo": "https://hg.mozilla.org/build/tools", + "tooltool_config": { + "manifest": "mobile/android/config/tooltool-manifests/android/releng.manifest", + "output_dir": "%(abs_work_dir)s/" + MOZILLA_DIR, + }, + "exes": { + 'tooltool.py': '/builds/tooltool.py', + }, + "repos": [{ + "vcs": "hg", + "repo": "https://hg.mozilla.org/build/tools", + "branch": "default", + "dest": "tools", + }, { + "vcs": "hg", + "repo": "https://hg.mozilla.org/projects/jamun", + "revision": "%(revision)s", + "dest": MOZILLA_DIR, + }], + "hg_l10n_base": "https://hg.mozilla.org/releases/l10n/mozilla-aurora", + "hg_l10n_tag": "default", + 'vcs_share_base': "/builds/hg-shared", + + "l10n_dir": "mozilla-aurora", + "repack_env": { + # so ugly, bug 951238 + "LD_LIBRARY_PATH": "/lib:/tools/gcc-4.7.2-0moz1/lib:/tools/gcc-4.7.2-0moz1/lib64", + "MOZ_OBJDIR": "obj-l10n", + "EN_US_BINARY_URL": os.environ.get("EN_US_BINARY_URL", EN_US_BINARY_URL), + "LOCALE_MERGEDIR": "%(abs_merge_dir)s/", + "MOZ_UPDATE_CHANNEL": "nightly-jamun", + }, + "upload_branch": "%s-android-api-15" % BRANCH, + "ssh_key_dir": "~/.ssh", + "merge_locales": True, + "mozilla_dir": MOZILLA_DIR, + "mozconfig": "%s/mobile/android/config/mozconfigs/android-api-15/l10n-nightly" % MOZILLA_DIR, + "signature_verification_script": "tools/release/signing/verify-android-signature.sh", + "stage_product": "mobile", + "platform": "android", + "build_type": "api-15-opt", + + # Balrog + "build_target": "Android_arm-eabi-gcc3", + + # Mock + "mock_target": "mozilla-centos6-x86_64-android", + "mock_packages": ['autoconf213', 'python', 'zip', 'mozilla-python27-mercurial', 'git', 'ccache', + 'glibc-static', 'libstdc++-static', 'perl-Test-Simple', 'perl-Config-General', + 'gtk2-devel', 'libnotify-devel', 'yasm', + 'alsa-lib-devel', 'libcurl-devel', + 'wireless-tools-devel', 'libX11-devel', + 'libXt-devel', 'mesa-libGL-devel', + 'gnome-vfs2-devel', 'GConf2-devel', 'wget', + 'mpfr', # required for system compiler + 'xorg-x11-font*', # fonts required for PGO + 'imake', # required for makedepend!?! + 'gcc45_0moz3', 'gcc454_0moz1', 'gcc472_0moz1', 'gcc473_0moz1', 'yasm', 'ccache', # <-- from releng repo + 'valgrind', 'dbus-x11', + 'pulseaudio-libs-devel', + 'gstreamer-devel', 'gstreamer-plugins-base-devel', + 'freetype-2.3.11-6.el6_1.8.x86_64', + 'freetype-devel-2.3.11-6.el6_1.8.x86_64', + 'java-1.7.0-openjdk-devel', + 'openssh-clients', + 'zlib-devel-1.2.3-27.el6.i686', + ], + "mock_files": [ + ("/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"), + ('/home/cltbld/.hgrc', '/builds/.hgrc'), + ('/builds/relengapi.tok', '/builds/relengapi.tok'), + ('/tools/tooltool.py', '/builds/tooltool.py'), + ('/usr/local/lib/hgext', '/usr/local/lib/hgext'), + ], +} From cf774261bf6cd826a8e937f5a1de94b0c3368dde Mon Sep 17 00:00:00 2001 From: Deepa Date: Wed, 22 Feb 2017 01:23:08 +0530 Subject: [PATCH 126/234] Bug 1341036 - Remove fallback styling from dropmarker.css. r=dao --- toolkit/themes/osx/global/dropmarker.css | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/toolkit/themes/osx/global/dropmarker.css b/toolkit/themes/osx/global/dropmarker.css index 701eea75c4ea..bdf160523ed9 100644 --- a/toolkit/themes/osx/global/dropmarker.css +++ b/toolkit/themes/osx/global/dropmarker.css @@ -7,22 +7,12 @@ dropmarker { width: 16px; -moz-box-align: center; -moz-box-pack: center; - border: 2px solid; - -moz-border-top-colors: ThreeDLightShadow ThreeDHighlight; - -moz-border-right-colors: ThreeDDarkShadow ThreeDShadow; - -moz-border-bottom-colors: ThreeDDarkShadow ThreeDShadow; - -moz-border-left-colors: ThreeDLightShadow ThreeDHighlight; - background-color: -moz-Dialog; padding: 1px; list-style-image: url("chrome://global/skin/arrow/arrow-dn.gif"); -moz-image-region: auto; } dropmarker:hover:active:not([disabled="true"]) { - -moz-border-top-colors: ThreeDShadow ThreeDFace; - -moz-border-right-colors: ThreeDShadow ThreeDFace; - -moz-border-bottom-colors: ThreeDShadow ThreeDFace; - -moz-border-left-colors: ThreeDShadow ThreeDFace; padding: 2px 0 0 2px; } From 0c17572124d91aa68f1d0d4616a41a42ca5c5d28 Mon Sep 17 00:00:00 2001 From: Deepa Date: Wed, 22 Feb 2017 01:41:54 +0530 Subject: [PATCH 127/234] Bug 1341047 - Stop setting background-color: transparent and border: none on .button-menu-dropmarker and .button-menubutton-dropmarker. r=dao --- toolkit/themes/windows/global/button.css | 2 -- 1 file changed, 2 deletions(-) diff --git a/toolkit/themes/windows/global/button.css b/toolkit/themes/windows/global/button.css index b8f3e1ef7fb0..f4ee61f15fbb 100644 --- a/toolkit/themes/windows/global/button.css +++ b/toolkit/themes/windows/global/button.css @@ -88,8 +88,6 @@ button[type="menu-button"] { .button-menubutton-dropmarker { -moz-appearance: none !important; margin: 1px; - background-color: transparent; - border: none; width: 11px; height: 11px; } From 5a13988731c477c8a8940cd6923e2f8f23285390 Mon Sep 17 00:00:00 2001 From: Olli Pettay Date: Wed, 22 Feb 2017 13:19:03 +0200 Subject: [PATCH 128/234] Bug 1339251 - Make Equals/Subsumes faster when comparing same objects, r=bholley --HG-- extra : rebase_source : 977c790f03188c4fda83297db026af62ee56a870 --- caps/nsIPrincipal.idl | 49 +++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/caps/nsIPrincipal.idl b/caps/nsIPrincipal.idl index 719d34b7ac29..16aceafeff7d 100644 --- a/caps/nsIPrincipal.idl +++ b/caps/nsIPrincipal.idl @@ -11,9 +11,29 @@ struct JSPrincipals; #include "nsCOMPtr.h" #include "nsTArray.h" +#include "mozilla/DebugOnly.h" namespace mozilla { class OriginAttributes; } + +/** + * Some methods have a fast path for the case when we're comparing a principal + * to itself. The situation may happen for example with about:blank documents. + */ + +#define DECL_FAST_INLINE_HELPER(method_) \ + inline bool method_(nsIPrincipal* aOther) \ + { \ + mozilla::DebugOnly val = false; \ + MOZ_ASSERT_IF(this == aOther, \ + NS_SUCCEEDED(method_(aOther, &val)) && val); \ + \ + bool retVal = false; \ + return \ + this == aOther || \ + (NS_SUCCEEDED(method_(aOther, &retVal)) && retVal); \ + } + %} interface nsIURI; @@ -41,15 +61,8 @@ interface nsIPrincipal : nsISerializable boolean equalsConsideringDomain(in nsIPrincipal other); %{C++ - inline bool Equals(nsIPrincipal* aOther) { - bool equal = false; - return NS_SUCCEEDED(Equals(aOther, &equal)) && equal; - } - - inline bool EqualsConsideringDomain(nsIPrincipal* aOther) { - bool equal = false; - return NS_SUCCEEDED(EqualsConsideringDomain(aOther, &equal)) && equal; - } + DECL_FAST_INLINE_HELPER(Equals) + DECL_FAST_INLINE_HELPER(EqualsConsideringDomain) %} /** @@ -101,20 +114,10 @@ interface nsIPrincipal : nsISerializable boolean subsumesConsideringDomainIgnoringFPD(in nsIPrincipal other); %{C++ - inline bool Subsumes(nsIPrincipal* aOther) { - bool subsumes = false; - return NS_SUCCEEDED(Subsumes(aOther, &subsumes)) && subsumes; - } - - inline bool SubsumesConsideringDomain(nsIPrincipal* aOther) { - bool subsumes = false; - return NS_SUCCEEDED(SubsumesConsideringDomain(aOther, &subsumes)) && subsumes; - } - - inline bool SubsumesConsideringDomainIgnoringFPD(nsIPrincipal* aOther) { - bool subsumes = false; - return NS_SUCCEEDED(SubsumesConsideringDomainIgnoringFPD(aOther, &subsumes)) && subsumes; - } + DECL_FAST_INLINE_HELPER(Subsumes) + DECL_FAST_INLINE_HELPER(SubsumesConsideringDomain) + DECL_FAST_INLINE_HELPER(SubsumesConsideringDomainIgnoringFPD) +#undef DECL_FAST_INLINE_HELPER %} /** From 2dcf7753c2370bb2758ab6c6ac600a568f603585 Mon Sep 17 00:00:00 2001 From: Makoto Kato Date: Wed, 22 Feb 2017 18:34:45 +0900 Subject: [PATCH 129/234] Bug 1327798 - Part 1. PasteNoFormatting shouldn't set text/html to clipboard event on paste. r=enndeakin MozReview-Commit-ID: 8VMudiPiXcK --HG-- extra : rebase_source : 2476f69296a60f6978f97da2daef021b90350dbf --- dom/base/nsCopySupport.cpp | 17 +++++++++++------ dom/events/DataTransfer.cpp | 20 +++++++++++++++++--- dom/events/DataTransfer.h | 2 +- editor/libeditor/HTMLEditorDataTransfer.cpp | 2 +- widget/EventMessageList.h | 1 + 5 files changed, 31 insertions(+), 11 deletions(-) diff --git a/dom/base/nsCopySupport.cpp b/dom/base/nsCopySupport.cpp index 0db373936b9c..fa8e28c9cf93 100644 --- a/dom/base/nsCopySupport.cpp +++ b/dom/base/nsCopySupport.cpp @@ -755,8 +755,13 @@ nsCopySupport::FireClipboardEvent(EventMessage aEventMessage, *aActionTaken = false; } - NS_ASSERTION(aEventMessage == eCut || aEventMessage == eCopy || - aEventMessage == ePaste, + EventMessage originalEventMessage = aEventMessage; + if (originalEventMessage == ePasteNoFormatting) { + originalEventMessage = ePaste; + } + + NS_ASSERTION(originalEventMessage == eCut || originalEventMessage == eCopy || + originalEventMessage == ePaste, "Invalid clipboard event type"); nsCOMPtr presShell = aPresShell; @@ -813,10 +818,10 @@ nsCopySupport::FireClipboardEvent(EventMessage aEventMessage, if (chromeShell || Preferences::GetBool("dom.event.clipboardevents.enabled", true)) { clipboardData = new DataTransfer(doc->GetScopeObject(), aEventMessage, - aEventMessage == ePaste, aClipboardType); + originalEventMessage == ePaste, aClipboardType); nsEventStatus status = nsEventStatus_eIgnore; - InternalClipboardEvent evt(true, aEventMessage); + InternalClipboardEvent evt(true, originalEventMessage); evt.mClipboardData = clipboardData; EventDispatcher::Dispatch(content, presShell->GetPresContext(), &evt, nullptr, &status); @@ -827,7 +832,7 @@ nsCopySupport::FireClipboardEvent(EventMessage aEventMessage, // No need to do anything special during a paste. Either an event listener // took care of it and cancelled the event, or the caller will handle it. // Return true to indicate that the event wasn't cancelled. - if (aEventMessage == ePaste) { + if (originalEventMessage == ePaste) { // Clear and mark the clipboardData as readonly. This prevents someone // from reading the clipboard contents after the paste event has fired. if (clipboardData) { @@ -867,7 +872,7 @@ nsCopySupport::FireClipboardEvent(EventMessage aEventMessage, // when cutting non-editable content, do nothing // XXX this is probably the wrong editable flag to check - if (aEventMessage != eCut || content->IsEditable()) { + if (originalEventMessage != eCut || content->IsEditable()) { // get the data from the selection if any bool isCollapsed; sel->GetIsCollapsed(&isCollapsed); diff --git a/dom/events/DataTransfer.cpp b/dom/events/DataTransfer.cpp index 26d2320d624d..5d31d2cb300b 100644 --- a/dom/events/DataTransfer.cpp +++ b/dom/events/DataTransfer.cpp @@ -105,8 +105,11 @@ DataTransfer::DataTransfer(nsISupports* aParent, EventMessage aEventMessage, aEventMessage == eDragStart) { mReadOnly = false; } else if (mIsExternal) { - if (aEventMessage == ePaste) { - CacheExternalClipboardFormats(); + if (aEventMessage == ePasteNoFormatting) { + mEventMessage = ePaste; + CacheExternalClipboardFormats(true); + } else if (aEventMessage == ePaste) { + CacheExternalClipboardFormats(false); } else if (aEventMessage >= eDragDropEventFirst && aEventMessage <= eDragDropEventLast) { CacheExternalDragFormats(); @@ -1356,7 +1359,7 @@ DataTransfer::CacheExternalDragFormats() } void -DataTransfer::CacheExternalClipboardFormats() +DataTransfer::CacheExternalClipboardFormats(bool aPlainTextOnly) { NS_ASSERTION(mEventMessage == ePaste, "caching clipboard data for invalid event"); @@ -1375,6 +1378,17 @@ DataTransfer::CacheExternalClipboardFormats() nsCOMPtr sysPrincipal; ssm->GetSystemPrincipal(getter_AddRefs(sysPrincipal)); + if (aPlainTextOnly) { + bool supported; + const char* unicodeMime[] = { kUnicodeMime }; + clipboard->HasDataMatchingFlavors(unicodeMime, 1, mClipboardType, + &supported); + if (supported) { + CacheExternalData(kUnicodeMime, 0, sysPrincipal, false); + } + return; + } + // Check if the clipboard has any files bool hasFileData = false; const char *fileMime[] = { kFileMime }; diff --git a/dom/events/DataTransfer.h b/dom/events/DataTransfer.h index 284edd56992c..729b23feb371 100644 --- a/dom/events/DataTransfer.h +++ b/dom/events/DataTransfer.h @@ -307,7 +307,7 @@ protected: void CacheExternalDragFormats(); // caches the formats that exist in the clipboard - void CacheExternalClipboardFormats(); + void CacheExternalClipboardFormats(bool aPlainTextOnly); FileList* GetFilesInternal(ErrorResult& aRv, nsIPrincipal* aSubjectPrincipal); nsresult GetDataAtInternal(const nsAString& aFormat, uint32_t aIndex, diff --git a/editor/libeditor/HTMLEditorDataTransfer.cpp b/editor/libeditor/HTMLEditorDataTransfer.cpp index 21a6948e1673..1d126fe09aeb 100644 --- a/editor/libeditor/HTMLEditorDataTransfer.cpp +++ b/editor/libeditor/HTMLEditorDataTransfer.cpp @@ -1495,7 +1495,7 @@ HTMLEditor::PasteTransferable(nsITransferable* aTransferable) NS_IMETHODIMP HTMLEditor::PasteNoFormatting(int32_t aSelectionType) { - if (!FireClipboardEvent(ePaste, aSelectionType)) { + if (!FireClipboardEvent(ePasteNoFormatting, aSelectionType)) { return NS_OK; } diff --git a/widget/EventMessageList.h b/widget/EventMessageList.h index a183253b5248..c4e42835663e 100644 --- a/widget/EventMessageList.h +++ b/widget/EventMessageList.h @@ -226,6 +226,7 @@ NS_EVENT_MESSAGE(eXULCommand) NS_EVENT_MESSAGE(eCopy) NS_EVENT_MESSAGE(eCut) NS_EVENT_MESSAGE(ePaste) +NS_EVENT_MESSAGE(ePasteNoFormatting) // Query for the selected text information, it return the selection offset, // selection length and selected text. From a4109eb8fa242d31f1b952a6122ef6a6b7be768a Mon Sep 17 00:00:00 2001 From: Makoto Kato Date: Wed, 1 Feb 2017 14:05:17 +0900 Subject: [PATCH 130/234] Bug 1327798 - Part 2. Add test. r=enndeakin MozReview-Commit-ID: 2B2mVNgcBEz --HG-- extra : rebase_source : 994d68282b51289b61dd1cc1ea39711cb21acb00 --- dom/events/test/mochitest.ini | 2 ++ dom/events/test/test_bug1327798.html | 47 ++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 dom/events/test/test_bug1327798.html diff --git a/dom/events/test/mochitest.ini b/dom/events/test/mochitest.ini index 797568b11411..1850b55644df 100644 --- a/dom/events/test/mochitest.ini +++ b/dom/events/test/mochitest.ini @@ -139,6 +139,8 @@ support-files = bug1017086_inner.html [test_bug1248459.html] [test_bug1264380.html] run-if = (e10s && os != "win") # Bug 1270043, crash at windows platforms; Bug1264380 comment 20, nsDragService::InvokeDragSessionImpl behaves differently among platform implementations in non-e10s mode which prevents us to check the validity of nsIDragService::getCurrentSession() consistently via synthesize mouse clicks in non-e10s mode. +[test_bug1327798.html] +subsuite = clipboard [test_clickevent_on_input.html] skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM [test_continuous_wheel_events.html] diff --git a/dom/events/test/test_bug1327798.html b/dom/events/test/test_bug1327798.html new file mode 100644 index 000000000000..2b6cb9589e31 --- /dev/null +++ b/dom/events/test/test_bug1327798.html @@ -0,0 +1,47 @@ + + + +Test for bug 1327798 + + + + + +Mozilla Bug 1327798 +

+ + +
Formatted Text
+
+
+
+ + From 8e150e46431cd60084ccc2a29bc04150e4a7f145 Mon Sep 17 00:00:00 2001 From: David Parks Date: Wed, 8 Feb 2017 11:38:40 -0800 Subject: [PATCH 131/234] Bug 1284897 - Hook GetSaveFileNameW/GetOpenFileNameW to record and grant a sandboxed process permission to access user-chosen files. r=jimm --HG-- extra : rebase_source : 024eae9f9657579debd38baba1526acfdca2385a --- dom/plugins/ipc/PPluginModule.ipdl | 7 + dom/plugins/ipc/PluginMessageUtils.cpp | 187 ++++++++++++++++++++++++ dom/plugins/ipc/PluginMessageUtils.h | 178 +++++++++++++++++++++- dom/plugins/ipc/PluginModuleChild.cpp | 140 ++++++++++++++++++ dom/plugins/ipc/PluginModuleParent.cpp | 70 +++++++++ dom/plugins/ipc/PluginModuleParent.h | 18 +++ dom/plugins/ipc/PluginProcessParent.cpp | 7 - dom/plugins/ipc/moz.build | 1 + ipc/ipdl/sync-messages.ini | 2 + 9 files changed, 602 insertions(+), 8 deletions(-) diff --git a/dom/plugins/ipc/PPluginModule.ipdl b/dom/plugins/ipc/PPluginModule.ipdl index 688e635a7ed0..659a4e6b87fe 100644 --- a/dom/plugins/ipc/PPluginModule.ipdl +++ b/dom/plugins/ipc/PPluginModule.ipdl @@ -14,6 +14,9 @@ using mozilla::dom::NativeThreadId from "mozilla/dom/TabMessageUtils.h"; using class mac_plugin_interposing::NSCursorInfo from "mozilla/plugins/PluginMessageUtils.h"; using struct nsID from "nsID.h"; using struct mozilla::plugins::NPAudioDeviceChangeDetailsIPC from "mozilla/plugins/PluginMessageUtils.h"; +using mozilla::plugins::GetFileNameFunc from "mozilla/plugins/PluginMessageUtils.h"; +using mozilla::plugins::OpenFileNameIPC from "mozilla/plugins/PluginMessageUtils.h"; +using mozilla::plugins::OpenFileNameRetIPC from "mozilla/plugins/PluginMessageUtils.h"; namespace mozilla { namespace plugins { @@ -163,6 +166,10 @@ parent: intr NPN_SetValue_NPPVpluginRequiresAudioDeviceChanges(bool shouldRegister) returns (NPError result); + + // Used to broker the GetOpenFileName/GetSaveFileName file pickers on Windows. + intr GetFileName(GetFileNameFunc aFunc, OpenFileNameIPC aOfnIn) + returns (OpenFileNameRetIPC aOfnOut, bool aResult); }; } // namespace plugins diff --git a/dom/plugins/ipc/PluginMessageUtils.cpp b/dom/plugins/ipc/PluginMessageUtils.cpp index 47653fe6eead..07d10820b3a4 100644 --- a/dom/plugins/ipc/PluginMessageUtils.cpp +++ b/dom/plugins/ipc/PluginMessageUtils.cpp @@ -151,5 +151,192 @@ void DeferNPVariantLastRelease(const NPNetscapeFuncs* f, NPVariant* v) VOID_TO_NPVARIANT(*v); } +#ifdef XP_WIN +void +OpenFileNameIPC::CopyFromOfn(LPOPENFILENAMEW aLpofn) +{ + mHwndOwner = nullptr; + + // Filter is double-NULL terminated. mFilter should include the double-NULL. + mHasFilter = aLpofn->lpstrFilter != nullptr; + if (mHasFilter) { + uint32_t dNullIdx = 0; + while (aLpofn->lpstrFilter[dNullIdx] != L'\0' || + aLpofn->lpstrFilter[dNullIdx+1] != L'\0') { + dNullIdx++; + } + mFilter.assign(aLpofn->lpstrFilter, dNullIdx+2); + } + mHasCustomFilter = aLpofn->lpstrCustomFilter != nullptr; + if (mHasCustomFilter) { + mCustomFilterIn = std::wstring(aLpofn->lpstrCustomFilter); + mNMaxCustFilterOut = + aLpofn->nMaxCustFilter - (wcslen(aLpofn->lpstrCustomFilter) + 1); + } + else { + mNMaxCustFilterOut = 0; + } + mFilterIndex = aLpofn->nFilterIndex; + mFile = std::wstring(aLpofn->lpstrFile); + mNMaxFile = aLpofn->nMaxFile; + mNMaxFileTitle = + aLpofn->lpstrFileTitle != nullptr ? aLpofn->nMaxFileTitle : 0; + mHasInitialDir = aLpofn->lpstrInitialDir != nullptr; + if (mHasInitialDir) { + mInitialDir = std::wstring(aLpofn->lpstrInitialDir); + } + mHasTitle = aLpofn->lpstrTitle != nullptr; + if (mHasTitle) { + mTitle = std::wstring(aLpofn->lpstrTitle); + } + mHasDefExt = aLpofn->lpstrDefExt != nullptr; + if (mHasDefExt) { + mDefExt = std::wstring(aLpofn->lpstrDefExt); + } + + mFlags = aLpofn->Flags; + // If the user sets OFN_ALLOWMULTISELECT then we require OFN_EXPLORER + // as well. Without OFN_EXPLORER, the method has ancient legacy + // behavior that we don't support. + MOZ_ASSERT((mFlags & OFN_EXPLORER) || !(mFlags & OFN_ALLOWMULTISELECT)); + + // We ignore any visual customization and callbacks that the user set. + mFlags &= ~(OFN_ENABLEHOOK | OFN_ENABLETEMPLATEHANDLE | OFN_ENABLETEMPLATE); + + mFlagsEx = aLpofn->FlagsEx; +} + +void +OpenFileNameIPC::AddToOfn(LPOPENFILENAMEW aLpofn) const +{ + aLpofn->lStructSize = sizeof(OPENFILENAMEW); + aLpofn->hwndOwner = mHwndOwner; + if (mHasFilter) { + memcpy(const_cast(aLpofn->lpstrFilter), + mFilter.data(), mFilter.size() * sizeof(wchar_t)); + } + if (mHasCustomFilter) { + aLpofn->nMaxCustFilter = mCustomFilterIn.size() + 1 + mNMaxCustFilterOut; + wcscpy(aLpofn->lpstrCustomFilter, mCustomFilterIn.c_str()); + memset(aLpofn->lpstrCustomFilter + mCustomFilterIn.size() + 1, 0, + mNMaxCustFilterOut * sizeof(wchar_t)); + } + else { + aLpofn->nMaxCustFilter = 0; + } + aLpofn->nFilterIndex = mFilterIndex; + wcscpy(aLpofn->lpstrFile, mFile.c_str()); + aLpofn->nMaxFile = mNMaxFile; + aLpofn->nMaxFileTitle = mNMaxFileTitle; + if (mHasInitialDir) { + wcscpy(const_cast(aLpofn->lpstrInitialDir), mInitialDir.c_str()); + } + if (mHasTitle) { + wcscpy(const_cast(aLpofn->lpstrTitle), mTitle.c_str()); + } + aLpofn->Flags = mFlags; /* TODO: Consider adding OFN_NOCHANGEDIR */ + if (mHasDefExt) { + wcscpy(const_cast(aLpofn->lpstrDefExt), mDefExt.c_str()); + } + aLpofn->FlagsEx = mFlagsEx; +} + +void +OpenFileNameIPC::AllocateOfnStrings(LPOPENFILENAMEW aLpofn) const +{ + if (mHasFilter) { + // mFilter is double-NULL terminated and it includes the double-NULL in its length. + aLpofn->lpstrFilter = + static_cast(moz_xmalloc(sizeof(wchar_t) * (mFilter.size()))); + } + if (mHasCustomFilter) { + aLpofn->lpstrCustomFilter = + static_cast(moz_xmalloc(sizeof(wchar_t) * (mCustomFilterIn.size() + 1) + mNMaxCustFilterOut)); + } + aLpofn->lpstrFile = + static_cast(moz_xmalloc(sizeof(wchar_t) * mNMaxFile)); + if (mNMaxFileTitle > 0) { + aLpofn->lpstrFileTitle = + static_cast(moz_xmalloc(sizeof(wchar_t) * mNMaxFileTitle)); + } + if (mHasInitialDir) { + aLpofn->lpstrInitialDir = + static_cast(moz_xmalloc(sizeof(wchar_t) * (mInitialDir.size() + 1))); + } + if (mHasTitle) { + aLpofn->lpstrTitle = + static_cast(moz_xmalloc(sizeof(wchar_t) * (mTitle.size() + 1))); + } + if (mHasDefExt) { + aLpofn->lpstrDefExt = + static_cast(moz_xmalloc(sizeof(wchar_t) * (mDefExt.size() + 1))); + } +} + +void +OpenFileNameIPC::FreeOfnStrings(LPOPENFILENAMEW aLpofn) const +{ + if (aLpofn->lpstrFilter) { + free(const_cast(aLpofn->lpstrFilter)); + } + if (aLpofn->lpstrCustomFilter) { + free(aLpofn->lpstrCustomFilter); + } + if (aLpofn->lpstrFile) { + free(aLpofn->lpstrFile); + } + if (aLpofn->lpstrFileTitle) { + free(aLpofn->lpstrFileTitle); + } + if (aLpofn->lpstrInitialDir) { + free(const_cast(aLpofn->lpstrInitialDir)); + } + if (aLpofn->lpstrTitle) { + free(const_cast(aLpofn->lpstrTitle)); + } + if (aLpofn->lpstrDefExt) { + free(const_cast(aLpofn->lpstrDefExt)); + } +} + +void +OpenFileNameRetIPC::CopyFromOfn(LPOPENFILENAMEW aLpofn) +{ + if (aLpofn->lpstrCustomFilter != nullptr) { + mCustomFilterOut = + std::wstring(aLpofn->lpstrCustomFilter + wcslen(aLpofn->lpstrCustomFilter) + 1); + } + mFile.assign(aLpofn->lpstrFile, aLpofn->nMaxFile); + if (aLpofn->lpstrFileTitle != nullptr) { + mFileTitle.assign(aLpofn->lpstrFileTitle, wcslen(aLpofn->lpstrFileTitle) + 1); + } + mFileOffset = aLpofn->nFileOffset; + mFileExtension = aLpofn->nFileExtension; +} + +void +OpenFileNameRetIPC::AddToOfn(LPOPENFILENAMEW aLpofn) const +{ + if (aLpofn->lpstrCustomFilter) { + LPWSTR secondString = + aLpofn->lpstrCustomFilter + wcslen(aLpofn->lpstrCustomFilter) + 1; + const wchar_t* customFilterOut = mCustomFilterOut.c_str(); + MOZ_ASSERT(wcslen(aLpofn->lpstrCustomFilter) + 1 + + wcslen(customFilterOut) + 1 + 1 <= aLpofn->nMaxCustFilter); + wcscpy(secondString, customFilterOut); + secondString[wcslen(customFilterOut) + 1] = L'\0'; // terminated with two NULLs + } + MOZ_ASSERT(mFile.size() <= aLpofn->nMaxFile); + memcpy(aLpofn->lpstrFile, + mFile.data(), mFile.size() * sizeof(wchar_t)); + if (aLpofn->lpstrFileTitle != nullptr) { + MOZ_ASSERT(mFileTitle.size() + 1 < aLpofn->nMaxFileTitle); + wcscpy(aLpofn->lpstrFileTitle, mFileTitle.c_str()); + } + aLpofn->nFileOffset = mFileOffset; + aLpofn->nFileExtension = mFileExtension; +} +#endif // XP_WIN + } // namespace plugins } // namespace mozilla diff --git a/dom/plugins/ipc/PluginMessageUtils.h b/dom/plugins/ipc/PluginMessageUtils.h index bc2e90f285a8..ee3fb73bda4f 100644 --- a/dom/plugins/ipc/PluginMessageUtils.h +++ b/dom/plugins/ipc/PluginMessageUtils.h @@ -32,6 +32,9 @@ namespace mac_plugin_interposing { class NSCursorInfo { }; } #endif using mac_plugin_interposing::NSCursorInfo; +#ifdef XP_WIN +#include "commdlg.h" +#endif namespace mozilla { namespace plugins { @@ -123,9 +126,59 @@ typedef intptr_t NativeWindowHandle; // never actually used, will always be 0 #ifdef XP_WIN typedef base::SharedMemoryHandle WindowsSharedMemoryHandle; typedef HANDLE DXGISharedSurfaceHandle; -#else + +// Values indicate GetOpenFileNameW and GetSaveFileNameW. +enum GetFileNameFunc { OPEN_FUNC, SAVE_FUNC }; + +// IPC-capable version of the Windows OPENFILENAMEW struct. +typedef struct _OpenFileNameIPC +{ + // Allocates memory for the strings in this object. This should usually + // be used with a zeroed out OPENFILENAMEW structure. + void AllocateOfnStrings(LPOPENFILENAMEW aLpofn) const; + void FreeOfnStrings(LPOPENFILENAMEW aLpofn) const; + void AddToOfn(LPOPENFILENAMEW aLpofn) const; + void CopyFromOfn(LPOPENFILENAMEW aLpofn); + + NativeWindowHandle mHwndOwner; + std::wstring mFilter; // Double-NULL terminated (i.e. L"\0\0") if mHasFilter is true + bool mHasFilter; + std::wstring mCustomFilterIn; + bool mHasCustomFilter; + uint32_t mNMaxCustFilterOut; + uint32_t mFilterIndex; + std::wstring mFile; + uint32_t mNMaxFile; + uint32_t mNMaxFileTitle; + std::wstring mInitialDir; + bool mHasInitialDir; + std::wstring mTitle; + bool mHasTitle; + uint32_t mFlags; + std::wstring mDefExt; + bool mHasDefExt; + uint32_t mFlagsEx; +} OpenFileNameIPC; + +// GetOpenFileNameW and GetSaveFileNameW overwrite fields of their OPENFILENAMEW +// parameter. This represents those values so that they can be returned via IPC. +typedef struct _OpenFileNameRetIPC +{ + void CopyFromOfn(LPOPENFILENAMEW aLpofn); + void AddToOfn(LPOPENFILENAMEW aLpofn) const; + + std::wstring mCustomFilterOut; + std::wstring mFile; // Double-NULL terminated (i.e. L"\0\0") + std::wstring mFileTitle; + uint16_t mFileOffset; + uint16_t mFileExtension; +} OpenFileNameRetIPC; +#else // XP_WIN typedef mozilla::null_t WindowsSharedMemoryHandle; typedef mozilla::null_t DXGISharedSurfaceHandle; +typedef mozilla::null_t GetFileNameFunc; +typedef mozilla::null_t OpenFileNameIPC; +typedef mozilla::null_t OpenFileNameRetIPC; #endif // XXX maybe not the best place for these. better one? @@ -723,6 +776,129 @@ struct ParamTraits } }; +#ifdef XP_WIN +template <> +struct ParamTraits +{ + typedef mozilla::plugins::_OpenFileNameIPC paramType; + + static void Write(Message* aMsg, const paramType& aParam) + { + WriteParam(aMsg, aParam.mHwndOwner); + WriteParam(aMsg, aParam.mFilter); + WriteParam(aMsg, aParam.mHasFilter); + WriteParam(aMsg, aParam.mCustomFilterIn); + WriteParam(aMsg, aParam.mHasCustomFilter); + WriteParam(aMsg, aParam.mNMaxCustFilterOut); + WriteParam(aMsg, aParam.mFilterIndex); + WriteParam(aMsg, aParam.mFile); + WriteParam(aMsg, aParam.mNMaxFile); + WriteParam(aMsg, aParam.mNMaxFileTitle); + WriteParam(aMsg, aParam.mInitialDir); + WriteParam(aMsg, aParam.mHasInitialDir); + WriteParam(aMsg, aParam.mTitle); + WriteParam(aMsg, aParam.mHasTitle); + WriteParam(aMsg, aParam.mFlags); + WriteParam(aMsg, aParam.mDefExt); + WriteParam(aMsg, aParam.mHasDefExt); + WriteParam(aMsg, aParam.mFlagsEx); + } + + static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) + { + if (ReadParam(aMsg, aIter, &aResult->mHwndOwner) && + ReadParam(aMsg, aIter, &aResult->mFilter) && + ReadParam(aMsg, aIter, &aResult->mHasFilter) && + ReadParam(aMsg, aIter, &aResult->mCustomFilterIn) && + ReadParam(aMsg, aIter, &aResult->mHasCustomFilter) && + ReadParam(aMsg, aIter, &aResult->mNMaxCustFilterOut) && + ReadParam(aMsg, aIter, &aResult->mFilterIndex) && + ReadParam(aMsg, aIter, &aResult->mFile) && + ReadParam(aMsg, aIter, &aResult->mNMaxFile) && + ReadParam(aMsg, aIter, &aResult->mNMaxFileTitle) && + ReadParam(aMsg, aIter, &aResult->mInitialDir) && + ReadParam(aMsg, aIter, &aResult->mHasInitialDir) && + ReadParam(aMsg, aIter, &aResult->mTitle) && + ReadParam(aMsg, aIter, &aResult->mHasTitle) && + ReadParam(aMsg, aIter, &aResult->mFlags) && + ReadParam(aMsg, aIter, &aResult->mDefExt) && + ReadParam(aMsg, aIter, &aResult->mHasDefExt) && + ReadParam(aMsg, aIter, &aResult->mFlagsEx)) { + return true; + } + return false; + } + + static void Log(const paramType& aParam, std::wstring* aLog) + { + aLog->append(StringPrintf(L"[%S, %S, %S, %S]", aParam.mFilter.c_str(), + aParam.mCustomFilterIn.c_str(), aParam.mFile.c_str(), + aParam.mTitle.c_str())); + } +}; + +template <> +struct ParamTraits +{ + typedef mozilla::plugins::_OpenFileNameRetIPC paramType; + + static void Write(Message* aMsg, const paramType& aParam) + { + WriteParam(aMsg, aParam.mCustomFilterOut); + WriteParam(aMsg, aParam.mFile); + WriteParam(aMsg, aParam.mFileTitle); + WriteParam(aMsg, aParam.mFileOffset); + WriteParam(aMsg, aParam.mFileExtension); + } + + static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) + { + if (ReadParam(aMsg, aIter, &aResult->mCustomFilterOut) && + ReadParam(aMsg, aIter, &aResult->mFile) && + ReadParam(aMsg, aIter, &aResult->mFileTitle) && + ReadParam(aMsg, aIter, &aResult->mFileOffset) && + ReadParam(aMsg, aIter, &aResult->mFileExtension)) { + return true; + } + return false; + } + + static void Log(const paramType& aParam, std::wstring* aLog) + { + aLog->append(StringPrintf(L"[%S, %S, %S, %d, %d]", aParam.mCustomFilterOut.c_str(), + aParam.mFile.c_str(), aParam.mFileTitle.c_str(), + aParam.mFileOffset, aParam.mFileExtension)); + } +}; + +template <> +struct ParamTraits +{ + typedef mozilla::plugins::GetFileNameFunc paramType; + + static void Write(Message* aMsg, const paramType& aParam) + { + WriteParam(aMsg, static_cast(aParam)); + } + + static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) + { + uint32_t result; + if (ReadParam(aMsg, aIter, &result)) { + *aResult = static_cast(result); + return true; + } + return false; + } + + static void Log(const paramType& aParam, std::wstring* aLog) + { + aLog->append(StringPrintf(L"[%S]", + aParam == mozilla::plugins::OPEN_FUNC ? "GetOpenFileName" : "GetSaveFileName")); + } +}; +#endif // XP_WIN + } /* namespace IPC */ diff --git a/dom/plugins/ipc/PluginModuleChild.cpp b/dom/plugins/ipc/PluginModuleChild.cpp index e68ab78a785e..49b2b94afa92 100644 --- a/dom/plugins/ipc/PluginModuleChild.cpp +++ b/dom/plugins/ipc/PluginModuleChild.cpp @@ -96,6 +96,17 @@ static HWND sBrowserHwnd = nullptr; // sandbox process doesn't get current key states. So we need get it on chrome. typedef SHORT (WINAPI *GetKeyStatePtr)(int); static GetKeyStatePtr sGetKeyStatePtrStub = nullptr; + +static WindowsDllInterceptor sComDlg32Intercept; + +// proxy GetSaveFileName/GetOpenFileName on chrome so that we can know which +// files the user has given permission to access +// We count on GetOpenFileNameA/GetSaveFileNameA calling +// GetOpenFileNameW/GetSaveFileNameW so we don't proxy them explicitly. +typedef BOOL (WINAPI *GetOpenFileNameWPtr)(LPOPENFILENAMEW lpofn); +static GetOpenFileNameWPtr sGetOpenFileNameWPtrStub = nullptr; +typedef BOOL (WINAPI *GetSaveFileNameWPtr)(LPOPENFILENAMEW lpofn); +static GetSaveFileNameWPtr sGetSaveFileNameWPtrStub = nullptr; #endif /* static */ @@ -2111,6 +2122,124 @@ PMCGetKeyState(int aVirtKey) } return sGetKeyStatePtrStub(aVirtKey); } + +BOOL WINAPI PMCGetSaveFileNameW(LPOPENFILENAMEW lpofn); +BOOL WINAPI PMCGetOpenFileNameW(LPOPENFILENAMEW lpofn); + +// Runnable that performs GetOpenFileNameW and GetSaveFileNameW +// on the main thread so that the call can be +// synchronously run on the PluginModuleParent via IPC. +// The task alerts the given semaphore when it is finished. +class GetFileNameTask : public Runnable +{ + BOOL* mReturnValue; + void* mLpOpenFileName; + HANDLE mSemaphore; + GetFileNameFunc mFunc; + +public: + explicit GetFileNameTask(GetFileNameFunc func, void* aLpOpenFileName, + HANDLE aSemaphore, BOOL* aReturnValue) : + mLpOpenFileName(aLpOpenFileName), mSemaphore(aSemaphore), + mReturnValue(aReturnValue), mFunc(func) + {} + + NS_IMETHOD Run() override + { + PLUGIN_LOG_DEBUG_METHOD; + AssertPluginThread(); + switch (mFunc) { + case OPEN_FUNC: + *mReturnValue = + PMCGetOpenFileNameW(static_cast(mLpOpenFileName)); + break; + case SAVE_FUNC: + *mReturnValue = + PMCGetSaveFileNameW(static_cast(mLpOpenFileName)); + break; + } + if (!ReleaseSemaphore(mSemaphore, 1, nullptr)) { + return NS_ERROR_FAILURE; + } + return NS_OK; + } +}; + +// static +BOOL +PostToPluginThread(GetFileNameFunc aFunc, void* aLpofn) +{ + MOZ_ASSERT(!IsPluginThread()); + + // Synchronously run GetFileNameTask from the main thread. + // Start a semaphore at 0. We release the semaphore (bringing its + // count to 1) when the synchronous call is done. + nsAutoHandle semaphore(CreateSemaphore(NULL, 0, 1, NULL)); + if (semaphore == nullptr) { + MOZ_ASSERT(semaphore != nullptr); + return FALSE; + } + + BOOL returnValue = FALSE; + RefPtr task = + new GetFileNameTask(aFunc, aLpofn, semaphore, &returnValue); + ProcessChild::message_loop()->PostTask(task.forget()); + DWORD err = WaitForSingleObject(semaphore, INFINITE); + if (err != WAIT_FAILED) { + return returnValue; + } + PLUGIN_LOG_DEBUG(("Error while waiting for semaphore: %d", + GetLastError())); + MOZ_ASSERT(err != WAIT_FAILED); + return FALSE; +} + +// static +BOOL WINAPI +PMCGetFileNameW(GetFileNameFunc aFunc, LPOPENFILENAMEW aLpofn) +{ + if (!IsPluginThread()) { + return PostToPluginThread(aFunc, aLpofn); + } + + PluginModuleChild* chromeInstance = PluginModuleChild::GetChrome(); + if (chromeInstance) { + bool ret = FALSE; + OpenFileNameIPC inputOfn; + inputOfn.CopyFromOfn(aLpofn); + OpenFileNameRetIPC outputOfn; + if (chromeInstance->CallGetFileName(aFunc, inputOfn, + &outputOfn, &ret)) { + if (ret) { + outputOfn.AddToOfn(aLpofn); + } + } + return ret; + } + + switch (aFunc) { + case OPEN_FUNC: + return sGetOpenFileNameWPtrStub(aLpofn); + case SAVE_FUNC: + return sGetSaveFileNameWPtrStub(aLpofn); + } + + MOZ_ASSERT_UNREACHABLE("Illegal GetFileNameFunc value"); + return FALSE; +} + +// static +BOOL WINAPI +PMCGetSaveFileNameW(LPOPENFILENAMEW aLpofn) +{ + return PMCGetFileNameW(SAVE_FUNC, aLpofn); +} +// static +BOOL WINAPI +PMCGetOpenFileNameW(LPOPENFILENAMEW aLpofn) +{ + return PMCGetFileNameW(OPEN_FUNC, aLpofn); +} #endif PPluginInstanceChild* @@ -2143,6 +2272,17 @@ PluginModuleChild::AllocPPluginInstanceChild(const nsCString& aMimeType, sUser32Intercept.AddHook("GetKeyState", reinterpret_cast(PMCGetKeyState), (void**) &sGetKeyStatePtrStub); } + + sComDlg32Intercept.Init("comdlg32.dll"); + if (!sGetSaveFileNameWPtrStub) { + sComDlg32Intercept.AddHook("GetSaveFileNameW", reinterpret_cast(PMCGetSaveFileNameW), + (void**) &sGetSaveFileNameWPtrStub); + } + + if (!sGetOpenFileNameWPtrStub) { + sComDlg32Intercept.AddHook("GetOpenFileNameW", reinterpret_cast(PMCGetOpenFileNameW), + (void**) &sGetOpenFileNameWPtrStub); + } #endif return new PluginInstanceChild(&mFunctions, aMimeType, aMode, aNames, diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp index d76cd402a8e8..8d24cd443582 100644 --- a/dom/plugins/ipc/PluginModuleParent.cpp +++ b/dom/plugins/ipc/PluginModuleParent.cpp @@ -810,6 +810,10 @@ PluginModuleChromeParent::~PluginModuleChromeParent() false); #endif +#if defined(XP_WIN) && defined(MOZ_SANDBOX) + mSandboxPermissions.RemovePermissionsForProcess(OtherPid()); +#endif + if (!mShutdown) { NS_WARNING("Plugin host deleted the module without shutting down."); NPError err; @@ -3433,3 +3437,69 @@ PluginModuleChromeParent::AnswerGetKeyState(const int32_t& aVirtKey, return PluginModuleParent::AnswerGetKeyState(aVirtKey, aRet); #endif } + +mozilla::ipc::IPCResult +PluginModuleChromeParent::AnswerGetFileName(const GetFileNameFunc& aFunc, + const OpenFileNameIPC& aOfnIn, + OpenFileNameRetIPC* aOfnOut, + bool* aResult) +{ +#if defined(XP_WIN) && defined(MOZ_SANDBOX) + OPENFILENAMEW ofn; + memset(&ofn, 0, sizeof(ofn)); + aOfnIn.AllocateOfnStrings(&ofn); + aOfnIn.AddToOfn(&ofn); + switch (aFunc) { + case OPEN_FUNC: + *aResult = GetOpenFileName(&ofn); + break; + case SAVE_FUNC: + *aResult = GetSaveFileName(&ofn); + break; + } + if (*aResult) { + if (ofn.Flags & OFN_ALLOWMULTISELECT) { + // We only support multiselect with the OFN_EXPLORER flag. + // This guarantees that ofn.lpstrFile follows the pattern below. + MOZ_ASSERT(ofn.Flags & OFN_EXPLORER); + + // lpstrFile is one of two things: + // 1. A null terminated full path to a file, or + // 2. A path to a folder, followed by a NULL, followed by a + // list of file names, each NULL terminated, followed by an + // additional NULL (so it is also double-NULL terminated). + std::wstring path = std::wstring(ofn.lpstrFile); + MOZ_ASSERT(ofn.nFileOffset > 0); + // For condition #1, nFileOffset points to the file name in the path. + // It will be preceeded by a non-NULL character from the path. + if (ofn.lpstrFile[ofn.nFileOffset-1] != L'\0') { + mSandboxPermissions.GrantFileAccess(OtherPid(), path.c_str(), + aFunc == SAVE_FUNC); + } + else { + // This is condition #2 + wchar_t* nextFile = ofn.lpstrFile + path.size() + 1; + while (*nextFile != L'\0') { + std::wstring nextFileStr(nextFile); + std::wstring fullPath = + path + std::wstring(L"\\") + nextFileStr; + mSandboxPermissions.GrantFileAccess(OtherPid(), fullPath.c_str(), + aFunc == SAVE_FUNC); + nextFile += nextFileStr.size() + 1; + } + } + } + else { + mSandboxPermissions.GrantFileAccess(OtherPid(), ofn.lpstrFile, + aFunc == SAVE_FUNC); + } + aOfnOut->CopyFromOfn(&ofn); + } + aOfnIn.FreeOfnStrings(&ofn); + return IPC_OK(); +#else + MOZ_ASSERT_UNREACHABLE("GetFileName IPC message is only available on " + "Windows builds with sandbox."); + return IPC_FAIL_NO_REASON(this); +#endif +} diff --git a/dom/plugins/ipc/PluginModuleParent.h b/dom/plugins/ipc/PluginModuleParent.h index 5149e24d1652..b9baee6cfac5 100644 --- a/dom/plugins/ipc/PluginModuleParent.h +++ b/dom/plugins/ipc/PluginModuleParent.h @@ -24,6 +24,7 @@ #include "nsIObserver.h" #ifdef XP_WIN #include "nsWindowsHelpers.h" +#include "sandboxPermissions.h" #endif #ifdef MOZ_CRASHREPORTER @@ -194,6 +195,14 @@ protected: const bool& shouldRegister, NPError* result) override; + virtual mozilla::ipc::IPCResult + AnswerGetFileName(const GetFileNameFunc& aFunc, + const OpenFileNameIPC& aOfnIn, + OpenFileNameRetIPC* aOfnOut, bool* aResult) override + { + return IPC_FAIL_NO_REASON(this); + } + protected: void SetChildTimeout(const int32_t aChildTimeout); static void TimeoutChanged(const char* aPref, void* aModule); @@ -509,6 +518,12 @@ class PluginModuleChromeParent virtual mozilla::ipc::IPCResult AnswerGetKeyState(const int32_t& aVirtKey, int16_t* aRet) override; + // Proxy GetOpenFileName/GetSaveFileName on Windows. + virtual mozilla::ipc::IPCResult + AnswerGetFileName(const GetFileNameFunc& aFunc, + const OpenFileNameIPC& aOfnIn, + OpenFileNameRetIPC* aOfnOut, bool* aResult) override; + private: virtual void EnteredCxxStack() override; @@ -662,6 +677,9 @@ private: nsCString mProfile; bool mIsBlocklisted; static bool sInstantiated; +#if defined(XP_WIN) && defined(MOZ_SANDBOX) + mozilla::SandboxPermissions mSandboxPermissions; +#endif }; } // namespace plugins diff --git a/dom/plugins/ipc/PluginProcessParent.cpp b/dom/plugins/ipc/PluginProcessParent.cpp index 57ed07111162..c4dbbdead867 100644 --- a/dom/plugins/ipc/PluginProcessParent.cpp +++ b/dom/plugins/ipc/PluginProcessParent.cpp @@ -97,13 +97,6 @@ AddSandboxAllowedFiles(int32_t aSandboxLevel, return; } - // Higher than level 2 currently removes the users own rights. - if (aSandboxLevel > 2) { - AddSandboxAllowedFile(aAllowedFilesRead, dirSvc, NS_WIN_HOME_DIR); - AddSandboxAllowedFile(aAllowedFilesRead, dirSvc, NS_WIN_HOME_DIR, - NS_LITERAL_STRING("\\*")); - } - // Level 2 and above is now using low integrity, so we need to give write // access to the Flash directories. // This should be made Flash specific (Bug 1171396). diff --git a/dom/plugins/ipc/moz.build b/dom/plugins/ipc/moz.build index b569aeb4c1fa..0b3152771ad2 100644 --- a/dom/plugins/ipc/moz.build +++ b/dom/plugins/ipc/moz.build @@ -129,6 +129,7 @@ if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_ARCH'] == 'WINNT': LOCAL_INCLUDES += [ '/security/sandbox/chromium', '/security/sandbox/chromium-shim', + '/security/sandbox/win/src/sandboxpermissions', ] DEFINES['FORCE_PR_LOG'] = True diff --git a/ipc/ipdl/sync-messages.ini b/ipc/ipdl/sync-messages.ini index 9fe88f84bef3..93ebf41c7d96 100644 --- a/ipc/ipdl/sync-messages.ini +++ b/ipc/ipdl/sync-messages.ini @@ -657,6 +657,8 @@ description = description = [PPluginModule::InitCrashReporter] description = +[PPluginModule::GetFileName] +description = [PPluginScriptableObject::NPN_Evaluate] description = [PPluginScriptableObject::Invalidate] From d97e0e7bb8603046fb5c4bd260bbdf1c06300d0d Mon Sep 17 00:00:00 2001 From: Tom Schuster Date: Wed, 22 Feb 2017 21:16:04 +0100 Subject: [PATCH 132/234] Bug 1319087 - Implement a CrossCompartmentWrapper IC stub. r=bz,bholley,jandem --- js/public/Proxy.h | 4 ++ js/src/jit/BaselineCacheIRCompiler.cpp | 24 +++++++- js/src/jit/CacheIR.cpp | 79 +++++++++++++++++++++++++- js/src/jit/CacheIR.h | 28 ++++++++- js/src/jit/CacheIRCompiler.cpp | 69 ++++++++++++++++++++++ js/src/jit/CacheIRCompiler.h | 5 +- js/src/jit/IonCacheIRCompiler.cpp | 22 +++++++ js/src/jit/VMFunctions.cpp | 32 +++++++++++ js/src/jit/VMFunctions.h | 2 + js/src/jscompartment.h | 4 ++ js/src/vm/ObjectGroup.h | 4 ++ 11 files changed, 267 insertions(+), 6 deletions(-) diff --git a/js/public/Proxy.h b/js/public/Proxy.h index 5d24e938056d..3cb441a4ad29 100644 --- a/js/public/Proxy.h +++ b/js/public/Proxy.h @@ -383,6 +383,10 @@ struct ProxyValueArray for (size_t i = 0; i < PROXY_EXTRA_SLOTS; i++) extraSlots[i] = JS::UndefinedValue(); } + + static size_t offsetOfPrivateSlot() { + return offsetof(ProxyValueArray, privateSlot); + } }; // All proxies share the same data layout. Following the object's shape and diff --git a/js/src/jit/BaselineCacheIRCompiler.cpp b/js/src/jit/BaselineCacheIRCompiler.cpp index 8c0bafdd6902..208e9822802f 100644 --- a/js/src/jit/BaselineCacheIRCompiler.cpp +++ b/js/src/jit/BaselineCacheIRCompiler.cpp @@ -261,6 +261,24 @@ BaselineCacheIRCompiler::emitGuardProto() return true; } +bool +BaselineCacheIRCompiler::emitGuardCompartment() +{ + Register obj = allocator.useRegister(masm, reader.objOperandId()); + reader.stubOffset(); // Read global. + AutoScratchRegister scratch(allocator, masm); + + FailurePath* failure; + if (!addFailurePath(&failure)) + return false; + + Address addr(stubAddress(reader.stubOffset())); + masm.loadPtr(Address(obj, JSObject::offsetOfGroup()), scratch); + masm.loadPtr(Address(scratch, ObjectGroup::offsetOfCompartment()), scratch); + masm.branchPtr(Assembler::NotEqual, addr, scratch, failure->label()); + return true; +} + bool BaselineCacheIRCompiler::emitGuardSpecificObject() { @@ -354,11 +372,11 @@ BaselineCacheIRCompiler::emitLoadDynamicSlotResult() AutoOutputRegister output(*this); Register obj = allocator.useRegister(masm, reader.objOperandId()); AutoScratchRegisterMaybeOutput scratch(allocator, masm, output); + AutoScratchRegister scratch2(allocator, masm); - // We're about to return, so it's safe to clobber obj now. masm.load32(stubAddress(reader.stubOffset()), scratch); - masm.loadPtr(Address(obj, NativeObject::offsetOfSlots()), obj); - masm.loadValue(BaseIndex(obj, scratch, TimesOne), output.valueReg()); + masm.loadPtr(Address(obj, NativeObject::offsetOfSlots()), scratch2); + masm.loadValue(BaseIndex(scratch2, scratch, TimesOne), output.valueReg()); return true; } diff --git a/js/src/jit/CacheIR.cpp b/js/src/jit/CacheIR.cpp index 23040728001f..1f4043f339db 100644 --- a/js/src/jit/CacheIR.cpp +++ b/js/src/jit/CacheIR.cpp @@ -159,6 +159,8 @@ GetPropIRGenerator::tryAttachStub() return true; if (tryAttachWindowProxy(obj, objId, id)) return true; + if (tryAttachCrossCompartmentWrapper(obj, objId, id)) + return true; if (tryAttachFunction(obj, objId, id)) return true; if (tryAttachProxy(obj, objId, id)) @@ -435,11 +437,14 @@ EmitReadSlotResult(CacheIRWriter& writer, JSObject* obj, JSObject* holder, } static void -EmitReadSlotReturn(CacheIRWriter& writer, JSObject*, JSObject* holder, Shape* shape) +EmitReadSlotReturn(CacheIRWriter& writer, JSObject*, JSObject* holder, Shape* shape, + bool wrapResult = false) { // Slot access. if (holder) { MOZ_ASSERT(shape); + if (wrapResult) + writer.wrapResult(); writer.typeMonitorResult(); } else { // Normally for this op, the result would have to be monitored by TI. @@ -593,6 +598,78 @@ GetPropIRGenerator::tryAttachWindowProxy(HandleObject obj, ObjOperandId objId, H MOZ_CRASH("Unreachable"); } +bool +GetPropIRGenerator::tryAttachCrossCompartmentWrapper(HandleObject obj, ObjOperandId objId, + HandleId id) +{ + // We can only optimize this very wrapper-handler, because others might + // have a security policy. + if (!IsWrapper(obj) || Wrapper::wrapperHandler(obj) != &CrossCompartmentWrapper::singleton) + return false; + + RootedObject unwrapped(cx_, Wrapper::wrappedObject(obj)); + MOZ_ASSERT(unwrapped == UnwrapOneChecked(obj)); + + // If we allowed different zones we would have to wrap strings. + if (unwrapped->compartment()->zone() != cx_->compartment()->zone()) + return false; + + AutoCompartment ac(cx_, unwrapped); + + // The first CCW for iframes is almost always wrapping another WindowProxy + // so we optimize for that case as well. + bool isWindowProxy = IsWindowProxy(unwrapped); + if (isWindowProxy) { + MOZ_ASSERT(ToWindowIfWindowProxy(unwrapped) == unwrapped->compartment()->maybeGlobal()); + unwrapped = cx_->global(); + MOZ_ASSERT(unwrapped); + } + + RootedShape shape(cx_); + RootedNativeObject holder(cx_); + NativeGetPropCacheability canCache = + CanAttachNativeGetProp(cx_, unwrapped, id, &holder, &shape, pc_, canAttachGetter_, + isTemporarilyUnoptimizable_); + if (canCache != CanAttachReadSlot) + return false; + + if (holder) { + EnsureTrackPropertyTypes(cx_, holder, id); + if (unwrapped == holder) { + // See the comment in StripPreliminaryObjectStubs. + if (IsPreliminaryObject(unwrapped)) + preliminaryObjectAction_ = PreliminaryObjectAction::NotePreliminary; + else + preliminaryObjectAction_ = PreliminaryObjectAction::Unlink; + } + } + + maybeEmitIdGuard(id); + writer.guardIsProxy(objId); + writer.guardIsCrossCompartmentWrapper(objId); + + // Load the object wrapped by the CCW + ObjOperandId wrapperTargetId = writer.loadWrapperTarget(objId); + + // If the compartment of the wrapped object is different we should fail. + writer.guardCompartment(wrapperTargetId, unwrapped->compartment()); + + ObjOperandId unwrappedId = wrapperTargetId; + if (isWindowProxy) { + // For the WindowProxy case also unwrap the inner window. + // We avoid loadObject, because storing cross compartment objects in + // stubs / JIT code is tricky. + writer.guardClass(wrapperTargetId, GuardClassKind::WindowProxy); + unwrappedId = writer.loadWrapperTarget(wrapperTargetId); + } + + EmitReadSlotResult(writer, unwrapped, holder, shape, unwrappedId); + EmitReadSlotReturn(writer, unwrapped, holder, shape, /* wrapResult = */ true); + + trackAttached("CCWSlot"); + return true; +} + bool GetPropIRGenerator::tryAttachGenericProxy(HandleObject obj, ObjOperandId objId, HandleId id) { diff --git a/js/src/jit/CacheIR.h b/js/src/jit/CacheIR.h index e05cfbef1b9d..b38c9870c793 100644 --- a/js/src/jit/CacheIR.h +++ b/js/src/jit/CacheIR.h @@ -157,7 +157,9 @@ extern const char* CacheKindNames[]; _(GuardGroup) \ _(GuardProto) \ _(GuardClass) \ + _(GuardCompartment) \ _(GuardIsProxy) \ + _(GuardIsCrossCompartmentWrapper) \ _(GuardNotDOMProxy) \ _(GuardSpecificObject) \ _(GuardSpecificAtom) \ @@ -172,6 +174,7 @@ extern const char* CacheKindNames[]; _(LoadObject) \ _(LoadProto) \ _(LoadEnclosingEnvironment) \ + _(LoadWrapperTarget) \ \ /* See CacheIR.cpp 'DOM proxies' comment. */ \ _(LoadDOMExpandoValue) \ @@ -228,7 +231,8 @@ extern const char* CacheKindNames[]; _(LoadBooleanResult) \ \ _(TypeMonitorResult) \ - _(ReturnFromIC) + _(ReturnFromIC) \ + _(WrapResult) enum class CacheOp { #define DEFINE_OP(op) op, @@ -483,6 +487,9 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter void guardIsProxy(ObjOperandId obj) { writeOpWithOperandId(CacheOp::GuardIsProxy, obj); } + void guardIsCrossCompartmentWrapper(ObjOperandId obj) { + writeOpWithOperandId(CacheOp::GuardIsCrossCompartmentWrapper, obj); + } void guardNotDOMProxy(ObjOperandId obj) { writeOpWithOperandId(CacheOp::GuardNotDOMProxy, obj); } @@ -502,6 +509,14 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter writeOpWithOperandId(CacheOp::GuardMagicValue, val); buffer_.writeByte(uint32_t(magic)); } + void guardCompartment(ObjOperandId obj, JSCompartment* compartment) { + writeOpWithOperandId(CacheOp::GuardCompartment, obj); + // Add a reference to the compartment's global to keep it alive. + addStubField(uintptr_t(compartment->maybeGlobal()), StubField::Type::JSObject); + // Use RawWord, because compartments never move and it can't be GCed. + addStubField(uintptr_t(compartment), StubField::Type::RawWord); + + } void guardNoDetachedTypedObjects() { writeOp(CacheOp::GuardNoDetachedTypedObjects); } @@ -558,6 +573,13 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter return res; } + ObjOperandId loadWrapperTarget(ObjOperandId obj) { + ObjOperandId res(nextOperandId_++); + writeOpWithOperandId(CacheOp::LoadWrapperTarget, obj); + writeOperandId(res); + return res; + } + ValOperandId loadDOMExpandoValue(ObjOperandId obj) { ValOperandId res(nextOperandId_++); writeOpWithOperandId(CacheOp::LoadDOMExpandoValue, obj); @@ -829,6 +851,9 @@ class MOZ_RAII CacheIRWriter : public JS::CustomAutoRooter void returnFromIC() { writeOp(CacheOp::ReturnFromIC); } + void wrapResult() { + writeOp(CacheOp::WrapResult); + } }; class CacheIRStubInfo; @@ -950,6 +975,7 @@ class MOZ_RAII GetPropIRGenerator : public IRGenerator bool tryAttachObjectLength(HandleObject obj, ObjOperandId objId, HandleId id); bool tryAttachModuleNamespace(HandleObject obj, ObjOperandId objId, HandleId id); bool tryAttachWindowProxy(HandleObject obj, ObjOperandId objId, HandleId id); + bool tryAttachCrossCompartmentWrapper(HandleObject obj, ObjOperandId objId, HandleId id); bool tryAttachFunction(HandleObject obj, ObjOperandId objId, HandleId id); bool tryAttachGenericProxy(HandleObject obj, ObjOperandId objId, HandleId id); diff --git a/js/src/jit/CacheIRCompiler.cpp b/js/src/jit/CacheIRCompiler.cpp index 306b8aaad281..d9a64bd09882 100644 --- a/js/src/jit/CacheIRCompiler.cpp +++ b/js/src/jit/CacheIRCompiler.cpp @@ -1283,6 +1283,22 @@ CacheIRCompiler::emitGuardIsProxy() return true; } +bool +CacheIRCompiler::emitGuardIsCrossCompartmentWrapper() +{ + Register obj = allocator.useRegister(masm, reader.objOperandId()); + AutoScratchRegister scratch(allocator, masm); + + FailurePath* failure; + if (!addFailurePath(&failure)) + return false; + + Address handlerAddr(obj, ProxyObject::offsetOfHandler()); + masm.branchPtr(Assembler::NotEqual, handlerAddr, ImmPtr(&CrossCompartmentWrapper::singleton), + failure->label()); + return true; +} + bool CacheIRCompiler::emitGuardNotDOMProxy() { @@ -1419,6 +1435,17 @@ CacheIRCompiler::emitLoadEnclosingEnvironment() return true; } +bool +CacheIRCompiler::emitLoadWrapperTarget() +{ + Register obj = allocator.useRegister(masm, reader.objOperandId()); + Register reg = allocator.defineRegister(masm, reader.objOperandId()); + + masm.loadPtr(Address(obj, ProxyObject::offsetOfValues()), reg); + masm.unboxObject(Address(reg, detail::ProxyValueArray::offsetOfPrivateSlot()), reg); + return true; +} + bool CacheIRCompiler::emitLoadDOMExpandoValue() { @@ -1921,3 +1948,45 @@ CacheIRCompiler::emitLoadTypedObjectResultShared(const Address& fieldAddr, Regis } } } + +bool +CacheIRCompiler::emitWrapResult() +{ + AutoOutputRegister output(*this); + AutoScratchRegister scratch(allocator, masm); + + FailurePath* failure; + if (!addFailurePath(&failure)) + return false; + + Label done; + // We only have to wrap objects, because we are in the same zone. + masm.branchTestObject(Assembler::NotEqual, output.valueReg(), &done); + + Register obj = output.valueReg().scratchReg(); + masm.unboxObject(output.valueReg(), obj); + + AllocatableRegisterSet regs(RegisterSet::Volatile()); + LiveRegisterSet save(regs.asLiveSet()); + masm.PushRegsInMask(save); + + masm.setupUnalignedABICall(scratch); + masm.loadJSContext(scratch); + masm.passABIArg(scratch); + masm.passABIArg(obj); + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, WrapObjectPure)); + masm.mov(ReturnReg, obj); + + LiveRegisterSet ignore; + ignore.add(obj); + masm.PopRegsInMaskIgnore(save, ignore); + + // We could not get a wrapper for this object. + masm.branchTestPtr(Assembler::Zero, obj, obj, failure->label()); + + // We clobbered the output register, so we have to retag. + masm.tagValue(JSVAL_TYPE_OBJECT, obj, output.valueReg()); + + masm.bind(&done); + return true; +} diff --git a/js/src/jit/CacheIRCompiler.h b/js/src/jit/CacheIRCompiler.h index 2dff77559abc..04aa173c2a5d 100644 --- a/js/src/jit/CacheIRCompiler.h +++ b/js/src/jit/CacheIRCompiler.h @@ -23,6 +23,7 @@ namespace jit { _(GuardType) \ _(GuardClass) \ _(GuardIsProxy) \ + _(GuardIsCrossCompartmentWrapper) \ _(GuardNotDOMProxy) \ _(GuardMagicValue) \ _(GuardNoUnboxedExpando) \ @@ -32,6 +33,7 @@ namespace jit { _(GuardAndGetIndexFromString) \ _(LoadProto) \ _(LoadEnclosingEnvironment) \ + _(LoadWrapperTarget) \ _(LoadDOMExpandoValue) \ _(LoadDOMExpandoValueIgnoreGeneration)\ _(LoadUndefinedResult) \ @@ -47,7 +49,8 @@ namespace jit { _(LoadDenseElementHoleResult) \ _(LoadDenseElementExistsResult) \ _(LoadUnboxedArrayElementResult) \ - _(LoadTypedElementResult) + _(LoadTypedElementResult) \ + _(WrapResult) // Represents a Value on the Baseline frame's expression stack. Slot 0 is the // value on top of the stack (the most recently pushed value), slot 1 is the diff --git a/js/src/jit/IonCacheIRCompiler.cpp b/js/src/jit/IonCacheIRCompiler.cpp index cdb700a2ef22..a2f82a201881 100644 --- a/js/src/jit/IonCacheIRCompiler.cpp +++ b/js/src/jit/IonCacheIRCompiler.cpp @@ -95,6 +95,9 @@ class MOZ_RAII IonCacheIRCompiler : public CacheIRCompiler ObjectGroup* groupStubField(uint32_t offset) { return (ObjectGroup*)readStubWord(offset, StubField::Type::ObjectGroup); } + JSCompartment* compartmentStubField(uint32_t offset) { + return (JSCompartment*)readStubWord(offset, StubField::Type::RawWord); + } jsid idStubField(uint32_t offset) { return mozilla::BitwiseCast(readStubWord(offset, StubField::Type::Id)); } @@ -490,6 +493,25 @@ IonCacheIRCompiler::emitGuardProto() return true; } +bool +IonCacheIRCompiler::emitGuardCompartment() +{ + Register obj = allocator.useRegister(masm, reader.objOperandId()); + objectStubField(reader.stubOffset()); // Read global. + JSCompartment* compartment = compartmentStubField(reader.stubOffset()); + + AutoScratchRegister scratch(allocator, masm); + + FailurePath* failure; + if (!addFailurePath(&failure)) + return false; + + masm.loadPtr(Address(obj, JSObject::offsetOfGroup()), scratch); + masm.loadPtr(Address(scratch, ObjectGroup::offsetOfCompartment()), scratch); + masm.branchPtr(Assembler::NotEqual, scratch, ImmPtr(compartment), failure->label()); + return true; +} + bool IonCacheIRCompiler::emitGuardSpecificObject() { diff --git a/js/src/jit/VMFunctions.cpp b/js/src/jit/VMFunctions.cpp index 62f54adab830..de391d9050d1 100644 --- a/js/src/jit/VMFunctions.cpp +++ b/js/src/jit/VMFunctions.cpp @@ -694,6 +694,38 @@ GetIndexFromString(JSString* str) return int32_t(index); } +JSObject* +WrapObjectPure(JSContext* cx, JSObject* obj) +{ + MOZ_ASSERT(obj); + MOZ_ASSERT(cx->compartment() != obj->compartment()); + + // From: JSCompartment::getNonWrapperObjectForCurrentCompartment + // Note that if the object is same-compartment, but has been wrapped into a + // different compartment, we need to unwrap it and return the bare same- + // compartment object. Note again that windows are always wrapped by a + // WindowProxy even when same-compartment so take care not to strip this + // particular wrapper. + obj = UncheckedUnwrap(obj, /* stopAtWindowProxy = */ true); + if (cx->compartment() == obj->compartment()) { + MOZ_ASSERT(!IsWindow(obj)); + JS::ExposeObjectToActiveJS(obj); + return obj; + } + + // Try to Lookup an existing wrapper for this object. We assume that + // if we can find such a wrapper, not calling preWrap is correct. + if (WrapperMap::Ptr p = cx->compartment()->lookupWrapper(obj)) { + JSObject* wrapped = &p->value().get().toObject(); + + // Ensure the wrapper is still exposed. + JS::ExposeObjectToActiveJS(wrapped); + return wrapped; + } + + return nullptr; +} + bool DebugPrologue(JSContext* cx, BaselineFrame* frame, jsbytecode* pc, bool* mustReturn) { diff --git a/js/src/jit/VMFunctions.h b/js/src/jit/VMFunctions.h index 43dbdc9c415f..09352b78ea7d 100644 --- a/js/src/jit/VMFunctions.h +++ b/js/src/jit/VMFunctions.h @@ -679,6 +679,8 @@ void PostGlobalWriteBarrier(JSRuntime* rt, JSObject* obj); // is not an index in this range, return -1. int32_t GetIndexFromString(JSString* str); +JSObject* WrapObjectPure(JSContext* cx, JSObject* obj); + MOZ_MUST_USE bool DebugPrologue(JSContext* cx, BaselineFrame* frame, jsbytecode* pc, bool* mustReturn); MOZ_MUST_USE bool diff --git a/js/src/jscompartment.h b/js/src/jscompartment.h index 77fdee125ab5..a72fff42abb3 100644 --- a/js/src/jscompartment.h +++ b/js/src/jscompartment.h @@ -652,6 +652,10 @@ struct JSCompartment return crossCompartmentWrappers.lookup(js::CrossCompartmentKey(wrapped)); } + js::WrapperMap::Ptr lookupWrapper(JSObject* obj) const { + return crossCompartmentWrappers.lookup(js::CrossCompartmentKey(obj)); + } + void removeWrapper(js::WrapperMap::Ptr p) { crossCompartmentWrappers.remove(p); } diff --git a/js/src/vm/ObjectGroup.h b/js/src/vm/ObjectGroup.h index dd6d0c44acbf..f020e1a41e27 100644 --- a/js/src/vm/ObjectGroup.h +++ b/js/src/vm/ObjectGroup.h @@ -443,6 +443,10 @@ class ObjectGroup : public gc::TenuredCell return offsetof(ObjectGroup, proto_); } + static inline uint32_t offsetOfCompartment() { + return offsetof(ObjectGroup, compartment_); + } + static inline uint32_t offsetOfAddendum() { return offsetof(ObjectGroup, addendum_); } From be135e5df735d686151c33c043fc07153c41f20a Mon Sep 17 00:00:00 2001 From: Tom Schuster Date: Wed, 22 Feb 2017 21:16:04 +0100 Subject: [PATCH 133/234] Bug 1319087 - Simple CCW DOM test. r=me --- dom/tests/mochitest/general/mochitest.ini | 1 + .../general/test_CCW_optimization.html | 50 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 dom/tests/mochitest/general/test_CCW_optimization.html diff --git a/dom/tests/mochitest/general/mochitest.ini b/dom/tests/mochitest/general/mochitest.ini index 334240e360f9..0e1bd58697ef 100644 --- a/dom/tests/mochitest/general/mochitest.ini +++ b/dom/tests/mochitest/general/mochitest.ini @@ -81,6 +81,7 @@ subsuite = clipboard subsuite = clipboard [test_consoleAPI.html] [test_contentViewer_overrideDPPX.html] +[test_CCW_optimization.html] [test_DOMMatrix.html] [test_domWindowUtils.html] [test_domWindowUtils_scrollbarSize.html] diff --git a/dom/tests/mochitest/general/test_CCW_optimization.html b/dom/tests/mochitest/general/test_CCW_optimization.html new file mode 100644 index 000000000000..39c21383a31c --- /dev/null +++ b/dom/tests/mochitest/general/test_CCW_optimization.html @@ -0,0 +1,50 @@ + + + + + Test for Bug 1319087 + + + + + +Mozilla Bug 1319087 +

+
+ + +
+
+
+
+

From 8828af4759ca7d08eecc04b4814aaa3e5d66e856 Mon Sep 17 00:00:00 2001
From: Nathan Froyd 
Date: Wed, 22 Feb 2017 16:41:35 -0500
Subject: [PATCH 134/234] Bug 1336344 - use sizeof(pthread_mutex_t) to size
 MutexImpl's platformData_; r=fitzgen

For pthreads platforms, we have a terribly large condition for the size
of a MutexImpl that attempts to hardcode the number of words that
pthread_mutex_t takes.  This hardcoding isn't always correct.  We
originally did this to try and keep  includes out of the
headers, but the PlatformConditionVariable.h header already includes
 anyway, and  isn't so namespace-invasive as
.  So go ahead and include  and use the actual
definition of pthread_mutex_t to size the platformData_ member.
---
 mozglue/misc/PlatformMutex.h | 22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/mozglue/misc/PlatformMutex.h b/mozglue/misc/PlatformMutex.h
index ed275d685306..f70e4f2f83f4 100644
--- a/mozglue/misc/PlatformMutex.h
+++ b/mozglue/misc/PlatformMutex.h
@@ -10,6 +10,10 @@
 #include "mozilla/Attributes.h"
 #include "mozilla/Move.h"
 
+#if !defined(XP_WIN)
+# include 
+#endif
+
 namespace mozilla {
 
 namespace detail {
@@ -40,19 +44,13 @@ private:
 
   PlatformData* platformData();
 
-// Linux and maybe other platforms define the storage size of pthread_mutex_t in
-// bytes. However, we must define it as an array of void pointers to ensure
-// proper alignment.
-#if defined(__APPLE__) && defined(__MACH__) && defined(__i386__)
-  void* platformData_[11];
-#elif defined(__APPLE__) && defined(__MACH__) && defined(__amd64__)
-  void* platformData_[8];
-#elif defined(__linux__)
-  void* platformData_[40 / sizeof(void*)];
-#elif defined(_WIN32)
-  void* platformData_[6];
+#if !defined(XP_WIN)
+  void* platformData_[sizeof(pthread_mutex_t) / sizeof(void*)];
+  static_assert(sizeof(pthread_mutex_t) / sizeof(void*) != 0 &&
+                sizeof(pthread_mutex_t) % sizeof(void*) == 0,
+                "pthread_mutex_t must have pointer alignment");
 #else
-  void* platformData_[64 / sizeof(void*)];
+  void* platformData_[6];
 #endif
 
   friend class mozilla::detail::ConditionVariableImpl;

From 96fd46ec9750128e4cecca7bca66ded7454666a2 Mon Sep 17 00:00:00 2001
From: Shu-yu Guo 
Date: Wed, 22 Feb 2017 14:07:16 -0800
Subject: [PATCH 135/234] Bug 1341339 - Check for duplicates in
 processIterators. (r=jandem)

---
 js/src/jit-test/tests/for-of/bug-1341339.js | 9 +++++++++
 js/src/jit/IonBuilder.cpp                   | 9 ++++++---
 2 files changed, 15 insertions(+), 3 deletions(-)
 create mode 100644 js/src/jit-test/tests/for-of/bug-1341339.js

diff --git a/js/src/jit-test/tests/for-of/bug-1341339.js b/js/src/jit-test/tests/for-of/bug-1341339.js
new file mode 100644
index 000000000000..1f88acdafaa5
--- /dev/null
+++ b/js/src/jit-test/tests/for-of/bug-1341339.js
@@ -0,0 +1,9 @@
+let m = parseModule(`
+function* values() {}
+var iterator = values();
+for (var i=0; i < 10000; ++i) {
+    for (var x of iterator) {}
+}
+`);
+m.declarationInstantiation();
+m.evaluation();
diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp
index d2637af2476f..1089590261fe 100644
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -870,9 +870,12 @@ IonBuilder::processIterators()
     Vector worklist;
 
     for (size_t i = 0; i < iterators_.length(); i++) {
-        if (!worklist.append(iterators_[i]))
-            return abort(AbortReason::Alloc);
-        iterators_[i]->setInWorklist();
+        MDefinition* iter = iterators_[i];
+        if (!iter->isInWorklist()) {
+            if (!worklist.append(iter))
+                return abort(AbortReason::Alloc);
+            iter->setInWorklist();
+        }
     }
 
     while (!worklist.empty()) {

From b5702c22fa4db41704ac572eb2c14f3e5417148d Mon Sep 17 00:00:00 2001
From: Shu-yu Guo 
Date: Wed, 22 Feb 2017 14:07:16 -0800
Subject: [PATCH 136/234] Bug 977849 - Followup: unskip test262 on Android.
 (r=sfink)

---
 js/src/tests/jstests.list | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/js/src/tests/jstests.list b/js/src/tests/jstests.list
index 332acd651433..e1c739cd6892 100644
--- a/js/src/tests/jstests.list
+++ b/js/src/tests/jstests.list
@@ -3,9 +3,6 @@
 
 skip script ecma_6/String/normalize-generateddata-input.js # input data for other test
 
-# jsreftest times out on Android when the complete test262 test suite is enabled.
-skip-if(Android) include test262/jstests.list
-
 # Times out on arm and cgc builds.
 slow script test262/built-ins/decodeURI/S15.1.3.1_A2.5_T1.js
 slow script test262/built-ins/decodeURIComponent/S15.1.3.2_A2.5_T1.js

From f7fb97ad16936aa8e487704635f311bf76507458 Mon Sep 17 00:00:00 2001
From: Nathan Froyd 
Date: Wed, 22 Feb 2017 17:15:02 -0500
Subject: [PATCH 138/234] Bug 1338282 - remove profile.dev options from
 rust-url-capi's Cargo.toml; r=valentin

---
 netwerk/base/rust-url-capi/Cargo.toml | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/netwerk/base/rust-url-capi/Cargo.toml b/netwerk/base/rust-url-capi/Cargo.toml
index 32cf27d86cb4..e5dae795243d 100644
--- a/netwerk/base/rust-url-capi/Cargo.toml
+++ b/netwerk/base/rust-url-capi/Cargo.toml
@@ -1,19 +1,11 @@
 [package]
-
 name = "rust_url_capi"
 version = "0.0.1"
 authors = ["Valentin Gosu "]
 
-[profile.dev]
-opt-level = 3
-debug = true
-rpath = true
-lto = true
-
 [lib]
 name = "rust_url_capi"
 
-
 [dependencies]
 libc = "0.2.0"
 url = "1.4.0"

From 504e663ff0262a5854390c51077660157d373cf5 Mon Sep 17 00:00:00 2001
From: Luke Wagner 
Date: Wed, 22 Feb 2017 16:12:27 -0600
Subject: [PATCH 139/234] Bug 1337561 - Baldr: call largeAllocationCallback and
 retry if executable allocation fails (r=jandem)

MozReview-Commit-ID: 1gMbNH13XuV

--HG--
extra : rebase_source : f454c047be1654c7372ddbf048d633094c801379
---
 js/src/wasm/WasmCode.cpp | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/js/src/wasm/WasmCode.cpp b/js/src/wasm/WasmCode.cpp
index db3a72b313f4..bb65b45adad4 100644
--- a/js/src/wasm/WasmCode.cpp
+++ b/js/src/wasm/WasmCode.cpp
@@ -71,6 +71,18 @@ AllocateCodeSegment(JSContext* cx, uint32_t codeLength)
     codeLength = JS_ROUNDUP(codeLength, ExecutableCodePageSize);
 
     void* p = AllocateExecutableMemory(codeLength, ProtectionSetting::Writable);
+
+    // If the allocation failed and the embedding gives us a last-ditch attempt
+    // to purge all memory (which, in gecko, does a purging GC/CC/GC), do that
+    // then retry the allocation.
+    if (!p) {
+        JSRuntime* rt = cx->runtime();
+        if (rt->largeAllocationFailureCallback) {
+            rt->largeAllocationFailureCallback(rt->largeAllocationFailureCallbackData);
+            p = AllocateExecutableMemory(codeLength, ProtectionSetting::Writable);
+        }
+    }
+
     if (!p) {
         ReportOutOfMemory(cx);
         return nullptr;

From 505f2bfb241c5f15e24d642837dc73ed105cfdeb Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote 
Date: Wed, 15 Feb 2017 14:44:07 +1100
Subject: [PATCH 140/234] Bug 1340928 (part 1) - Two small
 platform-linux-android.cpp tweaks. r=mstange.

- Don't bother checking gSampler in ProfilerSignalHandler. It is equivalent
  to checking gIsActive and we do that at the top of the loop in
  SignalSender(). There is no point repeatedly checking the same condition in
  the middle of that loop; that just opens up the possibility of partially
  complete samples where some threads are missing.

- Clear gCurrentThreadInfo in SignalSender() instead of in
  ProfilerSignalHandler(). The effect is much the same, but this change means
  gCurrentThreadInfo is both set and cleared in SignalSender(), i.e. on a
  single thread, removing any need for Atomic<>.

--HG--
extra : rebase_source : 645d321de4cad6fdb32383b6f1d0c7cbe54308fc
---
 tools/profiler/core/platform-linux-android.cpp | 15 ++++-----------
 1 file changed, 4 insertions(+), 11 deletions(-)

diff --git a/tools/profiler/core/platform-linux-android.cpp b/tools/profiler/core/platform-linux-android.cpp
index ceaf713292d1..44837912dd93 100644
--- a/tools/profiler/core/platform-linux-android.cpp
+++ b/tools/profiler/core/platform-linux-android.cpp
@@ -62,7 +62,6 @@
 #include 
 
 #include "prenv.h"
-#include "mozilla/Atomics.h"
 #include "mozilla/LinuxSignal.h"
 #include "mozilla/DebugOnly.h"
 #include "ProfileEntry.h"
@@ -146,7 +145,7 @@ static void* setup_atfork() {
 }
 #endif /* !defined(GP_OS_android) */
 
-static mozilla::Atomic gCurrentThreadInfo;
+static ThreadInfo* gCurrentThreadInfo;
 static sem_t gSignalHandlingDone;
 
 static void SetSampleContext(TickSample* sample, void* context)
@@ -178,13 +177,6 @@ SigprofHandler(int signal, siginfo_t* info, void* context)
   // Avoid TSan warning about clobbering errno.
   int savedErrno = errno;
 
-  // XXX: this is an off-main-thread(?) use of gSampler
-  if (!gSampler) {
-    sem_post(&gSignalHandlingDone);
-    errno = savedErrno;
-    return;
-  }
-
   TickSample sample_obj;
   TickSample* sample = &sample_obj;
   sample->context = context;
@@ -198,7 +190,6 @@ SigprofHandler(int signal, siginfo_t* info, void* context)
 
   Tick(sample);
 
-  gCurrentThreadInfo = NULL;
   sem_post(&gSignalHandlingDone);
   errno = savedErrno;
 }
@@ -326,8 +317,10 @@ SigprofSender(void* aArg)
 #endif
         }
 
-        // Wait for the signal handler to run before moving on to the next one
+        // Wait for the signal handler to run before moving on to the next one.
         sem_wait(&gSignalHandlingDone);
+
+        gCurrentThreadInfo = nullptr;
         isFirstProfiledThread = false;
       }
 #if defined(USE_LUL_STACKWALK)

From fba65fb101092435a59f5f6ea219c55e61b06a62 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote 
Date: Wed, 15 Feb 2017 14:44:09 +1100
Subject: [PATCH 141/234] Bug 1340928 (part 2) - Don't use ThreadInfo to pass
 Linux memory measurements. r=mstange.

This change means that all the relevant code is now within
platform-linux-android.cpp, which is nice.

--HG--
extra : rebase_source : 886a31005fdb67fae65e6f4209796973f1391244
---
 tools/profiler/core/ThreadInfo.cpp            |  4 ----
 tools/profiler/core/ThreadInfo.h              |  9 --------
 .../profiler/core/platform-linux-android.cpp  | 23 ++++++++++++++-----
 3 files changed, 17 insertions(+), 19 deletions(-)

diff --git a/tools/profiler/core/ThreadInfo.cpp b/tools/profiler/core/ThreadInfo.cpp
index 9e424fc7a1b4..abb13ce054d1 100644
--- a/tools/profiler/core/ThreadInfo.cpp
+++ b/tools/profiler/core/ThreadInfo.cpp
@@ -23,10 +23,6 @@ ThreadInfo::ThreadInfo(const char* aName, int aThreadId,
   , mStackTop(aStackTop)
   , mPendingDelete(false)
   , mMutex(MakeUnique("ThreadInfo::mMutex"))
-#if defined(GP_OS_linux) || defined(GP_OS_android)
-  , mRssMemory(0)
-  , mUssMemory(0)
-#endif
 {
   MOZ_COUNT_CTOR(ThreadInfo);
   mThread = NS_GetCurrentThread();
diff --git a/tools/profiler/core/ThreadInfo.h b/tools/profiler/core/ThreadInfo.h
index 7b5905058b1b..82b2e42126ab 100644
--- a/tools/profiler/core/ThreadInfo.h
+++ b/tools/profiler/core/ThreadInfo.h
@@ -106,15 +106,6 @@ private:
 
   mozilla::UniquePtr mMutex;
   ThreadResponsiveness mRespInfo;
-
-#if defined(GP_OS_linux) || defined(GP_OS_android)
-  // Only Linux is using a signal sender, instead of stopping the thread, so we
-  // need some space to store the data which cannot be collected in the signal
-  // handler code.
-public:
-  int64_t mRssMemory;
-  int64_t mUssMemory;
-#endif
 };
 
 #endif
diff --git a/tools/profiler/core/platform-linux-android.cpp b/tools/profiler/core/platform-linux-android.cpp
index 44837912dd93..925b7c61b8a6 100644
--- a/tools/profiler/core/platform-linux-android.cpp
+++ b/tools/profiler/core/platform-linux-android.cpp
@@ -145,7 +145,13 @@ static void* setup_atfork() {
 }
 #endif /* !defined(GP_OS_android) */
 
+// Global variables through which data is sent from SigprofSender() to
+// SigprofHandler(). gSignalHandlingDone provides inter-thread synchronization.
 static ThreadInfo* gCurrentThreadInfo;
+static int64_t gRssMemory;
+static int64_t gUssMemory;
+
+// Semaphore used to coordinate SigprofSender() and SigprofHandler().
 static sem_t gSignalHandlingDone;
 
 static void SetSampleContext(TickSample* sample, void* context)
@@ -185,8 +191,8 @@ SigprofHandler(int signal, siginfo_t* info, void* context)
   SetSampleContext(sample, context);
   sample->threadInfo = gCurrentThreadInfo;
   sample->timestamp = mozilla::TimeStamp::Now();
-  sample->rssMemory = sample->threadInfo->mRssMemory;
-  sample->ussMemory = sample->threadInfo->mUssMemory;
+  sample->rssMemory = gRssMemory;
+  sample->ussMemory = gUssMemory;
 
   Tick(sample);
 
@@ -298,11 +304,11 @@ SigprofSender(void* aArg)
         // safe, and will have low variation between the emission of the signal
         // and the signal handler catch.
         if (isFirstProfiledThread && gProfileMemory) {
-          info->mRssMemory = nsMemoryReporterManager::ResidentFast();
-          info->mUssMemory = nsMemoryReporterManager::ResidentUnique();
+          gRssMemory = nsMemoryReporterManager::ResidentFast();
+          gUssMemory = nsMemoryReporterManager::ResidentUnique();
         } else {
-          info->mRssMemory = 0;
-          info->mUssMemory = 0;
+          gRssMemory = 0;
+          gUssMemory = 0;
         }
 
         // Profile from the signal handler for information which is signal safe
@@ -321,6 +327,9 @@ SigprofSender(void* aArg)
         sem_wait(&gSignalHandlingDone);
 
         gCurrentThreadInfo = nullptr;
+        gRssMemory = 0;
+        gUssMemory = 0;
+
         isFirstProfiledThread = false;
       }
 #if defined(USE_LUL_STACKWALK)
@@ -365,6 +374,8 @@ PlatformStart()
 
   // Initialize signal handler communication
   gCurrentThreadInfo = nullptr;
+  gRssMemory = 0;
+  gUssMemory = 0;
   if (sem_init(&gSignalHandlingDone, /* pshared: */ 0, /* value: */ 0) != 0) {
     LOG("Error initializing semaphore");
     return;

From a84399b3b5eb6877ed96c8df9b7cb83c2d6e24d8 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote 
Date: Wed, 15 Feb 2017 14:44:12 +1100
Subject: [PATCH 142/234] Bug 1340928 (part 3) - Remove Sampler from
 ProfileGatherer. r=mstange.

It's only being used in a boolean fashion, so this patch replaces it with a
boolean.

--HG--
extra : rebase_source : 91152dff81107070fa49b3984e1b6759e0cd6d20
---
 tools/profiler/core/platform.cpp         |  2 +-
 tools/profiler/gecko/ProfileGatherer.cpp | 11 +++++------
 tools/profiler/public/ProfileGatherer.h  |  6 ++----
 3 files changed, 8 insertions(+), 11 deletions(-)

diff --git a/tools/profiler/core/platform.cpp b/tools/profiler/core/platform.cpp
index 76777ff8f95f..19f31c2a0819 100644
--- a/tools/profiler/core/platform.cpp
+++ b/tools/profiler/core/platform.cpp
@@ -2029,7 +2029,7 @@ profiler_start(int aProfileEntries, double aInterval,
   }
 #endif
 
-  gGatherer = new mozilla::ProfileGatherer(gSampler);
+  gGatherer = new mozilla::ProfileGatherer();
 
   MOZ_ASSERT(!gIsActive && !gIsPaused);
   PlatformStart();
diff --git a/tools/profiler/gecko/ProfileGatherer.cpp b/tools/profiler/gecko/ProfileGatherer.cpp
index 79451bfa36e6..4c8c620f72a4 100644
--- a/tools/profiler/gecko/ProfileGatherer.cpp
+++ b/tools/profiler/gecko/ProfileGatherer.cpp
@@ -27,8 +27,8 @@ static const uint32_t MAX_SUBPROCESS_EXIT_PROFILES = 5;
 
 NS_IMPL_ISUPPORTS(ProfileGatherer, nsIObserver)
 
-ProfileGatherer::ProfileGatherer(Sampler* aSampler)
-  : mSampler(aSampler)
+ProfileGatherer::ProfileGatherer()
+  : mIsCancelled(false)
   , mSinceTime(0)
   , mPendingProfiles(0)
   , mGathering(false)
@@ -145,7 +145,7 @@ ProfileGatherer::Finish()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  if (!mSampler) {
+  if (mIsCancelled) {
     // We somehow got called after we were cancelled! This shouldn't
     // be possible, but doing a belt-and-suspenders check to be sure.
     return;
@@ -216,7 +216,7 @@ ProfileGatherer::Reset()
 void
 ProfileGatherer::Cancel()
 {
-  // The Sampler is going away. If we have a Promise in flight, we should
+  // We're about to stop profiling. If we have a Promise in flight, we should
   // reject it.
   if (mPromise) {
     mPromise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
@@ -224,8 +224,7 @@ ProfileGatherer::Cancel()
   mPromise = nullptr;
   mFile = nullptr;
 
-  // Clear out the Sampler reference, since it's being destroyed.
-  mSampler = nullptr;
+  mIsCancelled = true;
 }
 
 void
diff --git a/tools/profiler/public/ProfileGatherer.h b/tools/profiler/public/ProfileGatherer.h
index 03dc8aedce7b..63b34aa8f529 100644
--- a/tools/profiler/public/ProfileGatherer.h
+++ b/tools/profiler/public/ProfileGatherer.h
@@ -8,8 +8,6 @@
 #include "mozilla/dom/Promise.h"
 #include "nsIFile.h"
 
-class Sampler;
-
 namespace mozilla {
 
 class ProfileGatherer final : public nsIObserver
@@ -18,7 +16,7 @@ public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIOBSERVER
 
-  explicit ProfileGatherer(Sampler* aSampler);
+  explicit ProfileGatherer();
   void WillGatherOOPProfile();
   void GatheredOOPProfile();
   void Start(double aSinceTime, mozilla::dom::Promise* aPromise);
@@ -35,7 +33,7 @@ private:
   nsTArray mExitProfiles;
   RefPtr mPromise;
   nsCOMPtr mFile;
-  Sampler* mSampler;
+  bool mIsCancelled;
   double mSinceTime;
   uint32_t mPendingProfiles;
   bool mGathering;

From 598cac65d4aa5b33d576166c398d1ae57fbf71ae Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote 
Date: Wed, 15 Feb 2017 14:44:12 +1100
Subject: [PATCH 143/234] Bug 1340928 (part 4) - Remove redundant
 PlatformStop() call in profiler_stop(). r=mstange.

There is another PlatformStop() call earlier in the function, and gIsActive is
always false by the time we reach the removed call, so it's dead code.

--HG--
extra : rebase_source : 3b358b6bef47d394d6d6bc76d1153ea38968919e
---
 tools/profiler/core/platform.cpp | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/tools/profiler/core/platform.cpp b/tools/profiler/core/platform.cpp
index 19f31c2a0819..ba0c3e25498f 100644
--- a/tools/profiler/core/platform.cpp
+++ b/tools/profiler/core/platform.cpp
@@ -2139,9 +2139,6 @@ profiler_stop()
   gProfileThreads   = false;
   gUseStackWalk     = false;
 
-  if (gIsActive)
-    PlatformStop();
-
   // Destroy ThreadInfo for all threads
   {
     StaticMutexAutoLock lock(gRegisteredThreadsMutex);

From 8c6f56c330cc458565e12ed0cd788f10c582dead Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote 
Date: Wed, 15 Feb 2017 14:44:12 +1100
Subject: [PATCH 144/234] Bug 1340928 (part 5) - Pass the interval to
 PlatformStart(). r=mstange.

This avoids the need for platform-linux-android.cpp to read gInterval off the
main thread in an awkward spot. It also makes platform-linux-android.cpp
more like platform-{win32,macos}.cpp.

--HG--
extra : rebase_source : c1c76a382d6373f9fd2e3f89a1e1f8fef9072257
---
 tools/profiler/core/platform-linux-android.cpp | 16 +++++++++++-----
 tools/profiler/core/platform-macos.cpp         | 12 ++++++------
 tools/profiler/core/platform-win32.cpp         | 13 ++++++-------
 tools/profiler/core/platform.cpp               | 10 +++-------
 4 files changed, 26 insertions(+), 25 deletions(-)

diff --git a/tools/profiler/core/platform-linux-android.cpp b/tools/profiler/core/platform-linux-android.cpp
index 925b7c61b8a6..d3b959b70f6d 100644
--- a/tools/profiler/core/platform-linux-android.cpp
+++ b/tools/profiler/core/platform-linux-android.cpp
@@ -145,6 +145,8 @@ static void* setup_atfork() {
 }
 #endif /* !defined(GP_OS_android) */
 
+static int gIntervalMicro;
+
 // Global variables through which data is sent from SigprofSender() to
 // SigprofHandler(). gSignalHandlingDone provides inter-thread synchronization.
 static ThreadInfo* gCurrentThreadInfo;
@@ -342,11 +344,8 @@ SigprofSender(void* aArg)
 #endif
     }
 
-    // This off-main-thread use of gInterval is safe due to implicit
-    // synchronization -- this function cannot run at the same time as
-    // profiler_{start,stop}(), where gInterval is set.
     TimeStamp targetSleepEndTime =
-      sampleStart + TimeDuration::FromMicroseconds(gInterval * 1000);
+      sampleStart + TimeDuration::FromMicroseconds(gIntervalMicro);
     TimeStamp beforeSleep = TimeStamp::Now();
     TimeDuration targetSleepDuration = targetSleepEndTime - beforeSleep;
     double sleepTime = std::max(0.0, (targetSleepDuration - lastSleepOverhead).ToMicroseconds());
@@ -358,7 +357,7 @@ SigprofSender(void* aArg)
 }
 
 static void
-PlatformStart()
+PlatformStart(double aInterval)
 {
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
 
@@ -372,6 +371,11 @@ PlatformStart()
   }
 #endif
 
+  gIntervalMicro = floor(aInterval * 1000 + 0.5);
+  if (gIntervalMicro <= 0) {
+    gIntervalMicro = 1;
+  }
+
   // Initialize signal handler communication
   gCurrentThreadInfo = nullptr;
   gRssMemory = 0;
@@ -426,6 +430,8 @@ PlatformStop()
   MOZ_ASSERT(gIsActive);
   gIsActive = false;
 
+  gIntervalMicro = 0;
+
   // Wait for signal sender termination (it will exit after setting
   // active_ to false).
   if (gHasSigprofSenderLaunched) {
diff --git a/tools/profiler/core/platform-macos.cpp b/tools/profiler/core/platform-macos.cpp
index 2ff975f0b622..fc67feec2d92 100644
--- a/tools/profiler/core/platform-macos.cpp
+++ b/tools/profiler/core/platform-macos.cpp
@@ -80,8 +80,8 @@ PlatformDataDestructor::operator()(PlatformData* aData)
 class SamplerThread
 {
 public:
-  explicit SamplerThread(double interval)
-    : mIntervalMicro(floor(interval * 1000 + 0.5))
+  explicit SamplerThread(double aInterval)
+    : mIntervalMicro(floor(aInterval * 1000 + 0.5))
   {
     if (mIntervalMicro <= 0) {
       mIntervalMicro = 1;
@@ -120,12 +120,12 @@ public:
     pthread_join(mThread, NULL);
   }
 
-  static void StartSampler() {
+  static void StartSampler(double aInterval) {
     MOZ_RELEASE_ASSERT(NS_IsMainThread());
     MOZ_RELEASE_ASSERT(!mInstance);
 
     if (mInstance == NULL) {
-      mInstance = new SamplerThread(gInterval);
+      mInstance = new SamplerThread(aInterval);
       mInstance->Start();
     }
   }
@@ -261,13 +261,13 @@ PlatformInit()
 }
 
 static void
-PlatformStart()
+PlatformStart(double aInterval)
 {
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
 
   MOZ_ASSERT(!gIsActive);
   gIsActive = true;
-  SamplerThread::StartSampler();
+  SamplerThread::StartSampler(aInterval);
 }
 
 static void
diff --git a/tools/profiler/core/platform-win32.cpp b/tools/profiler/core/platform-win32.cpp
index 9bab1a7225fd..01219339dec9 100644
--- a/tools/profiler/core/platform-win32.cpp
+++ b/tools/profiler/core/platform-win32.cpp
@@ -87,11 +87,10 @@ static const HANDLE kNoThread = INVALID_HANDLE_VALUE;
 class SamplerThread
 {
  public:
-  explicit SamplerThread(double interval)
+  explicit SamplerThread(double aInterval)
     : mThread(kNoThread)
-    , mInterval(interval)
+    , mInterval(floor(aInterval + 0.5))
   {
-    mInterval = floor(interval + 0.5);
     if (mInterval <= 0) {
       mInterval = 1;
     }
@@ -129,11 +128,11 @@ class SamplerThread
     }
   }
 
-  static void StartSampler() {
+  static void StartSampler(double aInterval) {
     MOZ_RELEASE_ASSERT(NS_IsMainThread());
     MOZ_RELEASE_ASSERT(!mInstance);
 
-    mInstance = new SamplerThread(gInterval);
+    mInstance = new SamplerThread(aInterval);
     mInstance->Start();
   }
 
@@ -273,13 +272,13 @@ PlatformInit()
 }
 
 static void
-PlatformStart()
+PlatformStart(double aInterval)
 {
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
 
   MOZ_ASSERT(!gIsActive);
   gIsActive = true;
-  SamplerThread::StartSampler();
+  SamplerThread::StartSampler(aInterval);
 }
 
 static void
diff --git a/tools/profiler/core/platform.cpp b/tools/profiler/core/platform.cpp
index ba0c3e25498f..d1279be44823 100644
--- a/tools/profiler/core/platform.cpp
+++ b/tools/profiler/core/platform.cpp
@@ -122,11 +122,7 @@ static Vector gFeatures;
 // All accesses to gEntrySize are on the main thread, so no locking is needed.
 static int gEntrySize = 0;
 
-// This variable is set on the main thread in profiler_{start,stop}(), and
-// mostly read on the main thread. There is one read off the main thread in
-// SigprofSender() in platform-linux.cc which is safe because there is implicit
-// synchronization between that function and the set points in
-// profiler_{start,stop}().
+// All accesses to gInterval are on the main thread, so no locking is needed.
 static double gInterval = 0;
 
 // XXX: These two variables are used extensively both on and off the main
@@ -1591,7 +1587,7 @@ RegisterCurrentThread(const char* aName, PseudoStack* aPseudoStack,
 
 // Platform-specific init/start/stop actions.
 static void PlatformInit();
-static void PlatformStart();
+static void PlatformStart(double aInterval);
 static void PlatformStop();
 
 void
@@ -2032,7 +2028,7 @@ profiler_start(int aProfileEntries, double aInterval,
   gGatherer = new mozilla::ProfileGatherer();
 
   MOZ_ASSERT(!gIsActive && !gIsPaused);
-  PlatformStart();
+  PlatformStart(gInterval);
   MOZ_ASSERT(gIsActive && !gIsPaused);  // PlatformStart() sets gIsActive.
 
   if (gProfileJS || privacyMode) {

From 5c520e77db18d10f83782e7c44734421ddbe98d3 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote 
Date: Thu, 16 Feb 2017 13:59:35 +1100
Subject: [PATCH 145/234] Bug 1340928 (part 6) - Clean up profiler code
 relating to env vars. r=mstange.

This patch mostly does formatting fixes.

It also removes some declarations from platform.h that are no longer necessary
now that platform-linux-android.cpp is in the same compilation unit as
platform.cpp (due to it being #include-d directly); this required reordering
some things.

--HG--
extra : rebase_source : d07ef71455885fe8f1414d87c261ca054989a6a8
---
 tools/profiler/core/platform.cpp | 180 ++++++++++++++++---------------
 tools/profiler/core/platform.h   |  16 ---
 2 files changed, 94 insertions(+), 102 deletions(-)

diff --git a/tools/profiler/core/platform.cpp b/tools/profiler/core/platform.cpp
index d1279be44823..60b6b40cd3db 100644
--- a/tools/profiler/core/platform.cpp
+++ b/tools/profiler/core/platform.cpp
@@ -167,13 +167,6 @@ static Atomic gProfileRestyle(false);
 static Atomic gProfileThreads(false);
 static Atomic gUseStackWalk(false);
 
-// Environment variables to control the profiler
-const char* PROFILER_HELP = "MOZ_PROFILER_HELP";
-const char* PROFILER_INTERVAL = "MOZ_PROFILER_INTERVAL";
-const char* PROFILER_ENTRIES = "MOZ_PROFILER_ENTRIES";
-const char* PROFILER_STACK = "MOZ_PROFILER_STACK_SCAN";
-const char* PROFILER_FEATURES = "MOZ_PROFILING_FEATURES";
-
 /* we don't need to worry about overflow because we only treat the
  * case of them being the same as special. i.e. we only run into
  * a problem if 2^32 events happen between samples that we need
@@ -1253,43 +1246,43 @@ void ProfilerMarker::StreamJSON(SpliceableJSONWriter& aWriter,
   aWriter.EndArray();
 }
 
-/* Has MOZ_PROFILER_VERBOSE been set? */
-
 // Verbosity control for the profiler.  The aim is to check env var
 // MOZ_PROFILER_VERBOSE only once.  However, we may need to temporarily
 // override that so as to print the profiler's help message.  That's
 // what profiler_set_verbosity is for.
 
-enum class ProfilerVerbosity : int8_t { UNCHECKED, NOTVERBOSE, VERBOSE };
+enum class Verbosity : int8_t { UNCHECKED, NOTVERBOSE, VERBOSE };
 
 // Raced on, potentially
-static ProfilerVerbosity profiler_verbosity = ProfilerVerbosity::UNCHECKED;
+static Verbosity gVerbosity = Verbosity::UNCHECKED;
 
-bool profiler_verbose()
+bool
+profiler_verbose()
 {
-  if (profiler_verbosity == ProfilerVerbosity::UNCHECKED) {
-    if (getenv("MOZ_PROFILER_VERBOSE") != nullptr)
-      profiler_verbosity = ProfilerVerbosity::VERBOSE;
-    else
-      profiler_verbosity = ProfilerVerbosity::NOTVERBOSE;
+  if (gVerbosity == Verbosity::UNCHECKED) {
+    gVerbosity = getenv("MOZ_PROFILER_VERBOSE")
+                       ? Verbosity::VERBOSE
+                       : Verbosity::NOTVERBOSE;
   }
 
-  return profiler_verbosity == ProfilerVerbosity::VERBOSE;
+  return gVerbosity == Verbosity::VERBOSE;
 }
 
-void profiler_set_verbosity(ProfilerVerbosity pv)
+static void
+profiler_set_verbosity(Verbosity aPv)
 {
-   MOZ_ASSERT(pv == ProfilerVerbosity::UNCHECKED ||
-              pv == ProfilerVerbosity::VERBOSE);
-   profiler_verbosity = pv;
+  MOZ_ASSERT(aPv == Verbosity::UNCHECKED ||
+             aPv == Verbosity::VERBOSE);
+  gVerbosity = aPv;
 }
 
-
-bool set_profiler_interval(const char* interval) {
-  if (interval) {
+static bool
+set_profiler_interval(const char* aInterval)
+{
+  if (aInterval) {
     errno = 0;
-    long int n = strtol(interval, (char**)nullptr, 10);
-    if (errno == 0 && n >= 1 && n <= 1000) {
+    long int n = strtol(aInterval, nullptr, 10);
+    if (errno == 0 && 1 <= n && n <= 1000) {
       gUnwindInterval = n;
       return true;
     }
@@ -1299,10 +1292,12 @@ bool set_profiler_interval(const char* interval) {
   return true;
 }
 
-bool set_profiler_entries(const char* entries) {
-  if (entries) {
+static bool
+set_profiler_entries(const char* aEntries)
+{
+  if (aEntries) {
     errno = 0;
-    long int n = strtol(entries, (char**)nullptr, 10);
+    long int n = strtol(aEntries, nullptr, 10);
     if (errno == 0 && n > 0) {
       gProfileEntries = n;
       return true;
@@ -1313,11 +1308,13 @@ bool set_profiler_entries(const char* entries) {
   return true;
 }
 
-bool set_profiler_scan(const char* scanCount) {
-  if (scanCount) {
+static bool
+set_profiler_scan(const char* aScanCount)
+{
+  if (aScanCount) {
     errno = 0;
-    long int n = strtol(scanCount, (char**)nullptr, 10);
-    if (errno == 0 && n >= 0 && n <= 100) {
+    long int n = strtol(aScanCount, nullptr, 10);
+    if (errno == 0 && 0 <= n && n <= 100) {
       gUnwindStackScan = n;
       return true;
     }
@@ -1327,7 +1324,9 @@ bool set_profiler_scan(const char* scanCount) {
   return true;
 }
 
-bool is_native_unwinding_avail() {
+static bool
+is_native_unwinding_avail()
+{
 # if defined(HAVE_NATIVE_UNWIND)
   return true;
 #else
@@ -1335,44 +1334,18 @@ bool is_native_unwinding_avail() {
 #endif
 }
 
-// Read env vars at startup, so as to set:
-//   gUnwindInterval, gProfileEntries, gUnwindStackScan.
-void read_profiler_env_vars()
+// Environment variables to control the profiler
+static const char* PROFILER_HELP     = "MOZ_PROFILER_HELP";
+static const char* PROFILER_INTERVAL = "MOZ_PROFILER_INTERVAL";
+static const char* PROFILER_ENTRIES  = "MOZ_PROFILER_ENTRIES";
+static const char* PROFILER_STACK    = "MOZ_PROFILER_STACK_SCAN";
+#if defined(GP_OS_android)
+static const char* PROFILER_FEATURES = "MOZ_PROFILING_FEATURES";
+#endif
+
+static void
+profiler_usage()
 {
-  /* Set defaults */
-  gUnwindInterval = 0;  /* We'll have to look elsewhere */
-  gProfileEntries = 0;
-
-  const char* interval = getenv(PROFILER_INTERVAL);
-  const char* entries = getenv(PROFILER_ENTRIES);
-  const char* scanCount = getenv(PROFILER_STACK);
-
-  if (getenv(PROFILER_HELP)) {
-     // Enable verbose output
-     profiler_set_verbosity(ProfilerVerbosity::VERBOSE);
-     profiler_usage();
-     // Now force the next enquiry of profiler_verbose to re-query
-     // env var MOZ_PROFILER_VERBOSE.
-     profiler_set_verbosity(ProfilerVerbosity::UNCHECKED);
-  }
-
-  if (!set_profiler_interval(interval) ||
-      !set_profiler_entries(entries) ||
-      !set_profiler_scan(scanCount)) {
-      profiler_usage();
-  } else {
-    LOG( "Profiler:");
-    LOGF("Profiler: Sampling interval = %d ms (zero means \"platform default\")",
-        (int)gUnwindInterval);
-    LOGF("Profiler: Entry store size  = %d (zero means \"platform default\")",
-        (int)gProfileEntries);
-    LOGF("Profiler: UnwindStackScan   = %d (max dubious frames per unwind).",
-        (int)gUnwindStackScan);
-    LOG( "Profiler:");
-  }
-}
-
-void profiler_usage() {
   LOG( "Profiler: ");
   LOG( "Profiler: Environment variable usage:");
   LOG( "Profiler: ");
@@ -1412,19 +1385,54 @@ void profiler_usage() {
   LOGF("Profiler: UnwindStackScan   = %d (max dubious frames per unwind).",
        (int)gUnwindStackScan);
   LOG( "Profiler:");
-
-  return;
 }
 
-bool is_main_thread_name(const char* aName) {
-  if (!aName) {
-    return false;
+// Read env vars at startup, so as to set:
+//   gUnwindInterval, gProfileEntries, gUnwindStackScan.
+static void
+read_profiler_env_vars()
+{
+  /* Set defaults */
+  gUnwindInterval = 0;  /* We'll have to look elsewhere */
+  gProfileEntries = 0;
+
+  const char* interval = getenv(PROFILER_INTERVAL);
+  const char* entries = getenv(PROFILER_ENTRIES);
+  const char* scanCount = getenv(PROFILER_STACK);
+
+  if (getenv(PROFILER_HELP)) {
+    // Enable verbose output
+    profiler_set_verbosity(Verbosity::VERBOSE);
+    profiler_usage();
+    // Now force the next enquiry of profiler_verbose to re-query
+    // env var MOZ_PROFILER_VERBOSE.
+    profiler_set_verbosity(Verbosity::UNCHECKED);
   }
-  return strcmp(aName, gGeckoThreadName) == 0;
+
+  if (!set_profiler_interval(interval) ||
+      !set_profiler_entries(entries) ||
+      !set_profiler_scan(scanCount)) {
+      profiler_usage();
+  } else {
+    LOG( "Profiler:");
+    LOGF("Profiler: Sampling interval = %d ms (zero means \"platform default\")",
+        (int)gUnwindInterval);
+    LOGF("Profiler: Entry store size  = %d (zero means \"platform default\")",
+        (int)gProfileEntries);
+    LOGF("Profiler: UnwindStackScan   = %d (max dubious frames per unwind).",
+        (int)gUnwindStackScan);
+    LOG( "Profiler:");
+  }
+}
+
+static bool
+is_main_thread_name(const char* aName)
+{
+  return aName && (strcmp(aName, gGeckoThreadName) == 0);
 }
 
 #ifdef HAVE_VA_COPY
-#define VARARGS_ASSIGN(foo, bar)        VA_COPY(foo,bar)
+#define VARARGS_ASSIGN(foo, bar)     VA_COPY(foo,bar)
 #elif defined(HAVE_VA_LIST_AS_ARRAY)
 #define VARARGS_ASSIGN(foo, bar)     foo[0] = bar[0]
 #else
@@ -1432,15 +1440,15 @@ bool is_main_thread_name(const char* aName) {
 #endif
 
 void
-profiler_log(const char* str)
+profiler_log(const char* aStr)
 {
   // This function runs both on and off the main thread.
 
-  profiler_tracing("log", str, TRACING_EVENT);
+  profiler_tracing("log", aStr, TRACING_EVENT);
 }
 
 void
-profiler_log(const char* fmt, va_list args)
+profiler_log(const char* aFmt, va_list aArgs)
 {
   // This function runs both on and off the main thread.
 
@@ -1449,8 +1457,8 @@ profiler_log(const char* fmt, va_list args)
     // this is mozilla external code
     char buf[2048];
     va_list argsCpy;
-    VARARGS_ASSIGN(argsCpy, args);
-    int required = VsprintfLiteral(buf, fmt, argsCpy);
+    VARARGS_ASSIGN(argsCpy, aArgs);
+    int required = VsprintfLiteral(buf, aFmt, argsCpy);
     va_end(argsCpy);
 
     if (required < 0) {
@@ -1460,8 +1468,8 @@ profiler_log(const char* fmt, va_list args)
     } else {
       char* heapBuf = new char[required+1];
       va_list argsCpy;
-      VARARGS_ASSIGN(argsCpy, args);
-      vsnprintf(heapBuf, required+1, fmt, argsCpy);
+      VARARGS_ASSIGN(argsCpy, aArgs);
+      vsnprintf(heapBuf, required+1, aFmt, argsCpy);
       va_end(argsCpy);
       // EVENT_BACKTRACE could be used to get a source
       // for all log events. This could be a runtime
diff --git a/tools/profiler/core/platform.h b/tools/profiler/core/platform.h
index 91b0edc6efa4..f6dea9385957 100644
--- a/tools/profiler/core/platform.h
+++ b/tools/profiler/core/platform.h
@@ -133,22 +133,6 @@ public:
 # define HAVE_NATIVE_UNWIND
 #endif
 
-/* Some values extracted at startup from environment variables, that
-   control the behaviour of the breakpad unwinder. */
-extern const char* PROFILER_INTERVAL;
-extern const char* PROFILER_ENTRIES;
-extern const char* PROFILER_STACK;
-extern const char* PROFILER_FEATURES;
-
-void read_profiler_env_vars();
-void profiler_usage();
-
-// Helper methods to expose modifying profiler behavior
-bool set_profiler_interval(const char*);
-bool set_profiler_entries(const char*);
-bool set_profiler_scan(const char*);
-bool is_native_unwinding_avail();
-
 // ----------------------------------------------------------------------------
 // Miscellaneous
 

From 3c26f56f0b6a0f47978d18933fa76747016541f5 Mon Sep 17 00:00:00 2001
From: Jessica Jong 
Date: Mon, 20 Feb 2017 22:43:00 -0500
Subject: [PATCH 146/234] Bug 1335356 - Part 1: Insert caption and thead in the
 right order. r=smaug

---
 dom/html/HTMLTableElement.cpp                 | 21 +++++++++++++++----
 dom/html/HTMLTableElement.h                   | 16 ++++++++++++--
 .../the-caption-element/caption_001.html.ini  |  5 -----
 .../caption-methods.html.ini                  | 10 ---------
 .../the-table-element/tHead.html.ini          |  5 -----
 5 files changed, 31 insertions(+), 26 deletions(-)
 delete mode 100644 testing/web-platform/meta/html/semantics/tabular-data/the-caption-element/caption_001.html.ini
 delete mode 100644 testing/web-platform/meta/html/semantics/tabular-data/the-table-element/tHead.html.ini

diff --git a/dom/html/HTMLTableElement.cpp b/dom/html/HTMLTableElement.cpp
index 699576f56926..541596813c6b 100644
--- a/dom/html/HTMLTableElement.cpp
+++ b/dom/html/HTMLTableElement.cpp
@@ -411,8 +411,19 @@ HTMLTableElement::CreateTHead()
       return nullptr;
     }
 
-    ErrorResult rv;
-    nsCOMPtr refNode = nsINode::GetFirstChild();
+    nsCOMPtr refNode = nullptr;
+    for (refNode = nsINode::GetFirstChild();
+         refNode;
+         refNode = refNode->GetNextSibling()) {
+
+      if (refNode->IsHTMLElement() &&
+          !refNode->IsHTMLElement(nsGkAtoms::caption) &&
+          !refNode->IsHTMLElement(nsGkAtoms::colgroup)) {
+        break;
+      }
+    }
+
+    IgnoredErrorResult rv;
     nsINode::InsertBefore(*head, refNode, rv);
   }
   return head.forget();
@@ -475,7 +486,9 @@ HTMLTableElement::CreateCaption()
       return nullptr;
     }
 
-    AppendChildTo(caption, true);
+    IgnoredErrorResult rv;
+    nsCOMPtr firsChild = nsINode::GetFirstChild();
+    nsINode::InsertBefore(*caption, firsChild, rv);
   }
   return caption.forget();
 }
@@ -514,7 +527,7 @@ HTMLTableElement::CreateTBody()
     }
   }
 
-  ErrorResult rv;
+  IgnoredErrorResult rv;
   nsINode::InsertBefore(*newBody, referenceNode, rv);
 
   return newBody.forget();
diff --git a/dom/html/HTMLTableElement.h b/dom/html/HTMLTableElement.h
index 899c549f38f1..2b666f84d55b 100644
--- a/dom/html/HTMLTableElement.h
+++ b/dom/html/HTMLTableElement.h
@@ -36,7 +36,8 @@ public:
   {
     DeleteCaption();
     if (aCaption) {
-      nsINode::AppendChild(*aCaption, aError);
+      nsCOMPtr firstChild = nsINode::GetFirstChild();
+      nsINode::InsertBefore(*aCaption, firstChild, aError);
     }
   }
 
@@ -59,7 +60,18 @@ public:
 
     DeleteTHead();
     if (aTHead) {
-      nsCOMPtr refNode = nsINode::GetFirstChild();
+
+      nsCOMPtr refNode = nullptr;
+      for (refNode = nsINode::GetFirstChild();
+           refNode;
+           refNode = refNode->GetNextSibling()) {
+        if (refNode->IsHTMLElement() &&
+            !refNode->IsHTMLElement(nsGkAtoms::caption) &&
+            !refNode->IsHTMLElement(nsGkAtoms::colgroup)) {
+          break;
+        }
+      }
+
       nsINode::InsertBefore(*aTHead, refNode, aError);
     }
   }
diff --git a/testing/web-platform/meta/html/semantics/tabular-data/the-caption-element/caption_001.html.ini b/testing/web-platform/meta/html/semantics/tabular-data/the-caption-element/caption_001.html.ini
deleted file mode 100644
index bb7580d2acb7..000000000000
--- a/testing/web-platform/meta/html/semantics/tabular-data/the-caption-element/caption_001.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[caption_001.html]
-  type: testharness
-  [setting caption on a table]
-    expected: FAIL
-
diff --git a/testing/web-platform/meta/html/semantics/tabular-data/the-table-element/caption-methods.html.ini b/testing/web-platform/meta/html/semantics/tabular-data/the-table-element/caption-methods.html.ini
index 848003ff77b8..891adee209eb 100644
--- a/testing/web-platform/meta/html/semantics/tabular-data/the-table-element/caption-methods.html.ini
+++ b/testing/web-platform/meta/html/semantics/tabular-data/the-table-element/caption-methods.html.ini
@@ -1,14 +1,4 @@
 [caption-methods.html]
-  type: testharness
-  [createCaption method creates a new caption and inserts it as the first node of the table element]
-    expected: FAIL
-
-  [createCaption method creates new caption if existing caption is not in html namespace]
-    expected: FAIL
-
   [createCaption will not copy table's prefix]
     expected: FAIL
 
-  [Assigning a caption to table.caption]
-    expected: FAIL
-
diff --git a/testing/web-platform/meta/html/semantics/tabular-data/the-table-element/tHead.html.ini b/testing/web-platform/meta/html/semantics/tabular-data/the-table-element/tHead.html.ini
deleted file mode 100644
index 61364e793d08..000000000000
--- a/testing/web-platform/meta/html/semantics/tabular-data/the-table-element/tHead.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[tHead.html]
-  type: testharness
-  [tHead tests]
-    expected: FAIL
-

From 94e413bc2386ef9dcf7a91c1dd1e8f0700d2a25e Mon Sep 17 00:00:00 2001
From: Jessica Jong 
Date: Mon, 20 Feb 2017 22:44:00 -0500
Subject: [PATCH 147/234] Bug 1335356 - Part 2: Rename
 nsContentUtils::NameChanged to QNameChanged and use null prefix. r=smaug

---
 dom/base/nsContentUtils.cpp                   |  6 ++---
 dom/base/nsContentUtils.h                     | 10 ++++----
 dom/html/HTMLSelectElement.cpp                |  4 ++--
 dom/html/HTMLTableElement.cpp                 | 24 +++++++++----------
 dom/html/HTMLTableRowElement.cpp              |  4 ++--
 dom/html/HTMLTableSectionElement.cpp          |  4 ++--
 .../caption-methods.html.ini                  |  4 ----
 .../table-insertRow.html.ini                  |  5 ----
 .../common-HTMLOptionsCollection.html         | 18 ++++++++++++++
 .../tabular-data/the-table-element/tFoot.html |  8 +++++++
 .../tabular-data/the-table-element/tHead.html |  8 +++++++
 .../the-tr-element/insertCell.html            |  9 +++++++
 12 files changed, 70 insertions(+), 34 deletions(-)
 delete mode 100644 testing/web-platform/meta/html/semantics/tabular-data/the-table-element/caption-methods.html.ini
 delete mode 100644 testing/web-platform/meta/html/semantics/tabular-data/the-table-element/table-insertRow.html.ini

diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp
index 99b55360ccb2..c09827e9497b 100644
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -3444,12 +3444,12 @@ nsContentUtils::IsDraggableLink(const nsIContent* aContent) {
 
 // static
 nsresult
-nsContentUtils::NameChanged(mozilla::dom::NodeInfo* aNodeInfo, nsIAtom* aName,
-                            mozilla::dom::NodeInfo** aResult)
+nsContentUtils::QNameChanged(mozilla::dom::NodeInfo* aNodeInfo, nsIAtom* aName,
+                             mozilla::dom::NodeInfo** aResult)
 {
   nsNodeInfoManager *niMgr = aNodeInfo->NodeInfoManager();
 
-  *aResult = niMgr->GetNodeInfo(aName, aNodeInfo->GetPrefixAtom(),
+  *aResult = niMgr->GetNodeInfo(aName, nullptr,
                                 aNodeInfo->NamespaceID(),
                                 aNodeInfo->NodeType(),
                                 aNodeInfo->GetExtraName()).take();
diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h
index 2146f7ddb4a0..af250c46c05b 100644
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -796,11 +796,13 @@ public:
   static bool IsDraggableLink(const nsIContent* aContent);
 
   /**
-   * Convenience method to create a new nodeinfo that differs only by name
-   * from aNodeInfo.
+   * Convenience method to create a new nodeinfo that differs only by prefix and
+   * name from aNodeInfo. The new nodeinfo's name is set to aName, and prefix is
+   * set to null.
    */
-  static nsresult NameChanged(mozilla::dom::NodeInfo* aNodeInfo, nsIAtom* aName,
-                              mozilla::dom::NodeInfo** aResult);
+  static nsresult QNameChanged(mozilla::dom::NodeInfo* aNodeInfo,
+                               nsIAtom* aName,
+                               mozilla::dom::NodeInfo** aResult);
 
   /**
    * Returns the appropriate event argument names for the specified
diff --git a/dom/html/HTMLSelectElement.cpp b/dom/html/HTMLSelectElement.cpp
index 0f4dbaa87733..5d0b00a69803 100644
--- a/dom/html/HTMLSelectElement.cpp
+++ b/dom/html/HTMLSelectElement.cpp
@@ -717,8 +717,8 @@ HTMLSelectElement::SetLength(uint32_t aLength, ErrorResult& aRv)
 
     RefPtr nodeInfo;
 
-    nsContentUtils::NameChanged(mNodeInfo, nsGkAtoms::option,
-                                getter_AddRefs(nodeInfo));
+    nsContentUtils::QNameChanged(mNodeInfo, nsGkAtoms::option,
+                                 getter_AddRefs(nodeInfo));
 
     nsCOMPtr node = NS_NewHTMLOptionElement(nodeInfo.forget());
 
diff --git a/dom/html/HTMLTableElement.cpp b/dom/html/HTMLTableElement.cpp
index 541596813c6b..c941b0a07787 100644
--- a/dom/html/HTMLTableElement.cpp
+++ b/dom/html/HTMLTableElement.cpp
@@ -403,8 +403,8 @@ HTMLTableElement::CreateTHead()
   if (!head) {
     // Create a new head rowgroup.
     RefPtr nodeInfo;
-    nsContentUtils::NameChanged(mNodeInfo, nsGkAtoms::thead,
-                                getter_AddRefs(nodeInfo));
+    nsContentUtils::QNameChanged(mNodeInfo, nsGkAtoms::thead,
+                                 getter_AddRefs(nodeInfo));
 
     head = NS_NewHTMLTableSectionElement(nodeInfo.forget());
     if (!head) {
@@ -447,8 +447,8 @@ HTMLTableElement::CreateTFoot()
   if (!foot) {
     // create a new foot rowgroup
     RefPtr nodeInfo;
-    nsContentUtils::NameChanged(mNodeInfo, nsGkAtoms::tfoot,
-                                getter_AddRefs(nodeInfo));
+    nsContentUtils::QNameChanged(mNodeInfo, nsGkAtoms::tfoot,
+                                 getter_AddRefs(nodeInfo));
 
     foot = NS_NewHTMLTableSectionElement(nodeInfo.forget());
     if (!foot) {
@@ -478,8 +478,8 @@ HTMLTableElement::CreateCaption()
   if (!caption) {
     // Create a new caption.
     RefPtr nodeInfo;
-    nsContentUtils::NameChanged(mNodeInfo, nsGkAtoms::caption,
-                                getter_AddRefs(nodeInfo));
+    nsContentUtils::QNameChanged(mNodeInfo, nsGkAtoms::caption,
+                                 getter_AddRefs(nodeInfo));
 
     caption = NS_NewHTMLTableCaptionElement(nodeInfo.forget());
     if (!caption) {
@@ -573,8 +573,8 @@ HTMLTableElement::InsertRow(int32_t aIndex, ErrorResult& aError)
 
     // create the row
     RefPtr nodeInfo;
-    nsContentUtils::NameChanged(mNodeInfo, nsGkAtoms::tr,
-                                getter_AddRefs(nodeInfo));
+    nsContentUtils::QNameChanged(mNodeInfo, nsGkAtoms::tr,
+                                 getter_AddRefs(nodeInfo));
 
     newRow = NS_NewHTMLTableRowElement(nodeInfo.forget());
 
@@ -607,8 +607,8 @@ HTMLTableElement::InsertRow(int32_t aIndex, ErrorResult& aError)
 
     if (!rowGroup) { // need to create a TBODY
       RefPtr nodeInfo;
-      nsContentUtils::NameChanged(mNodeInfo, nsGkAtoms::tbody,
-                                  getter_AddRefs(nodeInfo));
+      nsContentUtils::QNameChanged(mNodeInfo, nsGkAtoms::tbody,
+                                   getter_AddRefs(nodeInfo));
 
       rowGroup = NS_NewHTMLTableSectionElement(nodeInfo.forget());
       if (rowGroup) {
@@ -621,8 +621,8 @@ HTMLTableElement::InsertRow(int32_t aIndex, ErrorResult& aError)
 
     if (rowGroup) {
       RefPtr nodeInfo;
-      nsContentUtils::NameChanged(mNodeInfo, nsGkAtoms::tr,
-                                  getter_AddRefs(nodeInfo));
+      nsContentUtils::QNameChanged(mNodeInfo, nsGkAtoms::tr,
+                                   getter_AddRefs(nodeInfo));
 
       newRow = NS_NewHTMLTableRowElement(nodeInfo.forget());
       if (newRow) {
diff --git a/dom/html/HTMLTableRowElement.cpp b/dom/html/HTMLTableRowElement.cpp
index 86edeebb0e43..fccccc1e5282 100644
--- a/dom/html/HTMLTableRowElement.cpp
+++ b/dom/html/HTMLTableRowElement.cpp
@@ -175,8 +175,8 @@ HTMLTableRowElement::InsertCell(int32_t aIndex,
 
   // create the cell
   RefPtr nodeInfo;
-  nsContentUtils::NameChanged(mNodeInfo, nsGkAtoms::td,
-                              getter_AddRefs(nodeInfo));
+  nsContentUtils::QNameChanged(mNodeInfo, nsGkAtoms::td,
+                               getter_AddRefs(nodeInfo));
 
   RefPtr cell =
     NS_NewHTMLTableCellElement(nodeInfo.forget());
diff --git a/dom/html/HTMLTableSectionElement.cpp b/dom/html/HTMLTableSectionElement.cpp
index b74ca536c2dc..07994959b760 100644
--- a/dom/html/HTMLTableSectionElement.cpp
+++ b/dom/html/HTMLTableSectionElement.cpp
@@ -80,8 +80,8 @@ HTMLTableSectionElement::InsertRow(int32_t aIndex, ErrorResult& aError)
 
   // create the row
   RefPtr nodeInfo;
-  nsContentUtils::NameChanged(mNodeInfo, nsGkAtoms::tr,
-                              getter_AddRefs(nodeInfo));
+  nsContentUtils::QNameChanged(mNodeInfo, nsGkAtoms::tr,
+                               getter_AddRefs(nodeInfo));
 
   RefPtr rowContent =
     NS_NewHTMLTableRowElement(nodeInfo.forget());
diff --git a/testing/web-platform/meta/html/semantics/tabular-data/the-table-element/caption-methods.html.ini b/testing/web-platform/meta/html/semantics/tabular-data/the-table-element/caption-methods.html.ini
deleted file mode 100644
index 891adee209eb..000000000000
--- a/testing/web-platform/meta/html/semantics/tabular-data/the-table-element/caption-methods.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[caption-methods.html]
-  [createCaption will not copy table's prefix]
-    expected: FAIL
-
diff --git a/testing/web-platform/meta/html/semantics/tabular-data/the-table-element/table-insertRow.html.ini b/testing/web-platform/meta/html/semantics/tabular-data/the-table-element/table-insertRow.html.ini
deleted file mode 100644
index 5b21e073ce49..000000000000
--- a/testing/web-platform/meta/html/semantics/tabular-data/the-table-element/table-insertRow.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[table-insertRow.html]
-  type: testharness
-  [insertRow should not copy prefixes]
-    expected: FAIL
-
diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/common-HTMLOptionsCollection.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/common-HTMLOptionsCollection.html
index 307b73f8722b..737e9be87683 100644
--- a/testing/web-platform/tests/html/semantics/forms/the-select-element/common-HTMLOptionsCollection.html
+++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/common-HTMLOptionsCollection.html
@@ -96,4 +96,22 @@ test(function () {
 
 }, "Setting element by index should correctly append and replace elements");
 
+test(function () {
+    var selection = document.createElementNS("http://www.w3.org/1999/xhtml", "foo:select");
+
+    selection.length = 5;
+    assert_equals(selection.length, 5,
+                  "Number of nodes in collection should have changed");
+    for (var i = 0; i < 5; ++i) {
+        var child = selection.children[i];
+        assert_equals(child.localName, "option",
+                      "new child should be an option");
+        assert_equals(child.namespaceURI, "http://www.w3.org/1999/xhtml",
+                      "new child should be an HTML element");
+        assert_equals(child.prefix, null,
+                      "new child should not copy select's prefix");
+    }
+
+}, "Changing the length adds new nodes; The new nodes will not copy select's prefix");
+
 
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/tFoot.html b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/tFoot.html
index d06e16f2005e..e83d193f35f7 100644
--- a/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/tFoot.html
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/tFoot.html
@@ -54,4 +54,12 @@ test(function() {
         t.tFoot = document.createElement("thead");
     });
 })
+
+test(function () {
+    var table = document.createElementNS("http://www.w3.org/1999/xhtml", "foo:table")
+    var tfoot = table.createTFoot();
+
+    assert_equals(table.tFoot, tfoot);
+    assert_equals(tfoot.prefix, null);
+});
 
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/tHead.html b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/tHead.html
index ea2ebf1281da..78a874824df2 100644
--- a/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/tHead.html
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/tHead.html
@@ -63,4 +63,12 @@ test(function() {
         t2.tHead = t2thead;
     });
 });
+
+test(function () {
+    var table = document.createElementNS("http://www.w3.org/1999/xhtml", "foo:table")
+    var thead = table.createTHead();
+
+    assert_equals(table.tHead, thead);
+    assert_equals(thead.prefix, null);
+});
 
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/insertCell.html b/testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/insertCell.html
index 07eac1efb592..7c2edc4acbf3 100644
--- a/testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/insertCell.html
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/insertCell.html
@@ -52,4 +52,13 @@ test(function () {
   });
 }, "HTMLTableRowElement insertCell(cells.length + 1)");
 
+test(function () {
+  var table = document.createElementNS("http://www.w3.org/1999/xhtml", "foo:table")
+  var row = table.insertRow(0);
+  var cell = row.insertCell(0);
+
+  assert_equals(row.cells[0], cell);
+  assert_equals(cell.prefix, null);
+}, "HTMLTableRowElement insertCell will not copy table's prefix");
+
 

From cf171891174f6e668056301204d908e16023a86f Mon Sep 17 00:00:00 2001
From: Jessica Jong 
Date: Wed, 22 Feb 2017 01:00:00 -0500
Subject: [PATCH 148/234] Bug 1340086 - Remove uses of AnimationsPaused() since
 it is always false after bug 1316330. r=mrbkap

---
 docshell/base/nsDocShell.cpp         |  9 +--
 dom/base/nsDOMWindowUtils.cpp        |  4 +-
 dom/base/nsDocument.cpp              | 91 +++++++---------------------
 dom/base/nsDocument.h                | 12 +---
 dom/base/nsGlobalWindow.cpp          | 10 +--
 dom/base/nsIDocument.h               | 17 +-----
 dom/bindings/BindingUtils.cpp        |  2 +-
 dom/xhr/XMLHttpRequestMainThread.cpp |  5 +-
 layout/base/nsDocumentViewer.cpp     |  3 +-
 9 files changed, 37 insertions(+), 116 deletions(-)

diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp
index 75206c188018..b1319c3638be 100644
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -8852,14 +8852,7 @@ nsDocShell::RestoreFromHistory()
       nsCOMPtr d = parent->GetDocument();
       if (d) {
         if (d->EventHandlingSuppressed()) {
-          document->SuppressEventHandling(nsIDocument::eEvents,
-                                          d->EventHandlingSuppressed());
-        }
-
-        // Ick, it'd be nicer to not rewalk all of the subdocs here.
-        if (d->AnimationsPaused()) {
-          document->SuppressEventHandling(nsIDocument::eAnimationsOnly,
-                                          d->AnimationsPaused());
+          document->SuppressEventHandling(d->EventHandlingSuppressed());
         }
       }
     }
diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp
index 40ae9485c2b1..53e34c86d7ba 100644
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -1650,9 +1650,9 @@ nsDOMWindowUtils::SuppressEventHandling(bool aSuppress)
   NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
 
   if (aSuppress) {
-    doc->SuppressEventHandling(nsIDocument::eEvents);
+    doc->SuppressEventHandling();
   } else {
-    doc->UnsuppressEventHandlingAndFireEvents(nsIDocument::eEvents, true);
+    doc->UnsuppressEventHandlingAndFireEvents(true);
   }
 
   return NS_OK;
diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
index 657e9415eec5..159e942b2348 100644
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -1358,7 +1358,6 @@ nsIDocument::nsIDocument()
     mPresShell(nullptr),
     mSubtreeModifiedDepth(0),
     mEventsSuppressed(0),
-    mAnimationsPaused(0),
     mExternalScriptsBeingEvaluated(0),
     mFrameRequestCallbackCounter(0),
     mStaticCloneCount(0),
@@ -3811,7 +3810,7 @@ nsDocument::CreateShell(nsPresContext* aContext, nsViewManager* aViewManager,
 void
 nsDocument::MaybeRescheduleAnimationFrameNotifications()
 {
-  if (!mPresShell || !IsEventHandlingEnabled() || AnimationsPaused()) {
+  if (!mPresShell || !IsEventHandlingEnabled()) {
     // bail out for now, until one of those conditions changes
     return;
   }
@@ -3874,7 +3873,7 @@ void
 nsDocument::DeleteShell()
 {
   mExternalResourceMap.HideViewers();
-  if (IsEventHandlingEnabled() && !AnimationsPaused()) {
+  if (IsEventHandlingEnabled()) {
     RevokeAnimationFrameNotifications();
   }
   if (nsPresContext* presContext = mPresShell->GetPresContext()) {
@@ -4656,7 +4655,7 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject)
     // our layout history state now.
     mLayoutHistoryState = GetLayoutHistoryState();
 
-    if (mPresShell && !EventHandlingSuppressed() && !AnimationsPaused()) {
+    if (mPresShell && !EventHandlingSuppressed()) {
       RevokeAnimationFrameNotifications();
     }
 
@@ -9325,44 +9324,28 @@ nsIDocument::GetReadyState(nsAString& aReadyState) const
   }
 }
 
-namespace {
-
-struct SuppressArgs
-{
-  nsIDocument::SuppressionType mWhat;
-  uint32_t mIncrease;
-};
-
-} // namespace
-
 static bool
 SuppressEventHandlingInDocument(nsIDocument* aDocument, void* aData)
 {
-  SuppressArgs* args = static_cast(aData);
-  aDocument->SuppressEventHandling(args->mWhat, args->mIncrease);
+  aDocument->SuppressEventHandling(*static_cast(aData));
+
   return true;
 }
 
 void
-nsDocument::SuppressEventHandling(nsIDocument::SuppressionType aWhat,
-                                  uint32_t aIncrease)
+nsDocument::SuppressEventHandling(uint32_t aIncrease)
 {
-  if (mEventsSuppressed == 0 && mAnimationsPaused == 0 &&
-      aIncrease != 0 && mPresShell && mScriptGlobalObject) {
+  if (mEventsSuppressed == 0 && aIncrease != 0 && mPresShell &&
+      mScriptGlobalObject) {
     RevokeAnimationFrameNotifications();
   }
 
-  if (aWhat == eAnimationsOnly) {
-    mAnimationsPaused += aIncrease;
-  } else {
-    mEventsSuppressed += aIncrease;
-    for (uint32_t i = 0; i < aIncrease; ++i) {
-      ScriptLoader()->AddExecuteBlocker();
-    }
+  mEventsSuppressed += aIncrease;
+  for (uint32_t i = 0; i < aIncrease; ++i) {
+    ScriptLoader()->AddExecuteBlocker();
   }
 
-  SuppressArgs args = { aWhat, aIncrease };
-  EnumerateSubDocuments(SuppressEventHandlingInDocument, &args);
+  EnumerateSubDocuments(SuppressEventHandlingInDocument, &aIncrease);
 }
 
 static void
@@ -9664,62 +9647,35 @@ private:
   nsTArray > mDocuments;
 };
 
-namespace {
-
-struct UnsuppressArgs
-{
-  explicit UnsuppressArgs(nsIDocument::SuppressionType aWhat)
-    : mWhat(aWhat)
-  {
-  }
-
-  nsIDocument::SuppressionType mWhat;
-  nsTArray> mDocs;
-};
-
-} // namespace
-
 static bool
 GetAndUnsuppressSubDocuments(nsIDocument* aDocument,
                              void* aData)
 {
-  UnsuppressArgs* args = static_cast(aData);
-  if (args->mWhat != nsIDocument::eAnimationsOnly &&
-      aDocument->EventHandlingSuppressed() > 0) {
+  if (aDocument->EventHandlingSuppressed() > 0) {
     static_cast(aDocument)->DecreaseEventSuppression();
     aDocument->ScriptLoader()->RemoveExecuteBlocker();
-  } else if (args->mWhat == nsIDocument::eAnimationsOnly &&
-             aDocument->AnimationsPaused()) {
-    static_cast(aDocument)->ResumeAnimations();
   }
 
-  if (args->mWhat != nsIDocument::eAnimationsOnly) {
-    // No need to remember documents if we only care about animation frames.
-    args->mDocs.AppendElement(aDocument);
-  }
+  nsTArray >* docs =
+    static_cast >* >(aData);
 
+  docs->AppendElement(aDocument);
   aDocument->EnumerateSubDocuments(GetAndUnsuppressSubDocuments, aData);
   return true;
 }
 
 void
-nsDocument::UnsuppressEventHandlingAndFireEvents(nsIDocument::SuppressionType aWhat,
-                                                 bool aFireEvents)
+nsDocument::UnsuppressEventHandlingAndFireEvents(bool aFireEvents)
 {
-  UnsuppressArgs args(aWhat);
-  GetAndUnsuppressSubDocuments(this, &args);
-
-  if (aWhat == nsIDocument::eAnimationsOnly) {
-    // No need to fire events if we only care about animations here.
-    return;
-  }
+  nsTArray> documents;
+  GetAndUnsuppressSubDocuments(this, &documents);
 
   if (aFireEvents) {
     MOZ_RELEASE_ASSERT(NS_IsMainThread());
-    nsCOMPtr ded = new nsDelayedEventDispatcher(args.mDocs);
+    nsCOMPtr ded = new nsDelayedEventDispatcher(documents);
     Dispatch("nsDelayedEventDispatcher", TaskCategory::Other, ded.forget());
   } else {
-    FireOrClearDelayedEvents(args.mDocs, false);
+    FireOrClearDelayedEvents(documents, false);
   }
 }
 
@@ -10044,8 +10000,7 @@ nsIDocument::ScheduleFrameRequestCallback(FrameRequestCallback& aCallback,
   DebugOnly request =
     mFrameRequestCallbacks.AppendElement(FrameRequest(aCallback, newHandle));
   NS_ASSERTION(request, "This is supposed to be infallible!");
-  if (!alreadyRegistered && mPresShell && IsEventHandlingEnabled() &&
-      !AnimationsPaused()) {
+  if (!alreadyRegistered && mPresShell && IsEventHandlingEnabled()) {
     mPresShell->GetPresContext()->RefreshDriver()->
       ScheduleFrameRequestCallbacks(this);
   }
@@ -10060,7 +10015,7 @@ nsIDocument::CancelFrameRequestCallback(int32_t aHandle)
   // mFrameRequestCallbacks is stored sorted by handle
   if (mFrameRequestCallbacks.RemoveElementSorted(aHandle) &&
       mFrameRequestCallbacks.IsEmpty() &&
-      mPresShell && IsEventHandlingEnabled() && !AnimationsPaused()) {
+      mPresShell && IsEventHandlingEnabled()) {
     mPresShell->GetPresContext()->RefreshDriver()->
       RevokeFrameRequestCallbacks(this);
   }
diff --git a/dom/base/nsDocument.h b/dom/base/nsDocument.h
index 41c4b37c3ea3..5272e9616b2d 100644
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -907,11 +907,9 @@ public:
   virtual mozilla::PendingAnimationTracker*
   GetOrCreatePendingAnimationTracker() override;
 
-  virtual void SuppressEventHandling(SuppressionType aWhat,
-                                     uint32_t aIncrease) override;
+  virtual void SuppressEventHandling(uint32_t aIncrease) override;
 
-  virtual void UnsuppressEventHandlingAndFireEvents(SuppressionType aWhat,
-                                                    bool aFireEvents) override;
+  virtual void UnsuppressEventHandlingAndFireEvents(bool aFireEvents) override;
 
   void DecreaseEventSuppression() {
     MOZ_ASSERT(mEventsSuppressed);
@@ -919,12 +917,6 @@ public:
     MaybeRescheduleAnimationFrameNotifications();
   }
 
-  void ResumeAnimations() {
-    MOZ_ASSERT(mAnimationsPaused);
-    --mAnimationsPaused;
-    MaybeRescheduleAnimationFrameNotifications();
-  }
-
   virtual nsIDocument* GetTemplateContentsOwner() override;
 
   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsDocument,
diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp
index 9525b2c6aaef..5f867545f177 100644
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -2004,11 +2004,8 @@ nsGlobalWindow::FreeInnerObjects()
     mDocBaseURI = mDoc->GetDocBaseURI();
 
     while (mDoc->EventHandlingSuppressed()) {
-      mDoc->UnsuppressEventHandlingAndFireEvents(nsIDocument::eEvents, false);
+      mDoc->UnsuppressEventHandlingAndFireEvents(false);
     }
-
-    // Note: we don't have to worry about eAnimationsOnly suppressions because
-    // they won't leak.
   }
 
   // Remove our reference to the document and the document principal.
@@ -9266,7 +9263,7 @@ nsGlobalWindow::EnterModalState()
 
     topWin->mSuspendedDoc = topDoc;
     if (topDoc) {
-      topDoc->SuppressEventHandling(nsIDocument::eEvents);
+      topDoc->SuppressEventHandling();
     }
 
     nsGlobalWindow* inner = topWin->GetCurrentInnerWindowInternal();
@@ -9303,8 +9300,7 @@ nsGlobalWindow::LeaveModalState()
 
     if (topWin->mSuspendedDoc) {
       nsCOMPtr currentDoc = topWin->GetExtantDoc();
-      topWin->mSuspendedDoc->UnsuppressEventHandlingAndFireEvents(nsIDocument::eEvents,
-                                                                  currentDoc == topWin->mSuspendedDoc);
+      topWin->mSuspendedDoc->UnsuppressEventHandlingAndFireEvents(currentDoc == topWin->mSuspendedDoc);
       topWin->mSuspendedDoc = nullptr;
     }
   }
diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h
index 62386ef2332b..6bd5d2259576 100644
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -2158,31 +2158,20 @@ public:
   virtual mozilla::PendingAnimationTracker*
   GetOrCreatePendingAnimationTracker() = 0;
 
-  enum SuppressionType {
-    eAnimationsOnly = 0x1,
-
-    // Note that suppressing events also suppresses animation frames, so
-    // there's no need to split out events in its own bitmask.
-    eEvents = 0x3,
-  };
-
   /**
    * Prevents user initiated events from being dispatched to the document and
    * subdocuments.
    */
-  virtual void SuppressEventHandling(SuppressionType aWhat,
-                                     uint32_t aIncrease = 1) = 0;
+  virtual void SuppressEventHandling(uint32_t aIncrease = 1) = 0;
 
   /**
    * Unsuppress event handling.
    * @param aFireEvents If true, delayed events (focus/blur) will be fired
    *                    asynchronously.
    */
-  virtual void UnsuppressEventHandlingAndFireEvents(SuppressionType aWhat,
-                                                    bool aFireEvents) = 0;
+  virtual void UnsuppressEventHandlingAndFireEvents(bool aFireEvents) = 0;
 
   uint32_t EventHandlingSuppressed() const { return mEventsSuppressed; }
-  uint32_t AnimationsPaused() const { return mAnimationsPaused; }
 
   bool IsEventHandlingEnabled() {
     return !EventHandlingSuppressed() && mScriptGlobalObject;
@@ -3282,8 +3271,6 @@ protected:
 
   uint32_t mEventsSuppressed;
 
-  uint32_t mAnimationsPaused;
-
   /**
    * The number number of external scripts (ones with the src attribute) that
    * have this document as their owner and that are being evaluated right now.
diff --git a/dom/bindings/BindingUtils.cpp b/dom/bindings/BindingUtils.cpp
index 6a817adaa24d..6e9b4b54eaf2 100644
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -2787,7 +2787,7 @@ HandlePrerenderingViolation(nsPIDOMWindowInner* aWindow)
   // Suspend event handling on the document
   nsCOMPtr doc = aWindow->GetExtantDoc();
   if (doc) {
-    doc->SuppressEventHandling(nsIDocument::eEvents);
+    doc->SuppressEventHandling();
   }
 }
 
diff --git a/dom/xhr/XMLHttpRequestMainThread.cpp b/dom/xhr/XMLHttpRequestMainThread.cpp
index 2de2d0753f85..499b57c719fc 100644
--- a/dom/xhr/XMLHttpRequestMainThread.cpp
+++ b/dom/xhr/XMLHttpRequestMainThread.cpp
@@ -2828,8 +2828,7 @@ XMLHttpRequestMainThread::UnsuppressEventHandlingAndResume()
   MOZ_ASSERT(mFlagSynchronous);
 
   if (mSuspendedDoc) {
-    mSuspendedDoc->UnsuppressEventHandlingAndFireEvents(nsIDocument::eEvents,
-                                                         true);
+    mSuspendedDoc->UnsuppressEventHandlingAndFireEvents(true);
     mSuspendedDoc = nullptr;
   }
 
@@ -2963,7 +2962,7 @@ XMLHttpRequestMainThread::SendInternal(const BodyExtractorBase* aBody)
         if (nsCOMPtr topInner = topWindow->GetCurrentInnerWindow()) {
           mSuspendedDoc = topWindow->GetExtantDoc();
           if (mSuspendedDoc) {
-            mSuspendedDoc->SuppressEventHandling(nsIDocument::eEvents);
+            mSuspendedDoc->SuppressEventHandling();
           }
           topInner->Suspend();
           mResumeTimeoutRunnable = new nsResumeTimeoutsEvent(topInner);
diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp
index 1302f3ddb241..127076ea4b8a 100644
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -626,8 +626,7 @@ nsDocumentViewer::SyncParentSubDocMap()
   if (mDocument &&
       parent_doc->GetSubDocumentFor(element) != mDocument &&
       parent_doc->EventHandlingSuppressed()) {
-    mDocument->SuppressEventHandling(nsIDocument::eEvents,
-                                     parent_doc->EventHandlingSuppressed());
+    mDocument->SuppressEventHandling(parent_doc->EventHandlingSuppressed());
   }
   return parent_doc->SetSubDocumentFor(element, mDocument);
 }

From 51562641fcc025794b27bdec179f4a83e8dfbe2e Mon Sep 17 00:00:00 2001
From: Jean-Yves Avenard 
Date: Tue, 21 Feb 2017 15:54:50 +0100
Subject: [PATCH 149/234] Bug 1325707: Follow-up, fix invalid unsigned
 comparison. r=gerald

MozReview-Commit-ID: 26bxAyhxbsx
---
 dom/media/platforms/agnostic/OpusDecoder.cpp | 34 +++++++++++++-------
 1 file changed, 22 insertions(+), 12 deletions(-)

diff --git a/dom/media/platforms/agnostic/OpusDecoder.cpp b/dom/media/platforms/agnostic/OpusDecoder.cpp
index 35f995653ac2..8399cbac6261 100644
--- a/dom/media/platforms/agnostic/OpusDecoder.cpp
+++ b/dom/media/platforms/agnostic/OpusDecoder.cpp
@@ -174,10 +174,10 @@ OpusDataDecoder::ProcessDecode(MediaRawData* aSample)
   }
 
   // Maximum value is 63*2880, so there's no chance of overflow.
-  uint32_t frames_number = opus_packet_get_nb_frames(aSample->Data(),
-                                                    aSample->Size());
+  int frames_number =
+    opus_packet_get_nb_frames(aSample->Data(), aSample->Size());
   if (frames_number <= 0) {
-    OPUS_DEBUG("Invalid packet header: r=%" PRIu32 " length=%" PRIuSIZE, frames_number,
+    OPUS_DEBUG("Invalid packet header: r=%d length=%" PRIuSIZE, frames_number,
                aSample->Size());
     return DecodePromise::CreateAndReject(
       MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
@@ -186,16 +186,25 @@ OpusDataDecoder::ProcessDecode(MediaRawData* aSample)
       __func__);
   }
 
-  uint32_t samples = opus_packet_get_samples_per_frame(
+  int samples = opus_packet_get_samples_per_frame(
     aSample->Data(), opus_int32(mOpusParser->mRate));
 
   // A valid Opus packet must be between 2.5 and 120 ms long (48kHz).
-  uint32_t frames = frames_number*samples;
-  if (frames < 120 || frames > 5760) {
-    OPUS_DEBUG("Invalid packet frames: %u", frames);
+  CheckedInt32 totalFrames =
+    CheckedInt32(frames_number) * CheckedInt32(samples);
+  if (!totalFrames.isValid()) {
     return DecodePromise::CreateAndReject(
       MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
-                  RESULT_DETAIL("Invalid packet frames:%u", frames)),
+                  RESULT_DETAIL("Frames count overflow")),
+      __func__);
+  }
+
+  int frames = totalFrames.value();
+  if (frames < 120 || frames > 5760) {
+    OPUS_DEBUG("Invalid packet frames: %d", frames);
+    return DecodePromise::CreateAndReject(
+      MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
+                  RESULT_DETAIL("Invalid packet frames:%d", frames)),
       __func__);
   }
 
@@ -221,14 +230,15 @@ OpusDataDecoder::ProcessDecode(MediaRawData* aSample)
                   RESULT_DETAIL("Opus decoding error:%d", ret)),
       __func__);
   }
-  NS_ASSERTION(uint32_t(ret) == frames, "Opus decoded too few audio samples");
+  NS_ASSERTION(ret == frames, "Opus decoded too few audio samples");
   CheckedInt64 startTime = aSample->mTime;
 
   // Trim the initial frames while the decoder is settling.
   if (mSkip > 0) {
     int32_t skipFrames = std::min(mSkip, frames);
     int32_t keepFrames = frames - skipFrames;
-    OPUS_DEBUG("Opus decoder skipping %d of %d frames", skipFrames, frames);
+    OPUS_DEBUG(
+      "Opus decoder skipping %d of %d frames", skipFrames, frames);
     PodMove(buffer.get(),
             buffer.get() + skipFrames * channels,
             keepFrames * channels);
@@ -238,12 +248,12 @@ OpusDataDecoder::ProcessDecode(MediaRawData* aSample)
   }
 
   if (aSample->mDiscardPadding > 0) {
-    OPUS_DEBUG("Opus decoder discarding %u of %u frames",
+    OPUS_DEBUG("Opus decoder discarding %u of %d frames",
                aSample->mDiscardPadding, frames);
     // Padding discard is only supposed to happen on the final packet.
     // Record the discard so we can return an error if another packet is
     // decoded.
-    if (aSample->mDiscardPadding > frames) {
+    if (aSample->mDiscardPadding > uint32_t(frames)) {
       // Discarding more than the entire packet is invalid.
       OPUS_DEBUG("Opus error, discard padding larger than packet");
       return DecodePromise::CreateAndReject(

From 5de1d8e8823b13a5e24ff68889b35c388eaf355d Mon Sep 17 00:00:00 2001
From: Jean-Yves Avenard 
Date: Mon, 20 Feb 2017 18:30:42 +0100
Subject: [PATCH 150/234] Bug 1322739: P1. Fix style and headers. r=gerald

MozReview-Commit-ID: L24Q7fX06Z0
---
 dom/media/gmp/GMPCrashHelper.h              |  3 +-
 dom/media/platforms/PlatformDecoderModule.h | 36 ++++++++++-----------
 2 files changed, 19 insertions(+), 20 deletions(-)

diff --git a/dom/media/gmp/GMPCrashHelper.h b/dom/media/gmp/GMPCrashHelper.h
index db5b392c65ff..c6d07deeac02 100644
--- a/dom/media/gmp/GMPCrashHelper.h
+++ b/dom/media/gmp/GMPCrashHelper.h
@@ -7,8 +7,9 @@
 #if !defined(GMPCrashHelper_h_)
 #define GMPCrashHelper_h_
 
-#include "nsPIDOMWindow.h"
+#include "MainThreadUtils.h"
 #include "nsISupportsImpl.h"
+#include "nsPIDOMWindow.h"
 
 namespace mozilla {
 
diff --git a/dom/media/platforms/PlatformDecoderModule.h b/dom/media/platforms/PlatformDecoderModule.h
index 5d1dbb0ebe89..89b52d3d0a38 100644
--- a/dom/media/platforms/PlatformDecoderModule.h
+++ b/dom/media/platforms/PlatformDecoderModule.h
@@ -7,16 +7,16 @@
 #if !defined(PlatformDecoderModule_h_)
 #define PlatformDecoderModule_h_
 
+#include "GMPCrashHelper.h"
 #include "MediaDecoderReader.h"
 #include "MediaInfo.h"
-#include "mozilla/MozPromise.h"
-#include "mozilla/layers/LayersTypes.h"
-#include "mozilla/layers/KnowsCompositor.h"
-#include "nsTArray.h"
-#include "mozilla/RefPtr.h"
-#include "GMPCrashHelper.h"
-#include 
 #include "MediaResult.h"
+#include "mozilla/MozPromise.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/layers/KnowsCompositor.h"
+#include "mozilla/layers/LayersTypes.h"
+#include "nsTArray.h"
+#include 
 
 namespace mozilla {
 class TrackInfo;
@@ -41,10 +41,7 @@ static LazyLogModule sPDMLog("PlatformDecoderModule");
 
 struct MOZ_STACK_CLASS CreateDecoderParams final
 {
-  explicit CreateDecoderParams(const TrackInfo& aConfig)
-    : mConfig(aConfig)
-  {
-  }
+  explicit CreateDecoderParams(const TrackInfo& aConfig) : mConfig(aConfig) { }
 
   template 
   CreateDecoderParams(const TrackInfo& aConfig, T1&& a1, Ts&&... args)
@@ -138,14 +135,15 @@ public:
 
   // Perform any per-instance initialization.
   // This is called on the decode task queue.
-  virtual nsresult Startup() { return NS_OK; };
+  virtual nsresult Startup() { return NS_OK; }
 
   // Indicates if the PlatformDecoderModule supports decoding of aMimeType.
-  virtual bool SupportsMimeType(
-    const nsACString& aMimeType,
-    DecoderDoctorDiagnostics* aDiagnostics) const = 0;
-  virtual bool Supports(const TrackInfo& aTrackInfo,
-                        DecoderDoctorDiagnostics* aDiagnostics) const
+  virtual bool
+  SupportsMimeType(const nsACString& aMimeType,
+                   DecoderDoctorDiagnostics* aDiagnostics) const = 0;
+  virtual bool
+  Supports(const TrackInfo& aTrackInfo,
+           DecoderDoctorDiagnostics* aDiagnostics) const
   {
     // By default, fall back to SupportsMimeType with just the MIME string.
     // (So PDMs do not need to override this method -- yet.)
@@ -207,7 +205,7 @@ protected:
 class MediaDataDecoder
 {
 protected:
-  virtual ~MediaDataDecoder() {};
+  virtual ~MediaDataDecoder() { }
 
 public:
   typedef TrackInfo::TrackType TrackType;
@@ -281,7 +279,7 @@ public:
   // Decoder may not honor this value. However, it'd be better that
   // video decoder implements this API to improve seek performance.
   // Note: it should be called before Input() or after Flush().
-  virtual void SetSeekThreshold(const media::TimeUnit& aTime) {}
+  virtual void SetSeekThreshold(const media::TimeUnit& aTime) { }
 
   // When playing adaptive playback, recreating an Android video decoder will
   // cause the transition not smooth during resolution change.

From 499848c9a750ae22077368181c3fde445e8132df Mon Sep 17 00:00:00 2001
From: Jean-Yves Avenard 
Date: Mon, 20 Feb 2017 19:22:45 +0100
Subject: [PATCH 151/234] Bug 1322739: P2. Add Low Latency option to
 CreateDecoderParams. r=gerald

MozReview-Commit-ID: KcTGGUK7aq5
---
 dom/media/platforms/PlatformDecoderModule.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/dom/media/platforms/PlatformDecoderModule.h b/dom/media/platforms/PlatformDecoderModule.h
index 89b52d3d0a38..6efa78213cce 100644
--- a/dom/media/platforms/PlatformDecoderModule.h
+++ b/dom/media/platforms/PlatformDecoderModule.h
@@ -11,6 +11,7 @@
 #include "MediaDecoderReader.h"
 #include "MediaInfo.h"
 #include "MediaResult.h"
+#include "mozilla/EnumSet.h"
 #include "mozilla/MozPromise.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/layers/KnowsCompositor.h"
@@ -43,6 +44,13 @@ struct MOZ_STACK_CLASS CreateDecoderParams final
 {
   explicit CreateDecoderParams(const TrackInfo& aConfig) : mConfig(aConfig) { }
 
+  enum class Option
+  {
+    Default,
+    LowLatency,
+  };
+  using OptionSet = EnumSet