1
0
mirror of https://github.com/redis/go-redis.git synced 2026-10-22 19:49:00 +03:00

fix(cmd): allow = in CLIENT INFO values (#4096)

* fix(cmd): allow = in CLIENT INFO values

Redis accepts "=" in a client name, a user name and lib-name, and
go-redis puts Options.IdentitySuffix into lib-name. parseClientInfo
split each field on every "=" and rejected a field with more than one,
so ClientInfo and ACLLog failed with "unexpected client info data".
Split each field at the first "=" only.

* Update client_info_internal_test.go

---------

Co-authored-by: Nedyalko Dyakov <1547186+ndyakov@users.noreply.github.com>
This commit is contained in:
Yingzi Zhang
2026-10-19 12:25:56 -04:00
committed by GitHub
parent 0c02a49410
commit fecce1ac79
2 changed files with 19 additions and 3 deletions

View File

@@ -32,3 +32,20 @@ func TestParseClientInfoForwardCompatFlags(t *testing.T) {
})
}
}
// TestParseClientInfoEqualsInValue pins that a value can contain "=". Redis
// accepts "=" in a client name, a user name and lib-name, and go-redis puts
// Options.IdentitySuffix into lib-name, so the parser must split each field
// at the first "=" only.
func TestParseClientInfoEqualsInValue(t *testing.T) {
info, err := parseClientInfo("id=1 addr=127.0.0.1:6379 name=app=web user=a=b lib-name=go-redis(env=prod,go1.26.0) db=0")
if err != nil {
t.Fatalf("parseClientInfo errored: %v", err)
}
if info.Name != "app=web" || info.User != "a=b" || info.LibName != "go-redis(env=prod,go1.26.0)" {
t.Fatalf("Name=%q User=%q LibName=%q", info.Name, info.User, info.LibName)
}
if _, err := parseClientInfo("id=1 garbage db=0"); err == nil {
t.Fatal("a field without \"=\" must still return an error")
}
}

View File

@@ -8058,11 +8058,10 @@ func (cmd *ClientInfoCmd) readReply(rd *proto.Reader) (err error) {
func parseClientInfo(txt string) (info *ClientInfo, err error) {
info = &ClientInfo{}
for _, s := range strings.Split(txt, " ") {
kv := strings.Split(s, "=")
if len(kv) != 2 {
key, val, ok := strings.Cut(s, "=")
if !ok {
return nil, fmt.Errorf("redis: unexpected client info data (%s)", s)
}
key, val := kv[0], kv[1]
switch key {
case "id":