commit 6389bca04359e19eb3f628cb8ade9ed355fbe25c
parent 7adc22ebe02c3afa146ae1792a41fe17d797ec1e
Author: Tim Culverhouse <tim@timculverhouse.com>
Date: Thu, 23 Mar 2023 16:02:48 -0500
bufio::scan_rune: properly read last 3 bytes
bufio::scan_rune returns io::EOF if it encounters an io::EOF during the
scan_readahead call. However, this call is made when the pending bytes
are < 4. The result is that if you will read EOF when you have 3 bytes
left in the buffer, leaving them unaccessible.
Only return io::EOF if the scan.pending is 0 after the call to
scan_readahead. Add a test for this behavior.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Diffstat:
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/bufio/scanner.ha b/bufio/scanner.ha
@@ -172,7 +172,9 @@ export fn scan_rune(
if (scan.pending == 0) {
match (scan_readahead(scan)?) {
case io::EOF =>
- return io::EOF;
+ if (scan.pending == 0) {
+ return io::EOF;
+ };
case size =>
yield;
};
@@ -210,6 +212,16 @@ export fn scan_rune(
};
};
+@test fn scan_rune() void = {
+ let in = fixed(strings::toutf8("1234"), io::mode::READ);
+ let scan = newscanner(&in, 4);
+ assert(scan_rune(&scan) == '1', "expected '1'");
+ assert(scan_rune(&scan) == '2', "expected '2'");
+ assert(scan_rune(&scan) == '3', "expected '3'");
+ assert(scan_rune(&scan) == '4', "expected '4'");
+ finish(&scan);
+};
+
// Scans a string of text from a [[scanner]] up to some delimiter. The return
// value is borrowed from the internal scanner buffer, which is invalidated
// during subsequent operations which use this scanner.