Index: services/catalog/catalog.cc |
diff --git a/services/catalog/catalog.cc b/services/catalog/catalog.cc |
index 35f5d706a67029e8e4f1d52c8ba0f22dfb5ff18e..50723deff4c21cd0564df14df703680e29e9feb5 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,51 @@ |
#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; |
+ PathService::Get(base::DIR_EXE, &base_path); |
+ // TODO(beng): this won't handle user-specific components. |
+ return base_path.AppendASCII(kMojoApplicationsDirName).AppendASCII(path). |
+ AppendASCII("resources"); |
+} |
+ |
+} // namespace |
Catalog::Catalog(base::SequencedWorkerPool* worker_pool, |
std::unique_ptr<Store> store, |
@@ -53,6 +106,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 +125,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, |
+ scoped_refptr<filesystem::SharedTempDir>(), |
+ lock_table_); |
+} |
+ |
Instance* Catalog::GetInstanceForUserId(const std::string& user_id) { |
auto it = instances_.find(user_id); |
if (it != instances_.end()) |