diff --git a/src/app-layer-ftp.c b/src/app-layer-ftp.c index f1bc87e077..fbcca8b5cf 100644 --- a/src/app-layer-ftp.c +++ b/src/app-layer-ftp.c @@ -473,17 +473,21 @@ static void FtpTransferCmdFree(void *data) static uint32_t CopyCommandLine(uint8_t **dest, uint8_t *src, uint32_t length) { if (likely(length)) { - uint8_t *where = FTPCalloc(length, sizeof(char)); + if (unlikely(length == UINT32_MAX)) { + return 0; + } + uint8_t *where = FTPCalloc(length + 1, sizeof(char)); if (unlikely(where == NULL)) { return 0; } memcpy(where, src, length); /* Remove trailing newlines/carriage returns */ - if (isspace((unsigned char)where[length - 1])) { - while(length && isspace((unsigned char)where[--length - 1])); - where[length] = '\0'; + while (length && isspace((unsigned char) where[length - 1])) { + length--; } + + where[length] = '\0'; *dest = where; } /* either 0 or actual */ @@ -750,6 +754,7 @@ static int FTPParseResponse(Flow *f, void *ftp_state, AppLayerParserState *pstat void *local_data, const uint8_t flags) { FtpState *state = (FtpState *)ftp_state; + FTPTransaction *tx = NULL; int retcode = 1; FTPTransaction *tx; @@ -769,9 +774,9 @@ static int FTPParseResponse(Flow *f, void *ftp_state, AppLayerParserState *pstat tx->command_descriptor = &FtpCommands[FTP_COMMAND_MAX -1]; } else { tx = FTPGetOldestTx(state); + state->curr_tx = tx; } - state->curr_tx = tx; if (state->command == FTP_COMMAND_AUTH_TLS) { if (input_len >= 4 && SCMemcmp("234 ", input, 4) == 0) { AppLayerRequestProtocolTLSUpgrade(f); diff --git a/src/output-json-ftp.c b/src/output-json-ftp.c index 06807769c8..10a9b35e02 100644 --- a/src/output-json-ftp.c +++ b/src/output-json-ftp.c @@ -69,14 +69,21 @@ static void JsonFTPLogJSON(json_t *tjs, Flow *f, FTPTransaction *tx) } else { cjs = json_object(); if (cjs) { - json_object_set_new(cjs, "command", - json_string(tx->command_descriptor->command_name_upper)); + FTPString *response; + if (tx->command_descriptor->command == FTP_COMMAND_UNKNOWN) { + // alternatively, `command` could be left out of the object completely + json_object_set_new(cjs, "command", json_null()); + } else { + json_object_set_new(cjs, "command", json_string(tx->command_descriptor->command_name_upper)); + } uint32_t min_length = tx->command_descriptor->command_length + 1; /* command + space */ - json_object_set_new(cjs, "command_data", - tx->request_length >= min_length ? + if (tx->request_length > min_length) { + json_object_set_new(cjs, "command_data", JsonAddStringN((const char *)tx->request + min_length, - tx->request_length - min_length) : - json_string(NULL)); + tx->request_length - min_length)); + } else { + json_object_set_new(cjs, "command_data", json_string(NULL)); + } if (!TAILQ_EMPTY(&tx->response_list)) { json_t *js_resplist = json_array(); if (likely(js_resplist != NULL)) {