Bug 1292275 - Stylo: Fix crash after failed stylesheet load. r=heycam draft
authorMatt Brubeck <mbrubeck@mozilla.com>
Tue, 25 Oct 2016 10:15:38 -0700
changeset 435657 0b46c9f9327eec0bac3bb2ca697198887948e2e6
parent 435656 680094d957919bd757685e3de5fe244a5e038658
child 536341 0f32a3bbbd87b2b4f8041d132c1420467bb74c2f
push id35078
push usermbrubeck@mozilla.com
push dateTue, 08 Nov 2016 22:02:54 +0000
reviewersheycam
bugs1292275
milestone52.0a1
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
layout/style/Loader.cpp
layout/style/ServoBindingList.h
layout/style/ServoStyleSheet.cpp
layout/style/ServoStyleSheet.h
--- 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; }