hexdump: fix short file of zero butes treated as dup
authorDenys Vlasenko <vda.linux@googlemail.com>
Tue, 3 Jul 2018 14:27:54 +0000 (16:27 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Tue, 3 Jul 2018 14:29:06 +0000 (16:29 +0200)
function                                             old     new   delta
bb_dump_dump                                        1466    1491     +25

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
libbb/dump.c
testsuite/hexdump.tests [new file with mode: 0755]

index 5941ef902c4d4833983e2bbd582943f51fc991fb..b4b49d709e77492c45fe17662a021c1ef9a65c55 100644 (file)
@@ -387,7 +387,10 @@ static unsigned char *get(priv_dumper_t *dumper)
                        if (need == blocksize) {
                                return NULL;
                        }
-                       if (dumper->pub.dump_vflag != ALL && !memcmp(dumper->get__curp, dumper->get__savp, nread)) {
+                       if (dumper->pub.dump_vflag != ALL   /* not "show all"? */
+                        && dumper->pub.dump_vflag != FIRST /* not first line? */
+                        && memcmp(dumper->get__curp, dumper->get__savp, nread) == 0 /* same data? */
+                       ) {
                                if (dumper->pub.dump_vflag != DUP) {
                                        puts("*");
                                }
@@ -399,7 +402,7 @@ static unsigned char *get(priv_dumper_t *dumper)
                }
                n = fread(dumper->get__curp + nread, sizeof(unsigned char),
                                dumper->pub.dump_length == -1 ? need : MIN(dumper->pub.dump_length, need), stdin);
-               if (!n) {
+               if (n == 0) {
                        if (ferror(stdin)) {
                                bb_simple_perror_msg(dumper->argv[-1]);
                        }
@@ -411,9 +414,10 @@ static unsigned char *get(priv_dumper_t *dumper)
                        dumper->pub.dump_length -= n;
                }
                need -= n;
-               if (!need) {
-                       if (dumper->pub.dump_vflag == ALL || dumper->pub.dump_vflag == FIRST
-                        || memcmp(dumper->get__curp, dumper->get__savp, blocksize)
+               if (need == 0) {
+                       if (dumper->pub.dump_vflag == ALL   /* "show all"? */
+                        || dumper->pub.dump_vflag == FIRST /* first line? */
+                        || memcmp(dumper->get__curp, dumper->get__savp, blocksize) != 0 /* not same data? */
                        ) {
                                if (dumper->pub.dump_vflag == DUP || dumper->pub.dump_vflag == FIRST) {
                                        dumper->pub.dump_vflag = WAIT;
diff --git a/testsuite/hexdump.tests b/testsuite/hexdump.tests
new file mode 100755 (executable)
index 0000000..45a0c13
--- /dev/null
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+# Copyright 2018 by Denys Vlasenko <vda.linux@googlemail.com>
+# Licensed under GPLv2, see file LICENSE in this source tree.
+
+. ./testing.sh
+
+# testing "description" "command" "result" "infile" "stdin"
+testing 'hexdump -C with four NULs' \
+       'hexdump -C' \
+       "\
+00000000  00 00 00 00                                       |....|
+00000004
+" \
+       '' \
+       '\0\0\0\0'
+
+exit $FAILCOUNT