diff options
-rw-r--r-- | .cargo_vcs_info.json | 2 | ||||
-rw-r--r-- | .github/workflows/ci.yml | 6 | ||||
-rw-r--r-- | Android.bp | 4 | ||||
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | Cargo.toml.orig | 2 | ||||
-rw-r--r-- | METADATA | 8 | ||||
-rw-r--r-- | build.rs | 4 | ||||
-rw-r--r-- | src/convert.rs | 19 | ||||
-rw-r--r-- | src/fallback.rs | 100 | ||||
-rw-r--r-- | src/lib.rs | 4 | ||||
-rw-r--r-- | src/parse.rs | 17 | ||||
-rw-r--r-- | src/rcvec.rs | 3 | ||||
-rw-r--r-- | tests/test.rs | 35 |
13 files changed, 175 insertions, 31 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index 9742e0b..c26dd7c 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,6 +1,6 @@ { "git": { - "sha1": "9f9328b7f016d3f7782ee9443dc441d63abe5b09" + "sha1": "72ee0b3b0523395e75bf71ae7702e93a7c506f1a" }, "path_in_vcs": "" }
\ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3e1bbba..1299805 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -97,6 +97,12 @@ jobs: - uses: dtolnay/rust-toolchain@nightly - uses: dtolnay/install@cargo-fuzz - run: cargo fuzz check + - run: cargo check --no-default-features --features afl + working-directory: fuzz + - uses: dtolnay/install@honggfuzz + - run: sudo apt-get install binutils-dev libunwind-dev + - run: cargo hfuzz build --no-default-features --features honggfuzz + working-directory: fuzz clippy: name: Clippy @@ -41,7 +41,7 @@ rust_library_host { name: "libproc_macro2", crate_name: "proc_macro2", cargo_env_compat: true, - cargo_pkg_version: "1.0.54", + cargo_pkg_version: "1.0.56", srcs: ["src/lib.rs"], edition: "2018", features: [ @@ -67,7 +67,7 @@ rust_defaults { name: "proc-macro2_test_defaults", crate_name: "proc_macro2", cargo_env_compat: true, - cargo_pkg_version: "1.0.54", + cargo_pkg_version: "1.0.56", test_suites: ["general-tests"], auto_gen_config: true, edition: "2018", @@ -13,7 +13,7 @@ edition = "2018" rust-version = "1.31" name = "proc-macro2" -version = "1.0.54" +version = "1.0.56" authors = [ "David Tolnay <dtolnay@gmail.com>", "Alex Crichton <alex@alexcrichton.com>", diff --git a/Cargo.toml.orig b/Cargo.toml.orig index 385bf0f..791d5e9 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -1,6 +1,6 @@ [package] name = "proc-macro2" -version = "1.0.54" # remember to update html_root_url +version = "1.0.56" # remember to update html_root_url authors = ["David Tolnay <dtolnay@gmail.com>", "Alex Crichton <alex@alexcrichton.com>"] autobenches = false categories = ["development-tools::procedural-macro-helpers"] @@ -11,13 +11,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/proc-macro2/proc-macro2-1.0.54.crate" + value: "https://static.crates.io/crates/proc-macro2/proc-macro2-1.0.56.crate" } - version: "1.0.54" + version: "1.0.56" license_type: NOTICE last_upgrade_date { year: 2023 - month: 3 - day: 30 + month: 4 + day: 3 } } @@ -72,6 +72,10 @@ fn main() { println!("cargo:rustc-cfg=no_libprocmacro_unwind_safe"); } + if version.minor < 34 { + println!("cargo:rustc-cfg=no_try_from"); + } + if version.minor < 39 { println!("cargo:rustc-cfg=no_bind_by_move_pattern_guard"); } diff --git a/src/convert.rs b/src/convert.rs new file mode 100644 index 0000000..afc5faf --- /dev/null +++ b/src/convert.rs @@ -0,0 +1,19 @@ +pub(crate) fn usize_to_u32(u: usize) -> Option<u32> { + #[cfg(not(no_try_from))] + { + use core::convert::TryFrom; + + u32::try_from(u).ok() + } + + #[cfg(no_try_from)] + { + use core::mem; + + if mem::size_of::<usize>() <= mem::size_of::<u32>() || u <= u32::max_value() as usize { + Some(u as u32) + } else { + None + } + } +} diff --git a/src/fallback.rs b/src/fallback.rs index 29d3933..bbea473 100644 --- a/src/fallback.rs +++ b/src/fallback.rs @@ -958,12 +958,25 @@ impl Literal { pub fn string(t: &str) -> Literal { let mut repr = String::with_capacity(t.len() + 2); repr.push('"'); - for c in t.chars() { - if c == '\'' { + let mut chars = t.chars(); + while let Some(ch) = chars.next() { + if ch == '\0' { + repr.push_str( + if chars + .as_str() + .starts_with(|next| '0' <= next && next <= '7') + { + // circumvent clippy::octal_escapes lint + "\\x00" + } else { + "\\0" + }, + ); + } else if ch == '\'' { // escape_debug turns this into "\'" which is unnecessary. - repr.push(c); + repr.push(ch); } else { - repr.extend(c.escape_debug()); + repr.extend(ch.escape_debug()); } } repr.push('"'); @@ -985,16 +998,21 @@ impl Literal { pub fn byte_string(bytes: &[u8]) -> Literal { let mut escaped = "b\"".to_string(); - for b in bytes { + let mut bytes = bytes.iter(); + while let Some(&b) = bytes.next() { #[allow(clippy::match_overlapping_arm)] - match *b { - b'\0' => escaped.push_str(r"\0"), + match b { + b'\0' => escaped.push_str(match bytes.as_slice().first() { + // circumvent clippy::octal_escapes lint + Some(b'0'..=b'7') => r"\x00", + _ => r"\0", + }), b'\t' => escaped.push_str(r"\t"), b'\n' => escaped.push_str(r"\n"), b'\r' => escaped.push_str(r"\r"), b'"' => escaped.push_str("\\\""), b'\\' => escaped.push_str("\\\\"), - b'\x20'..=b'\x7E' => escaped.push(*b as char), + b'\x20'..=b'\x7E' => escaped.push(b as char), _ => { let _ = write!(escaped, "\\x{:02X}", b); } @@ -1012,28 +1030,76 @@ impl Literal { self.span = span; } - pub fn subspan<R: RangeBounds<usize>>(&self, _range: R) -> Option<Span> { - None + pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> { + #[cfg(not(span_locations))] + { + let _ = range; + None + } + + #[cfg(span_locations)] + { + use crate::convert::usize_to_u32; + use core::ops::Bound; + + let lo = match range.start_bound() { + Bound::Included(start) => { + let start = usize_to_u32(*start)?; + self.span.lo.checked_add(start)? + } + Bound::Excluded(start) => { + let start = usize_to_u32(*start)?; + self.span.lo.checked_add(start)?.checked_add(1)? + } + Bound::Unbounded => self.span.lo, + }; + let hi = match range.end_bound() { + Bound::Included(end) => { + let end = usize_to_u32(*end)?; + self.span.lo.checked_add(end)?.checked_add(1)? + } + Bound::Excluded(end) => { + let end = usize_to_u32(*end)?; + self.span.lo.checked_add(end)? + } + Bound::Unbounded => self.span.hi, + }; + if lo <= hi && hi <= self.span.hi { + Some(Span { lo, hi }) + } else { + None + } + } } } impl FromStr for Literal { type Err = LexError; - fn from_str(mut repr: &str) -> Result<Self, Self::Err> { - let negative = repr.starts_with('-'); + fn from_str(repr: &str) -> Result<Self, Self::Err> { + let mut cursor = get_cursor(repr); + #[cfg(span_locations)] + let lo = cursor.off; + + let negative = cursor.starts_with_char('-'); if negative { - repr = &repr[1..]; - if !repr.starts_with(|ch: char| ch.is_ascii_digit()) { + cursor = cursor.advance(1); + if !cursor.starts_with_fn(|ch| ch.is_ascii_digit()) { return Err(LexError::call_site()); } } - let cursor = get_cursor(repr); - if let Ok((_rest, mut literal)) = parse::literal(cursor) { - if literal.repr.len() == repr.len() { + + if let Ok((rest, mut literal)) = parse::literal(cursor) { + if rest.is_empty() { if negative { literal.repr.insert(0, '-'); } + literal.span = Span { + #[cfg(span_locations)] + lo, + #[cfg(span_locations)] + hi: rest.off, + }; return Ok(literal); } } @@ -86,7 +86,7 @@ //! a different thread. // Proc-macro2 types in rustdoc of other crates get linked to here. -#![doc(html_root_url = "https://docs.rs/proc-macro2/1.0.54")] +#![doc(html_root_url = "https://docs.rs/proc-macro2/1.0.56")] #![cfg_attr( any(proc_macro_span, super_unstable), feature(proc_macro_span, proc_macro_span_shrink) @@ -143,6 +143,8 @@ use crate::fallback as imp; mod imp; #[cfg(span_locations)] +mod convert; +#[cfg(span_locations)] mod location; use crate::extra::DelimSpan; diff --git a/src/parse.rs b/src/parse.rs index 82291da..be2425b 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -27,7 +27,18 @@ impl<'a> Cursor<'a> { self.rest.starts_with(s) } - fn is_empty(&self) -> bool { + pub fn starts_with_char(&self, ch: char) -> bool { + self.rest.starts_with(ch) + } + + pub fn starts_with_fn<Pattern>(&self, f: Pattern) -> bool + where + Pattern: FnMut(char) -> bool, + { + self.rest.starts_with(f) + } + + pub fn is_empty(&self) -> bool { self.rest.is_empty() } @@ -756,7 +767,7 @@ fn digits(mut input: Cursor) -> Result<Cursor, Reject> { fn punct(input: Cursor) -> PResult<Punct> { let (rest, ch) = punct_char(input)?; if ch == '\'' { - if ident_any(rest)?.0.starts_with("'") { + if ident_any(rest)?.0.starts_with_char('\'') { Err(Reject) } else { Ok((rest, Punct::new('\'', Spacing::Joint))) @@ -848,7 +859,7 @@ fn doc_comment_contents(input: Cursor) -> PResult<(&str, bool)> { Ok((input, (&s[3..s.len() - 2], true))) } else if input.starts_with("///") { let input = input.advance(3); - if input.starts_with("/") { + if input.starts_with_char('/') { return Err(Reject); } let (input, s) = take_until_newline_or_eof(input); diff --git a/src/rcvec.rs b/src/rcvec.rs index 86ca7d8..62298b4 100644 --- a/src/rcvec.rs +++ b/src/rcvec.rs @@ -1,5 +1,6 @@ use core::mem; use core::slice; +use std::panic::RefUnwindSafe; use std::rc::Rc; use std::vec; @@ -140,3 +141,5 @@ impl<T> Iterator for RcVecIntoIter<T> { self.inner.size_hint() } } + +impl<T> RefUnwindSafe for RcVec<T> where T: RefUnwindSafe {} diff --git a/tests/test.rs b/tests/test.rs index e0af151..75f69e2 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -1,7 +1,8 @@ #![allow( clippy::assertions_on_result_states, clippy::items_after_statements, - clippy::non_ascii_literal + clippy::non_ascii_literal, + clippy::octal_escapes )] use proc_macro2::{Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree}; @@ -114,6 +115,10 @@ fn literal_string() { assert_eq!(Literal::string("foo").to_string(), "\"foo\""); assert_eq!(Literal::string("\"").to_string(), "\"\\\"\""); assert_eq!(Literal::string("didn't").to_string(), "\"didn't\""); + assert_eq!( + Literal::string("a\00b\07c\08d\0e\0").to_string(), + "\"a\\x000b\\x007c\\08d\\0e\\0\"", + ); } #[test] @@ -147,6 +152,10 @@ fn literal_byte_string() { Literal::byte_string(b"\0\t\n\r\"\\2\x10").to_string(), "b\"\\0\\t\\n\\r\\\"\\\\2\\x10\"", ); + assert_eq!( + Literal::byte_string(b"a\00b\07c\08d\0e\0").to_string(), + "b\"a\\x000b\\x007c\\08d\\0e\\0\"", + ); } #[test] @@ -265,6 +274,30 @@ fn literal_parse() { } #[test] +fn literal_span() { + let positive = "0.1".parse::<Literal>().unwrap(); + let negative = "-0.1".parse::<Literal>().unwrap(); + let subspan = positive.subspan(1..2); + + #[cfg(not(span_locations))] + { + let _ = negative; + assert!(subspan.is_none()); + } + + #[cfg(span_locations)] + { + assert_eq!(positive.span().start().column, 0); + assert_eq!(positive.span().end().column, 3); + assert_eq!(negative.span().start().column, 0); + assert_eq!(negative.span().end().column, 4); + assert_eq!(subspan.unwrap().source_text().unwrap(), "."); + } + + assert!(positive.subspan(1..4).is_none()); +} + +#[test] fn roundtrip() { fn roundtrip(p: &str) { println!("parse: {}", p); |