xlsReader
xlsReader copied to clipboard
Memory leak occurred while reading a corrupted file
When the program parses some corrupt Excel files, a memory overflow occurs, causing an error in the program。
Error like:
goroutine 68 [running]:
runtime.systemstack_switch()
runtime/asm_amd64.s:459 fp=0xc0008136e0 sp=0xc0008136d8 pc=0x468140
runtime.(*mheap).alloc(0x1fd980000?, 0xfecc0?, 0x80?)
runtime/mheap.go:904 +0x65 fp=0xc000813728 sp=0xc0008136e0 pc=0x427805
runtime.(*mcache).allocLarge(0x200?, 0x1fd980000, 0x1)
runtime/mcache.go:233 +0x85 fp=0xc000813778 sp=0xc000813728 pc=0x416b45
runtime.mallocgc(0x1fd980000, 0x0, 0x0)
runtime/malloc.go:1029 +0x57e fp=0xc0008137f0 sp=0xc000813778 pc=0x40cf7e
runtime.growslice(0xc000318000?, {0xc0994fe000?, 0xc0008138c8?, 0x82daec?}, 0xc000813978?)
runtime/slice.go:284 +0x4ac fp=0xc000813858 sp=0xc0008137f0 pc=0x44ea2c
github.com/shakinm/xlsReader/cfb.(*Cfb).getDataFromFatChain(0xc000318000, 0x80?)
github.com/shakinm/[email protected]/cfb/cfb.go:263 +0x105 fp=0xc0008138f0 sp=0xc000813858 pc=0x82e265
github.com/shakinm/xlsReader/cfb.(*Cfb).getDirectories(0xc000318000)
github.com/shakinm/[email protected]/cfb/cfb.go:108 +0x36 fp=0xc0008139a8 sp=0xc0008138f0 pc=0x82d316
github.com/shakinm/xlsReader/cfb.open(0xe11ab1a1e011cfd0?)
github.com/shakinm/[email protected]/cfb/cfb.go:80 +0x59 fp=0xc0008139c8 sp=0xc0008139a8 pc=0x82d179
github.com/shakinm/xlsReader/cfb.OpenReader(...)
You can downlaod example file here: corrupt.xls
I'm not familiar with the XLS protocol, but the following code solves my problem:
func (cfb *Cfb) getDataFromFatChain(offset uint32) (data []byte, err error) {
for {
sector := NewSector(&cfb.header)
point := cfb.sectorOffset(offset)
err = cfb.getData(point, §or.Data)
if err != nil {
return data, err
}
data = append(data, sector.Data...)
// try to fixed index out of range
if offset >= uint32(len(cfb.difatPositions)) {
return data, errors.New("corrupted file: index out of range")
}
offset = cfb.difatPositions[offset]
// try to fixed dead cycle loop, this may cause memory leak
// []uint32 len: 128, cap: 128, [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,0,0,0,0,0,0,...+64 more]
if len(data) > 0 && offset == 0 {
return data, errors.New("corrupted file")
}
if offset == helpers.BytesToUint32(ENDOFCHAIN) {
break
}
}
return data, err
}