Fix i3-dmenu-desktop quoting (#5162)
Commit 70f23caa9a
introduced new issues.
Instead of distinguishing " and \, as that commit attempted,
let’s instead keep the level of escaping by escaping each backslash,
just like each double quote.
I tested this with:
# recommended way to quote $ and " in quoted arguments, not ambiguous
Exec=/tmp/logargs "hello \\$PWD \\"and\\" more"
# permitted way to quote $ and " in quoted arguments, but ambiguous
Exec=/tmp/logargs "hello \$PWD \"and\" more"
# permitted way to quote arguments, slightly unusual to quote first arg
Exec="/tmp/logargs" hey
# a complicated shell expression, not ambiguous
Exec=sh -c "if [ -n \\"\\$*\\" ]; then exec /tmp/logargs --alternate-editor= --display=\\"\\$DISPLAY\\" \\"\\$@\\"; else exec /tmp/logargs --alternate-editor= --create-frame; fi" placeholder %F
related to https://github.com/i3/i3/issues/4697 (electrum, original)
related to https://github.com/i3/i3/issues/5152 (phpstorm, breakage)
related to https://github.com/i3/i3/issues/5156 (emacsclient, breakage)
This commit is contained in:
committed by
Michael Stapelberg
parent
3f58d51ec6
commit
decc37eba1
@@ -413,7 +413,7 @@ my $exec = $app->{Exec};
|
||||
my $location = $app->{_Location};
|
||||
|
||||
# Quote as described by “The Exec key”:
|
||||
# https://standards.freedesktop.org/desktop-entry-spec/latest/ar01s06.html
|
||||
# https://standards.freedesktop.org/desktop-entry-spec/latest/ar01s07.html
|
||||
sub quote {
|
||||
my ($str) = @_;
|
||||
$str =~ s/("|`|\$|\\)/\\$1/g;
|
||||
@@ -425,6 +425,17 @@ $choice = quote($choice);
|
||||
$location = quote($location);
|
||||
$name = quote($name);
|
||||
|
||||
# https://standards.freedesktop.org/desktop-entry-spec/latest/ar01s07.html:
|
||||
#
|
||||
# Note that the general escape rule for values of type string states that the
|
||||
# backslash character can be escaped as ("\\") as well and that this escape rule
|
||||
# is applied before the quoting rule. As such, to unambiguously represent a
|
||||
# literal backslash character in a quoted argument in a desktop entry file
|
||||
# requires the use of four successive backslash characters ("\\\\"). Likewise, a
|
||||
# literal dollar sign in a quoted argument in a desktop entry file is
|
||||
# unambiguously represented with ("\\$").
|
||||
$exec =~ s/\\\\/\\/g;
|
||||
|
||||
# Remove deprecated field codes, as the spec dictates.
|
||||
$exec =~ s/%[dDnNvm]//g;
|
||||
|
||||
@@ -481,9 +492,10 @@ EOT
|
||||
# starts with a double quote ("), everything is parsed as-is until the next
|
||||
# double quote which is NOT preceded by a backslash (\).
|
||||
#
|
||||
# Therefore, we escape all double quotes (") by replacing them with \"
|
||||
$exec =~ s/\\"/\\\\\\"/g;
|
||||
$exec =~ s/([^\\])"/$1\\"/g;
|
||||
# Therefore, we escape all double quotes (") by replacing them with \".
|
||||
# To not change the meaning of any double quote, backslashes need to be
|
||||
# escaped as well.
|
||||
$exec =~ s/(["\\])/\\$1/g;
|
||||
|
||||
if (exists($app->{StartupNotify}) && !$app->{StartupNotify}) {
|
||||
$nosn = '--no-startup-id';
|
||||
|
Reference in New Issue
Block a user