From: Philippe Antoine Date: Tue, 4 Jun 2024 13:24:18 +0000 (+0200) Subject: smtp: respect quotes for to and cc logging X-Git-Tag: suricata-7.0.6~17 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=897fc4ccea7dcdf37b48808a3e1ae3a656737867;p=thirdparty%2Fsuricata.git smtp: respect quotes for to and cc logging When splitting the field over commas, skip the commas which are innside quotes Ticket: 7060 Not a direct backport, but heavily inspired by new rust code handling it --- diff --git a/src/output-json-email-common.c b/src/output-json-email-common.c index 19afe78b7c..c96188e487 100644 --- a/src/output-json-email-common.c +++ b/src/output-json-email-common.c @@ -97,27 +97,49 @@ static inline char *SkipWhiteSpaceTill(char *p, char *savep) static bool EveEmailJsonArrayFromCommaList(JsonBuilder *js, const uint8_t *val, size_t len) { - char *savep = NULL; - char *p; - char *sp; - char *to_line = BytesToString((uint8_t *)val, len); - if (likely(to_line != NULL)) { - p = strtok_r(to_line, ",", &savep); - if (p == NULL) { - SCFree(to_line); - return false; - } - sp = SkipWhiteSpaceTill(p, savep); - jb_append_string(js, sp); - while ((p = strtok_r(NULL, ",", &savep)) != NULL) { - sp = SkipWhiteSpaceTill(p, savep); - jb_append_string(js, sp); + bool has_not_empty_field = false; + size_t start = 0; + int state = 0; + + for (size_t i = 0; i < len; i++) { + switch (state) { + case 0: + if (val[i] == ' ' || val[i] == '\t') { + // skip leading space + start += 1; + } else if (val[i] == '"') { + // quoted state + state = 2; + } else { + // field + state = 1; + } + break; + case 1: // field + if (val[i] == ',') { + if (i > start) { + jb_append_string_from_bytes(js, val + start, i - start); + has_not_empty_field = true; + } + start = i + 1; + state = 0; + } else if (val[i] == '"') { + // quoted + state = 2; + } + break; + case 2: // quoted + if (val[i] == '"') { + // out of quotes, back to field + state = 1; + } } - } else { - return false; } - SCFree(to_line); - return true; + if (len > start) { + jb_append_string_from_bytes(js, val + start, len - start); + has_not_empty_field = true; + } + return has_not_empty_field; } static void EveEmailLogJSONMd5(OutputJsonEmailCtx *email_ctx, JsonBuilder *js, SMTPTransaction *tx)