diff --git a/common.c b/common.c index 423bb7e..21842ad 100644 --- a/common.c +++ b/common.c @@ -741,6 +741,7 @@ struct ctcp_chunk LIST_HEADER (struct ctcp_chunk) bool is_extended; ///< Is this a tagged extended message? + bool is_partial; ///< Unterminated extended message struct str tag; ///< The tag, if any struct str text; ///< Message contents }; @@ -838,6 +839,9 @@ ctcp_parse (const char *message) struct ctcp_chunk *result = NULL, *result_tail = NULL; + // According to the original CTCP specification we should use + // ctcp_intra_decode() on all parts, however no one seems to + // use that and it breaks normal text with backslashes size_t start = 0; bool in_ctcp = false; for (size_t i = 0; i < m.len; i++) @@ -865,15 +869,17 @@ ctcp_parse (const char *message) LIST_APPEND_WITH_TAIL (result, result_tail, chunk); } - // Finish the last text part. We ignore unended tagged chunks. - // TODO: don't ignore them, e.g. a /me may get cut off - if (!in_ctcp && start != m.len) + // Finish the last part. Unended tagged chunks are marked as such. + if (start != m.len) { struct ctcp_chunk *chunk = ctcp_chunk_new (); - // According to the original CTCP specification we should use - // ctcp_intra_decode() but no one seems to use that and it breaks - // normal text with backslashes - str_append_data (&chunk->text, m.str + start, m.len - start); + if (in_ctcp) + { + ctcp_parse_tagged (m.str + start, m.len - start, chunk); + chunk->is_partial = true; + } + else + str_append_data (&chunk->text, m.str + start, m.len - start); LIST_APPEND_WITH_TAIL (result, result_tail, chunk); }