From 57d46e6a23398b0a4f3f3f291f8ea10242e9f17f Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Thu, 31 Aug 2023 17:18:09 +0300 Subject: [PATCH] Don't escape + in user ID localparts --- id/userid.go | 6 +++--- id/userid_test.go | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/id/userid.go b/id/userid.go index 0522b54c..3aae3b21 100644 --- a/id/userid.go +++ b/id/userid.go @@ -72,7 +72,7 @@ func (userID UserID) URI() *MatrixURI { } } -var ValidLocalpartRegex = regexp.MustCompile("^[0-9a-z-.=_/]+$") +var ValidLocalpartRegex = regexp.MustCompile("^[0-9a-z-.=_/+]+$") // ValidateUserLocalpart validates a Matrix user ID localpart using the grammar // in https://matrix.org/docs/spec/appendices#user-identifier @@ -132,7 +132,7 @@ func escape(buf *bytes.Buffer, b byte) { } func shouldEncode(b byte) bool { - return b != '-' && b != '.' && b != '_' && !(b >= '0' && b <= '9') && !(b >= 'a' && b <= 'z') && !(b >= 'A' && b <= 'Z') + return b != '-' && b != '.' && b != '_' && b != '+' && !(b >= '0' && b <= '9') && !(b >= 'a' && b <= 'z') && !(b >= 'A' && b <= 'Z') } func shouldEscape(b byte) bool { @@ -140,7 +140,7 @@ func shouldEscape(b byte) bool { } func isValidByte(b byte) bool { - return isValidEscapedChar(b) || (b >= '0' && b <= '9') || b == '.' || b == '=' || b == '-' + return isValidEscapedChar(b) || (b >= '0' && b <= '9') || b == '.' || b == '=' || b == '-' || b == '+' } func isValidEscapedChar(b byte) bool { diff --git a/id/userid_test.go b/id/userid_test.go index a18dd314..359bc687 100644 --- a/id/userid_test.go +++ b/id/userid_test.go @@ -66,8 +66,8 @@ func TestUserID_ParseAndValidate_NotLong(t *testing.T) { } func TestUserIDEncoding(t *testing.T) { - const inputLocalpart = "This localpart contains IlLeGaL chäracters 🚨" - const encodedLocalpart = "_this=20localpart=20contains=20_il_le_ga_l=20ch=c3=a4racters=20=f0=9f=9a=a8" + const inputLocalpart = "This local+part contains IlLeGaL chäracters 🚨" + const encodedLocalpart = "_this=20local+part=20contains=20_il_le_ga_l=20ch=c3=a4racters=20=f0=9f=9a=a8" const inputServerName = "example.com" userID := id.NewEncodedUserID(inputLocalpart, inputServerName) parsedLocalpart, parsedServerName, err := userID.ParseAndValidate()