diff --git a/src/core/ext/xds/xds_api.cc b/src/core/ext/xds/xds_api.cc index 9845eff3e11..6da587ed9aa 100644 --- a/src/core/ext/xds/xds_api.cc +++ b/src/core/ext/xds/xds_api.cc @@ -324,11 +324,17 @@ absl::Status XdsApi::ParseAdsResponse(absl::string_view encoded_response, const auto* resource_wrapper = envoy_service_discovery_v3_Resource_parse( serialized_resource.data(), serialized_resource.size(), arena.ptr()); if (resource_wrapper == nullptr) { - parser->ResourceWrapperParsingFailed(i); + parser->ResourceWrapperParsingFailed( + i, "Can't decode Resource proto wrapper"); continue; } const auto* resource = envoy_service_discovery_v3_Resource_resource(resource_wrapper); + if (resource == nullptr) { + parser->ResourceWrapperParsingFailed( + i, "No resource present in Resource proto wrapper"); + continue; + } type_url = absl::StripPrefix( UpbStringToAbsl(google_protobuf_Any_type_url(resource)), "type.googleapis.com/"); diff --git a/src/core/ext/xds/xds_api.h b/src/core/ext/xds/xds_api.h index 65c55139a70..256998cc24d 100644 --- a/src/core/ext/xds/xds_api.h +++ b/src/core/ext/xds/xds_api.h @@ -75,8 +75,9 @@ class XdsApi { absl::string_view serialized_resource) = 0; // Called when a resource is wrapped in a Resource wrapper proto but - // we fail to deserialize the wrapper proto. - virtual void ResourceWrapperParsingFailed(size_t idx) = 0; + // we fail to parse the Resource wrapper. + virtual void ResourceWrapperParsingFailed(size_t idx, + absl::string_view message) = 0; }; struct ClusterLoadReport { diff --git a/src/core/ext/xds/xds_client.cc b/src/core/ext/xds/xds_client.cc index 801c950aa4c..c5a53f66880 100644 --- a/src/core/ext/xds/xds_client.cc +++ b/src/core/ext/xds/xds_client.cc @@ -152,7 +152,8 @@ class XdsClient::ChannelState::AdsCallState absl::string_view serialized_resource) override ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_); - void ResourceWrapperParsingFailed(size_t idx) override; + void ResourceWrapperParsingFailed(size_t idx, + absl::string_view message) override; Result TakeResult() { return std::move(result_); } @@ -878,9 +879,9 @@ void XdsClient::ChannelState::AdsCallState::AdsResponseParser::ParseResource( } void XdsClient::ChannelState::AdsCallState::AdsResponseParser:: - ResourceWrapperParsingFailed(size_t idx) { - result_.errors.emplace_back(absl::StrCat( - "resource index ", idx, ": Can't decode Resource proto wrapper")); + ResourceWrapperParsingFailed(size_t idx, absl::string_view message) { + result_.errors.emplace_back( + absl::StrCat("resource index ", idx, ": ", message)); } // diff --git a/test/core/xds/xds_client_corpora/resource_wrapper_empty b/test/core/xds/xds_client_corpora/resource_wrapper_empty new file mode 100644 index 00000000000..534b6a4286b --- /dev/null +++ b/test/core/xds/xds_client_corpora/resource_wrapper_empty @@ -0,0 +1,26 @@ +bootstrap: "{\"xds_servers\": [{\"server_uri\":\"xds.example.com:443\", \"channel_creds\":[{\"type\": \"fake\"}]}]}" +actions { + start_watch { + resource_type { + cluster { + } + } + } +} +actions { + send_message_to_client { + stream_id { + ads { + } + } + response { + version_info: "envoy.config.cluster.v3.Cluster" + resources { + type_url: "envoy.service.discovery.v3.Resource" + } + canary: true + type_url: "envoy.config.cluster.v3.Cluster" + nonce: "envoy.config.cluster.v3.Cluster" + } + } +}