From 936ab41a87d2b4876e09efc43864faf591dc0c2c Mon Sep 17 00:00:00 2001 From: Gerd Zellweger Date: Sat, 3 Jul 2021 23:28:46 -0700 Subject: [PATCH] Replac uses of from_utf8_unchecked with from_utf8. Fixes #43. --- CHANGELOG.md | 2 ++ src/lib.rs | 30 ++++++++++-------------------- 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 53bc8a8..433658f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] - Use more idiomatic rust code in readme/doc.rs example. +- Use `str::from_utf8` instead of `str::from_utf8_unchecked` to avoid potential + panics with the Deserialize trait (Fixes #43). ## [9.1.0] - 2021-07-03 diff --git a/src/lib.rs b/src/lib.rs index 745ee54..76f5ad5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -712,16 +712,13 @@ impl VendorInfo { /// Return vendor identification as human readable string. pub fn as_string<'a>(&'a self) -> &'a str { let brand_string_start = self as *const VendorInfo as *const u8; - unsafe { + let slice = unsafe { // Safety: VendorInfo is laid out with repr(C) and exactly // 12 byte long without any padding. - let slice: &'a [u8] = - slice::from_raw_parts(brand_string_start, size_of::()); - // Safety: The field is specified to be ASCII, and the only safe - // way to construct VendorInfo is from real CPUID data or the - // Default implementation. - str::from_utf8_unchecked(slice) - } + slice::from_raw_parts(brand_string_start, size_of::()) + }; + + str::from_utf8(slice).unwrap_or("InvalidVendorString") } } @@ -4193,15 +4190,11 @@ pub struct SoCVendorBrand { impl SoCVendorBrand { pub fn as_string<'a>(&'a self) -> &'a str { let brand_string_start = self as *const SoCVendorBrand as *const u8; - unsafe { + let slice = unsafe { // Safety: SoCVendorBrand is laid out with repr(C). - let slice: &'a [u8] = - slice::from_raw_parts(brand_string_start, size_of::()); - // Safety: The field is specified to be ASCII, and the only safe - // way to construct SoCVendorBrand is from real CPUID data or the - // Default implementation. - str::from_utf8_unchecked(slice) - } + slice::from_raw_parts(brand_string_start, size_of::()) + }; + str::from_utf8(slice).unwrap_or("InvalidSoCVendorString") } } @@ -4329,10 +4322,7 @@ impl ExtendedFunctionInfo { // Brand terminated at nul byte or end, whichever comes first. let slice = slice.split(|&x| x == 0).next().unwrap(); - // Safety: Field is specified to be ASCII, and the only safe way - // to construct ExtendedFunctionInfo is from real CPUID data - // or the Default implementation. - Some(unsafe { str::from_utf8_unchecked(slice) }) + str::from_utf8(slice).ok() } else { None }