diff --git a/src/internal/zstd/fuzz_test.go b/src/internal/zstd/fuzz_test.go index 4b5c9961d8..e945f41241 100644 --- a/src/internal/zstd/fuzz_test.go +++ b/src/internal/zstd/fuzz_test.go @@ -25,6 +25,7 @@ var badStrings = []string{ "(\xb5/\xfd00\xec\x00\x00&@\x05\x05A7002\x02\x00\x02\x00\x02\x0000000000000000", "(\xb5/\xfd00\xec\x00\x00V@\x05\x0517002\x02\x00\x02\x00\x02\x0000000000000000", "\x50\x2a\x4d\x18\x02\x00\x00\x00", + "(\xb5/\xfd\xe40000000\xfa20\x000", } // This is a simple fuzzer to see if the decompressor panics. diff --git a/src/internal/zstd/zstd.go b/src/internal/zstd/zstd.go index 0230076f50..0370f601cb 100644 --- a/src/internal/zstd/zstd.go +++ b/src/internal/zstd/zstd.go @@ -237,7 +237,7 @@ retry: // Figure out the maximum amount of data we need to retain // for backreferences. - var windowSize int + var windowSize uint64 if !singleSegment { // Window descriptor. RFC 3.1.1.1.2. windowDescriptor := r.scratch[0] @@ -246,7 +246,7 @@ retry: windowLog := exponent + 10 windowBase := uint64(1) << windowLog windowAdd := (windowBase / 8) * mantissa - windowSize = int(windowBase + windowAdd) + windowSize = windowBase + windowAdd // Default zstd sets limits on the window size. if fuzzing && (windowLog > 31 || windowSize > 1<<27) { @@ -288,12 +288,13 @@ retry: // When Single_Segment_Flag is set, Window_Descriptor is not present. // In this case, Window_Size is Frame_Content_Size. if singleSegment { - windowSize = int(r.remainingFrameSize) + windowSize = r.remainingFrameSize } // RFC 8878 3.1.1.1.1.2. permits us to set an 8M max on window size. - if windowSize > 8<<20 { - windowSize = 8 << 20 + const maxWindowSize = 8 << 20 + if windowSize > maxWindowSize { + windowSize = maxWindowSize } relativeOffset += headerSize @@ -307,7 +308,7 @@ retry: r.repeatedOffset2 = 4 r.repeatedOffset3 = 8 r.huffmanTableBits = 0 - r.window.reset(windowSize) + r.window.reset(int(windowSize)) r.seqTables[0] = nil r.seqTables[1] = nil r.seqTables[2] = nil