From 641f82c96250aa64793ffd34c7c2b30846cc9b94 Mon Sep 17 00:00:00 2001 From: t8y2 <1156263951@qq.com> Date: Sat, 5 Sep 2026 16:09:17 +0800 Subject: [PATCH] fix(redshift): skip WKB probe slice on multibyte text values Redshift reads run every simple-query cell through decode_pg_text_wkb with an unknown column type. The probe sliced hex[..2] before the is_ascii() guard, so any cell starting with a 3-4 byte UTF-8 character with an even byte length >= 10 panicked on a non-char boundary and aborted the process under panic = abort (Windows BEX64 in dbx.exe). Check is_ascii() first so ordinary multibyte text passes through. Closes #7958 --- crates/dbx-core/src/db/postgres.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/crates/dbx-core/src/db/postgres.rs b/crates/dbx-core/src/db/postgres.rs index a5c3780809..a1e128ca37 100644 --- a/crates/dbx-core/src/db/postgres.rs +++ b/crates/dbx-core/src/db/postgres.rs @@ -972,7 +972,11 @@ fn decode_pg_text_wkb(value: &str) -> Option { .or_else(|| trimmed.strip_prefix("\\x")) .or_else(|| trimmed.strip_prefix("\\X")) .unwrap_or(trimmed); - if hex.len() < 10 || !hex.len().is_multiple_of(2) || !matches!(&hex[..2], "00" | "01") || !hex.is_ascii() { + // `is_ascii()` must be checked before slicing `hex[..2]`: multibyte UTF-8 + // text (e.g. Redshift simple-query values probed with an unknown column + // type) would otherwise panic on a non-char byte boundary and abort the + // process under `panic = "abort"`. + if hex.len() < 10 || !hex.len().is_multiple_of(2) || !hex.is_ascii() || !matches!(&hex[..2], "00" | "01") { return None; } let bytes = hex @@ -9470,6 +9474,17 @@ mod tests { assert_eq!(pg_text_fallback_value("SRID=4326;point(1 2)", None), (serde_json::json!("point(1 2)"), Some(4326))); } + #[test] + fn postgres_text_fallback_does_not_panic_on_multibyte_text() { + // Redshift reads decode every simple-query value through the hex-WKB + // probe with an unknown column type, so ordinary multibyte text must + // pass through instead of slicing at a non-char byte boundary. + for value in ["中文字符测试数据", "🚚运输状态标签", "0101中文不是几何数据"] { + assert_eq!(pg_text_fallback_value(value, None), (serde_json::json!(value), None)); + assert_eq!(pg_text_fallback_value(value, Some(PgColType::Geometry)), (serde_json::json!(value), None)); + } + } + struct DockerPostgres { name: String, port: u16,