From: Pádraig Brady
Date: Mon, 6 Oct 2025 18:41:24 +0000 (+0100) Subject: cksum: fix --check with untagged base64 format with tag matches X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=463925761048ec9ccb5742479ef7963f378b7f05;p=thirdparty%2Fcoreutils.git cksum: fix --check with untagged base64 format with tag matches * 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. This might happen in 1 in every 64K files. Note we remove the modification of string S (and redundant streq) in the tag matching, as that was not needed since v8.32-223-g217cd278e. * tests/cksum/cksum-c.sh: Add a test case. * NEWS: Mention the bug fix. --- diff --git a/NEWS b/NEWS index b49c2ea80f..aa7c13f97c 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 45c13e33c6..d2e6e212aa 100644 --- a/src/digest.c +++ b/src/digest.c @@ -847,43 +847,42 @@ 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)) { i += algo_name_len; #if HASH_ALGO_BLAKE2 || HASH_ALGO_CKSUM - /* Terminate and match algorithm name. */ - 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 HASH_ALGO_BLAKE2 digest_length = DIGEST_MAX_LEN * 8; # else digest_length = algorithm_bits[cksum_algorithm]; # endif - if (length_specified) + if (s[i] == '-') /* length specified. Not base64 */ { + ++i; uintmax_t length; char *siend; if (xstrtoumax (s + i, &siend, 0, &length, nullptr) != LONGINT_OK) @@ -908,14 +907,18 @@ 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; } /* Ignore this line if it is too short. diff --git a/tests/cksum/cksum-c.sh b/tests/cksum/cksum-c.sh index 452f93368d..79986d5778 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