antlr / stringtemplate4

StringTemplate 4
http://www.stringtemplate.org
Other
951 stars 231 forks source link

Trailing slash on the root dir leads to an IOException when calling URL.openstream() #276

Closed alexgast closed 2 years ago

alexgast commented 3 years ago

Instantiating a STGroupDir(URL root, ...), where root contains a trailing slash (/), leads to an Java IOException when calling URL.openstream() in the method public CompiledST loadTemplateFile(String prefix, String unqualifiedFileName). The reason is a doubleslash // coming from the expression f = new URL(root+prefix+unqualifiedFileName). Maybe URI normalizing could fix the problem, i.e. f = f.toURI().normalize().toURL(). This situation occurs (for example) after updating Apache Felix Framework to version 7.0.0 because of https://issues.apache.org/jira/browse/FELIX-6294.

StephanRichter commented 2 years ago

I can confirm this behaviour.

parrt commented 2 years ago

Wow. That's weird... thanks for the PR, @StephanRichter

Skoti commented 2 years ago

Instantiating a STGroupDir(URL root, ...), where root contains a trailing slash (/),

It's not only for the URL constructor.

Even if STGroupDir is initialized with a path string that do not ends with / it will add a trailing slash to the root in here:

    public STGroupDir(String dirName, char delimiterStartChar, char delimiterStopChar) {
        super(delimiterStartChar, delimiterStopChar);
        this.groupDirName = dirName;
        File dir = new File(dirName);
        if ( dir.exists() && dir.isDirectory() ) {
            // we found the directory and it'll be file based
            try {
                root = dir.toURI().toURL();

so the root (root = dir.toURI().toURL();) ends up with a trailing slash and later on when it is used to load the template it leads to an exception as described above.

Seems like the PR will fix that case too but it is still not released. Is there a chance for 4.3.2 to be released soon as a hot fix?

parrt commented 2 years ago

this is next on my list to look at....thanks!

parrt commented 2 years ago

this seems very strange to me. Why does toURL() adding trailing slash and are we trying to overcome a bug in the networking library? am I not using toURL() correctly?

parrt commented 2 years ago

this seems to pass:

@Test public void testSimpleGroupWithTrailingSlashOnDir() throws Exception {
    String dir = getRandomDir() + "/"; <---------------- add /
    writeFile(dir, "a.st", "a(x) ::= <<foo>>");
    STGroup group = new STGroupDir(dir);
    ST st = group.getInstanceOf("a");
    String expected = "foo";
    String result = st.render();
    assertEquals(expected, result);
}

maybe it has to be a URL like file:///... and not a file name?

parrt commented 2 years ago

I should also point out that without the /it also passes:

    @Test public void testSimpleGroup() throws Exception {
        String dir = getRandomDir();
        writeFile(dir, "a.st", "a(x) ::= <<foo>>");
        STGroup group = new STGroupDir(dir);
        ST st = group.getInstanceOf("a");
        String expected = "foo";
        String result = st.render();
        assertEquals(expected, result);
    }
parrt commented 2 years ago

@Skoti I've tried adding trailing slashes but I can't get it to fail. I definitely think this is related to the bug when there is a jar https://github.com/antlr/stringtemplate4/issues/293 But I'm having trouble replicating the exception. any simple test case would dramatically increase my ability to fix this. thanks!