treewide: force log format strings to be literals

luckily none of these a format strings vulnerabilities because
boost::format is smart enough to throw an exception when given
fewer format string arguments than are requested by specifiers

Change-Id: I5fa78f0d1396263271f6e1dbcee9c0b2e9e18c34
This commit is contained in:
eldritch horrors
2025-08-25 21:00:15 +00:00
parent 466115c9c8
commit 18285afa76
21 changed files with 68 additions and 59 deletions
+1 -1
View File
@@ -171,7 +171,7 @@ static void printSelectionFailureMessage(
Uncolored(machinesFormatted)
);
printMsg(level, error.str());
printMsg(level, "%1%", error.str());
}
namespace {
+1 -1
View File
@@ -344,7 +344,7 @@ void completeFlakeRefWithFragment(
}
}
} catch (Error & e) {
printTaggedWarning(e.msg());
printTaggedWarning("%1%", Uncolored(e.msg()));
}
}
+4 -4
View File
@@ -337,14 +337,14 @@ ReplExitStatus NixRepl::mainLoop()
// input without clearing the input so far.
continue;
} else {
printMsg(lvlError, e.msg());
printMsg(lvlError, "%1%", e.msg());
}
} catch (EvalError & e) {
printMsg(lvlError, e.msg());
printMsg(lvlError, "%1%", e.msg());
} catch (Error & e) {
printMsg(lvlError, e.msg());
printMsg(lvlError, "%1%", e.msg());
} catch (Interrupted & e) {
printMsg(lvlError, e.msg());
printMsg(lvlError, "%1%", e.msg());
}
// We handled the current input fully, so we should clear it
+1 -1
View File
@@ -42,7 +42,7 @@ MixCommonArgs::MixCommonArgs(const std::string & programName)
globalConfig.set(name, value);
} catch (UsageError & e) {
if (!getRoot().completions) {
printTaggedWarning(e.what());
printTaggedWarning("%1%", Uncolored(e.what()));
}
}
}},
+1 -2
View File
@@ -322,7 +322,6 @@ int handleExceptions(const std::string & programName, std::function<void()> fun)
* */
bool onlyForSubcommands = baseNameOf(programName) == "lix";
std::string error = ANSI_RED "error:" ANSI_NORMAL " ";
try {
fun();
} catch (Exit & e) {
@@ -338,7 +337,7 @@ int handleExceptions(const std::string & programName, std::function<void()> fun)
logError(e.info());
return e.info().status;
} catch (const std::bad_alloc & e) {
printError(error + "out of memory");
printError(ANSI_RED "error:" ANSI_NORMAL " out of memory");
return 1;
}
// Deliberately do not catch random std exceptions! We have a nice
+5 -5
View File
@@ -97,8 +97,9 @@ void handleDiffHook(
diffHook,
statusToString(diffRes.first));
if (diffRes.second != "")
printError(chomp(diffRes.second));
if (diffRes.second != "") {
printError("%1%", chomp(diffRes.second));
}
} catch (Error & error) {
ErrorInfo ei = error.info();
// FIXME: wrap errors.
@@ -844,7 +845,7 @@ try {
ex.addTrace({}, "while setting up the build environment");
throw ex;
}
debug("sandbox setup: " + msg);
debug("sandbox setup: %1%", msg);
msgs.push_back(std::move(msg));
}
@@ -1569,8 +1570,7 @@ void LocalDerivationGoal::runChild()
#include "sandbox-minimal.sb"
;
debug("Generated sandbox profile:");
debug(sandboxProfile);
debug("Generated sandbox profile: %1%", sandboxProfile);
bool allowLocalNetworking = parsedDrv->getBoolAttr("__darwinAllowLocalNetworking");
+2 -2
View File
@@ -41,7 +41,7 @@ Goal::WorkResult PathSubstitutionGoal::done(
{
BuildResult buildResult{.status = status};
if (errorMsg) {
debug(*errorMsg);
debug("%1%", *errorMsg);
buildResult.errorMsg = *errorMsg;
}
return WorkResult{result, std::move(buildResult)};
@@ -263,7 +263,7 @@ try {
thr.get();
break;
} catch (std::exception & e) { // NOLINT(lix-foreign-exceptions)
printError(e.what());
printError("%1%", e.what());
/* Cause the parent build to fail unless --fallback is given,
or the substitute has disappeared. The latter case behaves
+1 -1
View File
@@ -75,7 +75,7 @@ void builtinFetchurl(const BasicDerivation & drv, const std::string & netrcData,
);
return;
} catch (Error & e) {
debug(e.what());
debug("%1%", e.what());
}
}
}
+1 -1
View File
@@ -243,7 +243,7 @@ struct ClientSettings
name
);
} catch (UsageError & e) {
printTaggedWarning(e.what());
printTaggedWarning("%1%", Uncolored(e.what()));
}
}
}
+1 -1
View File
@@ -830,7 +830,7 @@ try {
if (!kept.empty()) {
printTalkative("Paths not deleted because they are still referenced by GC roots:");
for (auto &path: kept) {
printTalkative(path);
printTalkative("%1%", path);
}
}
+1 -1
View File
@@ -1576,7 +1576,7 @@ try {
if (TRY_AWAIT(isValidPath(i)))
logError(caught->info());
else
printTaggedWarning(caught->msg());
printTaggedWarning("%1%", Uncolored(caught->msg()));
errors = true;
}
}
+3 -1
View File
@@ -145,7 +145,9 @@ PathLock::lockImpl(const Path & path, std::string_view waitMsg, bool wait, Never
/* Acquire an exclusive lock. */
if (!tryLockFile(fd.get(), ltWrite)) {
if (wait) {
if (waitMsg != "") printError(std::string(waitMsg));
if (waitMsg != "") {
printError("%1%", waitMsg);
}
lockFile(fd.get(), ltWrite);
} else {
return std::nullopt;
+1 -1
View File
@@ -792,7 +792,7 @@ try {
}
else if (msg == STDERR_NEXT)
printError(chomp(TRY_AWAIT(readString(from))));
printError("%1%", chomp(TRY_AWAIT(readString(from))));
else if (msg == STDERR_START_ACTIVITY) {
auto act = TRY_AWAIT(readNum<ActivityId>(from));
+12 -9
View File
@@ -61,15 +61,18 @@ void setStackSize(rlim_t stackSize)
savedStackSize = limit.rlim_cur;
limit.rlim_cur = std::min(stackSize, limit.rlim_max);
if (setrlimit(RLIMIT_STACK, &limit) != 0) {
printError(HintFmt(
"Failed to increase stack size from %1% to %2% (maximum allowed "
"stack size: %3%): %4%",
savedStackSize,
stackSize,
limit.rlim_max,
std::strerror(errno)
)
.str());
printError(
"%1%",
HintFmt(
"Failed to increase stack size from %1% to %2% (maximum allowed "
"stack size: %3%): %4%",
savedStackSize,
stackSize,
limit.rlim_max,
std::strerror(errno)
)
.str()
);
}
}
}
+2 -2
View File
@@ -95,11 +95,11 @@ public:
{
if (type == resBuildLogLine && printBuildLogs) {
auto lastLine = fields[0].s;
printError(lastLine);
printError("%1%", lastLine);
}
else if (type == resPostBuildLogLine) {
auto lastLine = fields[0].s;
printError("post-build-hook: " + lastLine);
printError("post-build-hook: %1%", lastLine);
}
}
};
+18 -17
View File
@@ -255,27 +255,28 @@ extern Verbosity verbosity;
/**
* Print a string message if the current log level is at least the specified
* level. Note that this has to be implemented as a macro to ensure that the
* arguments are evaluated lazily.
* arguments are evaluated lazily. The format string *must* be a literal.
*/
#define printMsgUsing(loggerParam, level, args...) \
do { \
auto _lix_logger_print_lvl = level; \
if (_lix_logger_print_lvl <= ::nix::verbosity) { \
loggerParam->log(_lix_logger_print_lvl, ::nix::fmt(args)); \
} \
#define printMsgUsing(loggerParam, level, fs, args...) \
do { \
auto _lix_logger_print_lvl = level; \
const char * _lix_format = []<size_t N>(const char(&_lix_fs)[N]) { return _lix_fs; }(fs); \
if (_lix_logger_print_lvl <= ::nix::verbosity) { \
loggerParam->log(_lix_logger_print_lvl, ::nix::fmt(_lix_format, ##args)); \
} \
} while (0)
#define printMsg(level, args...) printMsgUsing(::nix::logger, level, args)
#define printMsg(level, fs, args...) printMsgUsing(::nix::logger, level, fs, ##args)
#define printWarning(args...) printMsg(::nix::lvlWarn, args)
#define printError(args...) printMsg(::nix::lvlError, args)
#define notice(args...) printMsg(::nix::lvlNotice, args)
#define printInfo(args...) printMsg(::nix::lvlInfo, args)
#define printTalkative(args...) printMsg(::nix::lvlTalkative, args)
#define debug(args...) printMsg(::nix::lvlDebug, args)
#define vomit(args...) printMsg(::nix::lvlVomit, args)
#define printWarning(fs, args...) printMsg(::nix::lvlWarn, fs, ##args)
#define printError(fs, args...) printMsg(::nix::lvlError, fs, ##args)
#define notice(fs, args...) printMsg(::nix::lvlNotice, fs, ##args)
#define printInfo(fs, args...) printMsg(::nix::lvlInfo, fs, ##args)
#define printTalkative(fs, args...) printMsg(::nix::lvlTalkative, fs, ##args)
#define debug(fs, args...) printMsg(::nix::lvlDebug, fs, ##args)
#define vomit(fs, args...) printMsg(::nix::lvlVomit, fs, ##args)
#define printTaggedWarning(args...) \
printWarning(ANSI_WARNING "warning:" ANSI_NORMAL " %1%", ::nix::HintFmt(args).str())
#define printTaggedWarning(fs, args...) \
printWarning("%1%", ::nix::HintFmt(ANSI_WARNING "warning:" ANSI_NORMAL " " fs, ##args).str())
void writeLogsToStderr(std::string_view s);
+1 -1
View File
@@ -52,7 +52,7 @@ void restoreMountNamespace()
if (chdir(savedCwd.c_str()) == -1)
throw SysError("restoring cwd");
} catch (Error & e) {
debug(e.msg());
debug("%1%", e.msg());
}
#endif
}
+1 -1
View File
@@ -94,7 +94,7 @@ static void extract_archive(TarArchive & archive, const Path & destDir)
if (!name)
throw Error("cannot get archive member name: %s", archive_error_string(archive.archive));
if (r == ARCHIVE_WARN)
printTaggedWarning(archive_error_string(archive.archive));
printTaggedWarning("%1%", Uncolored(archive_error_string(archive.archive)));
else
archive.check(r);
+4 -4
View File
@@ -25,17 +25,17 @@ std::string formatProtocol(unsigned int proto)
}
bool checkPass(const std::string & msg) {
notice(ANSI_GREEN "[PASS] " ANSI_NORMAL + msg);
notice(ANSI_GREEN "[PASS]" ANSI_NORMAL " %1%", msg);
return true;
}
bool checkFail(const std::string & msg) {
notice(ANSI_RED "[FAIL] " ANSI_NORMAL + msg);
notice(ANSI_RED "[FAIL]" ANSI_NORMAL " %1%", msg);
return false;
}
void checkInfo(const std::string & msg) {
notice(ANSI_BLUE "[INFO] " ANSI_NORMAL + msg);
notice(ANSI_BLUE "[INFO]" ANSI_NORMAL " %1%", msg);
}
}
@@ -61,7 +61,7 @@ struct CmdDoctor : StoreCommand
void run(ref<Store> store) override
{
printInfo("Running checks against store uri: " + store->getUri());
printInfo("Running checks against store uri %1%", store->getUri());
if (store.try_cast_shared<LocalFSStore>()) {
success &= checkNixInPath();
+6 -2
View File
@@ -954,8 +954,12 @@ struct CmdFlakeInitCommon : virtual Args, EvalCommand
}
auto welcomeText = cursor->maybeGetAttr(*evalState, "welcomeText");
if (welcomeText) {
notice("\n");
notice(renderMarkdownToTerminal(welcomeText->getString(*evalState), StandardOutputStream::Stderr));
notice(
"\n%1%",
renderMarkdownToTerminal(
welcomeText->getString(*evalState), StandardOutputStream::Stderr
)
);
}
if (!conflictedFiles.empty())
@@ -77,7 +77,7 @@ struct Proc {
JSON err;
auto msg = e.msg();
err["error"] = nix::filterANSIEscapes(msg, true);
printError(msg);
printError("%1%", msg);
if (tryWriteLine(to->get(), err.dump()) < 0) {
return; // main process died
};