sqlx/sqlx-mysql
Vladimir Petrzhikovskii e283bf9645 mysql: Fix panic on invalid text row length field
Previously, `TextRow::decode_with` would read a length-encoded field size
and attempt to advance the buffer by that amount. If the server sent a
malformed packet containing a length value larger than the remaining data
in the buffer, the call to `buf.advance(size)` would panic.

eg: 
```
thread 'main' panicked at /home/user/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.10.1/src/bytes.rs:711:9:
cannot advance past remaining: 8590116092 <= 0
stack backtrace:
0:     0x56119b657e00 - <std::sys::backtrace::BacktraceLock::print::DisplayBacktrace as core::fmt::Display>::fmt::h6d42cc84fc840290
1:     0x56119b67edd3 - core::fmt::write::h5af61a909e3ec64d
2:     0x56119b653ee3 - std::io::Write::write_fmt::h5a7b54aa6e4a315d
3:     0x56119b657c52 - std::sys::backtrace::BacktraceLock::print::h555579e7396c26ac
4:     0x56119b658cef - std::panicking::default_hook::{{closure}}::h9128866118196224
5:     0x56119b658b5a - std::panicking::default_hook::h52e9e7314e0255f6
6:     0x56119b659712 - std::panicking::rust_panic_with_hook::h541791bcc774ef34
7:     0x56119b65949a - std::panicking::begin_panic_handler::{{closure}}::h6479a2f0137c7d19
8:     0x56119b658319 - std::sys::backtrace::__rust_end_short_backtrace::ha04e7c0fc61ded91
9:     0x56119b65912d - rust_begin_unwind
10:     0x56119b67c390 - core::panicking::panic_fmt::h5764ee7030b7a73d
11:     0x56119b572b18 - <sqlx_mysql::protocol::text::row::TextRow as sqlx_core::io::decode::ProtocolDecode<&[sqlx_mysql::column::MySqlColumn]>>::decode_with::h17ac8b44140b5469
12:     0x56119b42df1f - sqlx_mysql::connection::executor::<impl sqlx_mysql::connection::MySqlConnection>::run::{{closure}}::{{closure}}::{{closure}}::h4874a0f73925d55a
```

This commit introduces a bounds check immediately after reading the field length from a packet.

This panic condition was specifically observed when executing a TiDB
`BATCH ON ... DELETE` statement via `pool.execute()`. It sends an OK packet immediately followed by
a full result set describing the batch status (column defs, row data, EOF).


 Observed TiDB response sequence for `BATCH DML` via `COM_QUERY`:
    1. OK Packet (seq=1, `SERVER_MORE_RESULTS_EXISTS` = false)
    2. Column Count Packet (seq=1, non-standard, protocol violation)
    3. Column Definition Packet (seq=2)
    4. Column Definition Packet (seq=3)
    5. Text Row Data Packet (seq=4)
    6. EOF Packet (seq=5, `SERVER_MORE_RESULTS_EXISTS` = false)

This differs from standard MySQL DML response (OK/ERR packet only) and
causes `sqlx` using `execute()` to attempt parsing the unexpected result
set packets after the initial OK packet.
2025-04-10 19:40:16 -07:00
..
2024-11-26 11:01:33 -08:00
2024-06-20 10:56:08 -07:00
2024-06-20 10:56:08 -07:00