fix open encrypted file OOM bug, return FileIsEncrpytedErr if file is encrypted
This commit is contained in:
parent
4a6cf26307
commit
35ae9246d6
BIN
Encrypted.xls
Normal file
BIN
Encrypted.xls
Normal file
Binary file not shown.
25
workbook.go
25
workbook.go
@ -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
2
xls.go
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user