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
+43 -65
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,
),
&mut cb_temp,
);
p_temp = p_temp.add(cb_len);
if tag_temp == tag { cb_len = get_length(&data[offset..], &mut cb_temp);
break; offset += cb_len;
}
p_temp = p_temp.add(cb_temp); if tag_temp == tag {
break;
} }
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 (*pcb_data + cb_len + cb_item) > cb_data_max { // If length would cause buffer overflow, return error
return Err(Error::GenericError); if (*pcb_data + cb_len + cb_item) > cb_data_max {
} return Err(Error::GenericError);
*p_temp = tag;
p_temp = p_temp.add(1);
p_temp = p_temp.add(set_length(
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);
} }
data[offset] = tag;
offset += 1;
offset += set_length(&mut data[offset..], cb_item);
data[offset..offset + cb_item].copy_from_slice(p_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(())