Skip to content

Embedded struct / message is not correctly populated, causing panic #2901

Open
@alexadhy

Description

🐛 Bug Report

Embedded struct / message is not correctly populated, causing panic

To Reproduce

Use this particular proto file:

syntax = "proto3";

package test;

import "google/api/annotations.proto";
import "protoc-gen-openapiv2/options/annotations.proto";

option go_package = "github.com/alexadhy/protos-gen-go/test;test";

option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
	responses: {
		key: "200";
	}
	responses: {
		key: "404";
		value: {
			description: "Returned when the resource does not exist.";
		}
	}
	responses: {
		key: "500";
		value: {
			description: "Returned when the service is temporarily unavailable.";
		}
	}
	responses: {
		key: "503";
		value: {
			description: "Returned when the resource is temporarily unavailable.";
		}
	}
};

service XService {
	rpc UpdateX (UpdateXRequest) returns (X) {
		option (google.api.http) = {
			put: "/v1/exes/{x.type=*}"
			body: "x"
		};
	}
}

message UpdateXRequest {
	// The parent resource
	string parent = 1;

	// The X to set.
	X x = 2;
}

enum XType {
	TYPE_UNDEFINED = 0;
	TYPE_A = 1;
	TYPE_B = 2;
}

message X {
	XType type = 1;
	string name = 2;
}

on generated code, it generates (snippet):

// Suppress "imported and not used" errors
var _ codes.Code
var _ io.Reader
var _ status.Status
var _ = runtime.String
var _ = utilities.NewDoubleArray
var _ = metadata.Join

var (
	filter_XService_UpdateX_0 = &utilities.DoubleArray{Encoding: map[string]int{"x": 0, "type": 1}, Base: []int{1, 2, 1, 0, 0}, Check: []int{0, 1, 2, 3, 2}}
)

func request_XService_UpdateX_0(ctx context.Context, marshaler runtime.Marshaler, client XServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
	var protoReq UpdateXRequest
	var metadata runtime.ServerMetadata

	newReader, berr := utilities.IOReaderFactory(req.Body)
	if berr != nil {
		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
	}
	if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.X); err != nil && err != io.EOF {
		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
	}

	var (
		val string
		e   int32
		ok  bool
		err error
		_   = err
	)

	val, ok = pathParams["x.type"]
	if !ok {
		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "x.type")
	}

	err = runtime.PopulateFieldFromPath(&protoReq, "x.type", val)
	if err != nil {
		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "x.type", err)
	}

	e, err = runtime.Enum(val, XType_value)
	if err != nil {
		return nil, metadata, status.Errorf(codes.InvalidArgument, "could not parse path as enum value, parameter: %s, error: %v", "x.type", err)
	}

	protoReq.X.Type = XType(e) // this line is causing issue

	if err := req.ParseForm(); err != nil {
		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
	}
	if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_XService_UpdateX_0); err != nil {
		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
	}

	msg, err := client.UpdateX(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
	return msg, metadata, err

}

I added a comment where the generated code creates an issue, because the X object is not yet initialized, access / assignment to X via protoreq.X.type = XType(e) will panic

Expected behavior

I expect that it should be populated correctly before assigning something, perhaps something like protoreq.X = &X{}

Actual Behavior

Panic

Your Environment

OS: Mac
Generated via buf with the following buf.lock:

Generated by buf. DO NOT EDIT.

version: v1
deps:

  • remote: buf.build
    owner: googleapis
    repository: googleapis
    commit: 8d7204855ec14631a499bd7393ce1970
  • remote: buf.build
    owner: grpc-ecosystem
    repository: grpc-gateway
    commit: bc28b723cd774c32b6fbc77621518765

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions