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; |
} |