diff --git a/src/org/ringojs/engine/RhinoEngine.java b/src/org/ringojs/engine/RhinoEngine.java index 30e60f402..36f371b74 100644 --- a/src/org/ringojs/engine/RhinoEngine.java +++ b/src/org/ringojs/engine/RhinoEngine.java @@ -749,7 +749,7 @@ public Resource findResource(String path, Repository localRoot) && (path.startsWith("./") || path.startsWith("../"))) { return findResource(localRoot.getRelativePath() + path, null); } else { - return config.getResource(path); + return config.getResource(normalizePath(path)); } } @@ -774,7 +774,38 @@ public Repository findRepository(String path, Repository localPath) throws IOExc return repository; } } - return config.getRepository(path); + return config.getRepository(normalizePath(path)); + } + + public static String normalizePath(String path) { + if (path.indexOf('.') == -1) { + return path; + } + boolean absolute = path.startsWith("/"); + String[] elements = path.split(Repository.SEPARATOR); + LinkedList list = new LinkedList(); + for (String e : elements) { + if ("..".equals(e)) { + if (list.isEmpty() || "..".equals(list.getLast())) { + list.add(e); + } else { + list.removeLast(); + } + } else if (!".".equals(e) && e.length() > 0) { + list.add(e); + } + } + StringBuilder sb = new StringBuilder(path.length()); + if (absolute) { + sb.append("/"); + } + int count = 0, last = list.size() - 1; + for (String e : list) { + sb.append(e); + if (count++ < last) + sb.append("/"); + } + return sb.toString(); } public void addToClasspath(Trackable path) throws MalformedURLException { diff --git a/src/org/ringojs/test/NormalizePathTest.java b/src/org/ringojs/test/NormalizePathTest.java new file mode 100644 index 000000000..a22338c5b --- /dev/null +++ b/src/org/ringojs/test/NormalizePathTest.java @@ -0,0 +1,38 @@ +package org.ringojs.test; + +import junit.framework.TestCase; + +import static org.ringojs.engine.RhinoEngine.normalizePath; + +public class NormalizePathTest extends TestCase { + + public void test1() { + String path = normalizePath("../bar/../foo/baz"); + assertEquals(path, "../foo/baz"); + } + + public void test2() { + String path = normalizePath("./bar/.//../foo/baz"); + assertEquals(path, "foo/baz"); + } + + public void test3() { + String path = normalizePath("bar/foo/baz"); + assertEquals(path, "bar/foo/baz"); + } + + public void test4() { + String path = normalizePath("/bar/foo/baz/../BAZ"); + assertEquals(path, "/bar/foo/BAZ"); + } + + public void test5() { + String path = normalizePath("bar//foo/./../baz/../../"); + assertEquals(path, ""); + } + + public void test6() { + String path = normalizePath("bar/../foo/./../baz/../../../"); + assertEquals(path, "../.."); + } +}