diff --git a/cache/src/main/scala/coursier/Cache.scala b/cache/src/main/scala/coursier/Cache.scala index 8ffee2f7d..1cc86e997 100644 --- a/cache/src/main/scala/coursier/Cache.scala +++ b/cache/src/main/scala/coursier/Cache.scala @@ -838,6 +838,18 @@ object Cache { parseChecksumLine(lines) orElse parseChecksumAlternative(lines) } + def parseRawChecksum(content: Array[Byte]): Option[BigInteger] = + if (content.length == 16 || content.length == 20) + Some(new BigInteger(content)) + else { + val s = new String(content, UTF_8) + val lines = s + .lines + .toVector + + parseChecksumLine(lines) orElse parseChecksumAlternative(lines) + } + // matches md5 or sha1 private val checksumPattern = Pattern.compile("^[0-9a-f]{32}([0-9a-f]{8})?") @@ -870,9 +882,7 @@ object Cache { val sumFile = localFile(sumUrl, cache, artifact.authentication.map(_.user)) Task { - val sumOpt = parseChecksum( - new String(FileUtil.readAllBytes(sumFile), UTF_8) - ) + val sumOpt = parseRawChecksum(FileUtil.readAllBytes(sumFile)) sumOpt match { case None => diff --git a/cache/src/main/scala/coursier/Platform.scala b/cache/src/main/scala/coursier/Platform.scala index b97b333ab..7fcee2193 100644 --- a/cache/src/main/scala/coursier/Platform.scala +++ b/cache/src/main/scala/coursier/Platform.scala @@ -1,6 +1,7 @@ package coursier import java.io._ +import java.nio.charset.Charset import scala.language.implicitConversions @@ -23,6 +24,8 @@ object Platform { buffer.toByteArray } + private lazy val UTF_8 = Charset.forName("UTF-8") + def readFully(is: => InputStream) = Task { \/.fromTryCatchNonFatal { @@ -31,7 +34,7 @@ object Platform { try readFullySync(is0) finally is0.close() - new String(b, "UTF-8") + new String(b, UTF_8) } .leftMap{ case e: java.io.FileNotFoundException if e.getMessage != null => s"Not found: ${e.getMessage}" diff --git a/cli/src/main/scala-2.11/coursier/cli/spark/Assembly.scala b/cli/src/main/scala-2.11/coursier/cli/spark/Assembly.scala index 9d73bf57c..a40bbd873 100644 --- a/cli/src/main/scala-2.11/coursier/cli/spark/Assembly.scala +++ b/cli/src/main/scala-2.11/coursier/cli/spark/Assembly.scala @@ -223,9 +223,7 @@ object Assembly { throw new Exception(s"SHA-1 file not found for ${a.url}") } - val sumOpt = Cache.parseChecksum( - new String(FileUtil.readAllBytes(f), "UTF-8") - ) + val sumOpt = Cache.parseRawChecksum(FileUtil.readAllBytes(f)) sumOpt match { case Some(sum) => diff --git a/tests/jvm/src/test/resources/empty.md5 b/tests/jvm/src/test/resources/empty.md5 new file mode 100644 index 000000000..5656351c6 Binary files /dev/null and b/tests/jvm/src/test/resources/empty.md5 differ diff --git a/tests/jvm/src/test/resources/empty.sha1 b/tests/jvm/src/test/resources/empty.sha1 new file mode 100644 index 000000000..ce3f5a920 --- /dev/null +++ b/tests/jvm/src/test/resources/empty.sha1 @@ -0,0 +1 @@ +9^kK 2U` \ No newline at end of file diff --git a/tests/jvm/src/test/scala/coursier/test/ChecksumTests.scala b/tests/jvm/src/test/scala/coursier/test/ChecksumTests.scala index 729846a94..ae1c6f31b 100644 --- a/tests/jvm/src/test/scala/coursier/test/ChecksumTests.scala +++ b/tests/jvm/src/test/scala/coursier/test/ChecksumTests.scala @@ -22,7 +22,7 @@ object ChecksumTests extends TestSuite { assert(Cache.parseChecksum(other) == expected) } - * - { + 'junk - { // https://repo1.maven.org/maven2/org/apache/spark/spark-core_2.11/1.2.0/spark-core_2.11-1.2.0.pom.sha1 // as of 2016-03-02 val junkSha1 = @@ -34,7 +34,7 @@ object ChecksumTests extends TestSuite { sha1ParseTest(cleanSha1, junkSha1) } - * - { + 'singleLine - { // https://repo1.maven.org/maven2/org/json/json/20080701/json-20080701.pom.sha1 // as of 2016-03-05 val dirtySha1 = @@ -45,6 +45,18 @@ object ChecksumTests extends TestSuite { sha1ParseTest(cleanSha1, dirtySha1) } + + 'binarySha1 - { + val content = Platform.readFullySync(getClass.getResource("/empty.sha1").openStream()) + val res = Cache.parseRawChecksum(content) + assert(res.nonEmpty) + } + + 'binaryMd5 - { + val content = Platform.readFullySync(getClass.getResource("/empty.md5").openStream()) + val res = Cache.parseRawChecksum(content) + assert(res.nonEmpty) + } } 'artifact - {