mirror of
https://bitbucket.org/s_l_teichmann/mtsatellite
synced 2024-11-08 11:10:27 +01:00
Do more boundary checks in block decoding.
This commit is contained in:
parent
011cd0e4f4
commit
08031f1dcd
|
@ -19,6 +19,7 @@ import (
|
||||||
var (
|
var (
|
||||||
ErrNoMoreBlocks = errors.New("No more blocks.")
|
ErrNoMoreBlocks = errors.New("No more blocks.")
|
||||||
ErrMapContentSizeMismatch = errors.New("Content size does not match.")
|
ErrMapContentSizeMismatch = errors.New("Content size does not match.")
|
||||||
|
ErrBlockTruncated = errors.New("Block is truncated.")
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -91,6 +92,12 @@ type posBuf struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDecodedBlock(data []byte, colors *Colors) (db *DecodedBlock, err error) {
|
func NewDecodedBlock(data []byte, colors *Colors) (db *DecodedBlock, err error) {
|
||||||
|
|
||||||
|
dataLen := len(data)
|
||||||
|
if dataLen < 4 {
|
||||||
|
return nil, ErrBlockTruncated
|
||||||
|
}
|
||||||
|
|
||||||
version := data[0]
|
version := data[0]
|
||||||
|
|
||||||
contentWidth := int(data[2])
|
contentWidth := int(data[2])
|
||||||
|
@ -132,6 +139,9 @@ func NewDecodedBlock(data []byte, colors *Colors) (db *DecodedBlock, err error)
|
||||||
|
|
||||||
offset += buf.Pos + 4
|
offset += buf.Pos + 4
|
||||||
buf.Pos = 0
|
buf.Pos = 0
|
||||||
|
if offset >= dataLen {
|
||||||
|
return nil, ErrBlockTruncated
|
||||||
|
}
|
||||||
buf.Data = data[offset:]
|
buf.Data = data[offset:]
|
||||||
|
|
||||||
if err = zr.(zlib.Resetter).Reset(&buf, nil); err != nil {
|
if err = zr.(zlib.Resetter).Reset(&buf, nil); err != nil {
|
||||||
|
@ -151,19 +161,31 @@ func NewDecodedBlock(data []byte, colors *Colors) (db *DecodedBlock, err error)
|
||||||
case version == 23:
|
case version == 23:
|
||||||
offset++
|
offset++
|
||||||
case version == 24:
|
case version == 24:
|
||||||
|
if offset >= dataLen {
|
||||||
|
return nil, ErrBlockTruncated
|
||||||
|
}
|
||||||
ver := data[offset]
|
ver := data[offset]
|
||||||
offset++
|
offset++
|
||||||
if ver == 1 {
|
if ver == 1 {
|
||||||
|
if offset+1 >= dataLen {
|
||||||
|
return nil, ErrBlockTruncated
|
||||||
|
}
|
||||||
num := int(binary.BigEndian.Uint16(data[offset:]))
|
num := int(binary.BigEndian.Uint16(data[offset:]))
|
||||||
offset += 2 + 10*num
|
offset += 2 + 10*num
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
offset++
|
offset++
|
||||||
|
if offset+1 >= dataLen {
|
||||||
|
return nil, ErrBlockTruncated
|
||||||
|
}
|
||||||
numStaticObjects := int(binary.BigEndian.Uint16(data[offset:]))
|
numStaticObjects := int(binary.BigEndian.Uint16(data[offset:]))
|
||||||
offset += 2
|
offset += 2
|
||||||
for i := 0; i < numStaticObjects; i++ {
|
for i := 0; i < numStaticObjects; i++ {
|
||||||
offset += 13
|
offset += 13
|
||||||
|
if offset+1 >= dataLen {
|
||||||
|
return nil, ErrBlockTruncated
|
||||||
|
}
|
||||||
dataSize := int(binary.BigEndian.Uint16(data[offset:]))
|
dataSize := int(binary.BigEndian.Uint16(data[offset:]))
|
||||||
offset += dataSize + 2
|
offset += dataSize + 2
|
||||||
}
|
}
|
||||||
|
@ -174,23 +196,30 @@ func NewDecodedBlock(data []byte, colors *Colors) (db *DecodedBlock, err error)
|
||||||
var transparent bool
|
var transparent bool
|
||||||
if version >= 22 {
|
if version >= 22 {
|
||||||
offset++
|
offset++
|
||||||
|
if offset+1 >= dataLen {
|
||||||
|
return nil, ErrBlockTruncated
|
||||||
|
}
|
||||||
numMappings := int(binary.BigEndian.Uint16(data[offset:]))
|
numMappings := int(binary.BigEndian.Uint16(data[offset:]))
|
||||||
offset += 2
|
offset += 2
|
||||||
|
|
||||||
|
// Be a bit more tolerant with truncated node name table.
|
||||||
|
// We should probably issue an error here, too!?
|
||||||
const outOfBounds = "Offset in node id table out of bounds. Ignored."
|
const outOfBounds = "Offset in node id table out of bounds. Ignored."
|
||||||
for i, n := 0, len(data); i < numMappings; i++ {
|
|
||||||
if offset+1 >= n {
|
for i := 0; i < numMappings; i++ {
|
||||||
|
if offset+1 >= dataLen {
|
||||||
log.Println(outOfBounds)
|
log.Println(outOfBounds)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
nodeId := int32(binary.BigEndian.Uint16(data[offset:]))
|
nodeId := int32(binary.BigEndian.Uint16(data[offset:]))
|
||||||
offset += 2
|
offset += 2
|
||||||
if offset+1 >= n {
|
if offset+1 >= dataLen {
|
||||||
log.Println(outOfBounds)
|
log.Println(outOfBounds)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
nameLen := int(binary.BigEndian.Uint16(data[offset:]))
|
nameLen := int(binary.BigEndian.Uint16(data[offset:]))
|
||||||
offset += 2
|
offset += 2
|
||||||
if offset+nameLen-1 >= n {
|
if offset+nameLen-1 >= dataLen {
|
||||||
log.Println(outOfBounds)
|
log.Println(outOfBounds)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user