Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issues #276 and #293 by checking for double slashes in STGroupDir #294

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions contributors.txt
Expand Up @@ -69,3 +69,4 @@ YYYY/MM/DD, github id, Full name, email
2020/09/16, Dvoreth, Jarmila Emanuela Panwitz, jaremapan@gmail.com
2020/10/01, beccagaspard, Becca Gaspard, beccagaspard at gmail dot com
2021/11/10, StephanRichter, Stephan Richter, postbox: s.richter domain: srsoftware.de
2022/02/22, Mooninaut, Clement Cherlin, mooninaut at gmail dot com
3 changes: 2 additions & 1 deletion pom.xml
Expand Up @@ -28,7 +28,7 @@
and maintainable; it also provides an excellent defense against malicious
template authors.
</description>

<licenses>
<license>
<name>The BSD License</name>
Expand Down Expand Up @@ -67,6 +67,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.3.1</version>
<configuration>
<additionalOptions>-Xdoclint:none</additionalOptions>
<additionalJOption>-Xdoclint:none</additionalJOption>
Expand Down
34 changes: 26 additions & 8 deletions src/org/stringtemplate/v4/STGroupDir.java
Expand Up @@ -125,12 +125,18 @@ protected CompiledST load(String name) {
// return loadTemplateFile("/", name+TEMPLATE_FILE_EXTENSION); // load t.st file
// }

String groupFileString = Misc.joinPathSegments(root.toString(), parent) + GROUP_FILE_EXTENSION;

URL groupFileURL;
try { // see if parent of template name is a group file
groupFileURL = new URI(root+parent+GROUP_FILE_EXTENSION).normalize().toURL();
groupFileURL = new URI(groupFileString).normalize().toURL();
}
catch (MalformedURLException e) {
badURLError(groupFileString, e);
return null;
}
catch (MalformedURLException | URISyntaxException e) {
errMgr.internalError(null, "bad URL: "+root+parent+GROUP_FILE_EXTENSION, e);
catch (URISyntaxException e) {
badURLError(groupFileString, e);
return null;
}

Expand All @@ -145,17 +151,21 @@ protected CompiledST load(String name) {
}
finally { // clean up
try {
if (is!=null ) is.close();
if (is!=null) is.close();
}
catch (IOException ioe) {
errMgr.internalError(null, "can't close template file stream "+name, ioe);
}
}

loadGroupFile(prefix, root+parent+GROUP_FILE_EXTENSION);
loadGroupFile(prefix, groupFileString);
return rawGetTemplate(name);
}

private void badURLError(String fullPath, Exception e) {
errMgr.internalError(null, "bad URL: "+fullPath, e);
}

/** Load .st as relative file name relative to root by {@code prefix}. */
public CompiledST loadTemplateFile(String prefix, String unqualifiedFileName) {
if ( verbose ) System.out.println("loadTemplateFile("+unqualifiedFileName+") in groupdir "+
Expand All @@ -164,9 +174,12 @@ public CompiledST loadTemplateFile(String prefix, String unqualifiedFileName) {
try {
f = new URI(root+prefix+unqualifiedFileName).normalize().toURL();
}
catch (MalformedURLException | URISyntaxException me) {
errMgr.runTimeError(null, null, ErrorType.INVALID_TEMPLATE_NAME,
me, root + unqualifiedFileName);
catch (MalformedURLException e) {
invalidTemplateError(unqualifiedFileName, e);
return null;
}
catch (URISyntaxException e) {
invalidTemplateError(unqualifiedFileName, e);
return null;
}

Expand All @@ -184,6 +197,11 @@ public CompiledST loadTemplateFile(String prefix, String unqualifiedFileName) {
return loadTemplateFile(prefix, unqualifiedFileName, fs);
}

private void invalidTemplateError(String unqualifiedFileName, Exception e) {
errMgr.runTimeError(null, null, ErrorType.INVALID_TEMPLATE_NAME,
e, root + unqualifiedFileName);
}

@Override
public String getName() { return groupDirName; }
@Override
Expand Down
42 changes: 28 additions & 14 deletions src/org/stringtemplate/v4/misc/Misc.java
Expand Up @@ -68,9 +68,9 @@ public static String strip(String s, int n) {
return s.substring(n, s.length()-n);
}

// public static String stripRight(String s, int n) {
// return s.substring(0, s.length()-n);
// }
public static String stripRight(String s, int n) {
return s.substring(0, s.length()-n);
}

/** Strip a single newline character from the front of {@code s}. */
public static String trimOneStartingNewline(String s) {
Expand All @@ -81,11 +81,19 @@ public static String trimOneStartingNewline(String s) {

/** Strip a single newline character from the end of {@code s}. */
public static String trimOneTrailingNewline(String s) {
if ( s.endsWith("\r\n") ) s = s.substring(0, s.length()-2);
else if ( s.endsWith("\n") ) s = s.substring(0, s.length()-1);
if ( s.endsWith("\r\n") ) s = stripRight(s, 2);
else if ( s.endsWith("\n") ) s = stripRight(s, 1);
return s;
}

public static String trimOneStarting(String s, String trim) {
return s.startsWith(trim) ? s.substring(trim.length()) : s;
}

public static String trimOneTrailing(String s, String trim) {
return s.endsWith(trim) ? stripRight(s, trim.length()) : s;
}

/** Given, say, {@code file:/tmp/test.jar!/org/foo/templates/main.stg}
* convert to {@code file:/tmp/test.jar!/org/foo/templates}
*/
Expand Down Expand Up @@ -117,19 +125,25 @@ public static String getParent(String name) {
return "";
}

/**
* Trims one trailing "/" from path1 and one initial "/" from path2 before
* joining them with one "/".
*/
public static String joinPathSegments(String path1, String path2) {
return trimOneTrailing(path1, "/") + "/" +
trimOneStarting(path2, "/");
}

public static String getPrefix(String name) {
if (name==null) return "/";
String parent = getParent(name);
String prefix = parent;
if ( !parent.endsWith("/") ) prefix += '/';
return prefix;
return parent.endsWith("/") ? parent : parent+"/";
}

public static String replaceEscapes(String s) {
s = s.replaceAll("\n", "\\\\n");
s = s.replaceAll("\r", "\\\\r");
s = s.replaceAll("\t", "\\\\t");
return s;
return s.replace("\n", "\\n")
.replace("\r", "\\r")
.replace("\t", "\\t");
}

/**
Expand Down Expand Up @@ -179,8 +193,8 @@ public static boolean urlExists(URL url) {
is.close();
} catch (Throwable e) {
// Closing the input stream may throw an exception. See bug below. Most probabaly it was
// the true reason for this commit:
// https://github.com/antlr/stringtemplate4/commit/21484ed46f1b20b2cdaec49f9d5a626fb26a493c
// the true reason for this commit:
// https://github.com/antlr/stringtemplate4/commit/21484ed46f1b20b2cdaec49f9d5a626fb26a493c
// https://bugs.openjdk.java.net/browse/JDK-8080094
// e.printStackTrace();
}
Expand Down
1 change: 1 addition & 0 deletions test/BUILD.bazel
Expand Up @@ -19,6 +19,7 @@ java_test(
# Skip as it uses AWT and the installed JRE is usually headless.
# "org.stringtemplate.v4.test.TestEarlyEvaluation",
"org.stringtemplate.v4.test.TestFunctions",
"org.stringtemplate.v4.test.TestJoinPathSegments",
"org.stringtemplate.v4.test.TestGroupSyntax",
"org.stringtemplate.v4.test.TestGroupSyntaxErrors",
"org.stringtemplate.v4.test.TestGroups",
Expand Down
32 changes: 32 additions & 0 deletions test/org/stringtemplate/v4/test/TestJoinPathSegments.java
@@ -0,0 +1,32 @@
package org.stringtemplate.v4.test;

import org.junit.Test;
import org.stringtemplate.v4.misc.Misc;

import static org.junit.Assert.assertEquals;

public class TestJoinPathSegments extends BaseTest {
private final String ROOT_DIR = "rootDir";
private final String TEMPLATE_GROUP_FILE = "templateDir/TestFile.stg";
private final String EXPECTED = "rootDir/templateDir/TestFile.stg";

@Test
public void testBareRootDirAndBareGroupDir() {
assertEquals(EXPECTED, Misc.joinPathSegments(ROOT_DIR, TEMPLATE_GROUP_FILE));
}

@Test
public void testRootDirWithTrailingSlashAndBareGroupDir() {
assertEquals(EXPECTED, Misc.joinPathSegments(ROOT_DIR + "/", TEMPLATE_GROUP_FILE));
}

@Test
public void testBareRootDirAndGroupDirWithLeadingSlash() {
assertEquals(EXPECTED, Misc.joinPathSegments(ROOT_DIR, "/" + TEMPLATE_GROUP_FILE));
}

@Test
public void testRootDirWithTrailingSlashAndGroupDirWithLeadingSlash() {
assertEquals(EXPECTED, Misc.joinPathSegments(ROOT_DIR + "/", "/" + TEMPLATE_GROUP_FILE));
}
}