From 223dade62b6bd64d240dd43027e7de329b93c688 Mon Sep 17 00:00:00 2001 From: ConnorSkees <39542938+ConnorSkees@users.noreply.github.com> Date: Sat, 16 May 2020 16:22:33 -0400 Subject: [PATCH] Emit proper error for escape sequence overflow Before this commit, escape sequences above std::char::MAX ('\u{10ffff}') would overflow and cause a panic. This commit replaces an `unwrap` with `ok_or` and a clearer error message. This message will likely change in the future in order to better conform to the `dart-sass` implementation which currently also fails to cleanly handle this overflow. See https://github.com/kaj/rsass/pull/73 --- src/utils/strings.rs | 10 +++++++--- tests/str-escape.rs | 4 ++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/utils/strings.rs b/src/utils/strings.rs index cd1399d..fae92c6 100644 --- a/src/utils/strings.rs +++ b/src/utils/strings.rs @@ -121,8 +121,9 @@ fn escape<I: Iterator<Item = Token>>( Some(t) => t, None => return Ok(String::new()), }; + let mut span = first.pos(); if first.kind == '\n' { - return Err(("Expected escape sequence.", first.pos()).into()); + return Err(("Expected escape sequence.", span).into()); } else if first.kind.is_ascii_hexdigit() { for _ in 0..6 { let next = match toks.peek() { @@ -133,16 +134,19 @@ fn escape<I: Iterator<Item = Token>>( break; } value *= 16; + span = span.merge(next.pos()); value += as_hex(toks.next().unwrap().kind) } if toks.peek().is_some() && toks.peek().unwrap().kind.is_whitespace() { toks.next(); } } else { - value = toks.next().unwrap().kind as u32; + let next = toks.next().unwrap(); + span = span.merge(next.pos()); + value = next.kind as u32; } - let c = std::char::from_u32(value).unwrap(); + let c = std::char::from_u32(value).ok_or(("Invalid escape sequence.", span))?; if (identifier_start && is_name_start(c) && !c.is_digit(10)) || (!identifier_start && is_name(c)) { diff --git a/tests/str-escape.rs b/tests/str-escape.rs index 5875cf2..c0ba921 100644 --- a/tests/str-escape.rs +++ b/tests/str-escape.rs @@ -168,3 +168,7 @@ test!( "a {\n color: \\9;\n}\n", "a {\n color: \\9 ;\n}\n" ); +error!( + escape_sequence_does_not_fit_inside_char, + "a {\n color: \\110000;\n}\n", "Error: Invalid escape sequence." +);