From 076277938e74e5eb553ab2aa6bdf9935f6986185 Mon Sep 17 00:00:00 2001 From: IllusionMan1212 Date: Sun, 19 Feb 2023 05:49:33 +0200 Subject: [PATCH] fix/test: properly parse tag values with escape characters. all tests pass --- irc/parser/parser.go | 46 ++++++++++++++++++++++++++++++++++++++- irc/parser/parser_test.go | 6 ----- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/irc/parser/parser.go b/irc/parser/parser.go index c2f8fa0..d09dfb7 100644 --- a/irc/parser/parser.go +++ b/irc/parser/parser.go @@ -39,6 +39,33 @@ func (m *IRCMessage) setTimestamp() { m.Timestamp = fmt.Sprintf("[%02d:%02d]", now.Hour(), now.Minute()) } +func escapeCharacters(char rune) string { + switch char { + case 's': + return " " + case 'n': + return "\n" + case 'r': + return "\r" + case 'b': + return "\b" + case 't': + return "\t" + case 'f': + return "\f" + case ':': + return ";" + case '\\': + fallthrough + case '\'': + fallthrough + case '"': + fallthrough + default: + return string(char) + } +} + func parseTags(rawTags string) Tags { tags := make(Tags, 0) rawTagsSlice := strings.Split(rawTags, ";") @@ -51,7 +78,24 @@ func parseTags(rawTags string) Tags { // we need to make sure a "value" exists before accessing str[1] if len(str) > 1 { - value = str[1] + rawValue := str[1] + for idx := 0; idx < len(rawValue); { + // if we have a backslash at the end of the string + // we need to ignore it + if idx == len(rawValue)-1 && rawValue[idx] == '\\' { + idx += 2 + continue + } + + if rawValue[idx] == '\\' { + value += escapeCharacters(rune(rawValue[idx+1])) + idx += 2 + continue + } + + value += string(rawValue[idx]) + idx++ + } } tags[key] = value diff --git a/irc/parser/parser_test.go b/irc/parser/parser_test.go index 548a9d5..fbbcd64 100644 --- a/irc/parser/parser_test.go +++ b/irc/parser/parser_test.go @@ -341,7 +341,6 @@ func TestParser(t *testing.T) { } }) - // TODO: fails t.Run("Test escaped tags", func(t *testing.T) { testMessage := "@a=b\\\\and\\nk;c=72\\s45;d=gh\\:764 foo" ircMessage, valid := ParseIRCMessage(testMessage) @@ -401,7 +400,6 @@ func TestParser(t *testing.T) { } }) - // TODO: FAIL t.Run("Test single param with preceeding :", func(t *testing.T) { testMessage := ":src JOIN :#chan" ircMessage, valid := ParseIRCMessage(testMessage) @@ -652,7 +650,6 @@ func TestParser(t *testing.T) { } }) - // TODO: FAIL t.Run("Test yaml encoding with slashes", func(t *testing.T) { testMessage := "@foo=\\\\\\\\\\:\\\\s\\s\\r\\n COMMAND" ircMessage, valid := ParseIRCMessage(testMessage) @@ -749,7 +746,6 @@ func TestParser(t *testing.T) { } }) - // TODO: FAIL t.Run("Test tags. they should be parsed char-at-a-time", func(t *testing.T) { testMessage := "@tag1=value\\\\ntest COMMAND" ircMessage, valid := ParseIRCMessage(testMessage) @@ -771,7 +767,6 @@ func TestParser(t *testing.T) { } }) - // TODO: FAIl t.Run("Test tag escape for char that doesn't need it", func(t *testing.T) { testMessage := "@tag1=value\\1 COMMAND" ircMessage, valid := ParseIRCMessage(testMessage) @@ -789,7 +784,6 @@ func TestParser(t *testing.T) { } }) - // TODO: FAIL t.Run("Test slash at end of tag", func(t *testing.T) { testMessage := "@tag1=value1\\ COMMAND" ircMessage, valid := ParseIRCMessage(testMessage)