@@ -44,6 +44,7 @@ import (
44
44
//
45
45
// data
46
46
// data size
47
+ // previous hash
47
48
48
49
// SimpleReader is a reader for uncompressed image containing hashes.
49
50
type SimpleReader struct {
@@ -59,8 +60,11 @@ type SimpleReader struct {
59
60
// current chunk position
60
61
done uint32
61
62
63
+ // prevHash is the previous hash value.
64
+ prevHash [sha256 .Size ]byte
65
+
62
66
// scratch is a scratch buffer used for reading chunk size and hash values.
63
- scratch [2 * sha256 .Size ]byte
67
+ scratch [sha256 .Size ]byte
64
68
}
65
69
66
70
var _ io.Reader = (* SimpleReader )(nil )
@@ -133,19 +137,22 @@ func (r *SimpleReader) Read(p []byte) (int, error) {
133
137
binary .BigEndian .PutUint32 (r .scratch [:4 ], r .chunkSize )
134
138
r .h .Write (r .scratch [:4 ])
135
139
136
- // Compute the hash into the first 32 bytes of the scratch buffer. Pass a
137
- // 32-byte capacity slice (with 0 length) to avoid allocation.
138
- r .h .Sum (r .scratch [0 :0 :sha256 .Size ])
140
+ // Add previous hash to hash.
141
+ r .h .Write (r .prevHash [:])
142
+
143
+ // Compute the hash into prevHash, now that we don't need the old value.
144
+ // Pass a 32-byte capacity slice (with 0 length) to avoid allocation.
145
+ r .h .Sum (r .prevHash [0 :0 :sha256 .Size ])
139
146
140
- // Read the hash value from the stream into the second 32 bytes of scratch .
141
- if _ , err := io .ReadFull (r .in , r .scratch [sha256 . Size : 2 * sha256 . Size ]); err != nil {
147
+ // Read the hash value from the stream.
148
+ if _ , err := io .ReadFull (r .in , r .scratch [: ]); err != nil {
142
149
if err == io .EOF {
143
150
return n , io .ErrUnexpectedEOF
144
151
}
145
152
return n , err
146
153
}
147
154
148
- if ! hmac .Equal (r .scratch [:sha256 .Size ], r .scratch [ sha256 . Size : 2 * sha256 .Size ]) {
155
+ if ! hmac .Equal (r .scratch [:sha256 .Size ], r .prevHash [: sha256 .Size ]) {
149
156
return n , ErrHashMismatch
150
157
}
151
158
@@ -173,6 +180,9 @@ type SimpleWriter struct {
173
180
// done is the current chunk position.
174
181
done int
175
182
183
+ // prevHash is the previous hash value.
184
+ prevHash [sha256 .Size ]byte
185
+
176
186
// buf is used to buffer the output.
177
187
buf []byte
178
188
@@ -258,13 +268,15 @@ func (w *SimpleWriter) directWrite(p []byte) (int, error) {
258
268
return n , err
259
269
}
260
270
261
- // Write the hash. Compute it by writing the data followed by data size .
271
+ // Write the hash. Compute it as per package comments .
262
272
w .h .Reset ()
263
273
_ , _ = w .h .Write (p )
264
274
_ , _ = w .h .Write (w .buf [:4 ])
265
- // Pass a 32-byte capacity slice (with 0 length) to avoid allocation.
266
- w .h .Sum (w .buf [0 :0 :sha256 .Size ])
267
- _ , err = w .base .Write (w .buf [:sha256 .Size ])
275
+ _ , _ = w .h .Write (w .prevHash [:])
276
+ // Compute the hash into prevHash, now that we don't need the old value.
277
+ // Pass a 32-byte capacity slice (with 0 length) to avoid allocation.
278
+ w .h .Sum (w .prevHash [0 :0 :sha256 .Size ])
279
+ _ , err = w .base .Write (w .prevHash [:sha256 .Size ])
268
280
return n , err
269
281
}
270
282
@@ -280,10 +292,13 @@ func (w *SimpleWriter) flush() error {
280
292
w .h .Reset ()
281
293
_ , _ = w .h .Write (w .buf [4 : 4 + w .done ])
282
294
_ , _ = w .h .Write (w .buf [:4 ])
295
+ _ , _ = w .h .Write (w .prevHash [:])
283
296
284
- // Calculate the hash and write it after the data section in the buffer .
297
+ // Compute the hash into prevHash, now that we don't need the old value .
285
298
// Pass a 32-byte capacity slice (with 0 length) to avoid allocation.
286
- w .h .Sum (w .buf [4 + w .done : 4 + w .done : 4 + w .done + sha256 .Size ])
299
+ w .h .Sum (w .prevHash [0 :0 :sha256 .Size ])
300
+ // Write it after the data section in the buffer.
301
+ copy (w .buf [4 + w .done :4 + w .done + sha256 .Size ], w .prevHash [:sha256 .Size ])
287
302
288
303
// Write out to the stream.
289
304
_ , err := w .base .Write (w .buf [:4 + w .done + sha256 .Size ])
0 commit comments