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.
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
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)