Browse code

pkg/tarsum: fix panic with dynamic buffer

When read is called on a tarsum with a two different read sizes, specifically the second call larger than the first, the dynamic buffer does not get reallocated causing a slice read error.

Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)

Derek McGowan authored on 2014/09/26 07:58:35
Showing 2 changed files
... ...
@@ -179,7 +179,7 @@ func (ts *tarSum) Read(buf []byte) (int, error) {
179 179
 	if ts.finished {
180 180
 		return ts.bufWriter.Read(buf)
181 181
 	}
182
-	if ts.bufData == nil {
182
+	if len(ts.bufData) < len(buf) {
183 183
 		switch {
184 184
 		case len(buf) <= buf8K:
185 185
 			ts.bufData = make([]byte, buf8K)
... ...
@@ -191,7 +191,7 @@ func (ts *tarSum) Read(buf []byte) (int, error) {
191 191
 			ts.bufData = make([]byte, len(buf))
192 192
 		}
193 193
 	}
194
-	buf2 := ts.bufData[:len(buf)-1]
194
+	buf2 := ts.bufData[:len(buf)]
195 195
 
196 196
 	n, err := ts.tarR.Read(buf2)
197 197
 	if err != nil {
... ...
@@ -274,6 +274,22 @@ func TestTarSums(t *testing.T) {
274 274
 			t.Errorf("%q :: %q", err, layer.filename)
275 275
 			continue
276 276
 		}
277
+
278
+		// Read variable number of bytes to test dynamic buffer
279
+		dBuf := make([]byte, 1)
280
+		_, err = ts.Read(dBuf)
281
+		if err != nil {
282
+			t.Errorf("failed to read 1B from %s: %s", layer.filename, err)
283
+			continue
284
+		}
285
+		dBuf = make([]byte, 16*1024)
286
+		_, err = ts.Read(dBuf)
287
+		if err != nil {
288
+			t.Errorf("failed to read 16KB from %s: %s", layer.filename, err)
289
+			continue
290
+		}
291
+
292
+		// Read and discard remaining bytes
277 293
 		_, err = io.Copy(ioutil.Discard, ts)
278 294
 		if err != nil {
279 295
 			t.Errorf("failed to copy from %s: %s", layer.filename, err)