Chromium Code Reviews| Index: services/catalog/catalog.cc |
| diff --git a/services/catalog/catalog.cc b/services/catalog/catalog.cc |
| index 35f5d706a67029e8e4f1d52c8ba0f22dfb5ff18e..7131adce520f3dfb286b4b49c13e295033ee26f0 100644 |
| --- a/services/catalog/catalog.cc |
| +++ b/services/catalog/catalog.cc |
| @@ -5,7 +5,15 @@ |
| #include "services/catalog/catalog.h" |
| #include "base/bind.h" |
| +#include "base/files/file_path.h" |
| +#include "base/files/scoped_temp_dir.h" |
| #include "base/memory/ptr_util.h" |
| +#include "base/path_service.h" |
| +#include "base/strings/string_split.h" |
| +#include "base/strings/string_util.h" |
| +#include "components/filesystem/directory_impl.h" |
| +#include "components/filesystem/lock_table.h" |
| +#include "components/filesystem/public/interfaces/types.mojom.h" |
| #include "services/catalog/constants.h" |
| #include "services/catalog/instance.h" |
| #include "services/catalog/reader.h" |
| @@ -13,6 +21,59 @@ |
| #include "services/shell/public/cpp/shell_connection.h" |
| namespace catalog { |
| +namespace { |
| + |
| +bool IsPathNameValid(const std::string& name) { |
| + if (name.empty() || name == "." || name == "..") |
| + return false; |
| + |
| + for (auto c : name) { |
| + if (!base::IsAsciiAlpha(c) && !base::IsAsciiDigit(c) && |
| + c != '_' && c != '.') |
| + return false; |
| + } |
| + return true; |
| +} |
| + |
| +base::FilePath GetPathForApplicationName(const std::string& application_name) { |
| + std::string path = application_name; |
| + const bool is_mojo = |
| + base::StartsWith(path, "mojo:", base::CompareCase::INSENSITIVE_ASCII); |
| + const bool is_exe = |
| + !is_mojo && |
| + base::StartsWith(path, "exe:", base::CompareCase::INSENSITIVE_ASCII); |
| + if (!is_mojo && !is_exe) |
| + return base::FilePath(); |
| + if (path.find('.') != std::string::npos) |
| + return base::FilePath(); |
| + if (is_mojo) |
| + path.erase(path.begin(), path.begin() + 5); |
| + else |
| + path.erase(path.begin(), path.begin() + 4); |
| + base::TrimString(path, "/", &path); |
| + size_t end_of_name = path.find('/'); |
| + if (end_of_name != std::string::npos) |
| + path.erase(path.begin() + end_of_name, path.end()); |
| + |
| + if (!IsPathNameValid(path)) |
| + return base::FilePath(); |
| + |
| + base::FilePath base_path; |
| +#if defined(OS_ANDROID) |
| + PathService::Get(base::DIR_ANDROID_APP_DATA, &base_path); |
| + // |base_path| on android has an additional path, need to go up a level to get |
| + // at other apps resources. |
| + base_path = base_path.DirName(); |
| + base_path = base_path.AppendASCII("app_cached_apps"); |
| +#else |
| + PathService::Get(base::DIR_EXE, &base_path); |
| +#endif |
| + // TODO(beng): this won't handle user-specific components. |
| + return base_path.AppendASCII("Mojo Applications").AppendASCII(path). |
| + AppendASCII("resources"); |
| +} |
| + |
| +} // namespace |
| Catalog::Catalog(base::SequencedWorkerPool* worker_pool, |
| std::unique_ptr<Store> store, |
| @@ -53,6 +114,7 @@ void Catalog::ScanSystemPackageDir() { |
| bool Catalog::AcceptConnection(shell::Connection* connection) { |
| connection->AddInterface<mojom::Catalog>(this); |
| + connection->AddInterface<filesystem::Directory>(this); |
| connection->AddInterface<shell::mojom::ShellResolver>(this); |
| return true; |
| } |
| @@ -71,6 +133,17 @@ void Catalog::Create(shell::Connection* connection, |
| instance->BindCatalog(std::move(request)); |
| } |
| +void Catalog::Create(shell::Connection* connection, |
| + filesystem::DirectoryRequest request) { |
| + if (!lock_table_) |
| + lock_table_ = new filesystem::LockTable; |
| + base::FilePath resources_path = |
| + GetPathForApplicationName(connection->GetRemoteIdentity().name()); |
| + new filesystem::DirectoryImpl(std::move(request), resources_path, |
| + std::unique_ptr<base::ScopedTempDir>(), |
|
yzshen1
2016/05/02 21:22:56
After the fix, this line still failed because argu
|
| + lock_table_); |
| +} |
| + |
| Instance* Catalog::GetInstanceForUserId(const std::string& user_id) { |
| auto it = instances_.find(user_id); |
| if (it != instances_.end()) |