☠☠ backed out by 15cebc1bbdef ☠ ☠ | |
author | Neil Deakin <neil@mozilla.com> |
Tue, 03 May 2022 19:44:27 +0000 | |
changeset 616004 | 30de4b77f24203072f4a612dce0f6c55750b4c57 |
parent 616003 | ebc6720fdab3b528fe21fbc368ac02b07899765a |
child 616005 | b0ef7c68abcfe37cf4e0324efee92c49a5fde6a5 |
push id | 39645 |
push user | imoraru@mozilla.com |
push date | Wed, 04 May 2022 03:39:47 +0000 |
treeherder | mozilla-central@7fafa8a52cb0 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | Gijs |
bugs | 1746052 |
milestone | 102.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/netwerk/mime/nsIMIMEService.idl +++ b/netwerk/mime/nsIMIMEService.idl @@ -163,16 +163,18 @@ interface nsIMIMEService : nsISupports { * replaced by spaces (*, :, etc) * - Bidi related marks are replaced by underscores (_) * - Whitespace and periods are removed from the beginning and end. * - Unless VALIDATE_DONT_COLLAPSE_WHITESPACE is specified, multiple * consecutive whitespace characters are collapsed to a single space * character, either ' ' or an ideographic space 0x3000 if present. * - Unless VALIDATE_DONT_TRUNCATE is specified, the filename is truncated * to a maximum length, preserving the extension if possible. + * - Some filenames are invalid on certain platforms. These are replaced if + * possible. * * If the VALIDATE_NO_DEFAULT_FILENAME flag is not specified, and after the * rules above are applied, the resulting filename is empty, a default * filename is used. * * If the VALIDATE_ALLOW_EMPTY flag is specified, an empty string may be * returned only if the filename could not be determined or was blank. *
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp +++ b/uriloader/exthandler/nsExternalHelperAppService.cpp @@ -100,16 +100,17 @@ #include "nsXULAppAPI.h" #include "nsPIDOMWindow.h" #include "ExternalHelperAppChild.h" #include "mozilla/dom/nsHTTPSOnlyUtils.h" #ifdef XP_WIN # include "nsWindowsHelpers.h" +# include "nsLocalFile.h" #endif #include "mozilla/Components.h" #include "mozilla/ClearOnShutdown.h" #include "mozilla/Preferences.h" #include "mozilla/ipc/URIUtils.h" using namespace mozilla; @@ -3445,16 +3446,20 @@ nsExternalHelperAppService::ValidateFile if (modify != ModifyExtension_Ignore && !extension.IsEmpty()) { fileName.AppendLiteral("."); fileName.Append(NS_ConvertUTF8toUTF16(extension)); } } } } +#ifdef XP_WIN + nsLocalFile::CheckForReservedFileName(fileName); +#endif + // If no filename is present, use a default filename. if (!(aFlags & VALIDATE_NO_DEFAULT_FILENAME) && (fileName.Length() == 0 || fileName.RFind(".") == 0)) { nsCOMPtr<nsIStringBundleService> stringService = mozilla::components::StringBundle::Service(); if (stringService) { nsCOMPtr<nsIStringBundle> bundle; if (NS_SUCCEEDED(stringService->CreateBundle(
--- a/widget/windows/nsDataObj.cpp +++ b/widget/windows/nsDataObj.cpp @@ -39,16 +39,17 @@ #include "mozilla/Preferences.h" #include "nsContentUtils.h" #include "nsIPrincipal.h" #include "nsNativeCharsetUtils.h" #include "nsMimeTypes.h" #include "imgIEncoder.h" #include "imgITools.h" #include "WinUtils.h" +#include "nsLocalFile.h" #include "mozilla/LazyIdleThread.h" #include <algorithm> using namespace mozilla; using namespace mozilla::glue; using namespace mozilla::widget; @@ -1083,58 +1084,28 @@ nsDataObj ::GetFileContents(FORMATETC& a else NS_WARNING("Not yet implemented\n"); return res; } // GetFileContents // -// Given a unicode string, we ensure that it contains only characters which are -// valid within the file system. Remove all forbidden characters from the name, -// and completely disallow any title that starts with a forbidden name and -// extension (e.g. "nul" is invalid, but "nul." and "nul.txt" are also invalid -// and will cause problems). -// -// It would seem that this is more functionality suited to being in nsIFile. -// -static void MangleTextToValidFilename(nsString& aText) { - static const char* forbiddenNames[] = { - "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", - "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", - "LPT8", "LPT9", "CON", "PRN", "AUX", "NUL", "CLOCK$"}; - - aText.StripChars(FILE_PATH_SEPARATOR FILE_ILLEGAL_CHARACTERS); - aText.CompressWhitespace(true, true); - uint32_t nameLen; - for (size_t n = 0; n < ArrayLength(forbiddenNames); ++n) { - nameLen = (uint32_t)strlen(forbiddenNames[n]); - if (aText.EqualsIgnoreCase(forbiddenNames[n], nameLen)) { - // invalid name is either the entire string, or a prefix with a period - if (aText.Length() == nameLen || aText.CharAt(nameLen) == char16_t('.')) { - aText.Truncate(); - break; - } - } - } -} - -// // Given a unicode string, convert it down to a valid local charset filename // with the supplied extension. This ensures that we do not cut MBCS characters // in the middle. // // It would seem that this is more functionality suited to being in nsIFile. // static bool CreateFilenameFromTextA(nsString& aText, const char* aExtension, char* aFilename, uint32_t aFilenameLen) { // ensure that the supplied name doesn't have invalid characters. If // a valid mangled filename couldn't be created then it will leave the // text empty. - MangleTextToValidFilename(aText); + nsLocalFile::CheckForReservedFileName(aText); if (aText.IsEmpty()) return false; // repeatably call WideCharToMultiByte as long as the title doesn't fit in the // buffer available to us. Continually reduce the length of the source title // until the MBCS version will fit in the buffer with room for the supplied // extension. Doing it this way ensures that even in MBCS environments there // will be a valid MBCS filename of the correct length. int maxUsableFilenameLen = @@ -1156,17 +1127,17 @@ static bool CreateFilenameFromTextA(nsSt } } static bool CreateFilenameFromTextW(nsString& aText, const wchar_t* aExtension, wchar_t* aFilename, uint32_t aFilenameLen) { // ensure that the supplied name doesn't have invalid characters. If // a valid mangled filename couldn't be created then it will leave the // text empty. - MangleTextToValidFilename(aText); + nsLocalFile::CheckForReservedFileName(aText); if (aText.IsEmpty()) return false; const int extensionLen = wcslen(aExtension); if (aText.Length() + extensionLen + 1 > aFilenameLen) aText.Truncate(aFilenameLen - extensionLen - 1); wcscpy(&aFilename[0], aText.get()); wcscpy(&aFilename[aText.Length()], aExtension); return true; @@ -2178,17 +2149,17 @@ HRESULT nsDataObj::GetDownloadDetails(ns nsAutoCString urlFileName; sourceURL->GetFileName(urlFileName); NS_UnescapeURL(urlFileName); CopyUTF8toUTF16(urlFileName, srcFileName); } if (srcFileName.IsEmpty()) return E_FAIL; // make the name safe for the filesystem - MangleTextToValidFilename(srcFileName); + nsLocalFile::CheckForReservedFileName(srcFileName); sourceURI.swap(*aSourceURI); aFilename = srcFileName; return S_OK; } HRESULT nsDataObj::GetFileDescriptor_IStreamA(FORMATETC& aFE, STGMEDIUM& aSTG) { HGLOBAL fileGroupDescHandle =
--- a/xpcom/io/nsLocalFileWin.cpp +++ b/xpcom/io/nsLocalFileWin.cpp @@ -186,16 +186,36 @@ nsresult nsLocalFile::RevealFile(const n CoTaskMemFree(dir); CoTaskMemFree(item); } return SUCCEEDED(hr) ? NS_OK : NS_ERROR_FAILURE; } +// static +void nsLocalFile::CheckForReservedFileName(nsString& aFileName) { + static const char* forbiddenNames[] = { + "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", + "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", + "LPT8", "LPT9", "CON", "PRN", "AUX", "NUL", "CLOCK$"}; + + uint32_t nameLen; + for (size_t n = 0; n < ArrayLength(forbiddenNames); ++n) { + nameLen = (uint32_t)strlen(forbiddenNames[n]); + if (aFileName.EqualsIgnoreCase(forbiddenNames[n], nameLen)) { + // invalid name is either the entire string, or a prefix with a period + if (aFileName.Length() == nameLen || + aFileName.CharAt(nameLen) == char16_t('.')) { + aFileName.Truncate(); + } + } + } +} + class nsDriveEnumerator : public nsSimpleEnumerator, public nsIDirectoryEnumerator { public: explicit nsDriveEnumerator(bool aUseDOSDevicePathSyntax); NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSISIMPLEENUMERATOR NS_FORWARD_NSISIMPLEENUMERATORBASE(nsSimpleEnumerator::) nsresult Init();
--- a/xpcom/io/nsLocalFileWin.h +++ b/xpcom/io/nsLocalFileWin.h @@ -44,16 +44,20 @@ class nsLocalFile final : public nsILoca public: // Removes registry command handler parameters, quotes, and expands // environment strings. static bool CleanupCmdHandlerPath(nsAString& aCommandHandler); // Called off the main thread to open the window revealing the file static nsresult RevealFile(const nsString& aResolvedPath); + // Checks if the filename is one of the windows reserved filenames + // (com1, com2, etc...) and truncates the string if so. + static void CheckForReservedFileName(nsString& aFileName); + private: // CopyMove and CopySingleFile constants for |options| parameter: enum CopyFileOption { FollowSymlinks = 1u << 0, Move = 1u << 1, SkipNtfsAclReset = 1u << 2, Rename = 1u << 3 };