Chromium Code Reviews| Index: chrome/common/extensions/permissions/socket_permission_data.cc |
| diff --git a/chrome/common/extensions/permissions/socket_permission_data.cc b/chrome/common/extensions/permissions/socket_permission_data.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..e23b0ee6ab071616b441bf8fb5a7e76f3b72d695 |
| --- /dev/null |
| +++ b/chrome/common/extensions/permissions/socket_permission_data.cc |
| @@ -0,0 +1,189 @@ |
| +// Copyright (c) 2012 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/common/extensions/permissions/socket_permission_data.h" |
| + |
| +#include <cstdlib> |
| +#include <sstream> |
| +#include <vector> |
| + |
| +#include "base/logging.h" |
| +#include "base/string_number_conversions.h" |
| +#include "base/string_split.h" |
| +#include "base/string_util.h" |
| + |
| +namespace { |
| + |
| +using extensions::SocketPermissionData; |
| + |
| +const char kInvalid[] = "invalid"; |
| +const char kTCPConnect[] = "tcp-connect"; |
| +const char kTCPListen[] = "tcp-listen"; |
| +const char kUDPBind[] = "udp-bind"; |
| +const char kUDPSendTo[] = "udp-send-to"; |
| + |
| +SocketPermissionData::OperationType StringToType(const std::string& s) { |
| + if (s == kTCPConnect) |
| + return SocketPermissionData::TCP_CONNECT; |
| + if (s == kTCPListen) |
| + return SocketPermissionData::TCP_LISTEN; |
| + if (s == kUDPBind) |
| + return SocketPermissionData::UDP_BIND; |
| + if (s == kUDPSendTo) |
| + return SocketPermissionData::UDP_SEND_TO; |
| + return SocketPermissionData::NONE; |
| +} |
| + |
| +const char* TypeToString(SocketPermissionData::OperationType type) { |
| + switch (type) { |
| + case SocketPermissionData::TCP_CONNECT: |
| + return kTCPConnect; |
| + case SocketPermissionData::TCP_LISTEN: |
| + return kTCPListen; |
| + case SocketPermissionData::UDP_BIND: |
| + return kUDPBind; |
| + case SocketPermissionData::UDP_SEND_TO: |
| + return kUDPSendTo; |
| + default: |
| + return kInvalid; |
| + } |
| +} |
| + |
| +} |
| + |
| +namespace extensions { |
| + |
| +SocketPermissionData::SocketPermissionData() |
| + : type_(NONE), |
| + match_subdomains_(true), |
| + port_(0) { |
| +} |
| + |
| +SocketPermissionData::~SocketPermissionData() { |
| +} |
| + |
| +bool SocketPermissionData::operator<(const SocketPermissionData& rhs) const { |
| + if (type_ < rhs.type_) |
| + return true; |
| + if (type_ > rhs.type_) |
| + return false; |
| + |
| + if (host_ < rhs.host_) |
| + return true; |
| + if (host_ > rhs.host_) |
| + return false; |
| + |
| + if (match_subdomains_ < rhs.match_subdomains_) |
| + return true; |
| + if (match_subdomains_ > rhs.match_subdomains_) |
| + return false; |
| + |
| + if (port_ < rhs.port_) |
| + return true; |
| + return false; |
| +} |
| + |
| +bool SocketPermissionData::operator==(const SocketPermissionData& rhs) const { |
| + return (type_ == rhs.type_) && (host_ == rhs.host_) && |
| + (match_subdomains_ == rhs.match_subdomains_) && |
| + (port_ == rhs.port_); |
| +} |
| + |
| +bool SocketPermissionData::Match( |
| + OperationType type, const std::string& host, int port) const { |
| + if (type_ != type) |
| + return false; |
| + |
| + std::string lhost = StringToLowerASCII(host); |
| + if (host_ != lhost) { |
| + if (!match_subdomains_) |
| + return false; |
| + |
| + // host should equal to one or more chars + "." + host_. |
|
miket_OOO
2012/08/07 23:02:47
either "be equal to" or just "equal."
Peng
2012/08/08 15:40:07
Done.
|
| + if (lhost.length() < host_.length() + 2) |
| + return false; |
| + |
| + if (lhost.compare(lhost.length() - host_.length(), |
| + host_.length(), host_) != 0) |
| + return false; |
| + } |
| + |
| + if (port_ != port && port_ != 0) |
| + return false; |
| + |
| + return true; |
| +} |
| + |
| +bool SocketPermissionData::Parse(const std::string& permission) { |
| + // Reset |
| + *this = SocketPermissionData(); |
| + |
| + std::vector<std::string> tokens; |
| + base::SplitString(permission, ':', &tokens); |
| + |
| + if (tokens.empty() || tokens.size() > 3) |
| + return false; |
| + |
| + type_ = StringToType(tokens[0]); |
| + if (type_ == NONE) |
| + return false; |
| + |
| + if (tokens.size() == 1) |
| + return true; |
| + |
| + // The first component can optionally be '*' to match all subdomains. |
| + host_ = StringToLowerASCII(tokens[1]); |
| + if (!host_.empty()) { |
| + std::vector<std::string> host_components; |
| + base::SplitString(host_, '.', &host_components); |
| + DCHECK(!host_components.empty()); |
| + |
| + if (host_components[0] == "*" || host_components[0].empty()) { |
| + host_components.erase(host_components.begin(), |
| + host_components.begin() + 1); |
| + } else { |
| + match_subdomains_ = false; |
| + } |
| + host_ = JoinString(host_components, '.'); |
| + } |
| + |
| + if (tokens.size() == 2) |
| + return true; |
| + |
| + if (tokens.empty() || tokens[2] == "*") |
| + return true; |
| + |
| + if (!tokens[2].empty()) { |
| + if (!base::StringToInt(tokens[2], &port_) || |
| + port_ < 0 || port_ > 65535) |
|
miket_OOO
2012/08/07 23:02:47
Is port == 0 really a valid port? I'm concerned th
Peng
2012/08/08 15:40:07
Done.
|
| + return false; |
| + } |
| + |
| + return true; |
| +} |
| + |
| +const std::string& SocketPermissionData::GetAsString() const { |
| + if (!spec_.empty()) |
| + return spec_; |
| + |
| + spec_.reserve(64); |
| + spec_.append(TypeToString(type_)); |
| + |
| + if (match_subdomains_) { |
| + spec_.append(":*"); |
| + if (!host_.empty()) |
| + spec_.append(".").append(host_); |
| + } else { |
| + spec_.append(":").append(host_); |
| + } |
| + |
| + if (port_ == 0) |
| + spec_.append(":*"); |
| + else |
| + spec_.append(":").append(base::IntToString(port_)); |
| + |
| + return spec_; |
| +} |
| + |
| +} // namespace extensions |