@@ -226,6 +226,69 @@ func TestBlockGeneric(t *testing.T) {
226
226
}
227
227
}
228
228
229
+ // Tests for unmarshaling hashes that have hashed a large amount of data
230
+ // The initial hash generation is omitted from the test, because it takes a long time.
231
+ // The test contains some already-generated states, and their expected sums
232
+ // Tests a problem that is outlined in Github issue #29517
233
+ // The problem is triggered when an amount of data has been hashed for which
234
+ // the data length has a 1 in the 32nd bit. When casted to int, this changes
235
+ // the sign of the value, and causes the modulus operation to return a
236
+ // different result.
237
+ type unmarshalTest struct {
238
+ state string
239
+ sum string
240
+ }
241
+
242
+ var largeUnmarshalTests = []unmarshalTest {
243
+ // Data length: 7_115_087_207
244
+ unmarshalTest {
245
+ state : "sha\x03 yX\xaf \xb7 \x04 *\x8f \xaa \x9b x\xc5 #\x1f \xeb \x94 \xfd z1\xaf \xfb k֗\n \xc9 3\xcf \x02 \v .\xa5 \xe4 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x01 \xa8 \x17 \x9d g" ,
246
+ sum : "f5e06371f0c115e9968455c8e48a318aba548b9f15676fa41de123f7d1c99c55" ,
247
+ },
248
+
249
+ // Data length: 7_070_038_086
250
+ unmarshalTest {
251
+ state : "sha\x03 $\x93 3u\n V\v \xe2 \xf7 :0!ʳ\xa4 \x13 \xd3 6\xdc BB\xb5 \x19 \xcd =\xc1 h\xee =\xb4 \x9c @ABCDE\x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x01 \xa5 h8F" ,
252
+ sum : "a280b08df5eba060fcd0eb3d29320bbc038afb95781661f91bbfd0a6fc9fdd6e" ,
253
+ },
254
+
255
+ // Data length: 6_464_878_887
256
+ unmarshalTest {
257
+ state : "sha\x03 \x9f \x12 \x87 G\xf2 \xdf <\x82 \xa0 \x11 /*W\x02 &IKWlh\x03 \x95 \xb1 \xab \f \n \xf6 Ze\xf9 \x1d \x1b \x00 \x01 \x02 \x03 \x04 \x05 \x06 \a \b \t \n \v \f \r \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a \x1b \x1c \x1d \x1e \x1f !\" #$%&\x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x01 \x81 V9'" ,
258
+ sum : "d2fffb762f105ab71e2d70069346c44c38c4fe183aad8cfcf5a76397c0457806" ,
259
+ },
260
+ }
261
+
262
+ func safeSum (h hash.Hash ) (sum []byte , err error ) {
263
+ defer func () {
264
+ if r := recover (); r != nil {
265
+ err = fmt .Errorf ("sum panic: %v" , r )
266
+ }
267
+ }()
268
+
269
+ return h .Sum (nil ), nil
270
+ }
271
+ func TestLargeHashes (t * testing.T ) {
272
+ for i , test := range largeUnmarshalTests {
273
+
274
+ h := New ()
275
+ if err := h .(encoding.BinaryUnmarshaler ).UnmarshalBinary ([]byte (test .state )); err != nil {
276
+ t .Errorf ("test %d could not unmarshal: %v" , i , err )
277
+ continue
278
+ }
279
+
280
+ sum , err := safeSum (h )
281
+ if err != nil {
282
+ t .Errorf ("test %d could not sum: %v" , i , err )
283
+ continue
284
+ }
285
+
286
+ if fmt .Sprintf ("%x" , sum ) != test .sum {
287
+ t .Errorf ("test %d sum mismatch: expect %s got %x" , i , test .sum , sum )
288
+ }
289
+ }
290
+ }
291
+
229
292
var bench = New ()
230
293
var buf = make ([]byte , 8192 )
231
294
0 commit comments