about summary refs log tree commit diff
path: root/src/libexpr/eval.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexpr/eval.cc')
-rw-r--r--src/libexpr/eval.cc47
1 files changed, 39 insertions, 8 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 8ce2f3dfa6af..7ad9a4e46d83 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;
 }
 
@@ -278,7 +305,7 @@ EvalState::EvalState(const Strings & _searchPath, ref<Store> store)
 
     /* Initialise the Nix expression search path. */
     Strings paths = parseNixPath(getEnv("NIX_PATH", ""));
-    for (auto & i : _searchPath) addToSearchPath(i, true);
+    for (auto & i : _searchPath) addToSearchPath(i);
     for (auto & i : paths) addToSearchPath(i);
     addToSearchPath("nix=" + settings.nixDataDir + "/nix/corepkgs");
 
@@ -301,11 +328,15 @@ Path EvalState::checkSourcePath(const Path & path_)
     if (!restricted) return path_;
 
     /* Resolve symlinks. */
+    debug(format("checking access to ‘%s’") % path_);
     Path path = canonPath(path_, true);
 
-    for (auto & i : searchPath)
-        if (path == i.second || isInDir(path, i.second))
+    for (auto & i : searchPath) {
+        auto r = resolveSearchPathElem(i);
+        if (!r.first) continue;
+        if (path == r.second || isInDir(path, r.second))
             return path;
+    }
 
     /* To support import-from-derivation, allow access to anything in
        the store. FIXME: only allow access to paths that have been