Skip to content

fix ios line gradient crash and LineChart popup IOOBE#168

Open
NadeemIqbal wants to merge 2 commits into
ehsannarmani:masterfrom
NadeemIqbal:fix/ios-shader-and-empty-data-guards
Open

fix ios line gradient crash and LineChart popup IOOBE#168
NadeemIqbal wants to merge 2 commits into
ehsannarmani:masterfrom
NadeemIqbal:fix/ios-shader-and-empty-data-guards

Conversation

@NadeemIqbal
Copy link
Copy Markdown

Two independent fixes in LineChart, kept as separate commits so they can be reviewed and reverted independently.

1. iOS ClassCastException in drawLineGradient on CMP 1.11.0 (closes #167)

Gradient.kt was using the low-level Skia interop path: Paint().shader = LinearGradientShader(...) inside drawIntoCanvas { it.drawPath(p, paint) }. In CMP <= 1.10 the iOS native bridge happened to unwrap this, but CMP 1.11.0 changed the internal Shader representation, so the runtime downcast in the iOS paint.shader setter fails:

kotlin.ClassCastException: class androidx.compose.ui.graphics.Shader
  cannot be cast to class org.jetbrains.skia.Shader
  at kfun:...drawLineGradient + 1995

Fix: use the public, multiplatform-safe DrawScope.drawPath(path, brush) with Brush.verticalGradient. The original gradient was strictly vertical (Offset(0f, 0f) to Offset(0f, _size.height)), so the swap is 1:1 and removes the drawIntoCanvas escape hatch entirely. Function signature is unchanged, both call sites in LineChart.kt keep compiling.

2. LineChart.showPopup IOOBE on empty / stale line data (closes #146, closes #158)

showPopup read linesPathData[dataIndex] and xPositions[startIndex] without guarding against three cases:

  1. A Line whose values list is empty produces empty xPositions; the index access throws IndexOutOfBoundsException.
  2. LaunchedEffect(data, minValue, computedMaxValue) { linesPathData.clear() } empties the state list whenever data updates, but a pointer event mid-update still tries to read linesPathData[dataIndex], surfacing as SnapshotStateList.get IOOBE on the gesture thread. This is exactly the stack in 🐛 LineChart crash in showPopup (IndexOutOfBoundsException) even when caller guards empty data #158.
  3. xPositions empty even when pathData is present.

Three early-return guards added before the index access. Each fails this iteration only, so a malformed line does not poison a sibling line.

Local build verification

./gradlew :compose-charts:compileKotlinIosArm64 \
          :compose-charts:compileKotlinIosSimulatorArm64 \
          :compose-charts:compileKotlinIosX64 \
          :compose-charts:compileKotlinDesktop
BUILD SUCCESSFUL

No new warnings introduced.

CMP 1.11.0 changed the iOS Shader representation, so the legacy path
`Paint().shader = LinearGradientShader(...)` plus drawIntoCanvas crashes
at runtime with:

  ClassCastException: class androidx.compose.ui.graphics.Shader cannot be
  cast to class org.jetbrains.skia.Shader

inside drawLineGradient. Switch to the public Compose API,
drawPath(brush = Brush.verticalGradient(...)), which works on every
target and avoids the raw shader downcast. The gradient was already
strictly vertical (Offset(0f, 0f) to Offset(0f, height)), so the swap is
1:1. Function signature unchanged.

Closes ehsannarmani#167
showPopup read linesPathData[dataIndex] and xPositions[startIndex]
without guarding against three cases:

  1. A Line whose `values` list is empty produces empty xPositions; the
     index access throws IndexOutOfBoundsException.
  2. LaunchedEffect(data, ...) { linesPathData.clear() } empties the
     state list whenever data updates, but a pointer event mid-update
     still tries to read linesPathData[dataIndex], surfacing as
     SnapshotStateList.get IOOBE on the gesture thread.
  3. xPositions empty even when pathData is present.

Add three early-return guards before the index access. Each fails this
iteration only, so a malformed line does not poison a sibling line.

Closes ehsannarmani#146
Closes ehsannarmani#158
@TheNephilim88
Copy link
Copy Markdown

@ehsannarmani please review and merge, so the lib can be used with latest compose multiplatform versions

@ehsannarmani
Copy link
Copy Markdown
Owner

Hi guys.
Thank you for contributing @NadeemIqbal
Sorry, currently i have no time to review, but i will do it ASAP.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants