Project

Profile

Help

Support #6312

closed

URIResolver.resolve() is called with "file:/" instead of "file:///"

Added by Gerben Abbink 4 months ago. Updated 2 months ago.

Status:
Closed
Priority:
Low
Assignee:
-
Category:
-
Sprint/Milestone:
-
Start date:
2024-01-03
Due date:
% Done:

0%

Estimated time:
Legacy ID:
Applies to branch:
Fix Committed on Branch:
Fixed in Maintenance Release:
Platforms:

Description

My registered URIResolver is sometimes called with "file:/" instead of "file:///". This is not allowed under Windows.

For example:

.../xslt30-test-master/report/report-keywords.xsl

I guess there's a problem in net/sf/saxon/om/DocumentKey.java.


Files

report-keywords.xsl (2.85 KB) report-keywords.xsl Gerben Abbink, 2024-01-04 13:25
Actions #1

Updated by Norm Tovey-Walsh 4 months ago

It's really difficult to get this right in a cross-platform way. The whole file: scheme is un(der)specified at best.

Actions #2

Updated by Michael Kay 4 months ago

Could you please clarify:

(a) Under what conditions does the URI resolver get called with a "file:/" URI?

(b) What exactly is not allowed under Windows, and how does it fail?

(Note, the URI manipulation done by DocumentKey.normalizeURI() should only be used to compare whether two URIs are equivalent; it's not intended that it should produce a URI that can be dereferenced, and I don't immediately see how the result can find its way into a call of the URIResolver. But I'm open to persuasion if you can tell us exactly what you are doing and exactly how it fails.)

Actions #3

Updated by Gerben Abbink 4 months ago

According to Wikipedia "file://" and "file:///" are allowed under Windows, "file:/" is only allowed under UNIX.

https://en.wikipedia.org/wiki/File_URI_scheme

For example, MSEdge uses "file:///":

Under Windows, open a local file in MSEdge.
Richt-click on the page, select Share.
Click on Gmail.
Gmail creates an email, the local file has URL "file:///...".

I have attached the file (report-keywords.xsl). It is a file from xslt30-test.

public Source URIResolver.resolve(String href, String base) throws TransformerException{
	base=[file:///C:/XMLBP%20Test%20Files/XML%20Conformance%20Tests/xslt30-test-master/report/report-keywords.xsl << OK
	href=[file:/d:/projects/w3.org/xt3/catalog.xml] << WRONG

Java Stack

net.sf.saxon.lib.ResourceResolverWrappingURIResolver.resolve(ResourceResolverWrappingURIResolver.java:58)
net.sf.saxon.lib.ResourceRequest.resolve(ResourceRequest.java:138)
net.sf.saxon.functions.DocumentFn.resolveURI(DocumentFn.java:414)
net.sf.saxon.functions.DocumentFn.makeDoc(DocumentFn.java:249)
net.sf.saxon.functions.Doc.call(Doc.java:140)
net.sf.saxon.expr.SystemFunctionCall$SystemFunctionCallElaborator.lambda$elaborateForPull$1(SystemFunctionCall.java:605)
net.sf.saxon.expr.instruct.ApplyTemplates$ApplyTemplatesElaborator.lambda$elaborateForPush$1(ApplyTemplates.java:628)
net.sf.saxon.expr.elab.PushElaborator.lambda$elaborateForPull$0(PushElaborator.java:38)
net.sf.saxon.expr.ItemChecker$ItemCheckerElaborator.lambda$elaborateForPull$0(ItemChecker.java:453)
net.sf.saxon.expr.elab.LazyPullEvaluator.evaluate(LazyPullEvaluator.java:39)
net.sf.saxon.expr.elab.LearningEvaluator.evaluate(LearningEvaluator.java:61)
net.sf.saxon.expr.LetExpression$LetExprElaborator.lambda$setAllVariables$1(LetExpression.java:849)
net.sf.saxon.expr.LetExpression$LetExprElaborator.lambda$elaborateForPush$6(LetExpression.java:940)
net.sf.saxon.expr.instruct.NamedTemplate.expand(NamedTemplate.java:269)
net.sf.saxon.expr.instruct.CallTemplate$CallTemplateElaborator.lambda$elaborateForPush$1(CallTemplate.java:633)
net.sf.saxon.expr.instruct.TemplateRule.applyLeavingTail(TemplateRule.java:393)
net.sf.saxon.trans.Mode.handleRuleNotNull(Mode.java:587)
net.sf.saxon.trans.Mode.applyTemplates(Mode.java:521)
net.sf.saxon.trans.XsltController.applyTemplates(XsltController.java:684)
net.sf.saxon.s9api.Xslt30Transformer.applyTemplates(Xslt30Transformer.java:438)

Actions #4

Updated by Michael Kay 4 months ago

Like almost everything else concerned with the file URI scheme, the Wikipedia article is thoroughly confused, and rarely makes it clear which specification it is referring to. For example the sentence "These are called "legacy" file URLs as opposed to "healthy" file URLs." links only to an anonymous personal blog entry dating back to 1997, and which is now available only on the Wayback machine: it's not authoritative information in any way.

Moreover, I don't quite see how you justify your claim "According to Wikipedia "file://" and "file:///" are allowed under Windows, "file:/" is only allowed under UNIX." from the Wikipedia article (let alone from the definitive RFCs). In practice it's not what "Windows" allows that matters, it's what specific software running under Windows allows, for example the Java or .NET class libraries.

You don't make it clear what API code you are using to run the transformation. This is critical.

Actions #5

Updated by Gerben Abbink 4 months ago

//
https://www.saxonica.com/documentation12/#!javadoc/net.sf.saxon.s9api/XsltCompiler

XsltCompiler compiler = processor.newXsltCompiler();
compiler.setResourceResolver(new
ResourceResolverWrappingURIResolver(resolver));

and

Xslt30Transformer transformer = executable.load30();
transformer.setResourceResolver(new
ResourceResolverWrappingURIResolver(resolver));

On Thu, Jan 4, 2024 at 2:10 PM Saxonica Developer Community <
> wrote:

Actions #6

Updated by Michael Kay 4 months ago

Thanks, but what are the inputs being supplied to the XsltTransformer and XsltCompiler -- specifically, how do you specify the stylesheet and source document locations?

Actions #7

Updated by Gerben Abbink 4 months ago

I did some tests under Windows with Java. I found that in Java both "file:/" and "file:///" are allowed and "file:/" is preferred:

URL url = new URL("file:/C:/FOLDER/File.txt"); url.toString(); << file:/C:/FOLDER/Filter.txt

URL url = new URL("file:///C:/FOLDER/File.txt"); url.toString(); << file:/C:/FOLDER/Filter.txt

I don't think it is a Saxon problem, or even a Java problem. I will have to accept that Java prefers "file:/" over "file:///".

Actions #8

Updated by Norm Tovey-Walsh 4 months ago

Yes. There's a fair bit of effort to work around these problems in XML Resolver. See, for example, the collection of ad hoc mitigations in

https://github.com/xmlresolver/xmlresolver/blob/main/src/main/java/org/xmlresolver/utils/URIUtils.java

But Michael is right, in order to understand the problem, we need to see the precise APIs and inputs involved.

Actions #10

Updated by Gerben Abbink 4 months ago

The XSLT input is a SAXSource (XMLBlueprintSAXSource extends SAXSource):

// https://www.saxonica.com/documentation12/#!javadoc/net.sf.saxon.s9api/XsltCompiler 
XsltCompiler compiler = processor.newXsltCompiler();
compiler.setCompileWithTracing(traceList != null);
compiler.setErrorReporter(new XMLBlueprintS9APIErrorReporterToListener(new XMLBlueprintS9APIErrorListener(errorWriter), xsltInputData.getURL())); // errorWriter!
compiler.setResourceResolver(new ResourceResolverWrappingURIResolver(resolver)); // resolver(<import>, <include>)!

// https://www.saxonica.com/documentation12/#!javadoc/net.sf.saxon.s9api/XsltExecutable
**XsltExecutable executable = compiler.compile(new XMLBlueprintSAXSource(xsltInputData, resolver, errorWriter)); // resolver(XInclude)! errorWriter!**

// https://www.saxonica.com/documentation12/#!javadoc/net.sf.saxon.s9api/Xslt30Transformer
Xslt30Transformer transformer = executable.load30();
transformer.setBaseOutputURI(xsltInputData.getURL());

The XML input is an XdmItem (called xomInputTree):

**transformer.setGlobalContextItem(xomInputTree);**
transformer.applyTemplates(xomInputTree, serializer);

Actions #11

Updated by Norm Tovey-Walsh 4 months ago

What is the resolver in this line?

compiler.setResourceResolver(new ResourceResolverWrappingURIResolver(resolver)); // resolver(<import>, <include>)!
Actions #12

Updated by Gerben Abbink 3 months ago

That's my own resolver

public class XMLBlueprintResolver implements EntityResolver2, LSResourceResolver, URIResolver {

	// URIResolver
	// https://docs.oracle.com/en/java/javase/19/docs/api/java.xml/javax/xml/transform/Source.html
	@Override
	public Source resolve(String href, String base) throws TransformerException{
		href = XMLBlueprintURLHelper.adjustURL(href); // !!!
		base = XMLBlueprintURLHelper.adjustURL(base); // !!!

XMLBlueprintURLHelper.adjustURL is where I have to convert "file:/" to "file:///".

Actions #13

Updated by Michael Kay 2 months ago

Gerben, do you want to keep this issue open? I think if we're going to make progress with it then we need a concrete repro - something we can run on our own Windows machine that clearly demonstrates the problem.

Actions #14

Updated by Gerben Abbink 2 months ago

You can close it. It's more a Java problem than a Saxon problem.

On Thu, Feb 22, 2024 at 6:33 PM Saxonica Developer Community <
> wrote:

Actions #15

Updated by Michael Kay 2 months ago

  • Tracker changed from Bug to Support
  • Status changed from New to Closed

Please register to edit this issue

Also available in: Atom PDF