diff options
author | jilles <jilles@FreeBSD.org> | 2014-07-20 20:29:09 +0000 |
---|---|---|
committer | jilles <jilles@FreeBSD.org> | 2014-07-20 20:29:09 +0000 |
commit | 8c44f4d5e2720f2acdcf5f17db3908e6b5a396c9 (patch) | |
tree | a9b54617a6a287ad1219072a06e97076eae1110f | |
parent | 30b6369746e5c67ea575ac72604b40bfdd81e6d7 (diff) | |
download | FreeBSD-src-8c44f4d5e2720f2acdcf5f17db3908e6b5a396c9.zip FreeBSD-src-8c44f4d5e2720f2acdcf5f17db3908e6b5a396c9.tar.gz |
sh: Allow arbitrarily large numbers in break and continue.
The argument is capped to loopnest, so strtol()'s [ERANGE] can be ignored.
-rw-r--r-- | bin/sh/eval.c | 10 | ||||
-rw-r--r-- | bin/sh/tests/builtins/Makefile | 1 | ||||
-rw-r--r-- | bin/sh/tests/builtins/break6.0 | 8 |
3 files changed, 18 insertions, 1 deletions
diff --git a/bin/sh/eval.c b/bin/sh/eval.c index 4f7559e..3fd3050 100644 --- a/bin/sh/eval.c +++ b/bin/sh/eval.c @@ -1250,8 +1250,16 @@ bltincmd(int argc, char **argv) int breakcmd(int argc, char **argv) { - int n = argc > 1 ? number(argv[1]) : 1; + long n; + char *end; + if (argc > 1) { + /* Allow arbitrarily large numbers. */ + n = strtol(argv[1], &end, 10); + if (!is_digit(argv[1][0]) || *end != '\0') + error("Illegal number: %s", argv[1]); + } else + n = 1; if (n > loopnest) n = loopnest; if (n > 0) { diff --git a/bin/sh/tests/builtins/Makefile b/bin/sh/tests/builtins/Makefile index bc2edd5..4c988da 100644 --- a/bin/sh/tests/builtins/Makefile +++ b/bin/sh/tests/builtins/Makefile @@ -14,6 +14,7 @@ FILES+= break2.0 break2.0.stdout FILES+= break3.0 FILES+= break4.4 FILES+= break5.4 +FILES+= break6.0 FILES+= builtin1.0 FILES+= case1.0 FILES+= case2.0 diff --git a/bin/sh/tests/builtins/break6.0 b/bin/sh/tests/builtins/break6.0 new file mode 100644 index 0000000..09fc0d8 --- /dev/null +++ b/bin/sh/tests/builtins/break6.0 @@ -0,0 +1,8 @@ +# $FreeBSD$ +# Per POSIX, this need only work if LONG_MAX > 4294967295. + +while :; do + break 4294967296 + echo bad + exit 3 +done |