Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1858)

Unified Diff: chrome/browser/extensions/api/cast_channel/cast_channel_api.cc

Issue 255443002: Implement argument validation for chrome.cast.channel.{open,send} (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix issues with prior patch. More test cases for Send. Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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;
}

Powered by Google App Engine
This is Rietveld 408576698