Skip to content

Commit c269f23

Browse files
authored
Merge pull request #61 from yktoo/master
Reimplement quoting as explained in #55
2 parents 4fe899c + 8b40d7a commit c269f23

2 files changed

Lines changed: 12 additions & 17 deletions

File tree

mpd/client.go

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,19 @@ import (
1616
"time"
1717
)
1818

19-
// Quote quotes strings in the format understood by MPD.
19+
// Quote quotes string VALUES in the format understood by MPD.
2020
// See: https://github.com/MusicPlayerDaemon/MPD/blob/master/src/util/Tokenizer.cxx
21-
// NB1: double quotes inside double-quoted literals must be escaped by the caller.
22-
// NB2: this will probably fail should you need to use single quotes outside of double-quoted literal.
21+
// NB: this function shouldn't be used on the PROTOCOL LEVEL because it considers single quotes special chars and
22+
// escapes them.
2323
func quote(s string) string {
2424
q := make([]byte, 2+2*len(s))
2525
i := 0
2626
q[i], i = '"', i+1
2727
for _, c := range []byte(s) {
28-
// We need to quote single/double quotes and backslash
28+
// We need to escape single/double quotes and a backslash by prepending them with a '\'
2929
if c == '"' || c == '\\' || c == '\'' {
30-
// Prepend the char with a backslash
3130
q[i] = '\\'
3231
i++
33-
// For single quotes the backslash must be doubled
34-
if c == '\'' {
35-
q[i] = '\\'
36-
i++
37-
}
3832
}
3933
q[i] = c
4034
i++

mpd/client_test.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -478,13 +478,14 @@ func TestQuote(t *testing.T) {
478478
}{
479479
{`test.ogg`, `"test.ogg"`},
480480
{`test "song".ogg`, `"test \"song\".ogg"`},
481-
{`test with 'single' and "double" quotes`, `"test with \\'single\\' and \"double\" quotes"`},
481+
{`test with 'single' and "double" quotes`, `"test with \'single\' and \"double\" quotes"`},
482+
{`escape \"escaped\"`, `"escape \\\"escaped\\\""`},
483+
{`just a \`, `"just a \\"`},
482484
{`04 - ILL - DECAYED LOVE feat.℃iel.ogg`, `"04 - ILL - DECAYED LOVE feat.℃iel.ogg"`},
483485
// Test case provided at https://www.musicpd.org/doc/html/protocol.html#escaping-string-values.
484-
// NB: it deviates from the original case in that the single quote is left unescaped because the escaping is
485-
// done by quote(). With this approach, the user should only take care of backslash-escaping double quotes
486-
// inside a double-quoted literal.
487-
{`(Artist == "foo'bar\"")`, `"(Artist == \"foo\\'bar\\\"\")"`},
486+
// NB: we don't support quoting in the "protocol level" mode, hence single quotes get the same treatment as
487+
// double quotes and there are 3 backslashes before the single quote, too.
488+
{`(Artist == "foo\'bar\"")`, `"(Artist == \"foo\\\'bar\\\"\")"`},
488489
}
489490
// Run tests
490491
for _, test := range quoteTests {
@@ -495,8 +496,8 @@ func TestQuote(t *testing.T) {
495496
}
496497

497498
func TestQuoteArgs(t *testing.T) {
498-
input := []string{`Artist`, `Nightingale`, `Title`, `\"Don't Go Away\"`}
499-
expected := `"Artist" "Nightingale" "Title" "\\\"Don\\'t Go Away\\\""`
499+
input := []string{`Artist`, `Nightingale`, `Title`, `"Don't Go Away"`}
500+
expected := `"Artist" "Nightingale" "Title" "\"Don\'t Go Away\""`
500501
if got := quoteArgs(input); got != expected {
501502
t.Errorf("quoteArgs(%v) returned %s; expected %s", input, got, expected)
502503
}

0 commit comments

Comments
 (0)