Skip to content

Commit

Permalink
bgzf,bgzf/index: prevent ChunkReader overreading when an end is at bl…
Browse files Browse the repository at this point in the history
…ock offset 0

Also fix LastChunk in bgzf.Reader where a zero-length read leave the
chunk with an end offset that is before the begin offset.

Fixes #17.
  • Loading branch information
kortschak committed Sep 18, 2015
1 parent 4d444e3 commit 9ef4716
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 14 deletions.
9 changes: 3 additions & 6 deletions bgzf/index/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,9 @@ func (r *ChunkReader) Read(p []byte) (int, error) {
// blocked mode and so will stop there anyway.
want := int(r.chunks[0].End.Block)
if r.chunks[0].End.Block == 0 && r.chunks[0].End.File > last.End.File {
// Special case for when the current end block offset is zero.
// We pick an arbitrary length (the maximum progression).
// Because we must move past the current bgzf block to get
// to the current chunk end this is safe since the bgzf
// Reader is in blocked mode.
want = len(p)
// Special case for when the current end block offset
// is zero.
want = r.r.BlockLen()
}
var cursor int
if last.End.File == r.chunks[0].End.File {
Expand Down
6 changes: 1 addition & 5 deletions bgzf/index/index_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,13 +265,9 @@ func (s *S) TestIssue10(c *check.C) {

var got bytes.Buffer
io.Copy(&got, cr)
gotString := got.String()
c.Check(strings.Contains(gotString, want), check.Equals, true,
c.Check(got.String(), check.Equals, want,
check.Commentf("clean=%t merge=%t trunc=%t chunks=%+v", clean, strategy != nil, truncFinal, chunks),
)
if gotString != want {
c.Logf("read over-run clean=%t merge=%t trunc=%t:\n\tgot: %q\n\twant:%q", clean, strategy != nil, truncFinal, gotString, want)
}
}
}
}
Expand Down
9 changes: 6 additions & 3 deletions bgzf/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,10 @@ func (bg *Reader) Seek(off Offset) error {
// seek operation.
func (bg *Reader) LastChunk() Chunk { return bg.lastChunk }

// BlockLen returns the number of bytes remaining to be read from the
// current BGZF block.
func (bg *Reader) BlockLen() int { return bg.current.len() }

// Close closes the reader and releases resources.
func (bg *Reader) Close() error {
if bg.control != nil {
Expand Down Expand Up @@ -521,9 +525,6 @@ func (bg *Reader) Read(p []byte) (int, error) {
for n < len(p) && bg.err == nil {
var _n int
_n, bg.err = bg.current.Read(p[n:])
if _n > 0 {
bg.lastChunk.End = bg.current.txOffset()
}
n += _n
if bg.err == io.EOF {
if n == len(p) {
Expand All @@ -533,6 +534,7 @@ func (bg *Reader) Read(p []byte) (int, error) {

if bg.Blocked {
bg.err = nil
bg.lastChunk.End = bg.current.txOffset()
return n, io.EOF
}

Expand All @@ -543,6 +545,7 @@ func (bg *Reader) Read(p []byte) (int, error) {
}
}

bg.lastChunk.End = bg.current.txOffset()
return n, bg.err
}

Expand Down

0 comments on commit 9ef4716

Please sign in to comment.