144 lines
4.9 KiB
Diff
144 lines
4.9 KiB
Diff
https://gitlab.freedesktop.org/xdg/xdg-utils/-/issues/252
|
|
https://gitlab.freedesktop.org/xdg/xdg-utils/-/commit/f113a8b997dcb9527b9694d31bddcfa05096aecf
|
|
|
|
From f113a8b997dcb9527b9694d31bddcfa05096aecf Mon Sep 17 00:00:00 2001
|
|
From: Slatian <baschdel@disroot.org>
|
|
Date: Tue, 21 May 2024 04:08:23 +0000
|
|
Subject: [PATCH] Make the desktop_file_to_binary function less likely to fall
|
|
over and do something unexpected.
|
|
|
|
* Uses a shell implementation ( !24) of `which` in the `desktop_file_to_binary` to avoid tripping over unexpected output from `command -v`
|
|
* In addition it also makes the parsing a bit more standards compliant than it previously was.
|
|
* Adds a developer script to easier test internal functions in the xdg-utils-common.in file
|
|
|
|
Fixes: #252
|
|
---
|
|
scripts/test-common-function | 13 ++++++++
|
|
scripts/xdg-utils-common.in | 64 +++++++++++++++++++++++++++++++-----
|
|
2 files changed, 68 insertions(+), 9 deletions(-)
|
|
create mode 100755 scripts/test-common-function
|
|
|
|
diff --git a/scripts/test-common-function b/scripts/test-common-function
|
|
new file mode 100755
|
|
index 0000000..c8af98d
|
|
--- /dev/null
|
|
+++ b/scripts/test-common-function
|
|
@@ -0,0 +1,13 @@
|
|
+#!/bin/sh
|
|
+
|
|
+# This script is for testing internal functions of the xdg-utils-common.in file
|
|
+#
|
|
+# Example ./test-common-function xdg_which echo
|
|
+
|
|
+XDG_UTILS_DEBUG_LEVEL="${XDG_UTILS_DEBUG_LEVEL:-99}"
|
|
+
|
|
+. ./xdg-utils-common.in
|
|
+
|
|
+"$@"
|
|
+
|
|
+exit $?
|
|
diff --git a/scripts/xdg-utils-common.in b/scripts/xdg-utils-common.in
|
|
index f0a1aac..adab368 100644
|
|
--- a/scripts/xdg-utils-common.in
|
|
+++ b/scripts/xdg-utils-common.in
|
|
@@ -51,19 +51,24 @@ binary_to_desktop_file()
|
|
}
|
|
|
|
#-------------------------------------------------------------
|
|
-# map a .desktop file to a binary
|
|
+# map a .desktop file name to its Exec binary
|
|
+# Returns the realpath resolved path to the binary or noting.
|
|
+
|
|
+# desktop_file_to_binary <desktop-file-name>
|
|
desktop_file_to_binary()
|
|
{
|
|
+ DEBUG 1 "desktop_file_to_binary '$1'"
|
|
search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
|
|
desktop="$(basename "$1")"
|
|
IFS=:
|
|
for dir in $search; do
|
|
+ DEBUG 2 "Searching in '$dir/{applications,applnk}'"
|
|
unset IFS
|
|
- [ "$dir" ] && [ -d "$dir/applications" ] || [ -d "$dir/applnk" ] || continue
|
|
+ [ -n "$dir" ] && [ -d "$dir/applications" ] || [ -d "$dir/applnk" ] || continue
|
|
# Check if desktop file contains -
|
|
if [ "${desktop#*-}" != "$desktop" ]; then
|
|
- vendor=${desktop%-*}
|
|
- app=${desktop#*-}
|
|
+ vendor="${desktop%-*}"
|
|
+ app="${desktop#*-}"
|
|
if [ -r "$dir/applications/$vendor/$app" ]; then
|
|
file_path="$dir/applications/$vendor/$app"
|
|
elif [ -r "$dir/applnk/$vendor/$app" ]; then
|
|
@@ -72,18 +77,31 @@ desktop_file_to_binary()
|
|
fi
|
|
if test -z "$file_path" ; then
|
|
for indir in "$dir"/applications/ "$dir"/applications/*/ "$dir"/applnk/ "$dir"/applnk/*/; do
|
|
+ DEBUG 4 "Does file exist? '$indir/$desktop'"
|
|
file="$indir/$desktop"
|
|
if [ -r "$file" ]; then
|
|
- file_path=$file
|
|
+ file_path="$file"
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
if [ -r "$file_path" ]; then
|
|
- # Remove any arguments (%F, %f, %U, %u, etc.).
|
|
- command="$(grep -E "^Exec(\[[^]=]*])?=" "$file_path" | cut -d= -f 2- | first_word)"
|
|
- command="$(command -v "$command")"
|
|
- xdg_realpath "$command"
|
|
+ DEBUG 2 "Checking desktop file '$file_path'"
|
|
+ # Get the command name from the correct Exec
|
|
+ # Note: Ignoring quoting and escape sequences here, see #253
|
|
+ binary="$(awk -F '=' '
|
|
+ /^\[/{ in_entry=0 }
|
|
+ $0 == "[Desktop Entry]"{ in_entry=1 }
|
|
+ in_entry && /^Exec\s*=/ {
|
|
+ sub(/^\s+/,"",$2);
|
|
+ match($2,/^[^ ]+/);
|
|
+ print substr($2,RSTART,RLENGTH)
|
|
+ }' \
|
|
+ < "$file_path" )"
|
|
+ DEBUG 2 "Found command: $binary"
|
|
+ binary="$(xdg_which "$binary")"
|
|
+ DEBUG 2 "Resolved to command to file: '$binary'"
|
|
+ [ -z "$binary" ] || xdg_realpath "$binary"
|
|
return
|
|
fi
|
|
done
|
|
@@ -461,3 +479,31 @@ xdg_realpath()
|
|
;;
|
|
esac
|
|
}
|
|
+
|
|
+#----------------------------------------------------------------------------
|
|
+# The `which` command but as a shell implementation.
|
|
+# Returns either the path of the resolved binary or nothing
|
|
+# because command -v does not always return the path of a command
|
|
+# (builtins, aliases, functions, etc.)
|
|
+
|
|
+# xdg_which <command>
|
|
+xdg_which()
|
|
+{
|
|
+ if [ -z "$1" ] ; then
|
|
+ return 1
|
|
+ elif [ -x "$1" ] ; then
|
|
+ printf "%s\n" "$1"
|
|
+ else
|
|
+ # this should be faster than the real thing because of shell builtins
|
|
+ old_ifs="$IFS"
|
|
+ IFS=:
|
|
+ for p in $PATH ; do
|
|
+ IFS="$old_ifs"
|
|
+ if [ -x "$p/$1" ] ; then
|
|
+ printf "%s\n" "$p/$1"
|
|
+ return
|
|
+ fi
|
|
+ done
|
|
+ return 1
|
|
+ fi
|
|
+}
|
|
--
|
|
GitLab
|