aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libexpr/eval-cache.cc13
-rw-r--r--src/libstore/build/derivation-goal.cc2
-rw-r--r--src/libstore/path.cc5
-rw-r--r--src/libutil/fmt.hh37
4 files changed, 37 insertions, 20 deletions
diff --git a/src/libexpr/eval-cache.cc b/src/libexpr/eval-cache.cc
index f26e6d724..5969ee449 100644
--- a/src/libexpr/eval-cache.cc
+++ b/src/libexpr/eval-cache.cc
@@ -576,8 +576,9 @@ std::string AttrCursor::getString()
auto & v = forceValue();
- if (v.type() != nString && v.type() != nPath)
- root->state.error<TypeError>("'%s' is not a string but %s", getAttrPathStr()).debugThrow();
+ if (v.type() != nString && v.type() != nPath) {
+ root->state.error<TypeError>("'%s' is not a string but %s", getAttrPathStr(), v.type()).debugThrow();
+ }
return v.type() == nString ? v.string.s : v.path().to_string();
}
@@ -622,11 +623,11 @@ string_t AttrCursor::getStringWithContext()
NixStringContext context;
copyContext(v, context);
return {v.string.s, std::move(context)};
- }
- else if (v.type() == nPath)
+ } else if (v.type() == nPath) {
return {v.path().to_string(), {}};
- else
- root->state.error<TypeError>("'%s' is not a string but %s", getAttrPathStr()).debugThrow();
+ } else {
+ root->state.error<TypeError>("'%s' is not a string but %s", getAttrPathStr(), v.type()).debugThrow();
+ }
}
bool AttrCursor::getBool()
diff --git a/src/libstore/build/derivation-goal.cc b/src/libstore/build/derivation-goal.cc
index f879a580e..faebd3c43 100644
--- a/src/libstore/build/derivation-goal.cc
+++ b/src/libstore/build/derivation-goal.cc
@@ -1009,7 +1009,7 @@ void DerivationGoal::buildDone()
if (diskFull)
msg += "\nnote: build failure may have been caused by lack of free disk space";
- throw BuildError(msg);
+ throw BuildError("%s", msg);
}
/* Compute the FS closure of the outputs and register them as
diff --git a/src/libstore/path.cc b/src/libstore/path.cc
index c896ff927..2f929b7b3 100644
--- a/src/libstore/path.cc
+++ b/src/libstore/path.cc
@@ -64,6 +64,11 @@ StorePath Store::parseStorePath(std::string_view path) const
std::optional<StorePath> Store::maybeParseStorePath(std::string_view path) const
{
+ // If it's not an absolute path, or if the dirname of the path isn't /nix/store
+ // (or whatever our storeDir is), then it can't be a store path.
+ if ((path.size() > 0 && path[0] != '/') || dirOf(canonPath(path)) != this->storeDir) {
+ return std::nullopt;
+ }
try {
return parseStorePath(path);
} catch (Error &) {
diff --git a/src/libutil/fmt.hh b/src/libutil/fmt.hh
index c68591b72..aa7c6926a 100644
--- a/src/libutil/fmt.hh
+++ b/src/libutil/fmt.hh
@@ -1,8 +1,15 @@
#pragma once
///@file
-#include <boost/format.hpp>
+#include <iostream>
#include <string>
+#include <optional>
+#include <boost/format.hpp>
+// Darwin stdenv does not define _GNU_SOURCE but does have _Unwind_Backtrace.
+#ifdef __APPLE__
+#define BOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED
+#endif
+#include <boost/stacktrace.hpp>
#include "ansicolor.hh"
namespace nix {
@@ -157,23 +164,27 @@ public:
*/
template<typename... Args>
HintFmt(const std::string & format, const Args &... args)
- : HintFmt(boost::format(format), args...)
- {
- }
-
- HintFmt(const HintFmt & hf) : fmt(hf.fmt) {}
-
- template<typename... Args>
- HintFmt(boost::format && fmt, const Args &... args)
- : fmt(fmt_internal::HintFmt(std::move(fmt), args...).into_format())
+ // Note the function try block.
+ try : fmt(fmt_internal::HintFmt(boost::format(format), args...).into_format())
{
if (this->fmt.remaining_args() != 0) {
- throw boost::io::too_few_args(
- this->fmt.bound_args() + this->fmt.fed_args(), this->fmt.expected_args()
- );
+ // Abort. I don't want anything to catch this, I want a coredump.
+ std::cerr << "HintFmt received incorrect number of format args. Original format string: '";
+ std::cerr << format << "'; number of arguments: " << sizeof...(args) << "\n";
+ // And regardless of the coredump give me a damn stacktrace.
+ std::cerr << boost::stacktrace::stacktrace() << std::endl;
+ abort();
}
+ } catch (boost::io::format_error & ex) {
+ // Same thing, but for anything that happens in the member initializers.
+ std::cerr << "HintFmt received incorrect format string. Original format string: '";
+ std::cerr << format << "'; number of arguments: " << sizeof...(args) << "\n";
+ std::cerr << boost::stacktrace::stacktrace() << std::endl;
+ abort();
}
+ HintFmt(const HintFmt & hf) : fmt(hf.fmt) {}
+
std::string str() const
{
return fmt.str();