Skip to content

Commit

Permalink
Validate on len_varint_buffer()
Browse files Browse the repository at this point in the history
len_varint_buffer() should validate invalid varint.
  • Loading branch information
kawasin73 committed Oct 29, 2023
1 parent 2517722 commit 5781b27
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 8 deletions.
5 changes: 3 additions & 2 deletions src/btree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,8 @@ fn compute_table_leaf_cell_size(
) -> ParseResult<u16> {
let (payload_size, payload_size_length) =
parse_varint(&buffer[offset..]).ok_or("parse payload size")?;
let key_length = len_varint_buffer(&buffer[offset + payload_size_length..]);
let key_length =
len_varint_buffer(&buffer[offset + payload_size_length..]).ok_or("key length")?;
let n_local = if payload_size <= ctx.max_local(true) as u64 {
payload_size as u16
} else {
Expand All @@ -376,7 +377,7 @@ fn compute_table_interior_cell_size(
buffer: &[u8],
offset: usize,
) -> ParseResult<u16> {
let key_length = len_varint_buffer(&buffer[offset + 4..]);
let key_length = len_varint_buffer(&buffer[offset + 4..]).ok_or("key length")?;
Ok(4 + key_length as u16)
}

Expand Down
4 changes: 3 additions & 1 deletion src/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -863,6 +863,7 @@ impl<'a> BtreeCursor<'a> {
let key_offset_in_cell = if current_page.page_type.is_leaf() {
// payload_size_length
len_varint_buffer(&left_buffer[cell_offset..])
.ok_or_else(|| anyhow::anyhow!("payload size len"))?
} else {
// Set the right page id of the left page.
// No header offset calibration because both pages must not page 1
Expand All @@ -875,7 +876,8 @@ impl<'a> BtreeCursor<'a> {
4
};
let key_offset = cell_offset + key_offset_in_cell;
let key_length = len_varint_buffer(&left_buffer[key_offset..]);
let key_length = len_varint_buffer(&left_buffer[key_offset..])
.ok_or_else(|| anyhow::anyhow!("key length"))?;
interior_cell_buf[4..4 + key_length]
.copy_from_slice(&left_buffer[key_offset..key_offset + key_length]);
key_length as u16
Expand Down
33 changes: 28 additions & 5 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,27 @@ pub fn unsafe_parse_varint(buf: &[u8]) -> (u64, usize) {
}

/// Length of varint in the buffer.
pub fn len_varint_buffer(buf: &[u8]) -> usize {
pub fn len_varint_buffer(buf: &[u8]) -> Option<usize> {
for (i, v2) in buf.iter().enumerate().take(8) {
if *v2 & VARINT_FLAG_MASK == 0 {
return Some(i + 1);
}
}
if buf.len() >= 9 {
Some(9)
} else {
None
}
}

#[allow(dead_code)]
pub fn unsafe_len_varint_buffer(buf: &[u8]) -> usize {
for (i, v2) in buf.iter().enumerate().take(8) {
if *v2 & VARINT_FLAG_MASK == 0 {
return i + 1;
}
}
assert!(buf.len() >= 9);
9
}

Expand Down Expand Up @@ -737,23 +752,30 @@ mod tests {
// valid as varint
assert!(parse_varint(buf).is_some());

assert_eq!(len_varint_buffer(buf), buf.len());
assert_eq!(len_varint_buffer(buf).unwrap(), buf.len());
assert_eq!(unsafe_len_varint_buffer(buf), buf.len());
}
}

#[test]
fn test_parse_varint_consume() {
let (_, consumed) = unsafe_parse_varint(&[0, 0]);
assert_eq!(consumed, 1);
assert_eq!(len_varint_buffer(&[0, 0]), 1);
assert_eq!(len_varint_buffer(&[0, 0]).unwrap(), 1);
assert_eq!(unsafe_len_varint_buffer(&[0, 0]), 1);
let (_, consumed) = unsafe_parse_varint(&[129, 0, 0]);
assert_eq!(consumed, 2);
assert_eq!(len_varint_buffer(&[129, 0, 0]), 2);
assert_eq!(len_varint_buffer(&[129, 0, 0]).unwrap(), 2);
assert_eq!(unsafe_len_varint_buffer(&[129, 0, 0]), 2);
let (_, consumed) =
unsafe_parse_varint(&[255, 255, 255, 255, 255, 255, 255, 255, 255, 255]);
assert_eq!(consumed, 9);
assert_eq!(
len_varint_buffer(&[255, 255, 255, 255, 255, 255, 255, 255, 255, 255]),
len_varint_buffer(&[255, 255, 255, 255, 255, 255, 255, 255, 255, 255]).unwrap(),
9
);
assert_eq!(
unsafe_len_varint_buffer(&[255, 255, 255, 255, 255, 255, 255, 255, 255, 255]),
9
);
}
Expand All @@ -774,6 +796,7 @@ mod tests {
] as [&[u8]; 10]
{
assert!(parse_varint(buf).is_none());
assert!(len_varint_buffer(buf).is_none());
}
}

Expand Down

0 comments on commit 5781b27

Please sign in to comment.