summaryrefslogtreecommitdiff
path: root/rts
diff options
context:
space:
mode:
authorStefan Pavikevik <stefan_pavikevik@outlook.com>2020-02-08 18:56:47 +0100
committerMarge Bot <ben+marge-bot@smart-cactus.org>2020-02-24 20:53:44 -0500
commite295a02440db8b1d96cebad22c5ee48774774681 (patch)
tree8122b5042d938d5e27808d491f328b7a583a6f53 /rts
parent84dd96105faff71cb17d1c1d069d724d014847dc (diff)
downloadhaskell-e295a02440db8b1d96cebad22c5ee48774774681.tar.gz
check for safe arguments, raising error when invalid (fix #17720)
Diffstat (limited to 'rts')
-rw-r--r--rts/RtsFlags.c56
1 files changed, 53 insertions, 3 deletions
diff --git a/rts/RtsFlags.c b/rts/RtsFlags.c
index fe118ea5f0..5b594c915d 100644
--- a/rts/RtsFlags.c
+++ b/rts/RtsFlags.c
@@ -21,7 +21,10 @@
#include <ctype.h>
#endif
+#include <errno.h>
+
#include <string.h>
+#include <stdlib.h>
#if defined(HAVE_UNISTD_H)
#include <unistd.h>
@@ -98,6 +101,9 @@ static int openStatsFile (
static StgWord64 decodeSize (
const char *flag, uint32_t offset, StgWord64 min, StgWord64 max);
+static double parseDouble (
+ const char *arg, bool *error);
+
static void bad_option (const char *s);
#if defined(DEBUG)
@@ -1326,8 +1332,13 @@ error = true;
if (rts_argv[arg][2] == '\0') {
/* use default */
} else {
+ double intervalSeconds = parseDouble(rts_argv[arg]+2, &error);
+
+ if (error) {
+ errorBelch("bad value for -i");
+ }
RtsFlags.ProfFlags.heapProfileInterval =
- fsecondsToTime(atof(rts_argv[arg]+2));
+ fsecondsToTime(intervalSeconds);
}
break;
@@ -1337,8 +1348,13 @@ error = true;
if (rts_argv[arg][2] == '\0')
RtsFlags.ConcFlags.ctxtSwitchTime = 0;
else {
+ double intervalSeconds = parseDouble(rts_argv[arg]+2, &error);
+
+ if (error) {
+ errorBelch("bad value for -C");
+ }
RtsFlags.ConcFlags.ctxtSwitchTime =
- fsecondsToTime(atof(rts_argv[arg]+2));
+ fsecondsToTime(intervalSeconds);
}
break;
@@ -1348,8 +1364,13 @@ error = true;
// turns off ticks completely
RtsFlags.MiscFlags.tickInterval = 0;
} else {
+ double intervalSeconds = parseDouble(rts_argv[arg]+2, &error);
+
+ if (error) {
+ errorBelch("bad value for -V");
+ }
RtsFlags.MiscFlags.tickInterval =
- fsecondsToTime(atof(rts_argv[arg]+2));
+ fsecondsToTime(intervalSeconds);
}
break;
@@ -1912,6 +1933,35 @@ decodeSize(const char *flag, uint32_t offset, StgWord64 min, StgWord64 max)
return val;
}
+/* ----------------------------------------------------------------------------------
+ * parseDouble: parse a double from a string, setting a flag in case of an error
+-------------------------------------------------------------------------------- */
+
+static double
+parseDouble(const char *arg, bool *error)
+{
+ char *endptr;
+ double out;
+ errno = 0;
+
+ out = strtod(arg, &endptr);
+
+ if (errno != 0 || endptr == arg) {
+ *error = true;
+ return out;
+ }
+
+ while (isspace((unsigned char)*endptr)) {
+ ++endptr;
+ }
+
+ if (*endptr != 0) {
+ *error = true;
+ }
+
+ return out;
+}
+
#if defined(DEBUG)
static void read_debug_flags(const char* arg)
{