Chromium Code Reviews| Index: chrome/browser/extensions/api/cast_channel/cast_channel_api.cc |
| diff --git a/chrome/browser/extensions/api/cast_channel/cast_channel_api.cc b/chrome/browser/extensions/api/cast_channel/cast_channel_api.cc |
| index d1a84e4a31261a8f61178ce6c93e854619311df5..088e7d16c6f165976cabe27d94baa314b1b585b9 100644 |
| --- a/chrome/browser/extensions/api/cast_channel/cast_channel_api.cc |
| +++ b/chrome/browser/extensions/api/cast_channel/cast_channel_api.cc |
| @@ -5,6 +5,7 @@ |
| #include "chrome/browser/extensions/api/cast_channel/cast_channel_api.h" |
| #include <limits> |
| +#include <string> |
| #include "base/json/json_writer.h" |
| #include "base/memory/scoped_ptr.h" |
| @@ -60,6 +61,21 @@ void FillChannelInfo(const CastSocket& socket, ChannelInfo* channel_info) { |
| channel_info->error_state = socket.error_state(); |
| } |
| +bool IsValidConnectInfoPort(const ConnectInfo& connect_info) { |
| + return connect_info.port > 0 && connect_info.port < |
| + std::numeric_limits<unsigned short>::max(); |
| +} |
| + |
| +bool IsValidConnectInfoAuth(const ConnectInfo& connect_info) { |
| + return connect_info.auth == cast_channel::CHANNEL_AUTH_TYPE_SSL_VERIFIED || |
| + connect_info.auth == cast_channel::CHANNEL_AUTH_TYPE_SSL; |
| +} |
| + |
| +bool IsValidConnectInfoIpAddress(const ConnectInfo& connect_info) { |
| + net::IPAddressNumber ip_address; |
| + return net::ParseIPLiteralToNumber(connect_info.ip_address, &ip_address); |
| +} |
| + |
| } // namespace |
| CastChannelAPI::CastChannelAPI(content::BrowserContext* context) |
| @@ -244,22 +260,12 @@ bool CastChannelOpenFunction::ParseChannelUrl(const GURL& url, |
| cast_channel::CHANNEL_AUTH_TYPE_SSL_VERIFIED : |
| cast_channel::CHANNEL_AUTH_TYPE_SSL; |
| return true; |
| -}; |
| +} |
| net::IPEndPoint* CastChannelOpenFunction::ParseConnectInfo( |
| const ConnectInfo& connect_info) { |
| net::IPAddressNumber ip_address; |
| - if (!net::ParseIPLiteralToNumber(connect_info.ip_address, &ip_address)) { |
| - return NULL; |
| - } |
| - if (connect_info.port < 0 || connect_info.port > |
| - std::numeric_limits<unsigned short>::max()) { |
| - return NULL; |
| - } |
| - if (connect_info.auth != cast_channel::CHANNEL_AUTH_TYPE_SSL_VERIFIED && |
| - connect_info.auth != cast_channel::CHANNEL_AUTH_TYPE_SSL) { |
| - return NULL; |
| - } |
| + CHECK(net::ParseIPLiteralToNumber(connect_info.ip_address, &ip_address)); |
| return new net::IPEndPoint(ip_address, connect_info.port); |
| } |
| @@ -274,8 +280,11 @@ bool CastChannelOpenFunction::Prepare() { |
| // The connect_info parameter may be a string URL like cast:// or casts:// or |
| // a ConnectInfo object. |
| std::string cast_url; |
| + bool is_connect_info_url = false; |
| + bool is_connect_info_dict = false; |
| switch (params_->connect_info->GetType()) { |
| case base::Value::TYPE_STRING: |
| + is_connect_info_url = true; |
| CHECK(params_->connect_info->GetAsString(&cast_url)); |
| connect_info_.reset(new ConnectInfo); |
| if (!ParseChannelUrl(GURL(cast_url), connect_info_.get())) { |
| @@ -283,17 +292,38 @@ bool CastChannelOpenFunction::Prepare() { |
| } |
| break; |
| case base::Value::TYPE_DICTIONARY: |
| + is_connect_info_dict = true; |
| connect_info_ = ConnectInfo::FromValue(*(params_->connect_info)); |
| break; |
| default: |
| break; |
| } |
| - if (connect_info_.get()) { |
| - channel_auth_ = connect_info_->auth; |
| - ip_endpoint_.reset(ParseConnectInfo(*connect_info_)); |
| - return ip_endpoint_.get() != NULL; |
| + |
| + DCHECK(!is_connect_info_dict || !is_connect_info_url); |
| + if (!connect_info_.get()) { |
| + if (!is_connect_info_dict && !is_connect_info_url) { |
| + SetError("Invalid connect_info (unknown type)"); |
|
Wez
2014/07/17 21:16:47
This can just go in the default: case, surely?
mark a. foltz
2014/07/17 22:23:40
Done.
|
| + } else if (is_connect_info_dict) { |
| + SetError("connect_info.auth is required"); |
|
Wez
2014/07/17 21:16:47
I was actually thinking we could just get rid of t
mark a. foltz
2014/07/17 22:23:40
FromValue() is generated code that can't be change
|
| + } else { |
| + SetError("Invalid connect_info (invalid Cast URL " + cast_url + ")"); |
|
Wez
2014/07/17 21:16:47
This could go in the TYPE_STRING failure block, if
mark a. foltz
2014/07/17 22:23:40
Done.
|
| + } |
| + return false; |
| + } |
| + |
| + if (!IsValidConnectInfoPort(*connect_info_)) { |
| + SetError("Invalid connect_info (invalid port)"); |
| + } else if (!IsValidConnectInfoAuth(*connect_info_)) { |
| + SetError("Invalid connect_info (invalid auth)"); |
| + } else if (!IsValidConnectInfoIpAddress(*connect_info_)) { |
| + SetError("Invalid connect_info (invalid IP address)"); |
| + } |
| + if (!GetError().empty()) { |
| + return false; |
| } |
| - return false; |
| + channel_auth_ = connect_info_->auth; |
| + ip_endpoint_.reset(ParseConnectInfo(*connect_info_)); |
| + return true; |
| } |
| void CastChannelOpenFunction::AsyncWorkStart() { |
| @@ -319,6 +349,26 @@ CastChannelSendFunction::~CastChannelSendFunction() { } |
| bool CastChannelSendFunction::Prepare() { |
| params_ = Send::Params::Create(*args_); |
| EXTENSION_FUNCTION_VALIDATE(params_.get()); |
| + if (params_->message.namespace_.empty()) { |
| + SetError("message_info.namespace_ is required"); |
| + return false; |
| + } |
| + if (params_->message.source_id.empty()) { |
| + SetError("message_info.source_id is required"); |
| + return false; |
| + } |
| + if (params_->message.destination_id.empty()) { |
| + SetError("message_info.destination_id is required"); |
| + return false; |
| + } |
| + switch (params_->message.data->GetType()) { |
| + case base::Value::TYPE_STRING: |
| + case base::Value::TYPE_BINARY: |
| + break; |
| + default: |
| + SetError("Invalid type of message_info.data"); |
| + return false; |
| + } |
| return true; |
| } |