From 46feb19e1622dca0548ac2d1e0f3c3a248570807 Mon Sep 17 00:00:00 2001 From: QianKai Lin Date: Mon, 21 Oct 2024 17:25:01 +0800 Subject: [PATCH] mysql: fix CI Task #3446 --- doc/userguide/output/eve/eve-json-format.rst | 2 +- rust/src/mysql/mysql.rs | 119 +++++++++++++------ rust/src/mysql/parser.rs | 39 ++---- src/output.c | 3 +- 4 files changed, 98 insertions(+), 65 deletions(-) diff --git a/doc/userguide/output/eve/eve-json-format.rst b/doc/userguide/output/eve/eve-json-format.rst index e3e981fa4437..a7667e2bbbcf 100644 --- a/doc/userguide/output/eve/eve-json-format.rst +++ b/doc/userguide/output/eve/eve-json-format.rst @@ -3059,7 +3059,7 @@ Example of ARP logging: request and response } Event type: MySQL ---------------- +----------------- Fields ~~~~~~ diff --git a/rust/src/mysql/mysql.rs b/rust/src/mysql/mysql.rs index 699dc9bbdd41..35636ab32c9e 100644 --- a/rust/src/mysql/mysql.rs +++ b/rust/src/mysql/mysql.rs @@ -308,10 +308,13 @@ impl MysqlState { } fn new_tx(&mut self, command: String) -> MysqlTransaction { - let mut tx = MysqlTransaction::new(self.version.clone().unwrap()); + let mut tx = MysqlTransaction::new(self.version.clone().unwrap_or_default()); self.tx_id += 1; tx.tx_id = self.tx_id; tx.tls = self.tls; + if tx.tls { + tx.complete = true; + } tx.command = Some(command); SCLogDebug!("Creating new transaction.tx_id: {}", tx.tx_id); if self.transactions.len() > unsafe { MYSQL_MAX_TX } + self.tx_index_completed { @@ -326,9 +329,6 @@ impl MysqlState { } self.tx_index_completed = index; } - if tx.tls { - tx.complete = true; - } tx } @@ -528,7 +528,7 @@ impl MysqlState { // If there was gap, check we can sync up again. if self.request_gap { - if !probe(i).is_ok() { + if probe(i).is_err() { SCLogDebug!("Suricata interprets there's a gap in the request"); return AppLayerResult::ok(); } @@ -612,14 +612,22 @@ impl MysqlState { Some(MysqlStateProgress::LocalFileRequestReceived) } MysqlResponsePacket::FieldsList { columns: _ } => { - let tx = self.get_tx_mut(self.tx_id - 1); + let tx = if self.tx_id > 0 { + self.get_tx_mut(self.tx_id - 1) + } else { + None + }; if let Some(tx) = tx { tx.complete = true; } Some(MysqlStateProgress::FieldListResponseReceived) } MysqlResponsePacket::Statistics => { - let tx = self.get_tx_mut(self.tx_id - 1); + let tx = if self.tx_id > 0 { + self.get_tx_mut(self.tx_id - 1) + } else { + None + }; if let Some(tx) = tx { tx.complete = true; } @@ -630,14 +638,22 @@ impl MysqlState { MysqlResponsePacket::Err { .. } => match self.state_progress { MysqlStateProgress::CommandReceived | MysqlStateProgress::TextResulsetContinue => { - let tx = self.get_tx_mut(self.tx_id - 1); + let tx = if self.tx_id > 0 { + self.get_tx_mut(self.tx_id - 1) + } else { + None + }; if let Some(tx) = tx { tx.complete = true; } Some(MysqlStateProgress::CommandResponseReceived) } MysqlStateProgress::FieldListReceived => { - let tx = self.get_tx_mut(self.tx_id - 1); + let tx = if self.tx_id > 0 { + self.get_tx_mut(self.tx_id - 1) + } else { + None + }; if let Some(tx) = tx { tx.complete = true; } @@ -645,7 +661,11 @@ impl MysqlState { } MysqlStateProgress::StmtExecReceived | MysqlStateProgress::StmtExecResponseContinue => { - let tx = self.get_tx_mut(self.tx_id - 1); + let tx = if self.tx_id > 0 { + self.get_tx_mut(self.tx_id - 1) + } else { + None + }; if let Some(tx) = tx { tx.complete = true; } @@ -655,7 +675,11 @@ impl MysqlState { Some(MysqlStateProgress::StmtResetResponseReceived) } MysqlStateProgress::ChangeUserReceived => { - let tx = self.get_tx_mut(self.tx_id - 1); + let tx = if self.tx_id > 0 { + self.get_tx_mut(self.tx_id - 1) + } else { + None + }; if let Some(tx) = tx { tx.complete = true; } @@ -663,7 +687,11 @@ impl MysqlState { } MysqlStateProgress::StmtFetchReceived | MysqlStateProgress::StmtFetchResponseContinue => { - let tx = self.get_tx_mut(self.tx_id - 1); + let tx = if self.tx_id > 0 { + self.get_tx_mut(self.tx_id - 1) + } else { + None + }; if let Some(tx) = tx { tx.complete = true; } @@ -678,16 +706,23 @@ impl MysqlState { } => match self.state_progress { MysqlStateProgress::Auth => Some(MysqlStateProgress::AuthFinished), MysqlStateProgress::CommandReceived => { - let tx = self.get_tx_mut(self.tx_id - 1); + let tx = if self.tx_id > 0 { + self.get_tx_mut(self.tx_id - 1) + } else { + None + }; if let Some(tx) = tx { tx.affected_rows = Some(rows); tx.complete = true; } - Some(MysqlStateProgress::CommandResponseReceived) } MysqlStateProgress::StmtExecReceived => { - let tx = self.get_tx_mut(self.tx_id - 1); + let tx = if self.tx_id > 0 { + self.get_tx_mut(self.tx_id - 1) + } else { + None + }; if let Some(tx) = tx { tx.affected_rows = Some(rows); tx.complete = true; @@ -701,34 +736,38 @@ impl MysqlState { Some(MysqlStateProgress::StmtResetResponseReceived) } MysqlStateProgress::TextResulsetContinue => { - let tx = self.get_tx_mut(self.tx_id - 1); + let tx = if self.tx_id > 0 { + self.get_tx_mut(self.tx_id - 1) + } else { + None + }; if let Some(tx) = tx { tx.complete = true; } - Some(MysqlStateProgress::CommandResponseReceived) } MysqlStateProgress::StmtExecResponseContinue => { let prepare_stmt = self.prepare_stmt.take(); - let tx = self.get_tx_mut(self.tx_id - 1); - if let Some(tx) = tx { - if let Some(mut prepare_stmt) = prepare_stmt { - let rows = prepare_stmt.rows.take(); - if let Some(rows) = rows { - tx.rows = Some( - rows.into_iter() - .map(|row| match row { - MysqlResultBinarySetRow::Err => String::new(), - MysqlResultBinarySetRow::Text(text) => text, - }) - .collect::>(), - ); + if self.tx_id > 0 { + let tx = self.get_tx_mut(self.tx_id - 1); + if let Some(tx) = tx { + if let Some(mut prepare_stmt) = prepare_stmt { + let rows = prepare_stmt.rows.take(); + if let Some(rows) = rows { + tx.rows = Some( + rows.into_iter() + .map(|row| match row { + MysqlResultBinarySetRow::Err => String::new(), + MysqlResultBinarySetRow::Text(text) => text, + }) + .collect::>(), + ); + } + + tx.complete = true; } - - tx.complete = true; } } - Some(MysqlStateProgress::StmtExecResponseReceived) } MysqlStateProgress::StmtFetchResponseContinue => { @@ -742,7 +781,11 @@ impl MysqlState { eof, rows, } => { - let tx = self.get_tx_mut(self.tx_id - 1); + let tx = if self.tx_id > 0 { + self.get_tx_mut(self.tx_id - 1) + } else { + None + }; if !rows.is_empty() { let mut rows = rows.into_iter().map(|row| row.texts.join(",")).collect(); if let Some(tx) = tx { @@ -798,7 +841,11 @@ impl MysqlState { if !rows.is_empty() { if eof.status_flags != 0x0A { - let tx = self.get_tx_mut(self.tx_id - 1); + let tx = if self.tx_id > 0 { + self.get_tx_mut(self.tx_id - 1) + } else { + None + }; if let Some(tx) = tx { tx.rows = Some( rows.into_iter() @@ -894,7 +941,7 @@ impl MysqlState { } if self.response_gap { - if !probe(i).is_ok() { + if probe(i).is_err() { SCLogDebug!("Suricata interprets there's a gap in the response"); return AppLayerResult::ok(); } diff --git a/rust/src/mysql/parser.rs b/rust/src/mysql/parser.rs index 6f908b6893d0..d74bbcaed5eb 100644 --- a/rust/src/mysql/parser.rs +++ b/rust/src/mysql/parser.rs @@ -216,13 +216,13 @@ pub enum MysqlCommand { }, } -impl MysqlCommand { - pub fn to_string(self) -> String { +impl std::fmt::Display for MysqlCommand { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { - MysqlCommand::Quit => "quit".to_string(), - MysqlCommand::Query { query } => query, - MysqlCommand::Ping => "ping".to_string(), - _ => String::new(), + MysqlCommand::Quit => write!(f, "quit"), + MysqlCommand::Query { query } => write!(f, "{}", query), + MysqlCommand::Ping => write!(f, "ping"), + _ => write!(f, ""), } } } @@ -744,15 +744,12 @@ fn parse_stmt_execute_cmd( let param_types = if let Some(new_param_types) = new_param_types { Some(new_param_types) } else { - match param_types { - Some(param_types) => Some( - param_types - .iter() - .map(|param_type| (param_type.field_type, param_type.flags != 0)) - .collect(), - ), - None => None, - } + param_types.map(|param_types| { + param_types + .iter() + .map(|param_type| (param_type.field_type, param_type.flags != 0)) + .collect() + }) }; let consumed = old.len() - i.len(); @@ -1096,7 +1093,7 @@ fn parse_resultset_row_texts(i: &[u8]) -> IResult<&[u8], Vec> { length -= consumed; } - Ok((rem, texts)) + Ok((&[], texts)) } fn parse_resultset_row(i: &[u8]) -> IResult<&[u8], MysqlResultSetRow> { @@ -2125,16 +2122,6 @@ mod test { use super::*; - #[test] - fn test_parse_packet_header() { - let pkt: &[u8] = &[0x07, 0x00, 0x00, 0x03]; - let (rem, packet_header) = parse_packet_header(pkt).unwrap(); - - assert!(rem.is_empty()); - assert_eq!(packet_header.pkt_len, 7); - assert_eq!(packet_header.pkt_num, 3); - } - #[test] fn test_parse_handshake_request() { let pkt: &[u8] = &[ diff --git a/src/output.c b/src/output.c index 44f0e6074e01..cc20406eef9c 100644 --- a/src/output.c +++ b/src/output.c @@ -901,8 +901,7 @@ void OutputRegisterRootLoggers(void) // underscore instead of dash for bittorrent_dht RegisterSimpleJsonApplayerLogger( ALPROTO_BITTORRENT_DHT, rs_bittorrent_dht_logger_log, "bittorrent_dht"); - RegisterSimpleJsonApplayerLogger( - ALPROTO_MYSQL, SCMysqlLogger, "mysql"); + RegisterSimpleJsonApplayerLogger(ALPROTO_MYSQL, SCMysqlLogger, "mysql"); OutputPacketLoggerRegister(); OutputFiledataLoggerRegister();