Go

Go

Made by DeepSource

Redis function called with an incorrect number of arguments GO-E1001

Bug risk
Critical

Some functions in go-redis/redis package are variadic functions, i.e., they accept any number of trailing arguments like fmt.Println. A few of them accept any number of trailing arguments, but there could be a runtime panic because of their undocumented behavior. If we look at the implementation of those functions, we will find calls to panic. Following functions are variadic, and if the number of trailing arguments are not correct, it might result in panic:

Such critical information is undocumented in "github.com/go-redis/redis" package, and it is hard to find such issues without manual deep code inspection.

Example: ZPopMin implementation:

func (c cmdable) ZPopMin(ctx context.Context, key string, count ...int64) *ZSliceCmd {
    args := []interface{}{
        "zpopmin",
        key,
    }

    switch len(count) {
    case 0:
        break
    case 1:
        args = append(args, count[0])
    default:
        panic("too many arguments")
    }

    ... // Full implementation is omitted for brevity

As count is a variadic parameter of ZPopMin, it can accept any number of trailing arguments, but it can be seen from the implementation that if len(count) > 1, it would cause a runtime panic.

Bad practice

ctx := context.TODO()
client := redis.NewClient(&redis.Options{})

// NOTE: Following methods panics
client.MemoryUsage(ctx, "", 0, 1)   // "samples" must have only 1 argument, not 2
client.ZPopMax(ctx, "", 1, 2, 3)    // "count" must have only 0 or 1 argument, not more than 1
client.ZPopMin(ctx, "", 1, 2, 3)    // "count" must have only 0 or 1 argument, not more than 1
client.BitPos(ctx, "", 0, 9, 9, 9)  // "pos" must have only 0, 1 or 2 argument(s), not more than 2

Recommended

ctx := context.TODO()
client := redis.NewClient(&redis.Options{})

client.MemoryUsage(ctx, "", 0)
client.ZPopMax(ctx, "")
client.ZPopMax(ctx, "", 1)
client.ZPopMin(ctx, "")
client.ZPopMin(ctx, "", 1)
client.BitPos(ctx, "", 0)
client.BitPos(ctx, "", 0, 9)
client.BitPos(ctx, "", 0, 9, 9)

References