| Index: chrome/browser/extensions/api/messaging/native_messaging_host_manifest.cc
|
| diff --git a/chrome/browser/extensions/api/messaging/native_messaging_host_manifest.cc b/chrome/browser/extensions/api/messaging/native_messaging_host_manifest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..a93b8637e088e1f10f0a1eb53491ed06abb35a46
|
| --- /dev/null
|
| +++ b/chrome/browser/extensions/api/messaging/native_messaging_host_manifest.cc
|
| @@ -0,0 +1,138 @@
|
| +// Copyright (c) 2013 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "chrome/browser/extensions/api/messaging/native_messaging_host_manifest.h"
|
| +
|
| +#include "base/json/json_file_value_serializer.h"
|
| +#include "base/logging.h"
|
| +#include "base/values.h"
|
| +
|
| +namespace extensions {
|
| +
|
| +NativeMessagingHostManifest::~NativeMessagingHostManifest() {}
|
| +
|
| +// static
|
| +bool NativeMessagingHostManifest::IsValidName(const std::string& name) {
|
| + if (name.empty()) {
|
| + return false;
|
| + }
|
| +
|
| + for (size_t i = 0; i < name.size(); ++i) {
|
| + char c = name[i];
|
| +
|
| + // Verify that only the following characters are used: [a-z0-9._].
|
| + if (!((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') ||
|
| + c == '.' || c == '_')) {
|
| + return false;
|
| + }
|
| +
|
| + // Verify that dots are separated by other characters and that string
|
| + // doesn't begin or end with a dot.
|
| + if (c == '.' && (i == 0 || name[i - 1] == '.' || i == name.size() - 1)) {
|
| + return false;
|
| + }
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| +// static
|
| +scoped_ptr<NativeMessagingHostManifest> NativeMessagingHostManifest::Load(
|
| + const base::FilePath& file_path,
|
| + std::string* error_message) {
|
| + DCHECK(error_message);
|
| +
|
| + JSONFileValueSerializer serializer(file_path);
|
| + scoped_ptr<base::Value> parsed(serializer.Deserialize(NULL, error_message));
|
| + if (!parsed) {
|
| + return scoped_ptr<NativeMessagingHostManifest>();
|
| + }
|
| +
|
| + base::DictionaryValue* dictionary;
|
| + if (!parsed->GetAsDictionary(&dictionary)) {
|
| + *error_message = "Invalid manifest file.";
|
| + return scoped_ptr<NativeMessagingHostManifest>();
|
| + }
|
| +
|
| + scoped_ptr<NativeMessagingHostManifest> result(
|
| + new NativeMessagingHostManifest());
|
| + if (!result->Parse(dictionary, error_message)) {
|
| + return scoped_ptr<NativeMessagingHostManifest>();
|
| + }
|
| +
|
| + return result.Pass();
|
| +}
|
| +
|
| +NativeMessagingHostManifest::NativeMessagingHostManifest() {
|
| +}
|
| +
|
| +bool NativeMessagingHostManifest::Parse(base::DictionaryValue* dictionary,
|
| + std::string* error_message) {
|
| + if (!dictionary->GetString("name", &name_) ||
|
| + !IsValidName(name_)) {
|
| + *error_message = "Invalid value for name.";
|
| + return false;
|
| + }
|
| +
|
| + if (!dictionary->GetString("description", &description_) ||
|
| + description_.empty()) {
|
| + *error_message = "Invalid value for description.";
|
| + return false;
|
| + }
|
| +
|
| + std::string type;
|
| + // stdio is the only host type that's currently supported.
|
| + if (!dictionary->GetString("type", &type) ||
|
| + type != "stdio") {
|
| + *error_message = "Invalid value for type.";
|
| + return false;
|
| + }
|
| + interface_ = HOST_INTERFACE_STDIO;
|
| +
|
| + std::string path;
|
| + // JSON parsed checks that all strings are valid UTF8.
|
| + if (!dictionary->GetString("path", &path) ||
|
| + (path_ = base::FilePath::FromUTF8Unsafe(path)).empty() ||
|
| + !path_.IsAbsolute()) {
|
| + *error_message = "Invalid value for path.";
|
| + return false;
|
| + }
|
| +
|
| + const base::ListValue* allowed_origins_list;
|
| + if (!dictionary->GetList("allowed_origins", &allowed_origins_list)) {
|
| + *error_message =
|
| + "Invalid value for allowed_origins. Expected a list of strings.";
|
| + return false;
|
| + }
|
| + allowed_origins_.ClearPatterns();
|
| + for (base::ListValue::const_iterator it = allowed_origins_list->begin();
|
| + it != allowed_origins_list->end(); ++it) {
|
| + std::string pattern_string;
|
| + if (!(*it)->GetAsString(&pattern_string)) {
|
| + *error_message = "allowed_origins must be list of strings.";
|
| + return false;
|
| + }
|
| +
|
| + URLPattern pattern(URLPattern::SCHEME_EXTENSION);
|
| + URLPattern::ParseResult result = pattern.Parse(pattern_string);
|
| + if (result != URLPattern::PARSE_SUCCESS) {
|
| + *error_message = "Failed to parse pattern \"" + pattern_string +
|
| + "\": " + URLPattern::GetParseResultString(result);
|
| + return false;
|
| + }
|
| +
|
| + // Disallow patterns that are too broad. Set of allowed origins must be a
|
| + // fixed list of extensions.
|
| + if (pattern.match_all_urls() || pattern.match_subdomains()) {
|
| + *error_message = "Pattern \"" + pattern_string + "\" is not allowed.";
|
| + return false;
|
| + }
|
| +
|
| + allowed_origins_.AddPattern(pattern);
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| +} // namespace extensions
|
|
|