]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Fix http announce of infohash containing ' ' bytes (#591)
authorMatt Joiner <anacrolix@gmail.com>
Sun, 12 Sep 2021 04:11:59 +0000 (14:11 +1000)
committerGitHub <noreply@github.com>
Sun, 12 Sep 2021 04:11:59 +0000 (14:11 +1000)
Fixes https://github.com/anacrolix/torrent/issues/534.

tracker/http/http.go
tracker/http/http_test.go

index 15306ca974eaa0656318ab4eab533dbd9ad4f35c..f45cc7c2e6ec2f17f4702c11acc215e3493d4c9d 100644 (file)
@@ -11,6 +11,7 @@ import (
        "net/http"
        "net/url"
        "strconv"
+       "strings"
 
        "github.com/anacrolix/missinggo/httptoo"
        "github.com/anacrolix/torrent/bencode"
@@ -61,7 +62,9 @@ func setAnnounceParams(_url *url.URL, ar *AnnounceRequest, opts AnnounceOpt) {
        }
        doIp("ipv4", opts.ClientIp4)
        doIp("ipv6", opts.ClientIp6)
-       _url.RawQuery = q.Encode()
+       // We're operating purely on query-escaped strings, where + would have already been encoded to
+       // %2B, and + has no other special meaning. See https://github.com/anacrolix/torrent/issues/534.
+       _url.RawQuery = strings.ReplaceAll(q.Encode(), "+", "%20")
 }
 
 type AnnounceOpt struct {
index f0066de75b17e4933d5105e34436be1955e502cb..878ca0586828af4da0115536eb1cf75ecbf13872 100644 (file)
@@ -1,9 +1,12 @@
 package http
 
 import (
+       "net/url"
        "testing"
 
        "github.com/anacrolix/torrent/bencode"
+       "github.com/anacrolix/torrent/tracker/udp"
+       qt "github.com/frankban/quicktest"
        "github.com/stretchr/testify/assert"
        "github.com/stretchr/testify/require"
 )
@@ -48,3 +51,24 @@ func TestUnmarshalHttpResponsePeers6NotCompact(t *testing.T) {
                &hr,
        ))
 }
+
+// Checks that infohash bytes that correspond to spaces are escaped with %20 instead of +. See
+// https://github.com/anacrolix/torrent/issues/534
+func TestSetAnnounceInfohashParamWithSpaces(t *testing.T) {
+       someUrl := &url.URL{}
+       ihBytes := [20]uint8{
+               0x2b, 0x76, 0xa, 0xa1, 0x78, 0x93, 0x20, 0x30, 0xc8, 0x47,
+               0xdc, 0xdf, 0x8e, 0xae, 0xbf, 0x56, 0xa, 0x1b, 0xd1, 0x6c}
+       setAnnounceParams(
+               someUrl,
+               &udp.AnnounceRequest{
+                       InfoHash: ihBytes,
+               },
+               AnnounceOpt{})
+       t.Logf("%q", someUrl)
+       qt.Assert(t, someUrl.Query().Get("info_hash"), qt.Equals, string(ihBytes[:]))
+       qt.Check(t,
+               someUrl.String(),
+               qt.Contains,
+               "info_hash=%2Bv%0A%A1x%93%200%C8G%DC%DF%8E%AE%BFV%0A%1B%D1l")
+}