diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libexpr/eval-cache.cc | 13 | ||||
-rw-r--r-- | src/libstore/build/derivation-goal.cc | 2 | ||||
-rw-r--r-- | src/libstore/path.cc | 5 | ||||
-rw-r--r-- | src/libutil/fmt.hh | 37 |
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(); |