Not safe to share Spans from one ParseSess to another

Spans in the AST returned by `parse_item_from_source_str` and other parsing
functions contain byte offsets into the source code they were parsed from. The
pretty printer uses these Spans [here][1] to preserve the representation of
literals when parsing and printing back out unmodified.

In this bug, the byte offset of a string in the input to
`parse_item_from_source_str` coincidentally matched the byte offset of a totally
different string in the input to `parse_crate_from_file` called [here][2] by
Syntex. The Span from the former triggered the pretty printer to write out the
content of the latter.

By using the same ParseSess, Spans from the two `parse_*` calls never collide.

[1]: https://github.com/rust-lang/rust/blob/1.12.0/src/libsyntax/print/pprust.rs#L628
[2]: https://github.com/serde-rs/syntex/blob/v0.45.0/syntex/src/registry.rs#L134
This commit is contained in:
David Tolnay 2016-10-17 23:12:29 -07:00
parent 532b950971
commit 1d719b542c
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82

View File

@ -169,8 +169,8 @@ macro_rules! shim {
use syntax::parse;
let name = stringify!($name).to_string();
let cfg = Vec::new();
let sess = parse::ParseSess::new();
let impl_item = parse::parse_item_from_source_str(name, expanded, cfg, &sess);
let sess = cx.parse_sess;
let impl_item = parse::parse_item_from_source_str(name, expanded, cfg, sess);
push(::syntax::ext::base::Annotatable::Item(impl_item.unwrap().unwrap()));
}
};