| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/filesystem/util.h" | 5 #include "components/filesystem/util.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <fcntl.h> | 8 #include <fcntl.h> |
| 9 #include <sys/stat.h> | 9 #include <sys/stat.h> |
| 10 #include <time.h> | 10 #include <time.h> |
| 11 | 11 |
| 12 #include <limits> | 12 #include <limits> |
| 13 | 13 |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
| 16 #include "mojo/public/cpp/bindings/string.h" | 16 #include "mojo/public/cpp/bindings/string.h" |
| 17 | 17 |
| 18 #if defined(OS_WIN) | |
| 19 #include "base/strings/utf_string_conversions.h" | |
| 20 #endif | |
| 21 | |
| 22 // module filesystem has various constants which must line up with enum values | 18 // module filesystem has various constants which must line up with enum values |
| 23 // in base::File::Flags. | 19 // in base::File::Flags. |
| 24 static_assert(filesystem::kFlagOpen == | 20 static_assert(filesystem::kFlagOpen == |
| 25 static_cast<uint32>(base::File::FLAG_OPEN), | 21 static_cast<uint32>(base::File::FLAG_OPEN), |
| 26 ""); | 22 ""); |
| 27 static_assert(filesystem::kFlagCreate == | 23 static_assert(filesystem::kFlagCreate == |
| 28 static_cast<uint32>(base::File::FLAG_CREATE), | 24 static_cast<uint32>(base::File::FLAG_CREATE), |
| 29 ""); | 25 ""); |
| 30 static_assert(filesystem::kFlagOpenAlways == | 26 static_assert(filesystem::kFlagOpenAlways == |
| 31 static_cast<uint32>(base::File::FLAG_OPEN_ALWAYS), | 27 static_cast<uint32>(base::File::FLAG_OPEN_ALWAYS), |
| 32 ""); | 28 ""); |
| 33 static_assert(filesystem::kCreateAlways == | 29 static_assert(filesystem::kCreateAlways == |
| 34 static_cast<uint32>(base::File::FLAG_CREATE_ALWAYS), | 30 static_cast<uint32>(base::File::FLAG_CREATE_ALWAYS), |
| 35 ""); | 31 ""); |
| 36 static_assert(filesystem::kFlagOpenTruncated == | 32 static_assert(filesystem::kFlagOpenTruncated == |
| 37 static_cast<uint32>(base::File::FLAG_OPEN_TRUNCATED), | 33 static_cast<uint32>(base::File::FLAG_OPEN_TRUNCATED), |
| 38 ""); | 34 ""); |
| 39 static_assert(filesystem::kFlagRead == | 35 static_assert(filesystem::kFlagRead == |
| 40 static_cast<uint32>(base::File::FLAG_READ), | 36 static_cast<uint32>(base::File::FLAG_READ), |
| 41 ""); | 37 ""); |
| 42 static_assert(filesystem::kFlagWrite == | 38 static_assert(filesystem::kFlagWrite == |
| 43 static_cast<uint32>(base::File::FLAG_WRITE), | 39 static_cast<uint32>(base::File::FLAG_WRITE), |
| 44 ""); | 40 ""); |
| 45 static_assert(filesystem::kFlagAppend == | 41 static_assert(filesystem::kFlagAppend == |
| 46 static_cast<uint32>(base::File::FLAG_APPEND), | 42 static_cast<uint32>(base::File::FLAG_APPEND), |
| 47 ""); | 43 ""); |
| 48 | 44 |
| 49 // filesystem.Error in types.mojom must be the same as base::File::Error. | 45 // filesystem.Error in types.mojom must be the same as base::File::Error. |
| 50 static_assert(static_cast<int>(filesystem::FILE_ERROR_OK) == | 46 static_assert(static_cast<int>(filesystem::ERROR_OK) == |
| 51 static_cast<int>(base::File::FILE_OK), | 47 static_cast<int>(base::File::FILE_OK), |
| 52 ""); | 48 ""); |
| 53 static_assert(static_cast<int>(filesystem::FILE_ERROR_FAILED) == | 49 static_assert(static_cast<int>(filesystem::ERROR_FAILED) == |
| 54 static_cast<int>(base::File::FILE_ERROR_FAILED), | 50 static_cast<int>(base::File::FILE_ERROR_FAILED), |
| 55 ""); | 51 ""); |
| 56 static_assert(static_cast<int>(filesystem::FILE_ERROR_IN_USE) == | 52 static_assert(static_cast<int>(filesystem::ERROR_IN_USE) == |
| 57 static_cast<int>(base::File::FILE_ERROR_IN_USE), | 53 static_cast<int>(base::File::FILE_ERROR_IN_USE), |
| 58 ""); | 54 ""); |
| 59 static_assert(static_cast<int>(filesystem::FILE_ERROR_EXISTS) == | 55 static_assert(static_cast<int>(filesystem::ERROR_EXISTS) == |
| 60 static_cast<int>(base::File::FILE_ERROR_EXISTS), | 56 static_cast<int>(base::File::FILE_ERROR_EXISTS), |
| 61 ""); | 57 ""); |
| 62 static_assert(static_cast<int>(filesystem::FILE_ERROR_NOT_FOUND) == | 58 static_assert(static_cast<int>(filesystem::ERROR_NOT_FOUND) == |
| 63 static_cast<int>(base::File::FILE_ERROR_NOT_FOUND), | 59 static_cast<int>(base::File::FILE_ERROR_NOT_FOUND), |
| 64 ""); | 60 ""); |
| 65 static_assert(static_cast<int>(filesystem::FILE_ERROR_ACCESS_DENIED) == | 61 static_assert(static_cast<int>(filesystem::ERROR_ACCESS_DENIED) == |
| 66 static_cast<int>(base::File::FILE_ERROR_ACCESS_DENIED), | 62 static_cast<int>(base::File::FILE_ERROR_ACCESS_DENIED), |
| 67 ""); | 63 ""); |
| 68 static_assert(static_cast<int>(filesystem::FILE_ERROR_TOO_MANY_OPENED) == | 64 static_assert(static_cast<int>(filesystem::ERROR_TOO_MANY_OPENED) == |
| 69 static_cast<int>(base::File::FILE_ERROR_TOO_MANY_OPENED), | 65 static_cast<int>(base::File::FILE_ERROR_TOO_MANY_OPENED), |
| 70 ""); | 66 ""); |
| 71 static_assert(static_cast<int>(filesystem::FILE_ERROR_NO_MEMORY) == | 67 static_assert(static_cast<int>(filesystem::ERROR_NO_MEMORY) == |
| 72 static_cast<int>(base::File::FILE_ERROR_NO_MEMORY), | 68 static_cast<int>(base::File::FILE_ERROR_NO_MEMORY), |
| 73 ""); | 69 ""); |
| 74 static_assert(static_cast<int>(filesystem::FILE_ERROR_NO_SPACE) == | 70 static_assert(static_cast<int>(filesystem::ERROR_NO_SPACE) == |
| 75 static_cast<int>(base::File::FILE_ERROR_NO_SPACE), | 71 static_cast<int>(base::File::FILE_ERROR_NO_SPACE), |
| 76 ""); | 72 ""); |
| 77 static_assert(static_cast<int>(filesystem::FILE_ERROR_NOT_A_DIRECTORY) == | 73 static_assert(static_cast<int>(filesystem::ERROR_NOT_A_DIRECTORY) == |
| 78 static_cast<int>(base::File::FILE_ERROR_NOT_A_DIRECTORY), | 74 static_cast<int>(base::File::FILE_ERROR_NOT_A_DIRECTORY), |
| 79 ""); | 75 ""); |
| 80 static_assert(static_cast<int>(filesystem::FILE_ERROR_INVALID_OPERATION) == | 76 static_assert(static_cast<int>(filesystem::ERROR_INVALID_OPERATION) == |
| 81 static_cast<int>(base::File::FILE_ERROR_INVALID_OPERATION), | 77 static_cast<int>(base::File::FILE_ERROR_INVALID_OPERATION), |
| 82 ""); | 78 ""); |
| 83 static_assert(static_cast<int>(filesystem::FILE_ERROR_SECURITY) == | 79 static_assert(static_cast<int>(filesystem::ERROR_SECURITY) == |
| 84 static_cast<int>(base::File::FILE_ERROR_SECURITY), | 80 static_cast<int>(base::File::FILE_ERROR_SECURITY), |
| 85 ""); | 81 ""); |
| 86 static_assert(static_cast<int>(filesystem::FILE_ERROR_ABORT) == | 82 static_assert(static_cast<int>(filesystem::ERROR_ABORT) == |
| 87 static_cast<int>(base::File::FILE_ERROR_ABORT), | 83 static_cast<int>(base::File::FILE_ERROR_ABORT), |
| 88 ""); | 84 ""); |
| 89 static_assert(static_cast<int>(filesystem::FILE_ERROR_NOT_A_FILE) == | 85 static_assert(static_cast<int>(filesystem::ERROR_NOT_A_FILE) == |
| 90 static_cast<int>(base::File::FILE_ERROR_NOT_A_FILE), | 86 static_cast<int>(base::File::FILE_ERROR_NOT_A_FILE), |
| 91 ""); | 87 ""); |
| 92 static_assert(static_cast<int>(filesystem::FILE_ERROR_NOT_EMPTY) == | 88 static_assert(static_cast<int>(filesystem::ERROR_NOT_EMPTY) == |
| 93 static_cast<int>(base::File::FILE_ERROR_NOT_EMPTY), | 89 static_cast<int>(base::File::FILE_ERROR_NOT_EMPTY), |
| 94 ""); | 90 ""); |
| 95 static_assert(static_cast<int>(filesystem::FILE_ERROR_INVALID_URL) == | 91 static_assert(static_cast<int>(filesystem::ERROR_INVALID_URL) == |
| 96 static_cast<int>(base::File::FILE_ERROR_INVALID_URL), | 92 static_cast<int>(base::File::FILE_ERROR_INVALID_URL), |
| 97 ""); | 93 ""); |
| 98 static_assert(static_cast<int>(filesystem::FILE_ERROR_IO) == | 94 static_assert(static_cast<int>(filesystem::ERROR_IO) == |
| 99 static_cast<int>(base::File::FILE_ERROR_IO), | 95 static_cast<int>(base::File::FILE_ERROR_IO), |
| 100 ""); | 96 ""); |
| 101 | 97 |
| 102 // filesystem.Whence in types.mojom must be the same as base::File::Whence. | 98 // filesystem.Whence in types.mojom must be the same as base::File::Whence. |
| 103 static_assert(static_cast<int>(filesystem::WHENCE_FROM_BEGIN) == | 99 static_assert(static_cast<int>(filesystem::WHENCE_FROM_BEGIN) == |
| 104 static_cast<int>(base::File::FROM_BEGIN), | 100 static_cast<int>(base::File::FROM_BEGIN), |
| 105 ""); | 101 ""); |
| 106 static_assert(static_cast<int>(filesystem::WHENCE_FROM_CURRENT) == | 102 static_assert(static_cast<int>(filesystem::WHENCE_FROM_CURRENT) == |
| 107 static_cast<int>(base::File::FROM_CURRENT), | 103 static_cast<int>(base::File::FROM_CURRENT), |
| 108 ""); | 104 ""); |
| 109 static_assert(static_cast<int>(filesystem::WHENCE_FROM_END) == | 105 static_assert(static_cast<int>(filesystem::WHENCE_FROM_END) == |
| 110 static_cast<int>(base::File::FROM_END), | 106 static_cast<int>(base::File::FROM_END), |
| 111 ""); | 107 ""); |
| 112 | 108 |
| 113 namespace filesystem { | 109 namespace filesystem { |
| 114 | 110 |
| 115 FileError IsWhenceValid(Whence whence) { | 111 Error IsWhenceValid(Whence whence) { |
| 116 return (whence == WHENCE_FROM_CURRENT || whence == WHENCE_FROM_BEGIN || | 112 return (whence == WHENCE_FROM_CURRENT || whence == WHENCE_FROM_BEGIN || |
| 117 whence == WHENCE_FROM_END) | 113 whence == WHENCE_FROM_END) |
| 118 ? FILE_ERROR_OK | 114 ? ERROR_OK |
| 119 : FILE_ERROR_INVALID_OPERATION; | 115 : ERROR_INVALID_OPERATION; |
| 120 } | 116 } |
| 121 | 117 |
| 122 FileError IsOffsetValid(int64_t offset) { | 118 Error IsOffsetValid(int64_t offset) { |
| 123 return (offset >= std::numeric_limits<off_t>::min() && | 119 return (offset >= std::numeric_limits<off_t>::min() && |
| 124 offset <= std::numeric_limits<off_t>::max()) | 120 offset <= std::numeric_limits<off_t>::max()) |
| 125 ? FILE_ERROR_OK | 121 ? ERROR_OK |
| 126 : FILE_ERROR_INVALID_OPERATION; | 122 : ERROR_INVALID_OPERATION; |
| 127 } | 123 } |
| 128 | 124 |
| 129 FileError GetError(const base::File& file) { | 125 Error GetError(const base::File& file) { |
| 130 return static_cast<filesystem::FileError>(file.error_details()); | 126 return static_cast<filesystem::Error>(file.error_details()); |
| 131 } | 127 } |
| 132 | 128 |
| 133 FileInformationPtr MakeFileInformation(const base::File::Info& info) { | 129 FileInformationPtr MakeFileInformation(const base::File::Info& info) { |
| 134 FileInformationPtr file_info(FileInformation::New()); | 130 FileInformationPtr file_info(FileInformation::New()); |
| 135 file_info->type = | 131 file_info->type = |
| 136 info.is_directory ? FS_FILE_TYPE_DIRECTORY : FS_FILE_TYPE_REGULAR_FILE; | 132 info.is_directory ? FILE_TYPE_DIRECTORY : FILE_TYPE_REGULAR_FILE; |
| 137 file_info->size = info.size; | 133 file_info->size = info.size; |
| 138 | 134 |
| 139 file_info->atime = info.last_accessed.ToDoubleT(); | 135 file_info->atime = info.last_accessed.ToDoubleT(); |
| 140 file_info->mtime = info.last_modified.ToDoubleT(); | 136 file_info->mtime = info.last_modified.ToDoubleT(); |
| 141 file_info->ctime = info.creation_time.ToDoubleT(); | 137 file_info->ctime = info.creation_time.ToDoubleT(); |
| 142 | 138 |
| 143 return file_info.Pass(); | 139 return file_info.Pass(); |
| 144 } | 140 } |
| 145 | 141 |
| 146 FileError ValidatePath(const mojo::String& raw_path, | 142 Error ValidatePath(const mojo::String& raw_path, |
| 147 const base::FilePath& filesystem_base, | 143 const base::FilePath& filesystem_base, |
| 148 base::FilePath* out) { | 144 base::FilePath* out) { |
| 149 DCHECK(!raw_path.is_null()); | 145 DCHECK(!raw_path.is_null()); |
| 150 if (!base::IsStringUTF8(raw_path.get())) | 146 if (!base::IsStringUTF8(raw_path.get())) |
| 151 return FILE_ERROR_INVALID_OPERATION; | 147 return ERROR_INVALID_OPERATION; |
| 152 | |
| 153 #if defined(OS_POSIX) | |
| 154 base::FilePath::StringType path = raw_path; | |
| 155 #elif defined(OS_WIN) | |
| 156 base::FilePath::StringType path = base::UTF8ToUTF16(raw_path.get()); | |
| 157 #endif | |
| 158 | 148 |
| 159 // TODO(erg): This isn't really what we want. FilePath::AppendRelativePath() | 149 // TODO(erg): This isn't really what we want. FilePath::AppendRelativePath() |
| 160 // is closer. We need to deal with entirely hostile apps trying to bust this | 150 // is closer. We need to deal with entirely hostile apps trying to bust this |
| 161 // function to use a possibly maliciously provided |raw_path| to bust out of | 151 // function to use a possibly maliciously provided |raw_path| to bust out of |
| 162 // |filesystem_base|. | 152 // |filesystem_base|. |
| 163 base::FilePath full_path = filesystem_base.Append(path); | 153 base::FilePath full_path = filesystem_base.Append(raw_path); |
| 164 if (full_path.ReferencesParent()) { | 154 if (full_path.ReferencesParent()) { |
| 165 // TODO(erg): For now, if it references a parent, we'll consider this bad. | 155 // TODO(erg): For now, if it references a parent, we'll consider this bad. |
| 166 return FILE_ERROR_ACCESS_DENIED; | 156 return ERROR_ACCESS_DENIED; |
| 167 } | 157 } |
| 168 | 158 |
| 169 *out = full_path; | 159 *out = full_path; |
| 170 return FILE_ERROR_OK; | 160 return ERROR_OK; |
| 171 } | 161 } |
| 172 | 162 |
| 173 } // namespace filesystem | 163 } // namespace filesystem |
| OLD | NEW |