diff options
author | Stefan Pavikevik <stefan_pavikevik@outlook.com> | 2020-02-08 18:56:47 +0100 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2020-02-24 20:53:44 -0500 |
commit | e295a02440db8b1d96cebad22c5ee48774774681 (patch) | |
tree | 8122b5042d938d5e27808d491f328b7a583a6f53 | |
parent | 84dd96105faff71cb17d1c1d069d724d014847dc (diff) | |
download | haskell-e295a02440db8b1d96cebad22c5ee48774774681.tar.gz |
check for safe arguments, raising error when invalid (fix #17720)
-rw-r--r-- | rts/RtsFlags.c | 56 | ||||
-rw-r--r-- | testsuite/tests/rts/flags/T17720/T17720.hs | 2 | ||||
-rw-r--r-- | testsuite/tests/rts/flags/T17720/T17720a.stderr | 1 | ||||
-rw-r--r-- | testsuite/tests/rts/flags/T17720/T17720b.stderr | 1 | ||||
-rw-r--r-- | testsuite/tests/rts/flags/T17720/T17720c.stderr | 1 | ||||
-rw-r--r-- | testsuite/tests/rts/flags/T17720/all.T | 20 |
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 |