Skip to content

Commit 6ffb7eb

Browse files
committed
procedural-masquerade: don’t normalize whitespace in string literals.
1 parent 3ad1cba commit 6ffb7eb

File tree

3 files changed

+45
-14
lines changed

3 files changed

+45
-14
lines changed

procedural-masquerade/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "procedural-masquerade"
3-
version = "0.1.0"
3+
version = "0.1.1"
44
authors = ["Simon Sapin <simon.sapin@exyr.org>"]
55
description = "macro_rules for making proc_macro_derive pretending to be proc_macro"
66
documentation = "https://docs.rs/procedural-masquerade/"

procedural-masquerade/lib.rs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ macro_rules! define_proc_macros {
175175
pub fn $proc_macro_name(derive_input: ::proc_macro::TokenStream)
176176
-> ::proc_macro::TokenStream {
177177
let $input = derive_input.to_string();
178-
let $input: &str = &$crate::_extract_input(&$input);
178+
let $input = $crate::_extract_input(&$input);
179179
$body.parse().unwrap()
180180
}
181181
)+
@@ -186,21 +186,26 @@ macro_rules! define_proc_macros {
186186
///
187187
/// **This function is not part of the public API. It can change or be removed between any versions.**
188188
#[doc(hidden)]
189-
pub fn _extract_input(derive_input: &str) -> String {
190-
let mut normalized = String::with_capacity(derive_input.len());
191-
for piece in derive_input.split_whitespace() {
192-
normalized.push_str(piece);
193-
normalized.push(' ');
189+
pub fn _extract_input(derive_input: &str) -> &str {
190+
let mut input = derive_input;
191+
192+
for expected in &["#[allow(unused)]", "enum", "ProceduralMasqueradeDummyType", "{",
193+
"Input", "=", "(0,", "stringify!", "("] {
194+
input = input.trim_left();
195+
assert!(input.starts_with(expected),
196+
"expected prefix {:?} not found in {:?}", expected, derive_input);
197+
input = &input[expected.len()..];
194198
}
195199

196-
let prefix = "#[allow(unused)] enum ProceduralMasqueradeDummyType { Input = (0, stringify!(";
197-
let suffix = ")).0, } ";
198-
assert!(normalized.starts_with(prefix), "expected prefix not found in {:?}", derive_input);
199-
assert!(normalized.ends_with(suffix), "expected suffix not found in {:?}", derive_input);
200+
for expected in [")", ").0,", "}"].iter().rev() {
201+
input = input.trim_right();
202+
assert!(input.ends_with(expected),
203+
"expected suffix {:?} not found in {:?}", expected, derive_input);
204+
let end = input.len() - expected.len();
205+
input = &input[..end];
206+
}
200207

201-
let start = prefix.len();
202-
let end = normalized.len() - suffix.len();
203-
normalized[start..end].to_owned()
208+
input
204209
}
205210

206211
/// This macro expands to the definition of another macro (whose name is given as a parameter).

src/tests.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -817,3 +817,29 @@ fn one_component_value_to_json(token: Token, input: &mut Parser) -> Json {
817817
Token::CloseCurlyBracket => JArray!["error", "}"],
818818
}
819819
}
820+
821+
/// A previous version of procedural-masquerade had a bug where it
822+
/// would normalize consecutive whitespace to a single space,
823+
/// including in string literals.
824+
#[test]
825+
fn procedural_masquerade_whitespace() {
826+
ascii_case_insensitive_phf_map! {
827+
map -> () = {
828+
" \t\n" => ()
829+
}
830+
}
831+
assert_eq!(map(" \t\n"), Some(&()));
832+
assert_eq!(map(" "), None);
833+
834+
match_ignore_ascii_case! { " \t\n",
835+
" " => panic!("1"),
836+
" \t\n" => {},
837+
_ => panic!("2"),
838+
}
839+
840+
match_ignore_ascii_case! { " ",
841+
" \t\n" => panic!("3"),
842+
" " => {},
843+
_ => panic!("4"),
844+
}
845+
}

0 commit comments

Comments
 (0)