>From 1a1029ea037d70d13eef05d29d17980fac729e2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= Date: Sun, 26 Mar 2017 17:04:36 -0700 Subject: [PATCH] md5sum,b2sum,sha*sum: don't erroneously trigger BSD reversed mode * src/md5sum.c (split_3): Verify hex digits internally before triggering the global bsd_reversed mode flag. (bsd_split_3): Likewise. * tests/misc/md5sum-bsd.sh: Add a test case. * NEWS: Mention the bug fix. Fixes http://bugs.gnu.org/26263 --- NEWS | 4 ++++ src/md5sum.c | 39 +++++++++++++++++++++------------------ tests/misc/md5sum-bsd.sh | 7 +++++++ 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/NEWS b/NEWS index e8d6d34..4604318 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,10 @@ GNU coreutils NEWS -*- outline -*- split no longer exits when invocations of a --filter return EPIPE. [bug introduced in coreutils-8.26] + md5sum --check no longer incorrectly enables BSD reversed format mode when + ignoring some non checksum lines. This also affects sha*sum and b2sum. + [bug introduced in coreutils-8.14] + * Noteworthy changes in release 8.27 (2017-03-08) [stable] diff --git a/src/md5sum.c b/src/md5sum.c index e58a68e..91cdfb2 100644 --- a/src/md5sum.c +++ b/src/md5sum.c @@ -346,6 +346,21 @@ filename_unescape (char *s, size_t s_len) return s; } +/* Return true if S is a NUL-terminated string of DIGEST_HEX_BYTES hex digits. + Otherwise, return false. */ +static bool _GL_ATTRIBUTE_PURE +hex_digits (unsigned char const *s) +{ + unsigned int i; + for (i = 0; i < digest_hex_bytes; i++) + { + if (!isxdigit (*s)) + return false; + ++s; + } + return *s == '\0'; +} + /* Split the checksum string S (of length S_LEN) from a BSD 'md5' or 'sha1' command into two parts: a hexadecimal digest, and the file name. S is modified. Return true if successful. */ @@ -386,7 +401,8 @@ bsd_split_3 (char *s, size_t s_len, unsigned char **hex_digest, i++; *hex_digest = (unsigned char *) &s[i]; - return true; + + return hex_digits (*hex_digest); } /* Split the string S (of length S_LEN) into three parts: @@ -492,6 +508,9 @@ split_3 (char *s, size_t s_len, s[i++] = '\0'; + if (! hex_digits (*hex_digest)) + return false; + /* If "bsd reversed" format detected. */ if ((s_len - i == 1) || (s[i] != ' ' && s[i] != '*')) { @@ -521,21 +540,6 @@ split_3 (char *s, size_t s_len, return true; } -/* Return true if S is a NUL-terminated string of DIGEST_HEX_BYTES hex digits. - Otherwise, return false. */ -static bool _GL_ATTRIBUTE_PURE -hex_digits (unsigned char const *s) -{ - unsigned int i; - for (i = 0; i < digest_hex_bytes; i++) - { - if (!isxdigit (*s)) - return false; - ++s; - } - return *s == '\0'; -} - /* If ESCAPE is true, then translate each NEWLINE byte to the string, "\\n", and each backslash to "\\\\". */ static void @@ -702,8 +706,7 @@ digest_check (const char *checkfile_name) line[--line_length] = '\0'; if (! (split_3 (line, line_length, &hex_digest, &binary, &filename) - && ! (is_stdin && STREQ (filename, "-")) - && hex_digits (hex_digest))) + && ! (is_stdin && STREQ (filename, "-")))) { ++n_misformatted_lines; diff --git a/tests/misc/md5sum-bsd.sh b/tests/misc/md5sum-bsd.sh index e2ad8db..dfd2cef 100755 --- a/tests/misc/md5sum-bsd.sh +++ b/tests/misc/md5sum-bsd.sh @@ -36,6 +36,13 @@ sed 's/ / /' check.md5sum > check.md5 md5sum --strict -c check.md5sum || fail=1 md5sum --strict -c check.md5 || fail=1 +# Ensure we don't trigger BSD reversed format with GPG headers etc. +echo '____not_all_hex_so_no_match_____ blah' > check2.md5sum +cat check.md5sum >> check2.md5sum +md5sum -c check2.md5sum 2>check2.err || fail=1 +echo 'md5sum: WARNING: 1 line is improperly formatted' >check2.exp +compare check2.exp check2.err || fail=1 + # If we skip the first entry in the BSD format checksums # then it'll be detected as standard format and error. # This unlikely caveat was thought better than mandating -- 2.9.3