haskell-chart icon indicating copy to clipboard operation
haskell-chart copied to clipboard

scaledAxis uses up all the memory when the range is invalid

Open takano-akio opened this issue 8 years ago • 1 comments

scaledAxis enters an infite loop and uses up the memory in the system when the given range has a negative size. For example:

*Graphics.Rendering.Chart.Axis.Floating> _axis_labels $ scaledAxis def (4, 0) [0,1,2,3]
[^C

I'm not sure what the correct behavior in this case is, but either returning something arbitrary or throwing an exception would be better than an infinte loop.

takano-akio avatar Sep 13 '17 03:09 takano-akio

The relevant code is this:

scaledAxis :: RealFloat a => LinearAxisParams a -> (a,a) -> AxisFn a
scaledAxis lap rs@(minV,maxV) ps0 = makeAxis' realToFrac realToFrac
                                         (_la_labelf lap) (labelvs,tickvs,gridvs)
  where
    ps        = filter isValidNumber ps0
    range []  = (0,1)
    range _   | minV == maxV = if minV==0 then (-1,1) else
                               let d = abs (minV * 0.01) in (minV-d,maxV+d)
              | otherwise    = rs
    labelvs   = map fromRational $ steps (fromIntegral (_la_nLabels lap)) r
    tickvs    = map fromRational $ steps (fromIntegral (_la_nTicks lap))
                                         (minimum labelvs,maximum labelvs)
    gridvs    = labelvs
    r         = range ps

The issue is that the steps function can't work if passed an invalid range (ie negative) range.

An extra check would be easy to add - though I'm unclear as to how the signal the failure mode. Returning something arbitrary wouldn't make it easy for users to diagnose the problem, and the library doesn't currently throw any exceptions - it's mostly pure code.

timbod7 avatar Sep 13 '17 06:09 timbod7