From 05b8dd913e07c2188a63c230cbe0986536cc1741 Mon Sep 17 00:00:00 2001 From: Stanislav Tkach Date: Fri, 16 Apr 2021 19:37:11 +0300 Subject: [PATCH] Replace the utf-8 library with std::str::from_utf8 usage --- Cargo.toml | 1 - src/protocol/message.rs | 57 +++++++++++++++++------------------------ 2 files changed, 24 insertions(+), 34 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5b579c9..2f633e7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,6 @@ rand = "0.8.0" sha-1 = "0.9" thiserror = "1.0.23" url = "2.1.0" -utf-8 = "0.7.5" [dependencies.native-tls-crate] optional = true diff --git a/src/protocol/message.rs b/src/protocol/message.rs index 6720c3c..0cd6d46 100644 --- a/src/protocol/message.rs +++ b/src/protocol/message.rs @@ -9,14 +9,12 @@ use super::frame::CloseFrame; use crate::error::{CapacityError, Error, Result}; mod string_collect { - use utf8::DecodeError; - use crate::error::{Error, Result}; #[derive(Debug)] pub struct StringCollector { data: String, - incomplete: Option, + incomplete: Option>, } impl StringCollector { @@ -25,46 +23,39 @@ mod string_collect { } pub fn len(&self) -> usize { - self.data - .len() - .saturating_add(self.incomplete.map(|i| i.buffer_len as usize).unwrap_or(0)) + self.data.len().saturating_add(self.incomplete.as_ref().map(|i| i.len()).unwrap_or(0)) } pub fn extend>(&mut self, tail: T) -> Result<()> { let mut input: &[u8] = tail.as_ref(); + if input.is_empty() { + return Ok(()); + } - if let Some(mut incomplete) = self.incomplete.take() { - if let Some((result, rest)) = incomplete.try_complete(input) { - input = rest; - if let Ok(text) = result { - self.data.push_str(text); - } else { - return Err(Error::Utf8); - } - } else { - input = &[]; - self.incomplete = Some(incomplete); - } + let incomplete = self.incomplete.take().map(|mut i| { + i.extend_from_slice(input); + i + }); + if let Some(i) = incomplete.as_ref() { + input = i.as_slice(); } - if !input.is_empty() { - match utf8::decode(input) { - Ok(text) => { - self.data.push_str(text); - Ok(()) - } - Err(DecodeError::Incomplete { valid_prefix, incomplete_suffix }) => { - self.data.push_str(valid_prefix); - self.incomplete = Some(incomplete_suffix); - Ok(()) - } - Err(DecodeError::Invalid { valid_prefix, .. }) => { - self.data.push_str(valid_prefix); + match std::str::from_utf8(input) { + Ok(text) => { + self.data.push_str(text); + Ok(()) + } + Err(e) => { + // The incomplete part cannot be longer than 4 bytes (char). + if e.valid_up_to() == 0 || input.len() - e.valid_up_to() > 4 { Err(Error::Utf8) + } else { + let (valid, incomplete) = input.split_at(e.valid_up_to()); + self.data.push_str(unsafe { std::str::from_utf8_unchecked(valid) }); + self.incomplete = Some(incomplete.to_owned()); + Ok(()) } } - } else { - Ok(()) } }