Bug 1292275 - Stylo: Fix crash after failed stylesheet load. r=heycam
Fixes a crash ServoStyleSet::AddDocStyleSheet caused by
ServoStyleSheet::RawSheet returning null.
MozReview-Commit-ID: BdDosompqTv
--- a/layout/style/Loader.cpp
+++ b/layout/style/Loader.cpp
@@ -1810,16 +1810,20 @@ Loader::ParseSheet(const nsAString& aInp
* blocked parent loads as needed, and most importantly calls
* NS_RELEASE on the load data to destroy the whole mess.
*/
void
Loader::SheetComplete(SheetLoadData* aLoadData, nsresult aStatus)
{
LOG(("css::Loader::SheetComplete"));
+ if (aLoadData->mSheet->IsServo() && NS_FAILED(aStatus)) {
+ aLoadData->mSheet->AsServo()->LoadFailed();
+ }
+
// 8 is probably big enough for all our common cases. It's not likely that
// imports will nest more than 8 deep, and multiple sheets with the same URI
// are rare.
AutoTArray<RefPtr<SheetLoadData>, 8> datasToNotify;
DoSheetComplete(aLoadData, aStatus, datasToNotify);
// Now it's safe to go ahead and notify observers
uint32_t count = datasToNotify.Length();
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -17,16 +17,18 @@
* SERVO_BINDING_FUNC(name_, return_, ...)
* before including this file.
*/
// Node data
SERVO_BINDING_FUNC(Servo_Node_ClearNodeData, void, RawGeckoNodeBorrowed node)
// Styleset and Stylesheet management
+SERVO_BINDING_FUNC(Servo_StyleSheet_Empty, RawServoStyleSheetStrong,
+ mozilla::css::SheetParsingMode parsing_mode)
SERVO_BINDING_FUNC(Servo_StyleSheet_FromUTF8Bytes, RawServoStyleSheetStrong,
const nsACString* data,
mozilla::css::SheetParsingMode parsing_mode,
const nsACString* base_url,
ThreadSafeURIHolder* base,
ThreadSafeURIHolder* referrer,
ThreadSafePrincipalHolder* principal)
SERVO_BINDING_FUNC(Servo_StyleSheet_AddRef, void,
--- a/layout/style/ServoStyleSheet.cpp
+++ b/layout/style/ServoStyleSheet.cpp
@@ -77,16 +77,22 @@ ServoStyleSheet::ParseSheet(const nsAStr
NS_ConvertUTF16toUTF8 input(aInput);
mSheet = Servo_StyleSheet_FromUTF8Bytes(&input, mParsingMode, &baseString,
base, referrer, principal).Consume();
return NS_OK;
}
void
+ServoStyleSheet::LoadFailed()
+{
+ mSheet = Servo_StyleSheet_Empty(mParsingMode).Consume();
+}
+
+void
ServoStyleSheet::DropSheet()
{
mSheet = nullptr;
}
size_t
ServoStyleSheet::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{
--- a/layout/style/ServoStyleSheet.h
+++ b/layout/style/ServoStyleSheet.h
@@ -35,16 +35,23 @@ public:
void AppendStyleSheet(ServoStyleSheet* aSheet);
MOZ_MUST_USE nsresult ParseSheet(const nsAString& aInput,
nsIURI* aSheetURI,
nsIURI* aBaseURI,
nsIPrincipal* aSheetPrincipal,
uint32_t aLineNumber);
+ /**
+ * Called instead of ParseSheet to initialize the Servo stylesheet object
+ * for a failed load. Either ParseSheet or LoadFailed must be called before
+ * adding a ServoStyleSheet to a ServoStyleSet.
+ */
+ void LoadFailed();
+
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
#ifdef DEBUG
void List(FILE* aOut = stdout, int32_t aIndex = 0) const;
#endif
RawServoStyleSheet* RawSheet() const { return mSheet; }