Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.

Commit 148d586

Browse files
committed
format: packfile ignores the header if not read
1 parent 45049b5 commit 148d586

File tree

2 files changed

+40
-2
lines changed

2 files changed

+40
-2
lines changed

formats/packfile/parser.go

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ type Scanner struct {
4949

5050
// pendingObject is used to detect if an object has been read, or still
5151
// is waiting to be read
52-
pendingObject *ObjectHeader
52+
pendingObject *ObjectHeader
53+
version, objects uint32
5354
}
5455

5556
// NewParser returns a new Parser that reads from the packfile represented by r.
@@ -70,6 +71,10 @@ func NewScanner(r io.ReadSeeker) *Scanner {
7071
// It returns the version and the object count and performs checks on the
7172
// validity of the signature and the version fields.
7273
func (s *Scanner) Header() (version, objects uint32, err error) {
74+
if s.version != 0 {
75+
return s.version, s.objects, nil
76+
}
77+
7378
sig, err := s.readSignature()
7479
if err != nil {
7580
if err == io.EOF {
@@ -85,6 +90,7 @@ func (s *Scanner) Header() (version, objects uint32, err error) {
8590
}
8691

8792
version, err = s.readVersion()
93+
s.version = version
8894
if err != nil {
8995
return
9096
}
@@ -95,6 +101,7 @@ func (s *Scanner) Header() (version, objects uint32, err error) {
95101
}
96102

97103
objects, err = s.readCount()
104+
s.objects = objects
98105
return
99106
}
100107

@@ -141,7 +148,7 @@ func (s *Scanner) readInt32() (uint32, error) {
141148

142149
// NextObjectHeader returns the ObjectHeader for the next object in the reader
143150
func (s *Scanner) NextObjectHeader() (*ObjectHeader, error) {
144-
if err := s.discardObjectIfNeeded(); err != nil {
151+
if err := s.doPending(); err != nil {
145152
return nil, err
146153
}
147154

@@ -180,6 +187,18 @@ func (s *Scanner) NextObjectHeader() (*ObjectHeader, error) {
180187
return h, nil
181188
}
182189

190+
func (s *Scanner) doPending() error {
191+
if s.version == 0 {
192+
var err error
193+
s.version, s.objects, err = s.Header()
194+
if err != nil {
195+
return err
196+
}
197+
}
198+
199+
return s.discardObjectIfNeeded()
200+
}
201+
183202
func (s *Scanner) discardObjectIfNeeded() error {
184203
if s.pendingObject == nil {
185204
return nil
@@ -275,6 +294,11 @@ func (s *Scanner) copyObject(w io.Writer) (int64, error) {
275294

276295
// Seek sets a new offset from start, returns the old position before the change
277296
func (s *Scanner) Seek(offset int64) (previous int64, err error) {
297+
// if seeking we asume that you are not interested on the header
298+
if s.version == 0 {
299+
s.version = VersionSupported
300+
}
301+
278302
previous, err = s.r.Seek(0, io.SeekCurrent)
279303
if err != nil {
280304
return -1, err

formats/packfile/parser_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,20 @@ func (s *ScannerSuite) TestHeader(c *C) {
2626
c.Assert(objects, Equals, uint32(31))
2727
}
2828

29+
func (s *ScannerSuite) TestNextObjectHeaderWithoutHeader(c *C) {
30+
r := fixtures.Basic().One().Packfile()
31+
p := NewScanner(r)
32+
33+
h, err := p.NextObjectHeader()
34+
c.Assert(err, IsNil)
35+
c.Assert(h, DeepEquals, &expectedHeadersOFS[0])
36+
37+
version, objects, err := p.Header()
38+
c.Assert(err, IsNil)
39+
c.Assert(version, Equals, VersionSupported)
40+
c.Assert(objects, Equals, uint32(31))
41+
}
42+
2943
func (s *ScannerSuite) TestNextObjectHeaderREFDelta(c *C) {
3044
s.testNextObjectHeader(c, "ref-delta", expectedHeadersREF)
3145
}

0 commit comments

Comments
 (0)