20
0

fix open encrypted file OOM bug, return FileIsEncrpytedErr if file is encrypted

This commit is contained in:
Jeff.JF Lin(林勁甫) 2020-10-21 17:06:43 +08:00
parent 4a6cf26307
commit 35ae9246d6
4 changed files with 27 additions and 6 deletions

BIN
Encrypted.xls Normal file

Binary file not shown.

View File

@ -3,12 +3,16 @@ package xls
import ( import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"golang.org/x/text/encoding/charmap" "errors"
"io" "io"
"os" "os"
"unicode/utf16" "unicode/utf16"
"golang.org/x/text/encoding/charmap"
) )
var FileIsEncryptedError = errors.New("File is encrypted")
//xls workbook type //xls workbook type
type WorkBook struct { type WorkBook struct {
Is5ver bool Is5ver bool
@ -29,28 +33,39 @@ type WorkBook struct {
} }
//read workbook from ole2 file //read workbook from ole2 file
func newWorkBookFromOle2(rs io.ReadSeeker) *WorkBook { func newWorkBookFromOle2(rs io.ReadSeeker) (*WorkBook, error) {
wb := new(WorkBook) wb := new(WorkBook)
wb.Formats = make(map[uint16]*Format) wb.Formats = make(map[uint16]*Format)
// wb.bts = bts // wb.bts = bts
wb.rs = rs wb.rs = rs
wb.sheets = make([]*WorkSheet, 0) wb.sheets = make([]*WorkSheet, 0)
wb.Parse(rs) if err := wb.Parse(rs); err != nil {
return wb return nil, err
}
return wb, nil
} }
func (w *WorkBook) Parse(buf io.ReadSeeker) { func (w *WorkBook) Parse(buf io.ReadSeeker) error {
b := new(bof) b := new(bof)
bof_pre := new(bof) bof_pre := new(bof)
// buf := bytes.NewReader(bts) // buf := bytes.NewReader(bts)
offset := 0 offset := 0
for { for {
if err := binary.Read(buf, binary.LittleEndian, b); err == nil { if err := binary.Read(buf, binary.LittleEndian, b); err == nil {
// if read in a FilePass record which indicated by 0x2f, then thisl file is encrypted.
// return FileIsEncryptedError here because we still aren't able to decode the file now.
// ref: https://stackoverflow.com/questions/25422599/parse-xls-file-with-protected-protected-workbook
// https://www.openoffice.org/sc/excelfileformat.pdf
if b.Id == 0x2f {
return FileIsEncryptedError
}
bof_pre, b, offset = w.parseBof(buf, b, bof_pre, offset) bof_pre, b, offset = w.parseBof(buf, b, bof_pre, offset)
} else { } else {
break break
} }
} }
return nil
} }
func (w *WorkBook) addXf(xf st_xf_data) { func (w *WorkBook) addXf(xf st_xf_data) {

2
xls.go
View File

@ -52,7 +52,7 @@ func OpenReader(reader io.ReadSeeker, charset string) (wb *WorkBook, err error)
} }
} }
if book != nil { if book != nil {
wb = newWorkBookFromOle2(ole.OpenFile(book, root)) wb, err = newWorkBookFromOle2(ole.OpenFile(book, root))
return return
} }
} }

View File

@ -3,8 +3,14 @@ package xls
import ( import (
"fmt" "fmt"
"testing" "testing"
"github.com/stretchr/testify/assert"
) )
func TestOpenEncryptedFile(t *testing.T) {
_, err := Open("Encrypted.xls", "utf-8")
assert.Equal(t, FileIsEncryptedError, err)
}
func TestOpen(t *testing.T) { func TestOpen(t *testing.T) {
if xlFile, err := Open("t1.xls", "utf-8"); err == nil { if xlFile, err := Open("t1.xls", "utf-8"); err == nil {
if sheet1 := xlFile.GetSheet(0); sheet1 != nil { if sheet1 := xlFile.GetSheet(0); sheet1 != nil {