From 16739d20d0c97162c2a19dc47a4fd4318aa12a7e Mon Sep 17 00:00:00 2001 From: Adnan Maolood Date: Fri, 27 Nov 2020 22:26:22 -0500 Subject: [PATCH] Fix escaping of queries --- client.go | 2 +- query.go | 17 +++++++++++++++++ request.go | 3 +++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 query.go diff --git a/client.go b/client.go index c1b3f98..17e7668 100644 --- a/client.go +++ b/client.go @@ -155,7 +155,7 @@ func (c *Client) do(req *Request, via []*Request) (*Response, error) { input, ok := c.GetInput(resp.Meta, resp.Status == StatusSensitiveInput) if ok { req.URL.ForceQuery = true - req.URL.RawQuery = url.QueryEscape(input) + req.URL.RawQuery = QueryEscape(input) return c.do(req, via) } } diff --git a/query.go b/query.go new file mode 100644 index 0000000..3e80e8b --- /dev/null +++ b/query.go @@ -0,0 +1,17 @@ +package gemini + +import ( + "net/url" + "strings" +) + +// QueryEscape properly escapes a string for use in a Gemini URL query. +// It is like url.PathEscape except that it also replaces plus signs with their percent-encoded counterpart. +func QueryEscape(query string) string { + return strings.ReplaceAll(url.PathEscape(query), "+", "%2B") +} + +// QueryUnescape is identical to url.PathUnescape. +func QueryUnescape(query string) (string, error) { + return url.PathUnescape(query) +} diff --git a/request.go b/request.go index b302445..b4c95c2 100644 --- a/request.go +++ b/request.go @@ -51,6 +51,9 @@ func NewRequest(rawurl string) (*Request, error) { // NewRequestFromURL returns a new request for the given URL. // The host is inferred from the URL. +// +// Callers should be careful that the URL query is properly escaped. +// See the documentation for QueryEscape for more information. func NewRequestFromURL(url *url.URL) *Request { host := url.Host if url.Port() == "" {