diff --git a/src/google/protobuf/json/internal/parser.cc b/src/google/protobuf/json/internal/parser.cc index 7b2289a433..90d8c3f55c 100644 --- a/src/google/protobuf/json/internal/parser.cc +++ b/src/google/protobuf/json/internal/parser.cc @@ -1181,6 +1181,19 @@ absl::Status ParseField(JsonLexer& lex, const Desc& desc, if (absl::StartsWith(name, "[") && absl::EndsWith(name, "]")) { absl::string_view extn_name = name.substr(1, name.size() - 2); field = Traits::ExtensionByName(desc, extn_name); + + if (field.has_value()) { + // The check for whether this is an invalid field occurs below, since it + // is combined for both extension and non-extension fields. + auto correct_type_name = Traits::TypeName(desc); + if (Traits::TypeName(Traits::ContainingType(*field)) != + correct_type_name) { + return lex.Invalid(absl::StrFormat( + "'%s' is a known extension name, but is not an extenion " + "of '%s' as expected", + extn_name, correct_type_name)); + } + } } else { field = Traits::FieldByName(desc, name); } diff --git a/src/google/protobuf/json/json_test.cc b/src/google/protobuf/json/json_test.cc index 1aefdbec34..faffcf6074 100644 --- a/src/google/protobuf/json/json_test.cc +++ b/src/google/protobuf/json/json_test.cc @@ -1053,6 +1053,16 @@ TEST_P(JsonTest, Extensions) { R"("[protobuf_unittest.TestMixedFieldsAndExtensions.c]":42,)" R"("b":[1,2,3],)" R"("[protobuf_unittest.TestMixedFieldsAndExtensions.d]":[1,1,2,3,5,8,13]})")); + + auto m2 = ToProto(R"json({ + "[this.extension.does.not.exist]": 42 + })json"); + EXPECT_THAT(m2, StatusIs(absl::StatusCode::kInvalidArgument)); + + auto m3 = ToProto(R"json({ + "[protobuf_unittest.TestMixedFieldsAndExtensions.c]": 42 + })json"); + EXPECT_THAT(m3, StatusIs(absl::StatusCode::kInvalidArgument)); } // Parsing does NOT work like MergeFrom: existing repeated field values are