| Index: components/filesystem/util.cc
|
| diff --git a/components/filesystem/util.cc b/components/filesystem/util.cc
|
| index c4797e3e1025ddbd4aee54a79e991b32835ef8bb..e268bc4e057421b584d62a4269df6cbed1efef9c 100644
|
| --- a/components/filesystem/util.cc
|
| +++ b/components/filesystem/util.cc
|
| @@ -15,146 +15,148 @@
|
| #include "base/strings/string_util.h"
|
| #include "mojo/public/cpp/bindings/string.h"
|
|
|
| -namespace filesystem {
|
| +// module filesystem has various constants which must line up with enum values
|
| +// in base::File::Flags.
|
| +static_assert(filesystem::kFlagOpen ==
|
| + static_cast<uint32>(base::File::FLAG_OPEN),
|
| + "");
|
| +static_assert(filesystem::kFlagCreate ==
|
| + static_cast<uint32>(base::File::FLAG_CREATE),
|
| + "");
|
| +static_assert(filesystem::kFlagOpenAlways ==
|
| + static_cast<uint32>(base::File::FLAG_OPEN_ALWAYS),
|
| + "");
|
| +static_assert(filesystem::kCreateAlways ==
|
| + static_cast<uint32>(base::File::FLAG_CREATE_ALWAYS),
|
| + "");
|
| +static_assert(filesystem::kFlagOpenTruncated ==
|
| + static_cast<uint32>(base::File::FLAG_OPEN_TRUNCATED),
|
| + "");
|
| +static_assert(filesystem::kFlagRead ==
|
| + static_cast<uint32>(base::File::FLAG_READ),
|
| + "");
|
| +static_assert(filesystem::kFlagWrite ==
|
| + static_cast<uint32>(base::File::FLAG_WRITE),
|
| + "");
|
| +static_assert(filesystem::kFlagAppend ==
|
| + static_cast<uint32>(base::File::FLAG_APPEND),
|
| + "");
|
| +
|
| +// filesystem.Error in types.mojom must be the same as base::File::Error.
|
| +static_assert(static_cast<int>(filesystem::ERROR_OK) ==
|
| + static_cast<int>(base::File::FILE_OK),
|
| + "");
|
| +static_assert(static_cast<int>(filesystem::ERROR_FAILED) ==
|
| + static_cast<int>(base::File::FILE_ERROR_FAILED),
|
| + "");
|
| +static_assert(static_cast<int>(filesystem::ERROR_IN_USE) ==
|
| + static_cast<int>(base::File::FILE_ERROR_IN_USE),
|
| + "");
|
| +static_assert(static_cast<int>(filesystem::ERROR_EXISTS) ==
|
| + static_cast<int>(base::File::FILE_ERROR_EXISTS),
|
| + "");
|
| +static_assert(static_cast<int>(filesystem::ERROR_NOT_FOUND) ==
|
| + static_cast<int>(base::File::FILE_ERROR_NOT_FOUND),
|
| + "");
|
| +static_assert(static_cast<int>(filesystem::ERROR_ACCESS_DENIED) ==
|
| + static_cast<int>(base::File::FILE_ERROR_ACCESS_DENIED),
|
| + "");
|
| +static_assert(static_cast<int>(filesystem::ERROR_TOO_MANY_OPENED) ==
|
| + static_cast<int>(base::File::FILE_ERROR_TOO_MANY_OPENED),
|
| + "");
|
| +static_assert(static_cast<int>(filesystem::ERROR_NO_MEMORY) ==
|
| + static_cast<int>(base::File::FILE_ERROR_NO_MEMORY),
|
| + "");
|
| +static_assert(static_cast<int>(filesystem::ERROR_NO_SPACE) ==
|
| + static_cast<int>(base::File::FILE_ERROR_NO_SPACE),
|
| + "");
|
| +static_assert(static_cast<int>(filesystem::ERROR_NOT_A_DIRECTORY) ==
|
| + static_cast<int>(base::File::FILE_ERROR_NOT_A_DIRECTORY),
|
| + "");
|
| +static_assert(static_cast<int>(filesystem::ERROR_INVALID_OPERATION) ==
|
| + static_cast<int>(base::File::FILE_ERROR_INVALID_OPERATION),
|
| + "");
|
| +static_assert(static_cast<int>(filesystem::ERROR_SECURITY) ==
|
| + static_cast<int>(base::File::FILE_ERROR_SECURITY),
|
| + "");
|
| +static_assert(static_cast<int>(filesystem::ERROR_ABORT) ==
|
| + static_cast<int>(base::File::FILE_ERROR_ABORT),
|
| + "");
|
| +static_assert(static_cast<int>(filesystem::ERROR_NOT_A_FILE) ==
|
| + static_cast<int>(base::File::FILE_ERROR_NOT_A_FILE),
|
| + "");
|
| +static_assert(static_cast<int>(filesystem::ERROR_NOT_EMPTY) ==
|
| + static_cast<int>(base::File::FILE_ERROR_NOT_EMPTY),
|
| + "");
|
| +static_assert(static_cast<int>(filesystem::ERROR_INVALID_URL) ==
|
| + static_cast<int>(base::File::FILE_ERROR_INVALID_URL),
|
| + "");
|
| +static_assert(static_cast<int>(filesystem::ERROR_IO) ==
|
| + static_cast<int>(base::File::FILE_ERROR_IO),
|
| + "");
|
| +
|
| +// filesystem.Whence in types.mojom must be the same as base::File::Whence.
|
| +static_assert(static_cast<int>(filesystem::WHENCE_FROM_BEGIN) ==
|
| + static_cast<int>(base::File::FROM_BEGIN),
|
| + "");
|
| +static_assert(static_cast<int>(filesystem::WHENCE_FROM_CURRENT) ==
|
| + static_cast<int>(base::File::FROM_CURRENT),
|
| + "");
|
| +static_assert(static_cast<int>(filesystem::WHENCE_FROM_END) ==
|
| + static_cast<int>(base::File::FROM_END),
|
| + "");
|
|
|
| -Error IsPathValid(const mojo::String& path) {
|
| - DCHECK(!path.is_null());
|
| - if (!base::IsStringUTF8(path.get()))
|
| - return ERROR_INVALID_ARGUMENT;
|
| - if (path.size() > 0 && path[0] == '/')
|
| - return ERROR_PERMISSION_DENIED;
|
| - return ERROR_OK;
|
| -}
|
| +namespace filesystem {
|
|
|
| Error IsWhenceValid(Whence whence) {
|
| - return (whence == WHENCE_FROM_CURRENT || whence == WHENCE_FROM_START ||
|
| + return (whence == WHENCE_FROM_CURRENT || whence == WHENCE_FROM_BEGIN ||
|
| whence == WHENCE_FROM_END)
|
| ? ERROR_OK
|
| - : ERROR_UNIMPLEMENTED;
|
| + : ERROR_INVALID_OPERATION;
|
| }
|
|
|
| Error IsOffsetValid(int64_t offset) {
|
| return (offset >= std::numeric_limits<off_t>::min() &&
|
| offset <= std::numeric_limits<off_t>::max())
|
| ? ERROR_OK
|
| - : ERROR_OUT_OF_RANGE;
|
| -}
|
| -
|
| -Error ErrnoToError(int errno_value) {
|
| - // TODO(vtl)
|
| - return ERROR_UNKNOWN;
|
| + : ERROR_INVALID_OPERATION;
|
| }
|
|
|
| -int WhenceToStandardWhence(Whence whence) {
|
| - DCHECK_EQ(IsWhenceValid(whence), ERROR_OK);
|
| - switch (whence) {
|
| - case WHENCE_FROM_CURRENT:
|
| - return SEEK_CUR;
|
| - case WHENCE_FROM_START:
|
| - return SEEK_SET;
|
| - case WHENCE_FROM_END:
|
| - return SEEK_END;
|
| - }
|
| - NOTREACHED();
|
| - return 0;
|
| +Error GetError(const base::File& file) {
|
| + return static_cast<filesystem::Error>(file.error_details());
|
| }
|
|
|
| -Error TimespecToStandardTimespec(const Timespec* in, struct timespec* out) {
|
| - if (!in) {
|
| - out->tv_sec = 0;
|
| - out->tv_nsec = UTIME_OMIT;
|
| - return ERROR_OK;
|
| - }
|
| -
|
| - static_assert(sizeof(int64_t) >= sizeof(time_t), "whoa, time_t is huge");
|
| - if (in->seconds < std::numeric_limits<time_t>::min() ||
|
| - in->seconds > std::numeric_limits<time_t>::max())
|
| - return ERROR_OUT_OF_RANGE;
|
| +FileInformationPtr MakeFileInformation(const base::File::Info& info) {
|
| + FileInformationPtr file_info(FileInformation::New());
|
| + file_info->type =
|
| + info.is_directory ? FILE_TYPE_DIRECTORY : FILE_TYPE_REGULAR_FILE;
|
| + file_info->size = info.size;
|
|
|
| - if (in->nanoseconds < 0 || in->nanoseconds >= 1000000000)
|
| - return ERROR_INVALID_ARGUMENT;
|
| + file_info->atime = info.last_accessed.ToDoubleT();
|
| + file_info->mtime = info.last_modified.ToDoubleT();
|
| + file_info->ctime = info.creation_time.ToDoubleT();
|
|
|
| - out->tv_sec = static_cast<time_t>(in->seconds);
|
| - out->tv_nsec = static_cast<long>(in->nanoseconds);
|
| - return ERROR_OK;
|
| + return file_info.Pass();
|
| }
|
|
|
| -Error TimespecOrNowToStandardTimespec(const TimespecOrNow* in,
|
| - struct timespec* out) {
|
| - if (!in) {
|
| - out->tv_sec = 0;
|
| - out->tv_nsec = UTIME_OMIT;
|
| - return ERROR_OK;
|
| - }
|
| -
|
| - if (in->now) {
|
| - if (!in->timespec.is_null())
|
| - return ERROR_INVALID_ARGUMENT;
|
| - out->tv_sec = 0;
|
| - out->tv_nsec = UTIME_NOW;
|
| - return ERROR_OK;
|
| +Error ValidatePath(const mojo::String& raw_path,
|
| + const base::FilePath& filesystem_base,
|
| + base::FilePath* out) {
|
| + DCHECK(!raw_path.is_null());
|
| + if (!base::IsStringUTF8(raw_path.get()))
|
| + return ERROR_INVALID_OPERATION;
|
| +
|
| + // TODO(erg): This isn't really what we want. FilePath::AppendRelativePath()
|
| + // is closer. We need to deal with entirely hostile apps trying to bust this
|
| + // function to use a possibly maliciously provided |raw_path| to bust out of
|
| + // |filesystem_base|.
|
| + base::FilePath full_path = filesystem_base.Append(raw_path);
|
| + if (full_path.ReferencesParent()) {
|
| + // TODO(erg): For now, if it references a parent, we'll consider this bad.
|
| + return ERROR_ACCESS_DENIED;
|
| }
|
|
|
| - return TimespecToStandardTimespec(in->timespec.get(), out);
|
| -}
|
| -
|
| -Error ValidateOpenFlags(uint32_t open_flags, bool is_directory) {
|
| - // Treat unknown flags as "unimplemented".
|
| - if ((open_flags &
|
| - ~(kOpenFlagRead | kOpenFlagWrite | kOpenFlagCreate | kOpenFlagExclusive |
|
| - kOpenFlagAppend | kOpenFlagTruncate)))
|
| - return ERROR_UNIMPLEMENTED;
|
| -
|
| - // At least one of |kOpenFlagRead| or |kOpenFlagWrite| must be set.
|
| - if (!(open_flags & (kOpenFlagRead | kOpenFlagWrite)))
|
| - return ERROR_INVALID_ARGUMENT;
|
| -
|
| - // |kOpenFlagCreate| requires |kOpenFlagWrite|.
|
| - if ((open_flags & kOpenFlagCreate) && !(open_flags & kOpenFlagWrite))
|
| - return ERROR_INVALID_ARGUMENT;
|
| -
|
| - // |kOpenFlagExclusive| requires |kOpenFlagCreate|.
|
| - if ((open_flags & kOpenFlagExclusive) && !(open_flags & kOpenFlagCreate))
|
| - return ERROR_INVALID_ARGUMENT;
|
| -
|
| - if (is_directory) {
|
| - // Check that file-only flags aren't set.
|
| - if ((open_flags & (kOpenFlagAppend | kOpenFlagTruncate)))
|
| - return ERROR_INVALID_ARGUMENT;
|
| - return ERROR_OK;
|
| - }
|
| -
|
| - // File-only flags:
|
| -
|
| - // |kOpenFlagAppend| requires |kOpenFlagWrite|.
|
| - if ((open_flags & kOpenFlagAppend) && !(open_flags & kOpenFlagWrite))
|
| - return ERROR_INVALID_ARGUMENT;
|
| -
|
| - // |kOpenFlagTruncate| requires |kOpenFlagWrite|.
|
| - if ((open_flags & kOpenFlagTruncate) && !(open_flags & kOpenFlagWrite))
|
| - return ERROR_INVALID_ARGUMENT;
|
| -
|
| - return ERROR_OK;
|
| -}
|
| -
|
| -Error ValidateDeleteFlags(uint32_t delete_flags) {
|
| - // Treat unknown flags as "unimplemented".
|
| - if ((delete_flags &
|
| - ~(kDeleteFlagFileOnly | kDeleteFlagDirectoryOnly |
|
| - kDeleteFlagRecursive)))
|
| - return ERROR_UNIMPLEMENTED;
|
| -
|
| - // Only one of the three currently-defined flags may be set.
|
| - if ((delete_flags & kDeleteFlagFileOnly) &&
|
| - (delete_flags & (kDeleteFlagDirectoryOnly | kDeleteFlagRecursive)))
|
| - return ERROR_INVALID_ARGUMENT;
|
| - if ((delete_flags & kDeleteFlagDirectoryOnly) &&
|
| - (delete_flags & (kDeleteFlagFileOnly | kDeleteFlagRecursive)))
|
| - return ERROR_INVALID_ARGUMENT;
|
| - if ((delete_flags & kDeleteFlagRecursive) &&
|
| - (delete_flags & (kDeleteFlagFileOnly | kDeleteFlagDirectoryOnly)))
|
| - return ERROR_INVALID_ARGUMENT;
|
| -
|
| + *out = full_path;
|
| return ERROR_OK;
|
| }
|
|
|
|
|