diff --git a/common/geodata/geodat_loader.go b/common/geodata/geodat_loader.go index 81d9e7e90..2c8fc8627 100644 --- a/common/geodata/geodat_loader.go +++ b/common/geodata/geodat_loader.go @@ -114,6 +114,9 @@ func decodeVarint(br *bufio.Reader) (uint64, error) { if err != nil { return 0, err } + if shift == 63 && b > 1 { + break // Only one value bit fits in the tenth byte. + } x |= (uint64(b) & 0x7F) << shift if (b & 0x80) == 0 { return x, nil diff --git a/common/geodata/geodat_loader_test.go b/common/geodata/geodat_loader_test.go index b6d400294..42db3b7d1 100644 --- a/common/geodata/geodat_loader_test.go +++ b/common/geodata/geodat_loader_test.go @@ -12,6 +12,22 @@ import ( "google.golang.org/protobuf/proto" ) +func TestLoadFileRejectsVarintOverflow(t *testing.T) { + payload := []byte{ + 0x0a, + 0x86, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x02, // 2^64 + 6 + 0x0a, 0x04, 'T', 'E', 'S', 'T', + } + dir := t.TempDir() + t.Setenv("xray.location.asset", dir) + if err := os.WriteFile(filepath.Join(dir, "overflow.dat"), payload, 0o600); err != nil { + t.Fatal(err) + } + if _, err := loadFile("overflow.dat", "TEST"); err == nil || !strings.Contains(err.Error(), "varint overflow") { + t.Fatalf("want varint overflow, got %v", err) + } +} + type siteEntry struct { Type Domain_Type Value string