diff options
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/Cargo.toml | 1 | ||||
-rw-r--r-- | components/script/body.rs | 7 | ||||
-rw-r--r-- | components/script/dom/blob.rs | 9 | ||||
-rw-r--r-- | components/script/dom/eventsource.rs | 42 | ||||
-rw-r--r-- | components/script/dom/textencoder.rs | 7 | ||||
-rw-r--r-- | components/script/lib.rs | 1 |
6 files changed, 46 insertions, 21 deletions
diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml index bc6c17a8871..346ab0ab165 100644 --- a/components/script/Cargo.toml +++ b/components/script/Cargo.toml @@ -89,6 +89,7 @@ swapper = "0.0.4" time = "0.1.12" unicode-segmentation = "1.1.0" url = {version = "1.2", features = ["heap_size", "query_encoding"]} +utf-8 = "0.7" uuid = {version = "0.4", features = ["v4"]} xml5ever = {version = "0.7", features = ["unstable"]} webrender_traits = {git = "https://github.com/servo/webrender", features = ["ipc"]} diff --git a/components/script/body.rs b/components/script/body.rs index 1967d69cf50..80c9be5d49f 100644 --- a/components/script/body.rs +++ b/components/script/body.rs @@ -11,8 +11,6 @@ use dom::blob::{Blob, BlobImpl}; use dom::formdata::FormData; use dom::globalscope::GlobalScope; use dom::promise::Promise; -use encoding::all::UTF_8; -use encoding::types::{DecoderTrap, Encoding}; use js::jsapi::JSContext; use js::jsapi::JS_ClearPendingException; use js::jsapi::JS_ParseJSON; @@ -110,14 +108,13 @@ fn run_package_data_algorithm<T: BodyOperations + DomObject>(object: &T, } fn run_text_data_algorithm(bytes: Vec<u8>) -> Fallible<FetchedData> { - let text = UTF_8.decode(&bytes, DecoderTrap::Replace).unwrap(); - Ok(FetchedData::Text(text)) + Ok(FetchedData::Text(String::from_utf8_lossy(&bytes).into_owned())) } #[allow(unsafe_code)] fn run_json_data_algorithm(cx: *mut JSContext, bytes: Vec<u8>) -> Fallible<FetchedData> { - let json_text = UTF_8.decode(&bytes, DecoderTrap::Replace).unwrap(); + let json_text = String::from_utf8_lossy(&bytes); let json_text: Vec<u16> = json_text.encode_utf16().collect(); rooted!(in(cx) let mut rval = UndefinedValue()); unsafe { diff --git a/components/script/dom/blob.rs b/components/script/dom/blob.rs index c076282dcc1..ddf14fc8096 100644 --- a/components/script/dom/blob.rs +++ b/components/script/dom/blob.rs @@ -12,8 +12,6 @@ use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object}; use dom::bindings::str::DOMString; use dom::globalscope::GlobalScope; use dom_struct::dom_struct; -use encoding::all::UTF_8; -use encoding::types::{EncoderTrap, Encoding}; use ipc_channel::ipc; use net_traits::{CoreResourceMsg, IpcSend}; use net_traits::blob_url_store::{BlobBuf, get_blob_origin}; @@ -337,12 +335,11 @@ pub fn blob_parts_to_bytes(blobparts: Vec<BlobOrString>) -> Result<Vec<u8>, ()> for blobpart in &blobparts { match blobpart { &BlobOrString::String(ref s) => { - let mut bytes = UTF_8.encode(s, EncoderTrap::Replace).map_err(|_|())?; - ret.append(&mut bytes); + ret.extend(s.as_bytes()); }, &BlobOrString::Blob(ref b) => { - let mut bytes = b.get_bytes().unwrap_or(vec![]); - ret.append(&mut bytes); + let bytes = b.get_bytes().unwrap_or(vec![]); + ret.extend(bytes); }, } } diff --git a/components/script/dom/eventsource.rs b/components/script/dom/eventsource.rs index 7945eec0b7d..81a2bc87584 100644 --- a/components/script/dom/eventsource.rs +++ b/components/script/dom/eventsource.rs @@ -16,8 +16,6 @@ use dom::eventtarget::EventTarget; use dom::globalscope::GlobalScope; use dom::messageevent::MessageEvent; use dom_struct::dom_struct; -use encoding::Encoding; -use encoding::all::UTF_8; use euclid::length::Length; use hyper::header::{Accept, qitem}; use ipc_channel::ipc; @@ -39,6 +37,7 @@ use std::str::{Chars, FromStr}; use std::sync::{Arc, Mutex}; use task_source::TaskSource; use timers::OneshotTimerCallback; +use utf8; header! { (LastEventId, "Last-Event-ID") => [String] } @@ -76,6 +75,8 @@ enum ParserState { } struct EventSourceContext { + incomplete_utf8: Option<utf8::Incomplete>, + event_source: Trusted<EventSource>, gen_id: GenerationId, action_sender: ipc::IpcSender<FetchResponseMsg>, @@ -293,12 +294,41 @@ impl FetchResponseListener for EventSourceContext { } fn process_response_chunk(&mut self, chunk: Vec<u8>) { - let mut stream = String::new(); - UTF_8.raw_decoder().raw_feed(&chunk, &mut stream); - self.parse(stream.chars()) + let mut input = &*chunk; + if let Some(mut incomplete) = self.incomplete_utf8.take() { + match incomplete.try_complete(input) { + None => return, + Some((result, remaining_input)) => { + self.parse(result.unwrap_or("\u{FFFD}").chars()); + input = remaining_input; + } + } + } + + while !input.is_empty() { + match utf8::decode(&input) { + Ok(s) => { + self.parse(s.chars()); + return + } + Err(utf8::DecodeError::Invalid { valid_prefix, remaining_input, .. }) => { + self.parse(valid_prefix.chars()); + self.parse("\u{FFFD}".chars()); + input = remaining_input; + } + Err(utf8::DecodeError::Incomplete { valid_prefix, incomplete_suffix }) => { + self.parse(valid_prefix.chars()); + self.incomplete_utf8 = Some(incomplete_suffix); + return + } + } + } } fn process_response_eof(&mut self, _response: Result<(), NetworkError>) { + if let Some(_) = self.incomplete_utf8.take() { + self.parse("\u{FFFD}".chars()); + } self.reestablish_the_connection(); } } @@ -378,6 +408,8 @@ impl EventSource { // Step 14 let (action_sender, action_receiver) = ipc::channel().unwrap(); let context = EventSourceContext { + incomplete_utf8: None, + event_source: Trusted::new(&ev), gen_id: ev.generation_id.get(), action_sender: action_sender.clone(), diff --git a/components/script/dom/textencoder.rs b/components/script/dom/textencoder.rs index 765c95ade0b..5cdbeca1dd3 100644 --- a/components/script/dom/textencoder.rs +++ b/components/script/dom/textencoder.rs @@ -11,9 +11,6 @@ use dom::bindings::reflector::{Reflector, reflect_dom_object}; use dom::bindings::str::{DOMString, USVString}; use dom::globalscope::GlobalScope; use dom_struct::dom_struct; -use encoding::EncoderTrap; -use encoding::Encoding; -use encoding::all::UTF_8; use js::jsapi::{JSContext, JSObject}; use js::typedarray::{Uint8Array, CreateWith}; use std::ptr; @@ -45,13 +42,13 @@ impl TextEncoder { impl TextEncoderMethods for TextEncoder { // https://encoding.spec.whatwg.org/#dom-textencoder-encoding fn Encoding(&self) -> DOMString { - DOMString::from(UTF_8.name()) + DOMString::from("utf-8") } #[allow(unsafe_code)] // https://encoding.spec.whatwg.org/#dom-textencoder-encode unsafe fn Encode(&self, cx: *mut JSContext, input: USVString) -> NonZero<*mut JSObject> { - let encoded = UTF_8.encode(&input.0, EncoderTrap::Strict).unwrap(); + let encoded = input.0.as_bytes(); rooted!(in(cx) let mut js_object = ptr::null_mut()); assert!(Uint8Array::create(cx, CreateWith::Slice(&encoded), js_object.handle_mut()).is_ok()); diff --git a/components/script/lib.rs b/components/script/lib.rs index 6e0b75d7ef9..1dc74905cc9 100644 --- a/components/script/lib.rs +++ b/components/script/lib.rs @@ -102,6 +102,7 @@ extern crate time; extern crate tinyfiledialogs; extern crate unicode_segmentation; extern crate url; +extern crate utf8; extern crate uuid; extern crate webrender_traits; extern crate webvr_traits; |