From 020c5d74706754981c14f35d50ac48034bd00fd9 Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Sun, 30 Apr 2023 11:54:11 +0100 Subject: [PATCH 1/3] Encapsulate unsafe in _cssparser_internal_to_lowercase macro This allows it to be used in codebases with #[forbid(unsafe)]. Also document the safety invariant for the unsafe block --- src/macros.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/macros.rs b/src/macros.rs index 1dfacbb5..69b5801b 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -121,11 +121,19 @@ macro_rules! ascii_case_insensitive_phf_map { #[doc(hidden)] macro_rules! _cssparser_internal_to_lowercase { ($input: expr, $BUFFER_SIZE: expr => $output: ident) => { - #[allow(unsafe_code)] - let mut buffer = unsafe { - ::std::mem::MaybeUninit::<[::std::mem::MaybeUninit; $BUFFER_SIZE]>::uninit() - .assume_init() - }; + /// Create a new array of MaybeUninit items, in an uninitialized state. + #[inline(always)] + fn create_uninit_array() -> [::std::mem::MaybeUninit; N] { + unsafe { + // SAFETY: An uninitialized `[MaybeUninit<_>; LEN]` is valid. + // See: https://doc.rust-lang.org/stable/core/mem/union.MaybeUninit.html#method.uninit_array + ::std::mem::MaybeUninit::<[::std::mem::MaybeUninit; N]>::uninit() + .assume_init() + } + } + + const BUFFER_SIZE: usize = $BUFFER_SIZE as usize; + let mut buffer = create_uninit_array::(); let input: &str = $input; let $output = $crate::_cssparser_internal_to_lowercase(&mut buffer, input); }; From 8982f0be11b6a05e93b5348282fd69623c861a27 Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Sun, 30 Apr 2023 12:06:43 +0100 Subject: [PATCH 2/3] Move function outside of macro definition --- src/macros.rs | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/macros.rs b/src/macros.rs index 69b5801b..34aa0e27 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -110,6 +110,16 @@ macro_rules! ascii_case_insensitive_phf_map { } } +/// Create a new array of MaybeUninit items, in an uninitialized state. +#[inline(always)] +pub fn _cssparser_internal_create_uninit_array() -> [MaybeUninit; N] { + unsafe { + // SAFETY: An uninitialized `[MaybeUninit<_>; LEN]` is valid. + // See: https://doc.rust-lang.org/stable/core/mem/union.MaybeUninit.html#method.uninit_array + MaybeUninit::<[MaybeUninit; N]>::uninit().assume_init() + } +} + /// Implementation detail of match_ignore_ascii_case! and ascii_case_insensitive_phf_map! macros. /// /// **This macro is not part of the public API. It can change or be removed between any versions.** @@ -121,19 +131,8 @@ macro_rules! ascii_case_insensitive_phf_map { #[doc(hidden)] macro_rules! _cssparser_internal_to_lowercase { ($input: expr, $BUFFER_SIZE: expr => $output: ident) => { - /// Create a new array of MaybeUninit items, in an uninitialized state. - #[inline(always)] - fn create_uninit_array() -> [::std::mem::MaybeUninit; N] { - unsafe { - // SAFETY: An uninitialized `[MaybeUninit<_>; LEN]` is valid. - // See: https://doc.rust-lang.org/stable/core/mem/union.MaybeUninit.html#method.uninit_array - ::std::mem::MaybeUninit::<[::std::mem::MaybeUninit; N]>::uninit() - .assume_init() - } - } - const BUFFER_SIZE: usize = $BUFFER_SIZE as usize; - let mut buffer = create_uninit_array::(); + let mut buffer = $crate::macros::_cssparser_internal_create_uninit_array::(); let input: &str = $input; let $output = $crate::_cssparser_internal_to_lowercase(&mut buffer, input); }; From 39ea1b07a899e76ed2bb3e311c39992f79f0baab Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Sun, 30 Apr 2023 12:10:47 +0100 Subject: [PATCH 3/3] Fix fn reference and remove usize cast --- src/lib.rs | 4 +++- src/macros.rs | 3 +-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 2c580a61..bac46221 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -75,7 +75,9 @@ pub use crate::color::{ pub use crate::cow_rc_str::CowRcStr; pub use crate::from_bytes::{stylesheet_encoding, EncodingSupport}; #[doc(hidden)] -pub use crate::macros::_cssparser_internal_to_lowercase; +pub use crate::macros::{ + _cssparser_internal_create_uninit_array, _cssparser_internal_to_lowercase, +}; pub use crate::nth::parse_nth; pub use crate::parser::{BasicParseError, BasicParseErrorKind, ParseError, ParseErrorKind}; pub use crate::parser::{Delimiter, Delimiters, Parser, ParserInput, ParserState}; diff --git a/src/macros.rs b/src/macros.rs index 34aa0e27..882b0bbc 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -131,8 +131,7 @@ pub fn _cssparser_internal_create_uninit_array() -> [MaybeUninit #[doc(hidden)] macro_rules! _cssparser_internal_to_lowercase { ($input: expr, $BUFFER_SIZE: expr => $output: ident) => { - const BUFFER_SIZE: usize = $BUFFER_SIZE as usize; - let mut buffer = $crate::macros::_cssparser_internal_create_uninit_array::(); + let mut buffer = $crate::_cssparser_internal_create_uninit_array::<{ $BUFFER_SIZE }>(); let input: &str = $input; let $output = $crate::_cssparser_internal_to_lowercase(&mut buffer, input); };