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,
Result CastMessageHandler::SendAppMessage(int channel_id,
const CastMessage& message) {
DCHECK(!IsCastInternalNamespace(message.namespace_()))
DCHECK(!IsCastReservedNamespace(message.namespace_()))
<< ": unexpected app message namespace: " << message.namespace_();
if (message.ByteSizeLong() > kMaxCastMessagePayload) {
return Result::kFailed;
......@@ -354,7 +354,7 @@ void CastMessageHandler::OnMessage(const CastSocket& socket,
// separate data type is pretty questionable, because it causes duplicated
// code paths in the downstream logic (manifested as separate OnAppMessage and
// OnInternalMessage methods).
if (IsCastInternalNamespace(message.namespace_())) {
if (IsCastReservedNamespace(message.namespace_())) {
if (message.payload_type() ==
cast::channel::CastMessage_PayloadType_STRING) {
VLOG(1) << __func__ << ": channel_id: " << socket.id()
......
......@@ -8,6 +8,7 @@
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "build/build_config.h"
......@@ -18,6 +19,7 @@
using base::Value;
using cast_util::EnumToString;
using cast_util::StringToEnum;
namespace cast_util {
using ::cast::channel::AuthChallenge;
......@@ -99,6 +101,24 @@ namespace cast_channel {
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
// value is used in the Media Router extension, but here it is reused in Chrome.
constexpr int kVirtualConnectSdkType = 2;
......@@ -209,11 +229,31 @@ bool IsCastMessageValid(const CastMessage& message_proto) {
message_proto.has_payload_binary());
}
bool IsCastInternalNamespace(const std::string& message_namespace) {
// Note: any namespace with the prefix is assumed to be reserved for internal
// messages.
return base::StartsWith(message_namespace, kCastInternalNamespacePrefix,
base::CompareCase::SENSITIVE);
bool IsCastReservedNamespace(base::StringPiece message_namespace) {
// Note: Any namespace with the prefix is theoretically reserved for internal
// messages, but there is at least one namespace in widespread use that uses
// the "reserved" prefix for app-level messages, so after matching the main
// 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) {
......
......@@ -17,8 +17,6 @@ using ::cast::channel::CastMessage;
using ::cast::channel::DeviceAuthMessage;
// Reserved message namespaces for internal messages.
static constexpr char kCastInternalNamespacePrefix[] =
"urn:x-cast:com.google.cast.";
static constexpr char kAuthNamespace[] =
"urn:x-cast:com.google.cast.tp.deviceauth";
static constexpr char kHeartbeatNamespace[] =
......@@ -164,7 +162,7 @@ bool IsCastMessageValid(const CastMessage& message_proto);
// Returns true if |message_namespace| is a namespace reserved for internal
// 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.
// The result is only valid if |payload| is a Cast application protocol message.
......
......@@ -106,7 +106,7 @@ DEFINE_PROTO_FUZZER(const CastMessageUtilInputs& input_union) {
break;
}
case CastMessageUtilInputs::kStringInput: {
IsCastInternalNamespace(input_union.string_input());
IsCastReservedNamespace(input_union.string_input());
break;
}
case CastMessageUtilInputs::kCastMessage: {
......
......@@ -15,12 +15,21 @@ using base::test::ParseJson;
namespace cast_channel {
TEST(CastMessageUtilTest, IsCastInternalNamespace) {
EXPECT_TRUE(IsCastInternalNamespace("urn:x-cast:com.google.cast.receiver"));
EXPECT_FALSE(IsCastInternalNamespace("urn:x-cast:com.google.youtube"));
EXPECT_FALSE(IsCastInternalNamespace("urn:x-cast:com.foo"));
EXPECT_FALSE(IsCastInternalNamespace("foo"));
EXPECT_FALSE(IsCastInternalNamespace(""));
TEST(CastMessageUtilTest, IsCastReservedNamespace) {
EXPECT_TRUE(
IsCastReservedNamespace("urn:x-cast:com.google.cast.receiver.xyzzy"));
EXPECT_TRUE(IsCastReservedNamespace("urn:x-cast:com.google.cast.receiver"));
EXPECT_FALSE(IsCastReservedNamespace("urn:x-cast:com.google.cast"));
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) {
......
......@@ -139,7 +139,7 @@ message CastMessageUtilInputs {
message GetLaunchSessionResponseInput { required JunkValue payload = 1; }
message IsCastInternalNamespaceInput {
message IsCastReservedNamespaceInput {
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