From 9e7e312fdfc2598d0bd43efc72738845bf2e3992 Mon Sep 17 00:00:00 2001
From: Alex Beregszaszi <alex@rtfs.hu>
Date: Fri, 5 Jan 2018 13:24:07 +0000
Subject: [PATCH] Properly support library file names containing a colon (such
 as URLs).

---
 Changelog.md                               |  2 +-
 libsolidity/interface/StandardCompiler.cpp |  2 +-
 test/libsolidity/StandardCompiler.cpp      | 35 ++++++++++++++++++++++
 3 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/Changelog.md b/Changelog.md
index bfaeeb27a..bad9baab3 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -9,7 +9,7 @@ Features:
 Bugfixes:
  * Parser: Disallow event declarations with no parameter list.
  * Standard JSON: Populate the ``sourceLocation`` field in the error list.
- * Standard JSON: Properly support file names containing a colon (such as URLs).
+ * Standard JSON: Properly support contract and library file names containing a colon (such as URLs).
  * Type Checker: Suggest the experimental ABI encoder if using ``struct``s as function parameters
    (instead of an internal compiler error).
  * Type Checker: Improve error message for wrong struct initialization.
diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp
index 7aa971c6f..04f5bd255 100644
--- a/libsolidity/interface/StandardCompiler.cpp
+++ b/libsolidity/interface/StandardCompiler.cpp
@@ -193,7 +193,7 @@ Json::Value formatLinkReferences(std::map<size_t, std::string> const& linkRefere
 	for (auto const& ref: linkReferences)
 	{
 		string const& fullname = ref.second;
-		size_t colon = fullname.find(':');
+		size_t colon = fullname.rfind(':');
 		solAssert(colon != string::npos, "");
 		string file = fullname.substr(0, colon);
 		string name = fullname.substr(colon + 1);
diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp
index fa0f1e59a..e48624e59 100644
--- a/test/libsolidity/StandardCompiler.cpp
+++ b/test/libsolidity/StandardCompiler.cpp
@@ -480,6 +480,41 @@ BOOST_AUTO_TEST_CASE(filename_with_colon)
 	BOOST_CHECK_EQUAL(dev::jsonCompactPrint(contract["abi"]), "[]");
 }
 
+BOOST_AUTO_TEST_CASE(library_filename_with_colon)
+{
+	char const* input = R"(
+	{
+		"language": "Solidity",
+		"settings": {
+			"outputSelection": {
+				"fileA": {
+					"A": [
+						"evm.bytecode"
+					]
+				}
+			}
+		},
+		"sources": {
+			"fileA": {
+				"content": "import \"git:library.sol\"; contract A { function f() returns (uint) { return L.g(); } }"
+			},
+			"git:library.sol": {
+				"content": "library L { function g() returns (uint) { return 1; } }"
+			}
+		}
+	}
+	)";
+	Json::Value result = compile(input);
+	BOOST_CHECK(containsAtMostWarnings(result));
+	Json::Value contract = getContractResult(result, "fileA", "A");
+	BOOST_CHECK(contract.isObject());
+	BOOST_CHECK(contract["evm"]["bytecode"].isObject());
+	BOOST_CHECK(contract["evm"]["bytecode"]["linkReferences"].isObject());
+	BOOST_CHECK(contract["evm"]["bytecode"]["linkReferences"]["git:library.sol"].isObject());
+	BOOST_CHECK(contract["evm"]["bytecode"]["linkReferences"]["git:library.sol"]["L"].isArray());
+	BOOST_CHECK(contract["evm"]["bytecode"]["linkReferences"]["git:library.sol"]["L"][0].isObject());
+}
+
 
 BOOST_AUTO_TEST_SUITE_END()