diff --git a/src/org/rascalmpl/semantics/dynamic/PathPart.java b/src/org/rascalmpl/semantics/dynamic/PathPart.java index b2a4def8fbc..4230b59f133 100644 --- a/src/org/rascalmpl/semantics/dynamic/PathPart.java +++ b/src/org/rascalmpl/semantics/dynamic/PathPart.java @@ -12,14 +12,21 @@ *******************************************************************************/ package org.rascalmpl.semantics.dynamic; +import java.net.URI; +import java.net.URISyntaxException; + import org.rascalmpl.ast.Expression; import org.rascalmpl.ast.PathChars; import org.rascalmpl.ast.PathTail; import org.rascalmpl.ast.PrePathChars; +import org.rascalmpl.exceptions.RuntimeExceptionFactory; import org.rascalmpl.interpreter.IEvaluator; import org.rascalmpl.interpreter.result.Result; +import org.rascalmpl.interpreter.result.ResultFactory; +import org.rascalmpl.uri.URIUtil; import io.usethesource.vallang.IConstructor; import io.usethesource.vallang.ISourceLocation; +import io.usethesource.vallang.IString; import io.usethesource.vallang.IValue; public abstract class PathPart extends org.rascalmpl.ast.PathPart { @@ -37,9 +44,29 @@ public Result interpret(IEvaluator> __eval) { Result pre = this.getPre().interpret(__eval); Result expr = this.getExpression().interpret(__eval); - Result tail = this.getTail().interpret(__eval); - - return pre.add(expr).add(tail); + // here we have to encode the string for us in the path part of a uri + // the trick is to use new File which does the encoding for us, in + // a way that conforms to the current OS where we are running. So if someone + // is splicing a windows path here, with the slashes the other way around, + // they are first interpreted as path separators and not encoded as %slash + // However, first we need to map the expression result to string by using + // the `add` semantics of strings: + IString path = (IString) ResultFactory.makeResult(TF.stringType(), VF.string(""), __eval) + .add(expr).getValue(); + + try { + // reuse our URI encoders here on the unencoded expression part + URI tmp = URIUtil.create("x", "", "/" + path.getValue()); + // but get the path out directly anyway, unencoded! + path = VF.string(tmp.getRawPath()); + + // connect the pre, middle and end pieces + Result tail = this.getTail().interpret(__eval); + return pre.add(ResultFactory.makeResult(TF.stringType(), path, __eval)).add(tail); + } + catch (URISyntaxException e) { + throw RuntimeExceptionFactory.malformedURI(path.getValue(), getExpression(), __eval.getStackTrace()); + } } } diff --git a/src/org/rascalmpl/semantics/dynamic/PathTail.java b/src/org/rascalmpl/semantics/dynamic/PathTail.java index ebe8a3807b7..17cfaaae30c 100644 --- a/src/org/rascalmpl/semantics/dynamic/PathTail.java +++ b/src/org/rascalmpl/semantics/dynamic/PathTail.java @@ -12,13 +12,21 @@ *******************************************************************************/ package org.rascalmpl.semantics.dynamic; +import java.net.URI; +import java.net.URISyntaxException; + import org.rascalmpl.ast.Expression; import org.rascalmpl.ast.MidPathChars; import org.rascalmpl.ast.PostPathChars; +import org.rascalmpl.exceptions.RuntimeExceptionFactory; import org.rascalmpl.interpreter.IEvaluator; import org.rascalmpl.interpreter.result.Result; +import org.rascalmpl.interpreter.result.ResultFactory; +import org.rascalmpl.uri.URIUtil; + import io.usethesource.vallang.IConstructor; import io.usethesource.vallang.ISourceLocation; +import io.usethesource.vallang.IString; import io.usethesource.vallang.IValue; public abstract class PathTail extends org.rascalmpl.ast.PathTail { @@ -34,9 +42,23 @@ public Mid(ISourceLocation __param1, IConstructor tree, MidPathChars __param2, E public Result interpret(IEvaluator> __eval) { Result mid = this.getMid().interpret(__eval); Result expr = this.getExpression().interpret(__eval); - Result tail = this.getTail().interpret(__eval); - return mid.add(expr).add(tail); + IString path = (IString) ResultFactory.makeResult(TF.stringType(), VF.string(""), __eval) + .add(expr).getValue(); + + try { + // reuse our URI encoders here on the unencoded expression part + URI tmp = URIUtil.create("x", "", "/" + path.getValue()); + // but get the path out directly anyway, unencoded! + path = VF.string(tmp.getRawPath()); + + // connect the pre, middle and end pieces + Result tail = this.getTail().interpret(__eval); + return mid.add(ResultFactory.makeResult(TF.stringType(), path, __eval)).add(tail); + } + catch (URISyntaxException e) { + throw RuntimeExceptionFactory.malformedURI(path.getValue(), getExpression(), __eval.getStackTrace()); + } } }