Decompose accounts for 0 scale, adds test.

Fixes an issue JC and I caught with a distance constraint causing a crash. Logic now mimics Dart one where scaleY will be 0 if the scaleX is 0 (which makes sense).

Diffs=
b90ac530a Decompose accounts for 0 scale, adds test. (#4975)
diff --git a/.rive_head b/.rive_head
index 1f1cfee..6c2564f 100644
--- a/.rive_head
+++ b/.rive_head
@@ -1 +1 @@
-2504d2ab24d258621fc89a0120c794f2b53a2ffc
+b90ac530ad934458cfa49acc93622ee9a541b635
diff --git a/src/math/mat2d.cpp b/src/math/mat2d.cpp
index b339837..5dab962 100644
--- a/src/math/mat2d.cpp
+++ b/src/math/mat2d.cpp
@@ -117,7 +117,7 @@
     float rotation = (float)std::atan2(m1, m0);
     float denom = m0 * m0 + m1 * m1;
     float scaleX = (float)std::sqrt(denom);
-    float scaleY = (m0 * m3 - m2 * m1) / scaleX;
+    float scaleY = scaleX == 0.0f ? 0.0f : (m0 * m3 - m2 * m1) / scaleX;
     float skewX = (float)std::atan2(m0 * m2 + m1 * m3, denom);
 
     TransformComponents result;
diff --git a/test/assets/zombie_skins.riv b/test/assets/zombie_skins.riv
new file mode 100644
index 0000000..ea9c8e2
--- /dev/null
+++ b/test/assets/zombie_skins.riv
Binary files differ
diff --git a/test/contour_measure_test.cpp b/test/contour_measure_test.cpp
index abf0635..e42f760 100644
--- a/test/contour_measure_test.cpp
+++ b/test/contour_measure_test.cpp
@@ -7,6 +7,9 @@
 #include <rive/math/raw_path.hpp>
 #include <rive/math/vec2d.hpp>
 
+#include "rive_file_reader.hpp"
+#include "rive/animation/state_machine_instance.hpp"
+
 #include <catch.hpp>
 #include <cstdio>
 
@@ -139,3 +142,13 @@
     REQUIRE(nearly_eq(cm->length(), 2 * r * math::PI, tol));
     REQUIRE(!iter.next());
 }
+
+TEST_CASE("bad contour", "[contourmeasure]")
+{
+    auto file = ReadRiveFile("../../test/assets/zombie_skins.riv");
+
+    auto artboard = file->artboard()->instance();
+    REQUIRE(artboard != nullptr);
+    auto machine = artboard->defaultStateMachine();
+    machine->advanceAndApply(0.0f);
+}