Skip to content

Commit dd92def

Browse files
committed
fix: audit PgValueRef::get() and usage sites for bad casts
1 parent 63349de commit dd92def

File tree

4 files changed

+26
-19
lines changed

4 files changed

+26
-19
lines changed

sqlx-postgres/src/types/array.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -242,21 +242,22 @@ where
242242
// length of the array axis
243243
let len = buf.get_i32();
244244

245+
let len = usize::try_from(len)
246+
.map_err(|_| format!("overflow converting array len ({len}) to usize"))?;
247+
245248
// the lower bound, we only support arrays starting from "1"
246249
let lower = buf.get_i32();
247250

248251
if lower != 1 {
249252
return Err(format!("encountered an array with a lower bound of {lower} in the first dimension; only arrays starting at one are supported").into());
250253
}
251254

252-
let mut elements = Vec::with_capacity(len as usize);
255+
let mut elements = Vec::with_capacity(len);
253256

254257
for _ in 0..len {
255-
elements.push(T::decode(PgValueRef::get(
256-
&mut buf,
257-
format,
258-
element_type_info.clone(),
259-
))?)
258+
let value_ref = PgValueRef::get(&mut buf, format, element_type_info.clone())?;
259+
260+
elements.push(T::decode(value_ref)?);
260261
}
261262

262263
Ok(elements)

sqlx-postgres/src/types/range.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ where
350350

351351
if !flags.contains(RangeFlags::LB_INF) {
352352
let value =
353-
T::decode(PgValueRef::get(&mut buf, value.format, element_ty.clone()))?;
353+
T::decode(PgValueRef::get(&mut buf, value.format, element_ty.clone())?)?;
354354

355355
start = if flags.contains(RangeFlags::LB_INC) {
356356
Bound::Included(value)
@@ -361,7 +361,7 @@ where
361361

362362
if !flags.contains(RangeFlags::UB_INF) {
363363
let value =
364-
T::decode(PgValueRef::get(&mut buf, value.format, element_ty.clone()))?;
364+
T::decode(PgValueRef::get(&mut buf, value.format, element_ty.clone())?)?;
365365

366366
end = if flags.contains(RangeFlags::UB_INC) {
367367
Bound::Included(value)

sqlx-postgres/src/types/record.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ impl<'r> PgRecordDecoder<'r> {
137137

138138
self.ind += 1;
139139

140-
T::decode(PgValueRef::get(&mut self.buf, self.fmt, element_type))
140+
T::decode(PgValueRef::get(&mut self.buf, self.fmt, element_type)?)
141141
}
142142

143143
PgValueFormat::Text => {

sqlx-postgres/src/value.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
use crate::error::{BoxDynError, UnexpectedNullError};
22
use crate::{PgTypeInfo, Postgres};
33
use sqlx_core::bytes::{Buf, Bytes};
4+
pub(crate) use sqlx_core::value::{Value, ValueRef};
45
use std::borrow::Cow;
56
use std::str::from_utf8;
67

7-
pub(crate) use sqlx_core::value::{Value, ValueRef};
8-
98
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
109
#[repr(u8)]
1110
pub enum PgValueFormat {
@@ -31,24 +30,31 @@ pub struct PgValue {
3130
}
3231

3332
impl<'r> PgValueRef<'r> {
34-
pub(crate) fn get(buf: &mut &'r [u8], format: PgValueFormat, ty: PgTypeInfo) -> Self {
35-
let mut element_len = buf.get_i32();
33+
pub(crate) fn get(
34+
buf: &mut &'r [u8],
35+
format: PgValueFormat,
36+
ty: PgTypeInfo,
37+
) -> Result<Self, String> {
38+
let element_len = buf.get_i32();
3639

3740
let element_val = if element_len == -1 {
38-
element_len = 0;
3941
None
4042
} else {
41-
Some(&buf[..(element_len as usize)])
42-
};
43+
let element_len: usize = element_len
44+
.try_into()
45+
.map_err(|_| format!("overflow converting element_len ({element_len}) to usize"))?;
4346

44-
buf.advance(element_len as usize);
47+
let val = &buf[..element_len];
48+
buf.advance(element_len);
49+
Some(val)
50+
};
4551

46-
PgValueRef {
52+
Ok(PgValueRef {
4753
value: element_val,
4854
row: None,
4955
type_info: ty,
5056
format,
51-
}
57+
})
5258
}
5359

5460
pub fn format(&self) -> PgValueFormat {

0 commit comments

Comments
 (0)