summaryrefslogtreecommitdiffstats
path: root/profile.c
diff options
context:
space:
mode:
authorGravatar Linus Torvalds <torvalds@linux-foundation.org>2013-02-20 18:57:50 -0800
committerGravatar Dirk Hohndel <dirk@hohndel.org>2013-02-20 21:24:08 -0800
commitbc5f82990df628bf2b28af780e24445ee9b086ee (patch)
treec561a9c1de39151d2a5c9ac9b4ab6ec1771293b8 /profile.c
parent49b4f7c4acea69bb3075d9555dbd4d58f16a9f56 (diff)
downloadsubsurface-bc5f82990df628bf2b28af780e24445ee9b086ee.tar.gz
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 <torvalds@linux-foundation.org> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Diffstat (limited to 'profile.c')
-rw-r--r--profile.c30
1 files changed, 25 insertions, 5 deletions
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 */