Created
August 7, 2025 11:40
-
-
Save tazjin/c83381ed2b10192365fe08dfc6b13e56 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "bytes" | |
| "encoding/binary" | |
| "fmt" | |
| "math" | |
| "os" | |
| "github.com/pierrec/lz4" | |
| ) | |
| type lz4HeaderSignature uint32 | |
| const ( | |
| lz4HeaderSignatureV1 lz4HeaderSignature = (1 << 30) + 1 | |
| lz4HeaderSignatureV2 lz4HeaderSignature = (1 << 30) + 2 | |
| ) | |
| const maxLz4BlockSize = 1 << 30 | |
| var lz4SignatureV1MaxLength = math.MaxInt32 | |
| type lz4Header struct { | |
| Signature lz4HeaderSignature | |
| Size uint32 | |
| } | |
| type lz4BlockHeader struct { | |
| CompressedSize uint32 | |
| UncompressedSize uint32 | |
| } | |
| type lz4DecompressFunc func(src, dst []byte) (int, error) | |
| func lz4BlockDecompress(block []byte, decompress lz4DecompressFunc) ([]byte, error) { | |
| if len(block) == 0 { | |
| return nil, nil | |
| } | |
| if len(block) < 8 { | |
| return nil, fmt.Errorf("unable to decode header: invalid length: %d", len(block)) | |
| } | |
| var out bytes.Buffer | |
| h := lz4Header{ | |
| Signature: lz4HeaderSignature(binary.LittleEndian.Uint32(block[:4])), | |
| Size: binary.LittleEndian.Uint32(block[4:8]), | |
| } | |
| inputOffset := 8 | |
| totalUncompressedSize := uint64(h.Size) | |
| if h.Signature == lz4HeaderSignatureV2 { | |
| if len(block) < 16 { | |
| return nil, fmt.Errorf("unable to decode v2 header: invalid length: %d", len(block)) | |
| } | |
| totalUncompressedSize = binary.LittleEndian.Uint64(block[8:16]) | |
| inputOffset += 8 | |
| } | |
| for inputOffset < len(block) { | |
| if len(block) < inputOffset+8 { | |
| return nil, fmt.Errorf("unable to decode block header: invalid length") | |
| } | |
| blockHeader := lz4BlockHeader{ | |
| CompressedSize: binary.LittleEndian.Uint32(block[inputOffset : inputOffset+4]), | |
| UncompressedSize: binary.LittleEndian.Uint32(block[inputOffset+4 : inputOffset+8]), | |
| } | |
| inputOffset += 8 | |
| if len(block) < inputOffset+int(blockHeader.CompressedSize) { | |
| return nil, fmt.Errorf("not enough data to decode block: header expects %d bytes, got %d", | |
| blockHeader.CompressedSize, len(block)-inputOffset) | |
| } | |
| compressedBlock := block[inputOffset : inputOffset+int(blockHeader.CompressedSize)] | |
| uncompressedBlock := make([]byte, blockHeader.UncompressedSize) | |
| uncompressedSize, err := decompress(compressedBlock, uncompressedBlock) | |
| if err != nil { | |
| return nil, err | |
| } | |
| if uncompressedSize != int(blockHeader.UncompressedSize) { | |
| return nil, fmt.Errorf("uncompressed block size mismatch: expected %d, got %d", | |
| blockHeader.UncompressedSize, uncompressedSize) | |
| } | |
| if _, err := out.Write(uncompressedBlock); err != nil { | |
| return nil, err | |
| } | |
| inputOffset += int(blockHeader.CompressedSize) | |
| } | |
| if uint64(out.Len()) != totalUncompressedSize { | |
| return nil, fmt.Errorf("uncompressed data size mismatch: expected %d, got %d", out.Len(), h.Size) | |
| } | |
| return out.Bytes(), nil | |
| } | |
| func main() { | |
| if len(os.Args) != 2 { | |
| fmt.Println("Usage: go run reproducer.go <input_file>") | |
| os.Exit(1) | |
| } | |
| // Read input file | |
| data, err := os.ReadFile(os.Args[1]) | |
| if err != nil { | |
| fmt.Printf("Error reading file: %v\n", err) | |
| os.Exit(1) | |
| } | |
| fmt.Printf("Read %d bytes from input file\n", len(data)) | |
| // Call the decompression that triggers the bug | |
| result, err := lz4BlockDecompress(data, lz4.UncompressBlock) | |
| if err != nil { | |
| fmt.Printf("DECOMPRESSION ERROR: %v\n", err) | |
| os.Exit(1) | |
| } | |
| fmt.Printf("SUCCESS: Decompressed %d bytes\n", len(result)) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment