Skip to content

Commit

Permalink
recover from string tables that cannot be parsed
Browse files Browse the repository at this point in the history
  • Loading branch information
jcoene committed Jun 13, 2018
1 parent 991d310 commit 0127c68
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 12 deletions.
9 changes: 9 additions & 0 deletions manta_test.go
Expand Up @@ -13,6 +13,7 @@ func BenchmarkMatch2159568145(b *testing.B) { testScenarios[2159568145].bench(b)
// Test client
func TestMatch6682694(t *testing.T) { testScenarios[6682694].test(t) }

func TestMatch3949386909(t *testing.T) { testScenarios[3949386909].test(t) }
func TestMatch3777736409(t *testing.T) { testScenarios[3777736409].test(t) }
func TestMatch3534483793(t *testing.T) { testScenarios[3534483793].test(t) }
func TestMatch3220517753(t *testing.T) { testScenarios[3220517753].test(t) }
Expand Down Expand Up @@ -64,6 +65,14 @@ type testScenario struct {
}

var testScenarios = map[int64]testScenario{
3949386909: {
matchId: "3949386909",
replayUrl: "https://s3-us-west-2.amazonaws.com/manta.dotabuff/3949386909.dem",
expectGameBuild: 2956,
expectEntityEvents: 3339557,
expectUnitOrderEvents: 77975,
},

3777736409: {
matchId: "3777736409",
replayUrl: "https://s3-us-west-2.amazonaws.com/manta.dotabuff/3777736409.dem",
Expand Down
29 changes: 19 additions & 10 deletions string_table.go
Expand Up @@ -43,6 +43,7 @@ type stringTable struct {
Items map[int32]*stringTableItem
userDataFixedSize bool
userDataSize int32
flags int32
}

func (st *stringTable) GetIndex() int32 { return st.index }
Expand Down Expand Up @@ -75,6 +76,7 @@ func (p *Parser) onCSVCMsg_CreateStringTable(m *dota.CSVCMsg_CreateStringTable)
Items: make(map[int32]*stringTableItem),
userDataFixedSize: m.GetUserDataFixedSize(),
userDataSize: m.GetUserDataSize(),
flags: m.GetFlags(),
}

// Increment the index
Expand All @@ -101,7 +103,7 @@ func (p *Parser) onCSVCMsg_CreateStringTable(m *dota.CSVCMsg_CreateStringTable)
}

// Parse the items out of the string table data
items := parseStringTable(buf, m.GetNumEntries(), t.userDataFixedSize, t.userDataSize)
items := parseStringTable(buf, m.GetNumEntries(), t.name, t.userDataFixedSize, t.userDataSize, t.flags)

// Insert the items into the table
for _, item := range items {
Expand Down Expand Up @@ -133,7 +135,7 @@ func (p *Parser) onCSVCMsg_UpdateStringTable(m *dota.CSVCMsg_UpdateStringTable)
}

// Parse the updates out of the string table data
items := parseStringTable(m.GetStringData(), m.GetNumChangedEntries(), t.userDataFixedSize, t.userDataSize)
items := parseStringTable(m.GetStringData(), m.GetNumChangedEntries(), t.name, t.userDataFixedSize, t.userDataSize, t.flags)

// Apply the updates to the parser state
for _, item := range items {
Expand All @@ -159,7 +161,14 @@ func (p *Parser) onCSVCMsg_UpdateStringTable(m *dota.CSVCMsg_UpdateStringTable)
}

// Parse a string table data blob, returning a list of item updates.
func parseStringTable(buf []byte, numUpdates int32, userDataFixed bool, userDataSize int32) (items []*stringTableItem) {
func parseStringTable(buf []byte, numUpdates int32, name string, userDataFixed bool, userDataSize int32, flags int32) (items []*stringTableItem) {
defer func() {
if err := recover(); err != nil {
_printf("warning: unable to parse string table %s: %s", name, err)
return
}
}()

items = make([]*stringTableItem, 0)

// Create a reader for the buffer
Expand Down Expand Up @@ -239,16 +248,16 @@ func parseStringTable(buf []byte, numUpdates int32, userDataFixed bool, userData
// Some entries have a value.
hasValue := r.readBoolean()
if hasValue {
// Values can be either fixed size (with a size specified in
// bits during table creation, or have a variable size with
// a 14-bit prefixed size.
bitSize := uint32(0)
if userDataFixed {
value = r.readBitsAsBytes(uint32(userDataSize))
bitSize = uint32(userDataSize)
} else {
size := r.readBits(14)
r.readBits(3) // XXX TODO: what is this?
value = r.readBytes(size)
if (flags & 0x1) != 0 {
r.readBoolean()
}
bitSize = r.readBits(17) * 8
}
value = r.readBitsAsBytes(bitSize)
}

items = append(items, &stringTableItem{index, key, value})
Expand Down
4 changes: 2 additions & 2 deletions string_table_test.go
Expand Up @@ -138,7 +138,7 @@ func TestParseStringTableCreate(t *testing.T) {
assert.Equal(s.tableName, m.GetName(), s.tableName)

// Parse the table data
items := parseStringTable(buf, m.GetNumEntries(), m.GetUserDataFixedSize(), m.GetUserDataSize())
items := parseStringTable(buf, m.GetNumEntries(), "", m.GetUserDataFixedSize(), m.GetUserDataSize(), m.GetFlags())

// Make sure we have the correct number of entries
assert.Equal(s.itemCount, len(items), s.tableName)
Expand All @@ -157,7 +157,7 @@ func TestParseStringTableUpdate(t *testing.T) {
assert := assert.New(t)
buf := _read_fixture("string_tables/updates/tick_03960_table_7_items_13_size_208")

items := parseStringTable(buf, 13, false, 0)
items := parseStringTable(buf, 13, "", false, 0, 0)

assert.Equal(int32(261), items[0].Index)
assert.Equal("broodmother_spawn_spiderlings", items[0].Key)
Expand Down

0 comments on commit 0127c68

Please sign in to comment.