Add a "path_fuzz" mode to the PLS fuzzer

Merge all fuzzers into a single application named "fuzz". Add another fuzzer that generates random paths. Fix some bugs it found.

Diffs=
1d0d2b6ac Add a "path_fuzz" mode to the PLS fuzzer (#7211)

Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com>
diff --git a/.rive_head b/.rive_head
index cb09d2a..2b396c2 100644
--- a/.rive_head
+++ b/.rive_head
@@ -1 +1 @@
-0d03a416b584cdd95aa4b496df105c14cdd2c05c
+1d0d2b6acd58a8541bf0fa01a9ac0b5bb761e65a
diff --git a/src/math/mat2d.cpp b/src/math/mat2d.cpp
index d88edbf..0980c8f 100644
--- a/src/math/mat2d.cpp
+++ b/src/math/mat2d.cpp
@@ -135,9 +135,11 @@
     }
 
     float4 bbox = simd::join(simd::min(mins.xy, mins.zw), simd::max(maxes.xy, maxes.zw));
-    if (!simd::all(bbox.xy <= bbox.zw))
+    // Use logic that takes the "nonfinite" branch when bbox has NaN values.
+    // Use "b - a >= 0" instead of "a >= b" because it fails when b == a == inf.
+    if (!simd::all(bbox.zw - bbox.xy >= 0))
     {
-        // The given points were NaN or empty.
+        // The given points were NaN or empty, or infinite.
         bbox = float4(0);
     }
     else
@@ -146,7 +148,10 @@
         bbox += trans;
     }
 
-    return math::bit_cast<AABB>(bbox);
+    auto aabb = math::bit_cast<AABB>(bbox);
+    assert(aabb.width() >= 0);
+    assert(aabb.height() >= 0);
+    return aabb;
 }
 
 AABB Mat2D::mapBoundingBox(const AABB& aabb) const
diff --git a/test/mat2d_test.cpp b/test/mat2d_test.cpp
index af1c559..cc80713 100644
--- a/test/mat2d_test.cpp
+++ b/test/mat2d_test.cpp
@@ -245,5 +245,14 @@
     CHECK(Mat2D().mapBoundingBox(AABB{-1, nan, 1, 1}) == AABB{-1, 1, 1, 1});
     CHECK(Mat2D().mapBoundingBox(AABB{-1, -1, nan, 1}) == AABB{-1, -1, -1, 1});
     CHECK(Mat2D().mapBoundingBox(AABB{-1, -1, 1, nan}) == AABB{-1, -1, 1, -1});
+
+    // When AABB::height() inf - inf, the result is nan.
+    auto inf = std::numeric_limits<float>::infinity();
+    CHECK(Mat2D().mapBoundingBox(AABB{0, inf, 0, nan}).height() == 0);
+    CHECK(Mat2D().mapBoundingBox(AABB{0, -inf, 0, nan}).height() == 0);
+    CHECK(Mat2D().mapBoundingBox(AABB{inf, 0, nan, 0}).width() == 0);
+    CHECK(Mat2D().mapBoundingBox(AABB{-inf, 0, nan, 0}).width() == 0);
+    CHECK(Mat2D().mapBoundingBox(AABB{inf, 0, inf, 0}).width() == 0);
+    CHECK(Mat2D().mapBoundingBox(AABB{0, -inf, 0, -inf}).height() == 0);
 }
 } // namespace rive