summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cut.c6
-rwxr-xr-xtests/misc/cut-huge-range.sh8
2 files changed, 10 insertions, 4 deletions
diff --git a/src/cut.c b/src/cut.c
index b347b307b..9501b3aa7 100644
--- a/src/cut.c
+++ b/src/cut.c
@@ -496,9 +496,9 @@ set_fields (const char *fieldstr)
if (rp[j].lo <= rp[i].hi)
{
rp[i].hi = MAX (rp[j].hi, rp[i].hi);
- memmove (rp + j, rp + j + 1,
- (n_rp - j - 1) * sizeof (struct range_pair));
- --n_rp;
+ memmove (rp + j, rp + j + 1, (n_rp - j - 1) * sizeof *rp);
+ n_rp--;
+ j--;
}
else
break;
diff --git a/tests/misc/cut-huge-range.sh b/tests/misc/cut-huge-range.sh
index 887197ae9..9905cd758 100755
--- a/tests/misc/cut-huge-range.sh
+++ b/tests/misc/cut-huge-range.sh
@@ -27,7 +27,13 @@ getlimits_
# Up to and including coreutils-8.21, cut would allocate possibly needed
# memory upfront. Subsequently memory is allocated as required.
-(ulimit -v 20000; : | cut -b1-$INT_MAX > err 2>&1) || fail=1
+(ulimit -v 20000; : | cut -b1-$INT_MAX >> err 2>&1) || fail=1
+
+# Ensure ranges are merged correctly when large range logic is in effect
+echo 1 > exp
+(dd bs=1MB if=/dev/zero count=1; echo '1') |
+cut -b1-1000000,2-3,4-5,1000001 2>>err | tail -c2 > out || fail=1
+compare exp out || fail=1
compare /dev/null err || fail=1