diff --git a/src/parse/value.rs b/src/parse/value.rs index 60d8e53..827fb02 100644 --- a/src/parse/value.rs +++ b/src/parse/value.rs @@ -528,15 +528,16 @@ impl<'a> Parser<'a> { fn parse_hex(&mut self) -> SassResult> { let mut s = String::with_capacity(7); s.push('#'); - if self + let first_char = self .toks .peek() .ok_or(("Expected identifier.", self.span_before))? - .kind - .is_ascii_hexdigit() - { + .kind; + let first_is_digit = first_char.is_ascii_digit(); + let first_is_hexdigit = first_char.is_ascii_hexdigit(); + if first_is_digit { while let Some(c) = self.toks.peek() { - if !c.kind.is_ascii_hexdigit() { + if !c.kind.is_ascii_hexdigit() || s.len() == 9 { break; } let tok = self.toks.next().unwrap(); @@ -548,10 +549,17 @@ impl<'a> Parser<'a> { // that is, `#ooobar`. } else { let ident = self.parse_identifier()?; - return Ok(Spanned { - node: Value::String(format!("#{}", ident.node), QuoteKind::None), - span: ident.span, - }); + if first_is_hexdigit + && ident.node.chars().all(|c| c.is_ascii_hexdigit()) + && matches!(ident.node.len(), 3 | 4 | 6 | 8) + { + s.push_str(&ident.node); + } else { + return Ok(Spanned { + node: Value::String(format!("#{}", ident.node), QuoteKind::None), + span: ident.span, + }); + } } let v = match u32::from_str_radix(&s[1..], 16) { Ok(a) => a, diff --git a/tests/color.rs b/tests/color.rs index e518003..d5b5ad0 100644 --- a/tests/color.rs +++ b/tests/color.rs @@ -593,7 +593,17 @@ test!( "a {\n color: #ooobar;\n}\n" ); test!( - more_than_8_hex_chars_after_hash, + more_than_8_hex_chars_after_hash_starts_with_letter, "a {\n color: #ffffffffff;\n}\n", "a {\n color: #ffffffffff;\n}\n" ); +test!( + more_than_8_hex_chars_after_hash_starts_with_number, + "a {\n color: #0000000000;\n}\n", + "a {\n color: #00000000 0;\n}\n" +); +test!( + more_than_8_hex_chars_after_hash_starts_with_number_contains_hex_char, + "a {\n color: #00000000f00;\n}\n", + "a {\n color: #00000000 f00;\n}\n" +);