diff options
author | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2014-03-28 16:59:26 +0100 |
---|---|---|
committer | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2014-03-28 16:59:26 +0100 |
commit | 49009573bc2eacd823d57433daf1f59dfe415065 (patch) | |
tree | 7a8a15d1bc549e674f40cffdf0613de7af512b93 /src/libutil/util.cc | |
parent | 24cb65efc3c34e24fc653779a4d42cf4f31c6737 (diff) |
Don't interpret strings as format strings
Ludo reported this error:
unexpected Nix daemon error: boost::too_few_args: format-string refered to more arguments than were passed
coming from this line:
printMsg(lvlError, run.program + ": " + string(err, 0, p));
The problem here is that the string ends up implicitly converted to a
Boost format() object, so % characters are treated specially. I
always assumed (wrongly) that strings are converted to a format object
that outputs the string as-is.
Since this assumption appears in several places that may be hard to
grep for, I've added some C++ type hackery to ensures that the right
thing happens. So you don't have to worry about % in statements like
printMsg(lvlError, "foo: " + s);
or
throw Error("foo: " + s);
Diffstat (limited to 'src/libutil/util.cc')
-rw-r--r-- | src/libutil/util.cc | 26 |
1 files changed, 13 insertions, 13 deletions
diff --git a/src/libutil/util.cc b/src/libutil/util.cc index b264fc5f3..15c462ce4 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -25,22 +25,22 @@ extern char * * environ; namespace nix { -BaseError::BaseError(const format & f, unsigned int status) +BaseError::BaseError(const FormatOrString & fs, unsigned int status) : status(status) { - err = f.str(); + err = fs.s; } -BaseError & BaseError::addPrefix(const format & f) +BaseError & BaseError::addPrefix(const FormatOrString & fs) { - prefix_ = f.str() + prefix_; + prefix_ = fs.s + prefix_; return *this; } -SysError::SysError(const format & f) - : Error(format("%1%: %2%") % f.str() % strerror(errno)) +SysError::SysError(const FormatOrString & fs) + : Error(format("%1%: %2%") % fs.s % strerror(errno)) , errNo(errno) { } @@ -417,14 +417,14 @@ static string escVerbosity(Verbosity level) } -void Nest::open(Verbosity level, const format & f) +void Nest::open(Verbosity level, const FormatOrString & fs) { if (level <= verbosity) { if (logType == ltEscapes) std::cerr << "\033[" << escVerbosity(level) << "p" - << f.str() << "\n"; + << fs.s << "\n"; else - printMsg_(level, f); + printMsg_(level, fs); nest = true; nestingLevel++; } @@ -442,7 +442,7 @@ void Nest::close() } -void printMsg_(Verbosity level, const format & f) +void printMsg_(Verbosity level, const FormatOrString & fs) { checkInterrupt(); if (level > verbosity) return; @@ -452,15 +452,15 @@ void printMsg_(Verbosity level, const format & f) prefix += "| "; else if (logType == ltEscapes && level != lvlInfo) prefix = "\033[" + escVerbosity(level) + "s"; - string s = (format("%1%%2%\n") % prefix % f.str()).str(); + string s = (format("%1%%2%\n") % prefix % fs.s).str(); writeToStderr(s); } -void warnOnce(bool & haveWarned, const format & f) +void warnOnce(bool & haveWarned, const FormatOrString & fs) { if (!haveWarned) { - printMsg(lvlError, format("warning: %1%") % f.str()); + printMsg(lvlError, format("warning: %1%") % fs.s); haveWarned = true; } } |