Skip to content

Commit 6549528

Browse files
committed
Add auto-deref workaround for ZeroizeOnDrop
1 parent 9d8d620 commit 6549528

File tree

2 files changed

+35
-7
lines changed

2 files changed

+35
-7
lines changed

zeroize/derive/src/lib.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,13 @@ fn derive_zeroize(mut s: synstructure::Structure<'_>) -> TokenStream {
6969

7070
/// Custom derive for `ZeroizeOnDrop`
7171
fn derive_zeroize_on_drop(mut s: synstructure::Structure<'_>) -> TokenStream {
72-
let zeroizers = generate_fields(&mut s);
72+
let zeroizers = generate_fields(&mut s, quote! { zeroize_or_on_drop });
7373

7474
let drop_impl = s.gen_impl(quote! {
7575
gen impl Drop for @Self {
7676
fn drop(&mut self) {
77+
use zeroize::AssertZeroize;
78+
use zeroize::AssertZeroizeOnDrop;
7779
match self {
7880
#zeroizers
7981
}
@@ -251,7 +253,7 @@ impl ZeroizeAttrs {
251253
}
252254
}
253255

254-
fn generate_fields(s: &mut synstructure::Structure<'_>) -> TokenStream {
256+
fn generate_fields(s: &mut synstructure::Structure<'_>, method: TokenStream) -> TokenStream {
255257
s.bind_with(|_| BindStyle::RefMut);
256258

257259
s.filter_variants(|vi| {
@@ -265,7 +267,7 @@ fn generate_fields(s: &mut synstructure::Structure<'_>) -> TokenStream {
265267
result
266268
})
267269
.filter(|bi| filter_skip(&bi.ast().attrs, true))
268-
.each(|bi| quote! { #bi.zeroize(); })
270+
.each(|bi| quote! { #bi.#method(); })
269271
}
270272

271273
fn filter_skip(attrs: &[Attribute], start: bool) -> bool {
@@ -291,7 +293,7 @@ fn filter_skip(attrs: &[Attribute], start: bool) -> bool {
291293

292294
/// Custom derive for `Zeroize` (without `Drop`)
293295
fn derive_zeroize_without_drop(mut s: synstructure::Structure<'_>) -> TokenStream {
294-
let zeroizers = generate_fields(&mut s);
296+
let zeroizers = generate_fields(&mut s, quote! { zeroize });
295297

296298
s.bound_impl(
297299
quote!(zeroize::Zeroize),
@@ -507,15 +509,17 @@ mod tests {
507509
const _DERIVE_Drop_FOR_Z: () = {
508510
impl Drop for Z {
509511
fn drop(&mut self) {
512+
use zeroize::AssertZeroize;
513+
use zeroize::AssertZeroizeOnDrop;
510514
match self {
511515
Z {
512516
a: ref mut __binding_0,
513517
b: ref mut __binding_1,
514518
c: ref mut __binding_2,
515519
} => {
516-
{ __binding_0.zeroize(); }
517-
{ __binding_1.zeroize(); }
518-
{ __binding_2.zeroize(); }
520+
{ __binding_0.zeroize_or_on_drop(); }
521+
{ __binding_1.zeroize_or_on_drop(); }
522+
{ __binding_2.zeroize_or_on_drop(); }
519523
}
520524
}
521525
}

zeroize/src/lib.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,30 @@ pub trait Zeroize {
263263
#[allow(drop_bounds)]
264264
pub trait ZeroizeOnDrop: Drop {}
265265

266+
/// Auto-deref workaround for deriving `ZeroizeOnDrop`.
267+
#[doc(hidden)]
268+
pub trait AssertZeroizeOnDrop {
269+
fn zeroize_or_on_drop(&mut self);
270+
}
271+
272+
#[doc(hidden)]
273+
impl<T: ZeroizeOnDrop> AssertZeroizeOnDrop for &mut T {
274+
fn zeroize_or_on_drop(&mut self) {}
275+
}
276+
277+
/// Auto-deref workaround for deriving `ZeroizeOnDrop`.
278+
#[doc(hidden)]
279+
pub trait AssertZeroize {
280+
fn zeroize_or_on_drop(&mut self);
281+
}
282+
283+
#[doc(hidden)]
284+
impl<T: Zeroize> AssertZeroize for T {
285+
fn zeroize_or_on_drop(&mut self) {
286+
self.zeroize()
287+
}
288+
}
289+
266290
/// Marker trait for types whose `Default` is the desired zeroization result
267291
pub trait DefaultIsZeroes: Copy + Default + Sized {}
268292

0 commit comments

Comments
 (0)