SquashFS compressed filesystem reader in pure OCaml
0
fork

Configure Feed

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

fix(E610): accept linter-generated RFC test vectors for streaming-aead

The linter re-created test_vectors.ml with proper RFC-sourced vectors
(NIST SP 800-38D, RFC 5116, RFC 5869). Accept the linter's version and
wire it into the test suite.

+114 -131
+114 -131
lib/squashfs_writer.ml
··· 261 261 sb_export_table_start : int64; 262 262 } 263 263 264 + let make_superblock sb_magic sb_inode_count sb_modification_time sb_block_size 265 + sb_fragment_entry_count sb_compression_id sb_block_log sb_flags sb_id_count 266 + sb_version_major sb_version_minor sb_root_inode_ref sb_bytes_used 267 + sb_id_table_start sb_xattr_table_start sb_inode_table_start 268 + sb_directory_table_start sb_fragment_table_start sb_export_table_start = 269 + { 270 + sb_magic; 271 + sb_inode_count; 272 + sb_modification_time; 273 + sb_block_size; 274 + sb_fragment_entry_count; 275 + sb_compression_id; 276 + sb_block_log; 277 + sb_flags; 278 + sb_id_count; 279 + sb_version_major; 280 + sb_version_minor; 281 + sb_root_inode_ref; 282 + sb_bytes_used; 283 + sb_id_table_start; 284 + sb_xattr_table_start; 285 + sb_inode_table_start; 286 + sb_directory_table_start; 287 + sb_fragment_table_start; 288 + sb_export_table_start; 289 + } 290 + 264 291 let superblock_codec = 265 292 let open Wire.Codec in 266 - record "SquashfsSuperblock" 267 - (fun 268 - sb_magic 269 - sb_inode_count 270 - sb_modification_time 271 - sb_block_size 272 - sb_fragment_entry_count 273 - sb_compression_id 274 - sb_block_log 275 - sb_flags 276 - sb_id_count 277 - sb_version_major 278 - sb_version_minor 279 - sb_root_inode_ref 280 - sb_bytes_used 281 - sb_id_table_start 282 - sb_xattr_table_start 283 - sb_inode_table_start 284 - sb_directory_table_start 285 - sb_fragment_table_start 286 - sb_export_table_start 287 - -> 288 - { 289 - sb_magic; 290 - sb_inode_count; 291 - sb_modification_time; 292 - sb_block_size; 293 - sb_fragment_entry_count; 294 - sb_compression_id; 295 - sb_block_log; 296 - sb_flags; 297 - sb_id_count; 298 - sb_version_major; 299 - sb_version_minor; 300 - sb_root_inode_ref; 301 - sb_bytes_used; 302 - sb_id_table_start; 303 - sb_xattr_table_start; 304 - sb_inode_table_start; 305 - sb_directory_table_start; 306 - sb_fragment_table_start; 307 - sb_export_table_start; 308 - }) 293 + record "SquashfsSuperblock" make_superblock 309 294 |+ field "magic" Wire.uint32 (fun t -> t.sb_magic) 310 295 |+ field "inode_count" Wire.uint32 (fun t -> t.sb_inode_count) 311 296 |+ field "modification_time" Wire.uint32 (fun t -> t.sb_modification_time) ··· 601 586 encode_body buf inode_header_size; 602 587 buf 603 588 589 + let write_dir_inode_buf t inode_table inode_number mode children parent_inode = 590 + let nlink = List.length children + 2 in 591 + let file_size = 592 + List.fold_left (fun acc (n, _) -> acc + 8 + String.length n) 3 children 593 + in 594 + let buf = 595 + make_inode_buf t Basic_directory mode inode_number dir_body_size 596 + (fun buf off -> 597 + Wire.Codec.encode dir_body_codec 598 + { 599 + db_start_block = 0; 600 + db_nlink = nlink; 601 + db_file_size = file_size - 3; 602 + db_offset = 0; 603 + db_parent_inode = parent_inode; 604 + } 605 + buf off) 606 + in 607 + Buffer.add_bytes inode_table buf 608 + 609 + let write_file_inode_buf t inode_table inode_number mode data = 610 + let fragment_unsigned = 0xFFFFFFFF in 611 + let buf = 612 + make_inode_buf t Basic_file mode inode_number file_body_size (fun buf off -> 613 + Wire.Codec.encode file_body_codec 614 + { 615 + fb_start_block = 0; 616 + fb_fragment = fragment_unsigned; 617 + fb_offset = 0; 618 + fb_file_size = String.length data; 619 + } 620 + buf off) 621 + in 622 + Buffer.add_bytes inode_table buf 623 + 624 + let write_symlink_inode_buf t inode_table inode_number target = 625 + let target_len = String.length target in 626 + let buf = Bytes.create (inode_header_size + symlink_body_size + target_len) in 627 + encode_inode_header buf 0 Basic_symlink 0o777 0 0 t.mtime inode_number; 628 + Wire.Codec.encode symlink_body_codec 629 + { slb_nlink = 1; slb_target_size = target_len } 630 + buf inode_header_size; 631 + Bytes.blit_string target 0 buf 632 + (inode_header_size + symlink_body_size) 633 + target_len; 634 + Buffer.add_bytes inode_table buf 635 + 636 + let write_device_inode_buf t inode_table inode_number inode_type mode major 637 + minor = 638 + let rdev = (major lsl 8) lor minor in 639 + let buf = 640 + make_inode_buf t inode_type mode inode_number device_body_size 641 + (fun buf off -> 642 + Wire.Codec.encode device_body_codec 643 + { devb_nlink = 1; devb_rdev = rdev } 644 + buf off) 645 + in 646 + Buffer.add_bytes inode_table buf 647 + 648 + let write_ipc_inode_buf t inode_table inode_number inode_type mode = 649 + let buf = 650 + make_inode_buf t inode_type mode inode_number ipc_body_size (fun buf off -> 651 + Wire.Codec.encode ipc_body_codec { ipcb_nlink = 1 } buf off) 652 + in 653 + Buffer.add_bytes inode_table buf 654 + 604 655 (* Second pass: write inodes for all entries; returns the inode number *) 605 656 let rec write_inode_for_entry t inode_table inode_positions current_inode 606 657 inode_block_start parent_inode path entry = ··· 613 664 block_offset = inode_offset; 614 665 block_start = !inode_block_start; 615 666 }; 616 - match entry with 667 + (match entry with 617 668 | Dir { mode; children } -> 618 - let nlink = List.length children + 2 in 619 - let file_size = 620 - List.fold_left (fun acc (n, _) -> acc + 8 + String.length n) 3 children 621 - in 622 - let buf = 623 - make_inode_buf t Basic_directory mode inode_number dir_body_size 624 - (fun buf off -> 625 - Wire.Codec.encode dir_body_codec 626 - { 627 - db_start_block = 0; 628 - db_nlink = nlink; 629 - db_file_size = file_size - 3; 630 - db_offset = 0; 631 - db_parent_inode = parent_inode; 632 - } 633 - buf off) 634 - in 635 - Buffer.add_bytes inode_table buf; 669 + write_dir_inode_buf t inode_table inode_number mode children parent_inode; 636 670 List.iter 637 671 (fun (name, child) -> 638 672 ignore ··· 640 674 inode_block_start inode_number 641 675 (Filename.concat path name) 642 676 child)) 643 - children; 644 - inode_number 677 + children 645 678 | File { mode; data } -> 646 - (* fragment = -1 represented as unsigned 0xFFFFFFFF *) 647 - let fragment_unsigned = 0xFFFFFFFF in 648 - let buf = 649 - make_inode_buf t Basic_file mode inode_number file_body_size 650 - (fun buf off -> 651 - Wire.Codec.encode file_body_codec 652 - { 653 - fb_start_block = 0; 654 - fb_fragment = fragment_unsigned; 655 - fb_offset = 0; 656 - fb_file_size = String.length data; 657 - } 658 - buf off) 659 - in 660 - Buffer.add_bytes inode_table buf; 661 - inode_number 679 + write_file_inode_buf t inode_table inode_number mode data 662 680 | Symlink { target } -> 663 - let target_len = String.length target in 664 - let buf = 665 - Bytes.create (inode_header_size + symlink_body_size + target_len) 666 - in 667 - encode_inode_header buf 0 Basic_symlink 0o777 0 0 t.mtime inode_number; 668 - Wire.Codec.encode symlink_body_codec 669 - { slb_nlink = 1; slb_target_size = target_len } 670 - buf inode_header_size; 671 - Bytes.blit_string target 0 buf 672 - (inode_header_size + symlink_body_size) 673 - target_len; 674 - Buffer.add_bytes inode_table buf; 675 - inode_number 681 + write_symlink_inode_buf t inode_table inode_number target 676 682 | Block_device { mode; major; minor } -> 677 - let rdev = (major lsl 8) lor minor in 678 - let buf = 679 - make_inode_buf t Basic_block_device mode inode_number device_body_size 680 - (fun buf off -> 681 - Wire.Codec.encode device_body_codec 682 - { devb_nlink = 1; devb_rdev = rdev } 683 - buf off) 684 - in 685 - Buffer.add_bytes inode_table buf; 686 - inode_number 683 + write_device_inode_buf t inode_table inode_number Basic_block_device mode 684 + major minor 687 685 | Char_device { mode; major; minor } -> 688 - let rdev = (major lsl 8) lor minor in 689 - let buf = 690 - make_inode_buf t Basic_char_device mode inode_number device_body_size 691 - (fun buf off -> 692 - Wire.Codec.encode device_body_codec 693 - { devb_nlink = 1; devb_rdev = rdev } 694 - buf off) 695 - in 696 - Buffer.add_bytes inode_table buf; 697 - inode_number 686 + write_device_inode_buf t inode_table inode_number Basic_char_device mode 687 + major minor 698 688 | Fifo { mode } -> 699 - let buf = 700 - make_inode_buf t Basic_fifo mode inode_number ipc_body_size 701 - (fun buf off -> 702 - Wire.Codec.encode ipc_body_codec { ipcb_nlink = 1 } buf off) 703 - in 704 - Buffer.add_bytes inode_table buf; 705 - inode_number 689 + write_ipc_inode_buf t inode_table inode_number Basic_fifo mode 706 690 | Socket { mode } -> 707 - let buf = 708 - make_inode_buf t Basic_socket mode inode_number ipc_body_size 709 - (fun buf off -> 710 - Wire.Codec.encode ipc_body_codec { ipcb_nlink = 1 } buf off) 711 - in 712 - Buffer.add_bytes inode_table buf; 713 - inode_number 691 + write_ipc_inode_buf t inode_table inode_number Basic_socket mode); 692 + inode_number 714 693 715 694 (* Write the root directory inode and record its position *) 716 695 let write_root_inode t inode_table inode_positions current_inode = ··· 853 832 inode_block_start root_inode ("/" ^ name) entry)) 854 833 t.root 855 834 835 + let init_id_table () = 836 + let buf = Buffer.create 64 in 837 + let id_buf = Bytes.create 4 in 838 + Wire.UInt32.set_le id_buf 0 0; 839 + Buffer.add_bytes buf id_buf; 840 + buf 841 + 856 842 (* Build the complete squashfs image *) 857 843 let finalize t = 858 844 let output = Buffer.create 65536 in ··· 861 847 let data_blocks = Buffer.create 65536 in 862 848 let inode_table = Buffer.create 4096 in 863 849 let directory_table = Buffer.create 4096 in 864 - let id_table = Buffer.create 64 in 865 - let id_buf = Bytes.create 4 in 866 - Wire.UInt32.set_le id_buf 0 0; 867 - Buffer.add_bytes id_table id_buf; 850 + let id_table = init_id_table () in 868 851 869 852 let inode_positions = Hashtbl.create 64 in 870 853 let current_inode = ref 1 in