From 2a719774948fc1762e60cf7dd2ee3393c8922bb2 Mon Sep 17 00:00:00 2001 From: Mike Kaganski Date: Mon, 27 Jun 2022 12:02:44 +0300 Subject: tdf#126263: do not try to delete non-temporary files Change-Id: I5df7db7eac6224fce833e6b9d4ea220cade44e4b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136483 Tested-by: Jenkins Reviewed-by: Mike Kaganski --- shell/source/win32/simplemail/senddoc.cxx | 38 ++++++++++++++++-------- shell/source/win32/simplemail/smplmailclient.cxx | 10 +++++-- shell/source/win32/simplemail/smplmailclient.hxx | 2 +- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/shell/source/win32/simplemail/senddoc.cxx b/shell/source/win32/simplemail/senddoc.cxx index 3b57684fe821..e34412cbfae1 100644 --- a/shell/source/win32/simplemail/senddoc.cxx +++ b/shell/source/win32/simplemail/senddoc.cxx @@ -58,8 +58,8 @@ namespace /* private */ std::vector gTo; std::vector gCc; std::vector gBcc; - // Keep temp filepath and displayed name - std::vector> gAttachments; + // Keep temp filepath, displayed name, and "do not delete" flag + std::vector> gAttachments; int gMapiFlags = 0; } @@ -121,11 +121,12 @@ static void initAttachmentList(MapiAttachmentList_t* pMapiAttachmentList) { OSL_ASSERT(pMapiAttachmentList->empty()); - for (const auto& attachment : gAttachments) + for (const auto& [filepath, attachname, nodelete] : gAttachments) { + (void)nodelete; MapiFileDescW mfd; ZeroMemory(&mfd, sizeof(mfd)); - mfd.lpszPathName = const_cast(attachment.first.c_str()); + mfd.lpszPathName = const_cast(filepath.c_str()); // MapiFileDesc documentation (https://msdn.microsoft.com/en-us/library/hh707272) // allows using here either nullptr, or a pointer to empty string. However, // for Outlook 2013, we cannot use nullptr here, and must point to a (possibly @@ -134,7 +135,7 @@ static void initAttachmentList(MapiAttachmentList_t* pMapiAttachmentList) // Since C++11, c_str() must return a pointer to single null character when the // string is empty, so we are OK here in case when there's no explicit file name // passed - mfd.lpszFileName = const_cast(attachment.second.c_str()); + mfd.lpszFileName = const_cast(attachname.c_str()); mfd.nPosition = sal::static_int_cast(-1); pMapiAttachmentList->push_back(mfd); } @@ -239,7 +240,14 @@ static void initParameter(int argc, wchar_t* argv[]) sName = argv[i+3]; i += 2; } - gAttachments.emplace_back(sPath, sName); + // Also there may be --nodelete to keep the attachment on exit + bool nodelete = false; + if ((i + 2) < argc && _wcsicmp(argv[i+2], L"--nodelete") == 0) + { + nodelete = true; + ++i; + } + gAttachments.emplace_back(sPath, sName, nodelete); } else if (_wcsicmp(argv[i], L"--langtag") == 0) gLangTag = o3tl::toU(argv[i+1]); @@ -401,8 +409,12 @@ int wmain(int argc, wchar_t* argv[]) } // Now cleanup the temporary attachment files - for (const auto& rAttachment : gAttachments) - DeleteFileW(rAttachment.first.c_str()); + for (const auto& [filepath, attachname, nodelete] : gAttachments) + { + (void)attachname; + if (!nodelete) + DeleteFileW(filepath.c_str()); + } // Only show the error message if UI was requested if ((ulRet != SUCCESS_SUCCESS) && (gMapiFlags & (MAPI_DIALOG | MAPI_LOGON_UI))) @@ -434,11 +446,13 @@ int wmain(int argc, wchar_t* argv[]) for (const auto& address : gBcc) oss << "--bcc " << address << std::endl; - for (const auto& attachment : gAttachments) + for (const auto& [filepath, attachname, nodelete] : gAttachments) { - oss << "--attach " << attachment.first << std::endl; - if (!attachment.second.empty()) - oss << "--attach-name " << attachment.second << std::endl; + oss << "--attach " << filepath << std::endl; + if (!attachname.empty()) + oss << "--attach-name " << attachname << std::endl; + if (nodelete) + oss << "--nodelete" << std::endl; } if (gMapiFlags & MAPI_DIALOG) diff --git a/shell/source/win32/simplemail/smplmailclient.cxx b/shell/source/win32/simplemail/smplmailclient.cxx index 4b19880d6cc2..075eaa34579d 100644 --- a/shell/source/win32/simplemail/smplmailclient.cxx +++ b/shell/source/win32/simplemail/smplmailclient.cxx @@ -180,7 +180,8 @@ const OUString& GetBaseTempDirURL() } } -OUString CSmplMailClient::CopyAttachment(const OUString& sOrigAttachURL, OUString& sUserVisibleName) +OUString CSmplMailClient::CopyAttachment(const OUString& sOrigAttachURL, OUString& sUserVisibleName, + bool& nodelete) { // We do two things here: // 1. Make the attachment temporary filename to not contain any fancy characters possible in @@ -203,6 +204,7 @@ OUString CSmplMailClient::CopyAttachment(const OUString& sOrigAttachURL, OUStrin INetURLObject url(sOrigAttachURL, INetURLObject::EncodeMechanism::WasEncoded); sUserVisibleName = url.getName(INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset); + nodelete = false; } else { @@ -211,6 +213,7 @@ OUString CSmplMailClient::CopyAttachment(const OUString& sOrigAttachURL, OUStrin // is the absent attachment file anyway. sNewAttachmentURL = sOrigAttachURL; maAttachmentFiles.pop_back(); + nodelete = true; // Do not delete a non-temporary in senddoc } return sNewAttachmentURL; } @@ -298,7 +301,8 @@ void CSmplMailClient::assembleCommandLine( for (const auto& attachment : attachments) { OUString sDisplayName; - OUString sTempFileURL(CopyAttachment(attachment, sDisplayName)); + bool nodelete = false; + OUString sTempFileURL(CopyAttachment(attachment, sDisplayName, nodelete)); OUString sysPath; osl::FileBase::RC err = osl::FileBase::getSystemPathFromFileURL(sTempFileURL, sysPath); if (err != osl::FileBase::E_None) @@ -314,6 +318,8 @@ void CSmplMailClient::assembleCommandLine( rCommandArgs.push_back("--attach-name"); rCommandArgs.push_back(sDisplayName); } + if (nodelete) + rCommandArgs.push_back("--nodelete"); } if (!(aFlag & NO_USER_INTERFACE)) diff --git a/shell/source/win32/simplemail/smplmailclient.hxx b/shell/source/win32/simplemail/smplmailclient.hxx index 5844e99147e5..6f71a1a2a715 100644 --- a/shell/source/win32/simplemail/smplmailclient.hxx +++ b/shell/source/win32/simplemail/smplmailclient.hxx @@ -38,7 +38,7 @@ public: private: void validateParameter(const css::uno::Reference& xSimpleMailMessage, sal_Int32 aFlag); void assembleCommandLine(const css::uno::Reference& xSimpleMailMessage, sal_Int32 aFlag, std::vector& rCommandArgs); - OUString CopyAttachment(const OUString& sOrigAttachURL, OUString& sUserVisibleName); + OUString CopyAttachment(const OUString& sOrigAttachURL, OUString& sUserVisibleName, bool& nodelete); // Don't try to delete the copied attachment files; let the spawned process cleanup them void ReleaseAttachments(); -- cgit