[librsvg/librsvg-2.48] (#582) - Parse XML processing instructions with xml5ever so we can build on Rust 1.39
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg/librsvg-2.48] (#582) - Parse XML processing instructions with xml5ever so we can build on Rust 1.39
- Date: Fri, 3 Apr 2020 18:47:51 +0000 (UTC)
commit b61c41f20daa5326b491ff4eff21711694298531
Author: Federico Mena Quintero <federico gnome org>
Date: Wed Apr 1 17:17:00 2020 -0600
(#582) - Parse XML processing instructions with xml5ever so we can build on Rust 1.39
Apparently xml-rs is using #[cfg(doctest)], which was made stable since
Rust 1.40.
Fixes https://gitlab.gnome.org/GNOME/librsvg/-/issues/582
Cargo.lock | 31 ++++++++++++++---
rsvg_internals/Cargo.toml | 2 +-
rsvg_internals/src/lib.rs | 1 -
rsvg_internals/src/xml.rs | 89 +++++++++++++++++++++++++++++++++++++----------
4 files changed, 99 insertions(+), 24 deletions(-)
---
diff --git a/Cargo.lock b/Cargo.lock
index f77caea5..fbbf318b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1088,6 +1088,11 @@ dependencies = [
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "redox_syscall"
+version = "0.1.56"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
[[package]]
name = "regex"
version = "1.3.6"
@@ -1147,7 +1152,7 @@ dependencies = [
"regex 1.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"selectors 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
"url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "xml-rs 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "xml5ever 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1326,6 +1331,16 @@ dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "time"
+version = "0.1.42"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "tinytemplate"
version = "1.0.3"
@@ -1424,9 +1439,15 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
-name = "xml-rs"
-version = "0.8.1"
+name = "xml5ever"
+version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "markup5ever 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
+]
[metadata]
"checksum aho-corasick 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)" =
"8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada"
@@ -1550,6 +1571,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" =
"08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9"
"checksum rctree 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" =
"be9e29cb19c8fe84169fcb07f8f11e66bc9e6e0280efd4715c54818296f8a4a8"
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" =
"678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
+"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" =
"2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
"checksum regex 1.3.6 (registry+https://github.com/rust-lang/crates.io-index)" =
"7f6946991529684867e47d86474e3a6d0c0ab9b82d5821e314b1ede31fa3a4b3"
"checksum regex-automata 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" =
"ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4"
"checksum regex-syntax 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)" =
"7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae"
@@ -1575,6 +1597,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" =
"d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
"checksum thin-slice 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" =
"8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c"
"checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" =
"d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
+"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" =
"db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
"checksum tinytemplate 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" =
"57a3c6667d3e65eb1bc3aed6fd14011c6cbc3a0665218ab7f5daf040b9ec371a"
"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" =
"6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" =
"49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
@@ -1589,4 +1612,4 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" =
"ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-util 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" =
"fa515c5163a99cc82bab70fd3bfdd36d827be85de63737b40fcef2ce084a436e"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" =
"712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
-"checksum xml-rs 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" =
"9afd061c1c7c8ef0a3d337fbf76fc8c098bd0dfefd4adaafef25a559352f2031"
+"checksum xml5ever 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" =
"0b1b52e6e8614d4a58b8e70cf51ec0cc21b256ad8206708bcff8139b5bbd6a59"
diff --git a/rsvg_internals/Cargo.toml b/rsvg_internals/Cargo.toml
index 4cb4669b..fb9b451b 100644
--- a/rsvg_internals/Cargo.toml
+++ b/rsvg_internals/Cargo.toml
@@ -36,7 +36,7 @@ rctree = "0.3.3"
regex = "1"
selectors = "0.22.0"
url = "2"
-xml-rs = "0.8.0"
+xml5ever = "0.16.1"
[dev-dependencies]
criterion = "0.2"
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index 7f589e5c..e72566fe 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -38,7 +38,6 @@
#![allow(clippy::not_unsafe_ptr_arg_deref)]
#![allow(clippy::too_many_arguments)]
#![warn(unused)]
-use ::xml as xml_rs;
pub use crate::color::Color;
diff --git a/rsvg_internals/src/xml.rs b/rsvg_internals/src/xml.rs
index ad5456de..31872da1 100644
--- a/rsvg_internals/src/xml.rs
+++ b/rsvg_internals/src/xml.rs
@@ -4,12 +4,16 @@ use encoding::label::encoding_from_whatwg_label;
use encoding::DecoderTrap;
use libc;
use markup5ever::{
- expanded_name, local_name, namespace_url, ns, ExpandedName, LocalName, Namespace, QualName,
+ buffer_queue::BufferQueue, expanded_name, local_name, namespace_url, ns, ExpandedName,
+ LocalName, Namespace, QualName,
};
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::{Rc, Weak};
use std::str;
+use std::string::ToString;
+use xml5ever::tendril::format_tendril;
+use xml5ever::tokenizer::{TagKind, Token, TokenSink, XmlTokenizer, XmlTokenizerOpts};
use crate::allowed_url::AllowedUrl;
use crate::document::{Document, DocumentBuilder};
@@ -21,7 +25,6 @@ use crate::property_bag::PropertyBag;
use crate::style::{Style, StyleType};
use crate::text::NodeChars;
use crate::xml2_load::Xml2Parser;
-use crate::xml_rs::{reader::XmlEvent, ParserConfig};
#[derive(Clone)]
enum Context {
@@ -620,6 +623,36 @@ impl Drop for XmlState {
}
}
+/// Temporary holding space for data in an XML processing instruction
+#[derive(Default)]
+struct ProcessingInstructionData {
+ attributes: Vec<(String, String)>,
+ error: bool,
+}
+
+struct ProcessingInstructionSink(Rc<RefCell<ProcessingInstructionData>>);
+
+impl TokenSink for ProcessingInstructionSink {
+ fn process_token(&mut self, token: Token) {
+ let mut data = self.0.borrow_mut();
+
+ match token {
+ Token::TagToken(tag) if tag.kind == TagKind::EmptyTag => {
+ for a in &tag.attrs {
+ let name = a.name.local.as_ref().to_string();
+ let value = a.value.to_string();
+
+ data.attributes.push((name, value));
+ }
+ }
+
+ Token::ParseError(_) => data.error = true,
+
+ _ => (),
+ }
+ }
+}
+
// https://www.w3.org/TR/xml-stylesheet/
//
// The syntax for the xml-stylesheet processing instruction we support
@@ -631,26 +664,26 @@ impl Drop for XmlState {
// ("xml-stylesheet"), so we'll create a mini-parser with a hackish
// element just to extract the data as attributes.
fn parse_xml_stylesheet_processing_instruction(data: &str) -> Result<Vec<(String, String)>, ()> {
- let xml_str = format!("<rsvg-hack {} />\n", data);
+ let pi_data = Rc::new(RefCell::new(ProcessingInstructionData {
+ attributes: Vec::new(),
+ error: false,
+ }));
- let mut buf = xml_str.as_bytes();
+ let mut queue = BufferQueue::new();
+ queue.push_back(format_tendril!("<rsvg-hack {} />", data));
- let reader = ParserConfig::new().create_reader(&mut buf);
+ let sink = ProcessingInstructionSink(pi_data.clone());
- for event in reader {
- match event {
- Ok(XmlEvent::StartElement { attributes, .. }) => {
- return Ok(attributes
- .iter()
- .map(|att| (att.name.local_name.clone(), att.value.clone()))
- .collect());
- }
- Err(_) => return Err(()),
- _ => (),
- }
- }
+ let mut tokenizer = XmlTokenizer::new(sink, XmlTokenizerOpts::default());
+ tokenizer.run(&mut queue);
- unreachable!();
+ let pi_data = pi_data.borrow();
+
+ if pi_data.error {
+ return Err(());
+ } else {
+ return Ok(pi_data.attributes.clone());
+ }
}
pub fn xml_load_from_possibly_compressed_stream(
@@ -667,3 +700,23 @@ pub fn xml_load_from_possibly_compressed_stream(
state.build_document(&stream, cancellable)
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn parses_processing_instruction_data() {
+ let mut r =
+ parse_xml_stylesheet_processing_instruction("foo=\"bar\" baz=\"beep\"").unwrap();
+ r.sort_by(|a, b| a.0.cmp(&b.0));
+
+ assert_eq!(
+ r,
+ vec![
+ ("baz".to_string(), "beep".to_string()),
+ ("foo".to_string(), "bar".to_string())
+ ]
+ );
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]