summaryrefslogtreecommitdiffstats
path: root/bin
diff options
context:
space:
mode:
authorjilles <jilles@FreeBSD.org>2014-07-20 20:29:09 +0000
committerjilles <jilles@FreeBSD.org>2014-07-20 20:29:09 +0000
commit8c44f4d5e2720f2acdcf5f17db3908e6b5a396c9 (patch)
treea9b54617a6a287ad1219072a06e97076eae1110f /bin
parent30b6369746e5c67ea575ac72604b40bfdd81e6d7 (diff)
downloadFreeBSD-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.
Diffstat (limited to 'bin')
-rw-r--r--bin/sh/eval.c10
-rw-r--r--bin/sh/tests/builtins/Makefile1
-rw-r--r--bin/sh/tests/builtins/break6.08
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
OpenPOWER on IntegriCloud