git: c6038436360e - stable/13 - diff: Tweak range of -C and -U arguments
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 18 Feb 2026 00:26:02 UTC
The branch stable/13 has been updated by des:
URL: https://cgit.FreeBSD.org/src/commit/?id=c6038436360ebf6344e6f65d40e1d38611d1d603
commit c6038436360ebf6344e6f65d40e1d38611d1d603
Author: Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2026-02-13 20:18:24 +0000
Commit: Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2026-02-18 00:20:36 +0000
diff: Tweak range of -C and -U arguments
POSIX uses the terms “positive decimal integer” for -C and “non-negative
decimal integer” for -U, which translates into lower bounds of 1 for -C
and 0 for -U.
POSIX does not specify a minimum upper bound for either mode, but as of
5fc739eb5949 both our backends support context sizes up to and including
INT_MAX, so use that.
Having had the opportunity to consult the Unix System Test Suite, the
diff test cases found therein happen to precisely match these bounds.
While here, switch to using strtonum() to parse numerical arguments, and
try to be more consistent in how we report usage errors.
MFC after: 1 week
Sponsored by: Klara, Inc.
Reviewed by: kevans
Differential Revision: https://reviews.freebsd.org/D55261
(cherry picked from commit 790f1d1cc5fa892ba59fd7f239b22064c8ab14c7)
---
usr.bin/diff/diff.c | 33 +++++++++++++++-----------
usr.bin/diff/tests/diff_test.sh | 52 +++++++++++++++++++++++++----------------
2 files changed, 51 insertions(+), 34 deletions(-)
diff --git a/usr.bin/diff/diff.c b/usr.bin/diff/diff.c
index 71f0ac94c7ab..b9a9b13c5d4d 100644
--- a/usr.bin/diff/diff.c
+++ b/usr.bin/diff/diff.c
@@ -108,10 +108,9 @@ void set_argstr(char **, char **);
int
main(int argc, char **argv)
{
- const char *errstr = NULL;
- char *ep, **oargv;
- long l;
- int ch, dflags, lastch, gotstdin, prevoptind, newarg;
+ const char *errstr;
+ char **oargv;
+ int ch, dflags, lastch, gotstdin, prevoptind, newarg;
oargv = argv;
gotstdin = 0;
@@ -148,10 +147,13 @@ main(int argc, char **argv)
cflag = 1;
diff_format = D_CONTEXT;
if (optarg != NULL) {
- l = strtol(optarg, &ep, 10);
- if (*ep != '\0' || l < 0 || l >= INT_MAX)
+ diff_context = (int) strtonum(optarg,
+ 1, INT_MAX, &errstr);
+ if (errstr != NULL) {
+ warnx("context size is %s: %s",
+ errstr, optarg);
usage();
- diff_context = (int)l;
+ }
}
break;
case 'd':
@@ -239,10 +241,13 @@ main(int argc, char **argv)
conflicting_format();
diff_format = D_UNIFIED;
if (optarg != NULL) {
- l = strtol(optarg, &ep, 10);
- if (*ep != '\0' || l < 0 || l >= INT_MAX)
+ diff_context = (int) strtonum(optarg,
+ 0, INT_MAX, &errstr);
+ if (errstr != NULL) {
+ warnx("context size is %s: %s",
+ errstr, optarg);
usage();
- diff_context = (int)l;
+ }
}
break;
case 'w':
@@ -251,8 +256,8 @@ main(int argc, char **argv)
case 'W':
Wflag = 1;
width = (int) strtonum(optarg, 1, INT_MAX, &errstr);
- if (errstr) {
- warnx("Invalid argument for width");
+ if (errstr != NULL) {
+ warnx("width is %s: %s", errstr, optarg);
usage();
}
break;
@@ -288,8 +293,8 @@ main(int argc, char **argv)
break;
case OPT_TSIZE:
tabsize = (int) strtonum(optarg, 1, INT_MAX, &errstr);
- if (errstr) {
- warnx("Invalid argument for tabsize");
+ if (errstr != NULL) {
+ warnx("tabsize is %s: %s", errstr, optarg);
usage();
}
break;
diff --git a/usr.bin/diff/tests/diff_test.sh b/usr.bin/diff/tests/diff_test.sh
index df98540083f9..9914cdcf84c7 100755
--- a/usr.bin/diff/tests/diff_test.sh
+++ b/usr.bin/diff/tests/diff_test.sh
@@ -20,8 +20,8 @@ atf_test_case report_identical
atf_test_case non_regular_file
atf_test_case binary
atf_test_case dirloop
-atf_test_case bigc
-atf_test_case bigu
+atf_test_case crange
+atf_test_case urange
atf_test_case prleak
atf_test_case same
@@ -309,30 +309,42 @@ dirloop_body()
atf_check diff -r a b
}
-bigc_head()
+crange_head()
{
- atf_set "descr" "Context diff with very large context"
+ atf_set "descr" "Context diff context length range"
}
-bigc_body()
+crange_body()
{
- echo $'x\na\ny' >a
- echo $'x\nb\ny' >b
- atf_check -s exit:2 -e ignore diff -C$(((1<<31)-1)) a b
- atf_check -s exit:1 -o match:'--- 1,3 ---' \
- diff -C$(((1<<31)-2)) a b
+ echo $'x\nx\na\ny\ny' >a
+ echo $'x\nx\nb\ny\ny' >b
+ atf_check -s exit:2 -e match:'too small' \
+ diff -C-1 a b
+ atf_check -s exit:2 -e match:'too small' \
+ diff -C0 a b
+ atf_check -s exit:1 -o match:'--- 2,4 ---' \
+ diff -C1 a b
+ atf_check -s exit:2 -e match:'too large' \
+ diff -C$((1<<31)) a b
+ atf_check -s exit:1 -o match:'--- 1,5 ---' \
+ diff -C$(((1<<31)-1)) a b
}
-bigu_head()
+urange_head()
{
- atf_set "descr" "Unified diff with very large context"
+ atf_set "descr" "Unified diff context length range"
}
-bigu_body()
+urange_body()
{
- echo $'x\na\ny' >a
- echo $'x\nb\ny' >b
- atf_check -s exit:2 -e ignore diff -U$(((1<<31)-1)) a b
- atf_check -s exit:1 -o match:'^@@ -1,3 \+1,3 @@$' \
- diff -U$(((1<<31)-2)) a b
+ echo $'x\nx\na\ny\ny' >a
+ echo $'x\nx\nb\ny\ny' >b
+ atf_check -s exit:2 -e match:'too small' \
+ diff -U-1 a b
+ atf_check -s exit:1 -o match:'^@@ -3 \+3 @@$' \
+ diff -U0 a b
+ atf_check -s exit:2 -e match:'too large' \
+ diff -U$((1<<31)) a b
+ atf_check -s exit:1 -o match:'^@@ -1,5 \+1,5 @@$' \
+ diff -U$(((1<<31)-1)) a b
}
prleak_head()
@@ -396,8 +408,8 @@ atf_init_test_cases()
atf_add_test_case non_regular_file
atf_add_test_case binary
atf_add_test_case dirloop
- atf_add_test_case bigc
- atf_add_test_case bigu
+ atf_add_test_case crange
+ atf_add_test_case urange
atf_add_test_case prleak
atf_add_test_case same
}