mirror of https://github.com/sbt/sbt.git
work around URI problems with encoding and resolving. Fixes #725
This commit is contained in:
parent
a4c059cb7e
commit
81babda6f6
|
|
@ -47,9 +47,10 @@ object Configuration
|
|||
}
|
||||
def configurationFromFile(path: String, baseDirectory: File): URL =
|
||||
{
|
||||
val pathURI = filePathURI(path)
|
||||
def resolve(against: URI): Option[URL] =
|
||||
{
|
||||
val resolved = against.resolve(path)
|
||||
val resolved = against.resolve(pathURI) // variant that accepts String doesn't properly escape (#725)
|
||||
val exists = try { (new File(resolved)).exists } catch { case _: IllegalArgumentException => false }
|
||||
if(exists) Some(resolved.toURL) else None
|
||||
}
|
||||
|
|
@ -111,8 +112,11 @@ object Configuration
|
|||
Option(props.getProperty(SbtVersionProperty))
|
||||
}
|
||||
|
||||
def resolveAgainst(baseDirectory: File): List[URI] = (baseDirectory toURI) :: (new File(System.getProperty("user.home")) toURI) ::
|
||||
toDirectory(classLocation(getClass).toURI) :: Nil
|
||||
def resolveAgainst(baseDirectory: File): List[URI] =
|
||||
directoryURI(baseDirectory) ::
|
||||
directoryURI(new File(System.getProperty("user.home"))) ::
|
||||
toDirectory(classLocation(getClass).toURI) ::
|
||||
Nil
|
||||
|
||||
def classLocation(cl: Class[_]): URL =
|
||||
{
|
||||
|
|
@ -120,12 +124,26 @@ object Configuration
|
|||
if(codeSource == null) error("No class location for " + cl)
|
||||
else codeSource.getLocation
|
||||
}
|
||||
// single-arg constructor doesn't properly escape
|
||||
def filePathURI(path: String): URI = {
|
||||
val f = new File(path)
|
||||
new URI(if(f.isAbsolute) "file" else null, path, null)
|
||||
}
|
||||
def directoryURI(dir: File): URI = directoryURI(dir.toURI)
|
||||
def directoryURI(uri: URI): URI =
|
||||
{
|
||||
assert(uri.isAbsolute)
|
||||
val str = uri.toASCIIString
|
||||
val dirStr = if(str.endsWith("/")) str else str + "/"
|
||||
(new URI(dirStr)).normalize
|
||||
}
|
||||
|
||||
def toDirectory(uri: URI): URI =
|
||||
try
|
||||
{
|
||||
val file = new File(uri)
|
||||
val newFile = if(file.isFile) file.getParentFile else file
|
||||
newFile.toURI
|
||||
directoryURI(newFile)
|
||||
}
|
||||
catch { case _: Exception => uri }
|
||||
private[this] def neNull: AnyRef => Boolean = _ ne null
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
package xsbt.boot
|
||||
|
||||
import org.scalacheck._
|
||||
import Prop._
|
||||
import Configuration._
|
||||
import java.io.File
|
||||
import java.net.URI
|
||||
|
||||
object URITests extends Properties("URI Tests")
|
||||
{
|
||||
val FileProtocol = "file"
|
||||
property("directoryURI adds trailing slash") = secure {
|
||||
val dirURI = directoryURI(new File("/a/b/c"))
|
||||
val directURI = filePathURI("/a/b/c/")
|
||||
dirURI == directURI
|
||||
}
|
||||
property("directoryURI preserves trailing slash") = secure {
|
||||
directoryURI(new File("/a/b/c/")) == filePathURI("/a/b/c/")
|
||||
}
|
||||
|
||||
property("filePathURI encodes spaces") = secure {
|
||||
val decoded = "has spaces"
|
||||
val encoded = "has%20spaces"
|
||||
val fpURI = filePathURI(decoded)
|
||||
val directURI = new URI(encoded)
|
||||
s"filePathURI: $fpURI" |:
|
||||
s"direct URI: $directURI" |:
|
||||
s"getPath: ${fpURI.getPath}" |:
|
||||
s"getRawPath: ${fpURI.getRawPath}" |:
|
||||
(fpURI == directURI) &&
|
||||
(fpURI.getPath == decoded) &&
|
||||
(fpURI.getRawPath == encoded)
|
||||
}
|
||||
|
||||
property("filePathURI and File.toURI agree for absolute file") = secure {
|
||||
val s = "/a/b'/has spaces"
|
||||
val viaPath = filePathURI(s)
|
||||
val viaFile = (new File(s)).toURI
|
||||
s"via path: $viaPath" |:
|
||||
s"via file: $viaFile" |:
|
||||
(viaPath == viaFile)
|
||||
}
|
||||
}
|
||||
|
|
@ -724,7 +724,9 @@ object IO
|
|||
(new URI(dirStr)).normalize
|
||||
}
|
||||
/** Converts the given File to a URI. If the File is relative, the URI is relative, unlike File.toURI*/
|
||||
def toURI(f: File): URI = if(f.isAbsolute) f.toURI else new URI(normalizeName(f.getPath))
|
||||
def toURI(f: File): URI =
|
||||
// need to use the three argument URI constructor because the single argument version doesn't encode
|
||||
if(f.isAbsolute) f.toURI else new URI(null, normalizeName(f.getPath), null)
|
||||
def resolve(base: File, f: File): File =
|
||||
{
|
||||
assertAbsolute(base)
|
||||
|
|
|
|||
Loading…
Reference in New Issue