From a9cbb644c59311954660ad4fd7d3314c8fdfaa89 Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Sun, 12 Sep 2021 14:11:59 +1000 Subject: [PATCH] Fix http announce of infohash containing ' ' bytes (#591) Fixes https://github.com/anacrolix/torrent/issues/534. --- tracker/http/http.go | 5 ++++- tracker/http/http_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/tracker/http/http.go b/tracker/http/http.go index 15306ca9..f45cc7c2 100644 --- a/tracker/http/http.go +++ b/tracker/http/http.go @@ -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 { diff --git a/tracker/http/http_test.go b/tracker/http/http_test.go index f0066de7..878ca058 100644 --- a/tracker/http/http_test.go +++ b/tracker/http/http_test.go @@ -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") +} -- 2.44.0