ChartsOrg / Charts

Beautiful charts for iOS/tvOS/OSX! The Apple side of the crossplatform MPAndroidChart.
Apache License 2.0
27.62k stars 6k forks source link

[Crash] Renderers (isDrawingValuesAllowed func) crash - wrong data type cast causes host app to crash #5197

Open sorinmiroiu97 opened 2 months ago

sorinmiroiu97 commented 2 months ago

What did you do?

We integrated the latest version of this library, as of the current time I'm writing this (v5.1.0), into our project for displaying some charts. There's an unusual behaviour, but a valid one in the project, that causes the app to crash because of a data cast from Double.infinite to Integer, but the this cast fails as infinite cannot be cast into an Int, and this code resides within the library. The class in questions is BarLineScatterCandleBubbleRenderer and this is the place where it crashes: open func isDrawingValuesAllowed(dataProvider: ChartDataProvider?) -> Bool { guard let data = dataProvider?.data else { return false } return data.entryCount < Int(CGFloat(dataProvider?.maxVisibleCount ?? 0) * viewPortHandler.scaleX) }

What did you expect to happen?

I would've expected for this CGFloat to be checked against CGFloat.infinity and CGFloat.nan and to return with a false in these cases out of the isDrawingValuesAllowed function. Also I'd expect this check to be applied to all renderers as it can occur in the other files as well.

What happened instead?

The type cast fails and thus it crashes the host app.

DGCharts Environment

DGCharts version/Branch/Commit Number:5.1.0 Xcode version:Version 15.4 (15F31d) Swift version:5 Platform(s) running DGCharts:iOS *macOS version running Xcode:14.5 (23F79)*

Demo Project

I'm not adding a demo project as I'm submitting a pull request so i need this ticket created in order to link the PR to this issue.

sorinmiroiu97 commented 2 months ago

I opened up a PR for this issue here: https://github.com/ChartsOrg/Charts/pull/5198 Thank you :D

ffchung commented 2 weeks ago

I have same problem when I upgrade the lib to 5.1. And the problem is viewPortHandler.scaleX infinity. And my temp fix : if viewPortHandler.scaleX == CGFloat.infinity { return false }

ffchung commented 2 weeks ago

For my case , it happen when input empty data with setVisibleXRange ` let values:[Double] = []

    let dataEntries:[ChartDataEntry] = values.enumerated().map{ return ChartDataEntry(x: Double($0), y: $1) }
    let lineChartDataSet = LineChartDataSet(entries: dataEntries, label: "")

    lineChartDataSet.drawValuesEnabled = false
    lineChartDataSet.drawHorizontalHighlightIndicatorEnabled = false
    lineChartDataSet.drawCirclesEnabled = false
    lineChartDataSet.setColor(UIColor.yellow)

    let lineChartData = LineChartData(dataSet: lineChartDataSet)

    self.lineChartView.data = lineChartData

    self.lineChartView.setVisibleXRange(minXRange: self.maxDataCount, maxXRange: self.maxDataCount*10)

`

sorinmiroiu97 commented 2 weeks ago

@ffchung it seems like the pr got approved, but it's not merged in yet. please check the page of the pr. in the meanwhile feel free to use my custom fork. thank you 😄

ffchung commented 2 weeks ago

@sorinmiroiu97 I just tested with the pr and it work for my case. Thanks.

sorinmiroiu97 commented 2 weeks ago

@ffchung so great to hear that buddy! thanks as well! 😄

ffchung commented 2 weeks ago

@sorinmiroiu97 I think you have something wrong on Source/Charts/Renderers/HorizontalBarChartRenderer.swift it was using viewPortHandler.scaleY and you chaned to use viewPortHandler.scaleX ? I didn't test it. just check the different between old and new code.

sorinmiroiu97 commented 2 weeks ago

@ffchung thanks a lot for pointing that out! i think i might have hit enter on the autocomplete and i didn't notice the X instead of Y. gonna fix it now! many thanks bud!