fix(postgres): don't panic if M or C Notice fields are not UTF-8

This has been observed with an old version of PostgreSQL (11.0.4)
running on Windows Server 2016 with windows-1252 encoding and French
locale.

This change replaces invalid UTF-8 fields with a default string, so the
other fields can still be read if they are valid.
This commit is contained in:
Ygor Souza
2024-07-12 21:54:37 +02:00
parent 0db12a9846
commit 362ca98bbd

View File

@@ -6,6 +6,11 @@ use sqlx_core::bytes::Bytes;
use crate::error::Error;
use crate::io::Decode;
const INVALID_UTF8: &str = "Postgres returned a non-UTF-8 string for its error message. \
This is most likely due to an error that occurred during authentication and \
the default lc_messages locale is not binary-compatible with UTF-8. \
See the server logs for the error details.";
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[repr(u8)]
pub enum PgSeverity {
@@ -100,8 +105,7 @@ impl Notice {
#[inline]
fn get_cached_str(&self, cache: (u16, u16)) -> &str {
// unwrap: this cannot fail at this stage
from_utf8(&self.storage[cache.0 as usize..cache.1 as usize]).unwrap()
from_utf8(&self.storage[cache.0 as usize..cache.1 as usize]).unwrap_or(INVALID_UTF8)
}
}
@@ -203,13 +207,7 @@ impl<'a> Iterator for Fields<'a> {
fn notice_protocol_err() -> Error {
// https://github.com/launchbadge/sqlx/issues/1144
Error::Protocol(
"Postgres returned a non-UTF-8 string for its error message. \
This is most likely due to an error that occurred during authentication and \
the default lc_messages locale is not binary-compatible with UTF-8. \
See the server logs for the error details."
.into(),
)
Error::Protocol(INVALID_UTF8.into())
}
#[test]