diff --git a/Encrypted.xls b/Encrypted.xls new file mode 100644 index 0000000..12927f2 Binary files /dev/null and b/Encrypted.xls differ diff --git a/workbook.go b/workbook.go index f917d53..82df4da 100644 --- a/workbook.go +++ b/workbook.go @@ -3,12 +3,16 @@ package xls import ( "bytes" "encoding/binary" - "golang.org/x/text/encoding/charmap" + "errors" "io" "os" "unicode/utf16" + + "golang.org/x/text/encoding/charmap" ) +var FileIsEncryptedError = errors.New("File is encrypted") + //xls workbook type type WorkBook struct { Is5ver bool @@ -29,28 +33,39 @@ type WorkBook struct { } //read workbook from ole2 file -func newWorkBookFromOle2(rs io.ReadSeeker) *WorkBook { +func newWorkBookFromOle2(rs io.ReadSeeker) (*WorkBook, error) { wb := new(WorkBook) wb.Formats = make(map[uint16]*Format) // wb.bts = bts wb.rs = rs wb.sheets = make([]*WorkSheet, 0) - wb.Parse(rs) - return wb + if err := wb.Parse(rs); err != nil { + return nil, err + } + return wb, nil } -func (w *WorkBook) Parse(buf io.ReadSeeker) { +func (w *WorkBook) Parse(buf io.ReadSeeker) error { b := new(bof) bof_pre := new(bof) // buf := bytes.NewReader(bts) offset := 0 for { 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) } else { break } } + + return nil } func (w *WorkBook) addXf(xf st_xf_data) { diff --git a/xls.go b/xls.go index 158d749..49eff16 100644 --- a/xls.go +++ b/xls.go @@ -52,7 +52,7 @@ func OpenReader(reader io.ReadSeeker, charset string) (wb *WorkBook, err error) } } if book != nil { - wb = newWorkBookFromOle2(ole.OpenFile(book, root)) + wb, err = newWorkBookFromOle2(ole.OpenFile(book, root)) return } } diff --git a/xls_test.go b/xls_test.go index 57c809c..a46b8c8 100644 --- a/xls_test.go +++ b/xls_test.go @@ -3,8 +3,14 @@ package xls import ( "fmt" "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) { if xlFile, err := Open("t1.xls", "utf-8"); err == nil { if sheet1 := xlFile.GetSheet(0); sheet1 != nil {