diff --git a/Cargo.toml b/Cargo.toml index 414b4e03..8bc1dae8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/servo/rust-cssparser" readme = "README.md" keywords = ["css", "syntax", "parser"] license = "MPL-2.0" -edition = "2018" +edition = "2024" rust-version = "1.85" exclude = ["src/css-parsing-tests/**", "src/big-data-url.css"] diff --git a/color/Cargo.toml b/color/Cargo.toml index 13153144..05d55daf 100644 --- a/color/Cargo.toml +++ b/color/Cargo.toml @@ -6,7 +6,7 @@ description = "Color implementation based on cssparser" documentation = "https://docs.rs/cssparser-color/" repository = "https://github.com/servo/rust-cssparser" license = "MPL-2.0" -edition = "2021" +edition = "2024" rust-version = "1.85" [lib] diff --git a/color/lib.rs b/color/lib.rs index bc59daff..93c8f198 100644 --- a/color/lib.rs +++ b/color/lib.rs @@ -12,10 +12,10 @@ mod tests; use cssparser::color::{ - clamp_floor_256_f32, clamp_unit_f32, parse_hash_color, serialize_color_alpha, - PredefinedColorSpace, OPAQUE, + OPAQUE, PredefinedColorSpace, clamp_floor_256_f32, clamp_unit_f32, parse_hash_color, + serialize_color_alpha, }; -use cssparser::{match_ignore_ascii_case, CowRcStr, ParseError, Parser, ToCss, Token}; +use cssparser::{CowRcStr, ParseError, Parser, ToCss, Token, match_ignore_ascii_case}; use std::f32::consts::PI; use std::fmt; @@ -1070,7 +1070,7 @@ pub trait FromParsedColor { /// Construct a new color from the `lab` notation. fn from_lab(lightness: Option, a: Option, b: Option, alpha: Option) - -> Self; + -> Self; /// Construct a new color from the `lch` notation. fn from_lch( diff --git a/color/tests.rs b/color/tests.rs index 98db40a3..7cfac15d 100644 --- a/color/tests.rs +++ b/color/tests.rs @@ -4,7 +4,7 @@ use super::*; use cssparser::ParserInput; -use serde_json::{json, Value}; +use serde_json::{Value, json}; fn almost_equals(a: &Value, b: &Value) -> bool { match (a, b) { diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index da45b9a2..656d7a45 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "arbitrary" @@ -14,25 +14,15 @@ version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - [[package]] name = "cssparser" -version = "0.28.1" +version = "0.38.0" dependencies = [ "cssparser-macros", "dtoa-short", "itoa", - "matches", "phf", - "proc-macro2", - "quote", "smallvec", - "syn", ] [[package]] @@ -45,10 +35,10 @@ dependencies = [ [[package]] name = "cssparser-macros" -version = "0.6.0" +version = "0.7.0" dependencies = [ "quote", - "syn", + "syn 3.0.4", ] [[package]] @@ -67,27 +57,16 @@ dependencies = [ ] [[package]] -name = "getrandom" -version = "0.1.16" +name = "fastrand" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" [[package]] name = "itoa" -version = "0.4.7" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" - -[[package]] -name = "libc" -version = "0.2.88" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03b07a082330a35e43f63177cc01689da34fbffa0105e1246cf0311472cac73a" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "libfuzzer-sys" @@ -99,142 +78,101 @@ dependencies = [ "cc", ] -[[package]] -name = "matches" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" - [[package]] name = "phf" -version = "0.8.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" +checksum = "010378780309880b08997fae13be7834dba947d36393bd372f2b1556deb2a2f6" dependencies = [ "phf_macros", "phf_shared", - "proc-macro-hack", + "serde", ] [[package]] name = "phf_generator" -version = "0.8.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" +checksum = "aeb62e0959d5a1bebc965f4d15d9e2b7cea002b6b0f5ba8cde6cc26738467100" dependencies = [ + "fastrand", "phf_shared", - "rand", ] [[package]] name = "phf_macros" -version = "0.8.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c" +checksum = "5fa8d0ca26d424d27630da600c6624696e7dec8bf7b3b492b383c5dc49e5e085" dependencies = [ "phf_generator", "phf_shared", - "proc-macro-hack", "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "phf_shared" -version = "0.8.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +checksum = "c6fd9027e2d9319be6349febd1db4e8d02aa544921200c9b777720ac34a3aa89" dependencies = [ "siphasher", ] -[[package]] -name = "ppv-lite86" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" - -[[package]] -name = "proc-macro-hack" -version = "0.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" - [[package]] name = "proc-macro2" -version = "1.0.24" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] name = "quote" -version = "1.0.9" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" dependencies = [ "proc-macro2", ] [[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom", - "libc", - "rand_chacha", - "rand_core", - "rand_hc", - "rand_pcg", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.5.1" +name = "serde" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" dependencies = [ - "getrandom", + "serde_core", ] [[package]] -name = "rand_hc" -version = "0.2.0" +name = "serde_core" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" dependencies = [ - "rand_core", + "serde_derive", ] [[package]] -name = "rand_pcg" -version = "0.2.1" +name = "serde_derive" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ - "rand_core", + "proc-macro2", + "quote", + "syn 3.0.4", ] [[package]] name = "siphasher" -version = "0.3.3" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa8f3741c7372e75519bd9346068370c9cdaabcc1f9599cbcf2a2719352286b7" +checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" [[package]] name = "smallvec" @@ -244,23 +182,28 @@ checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" [[package]] name = "syn" -version = "1.0.63" +version = "2.0.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd9bc7ccc2688b3344c2f48b9b546648b25ce0b20fc717ee7fa7981a8ca9717" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] -name = "unicode-xid" -version = "0.2.1" +name = "syn" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +checksum = "e6275cddf4610d1775e6d1fe9469b2e77d0f39fd98fb7450901b821e0c53649f" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] [[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" +name = "unicode-ident" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index ebe2036e..0d781215 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -4,7 +4,7 @@ name = "cssparser-fuzz" version = "0.0.0" authors = ["Automatically generated"] publish = false -edition = "2018" +edition = "2024" [package.metadata] cargo-fuzz = true diff --git a/fuzz/fuzz_targets/cssparser.rs b/fuzz/fuzz_targets/cssparser.rs index a9d89388..c95516d9 100644 --- a/fuzz/fuzz_targets/cssparser.rs +++ b/fuzz/fuzz_targets/cssparser.rs @@ -11,7 +11,7 @@ fn parse_and_serialize(input: &str, preserving_comments: bool) -> String { let result = do_parse_and_serialize( &mut parser, preserving_comments, - TokenSerializationType::nothing(), + TokenSerializationType::Nothing, &mut serialization, 0, ); @@ -27,7 +27,7 @@ fn do_parse_and_serialize<'i>( mut previous_token_type: TokenSerializationType, serialization: &mut String, indent_level: usize, -) -> Result<(), ParseError<'i, ()>> { +) -> Result<(), ParseError<()>> { loop { let token = if preserving_comments { input.next_including_whitespace_and_comments() @@ -45,8 +45,7 @@ fn do_parse_and_serialize<'i>( println!("{:?}", token); } if token.is_parse_error() { - let token = token.clone(); - return Err(input.new_unexpected_token_error(token)); + return Err(ParseError::unexpected_token()); } let token_type = token.serialization_type(); if previous_token_type.needs_separator_when_before(token_type) { diff --git a/src/cow_rc_str.rs b/src/cow_rc_str.rs index 65c89036..5edfd2aa 100644 --- a/src/cow_rc_str.rs +++ b/src/cow_rc_str.rs @@ -102,7 +102,7 @@ impl Clone for CowRcStr<'_> { #[cold] #[inline(never)] unsafe fn drop_slow(ptr: *const String) { - mem::drop(Rc::from_raw(ptr)) + unsafe { mem::drop(Rc::from_raw(ptr)) } } impl Drop for CowRcStr<'_> { diff --git a/src/lib.rs b/src/lib.rs index 0f48c1f9..61451dea 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -68,18 +68,18 @@ fn parse_border_spacing(_context: &ParserContext, input: &mut Parser) #![recursion_limit = "200"] // For color::parse_color_keyword pub use crate::cow_rc_str::CowRcStr; -pub use crate::from_bytes::{stylesheet_encoding, EncodingSupport}; +pub use crate::from_bytes::{EncodingSupport, stylesheet_encoding}; #[doc(hidden)] pub use crate::macros::_cssparser_internal_to_lowercase; pub use crate::nth::parse_nth; pub use crate::parser::{BasicParseError, BasicParseErrorKind, ParseError, ParseErrorKind}; pub use crate::parser::{Delimiter, Delimiters, Parser, ParserInput, ParserState}; -pub use crate::rules_and_declarations::{parse_important, parse_one_declaration}; -pub use crate::rules_and_declarations::{parse_one_rule, StyleSheetParser}; pub use crate::rules_and_declarations::{AtRuleParser, QualifiedRuleParser}; pub use crate::rules_and_declarations::{DeclarationParser, RuleBodyItemParser, RuleBodyParser}; -pub use crate::serializer::{serialize_identifier, serialize_name, serialize_string}; +pub use crate::rules_and_declarations::{StyleSheetParser, parse_one_rule}; +pub use crate::rules_and_declarations::{parse_important, parse_one_declaration}; pub use crate::serializer::{CssStringWriter, ToCss, TokenSerializationType}; +pub use crate::serializer::{serialize_identifier, serialize_name, serialize_string}; pub use crate::tokenizer::{SourceLocation, SourcePosition, Token}; pub use crate::unicode_range::UnicodeRange; diff --git a/src/parser.rs b/src/parser.rs index 2fe741f5..2efff17a 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -157,8 +157,8 @@ impl ParseErrorKind { impl fmt::Display for ParseErrorKind { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - ParseErrorKind::Basic(ref basic) => basic.fmt(f), - ParseErrorKind::Custom(ref custom) => custom.fmt(f), + ParseErrorKind::Basic(basic) => basic.fmt(f), + ParseErrorKind::Custom(custom) => custom.fmt(f), } } } diff --git a/src/rules_and_declarations.rs b/src/rules_and_declarations.rs index e28dc1b6..813224b8 100644 --- a/src/rules_and_declarations.rs +++ b/src/rules_and_declarations.rs @@ -6,7 +6,7 @@ use super::{BasicParseError, BasicParseErrorKind, Delimiter, ParseError, Parser, Token}; use crate::cow_rc_str::CowRcStr; -use crate::parser::{parse_nested_block, parse_until_after, ParseUntilErrorBehavior, ParserState}; +use crate::parser::{ParseUntilErrorBehavior, ParserState, parse_nested_block, parse_until_after}; use crate::tokenizer::SourceLocation; /// Parse `!important`. @@ -266,14 +266,14 @@ where | Token::WhiteSpace(..) | Token::Semicolon | Token::Comment(..) => continue, - Token::AtKeyword(ref name) => { + Token::AtKeyword(name) => { let name = name.clone(); return Some(parse_at_rule(&start, name, self.input, &mut *self.parser)); } // https://drafts.csswg.org/css-syntax/#consume-a-declaration bails out just to // keep parsing as a qualified rule if the token is not an ident, so we implement // that in a slightly more straight-forward way - Token::Ident(ref name) if self.parser.parse_declarations() => { + Token::Ident(name) if self.parser.parse_declarations() => { let name = name.clone(); let parse_qualified = self.parser.parse_qualified(); let result = { diff --git a/src/tests.rs b/src/tests.rs index b7de5d24..aa913c81 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -5,7 +5,7 @@ #[cfg(feature = "bench")] extern crate test; -use serde_json::{json, Map, Value}; +use serde_json::{Map, Value, json}; #[cfg(feature = "bench")] use crate::parser::ArbitrarySubstitutionFunctions; @@ -14,11 +14,11 @@ use crate::parser::ArbitrarySubstitutionFunctions; use self::test::Bencher; use super::{ - parse_important, parse_nth, parse_one_declaration, parse_one_rule, stylesheet_encoding, AtRuleParser, BasicParseError, BasicParseErrorKind, CowRcStr, DeclarationParser, Delimiter, EncodingSupport, ParseError, ParseErrorKind, Parser, ParserInput, ParserState, QualifiedRuleParser, RuleBodyItemParser, RuleBodyParser, SourceLocation, StyleSheetParser, - ToCss, Token, TokenSerializationType, UnicodeRange, + ToCss, Token, TokenSerializationType, UnicodeRange, parse_important, parse_nth, + parse_one_declaration, parse_one_rule, stylesheet_encoding, }; macro_rules! JArray { @@ -275,11 +275,13 @@ fn outer_block_end_consumed() { let mut input = ParserInput::new("(calc(true))"); let mut input = Parser::new(&mut input); assert!(input.expect_parenthesis_block().is_ok()); - assert!(input - .parse_nested_block(|input| input - .expect_function_matching("calc") - .map_err(Into::>::into)) - .is_ok()); + assert!( + input + .parse_nested_block(|input| input + .expect_function_matching("calc") + .map_err(Into::>::into)) + .is_ok() + ); println!("{:?}", input.position()); assert!(input.next().is_err()); } @@ -643,12 +645,14 @@ fn line_delimited() { let mut input = ParserInput::new(" { foo ; bar } baz;,"); let mut input = Parser::new(&mut input); assert_eq!(input.next(), Ok(&Token::CurlyBracketBlock)); - assert!({ - let result: Result<_, ParseError<()>> = - input.parse_until_after(Delimiter::Semicolon, |_| Ok(42)); - result - } - .is_err()); + assert!( + { + let result: Result<_, ParseError<()>> = + input.parse_until_after(Delimiter::Semicolon, |_| Ok(42)); + result + } + .is_err() + ); assert_eq!(input.next(), Ok(&Token::Comma)); assert!(input.next().is_err()); } @@ -904,24 +908,24 @@ impl<'i> DeclarationParser<'i> for JsonParser { let mut important = false; loop { let start = input.state(); - if let Ok(mut token) = input.next_including_whitespace().cloned() { - // Hack to deal with css-parsing-tests assuming that - // `!important` in the middle of a declaration value is OK. - // This can never happen per spec - // (even CSS Variables forbid top-level `!`) - if token == Token::Delim('!') { - input.reset(&start); - if parse_important(input).is_ok() && input.is_exhausted() { - important = true; - break; - } - input.reset(&start); - token = input.next_including_whitespace().unwrap().clone(); - } - value.push(one_component_value_to_json(token, input)); - } else { + let Ok(token) = input.next_including_whitespace() else { break; + }; + let mut token = token.clone(); + // Hack to deal with css-parsing-tests assuming that + // `!important` in the middle of a declaration value is OK. + // This can never happen per spec + // (even CSS Variables forbid top-level `!`) + if token == Token::Delim('!') { + input.reset(&start); + if parse_important(input).is_ok() && input.is_exhausted() { + important = true; + break; + } + input.reset(&start); + token = input.next_including_whitespace().unwrap().clone(); } + value.push(one_component_value_to_json(token, input)); } Ok(JArray!["declaration", name, value, important,]) } @@ -1004,8 +1008,8 @@ impl RuleBodyItemParser<'_, Value, ()> for JsonParser { fn component_values_to_json(input: &mut Parser) -> Vec { let mut values = vec![]; - while let Ok(token) = input.next_including_whitespace().cloned() { - values.push(one_component_value_to_json(token, input)); + while let Ok(token) = input.next_including_whitespace() { + values.push(one_component_value_to_json(token.clone(), input)); } values } diff --git a/src/tokenizer.rs b/src/tokenizer.rs index 9de5eea5..a1bca2d3 100644 --- a/src/tokenizer.rs +++ b/src/tokenizer.rs @@ -811,7 +811,7 @@ fn consume_quoted_string<'a>( single_quote: bool, ) -> Result, CowRcStr<'a>> { tokenizer.advance(1); // Skip the initial quote - // start_pos is at code point boundary, after " or ' + // start_pos is at code point boundary, after " or ' let start_pos = tokenizer.position(); let mut string_bytes; loop { @@ -1159,10 +1159,12 @@ fn consume_numeric<'a>(tokenizer: &mut Tokenizer<'a>) -> Token<'a> { #[inline] unsafe fn from_utf8_release_unchecked(string_bytes: Vec) -> String { - if cfg!(debug_assertions) { - String::from_utf8(string_bytes).unwrap() - } else { - String::from_utf8_unchecked(string_bytes) + unsafe { + if cfg!(debug_assertions) { + String::from_utf8(string_bytes).unwrap() + } else { + String::from_utf8_unchecked(string_bytes) + } } }