A cursor grew its buffer right after reading a chunk into it, so the rest of that chunk was read from the new, empty buffer: the first COUNTIF or MATCH over a whole column with more than eight cells could miss its matches. The buffer now grows before the next chunk is read.
- commit
- e29c1ef868d2cc17b091edd1a8efcd4edbb9dcd0
- parent
- 9c5103ddf0848b6ef75f9d86ddf5d5e2451c90c1
- author
- Dami <dami.etoile@gmail.com>
- kind
- fix risk score 1.0 of 3, Jev's estimate
| M | internal/ | 4 | +++- |
| A | internal/ | 24 | ++++++++++++++++++++++++ |
@@ -228,6 +228,9 @@ func (c *cursor) fill() (Addr, bool) {
228228 if c.from.Row > c.r.To.Row {229229 return Addr{}, false230230 }231+ // Grown here, before the chunk is read: growing makes a new buffer,232+ // which mustn't happen while the last chunk is still being walked.233+ c.b.fit(c.size)231234 c.n, c.i = c.rd.book.Scan(c.sheet, c.r, c.from, c.b.addrs[:c.size], nil), 1232235 if c.n <= 0 {233236 c.from.Row = c.r.To.Row + 1@@ -239,7 +242,6 @@ func (c *cursor) fill() (Addr, bool) {
239242 c.from = next(c.r, c.b.addrs[c.n-1])240243 if c.size < maxChunk {241244 c.size *= 2242- c.b.fit(c.size)243245 }244246 }245247 return c.b.addrs[0], true@@ -0,0 +1,24 @@
1+package sheet2+3+import "testing"4+5+// A criterion's walk over a whole column reads its cells right the first6+// time, when its buffer grows between chunks.7+func TestCriteriaWalkGrowingBuffer(t *testing.T) {8+ s := New()9+ for i := range 12 {10+ lv := "info"11+ if i == 5 {12+ lv = "error"13+ }14+ s.Set(Addr{Col: 1, Row: i}, lv)15+ }16+ s.Set(Addr{Col: 5}, `=COUNTIF(B:B,"error")`)17+ s.Set(Addr{Col: 5, Row: 1}, `=MATCH("error",B:B,0)`)18+ if got := s.Value(Addr{Col: 5}); got.Num != 1 {19+ t.Errorf("COUNTIF = %v, want 1", got)20+ }21+ if got := s.Value(Addr{Col: 5, Row: 1}); got.Num != 6 {22+ t.Errorf("MATCH = %v, want 6", got)23+ }24+}