Skip to content

Commit 7ca6b50

Browse files
Sophclaude
andcommitted
Upgrade go-git to v6.0.0-alpha.2
Closes the credential-leak advisory tracked as CVE-2026-41506 (GHSA-3xc5-wrhm-f963 / Dependabot alert #1). Our smart-HTTP path already used Go's stdlib http.Client directly, which strips the Authorization header on cross-host redirects since 1.8 — but upgrading clears the alert and pulls in the upstream http.followRedirects controls. Alpha.2 is a major rewrite of plumbing/transport. Translation: - *transport.Endpoint (struct) → *url.URL throughout. Field accesses (.Scheme, .Host, .Path, .User, .Hostname()) are unchanged. - transport.NewEndpoint → transport.ParseURL. - transport.AuthMethod (interface) is gone. Defined our own auth.Method and gitproto.AuthMethod with a single Authorizer(*http.Request) error method, satisfied by *transporthttp.BasicAuth and *transporthttp.TokenAuth (whose SetAuth methods were renamed to Authorizer). - transport.Service (typed) → string constants. Function parameters take string. - transporthttp.NewTransport(*TransportOptions) → NewTransport(Options) (value, not pointer). - transport.AdvertiseReferences → transport.AdvertiseRefs. - transport.UploadPackOptions → transport.UploadPackRequest; transport.ReceivePackOptions → transport.ReceivePackRequest. - transport.Register / transport.Get were removed. The TestMain shims in syncer/integration_test.go and cmd/git-sync/main_test.go registered a custom HTTP transport for go-git's transport registry, but our code never goes through that registry — it hits the network through gitproto's own http.Client. Dropped both shims as dead code. Also dropped the now-unused Conn.Transport field; nothing in git-sync read it. Updated .golangci.yaml ireturn allowlist to permit the new auth.Method interface where the previous transport.AuthMethod allowance lived. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Entire-Checkpoint: b0d39f2320f3
1 parent 66ab8c4 commit 7ca6b50

17 files changed

Lines changed: 130 additions & 162 deletions

File tree

.golangci.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ linters:
9797
- github.com/go-git/go-git/v6/storage.Storer
9898
- github.com/go-git/go-git/v6/plumbing/storer.EncodedObjectIter
9999
- github.com/go-git/go-billy/v6.Filesystem
100-
- github.com/go-git/go-git/v6/plumbing/transport.AuthMethod
100+
- github.com/entirehq/git-sync/internal/auth.Method
101101
nolintlint:
102102
require-explanation: true
103103
require-specific: true

cmd/git-sync/main_test.go

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import (
2323
"github.com/go-git/go-git/v6/plumbing/protocol/packp"
2424
"github.com/go-git/go-git/v6/plumbing/protocol/packp/capability"
2525
"github.com/go-git/go-git/v6/plumbing/transport"
26-
transporthttp "github.com/go-git/go-git/v6/plumbing/transport/http"
2726
"github.com/go-git/go-git/v6/storage/memory"
2827
)
2928

@@ -443,14 +442,14 @@ func (s *smartHTTPRepoServer) handle(w http.ResponseWriter, r *http.Request) {
443442
}
444443

445444
func (s *smartHTTPRepoServer) handleInfoRefs(w http.ResponseWriter, r *http.Request) {
446-
service := transport.Service(r.URL.Query().Get("service"))
445+
service := r.URL.Query().Get("service")
447446
if service != transport.UploadPackService && service != transport.ReceivePackService {
448447
http.Error(w, "missing service", http.StatusBadRequest)
449448
return
450449
}
451450

452451
var buf bytes.Buffer
453-
if err := transport.AdvertiseReferences(r.Context(), s.repo.Storer, &buf, service, false); err != nil {
452+
if err := transport.AdvertiseRefs(r.Context(), s.repo.Storer, &buf, service, false); err != nil {
454453
http.Error(w, err.Error(), http.StatusInternalServerError)
455454
return
456455
}
@@ -506,7 +505,7 @@ func (s *smartHTTPRepoServer) handleUploadPack(w http.ResponseWriter, r *http.Re
506505
var buf bytes.Buffer
507506
wc := nopWriteCloser{&buf}
508507

509-
err := transport.UploadPack(r.Context(), s.repo.Storer, r.Body, wc, &transport.UploadPackOptions{
508+
err := transport.UploadPack(r.Context(), s.repo.Storer, r.Body, wc, &transport.UploadPackRequest{
510509
StatelessRPC: true,
511510
})
512511
if err != nil {
@@ -528,7 +527,7 @@ func (s *smartHTTPRepoServer) handleReceivePack(w http.ResponseWriter, r *http.R
528527
var buf bytes.Buffer
529528
wc := nopWriteCloser{&buf}
530529

531-
err := transport.ReceivePack(r.Context(), s.repo.Storer, r.Body, wc, &transport.ReceivePackOptions{
530+
err := transport.ReceivePack(r.Context(), s.repo.Storer, r.Body, wc, &transport.ReceivePackRequest{
532531
StatelessRPC: true,
533532
})
534533

@@ -548,12 +547,3 @@ type nopWriteCloser struct{ io.Writer }
548547

549548
func (nopWriteCloser) Close() error { return nil }
550549

551-
func TestMain(m *testing.M) {
552-
customHTTP := transporthttp.NewTransport(&transporthttp.TransportOptions{
553-
Client: &http.Client{},
554-
})
555-
transport.Register("http", customHTTP)
556-
transport.Register("https", customHTTP)
557-
558-
os.Exit(m.Run())
559-
}

go.mod

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ go 1.25.2
44

55
require (
66
github.com/go-git/go-billy/v6 v6.0.0-20260410103409-85b6241850b5
7-
github.com/go-git/go-git/v6 v6.0.0-alpha.1
7+
github.com/go-git/go-git/v6 v6.0.0-alpha.2
88
github.com/stretchr/testify v1.11.1
99
github.com/zalando/go-keyring v0.2.8
1010
)
@@ -19,15 +19,14 @@ require (
1919
github.com/emirpasic/gods v1.18.1 // indirect
2020
github.com/go-git/gcfg/v2 v2.0.2 // indirect
2121
github.com/godbus/dbus/v5 v5.2.2 // indirect
22-
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
2322
github.com/kevinburke/ssh_config v1.6.0 // indirect
2423
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
2524
github.com/pjbgf/sha1cd v0.5.0 // indirect
2625
github.com/pmezard/go-difflib v1.0.0 // indirect
2726
github.com/sergi/go-diff v1.4.0 // indirect
28-
golang.org/x/crypto v0.48.0 // indirect
29-
golang.org/x/net v0.51.0 // indirect
30-
golang.org/x/sync v0.19.0 // indirect
27+
golang.org/x/crypto v0.50.0 // indirect
28+
golang.org/x/net v0.53.0 // indirect
29+
golang.org/x/sync v0.20.0 // indirect
3130
golang.org/x/sys v0.43.0 // indirect
3231
gopkg.in/yaml.v3 v3.0.1 // indirect
3332
)

go.sum

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,12 @@ github.com/go-git/gcfg/v2 v2.0.2 h1:MY5SIIfTGGEMhdA7d7JePuVVxtKL7Hp+ApGDJAJ7dpo=
2323
github.com/go-git/gcfg/v2 v2.0.2/go.mod h1:/lv2NsxvhepuMrldsFilrgct6pxzpGdSRC13ydTLSLs=
2424
github.com/go-git/go-billy/v6 v6.0.0-20260410103409-85b6241850b5 h1:r5Y4Hn9QwQj+u6vN0Ib1MipHkanYaG8Zj0kxsnv8Bu4=
2525
github.com/go-git/go-billy/v6 v6.0.0-20260410103409-85b6241850b5/go.mod h1:CdBVp7CXl9l3sOyNEog46cP1Pvx/hjCe9AD0mtaIUYU=
26-
github.com/go-git/go-git-fixtures/v5 v5.1.2-0.20260122163445-0622d7459a67 h1:3hutPZF+/FBjR/9MdsLJ7e1mlt9pwHgwxMW7CrbmWII=
27-
github.com/go-git/go-git-fixtures/v5 v5.1.2-0.20260122163445-0622d7459a67/go.mod h1:xKt0pNHST9tYHvbiLxSY27CQWFwgIxBJuDrOE0JvbZw=
28-
github.com/go-git/go-git/v6 v6.0.0-alpha.1 h1:tGohX5luKeO50DZD0/Zqd5dYjJzKtub91S4I+1qFVIs=
29-
github.com/go-git/go-git/v6 v6.0.0-alpha.1/go.mod h1:qtzfNHlFsnq6vCw54aT4KvFWPK5bsOpTVtFC2sysdB8=
26+
github.com/go-git/go-git-fixtures/v6 v6.0.0-20260405195209-b16dd39735e0 h1:XoTsdvaghuVfIr7HpNTmFDLu2nz3I2iGqyn6Uk6MkJc=
27+
github.com/go-git/go-git-fixtures/v6 v6.0.0-20260405195209-b16dd39735e0/go.mod h1:1Lr7/vYEYyl6Ir9Ku0tKrCIRreM5zovv0Jdx2MPSM4s=
28+
github.com/go-git/go-git/v6 v6.0.0-alpha.2 h1:T3loNtDuAixNzXtlQxZhnYiYpaQ3CA4vn9RssAniEeI=
29+
github.com/go-git/go-git/v6 v6.0.0-alpha.2/go.mod h1:oCD3i19CTz7gBpeb11ZZqL91WzqbMq9avn5KpUYy/Ak=
3030
github.com/godbus/dbus/v5 v5.2.2 h1:TUR3TgtSVDmjiXOgAAyaZbYmIeP3DPkld3jgKGV8mXQ=
3131
github.com/godbus/dbus/v5 v5.2.2/go.mod h1:3AAv2+hPq5rdnr5txxxRwiGjPXamgoIHgz9FPBfOp3c=
32-
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
33-
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
3432
github.com/kevinburke/ssh_config v1.6.0 h1:J1FBfmuVosPHf5GRdltRLhPJtJpTlMdKTBjRgTaQBFY=
3533
github.com/kevinburke/ssh_config v1.6.0/go.mod h1:q2RIzfka+BXARoNexmF9gkxEX7DmvbW9P4hIVx2Kg4M=
3634
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
@@ -54,18 +52,18 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu
5452
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
5553
github.com/zalando/go-keyring v0.2.8 h1:6sD/Ucpl7jNq10rM2pgqTs0sZ9V3qMrqfIIy5YPccHs=
5654
github.com/zalando/go-keyring v0.2.8/go.mod h1:tsMo+VpRq5NGyKfxoBVjCuMrG47yj8cmakZDO5QGii0=
57-
golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
58-
golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=
59-
golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo=
60-
golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y=
61-
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
62-
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
55+
golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI=
56+
golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q=
57+
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
58+
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
59+
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
60+
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
6361
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
6462
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
65-
golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg=
66-
golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM=
67-
golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
68-
golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
63+
golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY=
64+
golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY=
65+
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
66+
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
6967
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
7068
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
7169
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

internal/auth/auth.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,23 @@ package auth
33
import (
44
"context"
55
"fmt"
6+
"net/http"
7+
"net/url"
68
"os/exec"
79
"strings"
810

9-
"github.com/go-git/go-git/v6/plumbing/transport"
1011
transporthttp "github.com/go-git/go-git/v6/plumbing/transport/http"
1112
)
1213

1314
const defaultGitUsername = "git"
1415

16+
// Method authorizes outbound HTTP requests for a remote. It is satisfied
17+
// by *transporthttp.BasicAuth and *transporthttp.TokenAuth, whose Authorizer
18+
// methods replaced the Method interface that go-git removed in v6 alpha.2.
19+
type Method interface {
20+
Authorizer(req *http.Request) error
21+
}
22+
1523
// Endpoint holds the authentication-related fields for a remote.
1624
type Endpoint struct {
1725
Username string
@@ -22,7 +30,7 @@ type Endpoint struct {
2230

2331
// Resolve resolves the auth method for the given endpoint configuration.
2432
// Order: explicit flags → Entire DB token → git credential helper → anonymous.
25-
func Resolve(raw Endpoint, ep *transport.Endpoint) (transport.AuthMethod, error) {
33+
func Resolve(raw Endpoint, ep *url.URL) (Method, error) {
2634
if auth := explicitAuth(raw); auth != nil {
2735
return auth, nil
2836
}
@@ -43,7 +51,7 @@ func Resolve(raw Endpoint, ep *transport.Endpoint) (transport.AuthMethod, error)
4351
return nil, nil //nolint:nilnil // nil signals no auth method found at this stage
4452
}
4553

46-
func explicitAuth(raw Endpoint) transport.AuthMethod {
54+
func explicitAuth(raw Endpoint) Method {
4755
if raw.BearerToken != "" {
4856
return &transporthttp.TokenAuth{Token: raw.BearerToken}
4957
}
@@ -64,7 +72,7 @@ var GitCredentialFillCommand = func(ctx context.Context, input string) ([]byte,
6472
return cmd.Output()
6573
}
6674

67-
func lookupGitCredential(ep *transport.Endpoint) (string, string, bool) {
75+
func lookupGitCredential(ep *url.URL) (string, string, bool) {
6876
input := credentialFillInput(ep)
6977
if input == "" {
7078
return "", "", false
@@ -89,7 +97,7 @@ func lookupGitCredential(ep *transport.Endpoint) (string, string, bool) {
8997
return username, password, true
9098
}
9199

92-
func credentialFillInput(ep *transport.Endpoint) string {
100+
func credentialFillInput(ep *url.URL) string {
93101
if ep == nil || ep.Hostname() == "" {
94102
return ""
95103
}

internal/auth/auth_test.go

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -120,13 +120,11 @@ func TestTokenExpiredOrExpiring(t *testing.T) {
120120
}
121121

122122
func TestCredentialFillInput(t *testing.T) {
123-
ep := &transport.Endpoint{
124-
URL: url.URL{
125-
Scheme: "https",
126-
Host: "github.com",
127-
Path: "/owner/repo.git",
128-
User: url.User("myuser"),
129-
},
123+
ep := &url.URL{
124+
Scheme: "https",
125+
Host: "github.com",
126+
Path: "/owner/repo.git",
127+
User: url.User("myuser"),
130128
}
131129

132130
got := credentialFillInput(ep)
@@ -144,20 +142,18 @@ func TestCredentialFillInputNilEndpoint(t *testing.T) {
144142
}
145143

146144
func TestCredentialFillInputEmptyHost(t *testing.T) {
147-
ep := &transport.Endpoint{URL: url.URL{Scheme: "https"}}
145+
ep := &url.URL{Scheme: "https"}
148146
got := credentialFillInput(ep)
149147
if got != "" {
150148
t.Errorf("expected empty string for empty host, got %q", got)
151149
}
152150
}
153151

154152
func TestCredentialFillInputNoUser(t *testing.T) {
155-
ep := &transport.Endpoint{
156-
URL: url.URL{
157-
Scheme: "https",
158-
Host: "example.com",
159-
Path: "/repo.git",
160-
},
153+
ep := &url.URL{
154+
Scheme: "https",
155+
Host: "example.com",
156+
Path: "/repo.git",
161157
}
162158
got := credentialFillInput(ep)
163159
want := "protocol=https\nhost=example.com\npath=repo.git\n\n"
@@ -227,17 +223,17 @@ func TestParseCredentialOutput(t *testing.T) {
227223
}
228224

229225
func TestResolve(t *testing.T) {
230-
ep, err := transport.NewEndpoint("https://example.com/repo.git")
226+
ep, err := transport.ParseURL("https://example.com/repo.git")
231227
if err != nil {
232228
t.Fatal(err)
233229
}
234230

235-
sshEP := &transport.Endpoint{URL: url.URL{Scheme: "ssh", Host: "example.com", Path: "/repo.git"}}
231+
sshEP := &url.URL{Scheme: "ssh", Host: "example.com", Path: "/repo.git"}
236232

237233
tests := []struct {
238234
name string
239235
raw Endpoint
240-
ep *transport.Endpoint
236+
ep *url.URL
241237
mockCred func(ctx context.Context, input string) ([]byte, error)
242238
wantType string // "token", "basic", "nil"
243239
wantUser string
@@ -414,17 +410,17 @@ func TestExplicitAuth(t *testing.T) {
414410
func TestEndpointBaseURL(t *testing.T) {
415411
tests := []struct {
416412
name string
417-
ep *transport.Endpoint
413+
ep *url.URL
418414
want string
419415
}{
420416
{
421417
name: "https host",
422-
ep: &transport.Endpoint{URL: url.URL{Scheme: "https", Host: "example.com"}},
418+
ep: &url.URL{Scheme: "https", Host: "example.com"},
423419
want: "https://example.com",
424420
},
425421
{
426422
name: "http host with port",
427-
ep: &transport.Endpoint{URL: url.URL{Scheme: "http", Host: "example.com:8080"}},
423+
ep: &url.URL{Scheme: "http", Host: "example.com:8080"},
428424
want: "http://example.com:8080",
429425
},
430426
{
@@ -447,17 +443,17 @@ func TestEndpointBaseURL(t *testing.T) {
447443
func TestEndpointCredentialHost(t *testing.T) {
448444
tests := []struct {
449445
name string
450-
ep *transport.Endpoint
446+
ep *url.URL
451447
want string
452448
}{
453449
{
454450
name: "host without port",
455-
ep: &transport.Endpoint{URL: url.URL{Host: "example.com"}},
451+
ep: &url.URL{Host: "example.com"},
456452
want: "example.com",
457453
},
458454
{
459455
name: "host with port",
460-
ep: &transport.Endpoint{URL: url.URL{Host: "example.com:8080"}},
456+
ep: &url.URL{Host: "example.com:8080"},
461457
want: "example.com:8080",
462458
},
463459
{

internal/auth/entiredb.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import (
1414
"strings"
1515
"time"
1616

17-
"github.com/go-git/go-git/v6/plumbing/transport"
1817
"github.com/zalando/go-keyring"
1918
)
2019

@@ -39,7 +38,7 @@ type oauthTokenResponse struct {
3938
// Returns (username, password, true, nil) on success, ("", "", false, nil) when
4039
// no credential is configured, or ("", "", false, err) when a credential exists
4140
// but refresh failed (issue #7).
42-
func LookupEntireDBCredential(raw Endpoint, ep *transport.Endpoint) (string, string, bool, error) {
41+
func LookupEntireDBCredential(raw Endpoint, ep *url.URL) (string, string, bool, error) {
4342
if ep == nil || ep.Host == "" {
4443
return "", "", false, nil
4544
}
@@ -58,7 +57,7 @@ func LookupEntireDBCredential(raw Endpoint, ep *transport.Endpoint) (string, str
5857
return username, token, true, nil
5958
}
6059

61-
func endpointBaseURL(ep *transport.Endpoint) string {
60+
func endpointBaseURL(ep *url.URL) string {
6261
if ep == nil || ep.Hostname() == "" {
6362
return ""
6463
}
@@ -70,7 +69,7 @@ func endpointBaseURL(ep *transport.Endpoint) string {
7069
return scheme + "://" + host
7170
}
7271

73-
func endpointCredentialHost(ep *transport.Endpoint) string {
72+
func endpointCredentialHost(ep *url.URL) string {
7473
if ep == nil {
7574
return ""
7675
}

0 commit comments

Comments
 (0)