1
0
mirror of https://github.com/pbnjay/grate.git synced 2026-05-16 09:08:09 +02:00

handle uint32s better

This commit is contained in:
Jeremy Jay
2021-02-09 13:59:58 -05:00
parent 1c0ac5b92c
commit 4848de04e3
2 changed files with 47 additions and 29 deletions
+1 -2
View File
@@ -11,7 +11,6 @@ import (
) )
func decodeHyperlinks(r io.Reader) (displayText, linkText string, err error) { func decodeHyperlinks(r io.Reader) (displayText, linkText string, err error) {
var x uint64 var x uint64
binary.Read(r, binary.LittleEndian, &x) // skip and discard classid binary.Read(r, binary.LittleEndian, &x) // skip and discard classid
binary.Read(r, binary.LittleEndian, &x) binary.Read(r, binary.LittleEndian, &x)
@@ -113,7 +112,7 @@ func parseHyperlinkMoniker(r io.Reader) (string, error) {
if length > 0 { if length > 0 {
io.CopyN(ioutil.Discard, r, 6) io.CopyN(ioutil.Discard, r, 6)
length -= 6 length -= 6
buf2 := make([]uint16, (length-6)/2) buf2 := make([]uint16, length/2)
binary.Read(r, binary.LittleEndian, &buf2) binary.Read(r, binary.LittleEndian, &buf2)
return string(utf16.Decode(buf2)), nil return string(utf16.Decode(buf2)), nil
} }
+46 -27
View File
@@ -41,8 +41,11 @@ type WorkSheet struct {
ss int ss int
err error err error
minRow uint32
maxRow uint32
minCol uint16
maxCol uint16
rows []*row rows []*row
maxcol int
empty bool empty bool
iterRow int iterRow int
@@ -78,19 +81,15 @@ type row struct {
} }
func (s *WorkSheet) placeValue(rowIndex, colIndex int, val interface{}) { func (s *WorkSheet) placeValue(rowIndex, colIndex int, val interface{}) {
// ensure we always have a complete matrix if colIndex > int(s.maxCol) || rowIndex > int(s.maxRow) {
if s.maxcol <= colIndex { // invalid
s.maxcol = colIndex + 1 return
for _, r := range s.rows {
for len(r.cols) <= colIndex {
r.cols = append(r.cols, staticBlank)
}
}
} }
// ensure we always have a complete matrix
for len(s.rows) <= rowIndex { for len(s.rows) <= rowIndex {
emptyRow := make([]interface{}, s.maxcol) emptyRow := make([]interface{}, s.maxCol)
for i := 0; i < s.maxcol; i++ { for i := 0; i < int(s.maxCol); i++ {
emptyRow[i] = staticBlank emptyRow[i] = staticBlank
} }
s.rows = append(s.rows, &row{emptyRow}) s.rows = append(s.rows, &row{emptyRow})
@@ -104,8 +103,6 @@ func (s *WorkSheet) IsEmpty() bool {
} }
func (s *WorkSheet) parse() error { func (s *WorkSheet) parse() error {
var minRow, maxRow uint32
var minCol, maxCol uint16
for _, r := range s.b.substreams[s.ss] { for _, r := range s.b.substreams[s.ss] {
if r.RecType == RecTypeWsBool { if r.RecType == RecTypeWsBool {
if (r.Data[1] & 0x10) != 0 { if (r.Data[1] & 0x10) != 0 {
@@ -133,19 +130,24 @@ func (s *WorkSheet) parse() error {
switch r.RecType { switch r.RecType {
case RecTypeDimensions: case RecTypeDimensions:
binary.Read(bb, binary.LittleEndian, &minRow) binary.Read(bb, binary.LittleEndian, &s.minRow)
binary.Read(bb, binary.LittleEndian, &maxRow) binary.Read(bb, binary.LittleEndian, &s.maxRow)
binary.Read(bb, binary.LittleEndian, &minCol) binary.Read(bb, binary.LittleEndian, &s.minCol)
binary.Read(bb, binary.LittleEndian, &maxCol) binary.Read(bb, binary.LittleEndian, &s.maxCol)
//log.Printf("dimensions: %d,%d + %dx%d", minRow&0x0000FFFF, minCol, //log.Printf("dimensions: %d,%d + %dx%d", s.minRow&0x0000FFFF, s.minCol,
// (maxRow&0x0000FFFF)-(minRow&0x0000FFFF), maxCol-minCol) // (s.maxRow&0x0000FFFF)-(s.minRow&0x0000FFFF), s.maxCol-s.minCol)
if minRow > 0x0000FFFF || maxRow > 0x00010000 { if s.minRow > 0x0000FFFF || s.maxRow > 0x00010000 {
log.Println("invalid dimensions") log.Println("invalid dimensions")
} }
if minCol > 0x00FF || maxCol > 0x0100 { if s.minCol > 0x00FF || s.maxCol > 0x0100 {
log.Println("invalid dimensions") log.Println("invalid dimensions")
} }
if (maxRow-minRow) == 0 && (maxCol-minCol) == 0 { s.minRow &= 0xFFFF
s.maxRow &= 0xFFFF
s.minCol &= 0x00FF
s.maxCol &= 0x00FF
if (s.maxRow-s.minRow) == 0 && (s.maxCol-s.minCol) == 0 {
s.empty = true s.empty = true
} }
@@ -330,17 +332,20 @@ func (s *WorkSheet) parse() error {
case RecTypeHLink: case RecTypeHLink:
loc := &shRef8{} loc := &shRef8{}
binary.Read(bb, binary.LittleEndian, loc) binary.Read(bb, binary.LittleEndian, loc)
loc.FirstCol &= 0x00FF // spec doesn't say what to do when MUST is disregarded... if loc.FirstCol > s.maxCol {
loc.LastCol &= 0x00FF
if loc.FirstCol > maxCol {
//log.Println("invalid hyperlink column") //log.Println("invalid hyperlink column")
continue continue
} }
if uint32(loc.FirstRow) > maxRow { if uint32(loc.FirstRow) > s.maxRow {
//log.Println("invalid hyperlink row") //log.Println("invalid hyperlink row")
continue continue
} }
if loc.LastRow == 0xFFFF {
loc.LastRow = uint16(s.maxRow)
}
if loc.LastCol == 0xFF {
loc.LastCol = s.maxCol
}
displayText, linkText, err := decodeHyperlinks(bb) displayText, linkText, err := decodeHyperlinks(bb)
if err != nil { if err != nil {
@@ -367,6 +372,10 @@ func (s *WorkSheet) parse() error {
s.placeValue(int(rn), int(cn), continueColumnMerged) s.placeValue(int(rn), int(cn), continueColumnMerged)
} }
} }
if rn == 0xFFFF {
// uint32s are fun
break
}
} }
case RecTypeMergeCells: case RecTypeMergeCells:
@@ -375,6 +384,12 @@ func (s *WorkSheet) parse() error {
mcRefs := make([]shRef8, cmcs) mcRefs := make([]shRef8, cmcs)
binary.Read(bb, binary.LittleEndian, &mcRefs) binary.Read(bb, binary.LittleEndian, &mcRefs)
for _, loc := range mcRefs { for _, loc := range mcRefs {
if loc.LastRow == 0xFFFF {
loc.LastRow = uint16(s.maxRow)
}
if loc.LastCol == 0xFF {
loc.LastCol = s.maxCol
}
for rn := loc.FirstRow; rn <= loc.LastRow; rn++ { for rn := loc.FirstRow; rn <= loc.LastRow; rn++ {
for cn := loc.FirstCol; cn <= loc.LastCol; cn++ { for cn := loc.FirstCol; cn <= loc.LastCol; cn++ {
if rn == loc.FirstRow && cn == loc.FirstCol { if rn == loc.FirstRow && cn == loc.FirstCol {
@@ -393,6 +408,10 @@ func (s *WorkSheet) parse() error {
s.placeValue(int(rn), int(cn), continueColumnMerged) s.placeValue(int(rn), int(cn), continueColumnMerged)
} }
} }
if rn == 0xFFFF {
// uint32s are fun
break
}
} }
} }