On 04/10/2026 05:08, Collin Funk wrote:
* 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
Very nice!
Other tests check for: test "$LOCALE_FR_UTF8" != "none
So this probably needs:
{ test -z "$loc" || test "$loc" = 'none'; } && continue
It seems like `split --filter` would be good to include
thanks,
Padraig