aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2017-05-12 11:53:01 +1000
committerSteve Bennett <steveb@workware.net.au>2017-05-12 13:02:15 +1000
commitc8e41c8a8a0d6cae87f89a6b26b336b2df8099d2 (patch)
tree7b67cf2effc2846b1409d2c76b2e0d1721966768
parent002a3ef0b663724b0f43dbd2d184505afae6dd3e (diff)
downloadjimtcl-c8e41c8a8a0d6cae87f89a6b26b336b2df8099d2.zip
jimtcl-c8e41c8a8a0d6cae87f89a6b26b336b2df8099d2.tar.gz
jimtcl-c8e41c8a8a0d6cae87f89a6b26b336b2df8099d2.tar.bz2
lsort -unique: Fix case with no duplicates
In this case the final element was written a second time. Reported-by: Ryan Whitworth <me@ryanwhitworth.com> Signed-off-by: Steve Bennett <steveb@workware.net.au>
-rw-r--r--jim.c8
-rw-r--r--regtest.tcl5
2 files changed, 11 insertions, 2 deletions
diff --git a/jim.c b/jim.c
index b857865..037d886 100644
--- a/jim.c
+++ b/jim.c
@@ -6659,8 +6659,12 @@ static void ListRemoveDuplicates(Jim_Obj *listObjPtr, int (*comp)(Jim_Obj **lhs,
}
ele[dst] = ele[src];
}
- /* At end of list, keep the final element */
- ele[++dst] = ele[src];
+
+ /* At end of list, keep the final element unless all elements were kept */
+ dst++;
+ if (dst < listObjPtr->internalRep.listValue.len) {
+ ele[dst] = ele[src];
+ }
/* Set the new length */
listObjPtr->internalRep.listValue.len = dst;
diff --git a/regtest.tcl b/regtest.tcl
index 0761c49..df25d13 100644
--- a/regtest.tcl
+++ b/regtest.tcl
@@ -310,6 +310,11 @@ puts "TEST 42 PASSED"
catch {format %----------------------------------------d 1}
puts "TEST 43 PASSED"
+# REGTEST 44
+# lsort -unique with no duplicate - invalid memory write
+lsort -unique {a b c d}
+puts "TEST 44 PASSED"
+
# TAKE THE FOLLOWING puts AS LAST LINE
puts "--- ALL TESTS PASSED ---"