Skip to content

Commit

Permalink
Fix a panic in Postgres revision parsing for incompatible ZedTokens
Browse files Browse the repository at this point in the history
If Postgres is passed a ZedToken from CRDB, it will (incorrectly) interpret the token and try to create a slice with too much capacity. This change caps the delta on the transaction IDs and returns an error in that scenario

Fixes #1539
  • Loading branch information
josephschorr committed Sep 19, 2023
1 parent ebda6d1 commit 9c685f9
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 0 deletions.
6 changes: 6 additions & 0 deletions internal/datastore/postgres/revisions.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ func parseRevisionProto(revisionStr string) (datastore.Revision, error) {
}, nil
}

const MaxRevisionDelta = 1000

// parseRevisionDecimal parses a deprecated decimal.Decimal encoding of the revision
// with an optional xmin component, in the format of revision.xmin, e.g. 100.99.
// Because we're encoding to a snapshot, we want the revision to be considered visible,
Expand Down Expand Up @@ -203,6 +205,10 @@ func parseRevisionDecimal(revisionStr string) (datastore.Revision, error) {

var xipList []uint64
if xmax > xmin {
if xmax-xmin > MaxRevisionDelta {
return nil, fmt.Errorf("received revision delta in excess of that expected; are you sure you're not passing a ZedToken from an incompatible datastore?")
}

xipList = make([]uint64, 0, xmax-xmin)
for i := xmin; i < xid; i++ {
xipList = append(xipList, i)
Expand Down
5 changes: 5 additions & 0 deletions internal/datastore/postgres/revisions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,11 @@ func TestCombinedRevisionParsing(t *testing.T) {
}
}

func TestBrokenInvalidRevision(t *testing.T) {
_, err := parseRevision("1693540940373045727.0000000001")
require.Error(t, err)
}

func FuzzRevision(f *testing.F) {
// Attempt to find a decimal revision that is a valid base64 encoded proto revision
f.Add(uint64(0), -1)
Expand Down
12 changes: 12 additions & 0 deletions pkg/zedtoken/zedtoken_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,18 @@ var decodeTests = []struct {
expectedRevision: decimal.New(12345, -2),
expectError: false,
},
{
format: "V1 ZedToken",
token: "GiAKHjE2OTM1NDA5NDAzNzMwNDU3MjcuMDAwMDAwMDAwMQ==",
expectedRevision: (func() decimal.Decimal {
v, err := decimal.NewFromString("1693540940373045727.0000000001")
if err != nil {
panic(err)
}
return v
})(),
expectError: false,
},
}

func TestDecode(t *testing.T) {
Expand Down

0 comments on commit 9c685f9

Please sign in to comment.