From 264d828654ff323595e28c8a1f08214481f40f9c Mon Sep 17 00:00:00 2001 From: Claudio Bley Date: Tue, 8 May 2018 23:02:24 +0200 Subject: Treat unicode hex digits case-insensitively In Rust >= 1.24.0 we could have used `char::is_ascii_hexdigit`, but to keep compatiblity with older versions, `char::is_digit(16)` is used. Fixes #240. --- src/tokens.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'src/tokens.rs') diff --git a/src/tokens.rs b/src/tokens.rs index bcabd94..3f47f02 100644 --- a/src/tokens.rs +++ b/src/tokens.rs @@ -2,6 +2,7 @@ use std::borrow::Cow; use std::char; use std::str; use std::string; +use std::string::String as StdString; use self::Token::*; @@ -369,19 +370,15 @@ impl<'a> Tokenizer<'a> { } fn hex(&mut self, start: usize, i: usize, len: usize) -> Result { - let mut val = 0; + let mut buf = StdString::with_capacity(len); for _ in 0..len { match self.one() { - Some((_, ch)) if '0' <= ch && ch <= '9' => { - val = val * 16 + (ch as u32 - '0' as u32); - } - Some((_, ch)) if 'A' <= ch && ch <= 'F' => { - val = val * 16 + (ch as u32 - 'A' as u32) + 10; - } + Some((_, ch)) if ch as u32 <= 0x7F && ch.is_digit(16) => buf.push(ch), Some((i, ch)) => return Err(Error::InvalidHexEscape(i, ch)), None => return Err(Error::UnterminatedString(start)), } } + let val = u32::from_str_radix(&buf, 16).unwrap(); match char::from_u32(val) { Some(ch) => Ok(ch), None => Err(Error::InvalidEscapeValue(i, val)), -- cgit v1.2.3