From 51f199ce0760ffbad1f93b84810c9c9f4767091b Mon Sep 17 00:00:00 2001 From: tangenta Date: Thu, 18 Nov 2021 23:07:48 +0800 Subject: [PATCH 1/4] ddl, util/codec: prevent panic in logging --- ddl/backfilling.go | 6 ++++++ util/codec/codec.go | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ddl/backfilling.go b/ddl/backfilling.go index 6be728a56640c..14ccbe1972aab 100644 --- a/ddl/backfilling.go +++ b/ddl/backfilling.go @@ -425,6 +425,12 @@ func (w *worker) handleReorgTasks(reorgInfo *reorgInfo, totalAddedCount *int64, } func tryDecodeToHandleString(key kv.Key) string { + defer func() { + r := recover() + 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/util/codec/codec.go b/util/codec/codec.go index f6daf7e54261d..c9e785fdfe588 100644 --- a/util/codec/codec.go +++ b/util/codec/codec.go @@ -962,7 +962,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, "+ From 9cbf918aae54a77b09b24f59c21158ca0d79ad73 Mon Sep 17 00:00:00 2001 From: tangenta Date: Fri, 19 Nov 2021 10:56:07 +0800 Subject: [PATCH 2/4] check recover result --- ddl/backfilling.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ddl/backfilling.go b/ddl/backfilling.go index 14ccbe1972aab..478adb337551d 100644 --- a/ddl/backfilling.go +++ b/ddl/backfilling.go @@ -426,9 +426,12 @@ func (w *worker) handleReorgTasks(reorgInfo *reorgInfo, totalAddedCount *int64, func tryDecodeToHandleString(key kv.Key) string { defer func() { - r := recover() + var rs interface{} = "nil" + if r := recover(); r != nil { + rs = r + } logutil.BgLogger().Warn("tryDecodeToHandleString panic", - zap.Any("recover()", r), + zap.Any("recover()", rs), zap.Binary("key", key)) }() handle, err := tablecodec.DecodeRowKey(key) From 79396e4e5cb8bdfb5a529df464f3aa3dba99869c Mon Sep 17 00:00:00 2001 From: tangenta Date: Fri, 19 Nov 2021 11:43:59 +0800 Subject: [PATCH 3/4] address comment --- ddl/backfilling.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/ddl/backfilling.go b/ddl/backfilling.go index 478adb337551d..7c6bfad46c938 100644 --- a/ddl/backfilling.go +++ b/ddl/backfilling.go @@ -426,13 +426,11 @@ func (w *worker) handleReorgTasks(reorgInfo *reorgInfo, totalAddedCount *int64, func tryDecodeToHandleString(key kv.Key) string { defer func() { - var rs interface{} = "nil" if r := recover(); r != nil { - rs = r + logutil.BgLogger().Warn("tryDecodeToHandleString panic", + zap.Any("recover()", r), + zap.Binary("key", key)) } - logutil.BgLogger().Warn("tryDecodeToHandleString panic", - zap.Any("recover()", rs), - zap.Binary("key", key)) }() handle, err := tablecodec.DecodeRowKey(key) if err != nil { From f998c6e40a2cd6d3065873f5751b8169dba5eca1 Mon Sep 17 00:00:00 2001 From: tangenta Date: Fri, 19 Nov 2021 23:05:37 +0800 Subject: [PATCH 4/4] add test for DecodeRowKey --- tablecodec/tablecodec_test.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) 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