Skip to content

database/gredis: When using the ScriptExists method, if Redis crashes or the connection is down, there will be an index out of range issue that causes the program to crash. #3646

@CampbellChen

Description

@CampbellChen

Go version

go version go1.22.1 linux/amd64

GoFrame version

v2.7.1

Can this bug be reproduced with the latest release?

Option Yes

What did you do?

main.go

package main

import (
	_ "github.com/gogf/gf/contrib/nosql/redis/v2"

	"crypto/sha1"
	"encoding/hex"
	"io"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gctx"
)

const scriptLck = `
local flg = tostring(KEYS[1])
local exp = tonumber(ARGV[1])
local uid = tostring(ARGV[2])
local res = redis.call('GET', flg)
if res then
  return 0
else
  redis.call('SETEX', flg, exp, uid)
  return 1
end
`

func main() {
	_sha1 := hash(scriptLck)
	ctx := gctx.New()
	exists, err := g.Redis().ScriptExists(ctx, _sha1)
	if err != nil {
		g.Log().Errorf(ctx, "[sync.lock] error checking script (%s) existence: %+v", _sha1, err)
	}
	if len(exists) > 0 && exists[_sha1] {
		g.Log().Infof(ctx, "[sync.lock] script (%s) already exists", _sha1)
	} else {
		g.Log().Infof(ctx, "[sync.lock] script (%s) not exists.", _sha1)
	}
}

// hash generates SHA-1 hash for the given string.
func hash(k string) string {
	h := sha1.New()
	_, _ = io.WriteString(h, k)
	return hex.EncodeToString(h.Sum(nil))
}

What did you see happen?

During the execution of the above code, if a Redis outage occurs or the Redis connection is unavailable, an index out of range error will occur, causing the service to crash.

2024-06-17 15:30:52.327 [FATA] {d8d390f526bad9174ce6096d32e970ee} exception recovered: runtime error: index out of range [0] with length 0
1. exception recovered: runtime error: index out of range [0] with length 0
   1).  go.opentelemetry.io/otel/sdk/trace.(*recordingSpan).End.deferwrap1
        C:/Users/Administrator/go/pkg/mod/go.opentelemetry.io/otel/sdk@v1.25.0/trace/span.go:381
   2).  go.opentelemetry.io/otel/sdk/trace.(*recordingSpan).End
        C:/Users/Administrator/go/pkg/mod/go.opentelemetry.io/otel/sdk@v1.25.0/trace/span.go:413

What did you expect to see?

Upon debug, it was found that the ScriptExists method under the database/gredis package does not check for null values and index bounds before using the returned values.

image

Pls fix it. Tks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugIt is confirmed a bug, but don't worry, we'll handle it.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions