[Android] Crash: java.lang.IllegalArgumentException in LinearGradient.nativeCreate due to invalid gradient parameters - React-Native Crash #2762
Shashank1702
started this conversation in
General
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
The application crashes on Android when attempting to render an SVG that contains a LinearGradient with invalid parameters (e.g., zero-length or mismatched stops/colors). This leads to an unhandled java.lang.IllegalArgumentException originating from the native Android graphics engine.
Stack Trace:
Java
java.lang.IllegalArgumentException
at android.graphics.LinearGradient.nativeCreate(Native Method)
at android.graphics.LinearGradient.createNativeInstance(LinearGradient.java:170)
at android.graphics.Shader.getNativeInstance(Shader.java:196)
at android.graphics.Paint.getNativeInstance(Paint.java:826)
at android.graphics.BaseCanvas.drawPath(BaseCanvas.java:519)
at android.graphics.Canvas.drawPath(Canvas.java:1939)
at com.horcrux.svg.RenderableView.draw(Unknown Source:105)
at com.horcrux.svg.RenderableView.render(Unknown Source:43)
at com.horcrux.svg.GroupView.b(Unknown Source:151)
at com.horcrux.svg.GroupView.draw(Unknown Source:6)
I propose a two-part solution to fix the root cause and add defensive programming to prevent future crashes.
Add a safeguard in Brush.java before the LinearGradient is created. This will validate the parameters, log a warning, and fall back gracefully instead of crashing.
File: android/src/main/java/com/horcrux/svg/Brush.java
Java
// SAFEGUARD STARTS HERE
boolean isZeroLength = ((float) x1 == (float) x2) && ((float) y1 == (float) y2);
boolean invalidStops = stopsColors == null || stopsColors.length < 2;
boolean mismatchStops = stops.length != stopsColors.length;
if (isZeroLength || invalidStops || mismatchStops) {
FLog.w(
ReactConstants.TAG,
"Invalid LinearGradient skipped (zero-length or invalid stops). " +
"x1=" + x1 + ", y1=" + y1 + ", x2=" + x2 + ", y2=" + y2 +
", stops=" + stops.length + ", stopsColors=" + (stopsColors != null ? stopsColors.length : "null")
);
paint.setShader(null); // fallback to no shader
return;
}
// SAFEGUARD ENDS HERE
// Original code to create LinearGradient follows...
LinearGradient linearGradient = new LinearGradient(
(float) x1,
(float) y1,
(float) x2,
(float) y2,
stopsColors,
stops,
mTileMode);
2. Add Defensive try-catch in RenderableView.java (Safety Net)
To make the rendering pipeline more robust, wrap the canvas.drawPath calls in RenderableView.java with try-catch blocks. This will prevent crashes even if other unexpected drawing-related exceptions occur.
File: android/src/main/java/com/horcrux/svg/RenderableView.java
Java
// In void draw(Canvas canvas, Paint paint, float opacity) method:
// ... before fill logic ...
// added try catch block to prevent above crash
try {
if (setupFillPaint(paint, opacity * fillOpacity)) {
if (computePaths) {
mFillPath = new Path();
paint.getFillPath(path, mFillPath);
}
canvas.drawPath(path, paint);
}
} catch (IllegalArgumentException e) {
Log.e("ReactNativeSVG", "Crash in drawPath (fill): Invalid gradient parameters", e);
// Optionally fallback to solid color or skip drawing
} catch (Exception e) {
Log.e("ReactNativeSVG", "Unexpected error in drawPath (fill)", e);
}
// added try catch block to prevent above crash
try {
if (setupStrokePaint(paint, opacity * strokeOpacity)) {
if (computePaths) {
mStrokePath = new Path();
paint.getFillPath(path, mStrokePath);
}
canvas.drawPath(path, paint);
}
} catch (IllegalArgumentException e) {
Log.e("ReactNativeSVG", "Crash in drawPath (stroke): Invalid gradient parameters", e);
} catch (Exception e) {
Log.e("ReactNativeSVG", "Unexpected error in drawPath (stroke)", e);
}
// ... after stroke logic ..
Beta Was this translation helpful? Give feedback.
All reactions