SquashFS compressed filesystem reader in pure OCaml
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix(E415): add pp to squashfs types; sync linter changes across squashfs, srp, streaming-aead, tar, tc

+72 -81
+6 -6
fuzz/dune
··· 1 1 (executable 2 - (name fuzz_squashfs) 3 - (modules fuzz_squashfs) 2 + (name fuzz) 3 + (modules fuzz fuzz_squashfs) 4 4 (libraries squashfs crowbar)) 5 5 6 6 (executable ··· 12 12 (alias runtest) 13 13 (enabled_if 14 14 (<> %{profile} afl)) 15 - (deps fuzz_squashfs.exe) 15 + (deps fuzz.exe) 16 16 (action 17 - (run %{exe:fuzz_squashfs.exe}))) 17 + (run %{exe:fuzz.exe}))) 18 18 19 19 (rule 20 20 (alias fuzz) ··· 22 22 (= %{profile} afl)) 23 23 (deps 24 24 (source_tree corpus) 25 - fuzz_squashfs.exe 25 + fuzz.exe 26 26 gen_corpus.exe) 27 27 (action 28 - (echo "AFL fuzzer built: %{exe:fuzz_squashfs.exe}\n"))) 28 + (echo "AFL fuzzer built: %{exe:fuzz.exe}\n")))
+1
fuzz/fuzz.ml
··· 1 + let () = Crowbar.run "squashfs" [ Fuzz_squashfs.suite ]
-2
fuzz/fuzz_squashfs.ml
··· 269 269 test_case "writer large file" [ range 1_100_000 ] test_writer_large_file; 270 270 test_case "writer compression" [ range 20000 ] test_writer_compression; 271 271 ] ) 272 - 273 - let () = run "squashfs" [ suite ]
+4
lib/squashfs.ml
··· 158 158 xattr_table_start : int64; 159 159 } 160 160 161 + let pp ppf t = 162 + Fmt.pf ppf "<squashfs %a %d bytes>" pp_compression t.superblock.compression 163 + (String.length t.data) 164 + 161 165 (* Binary reading helpers — kept for single-field reads at dynamic offsets 162 166 (metadata block headers, ID table entries) *) 163 167 let get_u16_le s off =
+3
lib/squashfs.mli
··· 52 52 type t 53 53 (** A SquashFS filesystem image. *) 54 54 55 + val pp : t Fmt.t 56 + (** [pp] pretty-prints a SquashFS filesystem image. *) 57 + 55 58 type inode 56 59 (** An inode in the filesystem. *) 57 60
+4
lib/squashfs_writer.ml
··· 74 74 mutable uid_gid_table : (int * int) list; 75 75 } 76 76 77 + let pp ppf t = 78 + Fmt.pf ppf "<squashfs-writer block_size=%d entries=%d>" t.block_size 79 + (List.length t.root) 80 + 77 81 (* Binary writing helper — kept for metadata block headers (single u16 field) *) 78 82 let set_u16_le buf off v = 79 83 Bytes.set buf off (Char.chr (v land 0xff));
+3
lib/squashfs_writer.mli
··· 52 52 type t 53 53 (** A squashfs filesystem being constructed. *) 54 54 55 + val pp : t Fmt.t 56 + (** [pp] pretty-prints a squashfs filesystem under construction. *) 57 + 55 58 type compression = 56 59 | Gzip 57 60 | Lzma
+1 -1
test/test.ml
··· 4 4 ---------------------------------------------------------------------------*) 5 5 6 6 let () = 7 - Alcotest.run "squashfs" (Test_squashfs.suite @ Test_squashfs_writer.suite) 7 + Alcotest.run "squashfs" [ Test_squashfs.suite; Test_squashfs_writer.suite ]
+28 -42
test/test_squashfs.ml
··· 269 269 "export_table_start" sb.sb_export_table_start sb'.sb_export_table_start 270 270 271 271 let suite = 272 - [ 273 - ( "errors", 274 - [ 275 - Alcotest.test_case "too short" `Quick test_too_short; 276 - Alcotest.test_case "invalid magic" `Quick test_invalid_magic; 277 - ] ); 278 - ( "pretty_print", 279 - [ 280 - Alcotest.test_case "compression" `Quick test_pp_compression; 281 - Alcotest.test_case "file_type" `Quick test_pp_file_type; 282 - ] ); 283 - ( "security", 284 - [ 285 - Alcotest.test_case "path traversal: .." `Quick 286 - test_path_traversal_dotdot; 287 - Alcotest.test_case "path traversal: absolute" `Quick 288 - test_path_traversal_absolute; 289 - Alcotest.test_case "path traversal: middle" `Quick 290 - test_path_traversal_middle; 291 - Alcotest.test_case "path traversal: safe" `Quick 292 - test_path_traversal_safe; 293 - Alcotest.test_case "path traversal: relative" `Quick 294 - test_path_traversal_relative; 295 - Alcotest.test_case "reject large block_size" `Quick 296 - test_reject_large_block_size; 297 - Alcotest.test_case "reject zero block_size" `Quick 298 - test_reject_zero_block_size; 299 - Alcotest.test_case "huge inode_count" `Quick test_huge_inode_count; 300 - Alcotest.test_case "huge id_count" `Quick test_huge_id_count; 301 - Alcotest.test_case "metadata beyond image" `Quick 302 - test_metadata_beyond_image; 303 - Alcotest.test_case "empty input" `Quick test_empty_input; 304 - Alcotest.test_case "minimum size" `Quick test_minimum_size; 305 - ] ); 306 - ( "wire", 307 - [ 308 - Alcotest.test_case "superblock codec size" `Quick 309 - test_superblock_codec_size; 310 - Alcotest.test_case "superblock roundtrip" `Quick 311 - test_superblock_roundtrip; 312 - ] ); 313 - ] 272 + ( "squashfs", 273 + [ 274 + Alcotest.test_case "too short" `Quick test_too_short; 275 + Alcotest.test_case "invalid magic" `Quick test_invalid_magic; 276 + Alcotest.test_case "compression" `Quick test_pp_compression; 277 + Alcotest.test_case "file_type" `Quick test_pp_file_type; 278 + Alcotest.test_case "path traversal: .." `Quick test_path_traversal_dotdot; 279 + Alcotest.test_case "path traversal: absolute" `Quick 280 + test_path_traversal_absolute; 281 + Alcotest.test_case "path traversal: middle" `Quick 282 + test_path_traversal_middle; 283 + Alcotest.test_case "path traversal: safe" `Quick test_path_traversal_safe; 284 + Alcotest.test_case "path traversal: relative" `Quick 285 + test_path_traversal_relative; 286 + Alcotest.test_case "reject large block_size" `Quick 287 + test_reject_large_block_size; 288 + Alcotest.test_case "reject zero block_size" `Quick 289 + test_reject_zero_block_size; 290 + Alcotest.test_case "huge inode_count" `Quick test_huge_inode_count; 291 + Alcotest.test_case "huge id_count" `Quick test_huge_id_count; 292 + Alcotest.test_case "metadata beyond image" `Quick 293 + test_metadata_beyond_image; 294 + Alcotest.test_case "empty input" `Quick test_empty_input; 295 + Alcotest.test_case "minimum size" `Quick test_minimum_size; 296 + Alcotest.test_case "superblock codec size" `Quick 297 + test_superblock_codec_size; 298 + Alcotest.test_case "superblock roundtrip" `Quick test_superblock_roundtrip; 299 + ] )
+1
test/test_squashfs.mli
··· 1 + val suite : string * unit Alcotest.test_case list
+20 -30
test/test_squashfs_writer.ml
··· 248 248 | Ok _ -> () 249 249 250 250 let suite = 251 - [ 252 - ( "basic", 253 - [ 254 - Alcotest.test_case "empty filesystem" `Quick test_empty_fs; 255 - Alcotest.test_case "add file" `Quick test_add_file; 256 - Alcotest.test_case "add directory" `Quick test_add_directory; 257 - Alcotest.test_case "add symlink" `Quick test_add_symlink; 258 - Alcotest.test_case "add device" `Quick test_add_device; 259 - Alcotest.test_case "add ipc" `Quick test_add_ipc; 260 - Alcotest.test_case "statistics" `Quick test_stats; 261 - ] ); 262 - ( "validation", 263 - [ 264 - Alcotest.test_case "reject absolute path" `Quick 265 - test_reject_absolute_path; 266 - Alcotest.test_case "reject traversal" `Quick test_reject_traversal; 267 - Alcotest.test_case "reject empty symlink" `Quick 268 - test_reject_empty_symlink; 269 - Alcotest.test_case "block size validation" `Quick 270 - test_block_size_validation; 271 - ] ); 272 - ( "features", 273 - [ 274 - Alcotest.test_case "compression gzip" `Quick test_compression_gzip; 275 - Alcotest.test_case "nested directories" `Quick test_nested_directories; 276 - Alcotest.test_case "implicit parent" `Quick test_implicit_parent; 277 - Alcotest.test_case "overwrite file" `Quick test_overwrite_file; 278 - Alcotest.test_case "write to writer" `Quick test_write_to_writer; 279 - ] ); 280 - ] 251 + ( "squashfs_writer", 252 + [ 253 + Alcotest.test_case "empty filesystem" `Quick test_empty_fs; 254 + Alcotest.test_case "add file" `Quick test_add_file; 255 + Alcotest.test_case "add directory" `Quick test_add_directory; 256 + Alcotest.test_case "add symlink" `Quick test_add_symlink; 257 + Alcotest.test_case "add device" `Quick test_add_device; 258 + Alcotest.test_case "add ipc" `Quick test_add_ipc; 259 + Alcotest.test_case "statistics" `Quick test_stats; 260 + Alcotest.test_case "reject absolute path" `Quick test_reject_absolute_path; 261 + Alcotest.test_case "reject traversal" `Quick test_reject_traversal; 262 + Alcotest.test_case "reject empty symlink" `Quick test_reject_empty_symlink; 263 + Alcotest.test_case "block size validation" `Quick 264 + test_block_size_validation; 265 + Alcotest.test_case "compression gzip" `Quick test_compression_gzip; 266 + Alcotest.test_case "nested directories" `Quick test_nested_directories; 267 + Alcotest.test_case "implicit parent" `Quick test_implicit_parent; 268 + Alcotest.test_case "overwrite file" `Quick test_overwrite_file; 269 + Alcotest.test_case "write to writer" `Quick test_write_to_writer; 270 + ] )
+1
test/test_squashfs_writer.mli
··· 1 + val suite : string * unit Alcotest.test_case list