Commit 43001197 authored by John Williams's avatar John Williams Committed by Commit Bot

[Cast MRP] Changed IsCastInternalNamespace to match legacy impl.

Bug: 1129217
Change-Id: I683aeee86f06a157255eae0c9db3948509ebcbf6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2438749
Commit-Queue: John Williams <jrw@chromium.org>
Reviewed-by: default avatarmark a. foltz <mfoltz@chromium.org>
Reviewed-by: default avatarTakumi Fujimoto <takumif@chromium.org>
Cr-Commit-Position: refs/heads/master@{#814806}
parent 22575234
...@@ -277,7 +277,7 @@ Result CastMessageHandler::SendCastMessage(int channel_id, ...@@ -277,7 +277,7 @@ Result CastMessageHandler::SendCastMessage(int channel_id,
Result CastMessageHandler::SendAppMessage(int channel_id, Result CastMessageHandler::SendAppMessage(int channel_id,
const CastMessage& message) { const CastMessage& message) {
DCHECK(!IsCastInternalNamespace(message.namespace_())) DCHECK(!IsCastReservedNamespace(message.namespace_()))
<< ": unexpected app message namespace: " << message.namespace_(); << ": unexpected app message namespace: " << message.namespace_();
if (message.ByteSizeLong() > kMaxCastMessagePayload) { if (message.ByteSizeLong() > kMaxCastMessagePayload) {
return Result::kFailed; return Result::kFailed;
...@@ -354,7 +354,7 @@ void CastMessageHandler::OnMessage(const CastSocket& socket, ...@@ -354,7 +354,7 @@ void CastMessageHandler::OnMessage(const CastSocket& socket,
// separate data type is pretty questionable, because it causes duplicated // separate data type is pretty questionable, because it causes duplicated
// code paths in the downstream logic (manifested as separate OnAppMessage and // code paths in the downstream logic (manifested as separate OnAppMessage and
// OnInternalMessage methods). // OnInternalMessage methods).
if (IsCastInternalNamespace(message.namespace_())) { if (IsCastReservedNamespace(message.namespace_())) {
if (message.payload_type() == if (message.payload_type() ==
cast::channel::CastMessage_PayloadType_STRING) { cast::channel::CastMessage_PayloadType_STRING) {
VLOG(1) << __func__ << ": channel_id: " << socket.id() VLOG(1) << __func__ << ": channel_id: " << socket.id()
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/json/json_writer.h" #include "base/json/json_writer.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "build/build_config.h" #include "build/build_config.h"
...@@ -18,6 +19,7 @@ ...@@ -18,6 +19,7 @@
using base::Value; using base::Value;
using cast_util::EnumToString; using cast_util::EnumToString;
using cast_util::StringToEnum; using cast_util::StringToEnum;
namespace cast_util { namespace cast_util {
using ::cast::channel::AuthChallenge; using ::cast::channel::AuthChallenge;
...@@ -99,6 +101,24 @@ namespace cast_channel { ...@@ -99,6 +101,24 @@ namespace cast_channel {
namespace { namespace {
constexpr base::StringPiece kCastReservedNamespacePrefix =
"urn:x-cast:com.google.cast.";
constexpr const char* kReservedNamespaces[] = {
kAuthNamespace,
kHeartbeatNamespace,
kConnectionNamespace,
kReceiverNamespace,
kBroadcastNamespace,
kMediaNamespace,
// mirroring::mojom::kRemotingNamespace
"urn:x-cast:com.google.cast.remoting",
// mirroring::mojom::kWebRtcNamespace
"urn:x-cast:com.google.cast.webrtc",
};
// The value used for "sdkType" in a virtual connect request. Historically, this // The value used for "sdkType" in a virtual connect request. Historically, this
// value is used in the Media Router extension, but here it is reused in Chrome. // value is used in the Media Router extension, but here it is reused in Chrome.
constexpr int kVirtualConnectSdkType = 2; constexpr int kVirtualConnectSdkType = 2;
...@@ -209,11 +229,31 @@ bool IsCastMessageValid(const CastMessage& message_proto) { ...@@ -209,11 +229,31 @@ bool IsCastMessageValid(const CastMessage& message_proto) {
message_proto.has_payload_binary()); message_proto.has_payload_binary());
} }
bool IsCastInternalNamespace(const std::string& message_namespace) { bool IsCastReservedNamespace(base::StringPiece message_namespace) {
// Note: any namespace with the prefix is assumed to be reserved for internal // Note: Any namespace with the prefix is theoretically reserved for internal
// messages. // messages, but there is at least one namespace in widespread use that uses
return base::StartsWith(message_namespace, kCastInternalNamespacePrefix, // the "reserved" prefix for app-level messages, so after matching the main
base::CompareCase::SENSITIVE); // prefix, we look for longer prefixes that really need to be reserved.
if (!base::StartsWith(message_namespace, kCastReservedNamespacePrefix))
return false;
const auto prefix_length = kCastReservedNamespacePrefix.length();
for (base::StringPiece reserved_namespace : kReservedNamespaces) {
DCHECK(base::StartsWith(reserved_namespace, kCastReservedNamespacePrefix));
// This comparison skips the first |prefix_length| characters
// because we already know they match.
if (base::StartsWith(message_namespace.substr(prefix_length),
reserved_namespace.substr(prefix_length)) &&
// This condition allows |reserved_namespace| to be equal
// |message_namespace| or be a prefix of it, but if it's a
// prefix, it must be followed by a dot. The subscript is
// never out of bounds because |message_namespace| must be
// at least as long as |reserved_namespace|.
(message_namespace.length() == reserved_namespace.length() ||
message_namespace[reserved_namespace.length()] == '.'))
return true;
}
return false;
} }
CastMessageType ParseMessageTypeFromPayload(const base::Value& payload) { CastMessageType ParseMessageTypeFromPayload(const base::Value& payload) {
......
...@@ -17,8 +17,6 @@ using ::cast::channel::CastMessage; ...@@ -17,8 +17,6 @@ using ::cast::channel::CastMessage;
using ::cast::channel::DeviceAuthMessage; using ::cast::channel::DeviceAuthMessage;
// Reserved message namespaces for internal messages. // Reserved message namespaces for internal messages.
static constexpr char kCastInternalNamespacePrefix[] =
"urn:x-cast:com.google.cast.";
static constexpr char kAuthNamespace[] = static constexpr char kAuthNamespace[] =
"urn:x-cast:com.google.cast.tp.deviceauth"; "urn:x-cast:com.google.cast.tp.deviceauth";
static constexpr char kHeartbeatNamespace[] = static constexpr char kHeartbeatNamespace[] =
...@@ -164,7 +162,7 @@ bool IsCastMessageValid(const CastMessage& message_proto); ...@@ -164,7 +162,7 @@ bool IsCastMessageValid(const CastMessage& message_proto);
// Returns true if |message_namespace| is a namespace reserved for internal // Returns true if |message_namespace| is a namespace reserved for internal
// messages. // messages.
bool IsCastInternalNamespace(const std::string& message_namespace); bool IsCastReservedNamespace(base::StringPiece message_namespace);
// Returns the value in the "type" field or |kOther| if the field is not found. // Returns the value in the "type" field or |kOther| if the field is not found.
// The result is only valid if |payload| is a Cast application protocol message. // The result is only valid if |payload| is a Cast application protocol message.
......
...@@ -106,7 +106,7 @@ DEFINE_PROTO_FUZZER(const CastMessageUtilInputs& input_union) { ...@@ -106,7 +106,7 @@ DEFINE_PROTO_FUZZER(const CastMessageUtilInputs& input_union) {
break; break;
} }
case CastMessageUtilInputs::kStringInput: { case CastMessageUtilInputs::kStringInput: {
IsCastInternalNamespace(input_union.string_input()); IsCastReservedNamespace(input_union.string_input());
break; break;
} }
case CastMessageUtilInputs::kCastMessage: { case CastMessageUtilInputs::kCastMessage: {
......
...@@ -15,12 +15,21 @@ using base::test::ParseJson; ...@@ -15,12 +15,21 @@ using base::test::ParseJson;
namespace cast_channel { namespace cast_channel {
TEST(CastMessageUtilTest, IsCastInternalNamespace) { TEST(CastMessageUtilTest, IsCastReservedNamespace) {
EXPECT_TRUE(IsCastInternalNamespace("urn:x-cast:com.google.cast.receiver")); EXPECT_TRUE(
EXPECT_FALSE(IsCastInternalNamespace("urn:x-cast:com.google.youtube")); IsCastReservedNamespace("urn:x-cast:com.google.cast.receiver.xyzzy"));
EXPECT_FALSE(IsCastInternalNamespace("urn:x-cast:com.foo")); EXPECT_TRUE(IsCastReservedNamespace("urn:x-cast:com.google.cast.receiver"));
EXPECT_FALSE(IsCastInternalNamespace("foo")); EXPECT_FALSE(IsCastReservedNamespace("urn:x-cast:com.google.cast"));
EXPECT_FALSE(IsCastInternalNamespace("")); EXPECT_FALSE(IsCastReservedNamespace("urn:x-cast:com.google.cast."));
EXPECT_FALSE(
IsCastReservedNamespace("urn:x-cast:com.google.cast.foo.receiver"));
EXPECT_FALSE(
IsCastReservedNamespace("urn:x-cast:com.google.cast.receiverfoo"));
EXPECT_FALSE(IsCastReservedNamespace("urn:x-cast:com.google.cast.xyzzy"));
EXPECT_FALSE(IsCastReservedNamespace("urn:x-cast:com.google.youtube"));
EXPECT_FALSE(IsCastReservedNamespace("urn:x-cast:com.foo"));
EXPECT_FALSE(IsCastReservedNamespace("foo"));
EXPECT_FALSE(IsCastReservedNamespace(""));
} }
TEST(CastMessageUtilTest, CastMessageType) { TEST(CastMessageUtilTest, CastMessageType) {
......
...@@ -139,7 +139,7 @@ message CastMessageUtilInputs { ...@@ -139,7 +139,7 @@ message CastMessageUtilInputs {
message GetLaunchSessionResponseInput { required JunkValue payload = 1; } message GetLaunchSessionResponseInput { required JunkValue payload = 1; }
message IsCastInternalNamespaceInput { message IsCastReservedNamespaceInput {
required string message_namespace = 1; required string message_namespace = 1;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment