How to implement an InputXmlResolver for Xslt30Transformer on .NET so that local files can't be accessed?
Added by Martin Honnen almost 7 years ago
https://www.saxonica.com/html/documentation/dotnetdoc/Saxon/Api/Xslt30Transformer.html#InputXmlResolver allows me to assign an @XmlResolver@ "to be used at run-time to resolve and dereference URIs supplied to the doc() and document() functions".
How would I have to implement such an @XmlResolver@ so that @file:@ URIs don't work?
I have tried to subclass the @XmlUrlResolver@ as follows:
class CustomResolver : XmlUrlResolver
{
public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
{
if (absoluteUri.IsFile)
{
return null;
}
return base.GetEntity(absoluteUri, role, ofObjectToReturn);
}
public override Task GetEntityAsync(Uri absoluteUri, string role, Type ofObjectToReturn)
{
if (absoluteUri.IsFile)
{
return null;
}
return base.GetEntityAsync(absoluteUri, role, ofObjectToReturn);
}
public override Uri ResolveUri(Uri baseUri, string relativeUri)
{
return base.ResolveUri(baseUri, relativeUri);
}
}
that is, for the @GetEntity@ method the custom resolver returns @null@ instead of a @Stream@. However, that doesn't seem to change Saxon's (tested with NuGet package of Saxon 9.8.0.6 HE) behaviour at all, neither @document@ nor @doc-available@ nor @doc@ calls show any difference to a normal XmlUrlResolver. On the other hand, if I pass such a CustomResolver to Microsoft's @XslCompiledTransform@, it throws an error when encountering a @document@ call with a @file:@ URI.
Test code I used:
static void TestSaxon(string inputUri, string sheetUri, XmlResolver resolver)
{
Processor processor = new Processor();
using (XmlReader sheetReader = XmlReader.Create(sheetUri))
{
Xslt30Transformer transformer = processor.NewXsltCompiler().Compile(XmlReader.Create(sheetUri)).Load30();
transformer.InputXmlResolver = resolver;
Console.WriteLine("resolver: {0}", resolver.GetType().Name);
using (XmlReader inputReader = XmlReader.Create(inputUri))
{
DocumentBuilder docBuilder = processor.NewDocumentBuilder();
XdmNode inputNode = docBuilder.Build(inputReader);
transformer.ApplyTemplates(inputNode, processor.NewSerializer(Console.Out));
}
}
}
Run with
TestSaxon("../../available-tests/dummy-input1.xml", "../../available-tests/available-test1.xsl", new XmlUrlResolver());
Console.WriteLine();
TestSaxon("../../available-tests/dummy-input1.xml", "../../available-tests/available-test1.xsl", new CustomResolver());
Console.WriteLine();
where @dummy-input1.xml@ can be any XML input and the stylesheet is
If @test-doc1.xml@ and @test-text1.txt@ exist and the files @test-doc2.xml@ and @test-text2.txt@ don't exist then the result for Saxon is the same for both method calls:
resolver: XmlUrlResolver example content 1 Test text doc 1. Example text 1. resolver: CustomResolver example content 1 Test text doc 1. Example text 1.
So that approach doesn't in any restrict the use of @file:@ URLs? How would I have to implement the @InputXmlResolver@ to prevent file URL access? Or do I have to use some other setting or property?
Please register to reply