summaryrefslogtreecommitdiff
path: root/x11-misc/xdg-utils/files/xdg-utils-1.2.1-xdg-mime-default.patch
blob: 8efcdca1cfeff63658a33f04d92800527d9d6e64 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
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