Rewrite metadata::set_item without unsafe

Also re-introduces some comments that were lost during corrosion.
This commit is contained in:
Jack Grigg
2019-11-28 17:49:17 +00:00
parent afb6a9479e
commit bd5669d9ef
+36 -58
View File
@@ -83,35 +83,25 @@ pub(crate) fn set_item(
tag: u8, tag: u8,
p_item: &[u8], p_item: &[u8],
) -> Result<(), Error> { ) -> Result<(), Error> {
let mut p_temp: *mut u8 = data.as_mut_ptr();
let mut cb_temp: usize = 0; let mut cb_temp: usize = 0;
let mut tag_temp: u8 = 0; let mut tag_temp: u8 = 0;
let mut cb_len: usize = 0; let mut cb_len: usize = 0;
let cb_item = p_item.len(); let cb_item = p_item.len();
// Must be signed to have negative offsets
let cb_moved: isize;
let p_next: *mut u8;
while p_temp < data[*pcb_data..].as_mut_ptr() { let mut offset = 0;
unsafe {
tag_temp = *p_temp;
p_temp = p_temp.add(1);
cb_len = get_length( while offset < *pcb_data {
slice::from_raw_parts( tag_temp = data[offset];
p_temp, offset += 1;
data.as_mut_ptr() as usize + data.len() - p_temp as usize,
), cb_len = get_length(&data[offset..], &mut cb_temp);
&mut cb_temp, offset += cb_len;
);
p_temp = p_temp.add(cb_len);
if tag_temp == tag { if tag_temp == tag {
break; break;
} }
p_temp = p_temp.add(cb_temp); offset += cb_temp;
}
} }
if tag_temp != tag { if tag_temp != tag {
@@ -120,75 +110,63 @@ pub(crate) fn set_item(
return Ok(()); return Ok(());
} }
unsafe { // We did not find an existing tag, append
p_temp = data.as_mut_ptr().add(*pcb_data); offset = *pcb_data;
cb_len = get_length_size(cb_item); cb_len = get_length_size(cb_item);
// If length would cause buffer overflow, return error
if (*pcb_data + cb_len + cb_item) > cb_data_max { if (*pcb_data + cb_len + cb_item) > cb_data_max {
return Err(Error::GenericError); return Err(Error::GenericError);
} }
*p_temp = tag; data[offset] = tag;
p_temp = p_temp.add(1); offset += 1;
p_temp = p_temp.add(set_length( offset += set_length(&mut data[offset..], cb_item);
slice::from_raw_parts_mut( data[offset..offset + cb_item].copy_from_slice(p_item);
p_temp,
data.as_ptr() as usize + data.len() - p_temp as usize,
),
cb_item,
));
ptr::copy(p_item.as_ptr(), p_temp, cb_item);
}
*pcb_data += 1 + cb_len + cb_item; *pcb_data += 1 + cb_len + cb_item;
return Ok(()); return Ok(());
} }
if cb_temp == cb_item { // Found tag
unsafe {
ptr::copy(p_item.as_ptr(), p_temp, cb_item);
}
// Check length, if it matches, overwrite
if cb_temp == cb_item {
data[offset..offset + cb_item].copy_from_slice(p_item);
return Ok(()); return Ok(());
} }
p_next = unsafe { p_temp.add(cb_temp) }; // Length doesn't match, expand/shrink to fit
cb_moved = (cb_item as isize - cb_temp as isize) let next_offset = offset + cb_temp;
// Must be signed to have negative offsets
let cb_moved: isize = (cb_item as isize - cb_temp as isize)
+ if cb_item != 0 { + if cb_item != 0 {
get_length_size(cb_item) as isize get_length_size(cb_item) as isize
} else { } else {
// For tag, if deleting
-1 -1
} }
// Accounts for different length encoding
- cb_len as isize; - cb_len as isize;
if (*pcb_data + cb_moved as usize) > cb_data_max { // If length would cause buffer overflow, return error
if (*pcb_data as isize + cb_moved) as usize > cb_data_max {
return Err(Error::GenericError); return Err(Error::GenericError);
} }
unsafe { // Move remaining data
ptr::copy( data.copy_within(
p_next, next_offset..*pcb_data,
p_next.offset(cb_moved), (next_offset as isize + cb_moved) as usize,
*pcb_data - p_next as usize - data.as_ptr() as usize,
); );
} *pcb_data = (*pcb_data as isize + cb_moved) as usize;
*pcb_data += cb_moved as usize;
// Re-encode item and insert
if cb_item != 0 { if cb_item != 0 {
unsafe { offset -= cb_len;
p_temp = p_temp.offset(-(cb_len as isize)); offset += set_length(&mut data[offset..], cb_item);
p_temp = p_temp.add(set_length( data[offset..offset + cb_item].copy_from_slice(p_item);
slice::from_raw_parts_mut(
p_temp,
data.as_ptr() as usize + data.len() - p_temp as usize,
),
cb_item,
));
ptr::copy(p_item.as_ptr(), p_temp, cb_item);
}
} }
Ok(()) Ok(())