| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "webkit/fileapi/isolated_context.h" | 5 #include "webkit/fileapi/isolated_context.h" |
| 6 | 6 |
| 7 #include "base/file_path.h" | 7 #include "base/file_path.h" |
| 8 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/rand_util.h" | 10 #include "base/rand_util.h" |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 #endif | 39 #endif |
| 40 } | 40 } |
| 41 | 41 |
| 42 bool IsSinglePathIsolatedFileSystem(FileSystemType type) { | 42 bool IsSinglePathIsolatedFileSystem(FileSystemType type) { |
| 43 switch (type) { | 43 switch (type) { |
| 44 // As of writing dragged file system is the only filesystem | 44 // As of writing dragged file system is the only filesystem |
| 45 // which could have multiple toplevel paths. | 45 // which could have multiple toplevel paths. |
| 46 case kFileSystemTypeDragged: | 46 case kFileSystemTypeDragged: |
| 47 return false; | 47 return false; |
| 48 | 48 |
| 49 // Regular file systems. | |
| 50 case kFileSystemTypeIsolated: | |
| 51 case kFileSystemTypeNativeMedia: | |
| 52 case kFileSystemTypeDeviceMedia: | |
| 53 case kFileSystemTypeTemporary: | |
| 54 case kFileSystemTypePersistent: | |
| 55 case kFileSystemTypeExternal: | |
| 56 case kFileSystemTypeTest: | |
| 57 return true; | |
| 58 | |
| 59 case kFileSystemTypeUnknown: | 49 case kFileSystemTypeUnknown: |
| 60 NOTREACHED(); | 50 NOTREACHED(); |
| 61 return true; | 51 return true; |
| 52 |
| 53 default: |
| 54 return true; |
| 62 } | 55 } |
| 63 NOTREACHED(); | 56 NOTREACHED(); |
| 64 return true; | 57 return true; |
| 65 } | 58 } |
| 66 | 59 |
| 67 } | 60 } |
| 68 | 61 |
| 69 static base::LazyInstance<IsolatedContext>::Leaky g_isolated_context = | 62 static base::LazyInstance<IsolatedContext>::Leaky g_isolated_context = |
| 70 LAZY_INSTANCE_INITIALIZER; | 63 LAZY_INSTANCE_INITIALIZER; |
| 71 | 64 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 bool IsolatedContext::FileInfoSet::AddPathWithName( | 98 bool IsolatedContext::FileInfoSet::AddPathWithName( |
| 106 const FilePath& path, const std::string& name) { | 99 const FilePath& path, const std::string& name) { |
| 107 // The given path should not contain any '..' and should be absolute. | 100 // The given path should not contain any '..' and should be absolute. |
| 108 if (path.ReferencesParent() || !path.IsAbsolute()) | 101 if (path.ReferencesParent() || !path.IsAbsolute()) |
| 109 return false; | 102 return false; |
| 110 return fileset_.insert(FileInfo(name, path.NormalizePathSeparators())).second; | 103 return fileset_.insert(FileInfo(name, path.NormalizePathSeparators())).second; |
| 111 } | 104 } |
| 112 | 105 |
| 113 //-------------------------------------------------------------------------- | 106 //-------------------------------------------------------------------------- |
| 114 | 107 |
| 108 class IsolatedContext::Instance { |
| 109 public: |
| 110 typedef FileSystemMountType MountType; |
| 111 |
| 112 // For a single-path isolated file system, which could be registered by |
| 113 // IsolatedContext::RegisterFileSystemForPath(). |
| 114 // Most of isolated file system contexts should be of this type. |
| 115 Instance(FileSystemType type, const FileInfo& file_info); |
| 116 |
| 117 // For a multi-paths isolated file system. As of writing only file system |
| 118 // type which could have multi-paths is Dragged file system, and |
| 119 // could be registered by IsolatedContext::RegisterDraggedFileSystem(). |
| 120 Instance(FileSystemType type, const std::set<FileInfo>& files); |
| 121 |
| 122 // For a single-path external file system. |
| 123 Instance(FileSystemType type, const FilePath& path); |
| 124 |
| 125 ~Instance(); |
| 126 |
| 127 MountType mount_type() const { return mount_type_; } |
| 128 FileSystemType type() const { return type_; } |
| 129 const FileInfo& file_info() const { return file_info_; } |
| 130 const std::set<FileInfo>& files() const { return files_; } |
| 131 int ref_counts() const { return ref_counts_; } |
| 132 |
| 133 void AddRef() { ++ref_counts_; } |
| 134 void RemoveRef() { --ref_counts_; } |
| 135 |
| 136 bool ResolvePathForName(const std::string& name, FilePath* path) const; |
| 137 |
| 138 // Returns true if the instance is a single-path instance. |
| 139 bool IsSinglePathInstance() const; |
| 140 |
| 141 private: |
| 142 const MountType mount_type_; |
| 143 const FileSystemType type_; |
| 144 |
| 145 // For single-path instance. |
| 146 const FileInfo file_info_; |
| 147 |
| 148 // For multiple-path instance (e.g. dragged file system). |
| 149 const std::set<FileInfo> files_; |
| 150 |
| 151 // Reference counts. Note that an isolated filesystem is created with ref==0 |
| 152 // and will get deleted when the ref count reaches <=0. |
| 153 int ref_counts_; |
| 154 |
| 155 DISALLOW_COPY_AND_ASSIGN(Instance); |
| 156 }; |
| 157 |
| 115 IsolatedContext::Instance::Instance(FileSystemType type, | 158 IsolatedContext::Instance::Instance(FileSystemType type, |
| 116 const FileInfo& file_info) | 159 const FileInfo& file_info) |
| 117 : type_(type), | 160 : mount_type_(kFileSystemMountTypeIsolated), |
| 161 type_(type), |
| 118 file_info_(file_info), | 162 file_info_(file_info), |
| 119 ref_counts_(0) { | 163 ref_counts_(0) { |
| 120 DCHECK(IsSinglePathIsolatedFileSystem(type_)); | 164 DCHECK(IsSinglePathIsolatedFileSystem(type_)); |
| 121 } | 165 } |
| 122 | 166 |
| 123 IsolatedContext::Instance::Instance(FileSystemType type, | 167 IsolatedContext::Instance::Instance(FileSystemType type, |
| 124 const std::set<FileInfo>& files) | 168 const std::set<FileInfo>& files) |
| 125 : type_(type), | 169 : mount_type_(kFileSystemMountTypeIsolated), |
| 170 type_(type), |
| 126 files_(files), | 171 files_(files), |
| 127 ref_counts_(0) { | 172 ref_counts_(0) { |
| 128 DCHECK(!IsSinglePathIsolatedFileSystem(type_)); | 173 DCHECK(!IsSinglePathIsolatedFileSystem(type_)); |
| 129 } | 174 } |
| 130 | 175 |
| 176 IsolatedContext::Instance::Instance(FileSystemType type, |
| 177 const FilePath& path) |
| 178 : mount_type_(kFileSystemMountTypeExternal), |
| 179 type_(type), |
| 180 file_info_(FileInfo("", path)), |
| 181 ref_counts_(0) { |
| 182 DCHECK(IsSinglePathIsolatedFileSystem(type_)); |
| 183 } |
| 184 |
| 131 IsolatedContext::Instance::~Instance() {} | 185 IsolatedContext::Instance::~Instance() {} |
| 132 | 186 |
| 133 bool IsolatedContext::Instance::ResolvePathForName(const std::string& name, | 187 bool IsolatedContext::Instance::ResolvePathForName(const std::string& name, |
| 134 FilePath* path) const { | 188 FilePath* path) const { |
| 135 if (IsSinglePathIsolatedFileSystem(type_)) { | 189 if (IsSinglePathIsolatedFileSystem(type_)) { |
| 136 *path = file_info_.path; | 190 *path = file_info_.path; |
| 137 return file_info_.name == name; | 191 return file_info_.name == name; |
| 138 } | 192 } |
| 139 std::set<FileInfo>::const_iterator found = files_.find( | 193 std::set<FileInfo>::const_iterator found = files_.find( |
| 140 FileInfo(name, FilePath())); | 194 FileInfo(name, FilePath())); |
| 141 if (found == files_.end()) | 195 if (found == files_.end()) |
| 142 return false; | 196 return false; |
| 143 *path = found->path; | 197 *path = found->path; |
| 144 return true; | 198 return true; |
| 145 } | 199 } |
| 146 | 200 |
| 147 bool IsolatedContext::Instance::IsSinglePathInstance() const { | 201 bool IsolatedContext::Instance::IsSinglePathInstance() const { |
| 148 return IsSinglePathIsolatedFileSystem(type_); | 202 return IsSinglePathIsolatedFileSystem(type_); |
| 149 } | 203 } |
| 150 | 204 |
| 151 //-------------------------------------------------------------------------- | 205 //-------------------------------------------------------------------------- |
| 152 | 206 |
| 153 // static | 207 // static |
| 154 IsolatedContext* IsolatedContext::GetInstance() { | 208 IsolatedContext* IsolatedContext::GetInstance() { |
| 155 return g_isolated_context.Pointer(); | 209 return g_isolated_context.Pointer(); |
| 156 } | 210 } |
| 157 | 211 |
| 212 // static |
| 213 bool IsolatedContext::IsIsolatedType(FileSystemType type) { |
| 214 return type == kFileSystemTypeIsolated || type == kFileSystemTypeExternal; |
| 215 } |
| 216 |
| 158 std::string IsolatedContext::RegisterDraggedFileSystem( | 217 std::string IsolatedContext::RegisterDraggedFileSystem( |
| 159 const FileInfoSet& files) { | 218 const FileInfoSet& files) { |
| 160 base::AutoLock locker(lock_); | 219 base::AutoLock locker(lock_); |
| 161 std::string filesystem_id = GetNewFileSystemId(); | 220 std::string filesystem_id = GetNewFileSystemId(); |
| 162 instance_map_[filesystem_id] = new Instance( | 221 instance_map_[filesystem_id] = new Instance( |
| 163 kFileSystemTypeDragged, files.fileset()); | 222 kFileSystemTypeDragged, files.fileset()); |
| 164 return filesystem_id; | 223 return filesystem_id; |
| 165 } | 224 } |
| 166 | 225 |
| 167 std::string IsolatedContext::RegisterFileSystemForPath( | 226 std::string IsolatedContext::RegisterFileSystemForPath( |
| (...skipping 11 matching lines...) Expand all Loading... |
| 179 register_name->assign(name); | 238 register_name->assign(name); |
| 180 } | 239 } |
| 181 | 240 |
| 182 base::AutoLock locker(lock_); | 241 base::AutoLock locker(lock_); |
| 183 std::string filesystem_id = GetNewFileSystemId(); | 242 std::string filesystem_id = GetNewFileSystemId(); |
| 184 instance_map_[filesystem_id] = new Instance(type, FileInfo(name, path)); | 243 instance_map_[filesystem_id] = new Instance(type, FileInfo(name, path)); |
| 185 path_to_id_map_[path].insert(filesystem_id); | 244 path_to_id_map_[path].insert(filesystem_id); |
| 186 return filesystem_id; | 245 return filesystem_id; |
| 187 } | 246 } |
| 188 | 247 |
| 248 #if defined(OS_CHROMEOS) |
| 249 bool IsolatedContext::RegisterExternalFileSystem(const std::string& mount_name, |
| 250 FileSystemType type, |
| 251 const FilePath& path) { |
| 252 base::AutoLock locker(lock_); |
| 253 IDToInstance::iterator found = instance_map_.find(mount_name); |
| 254 if (found != instance_map_.end()) |
| 255 return false; |
| 256 instance_map_[mount_name] = new Instance(type, path); |
| 257 path_to_id_map_[path].insert(mount_name); |
| 258 return true; |
| 259 } |
| 260 |
| 261 std::vector<IsolatedContext::FileInfo> |
| 262 IsolatedContext::GetExternalMountPoints() const { |
| 263 base::AutoLock locker(lock_); |
| 264 std::vector<FileInfo> files; |
| 265 for (IDToInstance::const_iterator iter = instance_map_.begin(); |
| 266 iter != instance_map_.end(); |
| 267 ++iter) { |
| 268 if (iter->second->mount_type() == kFileSystemMountTypeExternal) |
| 269 files.push_back(FileInfo(iter->first, iter->second->file_info().path)); |
| 270 } |
| 271 return files; |
| 272 } |
| 273 #endif |
| 274 |
| 189 bool IsolatedContext::RevokeFileSystem(const std::string& filesystem_id) { | 275 bool IsolatedContext::RevokeFileSystem(const std::string& filesystem_id) { |
| 190 base::AutoLock locker(lock_); | 276 base::AutoLock locker(lock_); |
| 191 return UnregisterFileSystem(filesystem_id); | 277 return UnregisterFileSystem(filesystem_id); |
| 192 } | 278 } |
| 193 | 279 |
| 194 void IsolatedContext::RevokeFileSystemByPath(const FilePath& path_in) { | 280 void IsolatedContext::RevokeFileSystemByPath(const FilePath& path_in) { |
| 195 base::AutoLock locker(lock_); | 281 base::AutoLock locker(lock_); |
| 196 FilePath path(path_in.NormalizePathSeparators()); | 282 FilePath path(path_in.NormalizePathSeparators()); |
| 197 PathToID::iterator ids_iter = path_to_id_map_.find(path); | 283 PathToID::iterator ids_iter = path_to_id_map_.find(path); |
| 198 if (ids_iter == path_to_id_map_.end()) | 284 if (ids_iter == path_to_id_map_.end()) |
| (...skipping 19 matching lines...) Expand all Loading... |
| 218 void IsolatedContext::RemoveReference(const std::string& filesystem_id) { | 304 void IsolatedContext::RemoveReference(const std::string& filesystem_id) { |
| 219 base::AutoLock locker(lock_); | 305 base::AutoLock locker(lock_); |
| 220 // This could get called for non-existent filesystem if it has been | 306 // This could get called for non-existent filesystem if it has been |
| 221 // already deleted by RevokeFileSystemByPath. | 307 // already deleted by RevokeFileSystemByPath. |
| 222 IDToInstance::iterator found = instance_map_.find(filesystem_id); | 308 IDToInstance::iterator found = instance_map_.find(filesystem_id); |
| 223 if (found == instance_map_.end()) | 309 if (found == instance_map_.end()) |
| 224 return; | 310 return; |
| 225 Instance* instance = found->second; | 311 Instance* instance = found->second; |
| 226 DCHECK(instance->ref_counts() > 0); | 312 DCHECK(instance->ref_counts() > 0); |
| 227 instance->RemoveRef(); | 313 instance->RemoveRef(); |
| 228 if (instance->ref_counts() == 0) { | 314 if (instance->ref_counts() == 0 && |
| 315 instance->mount_type() != kFileSystemMountTypeExternal) { |
| 229 bool deleted = UnregisterFileSystem(filesystem_id); | 316 bool deleted = UnregisterFileSystem(filesystem_id); |
| 230 DCHECK(deleted); | 317 DCHECK(deleted); |
| 231 } | 318 } |
| 232 } | 319 } |
| 233 | 320 |
| 234 bool IsolatedContext::CrackIsolatedPath(const FilePath& virtual_path, | 321 bool IsolatedContext::CrackIsolatedPath(const FilePath& virtual_path, |
| 235 std::string* filesystem_id, | 322 std::string* id_or_name, |
| 236 FileSystemType* type, | 323 FileSystemType* type, |
| 237 FilePath* path) const { | 324 FilePath* path) const { |
| 238 DCHECK(filesystem_id); | 325 DCHECK(id_or_name); |
| 239 DCHECK(path); | 326 DCHECK(path); |
| 240 | 327 |
| 241 // This should not contain any '..' references. | 328 // This should not contain any '..' references. |
| 242 if (virtual_path.ReferencesParent()) | 329 if (virtual_path.ReferencesParent()) |
| 243 return false; | 330 return false; |
| 244 | 331 |
| 245 // The virtual_path should comprise <filesystem_id> and <relative_path> parts. | 332 // The virtual_path should comprise <id_or_name> and <relative_path> parts. |
| 246 std::vector<FilePath::StringType> components; | 333 std::vector<FilePath::StringType> components; |
| 247 virtual_path.GetComponents(&components); | 334 virtual_path.GetComponents(&components); |
| 248 if (components.size() < 1) | 335 if (components.size() < 1) |
| 249 return false; | 336 return false; |
| 250 | 337 std::vector<FilePath::StringType>::iterator component_iter = |
| 251 base::AutoLock locker(lock_); | 338 components.begin(); |
| 252 std::string fsid = FilePath(components[0]).MaybeAsASCII(); | 339 std::string fsid = FilePath(*component_iter++).MaybeAsASCII(); |
| 253 if (fsid.empty()) | 340 if (fsid.empty()) |
| 254 return false; | 341 return false; |
| 255 IDToInstance::const_iterator found_instance = instance_map_.find(fsid); | 342 |
| 256 if (found_instance == instance_map_.end()) | 343 FilePath cracked_path; |
| 257 return false; | 344 { |
| 258 *filesystem_id = fsid; | 345 base::AutoLock locker(lock_); |
| 259 if (type) | 346 IDToInstance::const_iterator found_instance = instance_map_.find(fsid); |
| 260 *type = found_instance->second->type(); | 347 if (found_instance == instance_map_.end()) |
| 261 if (components.size() == 1) { | 348 return false; |
| 262 path->clear(); | 349 *id_or_name = fsid; |
| 263 return true; | 350 const Instance* instance = found_instance->second; |
| 351 if (type) |
| 352 *type = instance->type(); |
| 353 switch (instance->mount_type()) { |
| 354 case kFileSystemMountTypeIsolated: { |
| 355 if (component_iter == components.end()) { |
| 356 // The virtual root case. |
| 357 path->clear(); |
| 358 return true; |
| 359 } |
| 360 // *component_iter should be a name of the registered path. |
| 361 std::string name = FilePath(*component_iter++).AsUTF8Unsafe(); |
| 362 if (!instance->ResolvePathForName(name, &cracked_path)) |
| 363 return false; |
| 364 break; |
| 365 } |
| 366 case kFileSystemMountTypeExternal: |
| 367 cracked_path = instance->file_info().path; |
| 368 break; |
| 369 case kFileSystemMountTypeUnknown: |
| 370 NOTREACHED(); |
| 371 break; |
| 372 } |
| 264 } | 373 } |
| 265 // components[1] should be a name of the registered paths. | |
| 266 FilePath cracked_path; | |
| 267 std::string name = FilePath(components[1]).AsUTF8Unsafe(); | |
| 268 if (!found_instance->second->ResolvePathForName(name, &cracked_path)) | |
| 269 return false; | |
| 270 | 374 |
| 271 for (size_t i = 2; i < components.size(); ++i) | 375 for (; component_iter != components.end(); ++component_iter) |
| 272 cracked_path = cracked_path.Append(components[i]); | 376 cracked_path = cracked_path.Append(*component_iter); |
| 273 *path = cracked_path; | 377 *path = cracked_path; |
| 274 return true; | 378 return true; |
| 275 } | 379 } |
| 276 | 380 |
| 277 bool IsolatedContext::GetDraggedFileInfo( | 381 bool IsolatedContext::GetDraggedFileInfo( |
| 278 const std::string& filesystem_id, std::vector<FileInfo>* files) const { | 382 const std::string& filesystem_id, std::vector<FileInfo>* files) const { |
| 279 DCHECK(files); | 383 DCHECK(files); |
| 280 base::AutoLock locker(lock_); | 384 base::AutoLock locker(lock_); |
| 281 IDToInstance::const_iterator found = instance_map_.find(filesystem_id); | 385 IDToInstance::const_iterator found = instance_map_.find(filesystem_id); |
| 282 if (found == instance_map_.end() || | 386 if (found == instance_map_.end() || |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 uint32 random_data[4]; | 440 uint32 random_data[4]; |
| 337 std::string id; | 441 std::string id; |
| 338 do { | 442 do { |
| 339 base::RandBytes(random_data, sizeof(random_data)); | 443 base::RandBytes(random_data, sizeof(random_data)); |
| 340 id = base::HexEncode(random_data, sizeof(random_data)); | 444 id = base::HexEncode(random_data, sizeof(random_data)); |
| 341 } while (instance_map_.find(id) != instance_map_.end()); | 445 } while (instance_map_.find(id) != instance_map_.end()); |
| 342 return id; | 446 return id; |
| 343 } | 447 } |
| 344 | 448 |
| 345 } // namespace fileapi | 449 } // namespace fileapi |
| OLD | NEW |