From 5e3d017e7bc66cf6f666160f774944c2ff52d1ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= Date: Mon, 26 Oct 2015 01:26:04 +0000 Subject: [PATCH] md5sum: quote all printed file names This is especially significant when using --check with files generated on a windows system, where the \r characters produce corrupted and confusing error messages. This also ensures status messages are output on a single line. * src/md5sum.c: Use quote() for printed file names. * tests/misc/md5sum.pl: Adjust accordingly. * NEWS: Mention the change in behavior. Fixes http://bugs.gnu.org/21757 --- NEWS | 3 +++ src/md5sum.c | 27 +++++++++++++-------------- tests/misc/md5sum.pl | 27 ++++++++++++++------------- 3 files changed, 30 insertions(+), 27 deletions(-) diff --git a/NEWS b/NEWS index e771585..1997632 100644 --- a/NEWS +++ b/NEWS @@ -23,6 +23,9 @@ GNU coreutils NEWS -*- outline -*- df now prefers sources towards the root of a device when eliding duplicate bind mounted entries. + md5sum now quotes all printed file names to avoid confusing error messages. + This also affects sha1sum, sha224sum, sha256sum, sha384sum and sha512sum. + ** Improvements dircolors now supports globbing of TERM entries in its database. diff --git a/src/md5sum.c b/src/md5sum.c index bc2b709..564b753 100644 --- a/src/md5sum.c +++ b/src/md5sum.c @@ -37,6 +37,7 @@ #endif #include "error.h" #include "fadvise.h" +#include "quote.h" #include "stdio--.h" #include "xfreopen.h" @@ -451,7 +452,7 @@ digest_file (const char *filename, int *binary, unsigned char *bin_result) fp = fopen (filename, (O_BINARY && *binary ? "rb" : "r")); if (fp == NULL) { - error (0, errno, "%s", filename); + error (0, errno, "%s", quote (filename)); return false; } } @@ -461,7 +462,7 @@ digest_file (const char *filename, int *binary, unsigned char *bin_result) err = DIGEST_STREAM (fp, bin_result); if (err) { - error (0, errno, "%s", filename); + error (0, errno, "%s", quote (filename)); if (fp != stdin) fclose (fp); return false; @@ -469,7 +470,7 @@ digest_file (const char *filename, int *binary, unsigned char *bin_result) if (!is_stdin && fclose (fp) != 0) { - error (0, errno, "%s", filename); + error (0, errno, "%s", quote (filename)); return false; } @@ -504,7 +505,7 @@ digest_check (const char *checkfile_name) checkfile_stream = fopen (checkfile_name, "r"); if (checkfile_stream == NULL) { - error (0, errno, "%s", checkfile_name); + error (0, errno, "%s", quote (checkfile_name)); return false; } } @@ -522,7 +523,7 @@ digest_check (const char *checkfile_name) ++line_number; if (line_number == 0) error (EXIT_FAILURE, 0, _("%s: too many checksum lines"), - checkfile_name); + quote (checkfile_name)); line_length = getline (&line, &line_chars_allocated, checkfile_stream); if (line_length <= 0) @@ -547,7 +548,7 @@ digest_check (const char *checkfile_name) error (0, 0, _("%s: %" PRIuMAX ": improperly formatted %s checksum line"), - checkfile_name, line_number, + quote (checkfile_name), line_number, DIGEST_TYPE_STRING); } @@ -569,9 +570,7 @@ digest_check (const char *checkfile_name) { ++n_open_or_read_failures; if (!status_only) - { - printf (_("%s: FAILED open or read\n"), filename); - } + printf (_("%s: FAILED open or read\n"), quote (filename)); } else { @@ -593,9 +592,9 @@ digest_check (const char *checkfile_name) if (!status_only) { if (cnt != digest_bin_bytes) - printf ("%s: %s\n", filename, _("FAILED")); + printf ("%s: %s\n", quote (filename), _("FAILED")); else if (!quiet) - printf ("%s: %s\n", filename, _("OK")); + printf ("%s: %s\n", quote (filename), _("OK")); } } } @@ -606,13 +605,13 @@ digest_check (const char *checkfile_name) if (ferror (checkfile_stream)) { - error (0, 0, _("%s: read error"), checkfile_name); + error (0, 0, _("%s: read error"), quote (checkfile_name)); return false; } if (!is_stdin && fclose (checkfile_stream) != 0) { - error (0, errno, "%s", checkfile_name); + error (0, errno, "%s", quote (checkfile_name)); return false; } @@ -620,7 +619,7 @@ digest_check (const char *checkfile_name) { /* Warn if no tests are found. */ error (0, 0, _("%s: no properly formatted %s checksum lines found"), - checkfile_name, DIGEST_TYPE_STRING); + quote (checkfile_name), DIGEST_TYPE_STRING); } else { diff --git a/tests/misc/md5sum.pl b/tests/misc/md5sum.pl index b3ff4b4..d29a4ef 100755 --- a/tests/misc/md5sum.pl +++ b/tests/misc/md5sum.pl @@ -44,12 +44,12 @@ my @Tests = {OUT=>"\\$degenerate .\\\\foo\n"}], ['check-1', '--check', {AUX=> {f=> ''}}, {IN=> {'f.md5' => "$degenerate f\n"}}, - {OUT=>"f: OK\n"}], + {OUT=>"'f': OK\n"}], # Same as above, but with an added empty line, to provoke --strict. ['ck-strict-1', '--check --strict', {AUX=> {f=> ''}}, {IN=> {'f.md5' => "$degenerate f\n\n"}}, - {OUT=>"f: OK\n"}, + {OUT=>"'f': OK\n"}, {ERR=>"md5sum: " . "WARNING: 1 line is improperly formatted\n"}, {EXIT=> 1}], @@ -58,7 +58,7 @@ my @Tests = # lines are processed in spite of the preceding invalid input line. ['ck-strict-2', '--check --strict', {AUX=> {f=> ''}}, {IN=> {'in.md5' => "\n$degenerate f\n"}}, - {OUT=>"f: OK\n"}, + {OUT=>"'f': OK\n"}, {ERR=>"md5sum: " . "WARNING: 1 line is improperly formatted\n"}, {EXIT=> 1}], @@ -69,7 +69,7 @@ my @Tests = {OUT=>""}], ['check-quiet2', '--check', '--quiet', {IN=>{'f.md5' => "$degenerate f\n"}}, - {AUX=> {f=> 'foo'}}, {OUT=>"f: FAILED\n"}, + {AUX=> {f=> 'foo'}}, {OUT=>"'f': FAILED\n"}, {ERR=>"md5sum: WARNING: 1 computed" . " checksum did NOT match\n"}, {EXIT=> 1}], @@ -80,7 +80,7 @@ my @Tests = . "$degenerate f\n" . "invalid\n" }}, {AUX=> {f=> 'foo'}}, - {OUT=>"f: FAILED\nf: FAILED\n"}, + {OUT=>"'f': FAILED\n'f': FAILED\n"}, {ERR=>"md5sum: WARNING: 1 line is improperly formatted\n" . "md5sum: WARNING: 2 computed checksums did NOT match\n"}, {EXIT=> 1}], @@ -91,8 +91,9 @@ my @Tests = . "$degenerate f\n" . "invalid\n" }}, {AUX=> {f=> 'foo'}}, - {OUT=>"f: FAILED\nf: FAILED\n"}, - {ERR=>"md5sum: f.md5: 3: improperly formatted MD5 checksum line\n" + {OUT=>"'f': FAILED\n'f': FAILED\n"}, + {ERR=>"md5sum: 'f.md5': 3: " + . "improperly formatted MD5 checksum line\n" . "md5sum: WARNING: 1 line is improperly formatted\n" . "md5sum: WARNING: 2 computed checksums did NOT match\n"}, {EXIT=> 1}], @@ -101,26 +102,26 @@ my @Tests = # sha1sum accept BSD format. ['check-bsd', '--check', {IN=> {'f.sha1' => "SHA1 (f) = $degenerate\n"}}, {AUX=> {f=> ''}}, - {ERR=>"md5sum: f.sha1: no properly formatted " + {ERR=>"md5sum: 'f.sha1': no properly formatted " . "MD5 checksum lines found\n"}, {EXIT=> 1}], ['check-bsd2', '--check', {IN=> {'f.md5' => "MD5 (f) = $degenerate\n"}}, - {AUX=> {f=> ''}}, {OUT=>"f: OK\n"}], + {AUX=> {f=> ''}}, {OUT=>"'f': OK\n"}], ['check-bsd3', '--check', '--status', {IN=> {'f.md5' => "MD5 (f) = $degenerate\n"}}, {AUX=> {f=> 'bar'}}, {EXIT=> 1}], ['check-openssl', '--check', {IN=> {'f.sha1' => "SHA1(f)= $degenerate\n"}}, {AUX=> {f=> ''}}, - {ERR=>"md5sum: f.sha1: no properly formatted " + {ERR=>"md5sum: 'f.sha1': no properly formatted " . "MD5 checksum lines found\n"}, {EXIT=> 1}], ['check-openssl2', '--check', {IN=> {'f.md5' => "MD5(f)= $degenerate\n"}}, - {AUX=> {f=> ''}}, {OUT=>"f: OK\n"}], + {AUX=> {f=> ''}}, {OUT=>"'f': OK\n"}], ['check-openssl3', '--check', '--status', {IN=> {'f.md5' => "MD5(f)= $degenerate\n"}}, {AUX=> {f=> 'bar'}}, {EXIT=> 1}], ['bsd-segv', '--check', {IN=> {'z' => "MD5 ("}}, {EXIT=> 1}, - {ERR=> "$prog: z: no properly formatted MD5 checksum lines found\n"}], + {ERR=> "$prog: 'z': no properly formatted MD5 checksum lines found\n"}], # Ensure that when there's a NUL byte among the checksum hex digits # we detect the invalid formatting and don't even open the file. @@ -128,7 +129,7 @@ my @Tests = # h: FAILED # md5sum: WARNING: 1 of 1 computed checksum did NOT match ['nul-in-cksum', '--check', {IN=> {'h'=>("\0"x32)." h\n"}}, {EXIT=> 1}, - {ERR=> "$prog: h: no properly formatted MD5 checksum lines found\n"}], + {ERR=> "$prog: 'h': no properly formatted MD5 checksum lines found\n"}], ); # Insert the '--text' argument for each test. -- 2.5.0