]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
stat: don't check QUOTING_STYLE when --printf %%N is used
authorCollin Funk <collin.funk1@gmail.com>
Fri, 27 Feb 2026 04:39:12 +0000 (20:39 -0800)
committerCollin Funk <collin.funk1@gmail.com>
Fri, 27 Feb 2026 05:20:37 +0000 (21:20 -0800)
* NEWS: Mention the fix.
* src/stat.c (main): Only check QUOTING_STYLE if there is a %N that is
not preceded by a percentage sign.
* tests/stat/stat-fmt.sh: Add some test cases.

NEWS
src/stat.c
tests/stat/stat-fmt.sh

diff --git a/NEWS b/NEWS
index a01a13acc234168be0ffcd80ef2e03424cf88e1b..473b7c21d87498df1989d8c5e871438439691c69 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,10 @@ GNU coreutils NEWS                                    -*- outline -*-
   when operating in deep paths longer than twice the system PATH_MAX.
   [bug introduced in coreutils-9.6]
 
+  'stat --printf=%%N' no longer performs unnecessary checks of the QUOTING_STYLE
+  environment variable.
+  [bug introduced in coreutils-8.26]
+
 ** New Features
 
   'date --date' now parses dot delimited dd.mm.yy format common in Europe.
index 128fafd3152ba3835f8ce3a3b943832f8c374d67..1e350152572bbb1f462a4309b81466313b73c5e9 100644 (file)
@@ -1970,7 +1970,16 @@ main (int argc, char *argv[])
 
   if (format)
     {
-      if (strstr (format, "%N"))
+      bool need_quoting_style = false;
+      for (char const *p = format; (p = strchr (p, '%')); ++p)
+        {
+          if (p[1] == 'N' && (p == format || p[-1] != '%'))
+            {
+              need_quoting_style = true;
+              break;
+            }
+        }
+      if (need_quoting_style)
         getenv_quoting_style ();
       format2 = format;
     }
index 1c208e378602b3e30d085603a92cd445e22e9580..066c481337d4bbfc2e3e1ebb2ab5b86dade5b8ff 100755 (executable)
@@ -40,6 +40,36 @@ cat <<\EOF >exp
 EOF
 compare exp out || fail=1
 
+# Check the behavior with invalid values of QUOTING_STYLE.
+for style in '' 'abcdef'; do
+  QUOTING_STYLE="$style" stat -c%N \' > out 2> err || fail=1
+  cat <<\EOF > exp-out || framework_failure_
+"'"
+EOF
+  cat <<EOF > exp-err || framework_failure_
+stat: ignoring invalid value of environment variable QUOTING_STYLE: '$style'
+EOF
+  compare exp-out out || fail=1
+  compare exp-err err || fail=1
+  # coreutils-9.10 and earlier would unnecessarily check QUOTING_STYLE in
+  # these cases.
+  for format in '%%N' 'abc%%Ndef' 'abc%%Ndef%%N'; do
+    QUOTING_STYLE="$style" stat -c"$format" \' > out 2> err || fail=1
+    printf "$format\n" > exp-out || framework_failure_
+    compare exp-out out || fail=1
+    compare /dev/null err || fail=1
+  done
+done
+
+# Check the behavior with %N following %%N.
+stat -cabc%%Ndef%N \' > out || fail=1
+QUOTING_STYLE=locale stat -cabc%%Ndef%N \' >> out || fail=1
+cat <<\EOF >exp
+abc%Ndef"'"
+abc%Ndef'\''
+EOF
+compare exp out || fail=1
+
 # ensure %H and %L modifiers are handled
 stat -c '%r %R %Hd,%Ld %Hr,%Lr' . > out || fail=1
 grep -F '?' out && fail=1