1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-13 05:56:03 +01:00

Escape the file paths before sending them

Make sure that a file-path containing a `\t` or a `\n` doesn’t mess with
everything
This commit is contained in:
Théophane Hufschmitt 2022-04-11 10:20:37 +02:00
parent cd7e22e4e0
commit d4bbb1dec7
2 changed files with 29 additions and 5 deletions

View file

@ -286,14 +286,18 @@ void LocalStore::findRootsNoTemp(Roots & roots, bool censor)
settings.requireExperimentalFeature(Xp::ExternalGCDaemon); settings.requireExperimentalFeature(Xp::ExternalGCDaemon);
try { try {
StringMap unescapes = {
{ "\\n", "\n"},
{ "\\t", "\t"},
};
while (true) { while (true) {
auto line = readLine(fd.get()); auto line = readLine(fd.get());
if (line.empty()) break; // TODO: Handle the broken symlinks if (line.empty()) break; // TODO: Handle the broken symlinks
auto parsedLine = tokenizeString<std::vector<std::string>>(line, "\t"); auto parsedLine = tokenizeString<std::vector<std::string>>(line, "\t");
if (parsedLine.size() != 2) if (parsedLine.size() != 2)
throw Error("Invalid result from the gc helper"); throw Error("Invalid result from the gc helper");
auto rawDestPath = parsedLine[0]; auto rawDestPath = rewriteStrings(parsedLine[0], unescapes);
auto retainer = parsedLine[1]; auto retainer = rewriteStrings(parsedLine[1], unescapes);
if (!isInStore(rawDestPath)) continue; if (!isInStore(rawDestPath)) continue;
try { try {
auto destPath = toStorePath(rawDestPath).first; auto destPath = toStorePath(rawDestPath).first;

View file

@ -68,6 +68,26 @@ TracerConfig parseCmdLine(int argc, char** argv)
}; };
} }
/**
* Return `original` with every newline or tab character escaped
*/
std::string escape(std::string original)
{
map<string, string> replacements = {
{"\n", "\\n"},
{"\n", "\\t"},
};
for (auto [oldStr, newStr] : replacements) {
size_t currentPos = 0;
while ((currentPos = original.find(oldStr)) != std::string::npos) {
original.replace(currentPos, oldStr.length(), newStr);
currentPos += newStr.length();
}
}
return original;
}
#define SD_LISTEN_FDS_START 3 // Like in systemd #define SD_LISTEN_FDS_START 3 // Like in systemd
int main(int argc, char * * argv) int main(int argc, char * * argv)
@ -126,16 +146,16 @@ int main(int argc, char * * argv)
traceResult.storeRoots.insert(runtimeRoots.begin(), runtimeRoots.end()); traceResult.storeRoots.insert(runtimeRoots.begin(), runtimeRoots.end());
for (auto & [rootInStore, externalRoots] : traceResult.storeRoots) { for (auto & [rootInStore, externalRoots] : traceResult.storeRoots) {
for (auto & externalRoot : externalRoots) { for (auto & externalRoot : externalRoots) {
send(remoteSocket, rootInStore.string().c_str(), rootInStore.string().size(), 0); send(remoteSocket, escape(rootInStore.string()).c_str(), rootInStore.string().size(), 0);
send(remoteSocket, "\t", strlen("\t"), 0); send(remoteSocket, "\t", strlen("\t"), 0);
send(remoteSocket, externalRoot.string().c_str(), externalRoot.string().size(), 0); send(remoteSocket, escape(externalRoot.string()).c_str(), externalRoot.string().size(), 0);
send(remoteSocket, "\n", strlen("\n"), 0); send(remoteSocket, "\n", strlen("\n"), 0);
} }
} }
send(remoteSocket, "\n", strlen("\n"), 0); send(remoteSocket, "\n", strlen("\n"), 0);
for (auto & deadLink : traceResult.deadLinks) { for (auto & deadLink : traceResult.deadLinks) {
send(remoteSocket, deadLink.string().c_str(), deadLink.string().size(), 0); send(remoteSocket, escape(deadLink.string()).c_str(), deadLink.string().size(), 0);
send(remoteSocket, "\n", strlen("\n"), 0); send(remoteSocket, "\n", strlen("\n"), 0);
} }