xdg-utils/0008-xdg-open-safer-xdg-open-BR89130.patch

115 lines
4.0 KiB
Diff

From 13d9b0cac97e438bf7dc06452ee7fb3480907d88 Mon Sep 17 00:00:00 2001
From: Rex Dieter <rdieter@math.unl.edu>
Date: Fri, 20 Feb 2015 15:54:46 -0600
Subject: [PATCH 8/8] xdg-open: safer xdg-open (BR89130)
inspired by patch from Vincent Bernat <bernat@debian.org>
---
ChangeLog | 3 +++
scripts/xdg-open.in | 65 ++++++++++++++++++++++++++++++++---------------------
2 files changed, 43 insertions(+), 25 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 9a01f82..0c0ab97 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
=== xdg-utils 1.1.x ===
+2015-02-20 Rex Dieter <rdieter@fedoraproject.org>
+ * xdg-open: safer xdg-open (BR89130), inspired by patch from Vincent Bernat <bernat@debian.org>
+
2015-01-19 Rex Dieter <rdieter@fedoraproject.org>
* xdg-open: better fix for command injection vulnerability (BR66670)
* xdg-open is extremely slow because get_key executes grep unnecessarily (BR88524)
diff --git a/scripts/xdg-open.in b/scripts/xdg-open.in
index ee2889e..074ba6f 100644
--- a/scripts/xdg-open.in
+++ b/scripts/xdg-open.in
@@ -161,7 +161,7 @@ search_desktop_file()
{
local default="$1"
local dir="$2"
- local arg="$3"
+ local target="$3"
local file=""
# look for both vendor-app.desktop, vendor/app.desktop
@@ -174,34 +174,49 @@ search_desktop_file()
if [ -r "$file" ] ; then
command="$(get_key "${file}" "Exec" | first_word)"
command_exec=`which $command 2>/dev/null`
- arguments="$(get_key "${file}" "Exec" | last_word)"
- arg_one="`echo "$arg" | sed 's/[&*\\]/\\\\&/g'`"
icon="$(get_key "${file}" "Icon")"
- if [ "${icon}" != "" ]
- then
- icon="--icon '${icon}'"
- else
- icon="''"
- fi
# FIXME: Actually LC_MESSAGES should be used as described in
# http://standards.freedesktop.org/desktop-entry-spec/latest/ar01s04.html
- localised_name="'$(get_key "${file}" "Name")'"
- arguments_exec="$(echo "$arguments" | sed -e 's*%[fFuU]*'"$arg_one"'*g' \
- -e 's*%i*'"$icon"'*g' \
- -e 's*%c*'"$localised_name"'*g')"
-
- if [ -x "$command_exec" ] ; then
- if echo "$arguments" | grep -iq '%[fFuU]' ; then
- echo START "$command_exec" "$arguments_exec"
- eval "'$command_exec'" "'$arguments_exec'"
- else
- echo START "$command_exec" "$arguments_exec" "$arg"
- eval "'$command_exec'" "'$arguments_exec'" "'$arg'"
- fi
+ localised_name="$(get_key "${file}" "Name")"
+ set -- $(get_key "${file}" "Exec" | last_word)
+ # We need to replace any occurrence of "%f", "%F" and
+ # the like by the target file. We examine each
+ # argument and append the modified argument to the
+ # end then shift.
+ local args=$#
+ local replaced=0
+ while [ $args -gt 0 ]; do
+ case $1 in
+ %[c])
+ replaced=1
+ arg="${localised_name}"
+ shift
+ set -- "$@" "$arg"
+ ;;
+ %[fFuU])
+ replaced=1
+ arg="$(echo $target | sed 's/[&*\\]/\\\\&/g')"
+ shift
+ set -- "$@" "$arg"
+ ;;
+ %[i])
+ replaced=1
+ shift
+ set -- "$@" "--icon" "$icon"
+ ;;
+ *)
+ arg="$1"
+ shift
+ set -- "$@" "$arg"
+ ;;
+ esac
+ args=$(( $args - 1 ))
+ done
+ [ $replaced -eq 1 ] || set -- "$@" "$target"
+ "$command_exec" "$@"
- if [ $? -eq 0 ]; then
- exit_success
- fi
+ if [ $? -eq 0 ]; then
+ exit_success
fi
fi
--
1.9.3