From 49009573bc2eacd823d57433daf1f59dfe415065 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 28 Mar 2014 16:59:26 +0100 Subject: 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); --- src/libutil/util.cc | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'src/libutil/util.cc') diff --git a/src/libutil/util.cc b/src/libutil/util.cc index b264fc5f3d13..15c462ce4e5b 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; } } -- cgit 1.4.1