Skip to content

Commit 8143e0f

Browse files
authored
fix: Android crash on empty CSS strokeDasharray from the default keyframe endpoint (#9845)
## Summary Animating `strokeDasharray` with an implicit default keyframe endpoint ships an empty array to react-native-svg (the default `SVGStrokeDashArray()` serializes to `[]`), which crashes Android's `DashPathEffect` - it requires at least 2 intervals. #9719 does not cover this case because 0 is an even length. Per CSS, the initial `stroke-dasharray` is `none` (a solid stroke), so serialize the empty array as `null`, which react-native-svg renders as a solid stroke. ## Test plan Open the CSS app > Animated Properties > SVG > Stroke on Android. Before: a release build crashes within seconds of opening the screen. After: all examples render correctly and survive restart + scroll soaks. Recordings below.
1 parent 284b983 commit 8143e0f

2 files changed

Lines changed: 11 additions & 0 deletions

File tree

packages/react-native-reanimated/Common/cpp/reanimated/CSS/svg/values/SVGStrokeDashArray.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,15 @@ SVGStrokeDashArray SVGStrokeDashArray::interpolate(
3838
return SVGStrokeDashArray(result);
3939
}
4040

41+
folly::dynamic SVGStrokeDashArray::toDynamic() const {
42+
// Empty means "no dashing" - emit null instead of [], which react-native-svg
43+
// would feed to Android's DashPathEffect that requires at least 2 intervals.
44+
if (values.empty()) {
45+
return nullptr;
46+
}
47+
return CSSLengthVector::toDynamic();
48+
}
49+
4150
#ifndef NDEBUG
4251

4352
std::ostream &operator<<(std::ostream &os, const SVGStrokeDashArray &strokeDashArray) {

packages/react-native-reanimated/Common/cpp/reanimated/CSS/svg/values/SVGStrokeDashArray.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ struct SVGStrokeDashArray : public CSSLengthVector<SVGStrokeDashArray> {
1212
const SVGStrokeDashArray &to,
1313
const ResolvableValueInterpolationContext &context) const override;
1414

15+
folly::dynamic toDynamic() const override;
16+
1517
#ifndef NDEBUG
1618
friend std::ostream &operator<<(std::ostream &os, const SVGStrokeDashArray &strokeDashArray);
1719
#endif // NDEBUG

0 commit comments

Comments
 (0)