Fix crash when skinnable isn’t found.

Fixes https://github.com/rive-app/rive/issues/7317

Diffs=
876a2dca5 Fix crash when skinnable isn’t found. (#7554)

Co-authored-by: Luigi Rosso <luigi-rosso@users.noreply.github.com>
diff --git a/.rive_head b/.rive_head
index 026d8df..f234bbf 100644
--- a/.rive_head
+++ b/.rive_head
@@ -1 +1 @@
-8fbe13788fa0bd1050ce0b044beb210e1b14ab6a
+876a2dca5228aa6a27e934c3e0f430853a157931
diff --git a/src/bones/skin.cpp b/src/bones/skin.cpp
index 33a27c6..2041876 100644
--- a/src/bones/skin.cpp
+++ b/src/bones/skin.cpp
@@ -85,4 +85,10 @@
 }
 void Skin::addTendon(Tendon* tendon) { m_Tendons.push_back(tendon); }
 
-void Skin::onDirty(ComponentDirt dirt) { m_Skinnable->markSkinDirty(); }
+void Skin::onDirty(ComponentDirt dirt)
+{
+    if (m_Skinnable != nullptr)
+    {
+        m_Skinnable->markSkinDirty();
+    }
+}
diff --git a/test/assets/bad_skin.riv b/test/assets/bad_skin.riv
new file mode 100644
index 0000000..e5ba5d5
--- /dev/null
+++ b/test/assets/bad_skin.riv
Binary files differ
diff --git a/test/file_test.cpp b/test/file_test.cpp
index 03ca35c..69ec042 100644
--- a/test/file_test.cpp
+++ b/test/file_test.cpp
@@ -1,8 +1,10 @@
-#include <rive/file.hpp>
-#include <rive/node.hpp>
-#include <rive/shapes/rectangle.hpp>
-#include <rive/shapes/shape.hpp>
-#include <rive/assets/image_asset.hpp>
+#include "rive/file.hpp"
+#include "rive/node.hpp"
+#include "rive/shapes/rectangle.hpp"
+#include "rive/shapes/shape.hpp"
+#include "rive/assets/image_asset.hpp"
+#include "rive/shapes/points_path.hpp"
+#include "rive/shapes/mesh.hpp"
 #include "utils/no_op_renderer.hpp"
 #include "rive_file_reader.hpp"
 #include <catch.hpp>
@@ -193,6 +195,35 @@
     }
 }
 
+TEST_CASE("file a bad skin (no parent skinnable) doesn't crash", "[file]")
+{
+    FILE* fp = fopen("../../test/assets/bad_skin.riv", "rb");
+    REQUIRE(fp != nullptr);
+
+    fseek(fp, 0, SEEK_END);
+    const size_t length = ftell(fp);
+    fseek(fp, 0, SEEK_SET);
+    std::vector<uint8_t> bytes(length);
+    REQUIRE(fread(bytes.data(), 1, length, fp) == length);
+    fclose(fp);
+
+    rive::ImportResult result;
+    auto file = rive::File::import(bytes, &gNoOpFactory, &result);
+    REQUIRE(result == rive::ImportResult::success);
+    REQUIRE(file.get() != nullptr);
+    REQUIRE(file->artboard() != nullptr);
+
+    REQUIRE(file->artboard()->name() == "Illustration WOman.svg");
+    auto artboard = file->artboardDefault();
+    artboard->updateComponents();
+    auto paths = artboard->find<rive::PointsPath>();
+    for (auto path : paths)
+    {
+        path->markPathDirty();
+    }
+    artboard->updateComponents();
+}
+
 // TODO:
 // ShapePaint (fill/stroke) needs to be implemented in WASM (jsFill/jsStroke) in
 // order to create Paint objects as necessary.