]> git.draconx.ca Git - mpdhacks.git/commitdiff
Fix quoting of single quotes in MPD protocol.
authorNick Bowler <nbowler@draconx.ca>
Sat, 2 May 2020 15:53:28 +0000 (11:53 -0400)
committerNick Bowler <nbowler@draconx.ca>
Tue, 5 May 2020 02:25:12 +0000 (22:25 -0400)
Single quotes have to be quoted in the protocol, but were forgotten.

This is easy enough to fix but isn't helped by the fact that there
are three different copies of this bug on the perl side, so let's
split out that function into a new module and fix it there.

MPDHacks.pm [new file with mode: 0644]
mpdexec.pl
mpdmenu.pl
mpdreload.pl
mpdthumb.sh

diff --git a/MPDHacks.pm b/MPDHacks.pm
new file mode 100644 (file)
index 0000000..2c76c2f
--- /dev/null
@@ -0,0 +1,39 @@
+#!/usr/bin/perl
+#
+# Copyright © 2008,2010,2012,2019-2020 Nick Bowler
+#
+# License GPLv3+: GNU General Public License version 3 or any later version.
+# This is free software: you are free to change and redistribute it.
+# There is NO WARRANTY, to the extent permitted by law.
+
+package MPD;
+
+use strict;
+
+use Exporter;
+our ($VERSION, @ISA, @EXPORT);
+
+$VERSION = 0;
+@ISA = qw(Exporter);
+@EXPORT = qw();
+
+# Returns the argument (or $_ if no arguments are supplied) quoted so that it
+# can be presented as a single command argument to MPD at the protocol level.
+sub escape {
+       my $s = @_[0] // $_;
+
+       # No way to encode literal newlines in the protocol, so we convert
+       # any newlines in the arguments into a space, which can help with
+       # shell quoting.
+       $s =~ s/\n/ /g;
+
+       if ($s =~ /[ \t\\"']/) {
+               $s =~ s/[\\"]/\\$&/g;
+               return "\"$s\"";
+       }
+
+       $s =~ s/^\s*$/"$&"/;
+       return $s;
+}
+
+1;
index 0d477dae465d0923b297fea31d2af3919508d54a..8147f1d185c96fe4aec99a2399de5d63c6a1e279 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env perl
 #
-# Copyright © 2012,2019 Nick Bowler
+# Copyright © 2012,2019-2020 Nick Bowler
 #
 # Send commands to MPD.  Each command-line argument is quoted as necessary
 # so it appears as a single argument at the protocol level.  The result is
@@ -24,6 +24,10 @@ use IO::Socket::INET6;
 
 use Getopt::Long qw(:config gnu_getopt);
 
+use FindBin;
+use lib "$FindBin::Bin";
+use MPDHacks;
+
 my $host = $ENV{MPD_HOST} // "localhost";
 my $port = $ENV{MPD_PORT} // 6600;
 my ($quiet, $binary, $ignore_errors, $download);
@@ -112,21 +116,6 @@ if (!(<$sock> =~ /^OK MPD ([0-9]+)\.([0-9]+)\.([0-9]+)$/)) {
        die "MPD failed to announce version: $!";
 }
 
-sub mpd_escape {
-       ($_) = @_;
-
-       # No way to encode literal newlines in the protocol, so we convert
-       # any newlines in the arguments into a space, which can help with
-       # shell quoting.
-       s/\n/ /g;
-
-       if (/[ \t\\"]/) {
-               s/[\\"]/\\$&/g;
-               return "\"$_\"";
-       }
-       return $_;
-}
-
 sub read_binary {
        my ($count) = @_;
        my $buf;
@@ -185,7 +174,7 @@ sub mpd_exec {
 }
 
 if (@ARGV) {
-       mpd_exec(map { mpd_escape($_) } @ARGV)
+       mpd_exec(map { MPD::escape($_) } @ARGV)
 } else {
        while (<>) {
                chomp;
index a12eb4c39350e6948ed8fd75fd37058d0aef854c..3a84f7855bcda3ddfb60c92d41f06657b2bb45f6 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/perl
 #
-# Copyright © 2008,2010,2012,2019 Nick Bowler
+# Copyright © 2008,2010,2012,2020 Nick Bowler
 #
 # Silly little script to generate an FVWM menu with various bits of MPD
 # status information and controls.
@@ -24,6 +24,9 @@ use Scalar::Util qw(reftype);
 use List::Util qw(any max);
 use FindBin;
 
+use lib "$FindBin::Bin";
+use MPDHacks;
+
 use constant {
        MPD_MJR_MIN => 0,
        MPD_MNR_MIN => 21,
@@ -42,29 +45,10 @@ my ($topmenu, $menu);
 my $mode = "top";
 my %artistids;
 
-# Quotes the argument so that it is presented as a single argument to MPD
-# at the protocol level.  This also works OK for most FVWM arguments.
-sub escape {
-       my $s = @_[0] // $_;
-
-       # No way to encode literal newlines in the protocol, so we
-       # convert any newlines in the arguments into a space, which
-       # can help with quoting.
-       $s =~ s/\n/ /g;
-
-       if (/[ \t\\"]/) {
-               $s =~ s/[\\"]/\\$&/g;
-               return "\"$s\"";
-       }
-
-       $s =~ s/^\s*$/"$&"/;
-       return $s;
-}
-
 # Submit a command to the MPD server; each argument to this function
 # is quoted and sent as a single argument to MPD.
 sub mpd_exec {
-       my $cmd = join(' ', map { escape } @_);
+       my $cmd = join(' ', map { MPD::escape } @_);
 
        print $sock "$cmd\n";
 }
@@ -74,7 +58,7 @@ sub fvwm_cmd_unquoted {
 }
 
 sub fvwm_cmd {
-       fvwm_cmd_unquoted(map { escape } @_);
+       fvwm_cmd_unquoted(map { MPD::escape } @_);
 }
 
 # Quotes the argument in such a way that it is passed unadulterated by
@@ -243,8 +227,8 @@ sub top_track_cover {
                my $cover = mpd_cover_filename($file);
 
                $cover = fvwm_shell_literal($cover // $file);
-               fvwm_cmd_unquoted("AddToMenu", escape($menu),
-                                 escape($entry->{thumb}),
+               fvwm_cmd_unquoted("AddToMenu", MPD::escape($menu),
+                                 MPD::escape($entry->{thumb}),
                                  "Exec", "exec", "geeqie", $cover);
        }
 }
index 4c77e83075ee3ffa10e3c61cc47054154e24c95b..fcbbcc3e5cb122fcbe28edacfb75460d2b7238d6 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env perl
 #
-# Copyright © 2019 Nick Bowler
+# Copyright © 2019-2020 Nick Bowler
 #
 # Replace the current MPD play queue with a saved playlist, by rearranging
 # existing queue entries when possible.  This avoids losing the current
@@ -22,33 +22,18 @@ use IO::Socket::UNIX;
 
 use Getopt::Long qw(:config gnu_getopt);
 
+use FindBin;
+use lib "$FindBin::Bin";
+use MPDHacks;
+
 my $host = $ENV{MPD_HOST} // "localhost";
 my $port = $ENV{MPD_PORT} // 6600;
 my $sock;
 
-# Quotes the argument so that it is presented as a single argument to MPD
-# at the protocol level.
-sub escape {
-       my $s = @_[0] // $_;
-
-       # No way to encode literal newlines in the protocol, so we
-       # convert any newlines in the arguments into a space, which
-       # can help with quoting.
-       $s =~ s/\n/ /g;
-
-       if (/[ \t\\"]/) {
-               $s =~ s/[\\"]/\\$&/g;
-               return "\"$s\"";
-       }
-
-       $s =~ s/^\s*$/"$&"/;
-       return $s;
-}
-
 # Submit a command to the MPD server; each argument to this function
 # is quoted and sent as a single argument to MPD.
 sub mpd_exec {
-       my $cmd = join(' ', map { escape } @_);
+       my $cmd = join(' ', map { MPD::escape } @_);
 
        print $sock "$cmd\n";
 }
@@ -63,7 +48,7 @@ sub get_tracks_in_play_queue {
        while (<$sock>) {
                last if /^OK/;
                die($_) if /^ACK/;
-       
+
                if (/^(\w+): (.*)$/) {
                        if ($1 eq "file") {
                                if (exists($matches{$2})) {
index c48e398e528c5ca16561d916c05c309b2d90cd4e..30f30a16ff6440a8248bb7922d15fd6ebdc971fe 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# Copyright © 2019 Nick Bowler
+# Copyright © 2019-2020 Nick Bowler
 #
 # Generate thumbnails for cover art retrieved from MPD.
 #
@@ -78,7 +78,7 @@ for arg; do
   arg=${arg%/*}/
   shift; set x "$@" "$arg"; shift
 
-  printf '%s\n' "$arg" | sed '/[       \\"]/ {
+  printf '%s\n' "$arg" | sed '/[       \\"'\'']/ {
     s/[\\"]/\\&/g
     s/.*/"&"/
   }