From bc5f82990df628bf2b28af780e24445ee9b086ee Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 20 Feb 2013 18:57:50 -0800 Subject: Fix divide-by-zero bug in statistics.c GET_LOCAL_SAC did not check if the two entries had different time stamps and could therefore cause a divide-by-zero. x86 doesn't fault on that - it's still wrong. This now calls a function that does proper checking of all the values involved in the calculation. Signed-off-by: Linus Torvalds Signed-off-by: Dirk Hohndel --- profile.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) (limited to 'profile.c') diff --git a/profile.c b/profile.c index 2befb4d2c..62b465dfb 100644 --- a/profile.c +++ b/profile.c @@ -1010,12 +1010,32 @@ static void set_sac_color(struct graphics_context *gc, int sac, int avg_sac) } } +static double get_local_sac(struct plot_data *entry1, struct plot_data *entry2, struct dive *dive) +{ + int index = entry1->cylinderindex; + int delta_time = entry2->sec - entry1->sec; + double depth; + long delta_pressure = GET_PRESSURE(entry1) - GET_PRESSURE(entry2); + long mliter; + + if (entry2->cylinderindex != index) + return 0; + if (delta_pressure <= 0) + return 0; + if (delta_time <= 0) + return 0; + depth = (entry1->depth + entry2->depth) / 2.0; + + mliter = dive->cylinder[index].type.size.mliter; + + return delta_pressure * mliter / + (delta_time / 60.0) / + depth_to_mbar(depth, dive); +} + /* calculate the current SAC in ml/min and convert to int */ -#define GET_LOCAL_SAC(_entry1, _entry2, _dive) (int) \ - ((GET_PRESSURE((_entry1)) - GET_PRESSURE((_entry2))) * \ - (_dive)->cylinder[(_entry1)->cylinderindex].type.size.mliter / \ - (((_entry2)->sec - (_entry1)->sec) / 60.0) / \ - depth_to_mbar(((_entry1)->depth + (_entry2)->depth) / 2.0, (_dive))) +#define GET_LOCAL_SAC(_entry1, _entry2, _dive) \ + (int) get_local_sac(_entry1, _entry2, _dive) #define SAC_WINDOW 45 /* sliding window in seconds for current SAC calculation */ -- cgit v1.2.3-70-g09d2