* src/digest.c (split_3): Fallback to untagged matching in the
case where -a is specified and we have matched a TAG in
the possibly base64 data. Note we remove the modification
of string S (and redundant string compare) in the tag matching code,
as that was not needed since commit v8.32-223-g217cd278e.
* tests/cksum/cksum-c.sh: Add a test case.
* NEWS: Mention the bug fix.
---
NEWS | 6 ++++--
src/digest.c | 45 +++++++++++++++++++++++++-----------------
tests/cksum/cksum-c.sh | 8 ++++++++
3 files changed, 39 insertions(+), 20 deletions(-)
diff --git a/NEWS b/NEWS
index 6a548e99e..c2d77b567 100644
--- a/NEWS
+++ b/NEWS
@@ -7,8 +7,10 @@ GNU coreutils NEWS -*-
outline -*-
`basenc --base58` would not operate correctly with input > 15561475 bytes.
[bug introduced with --base58 in coreutils-9.8]
- 'cksum --check' now supports base64 encoded input in untagged format,
- for all length adjustable algorithms (blake2b, sha2, sha3).
+ 'cksum --check' now supports base64 encoded input in untagged format:
+ - for all length adjustable algorithms (blake2b, sha2, sha3),
+ - if that base64 input starts with a tag like "SHA1" etc.
+ Previously an error was given, about invalid input format.
[bug introduced in coreutils-9.2]
'cksum --check -a sha2' has better support for tagged format. Previously
diff --git a/src/digest.c b/src/digest.c
index 3a12b0a48..41bdca5fe 100644
--- a/src/digest.c
+++ b/src/digest.c
@@ -847,21 +847,28 @@ split_3 (char *s, size_t s_len,
if (! algorithm_specified || cksum_algorithm == sha2)
{
ptrdiff_t algo_tag = algorithm_from_tag (s + i);
- if (algo_tag >= 0)
+ if (! algorithm_specified)
{
- if (algo_tag <= crc32b)
- return false; /* We don't support checking these older formats.
*/
- if (cksum_algorithm == sha2 && algo_tag != sha2
- && algo_tag != sha224 && algo_tag != sha256
- && algo_tag != sha384 && algo_tag != sha512)
- return false; /* Wrong tag for -a sha2. */
- cksum_algorithm = algo_tag;
+ if (algo_tag >= 0)
+ {
+ if (algo_tag <= crc32b)
+ return false; /* We don't support checking these formats. */
+ cksum_algorithm = algo_tag;
+ }
+ else
+ return false; /* We only support tagged format without -a. */
+ }
+ else
+ {
+ if (cksum_algorithm == sha2 && (algo_tag == sha2
+ || algo_tag == sha224 || algo_tag == sha256
+ || algo_tag == sha384 || algo_tag == sha512))
+ cksum_algorithm = algo_tag;
}
- else if (! algorithm_specified)
- return false; /* We only support tagged format without -a. */
}
#endif
+ size_t parse_offset = i;
algo_name_len = strlen (DIGEST_TYPE_STRING);
if (STREQ_LEN (s + i, DIGEST_TYPE_STRING, algo_name_len))
{
@@ -871,18 +878,15 @@ split_3 (char *s, size_t s_len,
char const *algo_name = &s[i - algo_name_len];
bool length_specified = s[i] == '-';
bool openssl_format = s[i] == '('; /* and no length_specified */
- s[i++] = '\0';
- if (!streq (algo_name, DIGEST_TYPE_STRING))
- return false;
- if (openssl_format)
- s[--i] = '(';
+ if (! openssl_format)
+ i++;
# if HASH_ALGO_BLAKE2
digest_length = DIGEST_MAX_LEN * 8;
# else
digest_length = algorithm_bits[cksum_algorithm];
# endif
- if (length_specified)
+ if (length_specified) /* not base64 */
{
uintmax_t length;
char *siend;
@@ -908,16 +912,21 @@ split_3 (char *s, size_t s_len,
#endif
if (s[i] == ' ')
++i;
- if (s[i] == '(')
+ if (s[i] == '(') /* not base64 */
{
++i;
*binary = 0;
return bsd_split_3 (s + i, s_len - i,
digest, d_len, file_name, escaped_filename);
}
- return false;
+
+ /* Note with --base64 --untagged format, we may have matched a "tag".
+ Even very short digests with: cksum -a blake2b -l24 --untagged
--base64
+ So fallback to checking untagged format if issues detecting tags. */
+ i = parse_offset;
}
+check_untagged:
/* Ignore this line if it is too short.
Each line must have at least 'min_digest_line_length - 1' (or one more, if
the first is a backslash) more characters to contain correct message
digest
diff --git a/tests/cksum/cksum-c.sh b/tests/cksum/cksum-c.sh
index 452f93368..79986d577 100755
--- a/tests/cksum/cksum-c.sh
+++ b/tests/cksum/cksum-c.sh
@@ -45,6 +45,14 @@ echo 'cksum: sha2-bad-length.sum: no properly formatted
checksum lines found' \
> experr || framework_failure_
compare experr err || fail=1
+# Ensure base64 in untagged format that matches tags is supported
+# From coreutils 9.2 - 9.8 inclusive this was not supported
+echo 'SHA1+++++++++++++++++++++++= /dev/null' > tag-prefix.sum \
+ || framework_failure_
+returns_ 1 cksum --check -a sha1 tag-prefix.sum 2>err || fail=1
+echo 'cksum: WARNING: 1 computed checksum did NOT match' \
+ > experr || framework_failure_
+compare experr err || fail=1
# Ensure leading whitespace and \ ignored
sed 's/^/ \\/' CHECKSUMS | cksum --strict -c || fail=1
--
2.51.0