use qualname::{NamespaceUri, NcName, QName};
use std::rc::Rc;
use xrust::ErrorKind;
use xrust::item::{Item, Node};
use xrust::pattern::Pattern;
use xrust::security::{Feature, Policy};
use xrust::transform::callable::ActualParameters;
use xrust::transform::context::{ContextBuilder, StaticContextBuilder};
use xrust::transform::template::Template;
use xrust::transform::{Axis, KindTest, NodeMatch, NodeTest, Transform};
use xrust::value::Value;
use xrust::xdmerror::Error;
use xrust::xslt::from_document;
pub fn max_depth_np_1<N: Node, G>(make_empty_doc: G) -> Result<(), Error>
where
G: Fn() -> N,
{
let mut stctxt = StaticContextBuilder::new()
.message(|_| Ok(()))
.fetcher(|_| {
Err(Error::new(
xrust::ErrorKind::NotImplemented,
"not implemented",
))
})
.parser(|_| {
Err(Error::new(
xrust::ErrorKind::NotImplemented,
"not implemented",
))
})
.build();
let mut src_doc = make_empty_doc();
let top = src_doc
.new_element(QName::from_local_name(NcName::try_from("Top").unwrap()))
.expect("unable to create element");
src_doc.push(top).expect("unable to add element");
let x = Transform::ApplyTemplates(Box::new(Transform::Root), None, vec![]);
let ctxt = ContextBuilder::new()
.template(Template::new(
Pattern::try_from("child::Top").expect("unable to create Pattern for \"child::Top\""),
Transform::Literal(Item::<N>::Value(Rc::new(Value::from("at the top")))),
Some(0.0), vec![0], Some(1), None, String::from("child::Test"),
))
.template(Template::new(
Pattern::try_from("/").expect("unable to create Pattern for \"/\""),
Transform::ApplyTemplates(
Box::new(Transform::Step(NodeMatch {
axis: Axis::Child,
nodetest: NodeTest::Kind(KindTest::Any),
})),
None,
vec![],
), None, vec![0], None, None, String::from("/"),
))
.template(Template::new(
Pattern::try_from("child::text()")
.expect("unable to create Pattern for \"child::text()\""),
Transform::ContextItem, None, vec![0], None, None, String::from("child::text()"),
))
.context(vec![Item::Node(src_doc)])
.build();
ctxt.dispatch(&mut stctxt, &x).map(|_| ())
}
pub fn max_depth_np_2<N: Node, G>(make_empty_doc: G) -> Result<(), Error>
where
G: Fn() -> N,
{
let mut stctxt = StaticContextBuilder::new()
.message(|_| Ok(()))
.fetcher(|_| {
Err(Error::new(
xrust::ErrorKind::NotImplemented,
"not implemented",
))
})
.parser(|_| {
Err(Error::new(
xrust::ErrorKind::NotImplemented,
"not implemented",
))
})
.build();
let mut src_doc = make_empty_doc();
let mut top1 = src_doc
.new_element(QName::from_local_name(NcName::try_from("Top").unwrap()))
.expect("unable to create element");
src_doc.push(top1.clone()).expect("unable to add element");
let mut top2 = src_doc
.new_element(QName::from_local_name(NcName::try_from("Top").unwrap()))
.expect("unable to create element");
top1.push(top2.clone()).expect("unable to add element");
let top3 = src_doc
.new_element(QName::from_local_name(NcName::try_from("Top").unwrap()))
.expect("unable to create element");
top2.push(top3.clone()).expect("unable to add element");
let x = Transform::ApplyTemplates(Box::new(Transform::Root), None, vec![]);
let ctxt = ContextBuilder::new()
.template(Template::new(
Pattern::try_from("child::Top").expect("unable to create Pattern for \"child::Top\""),
Transform::ApplyTemplates(Box::new(Transform::ContextItem), None, vec![]), Some(0.0), vec![0], Some(1), None, String::from("child::Test"),
))
.template(Template::new(
Pattern::try_from("/").expect("unable to create Pattern for \"/\""),
Transform::ApplyTemplates(
Box::new(Transform::Step(NodeMatch {
axis: Axis::Child,
nodetest: NodeTest::Kind(KindTest::Any),
})),
None,
vec![],
), None, vec![0], None, None, String::from("/"),
))
.template(Template::new(
Pattern::try_from("child::text()")
.expect("unable to create Pattern for \"child::text()\""),
Transform::ContextItem, None, vec![0], None, None, String::from("child::text()"),
))
.context(vec![Item::Node(src_doc)])
.build();
if ctxt
.dispatch(&mut stctxt, &x)
.map(|_| ())
.is_err_and(|e| e.kind == ErrorKind::LimitExceeded)
{
Ok(())
} else {
panic!("failed to fail")
}
}
pub fn max_depth_pol_none<N: Node, G>(make_empty_doc: G) -> Result<(), Error>
where
G: Fn() -> N,
{
let mut stctxt = StaticContextBuilder::new()
.message(|_| Ok(()))
.fetcher(|_| {
Err(Error::new(
xrust::ErrorKind::NotImplemented,
"not implemented",
))
})
.parser(|_| {
Err(Error::new(
xrust::ErrorKind::NotImplemented,
"not implemented",
))
})
.build();
let mut src_doc = make_empty_doc();
let mut top = src_doc
.new_element(QName::from_local_name(NcName::try_from("Top").unwrap()))
.expect("unable to create element");
src_doc.push(top.clone()).expect("unable to add element");
for _ in 0..252 {
let nxt = src_doc
.new_element(QName::from_local_name(NcName::try_from("Top").unwrap()))
.expect("unable to create element");
top.push(nxt.clone()).expect("unable to add element");
top = nxt;
}
let mut policy: Policy<N> = Policy::new(QName::from_local_name(
NcName::try_from("test_policy").unwrap(),
));
policy.add(
QName::new_from_parts(
NcName::try_from("maximum-depth").unwrap(),
Some(
NamespaceUri::try_from(
"http://gitlab.gnome.org/World/Rust/markup-rs/xrust/transform",
)
.unwrap(),
),
),
Feature::Permitted(None),
);
let x = Transform::ApplyTemplates(Box::new(Transform::Root), None, vec![]);
let ctxt = ContextBuilder::new()
.policy(Rc::new(policy))
.expect("unable to set security policy")
.template(Template::new(
Pattern::try_from("child::Top").expect("unable to create Pattern for \"child::Top\""),
Transform::ApplyTemplates(
Box::new(Transform::Step(NodeMatch {
axis: Axis::Child,
nodetest: NodeTest::Kind(KindTest::Any),
})),
None,
vec![],
),
Some(0.0), vec![0], Some(1), None, String::from("child::Test"),
))
.template(Template::new(
Pattern::try_from("/").expect("unable to create Pattern for \"/\""),
Transform::ApplyTemplates(
Box::new(Transform::Step(NodeMatch {
axis: Axis::Child,
nodetest: NodeTest::Kind(KindTest::Any),
})),
None,
vec![],
), None, vec![0], None, None, String::from("/"),
))
.template(Template::new(
Pattern::try_from("child::text()")
.expect("unable to create Pattern for \"child::text()\""),
Transform::ContextItem, None, vec![0], None, None, String::from("child::text()"),
))
.context(vec![Item::Node(src_doc)])
.build();
ctxt.dispatch(&mut stctxt, &x).map(|_| ())
}
pub fn max_depth_pol_set_1<N: Node, G>(make_empty_doc: G) -> Result<(), Error>
where
G: Fn() -> N,
{
let mut stctxt = StaticContextBuilder::new()
.message(|_| Ok(()))
.fetcher(|_| {
Err(Error::new(
xrust::ErrorKind::NotImplemented,
"not implemented",
))
})
.parser(|_| {
Err(Error::new(
xrust::ErrorKind::NotImplemented,
"not implemented",
))
})
.build();
let mut src_doc = make_empty_doc();
let mut top = src_doc
.new_element(QName::from_local_name(NcName::try_from("Top").unwrap()))
.expect("unable to create element");
src_doc.push(top.clone()).expect("unable to add element");
for _ in 0..50 {
let nxt = src_doc
.new_element(QName::from_local_name(NcName::try_from("Top").unwrap()))
.expect("unable to create element");
top.push(nxt.clone()).expect("unable to add element");
top = nxt;
}
let mut policy: Policy<N> = Policy::new(QName::from_local_name(
NcName::try_from("test_policy").unwrap(),
));
policy.add(
QName::new_from_parts(
NcName::try_from("maximum-depth").unwrap(),
Some(
NamespaceUri::try_from(
"http://gitlab.gnome.org/World/Rust/markup-rs/xrust/transform",
)
.unwrap(),
),
),
Feature::Permitted(Some(Transform::Literal(Item::Value(Rc::new(Value::from(
100,
)))))),
);
let x = Transform::ApplyTemplates(Box::new(Transform::Root), None, vec![]);
let ctxt = ContextBuilder::new()
.policy(Rc::new(policy))
.expect("unable to set security policy")
.template(Template::new(
Pattern::try_from("child::Top").expect("unable to create Pattern for \"child::Top\""),
Transform::ApplyTemplates(
Box::new(Transform::Step(NodeMatch {
axis: Axis::Child,
nodetest: NodeTest::Kind(KindTest::Any),
})),
None,
vec![],
),
Some(0.0), vec![0], Some(1), None, String::from("child::Test"),
))
.template(Template::new(
Pattern::try_from("/").expect("unable to create Pattern for \"/\""),
Transform::ApplyTemplates(
Box::new(Transform::Step(NodeMatch {
axis: Axis::Child,
nodetest: NodeTest::Kind(KindTest::Any),
})),
None,
vec![],
), None, vec![0], None, None, String::from("/"),
))
.template(Template::new(
Pattern::try_from("child::text()")
.expect("unable to create Pattern for \"child::text()\""),
Transform::ContextItem, None, vec![0], None, None, String::from("child::text()"),
))
.context(vec![Item::Node(src_doc)])
.build();
ctxt.dispatch(&mut stctxt, &x).map(|_| ())
}
pub fn max_depth_pol_set_2<N: Node, G>(make_empty_doc: G) -> Result<(), Error>
where
G: Fn() -> N,
{
let mut stctxt = StaticContextBuilder::new()
.message(|_| Ok(()))
.fetcher(|_| {
Err(Error::new(
xrust::ErrorKind::NotImplemented,
"not implemented",
))
})
.parser(|_| {
Err(Error::new(
xrust::ErrorKind::NotImplemented,
"not implemented",
))
})
.build();
let mut src_doc = make_empty_doc();
let mut top = src_doc
.new_element(QName::from_local_name(NcName::try_from("Top").unwrap()))
.expect("unable to create element");
src_doc.push(top.clone()).expect("unable to add element");
for _ in 0..1150 {
let nxt = src_doc
.new_element(QName::from_local_name(NcName::try_from("Top").unwrap()))
.expect("unable to create element");
top.push(nxt.clone()).expect("unable to add element");
top = nxt;
}
let mut policy: Policy<N> = Policy::new(QName::from_local_name(
NcName::try_from("test_policy").unwrap(),
));
policy.add(
QName::new_from_parts(
NcName::try_from("maximum-depth").unwrap(),
Some(
NamespaceUri::try_from(
"http://gitlab.gnome.org/World/Rust/markup-rs/xrust/transform",
)
.unwrap(),
),
),
Feature::Permitted(Some(Transform::Literal(Item::Value(Rc::new(Value::from(
1000,
)))))),
);
let x = Transform::ApplyTemplates(Box::new(Transform::Root), None, vec![]);
let ctxt = ContextBuilder::new()
.policy(Rc::new(policy))
.expect("unable to set security policy")
.template(Template::new(
Pattern::try_from("child::Top").expect("unable to create Pattern for \"child::Top\""),
Transform::ApplyTemplates(
Box::new(Transform::Step(NodeMatch {
axis: Axis::Child,
nodetest: NodeTest::Kind(KindTest::Any),
})),
None,
vec![],
),
Some(0.0), vec![0], Some(1), None, String::from("child::Test"),
))
.template(Template::new(
Pattern::try_from("/").expect("unable to create Pattern for \"/\""),
Transform::ApplyTemplates(
Box::new(Transform::Step(NodeMatch {
axis: Axis::Child,
nodetest: NodeTest::Kind(KindTest::Any),
})),
None,
vec![],
), None, vec![0], None, None, String::from("/"),
))
.template(Template::new(
Pattern::try_from("child::text()")
.expect("unable to create Pattern for \"child::text()\""),
Transform::ContextItem, None, vec![0], None, None, String::from("child::text()"),
))
.context(vec![Item::Node(src_doc)])
.build();
if ctxt
.dispatch(&mut stctxt, &x)
.map(|_| ())
.is_err_and(|e| e.kind == ErrorKind::LimitExceeded)
{
Ok(())
} else {
panic!("failed to fail")
}
}
pub fn max_depth_callable_1<N: Node, G, H>(make_empty_doc: G, make_from_str: H) -> Result<(), Error>
where
G: Fn() -> N,
H: Fn(&str) -> Result<N, Error>,
{
let styledoc = make_from_str(
"<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:template name='recurse'>
<xsl:param name='count' select='0'/>
<xsl:message>recurse called <xsl:sequence select='$count'/> times</xsl:message>
<xsl:choose>
<xsl:when test='$count lt 250'>
<xsl:call-template name='recurse'>
<xsl:with-param name='count' select='$count + 1'/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:message>reached 250 recursions</xsl:message>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match='/'>
<xsl:call-template name='recurse'>
<xsl:with-param name='count' select='1'/>
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>",
)
.map_err(|e| Error::new(e.kind, format!("error parsing stylesheet: {}", e.message)))?;
let mut stctxt = StaticContextBuilder::new()
.message(|m| {
eprintln!("{}", m);
Ok(())
})
.fetcher(|_| {
Err(Error::new(
xrust::ErrorKind::NotImplemented,
"not implemented",
))
})
.parser(|_| {
Err(Error::new(
xrust::ErrorKind::NotImplemented,
"not implemented",
))
})
.build();
let mut src_doc = make_empty_doc();
let top = src_doc
.new_element(QName::from_local_name(NcName::try_from("Top").unwrap()))
.expect("unable to create element");
src_doc.push(top.clone()).expect("unable to add element");
let mut ctxt = from_document(styledoc, None, |s| make_from_str(s), |_| Ok(String::new()))?;
ctxt.context(vec![Item::Node(src_doc.clone())], 0);
if ctxt
.evaluate(&mut stctxt)
.map(|_| ())
.is_err_and(|e| e.kind == ErrorKind::LimitExceeded)
{
Ok(())
} else {
panic!("failed to fail")
}
}
pub fn sec_feature<N: Node, G>(make_empty_doc: G) -> Result<(), Error>
where
G: Fn() -> N,
{
let mut stctxt = StaticContextBuilder::new()
.message(|_| Ok(()))
.fetcher(|_| Err(Error::new(ErrorKind::NotImplemented, "not implemented")))
.parser(|_| Err(Error::new(ErrorKind::NotImplemented, "not implemented")))
.build();
let mut src_doc = make_empty_doc();
let top = src_doc
.new_element(QName::from_local_name(NcName::try_from("Top").unwrap()))
.expect("unable to create element");
src_doc.push(top.clone()).expect("unable to add element");
let mut policy: Policy<N> = Policy::new(QName::from_local_name(
NcName::try_from("test_policy").unwrap(),
));
policy.add(
QName::new_from_parts(
NcName::try_from("maximum-depth").unwrap(),
Some(
NamespaceUri::try_from(
"http://gitlab.gnome.org/World/Rust/markup-rs/xrust/transform",
)
.unwrap(),
),
),
Feature::Permitted(Some(Transform::Literal(Item::Value(Rc::new(Value::from(
1000,
)))))),
);
let x: Transform<N> = Transform::ApplyTemplates(Box::new(Transform::Root), None, vec![]);
let ctxt = ContextBuilder::new()
.policy(Rc::new(policy))
.expect("unable to set security policy")
.template(Template::new(
Pattern::try_from("child::Top").expect("unable to create Pattern for \"child::Top\""),
Transform::ApplyTemplates(
Box::new(Transform::Step(NodeMatch {
axis: Axis::Child,
nodetest: NodeTest::Kind(KindTest::Any),
})),
None,
vec![],
),
Some(0.0), vec![0], Some(1), None, String::from("child::Test"),
))
.template(Template::new(
Pattern::try_from("/").expect("unable to create Pattern for \"/\""),
Transform::ApplyTemplates(
Box::new(Transform::Step(NodeMatch {
axis: Axis::Child,
nodetest: NodeTest::Kind(KindTest::Any),
})),
None,
vec![],
), None, vec![0], None, None, String::from("/"),
))
.template(Template::new(
Pattern::try_from("child::text()")
.expect("unable to create Pattern for \"child::text()\""),
Transform::ContextItem, None, vec![0], None, None, String::from("child::text()"),
))
.context(vec![Item::Node(src_doc)])
.build();
let _ = ctxt.security_feature(
&QName::new_from_parts(
NcName::try_from("maximum-depth").unwrap(),
Some(
NamespaceUri::try_from(
"http://gitlab.gnome.org/World/Rust/markup-rs/xrust/transform",
)
.unwrap(),
),
),
ActualParameters::Named(vec![]),
)?;
ctxt.dispatch(&mut stctxt, &x).map(|_| ())
}