Bug 1292275 - Stylo: Fix crash after failed stylesheet load. r=heycam
authorMatt Brubeck <mbrubeck@mozilla.com>
Tue, 25 Oct 2016 10:15:38 -0700
changeset 351875 069a6200844132e8e517940e45cd9528263a2e46
parent 351874 a66aa3e7dd91cd9f3c3333bc186bc177a0c05cf5
child 351876 0da5a6f77ffb2e1c4629cc0290b05be6bedd773e
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-esr52@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
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; }