Skip to content

Commit 263b006

Browse files
committed
Handle non-UTF8 error fields
1 parent c2b5c8a commit 263b006

File tree

2 files changed

+27
-20
lines changed

2 files changed

+27
-20
lines changed

postgres-protocol/src/message/backend.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,7 @@ impl<'a> FallibleIterator for ErrorFields<'a> {
633633
}
634634

635635
let value_end = find_null(self.buf, 0)?;
636-
let value = get_str(&self.buf[..value_end])?;
636+
let value = &self.buf[..value_end];
637637
self.buf = &self.buf[value_end + 1..];
638638

639639
Ok(Some(ErrorField { type_, value }))
@@ -642,7 +642,7 @@ impl<'a> FallibleIterator for ErrorFields<'a> {
642642

643643
pub struct ErrorField<'a> {
644644
type_: u8,
645-
value: &'a str,
645+
value: &'a [u8],
646646
}
647647

648648
impl<'a> ErrorField<'a> {
@@ -652,7 +652,13 @@ impl<'a> ErrorField<'a> {
652652
}
653653

654654
#[inline]
655+
#[deprecated(note = "use value_bytes instead", since = "0.6.7")]
655656
pub fn value(&self) -> &str {
657+
str::from_utf8(self.value).expect("error field value contained non-UTF8 bytes")
658+
}
659+
660+
#[inline]
661+
pub fn value_bytes(&self) -> &[u8] {
656662
self.value
657663
}
658664
}

tokio-postgres/src/error/mod.rs

+19-18
Original file line numberDiff line numberDiff line change
@@ -107,47 +107,48 @@ impl DbError {
107107
let mut routine = None;
108108

109109
while let Some(field) = fields.next()? {
110+
let value = String::from_utf8_lossy(field.value_bytes());
110111
match field.type_() {
111-
b'S' => severity = Some(field.value().to_owned()),
112-
b'C' => code = Some(SqlState::from_code(field.value())),
113-
b'M' => message = Some(field.value().to_owned()),
114-
b'D' => detail = Some(field.value().to_owned()),
115-
b'H' => hint = Some(field.value().to_owned()),
112+
b'S' => severity = Some(value.into_owned()),
113+
b'C' => code = Some(SqlState::from_code(&value)),
114+
b'M' => message = Some(value.into_owned()),
115+
b'D' => detail = Some(value.into_owned()),
116+
b'H' => hint = Some(value.into_owned()),
116117
b'P' => {
117-
normal_position = Some(field.value().parse::<u32>().map_err(|_| {
118+
normal_position = Some(value.parse::<u32>().map_err(|_| {
118119
io::Error::new(
119120
io::ErrorKind::InvalidInput,
120121
"`P` field did not contain an integer",
121122
)
122123
})?);
123124
}
124125
b'p' => {
125-
internal_position = Some(field.value().parse::<u32>().map_err(|_| {
126+
internal_position = Some(value.parse::<u32>().map_err(|_| {
126127
io::Error::new(
127128
io::ErrorKind::InvalidInput,
128129
"`p` field did not contain an integer",
129130
)
130131
})?);
131132
}
132-
b'q' => internal_query = Some(field.value().to_owned()),
133-
b'W' => where_ = Some(field.value().to_owned()),
134-
b's' => schema = Some(field.value().to_owned()),
135-
b't' => table = Some(field.value().to_owned()),
136-
b'c' => column = Some(field.value().to_owned()),
137-
b'd' => datatype = Some(field.value().to_owned()),
138-
b'n' => constraint = Some(field.value().to_owned()),
139-
b'F' => file = Some(field.value().to_owned()),
133+
b'q' => internal_query = Some(value.into_owned()),
134+
b'W' => where_ = Some(value.into_owned()),
135+
b's' => schema = Some(value.into_owned()),
136+
b't' => table = Some(value.into_owned()),
137+
b'c' => column = Some(value.into_owned()),
138+
b'd' => datatype = Some(value.into_owned()),
139+
b'n' => constraint = Some(value.into_owned()),
140+
b'F' => file = Some(value.into_owned()),
140141
b'L' => {
141-
line = Some(field.value().parse::<u32>().map_err(|_| {
142+
line = Some(value.parse::<u32>().map_err(|_| {
142143
io::Error::new(
143144
io::ErrorKind::InvalidInput,
144145
"`L` field did not contain an integer",
145146
)
146147
})?);
147148
}
148-
b'R' => routine = Some(field.value().to_owned()),
149+
b'R' => routine = Some(value.into_owned()),
149150
b'V' => {
150-
parsed_severity = Some(Severity::from_str(field.value()).ok_or_else(|| {
151+
parsed_severity = Some(Severity::from_str(&value).ok_or_else(|| {
151152
io::Error::new(
152153
io::ErrorKind::InvalidInput,
153154
"`V` field contained an invalid value",

0 commit comments

Comments
 (0)