From dff31114855382638129a7d846140afd5e18b2a5 Mon Sep 17 00:00:00 2001 From: LaughingMan Date: Fri, 3 Jul 2020 06:05:02 +0200 Subject: [PATCH] WGSL front end: Fix panic on invalid input MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Until now the WGSL parser would interpret a character index as a byte index. This could lead to a panic on invalid input strings like "\"\u{2}ПЀ\u{0}\"", because it would use that index to slice a string without ensuring the slicing happens on a character boundary. One possible fix would have been to call `str::find` instead of `position`, however by relying on `splitn` instead of slicing a str manually it is easier to convince ourselves that this code can no longer panic. Fixes https://github.com/gfx-rs/naga/issues/90 --- src/front/wgsl.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/front/wgsl.rs b/src/front/wgsl.rs index b5b1c5e2cb..15632b10b3 100644 --- a/src/front/wgsl.rs +++ b/src/front/wgsl.rs @@ -93,12 +93,15 @@ mod lex { (Token::Word(word), rest) } '"' => { - let base = chars.as_str(); - let len = match chars.position(|c| c == '"') { - Some(pos) => pos, - None => return (Token::UnterminatedString, chars.as_str()), - }; - (Token::String(&base[..len]), chars.as_str()) + let mut iter = chars.as_str().splitn(2, '"'); + + // splitn returns an iterator with at least one element, so unwrapping is fine + let quote_content = iter.next().unwrap(); + if let Some(rest) = iter.next() { + (Token::String(quote_content), rest) + } else { + (Token::UnterminatedString, quote_content) + } } '-' => { input = chars.as_str();