From 2965af8479861a71ebcda2fad860c0ad7e5b2010 Mon Sep 17 00:00:00 2001 From: Rudra2018 Date: Sat, 1 Nov 2025 07:42:55 +0530 Subject: [PATCH] harden(rest): escape REST path args in generated clients; update single golden (rest_EmptyRPC.want) --- internal/gengapic/genrest.go | 12 +++++++++++- internal/gengapic/testdata/rest_EmptyRPC.want | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/internal/gengapic/genrest.go b/internal/gengapic/genrest.go index c04d39578ab..796b9c58493 100644 --- a/internal/gengapic/genrest.go +++ b/internal/gengapic/genrest.go @@ -522,7 +522,17 @@ func (g *generator) generateBaseURL(info *httpInfo, ret string) { tokens = append(tokens, fmt.Sprintf("req%s", fieldGetter(path[1]))) } g.imports[pbinfo.ImportSpec{Path: "fmt"}] = true - p("baseUrl.Path += fmt.Sprintf(%s)", strings.Join(tokens, ", ")) +// Emit: baseUrl.Path += fmt.Sprintf("", url.PathEscape(arg1), url.PathEscape(arg2), ...) +// tokens[0] is the format string; tokens[1:] are the arguments to fmt.Sprintf. +if len(tokens) > 1 { + for i := 1; i < len(tokens); i++ { + t := strings.TrimSpace(tokens[i]) + if t != "" { + tokens[i] = fmt.Sprintf("url.PathEscape(%s)", tokens[i]) + } + } +} +p("baseUrl.Path += fmt.Sprintf(%s)", strings.Join(tokens, ", ")) p("") } diff --git a/internal/gengapic/testdata/rest_EmptyRPC.want b/internal/gengapic/testdata/rest_EmptyRPC.want index 1ca911d4d32..39491dba358 100644 --- a/internal/gengapic/testdata/rest_EmptyRPC.want +++ b/internal/gengapic/testdata/rest_EmptyRPC.want @@ -6,7 +6,7 @@ func (c *fooRESTClient) EmptyRPC(ctx context.Context, req *foopb.Foo, opts ...ga if err != nil { return err } - baseUrl.Path += fmt.Sprintf("/v1/foo/%v", req.GetOther()) + baseUrl.Path += fmt.Sprintf("/v1/foo/%v", url.PathEscape(req.GetOther())) params := url.Values{} if req != nil && req.RequestId != nil {