зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1173320 - patch 3/8 - Improve the Windows path management, r=smaug
This commit is contained in:
Родитель
4c6e588645
Коммит
f11df067d2
|
@ -34,14 +34,14 @@ function testCreateDirectory(rootDir, path) {
|
|||
}
|
||||
|
||||
function createDirectorySuccess(d) {
|
||||
ok(d.name === gName, "Failed to create directory: name mismatch.");
|
||||
is(d.name, gName, "Failed to create directory: name mismatch.");
|
||||
|
||||
// Get the new created directory from the root.
|
||||
gRoot.get(gPath).then(getSuccess, cbError);
|
||||
}
|
||||
|
||||
function getSuccess(d) {
|
||||
ok(d.name === gName, "Should get directory - " + (gPath || "[root]") + ".");
|
||||
is(d.name, gName, "Should get directory - " + (gPath || "[root]") + ".");
|
||||
switch (gTestCount) {
|
||||
case 0:
|
||||
gRoot = d;
|
||||
|
|
|
@ -35,6 +35,46 @@
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
namespace {
|
||||
|
||||
bool
|
||||
IsValidRelativeDOMPath(const nsString& aPath, nsTArray<nsString>& aParts)
|
||||
{
|
||||
// We don't allow empty relative path to access the root.
|
||||
if (aPath.IsEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Leading and trailing "/" are not allowed.
|
||||
if (aPath.First() == FILESYSTEM_DOM_PATH_SEPARATOR_CHAR ||
|
||||
aPath.Last() == FILESYSTEM_DOM_PATH_SEPARATOR_CHAR) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_NAMED_LITERAL_STRING(kCurrentDir, ".");
|
||||
NS_NAMED_LITERAL_STRING(kParentDir, "..");
|
||||
|
||||
// Split path and check each path component.
|
||||
nsCharSeparatedTokenizer tokenizer(aPath, FILESYSTEM_DOM_PATH_SEPARATOR_CHAR);
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
nsDependentSubstring pathComponent = tokenizer.nextToken();
|
||||
// The path containing empty components, such as "foo//bar", is invalid.
|
||||
// We don't allow paths, such as "../foo", "foo/./bar" and "foo/../bar",
|
||||
// to walk up the directory.
|
||||
if (pathComponent.IsEmpty() ||
|
||||
pathComponent.Equals(kCurrentDir) ||
|
||||
pathComponent.Equals(kParentDir)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aParts.AppendElement(pathComponent);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(Directory)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Directory)
|
||||
|
@ -302,7 +342,7 @@ void
|
|||
Directory::GetPath(nsAString& aRetval, ErrorResult& aRv)
|
||||
{
|
||||
if (mType == eDOMRootDirectory) {
|
||||
aRetval.AssignLiteral(FILESYSTEM_DOM_PATH_SEPARATOR);
|
||||
aRetval.AssignLiteral(FILESYSTEM_DOM_PATH_SEPARATOR_LITERAL);
|
||||
} else {
|
||||
// TODO: this should be a bit different...
|
||||
GetName(aRetval, aRv);
|
||||
|
@ -384,7 +424,8 @@ Directory::DOMPathToRealPath(const nsAString& aPath, nsIFile** aFile) const
|
|||
static const char kWhitespace[] = "\b\t\r\n ";
|
||||
relativePath.Trim(kWhitespace);
|
||||
|
||||
if (!IsValidRelativePath(relativePath)) {
|
||||
nsTArray<nsString> parts;
|
||||
if (!IsValidRelativeDOMPath(relativePath, parts)) {
|
||||
return NS_ERROR_DOM_FILESYSTEM_INVALID_PATH_ERR;
|
||||
}
|
||||
|
||||
|
@ -394,49 +435,16 @@ Directory::DOMPathToRealPath(const nsAString& aPath, nsIFile** aFile) const
|
|||
return rv;
|
||||
}
|
||||
|
||||
rv = file->AppendRelativePath(relativePath);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
for (uint32_t i = 0; i < parts.Length(); ++i) {
|
||||
rv = file->AppendRelativePath(parts[i]);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
file.forget(aFile);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
bool
|
||||
Directory::IsValidRelativePath(const nsString& aPath)
|
||||
{
|
||||
// We don't allow empty relative path to access the root.
|
||||
if (aPath.IsEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Leading and trailing "/" are not allowed.
|
||||
if (aPath.First() == FileSystemUtils::kSeparatorChar ||
|
||||
aPath.Last() == FileSystemUtils::kSeparatorChar) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_NAMED_LITERAL_STRING(kCurrentDir, ".");
|
||||
NS_NAMED_LITERAL_STRING(kParentDir, "..");
|
||||
|
||||
// Split path and check each path component.
|
||||
nsCharSeparatedTokenizer tokenizer(aPath, FileSystemUtils::kSeparatorChar);
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
nsDependentSubstring pathComponent = tokenizer.nextToken();
|
||||
// The path containing empty components, such as "foo//bar", is invalid.
|
||||
// We don't allow paths, such as "../foo", "foo/./bar" and "foo/../bar",
|
||||
// to walk up the directory.
|
||||
if (pathComponent.IsEmpty() ||
|
||||
pathComponent.Equals(kCurrentDir) ||
|
||||
pathComponent.Equals(kParentDir)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -147,9 +147,6 @@ private:
|
|||
FileSystemBase* aFileSystem = nullptr);
|
||||
~Directory();
|
||||
|
||||
static bool
|
||||
IsValidRelativePath(const nsString& aPath);
|
||||
|
||||
/*
|
||||
* Convert relative DOM path to the absolute real path.
|
||||
*/
|
||||
|
|
|
@ -64,39 +64,6 @@ FileSystemBase::GetWindow() const
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIFile>
|
||||
FileSystemBase::GetLocalFile(const nsAString& aRealPath) const
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess(),
|
||||
"Should be on parent process!");
|
||||
|
||||
// Let's convert the input path to /path
|
||||
nsAutoString localPath;
|
||||
if (!aRealPath.IsEmpty() &&
|
||||
!StringBeginsWith(aRealPath,
|
||||
NS_LITERAL_STRING(FILESYSTEM_DOM_PATH_SEPARATOR))) {
|
||||
localPath.AssignLiteral(FILESYSTEM_DOM_PATH_SEPARATOR);
|
||||
}
|
||||
localPath.Append(aRealPath);
|
||||
|
||||
// We have to normalize the path string in order to follow the separator
|
||||
// schema of this OS.
|
||||
nsAutoString normalizedPath;
|
||||
FileSystemUtils::NormalizedPathToLocalPath(localPath, normalizedPath);
|
||||
|
||||
// The full path is mLocalRootPath + normalizedPath.
|
||||
nsAutoString path(mLocalRootPath);
|
||||
path.Append(normalizedPath);
|
||||
|
||||
nsCOMPtr<nsIFile> file;
|
||||
nsresult rv = NS_NewLocalFile(path, false, getter_AddRefs(file));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return file.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
FileSystemBase::GetRealPath(BlobImpl* aFile, nsIFile** aPath) const
|
||||
{
|
||||
|
|
|
@ -39,12 +39,6 @@ public:
|
|||
virtual nsPIDOMWindowInner*
|
||||
GetWindow() const;
|
||||
|
||||
/**
|
||||
* Create nsIFile object from the given real path (absolute DOM path).
|
||||
*/
|
||||
already_AddRefed<nsIFile>
|
||||
GetLocalFile(const nsAString& aRealPath) const;
|
||||
|
||||
/*
|
||||
* Get the virtual name of the root directory. This name will be exposed to
|
||||
* the content page.
|
||||
|
|
|
@ -54,7 +54,7 @@ FileSystemUtils::IsDescendantPath(const nsAString& aPath,
|
|||
{
|
||||
// The descendant path should begin with its ancestor path.
|
||||
nsAutoString prefix;
|
||||
prefix = aPath + NS_LITERAL_STRING(FILESYSTEM_DOM_PATH_SEPARATOR);
|
||||
prefix = aPath + NS_LITERAL_STRING(FILESYSTEM_DOM_PATH_SEPARATOR_LITERAL);
|
||||
|
||||
// Check the sub-directory path to see if it has the parent path as prefix.
|
||||
if (aDescendantPath.Length() < prefix.Length() ||
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
#define FILESYSTEM_DOM_PATH_SEPARATOR "/"
|
||||
#define FILESYSTEM_DOM_PATH_SEPARATOR_LITERAL "/"
|
||||
#define FILESYSTEM_DOM_PATH_SEPARATOR_CHAR '/'
|
||||
|
||||
/*
|
||||
* This class is for error handling.
|
||||
|
@ -46,8 +47,6 @@ public:
|
|||
*/
|
||||
static bool
|
||||
IsDescendantPath(const nsAString& aPath, const nsAString& aDescendantPath);
|
||||
|
||||
static const char16_t kSeparatorChar = char16_t('/');
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -343,41 +343,6 @@ GetDirectoryListingTask::HandlerCallback()
|
|||
|
||||
for (unsigned i = 0; i < count; i++) {
|
||||
if (mTargetData[i].mType == Directory::BlobImplOrDirectoryPath::eDirectoryPath) {
|
||||
#ifdef DEBUG
|
||||
if (XRE_IsParentProcess()) {
|
||||
nsCOMPtr<nsIFile> file;
|
||||
nsresult rv = NS_NewLocalFile(mTargetData[i].mDirectoryPath, false,
|
||||
getter_AddRefs(file));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
mPromise->MaybeReject(rv);
|
||||
mPromise = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
bool exist;
|
||||
rv = file->Exists(&exist);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
mPromise->MaybeReject(rv);
|
||||
mPromise = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
// We cannot assert here because the file can be done in the meantime.
|
||||
NS_ASSERTION(exist, "The file doesn't exist anymore?!?");
|
||||
|
||||
nsAutoString normalizedLocalRootPath;
|
||||
FileSystemUtils::NormalizedPathToLocalPath(mFileSystem->GetLocalRootPath(),
|
||||
normalizedLocalRootPath);
|
||||
|
||||
nsAutoString directoryPath;
|
||||
FileSystemUtils::NormalizedPathToLocalPath(mTargetData[i].mDirectoryPath,
|
||||
directoryPath);
|
||||
|
||||
MOZ_ASSERT(FileSystemUtils::IsDescendantPath(normalizedLocalRootPath,
|
||||
directoryPath));
|
||||
}
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIFile> directoryPath;
|
||||
NS_ConvertUTF16toUTF8 path(mTargetData[i].mDirectoryPath);
|
||||
nsresult rv = NS_NewNativeLocalFile(path, true,
|
||||
|
@ -388,6 +353,19 @@ GetDirectoryListingTask::HandlerCallback()
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsIFile> rootPath;
|
||||
rv = NS_NewLocalFile(mFileSystem->GetLocalRootPath(), false,
|
||||
getter_AddRefs(rootPath));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
mPromise->MaybeReject(rv);
|
||||
mPromise = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(FileSystemUtils::IsDescendantPath(rootPath, directoryPath));
|
||||
#endif
|
||||
|
||||
RefPtr<Directory> directory = Directory::Create(mFileSystem->GetWindow(),
|
||||
directoryPath,
|
||||
Directory::eNotDOMRootDirectory,
|
||||
|
|
|
@ -51,7 +51,7 @@ OSFileSystem::GetWindow() const
|
|||
void
|
||||
OSFileSystem::GetRootName(nsAString& aRetval) const
|
||||
{
|
||||
return aRetval.AssignLiteral("/");
|
||||
aRetval.AssignLiteral(FILESYSTEM_DOM_PATH_SEPARATOR_LITERAL);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
Загрузка…
Ссылка в новой задаче