summaryrefslogtreecommitdiff
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
parent84dd96105faff71cb17d1c1d069d724d014847dc (diff)
downloadhaskell-e295a02440db8b1d96cebad22c5ee48774774681.tar.gz
check for safe arguments, raising error when invalid (fix #17720)
-rw-r--r--rts/RtsFlags.c56
-rw-r--r--testsuite/tests/rts/flags/T17720/T17720.hs2
-rw-r--r--testsuite/tests/rts/flags/T17720/T17720a.stderr1
-rw-r--r--testsuite/tests/rts/flags/T17720/T17720b.stderr1
-rw-r--r--testsuite/tests/rts/flags/T17720/T17720c.stderr1
-rw-r--r--testsuite/tests/rts/flags/T17720/all.T20
6 files changed, 78 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)
{
diff --git a/testsuite/tests/rts/flags/T17720/T17720.hs b/testsuite/tests/rts/flags/T17720/T17720.hs
new file mode 100644
index 0000000000..377b6b5516
--- /dev/null
+++ b/testsuite/tests/rts/flags/T17720/T17720.hs
@@ -0,0 +1,2 @@
+main :: IO ()
+main = return ()
diff --git a/testsuite/tests/rts/flags/T17720/T17720a.stderr b/testsuite/tests/rts/flags/T17720/T17720a.stderr
new file mode 100644
index 0000000000..03dd38d24a
--- /dev/null
+++ b/testsuite/tests/rts/flags/T17720/T17720a.stderr
@@ -0,0 +1 @@
+T17720a: bad value for -i \ No newline at end of file
diff --git a/testsuite/tests/rts/flags/T17720/T17720b.stderr b/testsuite/tests/rts/flags/T17720/T17720b.stderr
new file mode 100644
index 0000000000..198f49b5d7
--- /dev/null
+++ b/testsuite/tests/rts/flags/T17720/T17720b.stderr
@@ -0,0 +1 @@
+T17720b: bad value for -C \ No newline at end of file
diff --git a/testsuite/tests/rts/flags/T17720/T17720c.stderr b/testsuite/tests/rts/flags/T17720/T17720c.stderr
new file mode 100644
index 0000000000..77f4ae86d7
--- /dev/null
+++ b/testsuite/tests/rts/flags/T17720/T17720c.stderr
@@ -0,0 +1 @@
+T17720c: bad value for -V \ No newline at end of file
diff --git a/testsuite/tests/rts/flags/T17720/all.T b/testsuite/tests/rts/flags/T17720/all.T
new file mode 100644
index 0000000000..d3921bc112
--- /dev/null
+++ b/testsuite/tests/rts/flags/T17720/all.T
@@ -0,0 +1,20 @@
+test('T17720a',
+ [extra_run_opts('+RTS -ibogus'),
+ exit_code(1), check_errmsg('bad value for -i'), extra_files(['T17720.hs']),
+ only_ways(['normal'])],
+ multimod_compile_and_run,
+ ['T17720', '-rtsopts'])
+
+test('T17720b',
+ [extra_run_opts('+RTS -Cv'),
+ exit_code(1), check_errmsg('bad value for -C'), extra_files(['T17720.hs']),
+ only_ways(['normal'])],
+ multimod_compile_and_run,
+ ['T17720', '-rtsopts'])
+
+test('T17720c',
+ [extra_run_opts('+RTS -V3b'),
+ exit_code(1), check_errmsg('bad value for -V'), extra_files(['T17720.hs']),
+ only_ways(['normal'])],
+ multimod_compile_and_run,
+ ['T17720', '-rtsopts']) \ No newline at end of file