Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace unsafe strlen usage in metadata library with safe Rust #1926

Merged
merged 1 commit into from Jul 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 0 additions & 4 deletions crates/libs/metadata/src/imp.rs
Expand Up @@ -13,10 +13,6 @@ pub struct METADATA_HEADER {

pub const METADATA_SIGNATURE: u32 = 0x424A_5342;

extern "C" {
pub fn strlen(cs: *const u8) -> usize;
}

/// A coded index (see codes.rs) is a table index that may refer to different tables. The size of the column in memory
/// must therefore be large enough to hold an index for a row in the largest possible table. This function determines
/// this size for the given winmd file.
Expand Down
16 changes: 12 additions & 4 deletions crates/libs/metadata/src/reader/file.rs
Expand Up @@ -333,13 +333,21 @@ impl File {
}
}

/// Returns the string from the `#Strings` stream as referenced by
/// the (table, row, column) triple.
///
/// # Panics
///
/// * When any element of the (table, row, column) triple is invalid.
/// * When the offset in the string table is out of bounds.
/// * When no null terminator can be found in the string table.
/// * When the null-terminated string is not valid utf-8.
pub fn str(&self, row: usize, table: usize, column: usize) -> &str {
let offset = self.strings + self.usize(row, table, column);

unsafe {
let len = strlen(self.bytes.as_ptr().add(offset));
std::str::from_utf8_unchecked(&self.bytes[offset..offset + len])
}
let bytes = &self.bytes[offset..];
let nul_pos = bytes.iter().position(|&c| c == 0).expect("expected null-terminated C-string");
std::str::from_utf8(&bytes[..nul_pos]).expect("expected valid utf-8 C-string")
}

pub fn blob(&self, row: usize, table: usize, column: usize) -> &[u8] {
Expand Down