Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
init
  • Loading branch information
RidRisR committed Oct 22, 2025
commit d0a82991034e169bffd819ffe07ee697eafcb27c
16 changes: 12 additions & 4 deletions br/pkg/stream/meta_kv.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,14 +173,22 @@ l_for:
for len(data) > 0 {
switch data[0] {
case flagShortValuePrefix:
// Need at least 2 bytes: flag + vlen
if len(data) < 2 {
return errors.Annotatef(berrors.ErrInvalidArgument,
"insufficient data for short value prefix, need at least 2 bytes but only have %d",
len(data))
}
vlen := data[1]
if len(data) < int(vlen)+2 {
// Need: flag (1 byte) + vlen (1 byte) + value (vlen bytes)
requiredLen := int(vlen) + 2
if len(data) < requiredLen {
return errors.Annotatef(berrors.ErrInvalidArgument,
"insufficient data for short value, need %d bytes but only have %d",
int(vlen)+2, len(data))
requiredLen, len(data))
}
v.shortValue = data[2 : int(vlen)+2]
data = data[int(vlen)+2:]
v.shortValue = data[2:requiredLen]
data = data[requiredLen:]
case flagOverlappedRollback:
v.hasOverlappedRollback = true
data = data[1:]
Expand Down
12 changes: 12 additions & 0 deletions br/pkg/stream/meta_kv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,18 @@ func TestWriteCFValueShortValueOverflow(t *testing.T) {
require.True(t, v4.HasShortValue())
require.Equal(t, len(v4.GetShortValue()), 255)
require.True(t, bytes.Equal(v4.GetShortValue(), largeValue))

// Test case 5: Edge case with only 1 byte (flag), no vlen byte - should error
buff5 := make([]byte, 0, 9)
buff5 = append(buff5, WriteTypePut)
buff5 = codec.EncodeUvarint(buff5, ts)
buff5 = append(buff5, flagShortValuePrefix) // Only flag, no vlen byte following

v5 := new(RawWriteCFValue)
err5 := v5.ParseFrom(buff5)
require.Error(t, err5)
require.Contains(t, err5.Error(), "insufficient data for short value prefix")
require.Contains(t, err5.Error(), "need at least 2 bytes but only have 1")
}

func TestWriteCFValueWithRollback(t *testing.T) {
Expand Down
13 changes: 7 additions & 6 deletions br/pkg/task/backup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/pingcap/tidb/pkg/kv"
"github.com/pingcap/tidb/pkg/meta/model"
"github.com/stretchr/testify/require"
"github.com/tikv/client-go/v2/oracle"
)

func TestParseTSString(t *testing.T) {
Expand All @@ -32,8 +33,8 @@ func TestParseTSString(t *testing.T) {
ts, err = ParseTSString("2021-01-01 01:42:23", false)
require.NoError(t, err)
localTime := time.Date(2021, time.Month(1), 1, 1, 42, 23, 0, time.Local)
localTimestamp := localTime.Unix()
localTSO := uint64((localTimestamp << 18) * 1000)
// Use oracle.GoTimeToTS instead of manual calculation to avoid overflow
localTSO := oracle.GoTimeToTS(localTime)
require.Equal(t, localTSO, ts)

_, err = ParseTSString("2021-01-01 01:42:23", true)
Expand All @@ -43,17 +44,17 @@ func TestParseTSString(t *testing.T) {
ts, err = ParseTSString("2021-01-01 01:42:23+00:00", true)
require.NoError(t, err)
localTime = time.Date(2021, time.Month(1), 1, 1, 42, 23, 0, time.UTC)
localTimestamp = localTime.Unix()
localTSO = uint64((localTimestamp << 18) * 1000)
// Use oracle.GoTimeToTS instead of manual calculation to avoid overflow
localTSO = oracle.GoTimeToTS(localTime)
require.Equal(t, localTSO, ts)

ts, err = ParseTSString("2021-01-01 01:42:23+08:00", true)
require.NoError(t, err)
secondsEastOfUTC := int((8 * time.Hour).Seconds())
beijing := time.FixedZone("Beijing Time", secondsEastOfUTC)
localTime = time.Date(2021, time.Month(1), 1, 1, 42, 23, 0, beijing)
localTimestamp = localTime.Unix()
localTSO = uint64((localTimestamp << 18) * 1000)
// Use oracle.GoTimeToTS instead of manual calculation to avoid overflow
localTSO = oracle.GoTimeToTS(localTime)
require.Equal(t, localTSO, ts)
}

Expand Down
Loading