diff --git a/ddl/backfilling.go b/ddl/backfilling.go index 6be728a56640c..7c6bfad46c938 100644 --- a/ddl/backfilling.go +++ b/ddl/backfilling.go @@ -425,6 +425,13 @@ func (w *worker) handleReorgTasks(reorgInfo *reorgInfo, totalAddedCount *int64, } func tryDecodeToHandleString(key kv.Key) string { + defer func() { + if r := recover(); r != nil { + logutil.BgLogger().Warn("tryDecodeToHandleString panic", + zap.Any("recover()", r), + zap.Binary("key", key)) + } + }() handle, err := tablecodec.DecodeRowKey(key) if err != nil { recordPrefixIdx := bytes.Index(key, []byte("_r")) diff --git a/tablecodec/tablecodec_test.go b/tablecodec/tablecodec_test.go index 554287b8dc6a7..e373eadba33b9 100644 --- a/tablecodec/tablecodec_test.go +++ b/tablecodec/tablecodec_test.go @@ -46,6 +46,20 @@ func TestTableCodec(t *testing.T) { require.Equal(t, int64(2), h.IntValue()) } +// https://github.com/pingcap/tidb/issues/27687. +func TestTableCodecInvalid(t *testing.T) { + tableID := int64(100) + buf := make([]byte, 0, 11) + buf = append(buf, 't') + buf = codec.EncodeInt(buf, tableID) + buf = append(buf, '_', 'r') + buf = codec.EncodeInt(buf, -9078412423848787968) + buf = append(buf, '0') + _, err := DecodeRowKey(buf) + require.NotNil(t, err) + require.Equal(t, "invalid encoded key", err.Error()) +} + // column is a structure used for test type column struct { id int64 diff --git a/util/codec/codec.go b/util/codec/codec.go index 57ebc5a11be21..a5657883a2648 100644 --- a/util/codec/codec.go +++ b/util/codec/codec.go @@ -963,7 +963,7 @@ func peek(b []byte) (length int, err error) { return 0, errors.Trace(err) } length += l - if length < 0 { + if length <= 0 { return 0, errors.New("invalid encoded key") } else if length > originLength { return 0, errors.Errorf("invalid encoded key, "+