Skip to content

Commit d8cab2a

Browse files
committed
Fix incorrect byte check in NewRangeScannerFragment
1 parent e54a196 commit d8cab2a

File tree

2 files changed

+56
-7
lines changed

2 files changed

+56
-7
lines changed

pos_scanner.go

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,11 @@ type RangeScanner struct {
2626
b []byte
2727
cb bufio.SplitFunc
2828

29-
pos Pos // position of next byte to process in b
30-
cur Range // latest range
31-
tok []byte // slice of b that is covered by cur
32-
err error // error from last scan, if any
29+
start Pos // position of first byte
30+
pos Pos // position of next byte to process
31+
cur Range // latest range
32+
tok []byte // slice of b that is covered by cur
33+
err error // error from last scan, if any
3334
}
3435

3536
// NewRangeScanner creates a new RangeScanner for the given buffer, producing
@@ -55,19 +56,22 @@ func NewRangeScannerFragment(b []byte, filename string, start Pos, cb bufio.Spli
5556
b: b,
5657
cb: cb,
5758
pos: start,
59+
start: start,
5860
}
5961
}
6062

6163
func (sc *RangeScanner) Scan() bool {
62-
if sc.pos.Byte >= len(sc.b) || sc.err != nil {
64+
currentByte := sc.pos.Byte - sc.start.Byte
65+
66+
if currentByte >= len(sc.b) || sc.err != nil {
6367
// All done
6468
return false
6569
}
6670

6771
// Since we're operating on an in-memory buffer, we always pass the whole
6872
// remainder of the buffer to our SplitFunc and set isEOF to let it know
6973
// that it has the whole thing.
70-
advance, token, err := sc.cb(sc.b[sc.pos.Byte:], true)
74+
advance, token, err := sc.cb(sc.b[currentByte:], true)
7175

7276
// Since we are setting isEOF to true this should never happen, but
7377
// if it does we will just abort and assume the SplitFunc is misbehaving.
@@ -95,7 +99,7 @@ func (sc *RangeScanner) Scan() bool {
9599
// we're being asked to skip over by the SplitFunc.
96100
// adv is a slice covering any additional bytes we are skipping over, based
97101
// on what the SplitFunc told us to do with advance.
98-
adv := sc.b[sc.pos.Byte : sc.pos.Byte+advance]
102+
adv := sc.b[currentByte : currentByte+advance]
99103

100104
// We now need to scan over our token to count the grapheme clusters
101105
// so we can correctly advance Column, and count the newlines so we

pos_scanner_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,3 +194,48 @@ func TestPosScanner(t *testing.T) {
194194
})
195195
}
196196
}
197+
198+
func TestPosScannerFragment(t *testing.T) {
199+
tests := map[string]struct {
200+
Input string
201+
Start Pos
202+
Want []Range
203+
WantToks [][]byte
204+
}{
205+
"single line": {
206+
"hello",
207+
Pos{Byte: 10, Line: 2, Column: 1},
208+
[]Range{
209+
{
210+
Start: Pos{Byte: 10, Line: 2, Column: 1},
211+
End: Pos{Byte: 15, Line: 2, Column: 6},
212+
},
213+
},
214+
[][]byte{
215+
[]byte("hello"),
216+
},
217+
},
218+
}
219+
220+
for name, test := range tests {
221+
t.Run(name, func(t *testing.T) {
222+
src := []byte(test.Input)
223+
sc := NewRangeScannerFragment(src, "", test.Start, bufio.ScanLines)
224+
got := make([]Range, 0)
225+
gotToks := make([][]byte, 0)
226+
for sc.Scan() {
227+
got = append(got, sc.Range())
228+
gotToks = append(gotToks, sc.Bytes())
229+
}
230+
if sc.Err() != nil {
231+
t.Fatalf("unexpected error: %s", sc.Err())
232+
}
233+
if !reflect.DeepEqual(got, test.Want) {
234+
t.Errorf("incorrect ranges\ngot: %swant: %s", spew.Sdump(got), spew.Sdump(test.Want))
235+
}
236+
if !reflect.DeepEqual(gotToks, test.WantToks) {
237+
t.Errorf("incorrect tokens\ngot: %swant: %s", spew.Sdump(gotToks), spew.Sdump(test.WantToks))
238+
}
239+
})
240+
}
241+
}

0 commit comments

Comments
 (0)