Skip to content

Commit 957f5c9

Browse files
authored
Support skipping variants with ZeroizeOnDrop (#109)
1 parent 2bf44d0 commit 957f5c9

File tree

3 files changed

+98
-48
lines changed

3 files changed

+98
-48
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111
- Use the `Copy` implementation for `Clone` and the `Ord` implementation for
1212
`PartialOrd` when custom bounds are present.
1313

14+
### Fixed
15+
- Support skipping only some variants with `ZeroizeOnDrop`.
16+
- Only generate single call to `zeroize()` with `ZeroizeOnDrop` on multiple
17+
fields or variants.
18+
1419
## [1.2.7] - 2023-12-14
1520

1621
### Fixed

src/test/zeroize.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,3 +230,46 @@ fn fqs() -> Result<()> {
230230
},
231231
)
232232
}
233+
234+
#[test]
235+
fn enum_skip() -> Result<()> {
236+
test_derive(
237+
quote! {
238+
#[derive_where(ZeroizeOnDrop)]
239+
enum Test<T> {
240+
A(std::marker::PhantomData<T>),
241+
#[derive_where(skip_inner)]
242+
B(std::marker::PhantomData<T>),
243+
}
244+
},
245+
#[cfg(not(feature = "zeroize-on-drop"))]
246+
quote! {
247+
#[automatically_derived]
248+
impl<T> ::core::ops::Drop for Test<T> {
249+
fn drop(&mut self) {
250+
::zeroize::Zeroize::zeroize(self);
251+
}
252+
}
253+
},
254+
#[cfg(feature = "zeroize-on-drop")]
255+
quote! {
256+
#[automatically_derived]
257+
impl <T> ::core::ops::Drop for Test<T> {
258+
fn drop(&mut self) {
259+
use ::zeroize::__internal::AssertZeroize;
260+
use ::zeroize::__internal::AssertZeroizeOnDrop;
261+
262+
match self {
263+
Test::A(ref mut __field_0) => {
264+
__field_0.zeroize_or_on_drop();
265+
}
266+
Test::B(ref mut __field_0) => { }
267+
}
268+
}
269+
}
270+
271+
#[automatically_derived]
272+
impl<T> ::zeroize::ZeroizeOnDrop for Test<T> { }
273+
},
274+
)
275+
}

src/trait_/zeroize_on_drop.rs

Lines changed: 50 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ use syn::{
77
Token,
88
};
99

10-
use crate::{
11-
util, Data, DeriveTrait, DeriveWhere, Error, Item, SimpleType, SplitGenerics, TraitImpl,
12-
};
10+
use crate::{util, DeriveTrait, DeriveWhere, Error, Item, SplitGenerics, TraitImpl};
11+
#[cfg(feature = "zeroize-on-drop")]
12+
use crate::{Data, SimpleType};
1313

1414
/// Dummy-struct implement [`Trait`](crate::Trait) for [`ZeroizeOnDrop`](https://docs.rs/zeroize/latest/zeroize/trait.ZeroizeOnDrop.html) .
1515
pub struct ZeroizeOnDrop;
@@ -97,80 +97,82 @@ impl TraitImpl for ZeroizeOnDrop {
9797
Item::Item(data) if data.is_empty(**trait_) => quote! {
9898
fn drop(&mut self) { }
9999
},
100+
#[cfg(feature = "zeroize-on-drop")]
100101
_ => {
101-
#[cfg(feature = "zeroize-on-drop")]
102-
{
103-
let crate_ = trait_.crate_();
104-
let internal = util::path_segment("__internal");
102+
let crate_ = trait_.crate_();
103+
let internal = util::path_segment("__internal");
105104

106-
let mut assert_zeroize = crate_.clone();
107-
assert_zeroize
108-
.segments
109-
.extend([internal.clone(), util::path_segment("AssertZeroize")]);
105+
let mut assert_zeroize = crate_.clone();
106+
assert_zeroize
107+
.segments
108+
.extend([internal.clone(), util::path_segment("AssertZeroize")]);
110109

111-
let mut assert_zeroize_on_drop = crate_;
112-
assert_zeroize_on_drop
113-
.segments
114-
.extend([internal, util::path_segment("AssertZeroizeOnDrop")]);
110+
let mut assert_zeroize_on_drop = crate_;
111+
assert_zeroize_on_drop
112+
.segments
113+
.extend([internal, util::path_segment("AssertZeroizeOnDrop")]);
115114

116-
quote! {
117-
fn drop(&mut self) {
118-
use #assert_zeroize;
119-
use #assert_zeroize_on_drop;
115+
quote! {
116+
fn drop(&mut self) {
117+
use #assert_zeroize;
118+
use #assert_zeroize_on_drop;
120119

121-
match self {
122-
#body
123-
}
120+
match self {
121+
#body
124122
}
125123
}
126124
}
127-
#[cfg(not(feature = "zeroize-on-drop"))]
125+
}
126+
#[cfg(not(feature = "zeroize-on-drop"))]
127+
_ => {
128+
// Use unused variables.
129+
let _ = body;
130+
131+
let path = util::path_from_root_and_strs(trait_.crate_(), &["Zeroize"]);
132+
128133
quote! {
129134
fn drop(&mut self) {
130-
#body
135+
#path::zeroize(self);
131136
}
132137
}
133138
}
134139
}
135140
}
136141

142+
#[cfg(feature = "zeroize-on-drop")]
137143
fn build_body(
138144
&self,
139145
_derive_where: &DeriveWhere,
140146
trait_: &DeriveTrait,
141147
data: &Data,
142148
) -> TokenStream {
143-
if data.is_empty(**trait_) {
144-
TokenStream::new()
145-
} else {
146-
match data.simple_type() {
147-
SimpleType::Struct(fields) | SimpleType::Tuple(fields) => {
148-
#[cfg(feature = "zeroize-on-drop")]
149-
{
150-
let self_pattern = fields.self_pattern_mut();
151-
let self_ident = data.iter_self_ident(**trait_);
152-
153-
quote! {
154-
#self_pattern => {
155-
#(#self_ident.zeroize_or_on_drop();)*
156-
}
149+
match data.simple_type() {
150+
SimpleType::Struct(fields) | SimpleType::Tuple(fields) => {
151+
#[cfg(feature = "zeroize-on-drop")]
152+
{
153+
let self_pattern = fields.self_pattern_mut();
154+
let self_ident = data.iter_self_ident(**trait_);
155+
156+
quote! {
157+
#self_pattern => {
158+
#(#self_ident.zeroize_or_on_drop();)*
157159
}
158160
}
159-
#[cfg(not(feature = "zeroize-on-drop"))]
160-
{
161-
// Use unused variables.
162-
let _ = fields;
161+
}
162+
#[cfg(not(feature = "zeroize-on-drop"))]
163+
{
164+
// Use unused variables.
165+
let _ = fields;
163166

164-
let path = util::path_from_root_and_strs(trait_.crate_(), &["Zeroize"]);
167+
let path = util::path_from_root_and_strs(trait_.crate_(), &["Zeroize"]);
165168

166-
quote! {
167-
#path::zeroize(self);
168-
}
169+
quote! {
170+
#path::zeroize(self);
169171
}
170172
}
171-
SimpleType::Unit(_) => TokenStream::new(),
172-
SimpleType::Union => unreachable!("unexpected trait for union"),
173173
}
174+
SimpleType::Unit(_) => TokenStream::new(),
175+
SimpleType::Union => unreachable!("unexpected trait for union"),
174176
}
175177
}
176178
}

0 commit comments

Comments
 (0)