aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2016-04-14 17:25:49 +0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2016-04-14 17:29:08 +0200
commit5169a6da98d43f9d32bccd95d69e1138902d5595 (patch)
treea391cd41105ad8caced71e7d23623f1725267d3a /src
parentc045630522b8c5d7b3804c6cb0173c16eb1a6d33 (diff)
Make $NIX_PATH parsing more robust
Diffstat (limited to 'src')
-rw-r--r--src/libexpr/eval.cc37
1 files changed, 32 insertions, 5 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 03d359725..7ad9a4e46 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -5,6 +5,7 @@
#include "derivations.hh"
#include "globals.hh"
#include "eval-inline.hh"
+#include "download.hh"
#include <algorithm>
#include <cstring>
@@ -238,12 +239,38 @@ void initGC()
/* Very hacky way to parse $NIX_PATH, which is colon-separated, but
can contain URLs (e.g. "nixpkgs=https://bla...:foo=https://"). */
-static Strings parseNixPath(const string & in)
+static Strings parseNixPath(const string & s)
{
- string marker = "\001//";
- auto res = tokenizeString<Strings>(replaceStrings(in, "://", marker), ":");
- for (auto & s : res)
- s = replaceStrings(s, marker, "://");
+ Strings res;
+
+ auto p = s.begin();
+
+ while (p != s.end()) {
+ auto start = p;
+ auto start2 = p;
+
+ while (p != s.end() && *p != ':') {
+ if (*p == '=') start2 = p + 1;
+ ++p;
+ }
+
+ if (p == s.end()) {
+ if (p != start) res.push_back(std::string(start, p));
+ break;
+ }
+
+ if (*p == ':') {
+ if (isUri(std::string(start2, s.end()))) {
+ ++p;
+ while (p != s.end() && *p != ':') ++p;
+ }
+ res.push_back(std::string(start, p));
+ if (p == s.end()) break;
+ }
+
+ ++p;
+ }
+
return res;
}