* tests/misc/exec-bad-unicode.sh: New file.
* tests/local.mk (all_tests): Add the new test.
---
 tests/local.mk                 |   1 +
 tests/misc/exec-bad-unicode.sh | 109 +++++++++++++++++++++++++++++++++
 2 files changed, 110 insertions(+)
 create mode 100755 tests/misc/exec-bad-unicode.sh

diff --git a/tests/local.mk b/tests/local.mk
index dbf5789df..9b9d25a4d 100644
--- a/tests/local.mk
+++ b/tests/local.mk
@@ -186,6 +186,7 @@ all_tests =                                 \
   tests/misc/read-errors.sh                    \
   tests/misc/responsive.sh                     \
   tests/misc/no-fork.sh                                \
+  tests/misc/exec-bad-unicode.sh               \
   tests/misc/traversal-missing.sh              \
   tests/misc/tty-quoting.sh                    \
   tests/misc/uname-labeled.sh                  \
diff --git a/tests/misc/exec-bad-unicode.sh b/tests/misc/exec-bad-unicode.sh
new file mode 100755
index 000000000..3a72189d3
--- /dev/null
+++ b/tests/misc/exec-bad-unicode.sh
@@ -0,0 +1,109 @@
+#!/bin/sh
+# Test that various programs can execute a program name with invalid
+# Unicode characters.
+
+# Copyright (C) 2026 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+
+script="$(bad_unicode)"
+
+# Create a program with invalid Unicode in its name.
+cat <<EOF >"$script"
+#!$SHELL
+echo "\$@"
+EOF
+test $? = 0 || skip_ 'bad unicode not supported in shell or file system'
+chmod u+x "$script" || framework_failure_
+
+# Check that it can be executed.
+./"$script" "$script" >exp \
+  || skip_ 'cannot execute a file name with invalid unicode'
+
+# List of programs that execute another command.
+printf '%s' '\
+chroot --skip-chdir /
+env
+nice
+nohup
+runcon '"$(id -Z)"'
+stdbuf -oL
+timeout 10
+' |
+sort -k 1b,1 > all_executors || framework_failure_
+
+printf '%s\n' $built_programs |
+sort -k 1b,1 > built_programs || framework_failure_
+
+join all_executors built_programs > built_executors || framework_failure_
+
+for loc in C "$LOCALE_FR" "$LOCALE_FR_UTF8"; do
+  test -z "$loc" && continue
+  while read executor; do
+    LC_ALL="$loc" $executor ./"$script" "$script" >out 2>err
+    if test $? = 0; then
+      compare exp out || fail=1
+      compare /dev/null err || fail=1
+    else
+      case "$executor" in
+        runcon*)
+          grep 'runcon: runcon may be used only on a SELinux kernel' err
+          ;;
+        chroot*)
+          ! uid_is_privileged_
+          ;;
+        *)
+          false
+          ;;
+      esac || { cat err; fail=1; }
+    fi
+  done < built_executors
+done
+
+# Test 'sort --compress-program'.
+cat <<EOF >"$script" || framework_failure_
+#!$SHELL
+tr 41 14
+touch ok
+EOF
+seq -w 2000 >exp || framework_failure_
+tac exp >in || framework_failure_
+for loc in C "$LOCALE_FR" "$LOCALE_FR_UTF8"; do
+  test -z "$loc" && continue
+  LC_ALL="$loc" sort -S 1k --compress-program=./"$script" in >out 2>err \
+    || fail=1
+  compare exp out || fail=1
+  compare /dev/null err || fail=1
+  test -f ok || fail=1
+done
+
+# Test 'install --strip --strip-program'.
+cat <<EOF >"$script" || framework_failure_
+#!$SHELL
+sed s/b/B/ \$1 > \$1.t && mv \$1.t \$1
+EOF
+for loc in C "$LOCALE_FR" "$LOCALE_FR_UTF8"; do
+  test -z "$loc" && continue
+  echo abc > src || framework_failure_
+  echo aBc > exp || framework_failure_
+  ginstall src dest -s --strip-program=./"$script" >out 2>err || fail=1
+  compare /dev/null out || fail=1
+  compare /dev/null err || fail=1
+  compare exp dest || fail=1
+  rm -f dest || framework_failure_
+done
+
+Exit $fail
-- 
2.55.0


Reply via email to