From 7c9dd9fc4a1d38a9d669fa50decd5696f446d55e Mon Sep 17 00:00:00 2001 From: Abhinav Dangeti Date: Tue, 22 Feb 2022 14:20:55 -0700 Subject: [PATCH] Place bounds check within memUvarintReader's ReadUvarint This bounds check is to return an empty uint64 while decoding a 64-bit integer, should the reader have already read all the bytes available. For: https://github.com/blevesearch/bleve/issues/1651 ``` Some context on the memUvarintReader .. The code here reflects ReadUVarint(..) from https://cs.opensource.google/go/go/+/refs/tags/go1.13.7:src/encoding/binary/varint.go But as reported here: https://github.com/golang/go/issues/40618, it appears it contained an error prone path that was addressed in 1.15. ``` --- memuvarint.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/memuvarint.go b/memuvarint.go index 0c10c83..b083ade 100644 --- a/memuvarint.go +++ b/memuvarint.go @@ -44,6 +44,11 @@ func (r *memUvarintReader) ReadUvarint() (uint64, error) { var C = r.C var S = r.S + if C >= len(S) { + // nothing else to read + return 0, nil + } + for { b := S[C] C++ @@ -59,7 +64,7 @@ func (r *memUvarintReader) ReadUvarint() (uint64, error) { // why the "extra" >= check? The normal case is that s < // 63, so we check this single >= guard first so that we // hit the normal, nil-error return pathway sooner. - if s >= 63 && (s > 63 || s == 63 && b > 1) { + if s >= 63 && (s > 63 || b > 1) { return 0, fmt.Errorf("memUvarintReader overflow") } @@ -74,6 +79,10 @@ func (r *memUvarintReader) ReadUvarint() (uint64, error) { // SkipUvarint skips ahead one encoded uint64. func (r *memUvarintReader) SkipUvarint() { for { + if r.C >= len(r.S) { + return + } + b := r.S[r.C] r.C++