mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 21:01:08 +00:00
Bug 1746052, don't allow Windows reserved filenames when sanitizing filenames. Move MangleTextToValidFileName to nsLocalFileWin and rename it to CheckForReservedFileName, r=Gijs
Differential Revision: https://phabricator.services.mozilla.com/D138737
This commit is contained in:
parent
679f61ea4c
commit
c1e573cd3c
@ -168,6 +168,8 @@ interface nsIMIMEService : nsISupports {
|
||||
* 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
|
||||
|
@ -105,6 +105,7 @@
|
||||
|
||||
#ifdef XP_WIN
|
||||
# include "nsWindowsHelpers.h"
|
||||
# include "nsLocalFile.h"
|
||||
#endif
|
||||
|
||||
#include "mozilla/Components.h"
|
||||
@ -3451,6 +3452,10 @@ nsExternalHelperAppService::ValidateFileNameForSaving(
|
||||
}
|
||||
}
|
||||
|
||||
#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)) {
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "imgIEncoder.h"
|
||||
#include "imgITools.h"
|
||||
#include "WinUtils.h"
|
||||
#include "nsLocalFile.h"
|
||||
|
||||
#include "mozilla/LazyIdleThread.h"
|
||||
#include <algorithm>
|
||||
@ -1087,36 +1088,6 @@ nsDataObj ::GetFileContents(FORMATETC& aFE, STGMEDIUM& aSTG) {
|
||||
|
||||
} // 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
|
||||
@ -1129,7 +1100,7 @@ static bool CreateFilenameFromTextA(nsString& aText, const char* aExtension,
|
||||
// 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
|
||||
@ -1161,7 +1132,7 @@ static bool CreateFilenameFromTextW(nsString& aText, const wchar_t* aExtension,
|
||||
// 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);
|
||||
@ -2183,7 +2154,7 @@ HRESULT nsDataObj::GetDownloadDetails(nsIURI** aSourceURI,
|
||||
if (srcFileName.IsEmpty()) return E_FAIL;
|
||||
|
||||
// make the name safe for the filesystem
|
||||
MangleTextToValidFilename(srcFileName);
|
||||
nsLocalFile::CheckForReservedFileName(srcFileName);
|
||||
|
||||
sourceURI.swap(*aSourceURI);
|
||||
aFilename = srcFileName;
|
||||
|
@ -191,6 +191,26 @@ nsresult nsLocalFile::RevealFile(const nsString& aResolvedPath) {
|
||||
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:
|
||||
|
@ -49,6 +49,10 @@ class nsLocalFile final : public nsILocalFileWin {
|
||||
// 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 {
|
||||
|
Loading…
Reference in New Issue
Block a user