Skip to content

Commit 9a39eb7

Browse files
committed
pd-ctl: fix region keyspace table query escaping
Keep table range lookups aligned with url.Values encoding and reject keyspace IDs outside the supported 24-bit range. Update the command tests to match the request shape and cover the out-of-range keyspace case. Signed-off-by: Ryan Leung <rleungx@gmail.com>
1 parent 6248525 commit 9a39eb7

File tree

2 files changed

+32
-11
lines changed

2 files changed

+32
-11
lines changed

tools/pd-ctl/pdctl/command/region_command.go

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import (
3535

3636
"github.com/pingcap/errors"
3737
"github.com/pingcap/failpoint"
38+
"github.com/tikv/pd/client/constants"
3839

3940
"github.com/tikv/pd/client/clients/router"
4041
pd "github.com/tikv/pd/client/http"
@@ -549,10 +550,17 @@ func showRegionWithKeyspaceCommandFunc(cmd *cobra.Command, args []string) {
549550
return
550551
}
551552

552-
if _, err := strconv.ParseUint(args[0], 10, 32); err != nil {
553+
keyspaceIDUint64, err := strconv.ParseUint(args[0], 10, 32)
554+
if err != nil {
553555
cmd.Println("keyspace_id should be a number")
554556
return
555557
}
558+
keyspaceID := uint32(keyspaceIDUint64)
559+
if keyspaceID < constants.DefaultKeyspaceID || keyspaceID > constants.MaxKeyspaceID {
560+
cmd.Printf("invalid keyspace id %d. It must be in the range of [%d, %d]\n",
561+
keyspaceID, constants.DefaultKeyspaceID, constants.MaxKeyspaceID)
562+
return
563+
}
556564

557565
prefix := regionsKeyspacePrefix + "/id/" + args[0]
558566
if len(args) == 2 {
@@ -572,9 +580,9 @@ func showRegionWithKeyspaceCommandFunc(cmd *cobra.Command, args []string) {
572580
return
573581
}
574582
query := make(url.Values)
575-
startKey, endKey := makeTableRangeInKeyspace(args[0], tableID)
576-
query.Set("key", url.QueryEscape(string(startKey)))
577-
query.Set("end_key", url.QueryEscape(string(endKey)))
583+
startKey, endKey := makeTableRangeInKeyspace(keyspaceID, tableID)
584+
query.Set("key", string(startKey))
585+
query.Set("end_key", string(endKey))
578586
if len(args) == 4 {
579587
if _, err := strconv.Atoi(args[3]); err != nil {
580588
cmd.Println("limit should be a number")
@@ -593,10 +601,9 @@ func showRegionWithKeyspaceCommandFunc(cmd *cobra.Command, args []string) {
593601
cmd.Println(r)
594602
}
595603

596-
func makeTableRangeInKeyspace(keyspaceID string, tableID int64) ([]byte, []byte) {
597-
keyspaceIDUint64, _ := strconv.ParseUint(keyspaceID, 10, 32)
604+
func makeTableRangeInKeyspace(keyspaceID uint32, tableID int64) ([]byte, []byte) {
598605
keyspaceIDBytes := make([]byte, 4)
599-
binary.BigEndian.PutUint32(keyspaceIDBytes, uint32(keyspaceIDUint64))
606+
binary.BigEndian.PutUint32(keyspaceIDBytes, keyspaceID)
600607

601608
keyPrefix := append([]byte{'x'}, keyspaceIDBytes[1:]...)
602609
startKey := codec.EncodeBytes(nil, append(keyPrefix, append([]byte{'t'}, codec.EncodeInt(nil, tableID)...)...))

tools/pd-ctl/pdctl/command/region_command_test.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ func TestRegionKeyspaceIDTableIDPath(t *testing.T) {
7676

7777
startKey, endKey := expectedTableRangeInKeyspace(1, 100)
7878
query := make(url.Values)
79-
query.Set("key", url.QueryEscape(string(startKey)))
80-
query.Set("end_key", url.QueryEscape(string(endKey)))
79+
query.Set("key", string(startKey))
80+
query.Set("end_key", string(endKey))
8181

8282
cmd := NewRegionWithKeyspaceCommand()
8383
cmd.PersistentFlags().String("pd", "http://mock-pd:2379", "")
@@ -121,8 +121,8 @@ func TestRegionKeyspaceIDTableIDPathWithLimit(t *testing.T) {
121121

122122
startKey, endKey := expectedTableRangeInKeyspace(1, 100)
123123
query := make(url.Values)
124-
query.Set("key", url.QueryEscape(string(startKey)))
125-
query.Set("end_key", url.QueryEscape(string(endKey)))
124+
query.Set("key", string(startKey))
125+
query.Set("end_key", string(endKey))
126126
query.Set("limit", "16")
127127

128128
cmd := NewRegionWithKeyspaceCommand()
@@ -152,6 +152,20 @@ func TestRegionKeyspaceIDInvalidKeyspaceID(t *testing.T) {
152152
re.Contains(out.String(), "keyspace_id should be a number")
153153
}
154154

155+
func TestRegionKeyspaceIDOutOfRangeKeyspaceID(t *testing.T) {
156+
re := require.New(t)
157+
158+
cmd := NewRegionWithKeyspaceCommand()
159+
cmd.PersistentFlags().String("pd", "http://mock-pd:2379", "")
160+
cmd.SetArgs([]string{"id", "16777216"})
161+
var out bytes.Buffer
162+
cmd.SetOut(&out)
163+
cmd.SetErr(&out)
164+
165+
re.NoError(cmd.Execute())
166+
re.Contains(out.String(), "invalid keyspace id 16777216. It must be in the range of [0, 16777215]")
167+
}
168+
155169
func TestRegionKeyspaceIDInvalidTableID(t *testing.T) {
156170
re := require.New(t)
157171

0 commit comments

Comments
 (0)