From 76161b63a1dfea01f4bab722a0116b743e22917f Mon Sep 17 00:00:00 2001 From: Marcelo Altmann Date: Mon, 5 May 2025 14:24:48 -0300 Subject: [PATCH 1/2] mysql-time: hour overflow test case. This commit adds a test case for the hour overflow issue. Test case: ``` mysql> CREATE TABLE t (c TIME); Query OK, 0 rows affected (0,018 sec) mysql> INSERT INTO t values ('-507:48:27'); Query OK, 1 row affected (0,009 sec) ``` --- src/binlog/mod.rs | 20 ++++++++++++++++++++ test-data/binlogs/time_issue.000001 | Bin 0 -> 472 bytes 2 files changed, 20 insertions(+) create mode 100644 test-data/binlogs/time_issue.000001 diff --git a/src/binlog/mod.rs b/src/binlog/mod.rs index 46f9ea7..235e75d 100644 --- a/src/binlog/mod.rs +++ b/src/binlog/mod.rs @@ -1190,6 +1190,26 @@ mod tests { } } + if file_path.file_name().unwrap() == "time_issue.000001" { + let event_data = ev.read_data().unwrap(); + match event_data { + Some(EventData::RowsEvent(ev)) => { + let table_map_event = + binlog_file.reader().get_tme(ev.table_id()).unwrap(); + let row = ev.rows(table_map_event).next().unwrap().unwrap(); + let after_image = row.1.unwrap(); + after_image.columns().iter().enumerate().for_each(|(i, _)| { + match after_image.as_ref(i).unwrap() { + BinlogValue::Value(val) => { + assert_eq!(val, &Value::Time(true, 21, 3, 48, 27, 0)); + } + _ => panic!("Expected a value"), + } + }); + } + _ => (), + } + } ev_pos = ev_end; } } diff --git a/test-data/binlogs/time_issue.000001 b/test-data/binlogs/time_issue.000001 new file mode 100644 index 0000000000000000000000000000000000000000..d4fe9b4c7ad53a4c8f0da8db695681eeb96b7ac3 GIT binary patch literal 472 zcmeyDl$p2Vsze4qBLf3N6%f|}F#`h&gN2@fo{0gNLjobpz{|h^F@Oa~B{8r_fw&wT z985rpi;GK3i$TbQflGsdu`}CcFUV$Pkj?TyJQs)?fEWTUCb_8`2TCh}r2T>T4O9XL z1u`EDKW2xOKp$Sge|P6OMi!v@mE$iNCw z%2>j{2vosXB`l!;QY{Bkqz=TrD5{wl82>XQI6r-E{9rCfnE*%@6dY^7%I4LADF)GH k{|c@FrCC5+9U#5|76%0~2moU-CqG@!00d0it8Uf<0DZ_tjQ{`u literal 0 HcmV?d00001 From a381a9fa724f44061c99474efc982e504ba6c6bc Mon Sep 17 00:00:00 2001 From: Marcelo Altmann Date: Mon, 5 May 2025 14:26:02 -0300 Subject: [PATCH 2/2] mysql-time: hour overflow The way we currently parse hour at time_from_packed can overflow if the amount of hours is greater than 255 because the hour field from time struct is a u8. This commit fixes the issue by converting the hours to days and hours. Fixes: #169 --- src/binlog/misc.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/binlog/misc.rs b/src/binlog/misc.rs index a80890d..35cdd5a 100644 --- a/src/binlog/misc.rs +++ b/src/binlog/misc.rs @@ -73,10 +73,12 @@ pub fn time_from_packed(mut tmp: i64) -> Value { }; let hms = my_packed_time_get_int_part(tmp); let h = ((hms >> 12) as u32) % (1 << 10); + let d = h / 24; + let h = h % 24; let m = ((hms >> 6) as u32) % (1 << 6); let s = ((hms) as u32) % (1 << 6); let u = my_packed_time_get_frac_part(tmp); - Value::Time(neg, 0, h as u8, m as u8, s as u8, u as u32) + Value::Time(neg, d, h as u8, m as u8, s as u8, u as u32) } pub fn my_datetime_packed_from_binary(mut input: T, dec: u32) -> io::Result {