]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
cksum: escape filenames with a leading '\' in --check status
authorPádraig Brady <P@draigBrady.com>
Sat, 1 Jul 2023 16:01:18 +0000 (17:01 +0100)
committerPádraig Brady <P@draigBrady.com>
Tue, 11 Jul 2023 11:16:41 +0000 (12:16 +0100)
* src/digest.c (digest_check): Also escape in the case that the
file name contains '\'.
* tests/cksum/md5sum-bsd.sh: Add a test case.
* doc/coreutils.texi (md5um invocation): Clarify escaping operation.
* NEWS: Mention the bug fix.
Fixes https://bugs.gnu.org/64392

NEWS
doc/coreutils.texi
src/digest.c
tests/cksum/md5sum-bsd.sh

diff --git a/NEWS b/NEWS
index a3ce05e6328beba393a5af4bfa88599a754b0e99..35ae02a8eb3fb61b5f682e2e90e9b3cb4e339d71 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -19,6 +19,11 @@ GNU coreutils NEWS                                    -*- outline -*-
   cksum again diagnoses read errors in its default CRC32 mode.
   [bug introduced in coreutils-9.0]
 
+  'cksum --check' now ensures filenames with a leading backslash character
+  are escaped appropriately in the status output.
+  This also applies to the standalone checksumming utilities.
+  [bug introduced in coreutils-8.25]
+
   dd again supports more than two multipliers for numbers.
   Previously numbers of the form '1024x1024x32' gave "invalid number" errors.
   [bug introduced in coreutils-9.1]
index d6918e8ad5ec65c5ccda8799cf9801b1b4431e9a..c3673fd3f1da89111c398978cfd19539a811c495 100644 (file)
@@ -4162,6 +4162,8 @@ Without @option{--zero}, if @var{file} contains a backslash, newline,
 or carriage return, the line is started with a backslash, and each
 problematic character in the file name is escaped with a backslash,
 making the output unambiguous even in the presence of arbitrary file names.
+Since the backslash character itself is escaped, any other backslash
+escape sequences are reserved for future use.
 
 If @var{file} is omitted or specified as @samp{-}, standard input is read.
 
@@ -4258,8 +4260,8 @@ indicating there was a failure.
 @cindex BSD output
 Output BSD style checksums, which indicate the checksum algorithm used.
 As a GNU extension, if @option{--zero} is not used, file names with problematic
-characters are escaped as described above, with the same escaping indicator of
-@samp{\} at the start of the line, being used.
+characters are escaped as described above, using the same escaping indicator of
+@samp{\} at the start of the line, as used with the other output format.
 The @option{--tag} option implies binary mode, and is disallowed with
 @option{--text} mode as supporting that would unnecessarily complicate
 the output format, while providing little benefit.
index 4c9c477dd4d3c4e773a42f042c682f869871c739..5490f96a49e1bf4b2e3ca1d36047fb5ca9cce349 100644 (file)
@@ -560,6 +560,16 @@ or equivalent standalone program.\
   exit (status);
 }
 
+/* Given a string S, return TRUE if it contains problematic characters
+   that need escaping.  Note we escape '\' itself to provide some forward
+   compat to introduce escaping of other characters.  */
+
+static bool
+problematic_chars (char const *s)
+{
+  return strchr (s, '\\') || strchr (s, '\n') || strchr (s, '\r');
+}
+
 #define ISWHITE(c) ((c) == ' ' || (c) == '\t')
 
 /* Given a file name, S of length S_LEN, that is not NUL-terminated,
@@ -1029,12 +1039,9 @@ output_file (char const *file, int binary_file, void const *digest,
 
   unsigned char const *bin_buffer = digest;
 
-  /* Output a leading backslash if the file name contains problematic chars.
-     Note we escape '\' itself to provide some forward compat to introduce
-     escaping of other characters.  */
-  bool needs_escape = delim == '\n' && (strchr (file, '\\')
-                                        || strchr (file, '\n')
-                                        || strchr (file, '\r'));
+  /* Output a leading backslash if the file name contains problematic chars.  */
+  bool needs_escape = delim == '\n' && problematic_chars (file);
+
   if (needs_escape)
     putchar ('\\');
 
@@ -1206,9 +1213,7 @@ digest_check (char const *checkfile_name)
         {
           bool ok;
           bool missing;
-          /* Only escape in the edge case producing multiple lines,
-             to ease automatic processing of status output.  */
-          bool needs_escape = ! status_only && strchr (filename, '\n');
+          bool needs_escape = ! status_only && problematic_chars (filename);
 
           properly_formatted_lines = true;
 
index 5fe9b2fc93bee47f50cc4344923d7bf34015457e..1581b8ac88e5689abc077abc781f96b87ea1e19d 100755 (executable)
@@ -74,13 +74,17 @@ md5sum --strict -c check.md5 || fail=1
 # with the GNU extension of escaped newlines
 nl='
 '
-tab='  '
+t='    '
 rm check.md5
-for i in 'a\b' 'a\' "a${nl}b" "a${tab}b"; do
+for i in 'a\b' 'a\' '\a' "a${nl}b" "a${t}b"; do
   : > "$i"
   md5sum --tag "$i" >> check.md5 || fail=1
 done
-md5sum --strict -c check.md5 || fail=1
+md5sum --strict -c check.md5 > out || fail=1
+printf '%s: OK\n' '\a\\b' '\a\\' '\\\a' '\a\nb' "a${t}b" > exp ||
+  framework_failure_
+compare exp out || fail=1
+
 
 # Ensure BSD traditional format with GNU extension escapes
 # is in the expected format