|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Clean-room, read-only streaming tar walker (POSIX ustar + pax + GNU). More...
#include <stddef.h>#include <stdint.h>#include "ra8_decomp_limits.h"#include "ra8_err.h"#include "unarch_io.h"Go to the source code of this file.
Data Structures | |
| struct | unarch_tar_t |
| One open tar archive: the backing plus the walk's running budget. More... | |
| struct | unarch_tar_entry_t |
| One decoded tar member: a file, a directory, or a skipped block. More... | |
Enumerations | |
| enum | unarch_tar_dims_t : uint16_t { k_unarch_tar_block = 512U , k_unarch_tar_meta_max = 4U , k_unarch_tar_pax_max = 2048U } |
| Fixed sizes of the tar on-disk grammar and the walker's bounds. More... | |
Functions | |
| bool | unarch_tar_probe (const uint8_t *block, size_t len) |
| Whether a leading header block looks like a tar archive. | |
| ra8_err_t | unarch_tar_open (unarch_tar_t *t, unarch_read_fn read, void *ctx, uint64_t size, const ra8_decomp_limits_t *limits) |
| Bind a walker to an archive and validate its first header block. | |
| ra8_err_t | unarch_tar_next (unarch_tar_t *t, uint64_t off, char *name_buf, uint16_t name_cap, unarch_tar_entry_t *out) |
Decode the member at off and advance to the next member. | |
| ra8_err_t | unarch_tar_read (const unarch_tar_t *t, const unarch_tar_entry_t *ent, uint8_t *buf, size_t cap, size_t *got) |
| Copy a file member's data area into the caller buffer. | |
Clean-room, read-only streaming tar walker (POSIX ustar + pax + GNU).
A first-party, hand-written tar reader for the comic-book-archive (.cbt) and wrapped-tar (.tar.gz / .tar.xz) use cases. It walks the 512-byte block chain of a POSIX ustar archive one header at a time over the shared seek+read seam (unarch_io.h) and exposes each member (name, size, data offset) without ever materialising the archive. Supported header dialects, all parsed fail-closed:
Everything else – link/device/fifo members, unknown typeflags – is enumerated as a non-file entry and skipped by size, so the walk never stalls on exotic content.
Definition in file unarch_tar.h.
| enum unarch_tar_dims_t : uint16_t |
Fixed sizes of the tar on-disk grammar and the walker's bounds.
The block size is fixed by every tar dialect; the meta and pax bounds are this walker's fail-closed limits on the pax / GNU prelude a single member may carry.
| Enumerator | |
|---|---|
| k_unarch_tar_block | On-disk block / header size. |
| k_unarch_tar_meta_max | Max meta (x/g/L/K) blocks per member. |
| k_unarch_tar_pax_max | Max pax / longname data bytes. |
Definition at line 76 of file unarch_tar.h.
|
nodiscard |
Decode the member at off and advance to the next member.
Consumes the member's pax / GNU meta prelude (bounded by k_unarch_tar_meta_max blocks and k_unarch_tar_pax_max data bytes), decodes the real header, applies any path / size overrides, and fills out – including out->next_off, the offset of the following member. The member name (pax path, GNU longname, or prefix-joined ustar name) is copied into name_buf, clamped to name_cap. Every examined block charges the walk's iteration budget and every returned member charges its entry budget; a member whose declared size breaks the policy's output cap or overruns the archive is rejected.
| [in,out] | t | Walker bound by unarch_tar_open (non-NULL). |
| [in] | off | Absolute offset of the member's first block. |
| [out] | name_buf | Buffer for the member name (non-NULL if name_cap > 0). |
| [in] | name_cap | Capacity of name_buf in bytes. |
| [out] | out | Decoded member descriptor (non-NULL). |
| k_ra8_ok | Member decoded; out filled. |
| k_ra8_err_null_ptr | t or out was NULL. |
| k_ra8_err_invalid_state | t was never bound. |
| k_ra8_err_not_found | End of archive (zero block or EOF). |
| k_ra8_err_validation_failed | A truncated / malformed / lying header, checksum failure, or an over-limit meta prelude. |
| k_ra8_err_decomp_entries | The policy entry cap was crossed. |
| k_ra8_err_decomp_iterations | The block-examination budget ran out. |
| k_ra8_err_decomp_output_cap | A member declares more bytes than the policy's per-unit output cap. |
t was populated by unarch_tar_open. off is 0 or a next_off from a previous call. out is left zeroed.Definition at line 419 of file unarch_tar.c.
References unarch_tar_t::budget, internal_decode_header(), internal_finish_member(), internal_meta_consume(), internal_read_block(), k_ra8_err_invalid_state, k_ra8_err_not_found, k_ra8_err_validation_failed, k_ra8_ok, k_ra8_tar_type_longname, k_ra8_tar_type_meta, k_ra8_tar_type_other, k_ra8_tar_type_pax, k_unarch_tar_block, k_unarch_tar_meta_max, unarch_tar_t::live, priv_unarch_tar_block_zero(), RA8_CHECK_NULL_PTR, ra8_decomp_budget_charge_iter(), s_tag_tar, and unarch_tar_t::size.
Referenced by priv_comic_cbt_open().
|
nodiscard |
Bind a walker to an archive and validate its first header block.
Reads block 0 through read, requires the ustar/GNU magic and a valid checksum (rejecting non-tar bytes cheaply), and binds the walk's decompression budget to limits (or the default policy). Performs no other I/O; the walk proceeds through unarch_tar_next.
| [out] | t | Walker to populate (caller-owned). |
| [in] | read | Byte reader over the archive (non-NULL). |
| [in] | ctx | Context passed to read. |
| [in] | size | Archive length in bytes (>= one block). |
| [in] | limits | Policy to enforce, or NULL for the default. |
| k_ra8_ok | Recognised tar archive; t bound. |
| k_ra8_err_null_ptr | t or read was NULL. |
| k_ra8_err_invalid_size | size is smaller than one block. |
| k_ra8_err_invalid_arg | limits has a zero field. |
| k_ra8_err_not_supported | Block 0 is not a tar header. |
read serves offsets [0, size) of the archive. t is a writable unarch_tar_t. t is left dead (live == false).Definition at line 74 of file unarch_tar.c.
References unarch_tar_t::budget, unarch_tar_t::ctx, k_ra8_err_invalid_size, k_ra8_err_not_supported, k_ra8_err_null_ptr, k_ra8_ok, k_unarch_tar_block, unarch_tar_t::live, RA8_CHECK_NULL_PTR, ra8_decomp_budget_init(), ra8_log_error, unarch_tar_t::read, s_tag_tar, unarch_tar_t::size, and unarch_tar_probe().
Referenced by internal_open_detect().
|
nodiscard |
Whether a leading header block looks like a tar archive.
Pure probe over the first k_unarch_tar_block bytes: the ustar/GNU magic at its fixed offset plus a valid header checksum. Used by container detection to route a .cbt without constructing a walker. tar has no leading magic bytes, so both tests are required to keep false positives out of the comic open path.
| [in] | block | Leading archive bytes (may be NULL). |
| [in] | len | Readable length of block in bytes. |
| true | Magic and checksum both hold. |
| false | block is NULL, short, or not a tar header. |
block holds len readable bytes when non-NULL. len is the true readable length (untrusted values are safe). Definition at line 60 of file unarch_tar.c.
References k_unarch_tar_block, priv_unarch_tar_checksum_ok(), and priv_unarch_tar_magic_ok().
Referenced by unarch_tar_open().
|
nodiscard |
Copy a file member's data area into the caller buffer.
Streams ent->size verbatim bytes from [ent->data_off, ent->data_off + ent->size) through the archive reader into buf. tar stores members uncompressed, so this is the whole extraction step; the bounds re-checked here make a hand-forged entry harmless.
| [in] | t | Walker bound by unarch_tar_open (non-NULL). |
| [in] | ent | A file member from unarch_tar_next (non-NULL, is_file == 1). |
| [out] | buf | Destination for the member bytes (non-NULL). |
| [in] | cap | Capacity of buf in bytes; must be >= ent->size. |
| [out] | got | Receives the number of bytes written (non-NULL). |
| k_ra8_ok | Member copied; *got == ent->size. |
| k_ra8_err_null_ptr | A required pointer was NULL. |
| k_ra8_err_invalid_state | t was never bound. |
| k_ra8_err_not_supported | ent is not a regular file member. |
| k_ra8_err_no_mem | cap is smaller than ent->size. |
| k_ra8_err_invalid_size | The member overruns the archive, or the reader returned a short read. |
t was populated by unarch_tar_open. ent came from unarch_tar_next on the same t. buf contents are unspecified and *got == 0.Definition at line 486 of file unarch_tar.c.
References unarch_tar_t::ctx, unarch_tar_entry_t::data_off, unarch_tar_entry_t::is_file, k_ra8_err_invalid_size, k_ra8_err_invalid_state, k_ra8_err_no_mem, k_ra8_err_not_supported, k_ra8_ok, unarch_tar_t::live, RA8_CHECK_NULL_PTR, unarch_tar_t::read, s_tag_tar, unarch_tar_entry_t::size, and unarch_tar_t::size.
Referenced by priv_comic_cbt_extract().