Skip to content

Commit 533cced

Browse files
xokdviumeldritch horrors
andcommitted
libutil: Add requireCString, make renderUrlPathEnsureLegal error on NUL bytes better
Same utility as in lix's change I3caf476e59dcb7899ac5a3d83dfa3fb7ceaaabf0. Co-authored-by: eldritch horrors <[email protected]>
1 parent 72dbd43 commit 533cced

File tree

3 files changed

+22
-2
lines changed

3 files changed

+22
-2
lines changed

src/libutil/include/nix/util/strings.hh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,4 +166,10 @@ public:
166166
}
167167
};
168168

169+
/**
170+
* Check that the string does not contain any NUL bytes and return c_str().
171+
* @throws Error if str contains '\0' bytes.
172+
*/
173+
const char * requireCString(const std::string & str);
174+
169175
} // namespace nix

src/libutil/strings.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "nix/util/strings-inline.hh"
66
#include "nix/util/os-string.hh"
77
#include "nix/util/error.hh"
8+
#include "nix/util/util.hh"
89

910
namespace nix {
1011

@@ -152,4 +153,14 @@ std::string optionalBracket(std::string_view prefix, std::string_view content, s
152153
return result;
153154
}
154155

156+
const char * requireCString(const std::string & s)
157+
{
158+
if (std::memchr(s.data(), '\0', s.size())) [[unlikely]] {
159+
using namespace std::string_view_literals;
160+
auto str = replaceStrings(s, "\0"sv, ""sv);
161+
throw Error("string '%s' with null (\\0) bytes used where it's not allowed", str);
162+
}
163+
return s.c_str();
164+
}
165+
155166
} // namespace nix

src/libutil/url.cc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,8 +327,11 @@ Path renderUrlPathEnsureLegal(const std::vector<std::string> & urlPath)
327327
/* This is only really valid for UNIX. Windows has more restrictions. */
328328
if (comp.contains('/'))
329329
throw BadURL("URL path component '%s' contains '/', which is not allowed in file names", comp);
330-
if (comp.contains(char(0)))
331-
throw BadURL("URL path component '%s' contains NUL byte which is not allowed", comp);
330+
if (comp.contains(char(0))) {
331+
using namespace std::string_view_literals;
332+
auto str = replaceStrings(comp, "\0"sv, ""sv);
333+
throw BadURL("URL path component '%s' contains NUL byte which is not allowed", str);
334+
}
332335
}
333336

334337
return concatStringsSep("/", urlPath);

0 commit comments

Comments
 (0)