From ff69fbbeb930eca02a8c0b34f95b75016ec24fd8 Mon Sep 17 00:00:00 2001 From: Andrey Prygunkov Date: Sat, 23 Jan 2016 14:23:53 +0100 Subject: [PATCH] #136: avoid double slashes in paths Extra long path names are not normalized automatically by Windows and therefore must contain paths in canonical form. --- daemon/feed/FeedCoordinator.cpp | 4 +- daemon/main/Options.cpp | 5 ++- daemon/nntp/ArticleWriter.cpp | 2 +- daemon/postprocess/Cleanup.cpp | 5 ++- daemon/postprocess/PrePostProcessor.cpp | 3 +- daemon/postprocess/Unpack.cpp | 5 ++- daemon/queue/DiskState.cpp | 58 +++++++++++++------------ daemon/queue/DownloadInfo.cpp | 10 ++--- daemon/queue/Scanner.cpp | 14 +++--- daemon/queue/UrlCoordinator.cpp | 3 +- daemon/remote/WebServer.cpp | 2 +- daemon/remote/XmlRpc.cpp | 2 +- 12 files changed, 60 insertions(+), 53 deletions(-) diff --git a/daemon/feed/FeedCoordinator.cpp b/daemon/feed/FeedCoordinator.cpp index 5fdc7346..0e00ec16 100644 --- a/daemon/feed/FeedCoordinator.cpp +++ b/daemon/feed/FeedCoordinator.cpp @@ -310,11 +310,11 @@ void FeedCoordinator::StartFeedDownload(FeedInfo* feedInfo, bool force) BString<1024> outFilename; if (feedInfo->GetId() > 0) { - outFilename.Format("%sfeed-%i.tmp", g_Options->GetTempDir(), feedInfo->GetId()); + outFilename.Format("%s%cfeed-%i.tmp", g_Options->GetTempDir(), PATH_SEPARATOR, feedInfo->GetId()); } else { - outFilename.Format("%sfeed-%i-%i.tmp", g_Options->GetTempDir(), (int)Util::CurrentTime(), rand()); + outFilename.Format("%s%cfeed-%i-%i.tmp", g_Options->GetTempDir(), PATH_SEPARATOR, (int)Util::CurrentTime(), rand()); } feedDownloader->SetOutputFilename(outFilename); diff --git a/daemon/main/Options.cpp b/daemon/main/Options.cpp index 7cb1a913..416fa1c4 100644 --- a/daemon/main/Options.cpp +++ b/daemon/main/Options.cpp @@ -677,9 +677,10 @@ void Options::CheckDir(CString& dir, const char* optionName, dir = tempdir; FileSystem::NormalizePathSeparators((char*)dir); - if (dir[dir.Length() - 1] != PATH_SEPARATOR) + if (!Util::EmptyStr(dir) && dir[dir.Length() - 1] == PATH_SEPARATOR) { - dir.AppendFmt("%c", (int)PATH_SEPARATOR); + // remove trailing slash + dir[dir.Length() - 1] = '\0'; } if (!(dir[0] == PATH_SEPARATOR || dir[0] == ALT_PATH_SEPARATOR || diff --git a/daemon/nntp/ArticleWriter.cpp b/daemon/nntp/ArticleWriter.cpp index 16c89dc4..791cb31e 100644 --- a/daemon/nntp/ArticleWriter.cpp +++ b/daemon/nntp/ArticleWriter.cpp @@ -281,7 +281,7 @@ bool ArticleWriter::CreateOutputFile(int64 size) void ArticleWriter::BuildOutputFilename() { - BString<1024> filename("%s%i.%03i", g_Options->GetTempDir(), + BString<1024> filename("%s%c%i.%03i", g_Options->GetTempDir(), PATH_SEPARATOR, m_fileInfo->GetId(), m_articleInfo->GetPartNumber()); m_articleInfo->SetResultFilename(filename); diff --git a/daemon/postprocess/Cleanup.cpp b/daemon/postprocess/Cleanup.cpp index 8bcd13ed..33614e8c 100644 --- a/daemon/postprocess/Cleanup.cpp +++ b/daemon/postprocess/Cleanup.cpp @@ -149,8 +149,9 @@ void CleanupController::Run() m_destDir = m_postInfo->GetNzbInfo()->GetDestDir(); - bool interDir = strlen(g_Options->GetInterDir()) > 0 && - !strncmp(m_destDir, g_Options->GetInterDir(), strlen(g_Options->GetInterDir())); + bool interDir = !Util::EmptyStr(g_Options->GetInterDir()) && + !strncmp(m_destDir, g_Options->GetInterDir(), strlen(g_Options->GetInterDir())) && + m_destDir[strlen(g_Options->GetInterDir())] == PATH_SEPARATOR; if (interDir) { m_finalDir = m_postInfo->GetNzbInfo()->BuildFinalDirName(); diff --git a/daemon/postprocess/PrePostProcessor.cpp b/daemon/postprocess/PrePostProcessor.cpp index 5725dbe5..6ef31dc9 100644 --- a/daemon/postprocess/PrePostProcessor.cpp +++ b/daemon/postprocess/PrePostProcessor.cpp @@ -570,7 +570,8 @@ void PrePostProcessor::StartJob(DownloadQueue* downloadQueue, PostInfo* postInfo postInfo->GetNzbInfo()->GetParStatus() != NzbInfo::psManual && postInfo->GetNzbInfo()->GetDeleteStatus() == NzbInfo::dsNone && !Util::EmptyStr(g_Options->GetInterDir()) && - !strncmp(postInfo->GetNzbInfo()->GetDestDir(), g_Options->GetInterDir(), strlen(g_Options->GetInterDir())); + !strncmp(postInfo->GetNzbInfo()->GetDestDir(), g_Options->GetInterDir(), strlen(g_Options->GetInterDir())) && + postInfo->GetNzbInfo()->GetDestDir()[strlen(g_Options->GetInterDir())] == PATH_SEPARATOR; bool postScript = true; diff --git a/daemon/postprocess/Unpack.cpp b/daemon/postprocess/Unpack.cpp index 72a72af6..70a171c3 100644 --- a/daemon/postprocess/Unpack.cpp +++ b/daemon/postprocess/Unpack.cpp @@ -590,8 +590,9 @@ void UnpackController::RequestParCheck(bool forceRepair) void UnpackController::CreateUnpackDir() { - m_interDir = strlen(g_Options->GetInterDir()) > 0 && - !strncmp(m_destDir, g_Options->GetInterDir(), strlen(g_Options->GetInterDir())); + m_interDir = !Util::EmptyStr(g_Options->GetInterDir()) && + !strncmp(m_destDir, g_Options->GetInterDir(), strlen(g_Options->GetInterDir())) && + m_destDir[strlen(g_Options->GetInterDir())] == PATH_SEPARATOR; if (m_interDir) { m_finalDir = m_postInfo->GetNzbInfo()->BuildFinalDirName(); diff --git a/daemon/queue/DiskState.cpp b/daemon/queue/DiskState.cpp index a4e58ac2..9f47b783 100644 --- a/daemon/queue/DiskState.cpp +++ b/daemon/queue/DiskState.cpp @@ -85,8 +85,8 @@ public: StateFile::StateFile(const char* filename, int formatVersion) { m_formatVersion = formatVersion; - m_destFilename.Format("%s%s", g_Options->GetQueueDir(), filename); - m_tempFilename.Format("%s%s.new", g_Options->GetQueueDir(), filename); + m_destFilename.Format("%s%c%s", g_Options->GetQueueDir(), PATH_SEPARATOR, filename); + m_tempFilename.Format("%s%c%s.new", g_Options->GetQueueDir(), PATH_SEPARATOR, filename); } void StateFile::Discard() @@ -966,7 +966,7 @@ bool DiskState::LoadNzbInfo(NzbInfo* nzbInfo, Servers* servers, DiskFile& infile nzbInfo->SetPriority(priority); } - BString<1024> fileName("%s%i", g_Options->GetQueueDir(), id); + BString<1024> fileName("%s%c%i", g_Options->GetQueueDir(), PATH_SEPARATOR, id); FileInfo* fileInfo = new FileInfo(); bool res = LoadFileInfo(fileInfo, fileName, true, false); if (res) @@ -1025,7 +1025,7 @@ bool DiskState::LoadFileQueue12(NzbList* nzbList, NzbList* sortList, DiskFile& i } if (nzbIndex > nzbList->size()) goto error; - BString<1024> fileName("%s%i", g_Options->GetQueueDir(), id); + BString<1024> fileName("%s%c%i", g_Options->GetQueueDir(), PATH_SEPARATOR, id); FileInfo* fileInfo = new FileInfo(); bool res = LoadFileInfo(fileInfo, fileName, true, false); if (res) @@ -1101,7 +1101,7 @@ error: bool DiskState::SaveFile(FileInfo* fileInfo) { - BString<1024> fileName("%s%i", g_Options->GetQueueDir(), fileInfo->GetId()); + BString<1024> fileName("%s%c%i", g_Options->GetQueueDir(), PATH_SEPARATOR, fileInfo->GetId()); return SaveFileInfo(fileInfo, fileName); } @@ -1151,7 +1151,7 @@ bool DiskState::SaveFileInfo(FileInfo* fileInfo, const char* filename) bool DiskState::LoadArticles(FileInfo* fileInfo) { - BString<1024> fileName("%s%i", g_Options->GetQueueDir(), fileInfo->GetId()); + BString<1024> fileName("%s%c%i", g_Options->GetQueueDir(), PATH_SEPARATOR, fileInfo->GetId()); return LoadFileInfo(fileInfo, fileName, false, true); } @@ -1275,7 +1275,8 @@ bool DiskState::SaveFileState(FileInfo* fileInfo, bool completed) { debug("Saving FileState to disk"); - BString<1024> filename("%s%i%s", g_Options->GetQueueDir(), fileInfo->GetId(), completed ? "c" : "s"); + BString<1024> filename("%s%c%i%s", g_Options->GetQueueDir(), PATH_SEPARATOR, + fileInfo->GetId(), completed ? "c" : "s"); DiskFile outfile; if (!outfile.Open(filename, DiskFile::omWrite)) @@ -1311,7 +1312,8 @@ bool DiskState::LoadFileState(FileInfo* fileInfo, Servers* servers, bool complet { bool hasArticles = !fileInfo->GetArticles()->empty(); - BString<1024> filename("%s%i%s", g_Options->GetQueueDir(), fileInfo->GetId(), completed ? "c" : "s"); + BString<1024> filename("%s%c%i%s", g_Options->GetQueueDir(), PATH_SEPARATOR, + fileInfo->GetId(), completed ? "c" : "s"); DiskFile infile; if (!infile.Open(filename, DiskFile::omRead)) @@ -1425,18 +1427,18 @@ void DiskState::DiscardFiles(NzbInfo* nzbInfo) { if (completedFile.GetStatus() != CompletedFile::cfSuccess && completedFile.GetId() > 0) { - filename.Format("%s%i", g_Options->GetQueueDir(), completedFile.GetId()); + filename.Format("%s%c%i", g_Options->GetQueueDir(), PATH_SEPARATOR, completedFile.GetId()); FileSystem::DeleteFile(filename); - filename.Format("%s%is", g_Options->GetQueueDir(), completedFile.GetId()); + filename.Format("%s%c%is", g_Options->GetQueueDir(), PATH_SEPARATOR, completedFile.GetId()); FileSystem::DeleteFile(filename); - filename.Format("%s%ic", g_Options->GetQueueDir(), completedFile.GetId()); + filename.Format("%s%c%ic", g_Options->GetQueueDir(), PATH_SEPARATOR, completedFile.GetId()); FileSystem::DeleteFile(filename); } } - filename.Format("%sn%i.log", g_Options->GetQueueDir(), nzbInfo->GetId()); + filename.Format("%s%cn%i.log", g_Options->GetQueueDir(), PATH_SEPARATOR, nzbInfo->GetId()); FileSystem::DeleteFile(filename); } @@ -1517,7 +1519,7 @@ bool DiskState::LoadPostQueue5(DownloadQueue* downloadQueue, NzbList* nzbList) { debug("Loading post-queue from disk"); - BString<1024> fileName("%s%s", g_Options->GetQueueDir(), "postq"); + BString<1024> fileName("%s%c%s", g_Options->GetQueueDir(), PATH_SEPARATOR, "postq"); if (!FileSystem::FileExists(fileName)) { @@ -1966,7 +1968,7 @@ void DiskState::DiscardDownloadQueue() { debug("Discarding queue"); - BString<1024> fullFilename("%s%s", g_Options->GetQueueDir(), "queue"); + BString<1024> fullFilename("%s%c%s", g_Options->GetQueueDir(), PATH_SEPARATOR, "queue"); FileSystem::DeleteFile(fullFilename); DirBrowser dir(g_Options->GetQueueDir()); @@ -1984,15 +1986,15 @@ void DiskState::DiscardDownloadQueue() } if (onlyNums) { - fullFilename.Format("%s%s", g_Options->GetQueueDir(), filename); + fullFilename.Format("%s%c%s", g_Options->GetQueueDir(), PATH_SEPARATOR, filename); FileSystem::DeleteFile(fullFilename); // delete file state file - fullFilename.Format("%s%ss", g_Options->GetQueueDir(), filename); + fullFilename.Format("%s%c%ss", g_Options->GetQueueDir(), PATH_SEPARATOR, filename); FileSystem::DeleteFile(fullFilename); // delete failed info file - fullFilename.Format("%s%sc", g_Options->GetQueueDir(), filename); + fullFilename.Format("%s%c%sc", g_Options->GetQueueDir(), PATH_SEPARATOR, filename); FileSystem::DeleteFile(fullFilename); } } @@ -2002,7 +2004,7 @@ bool DiskState::DownloadQueueExists() { debug("Checking if a saved queue exists on disk"); - BString<1024> fileName("%s%s", g_Options->GetQueueDir(), "queue"); + BString<1024> fileName("%s%c%s", g_Options->GetQueueDir(), PATH_SEPARATOR, "queue"); return FileSystem::FileExists(fileName); } @@ -2013,21 +2015,21 @@ void DiskState::DiscardFile(FileInfo* fileInfo, bool deleteData, bool deletePart // info and articles file if (deleteData) { - fileName.Format("%s%i", g_Options->GetQueueDir(), fileInfo->GetId()); + fileName.Format("%s%c%i", g_Options->GetQueueDir(), PATH_SEPARATOR, fileInfo->GetId()); FileSystem::DeleteFile(fileName); } // partial state file if (deletePartialState) { - fileName.Format("%s%is", g_Options->GetQueueDir(), fileInfo->GetId()); + fileName.Format("%s%c%is", g_Options->GetQueueDir(), PATH_SEPARATOR, fileInfo->GetId()); FileSystem::DeleteFile(fileName); } // completed state file if (deleteCompletedState) { - fileName.Format("%s%ic", g_Options->GetQueueDir(), fileInfo->GetId()); + fileName.Format("%s%c%ic", g_Options->GetQueueDir(), PATH_SEPARATOR, fileInfo->GetId()); FileSystem::DeleteFile(fileName); } } @@ -2041,7 +2043,7 @@ void DiskState::CleanupTempDir(DownloadQueue* downloadQueue) if (strstr(filename, ".tmp") || strstr(filename, ".dec") || (sscanf(filename, "%i.%i", &id, &part) == 2)) { - BString<1024> fullFilename("%s%s", g_Options->GetTempDir(), filename); + BString<1024> fullFilename("%s%c%s", g_Options->GetTempDir(), PATH_SEPARATOR, filename); FileSystem::DeleteFile(fullFilename); } } @@ -2320,7 +2322,7 @@ void DiskState::CalcNzbFileStats(NzbInfo* nzbInfo, int formatVersion) bool DiskState::LoadAllFileStates(DownloadQueue* downloadQueue, Servers* servers) { - BString<1024> cacheFlagFilename("%s%s", g_Options->GetQueueDir(), "acache"); + BString<1024> cacheFlagFilename("%s%c%s", g_Options->GetQueueDir(), PATH_SEPARATOR, "acache"); bool cacheWasActive = FileSystem::FileExists(cacheFlagFilename); DirBrowser dir(g_Options->GetQueueDir()); @@ -2346,7 +2348,7 @@ bool DiskState::LoadAllFileStates(DownloadQueue* downloadQueue, Servers* servers } else { - BString<1024> fullFilename("%s%s", g_Options->GetQueueDir(), filename); + BString<1024> fullFilename("%s%c%s", g_Options->GetQueueDir(), PATH_SEPARATOR, filename); FileSystem::DeleteFile(fullFilename); } } @@ -2774,7 +2776,7 @@ error: void DiskState::WriteCacheFlag() { - BString<1024> flagFilename("%s%s", g_Options->GetQueueDir(), "acache"); + BString<1024> flagFilename("%s%c%s", g_Options->GetQueueDir(), PATH_SEPARATOR, "acache"); DiskFile outfile; if (!outfile.Open(flagFilename, DiskFile::omWrite)) @@ -2788,13 +2790,13 @@ void DiskState::WriteCacheFlag() void DiskState::DeleteCacheFlag() { - BString<1024> flagFilename("%s%s", g_Options->GetQueueDir(), "acache"); + BString<1024> flagFilename("%s%c%s", g_Options->GetQueueDir(), PATH_SEPARATOR, "acache"); FileSystem::DeleteFile(flagFilename); } void DiskState::AppendNzbMessage(int nzbId, Message::EKind kind, const char* text) { - BString<1024> logFilename("%sn%i.log", g_Options->GetQueueDir(), nzbId); + BString<1024> logFilename("%s%cn%i.log", g_Options->GetQueueDir(), PATH_SEPARATOR, nzbId); DiskFile outfile; if (!outfile.Open(logFilename, DiskFile::omAppend)) @@ -2835,7 +2837,7 @@ void DiskState::LoadNzbMessages(int nzbId, MessageList* messages) // - Other threads may be writing into the log-file at any time; // - The log-file may also be deleted from another thread; - BString<1024> logFilename("%sn%i.log", g_Options->GetQueueDir(), nzbId); + BString<1024> logFilename("%s%cn%i.log", g_Options->GetQueueDir(), PATH_SEPARATOR, nzbId); if (!FileSystem::FileExists(logFilename)) { diff --git a/daemon/queue/DownloadInfo.cpp b/daemon/queue/DownloadInfo.cpp index 9198babd..fadee7ea 100644 --- a/daemon/queue/DownloadInfo.cpp +++ b/daemon/queue/DownloadInfo.cpp @@ -332,7 +332,7 @@ void NzbInfo::BuildDestDirName() } else { - destDir.Format("%s%s.#%i", g_Options->GetInterDir(), GetName(), GetId()); + destDir.Format("%s%c%s.#%i", g_Options->GetInterDir(), PATH_SEPARATOR, GetName(), GetId()); } SetDestDir(destDir); @@ -341,12 +341,12 @@ void NzbInfo::BuildDestDirName() CString NzbInfo::BuildFinalDirName() { CString finalDir = g_Options->GetDestDir(); - bool useCategory = m_category && m_category[0] != '\0'; + bool useCategory = !Util::EmptyStr(m_category); if (useCategory) { Options::Category *category = g_Options->FindCategory(m_category, false); - if (category && category->GetDestDir() && category->GetDestDir()[0] != '\0') + if (category && !Util::EmptyStr(category->GetDestDir())) { finalDir = category->GetDestDir(); useCategory = false; @@ -359,10 +359,10 @@ CString NzbInfo::BuildFinalDirName() categoryDir = m_category; FileSystem::MakeValidFilename(categoryDir, '_', true); // we can't format using "finalDir.Format" because one of the parameter is "finalDir" itself. - finalDir = BString<1024>("%s%s%c", *finalDir, *categoryDir, PATH_SEPARATOR); + finalDir = BString<1024>("%s%c%s", *finalDir, PATH_SEPARATOR, *categoryDir); } - finalDir.Append(GetName()); + finalDir.AppendFmt("%c%s", PATH_SEPARATOR, GetName()); return finalDir; } diff --git a/daemon/queue/Scanner.cpp b/daemon/queue/Scanner.cpp index c6b53529..f62958c7 100644 --- a/daemon/queue/Scanner.cpp +++ b/daemon/queue/Scanner.cpp @@ -161,13 +161,11 @@ void Scanner::CheckIncomingNzbs(const char* directory, const char* category, boo continue; } - BString<1024> fullfilename("%s%s", directory, filename); + BString<1024> fullfilename("%s%c%s", directory, PATH_SEPARATOR, filename); bool isDirectory = FileSystem::DirectoryExists(fullfilename); // check subfolders if (isDirectory) { - fullfilename[strlen(fullfilename) + 1] = '\0'; - fullfilename.AppendFmt("%c", PATH_SEPARATOR); const char* useCategory = filename; BString<1024> subCategory; if (strlen(category) > 0) @@ -509,7 +507,7 @@ Scanner::EAddStatus Scanner::AddExternalFile(const char* nzbName, const char* ca int num = 1; while (num == 1 || FileSystem::FileExists(tempFileName)) { - tempFileName.Format("%snzb-%i.tmp", g_Options->GetTempDir(), num); + tempFileName.Format("%s%cnzb-%i.tmp", g_Options->GetTempDir(), PATH_SEPARATOR, num); num++; } @@ -535,7 +533,7 @@ Scanner::EAddStatus Scanner::AddExternalFile(const char* nzbName, const char* ca validNzbName.Append(".nzb"); } - BString<1024> scanFileName("%s%s", g_Options->GetNzbDir(), *validNzbName); + BString<1024> scanFileName("%s%c%s", g_Options->GetNzbDir(), PATH_SEPARATOR, *validNzbName); char *ext = strrchr(validNzbName, '.'); if (ext) @@ -549,11 +547,13 @@ Scanner::EAddStatus Scanner::AddExternalFile(const char* nzbName, const char* ca { if (ext) { - scanFileName.Format("%s%s_%i.%s", g_Options->GetNzbDir(), *validNzbName, num, ext); + scanFileName.Format("%s%c%s_%i.%s", g_Options->GetNzbDir(), + PATH_SEPARATOR, *validNzbName, num, ext); } else { - scanFileName.Format("%s%s_%i", g_Options->GetNzbDir(), *validNzbName, num); + scanFileName.Format("%s%c%s_%i", g_Options->GetNzbDir(), + PATH_SEPARATOR, *validNzbName, num); } num++; } diff --git a/daemon/queue/UrlCoordinator.cpp b/daemon/queue/UrlCoordinator.cpp index 9b6a6aa4..7a90da29 100644 --- a/daemon/queue/UrlCoordinator.cpp +++ b/daemon/queue/UrlCoordinator.cpp @@ -272,7 +272,8 @@ void UrlCoordinator::StartUrlDownload(NzbInfo* nzbInfo) urlDownloader->SetUrl(nzbInfo->GetUrl()); urlDownloader->SetForce(g_Options->GetUrlForce()); urlDownloader->SetInfoName(nzbInfo->MakeNiceUrlName(nzbInfo->GetUrl(), nzbInfo->GetFilename())); - urlDownloader->SetOutputFilename(BString<1024>("%surl-%i.tmp", g_Options->GetTempDir(), nzbInfo->GetId())); + urlDownloader->SetOutputFilename(BString<1024>("%s%curl-%i.tmp", + g_Options->GetTempDir(), PATH_SEPARATOR, nzbInfo->GetId())); nzbInfo->SetActiveDownloads(1); nzbInfo->SetUrlStatus(NzbInfo::lsRunning); diff --git a/daemon/remote/WebServer.cpp b/daemon/remote/WebServer.cpp index bc5df81c..fd393081 100644 --- a/daemon/remote/WebServer.cpp +++ b/daemon/remote/WebServer.cpp @@ -334,7 +334,7 @@ void WebProcessor::Dispatch() defRes = "index.html"; } - BString<1024> disk_filename("%s%s%s", g_Options->GetWebDir(), m_url + 1, defRes); + BString<1024> disk_filename("%s%s%s", g_Options->GetWebDir(), m_url, defRes); SendFileResponse(disk_filename); } diff --git a/daemon/remote/XmlRpc.cpp b/daemon/remote/XmlRpc.cpp index 91a85f7b..f2790709 100644 --- a/daemon/remote/XmlRpc.cpp +++ b/daemon/remote/XmlRpc.cpp @@ -3036,7 +3036,7 @@ void ReadUrlXmlCommand::Execute() int num = 1; while (num == 1 || FileSystem::FileExists(tempFileName)) { - tempFileName.Format("%sreadurl-%i.tmp", g_Options->GetTempDir(), num); + tempFileName.Format("%s%creadurl-%i.tmp", g_Options->GetTempDir(), PATH_SEPARATOR, num); num++; }