ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
comic_wrapped.c File Reference

Wrapped comic open: gzip / XZ unwrap in front of the container detect. More...

#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "comic.h"
#include "comic_internal.h"
#include "ra8_attributes.h"
#include "ra8_check.h"
#include "unarch_gzip.h"
#include "unarch_io.h"
#include "unarch_xz.h"
Include dependency graph for comic_wrapped.c:

Go to the source code of this file.

Enumerations

enum  wrap_dims_t : uint16_t { k_wrap_hdr_bytes }
 Arena layout constants for the wrapped open. More...

Functions

static ra8_err_t internal_unwrap (comic_read_fn read, void *ctx, uint64_t size, bool is_gzip, uint8_t *payload, size_t payload_cap, void *xz_scratch, uint32_t xz_scratch_len, size_t *out_len)
 Decode the gzip / XZ wrapper into the arena's payload region.
static bool internal_arena_valid (uint8_t *arena, size_t arena_cap)
 Check wrapper-arena alignment and payload capacity.
static ra8_err_t internal_open_unwrapped (comic_t *c, uint8_t *payload, size_t inner_len, comic_page_t *pages, uint32_t page_cap, char *names, uint32_t names_cap, uint8_t *arena)
 Reject nested wrappers and open the decoded inner comic.
ra8_err_t comic_open_wrapped (comic_t *c, comic_read_fn read, void *ctx, uint64_t size, comic_page_t *pages, uint32_t page_cap, char *names, uint32_t names_cap, uint8_t *arena, size_t arena_cap, void *xz_scratch, uint32_t xz_scratch_len)
 Open a comic that may be gzip- or XZ-wrapped (.cbt.gz, .tar.xz).

Detailed Description

Wrapped comic open: gzip / XZ unwrap in front of the container detect.

Tag
[Ring 4 / Domain] {World: NS}

comic_open_wrapped extends the facade to gzip- and XZ-wrapped archives (.tar.gz, .tar.xz, .cbt.gz, ...): the wrapper is decoded whole into a caller-owned arena under the default decompression-limits policy, then the inner bytes are opened through the ordinary container detect over a flat-memory view. The view descriptor (unarch_mem_t) is stored at the arena's (8-aligned) start so it out-lives the open exactly as long as the arena does – demand-paged page reads keep hitting it for the comic's whole lifetime, and the caller owns exactly one buffer.

Nesting is bounded structurally: the unwrapped bytes are re-probed and a second wrapper layer (gzip-in-gzip, xz-in-gzip, ...) is rejected as a k_ra8_err_decomp_depth bomb before any inner decode starts.

Since
Version 0.1.0

Definition in file comic_wrapped.c.

Enumeration Type Documentation

◆ wrap_dims_t

enum wrap_dims_t : uint16_t

Arena layout constants for the wrapped open.

The flat-memory descriptor occupies the first k_wrap_hdr_bytes of the caller arena (its size rounded up to the arena alignment); the unwrapped payload follows.

Since
Version 0.1.0
Enumerator
k_wrap_hdr_bytes 

Descriptor slot at the arena start (aligned sizeof).

Definition at line 48 of file comic_wrapped.c.

Function Documentation

◆ comic_open_wrapped()

ra8_err_t comic_open_wrapped ( comic_t * c,
comic_read_fn read,
void * ctx,
uint64_t size,
comic_page_t * pages,
uint32_t page_cap,
char * names,
uint32_t names_cap,
uint8_t * arena,
size_t arena_cap,
void * xz_scratch,
uint32_t xz_scratch_len )
nodiscard

Open a comic that may be gzip- or XZ-wrapped (.cbt.gz, .tar.xz).

Probes the leading magic: a bare container (ZIP / RAR / tar) passes straight through to comic_open; a gzip or XZ wrapper is first decoded whole into the caller arena under the default decompression-limits policy, the unwrapped bytes are re-probed (a wrapper inside a wrapper is rejected as a nesting bomb), and the inner container is opened from the arena. The arena therefore must out-live the comic, exactly like the page-index and name buffers.

Parameters
[out]cReader to populate (caller-owned).
[in]readByte reader over the outer file (non-NULL).
[in]ctxContext passed to read.
[in]sizeOuter file length in bytes (> 0).
[in]pagesCaller page-index array (non-NULL).
[in]page_capCapacity of pages in entries (> 0).
[in]namesCaller name arena (non-NULL).
[in]names_capCapacity of names in bytes (> 0).
[in]arenaUnwrap arena (non-NULL, 8-aligned; out-lives c).
[in]arena_capCapacity of arena in bytes.
[in]xz_scratchXZ session scratch (8-aligned, > k_unarch_xz_state_reserve bytes; may be NULL when XZ content is not expected – an XZ file is then rejected fail-closed).
[in]xz_scratch_lenScratch length in bytes.
Returns
ra8_err_t Error code.
Return values
k_ra8_okComic opened; c bound with >= 1 page.
k_ra8_err_null_ptrA required pointer argument was NULL.
k_ra8_err_invalid_sizeA zero size/capacity, a short magic read, a misaligned or undersized arena, or full index buffers.
k_ra8_err_decomp_depthThe unwrapped bytes are another gzip/XZ wrapper (nesting bomb).
k_ra8_err_decomp_*The wrapper breached the policy.
k_ra8_err_checksum_mismatchThe gzip integrity check failed.
k_ra8_err_not_supportedNot a recognised container or wrapper.
k_ra8_err_*An unwrap or inner-open error.
Precondition
read serves offsets [0, size) of the outer file.
arena (and every other buffer) out-lives c and every read.
Postcondition
On k_ra8_ok the comic serves pages exactly like comic_open.
On any error c is left with kind == k_comic_kind_none.
Note
Not thread-safe (shares the single-client XZ pool / gzip state).
See also
comic_open()
Since
Version 0.1.0

Log tag for wrapped-open diagnostics.

Definition at line 190 of file comic_wrapped.c.

References comic_open(), internal_arena_valid(), internal_open_unwrapped(), internal_unwrap(), k_comic_magic_len, k_ra8_err_invalid_size, k_ra8_ok, k_wrap_hdr_bytes, RA8_CHECK_NULL_PTR, unarch_gzip_magic(), and unarch_xz_magic().

◆ internal_arena_valid()

bool internal_arena_valid ( uint8_t * arena,
size_t arena_cap )
static

Check wrapper-arena alignment and payload capacity.

Converts the pointer representation without aliasing and checks the alignment and minimum header-plus-payload geometry.

Parameters
[in]arenaCandidate wrapper arena base.
[in]arena_capAvailable arena bytes.
Returns
Whether the arena satisfies the wrapper storage contract.
Return values
trueThe base is aligned and capacity exceeds the wrapper header.
falseAlignment or capacity is invalid.
Precondition
arena may carry any object-pointer representation.
arena_cap may carry any representable size.
Postcondition
No arena byte is read or modified.
The result depends only on the supplied address and capacity.
Note
Pure and thread-safe.
Since
Version 0.1.0

Definition at line 119 of file comic_wrapped.c.

References k_comic_wrap_align, k_wrap_hdr_bytes, memcpy(), and RA8_INTERNAL.

Referenced by comic_open_wrapped().

◆ internal_open_unwrapped()

ra8_err_t internal_open_unwrapped ( comic_t * c,
uint8_t * payload,
size_t inner_len,
comic_page_t * pages,
uint32_t page_cap,
char * names,
uint32_t names_cap,
uint8_t * arena )
static

Reject nested wrappers and open the decoded inner comic.

Installs the arena-resident memory-reader descriptor only after confirming the decoded payload is not another gzip or XZ stream.

Parameters
[in,out]cComic handle to initialise.
[in]payloadDecoded inner-container bytes.
[in]inner_lenDecoded byte count.
[out]pagesCaller-owned page table.
[in]page_capCapacity of pages.
[out]namesCaller-owned page-name arena.
[in]names_capCapacity of names.
[in,out]arenaWrapper arena whose prefix stores the reader descriptor.
Returns
Error code from nesting validation or comic_open.
Return values
k_ra8_okInner comic opened successfully.
k_ra8_err_decomp_depthA second compression wrapper was detected.
k_ra8_err_*Inner comic detection or validation failed.
Precondition
payload addresses inner_len decoded bytes in arena.
arena has room for the aligned unarch_mem_t descriptor.
Postcondition
On success c reads the decoded payload through the arena descriptor.
On error no nested wrapper is decoded.
Note
Not thread-safe; the caller owns all supplied storage.
Since
Version 0.1.0

Definition at line 153 of file comic_wrapped.c.

References unarch_mem_t::base, comic_open(), k_ra8_err_decomp_depth, unarch_mem_t::len, unarch_gzip_magic(), unarch_mem_read(), and unarch_xz_magic().

Referenced by comic_open_wrapped().

◆ internal_unwrap()

ra8_err_t internal_unwrap ( comic_read_fn read,
void * ctx,
uint64_t size,
bool is_gzip,
uint8_t * payload,
size_t payload_cap,
void * xz_scratch,
uint32_t xz_scratch_len,
size_t * out_len )
static

Decode the gzip / XZ wrapper into the arena's payload region.

Routes on the probed magic; both legs run the default decompression-limits policy. An XZ file without a caller XZ scratch fails closed through the XZ wrapper's null guard.

Parameters
[in]readByte reader over the outer file.
[in]ctxContext for read.
[in]sizeOuter file length in bytes.
[in]is_gzipTrue for a gzip wrapper, false for XZ.
[out]payloadUnwrap destination (the arena past the header).
[in]payload_capDestination capacity in bytes.
[in]xz_scratchXZ session scratch (unused for gzip).
[in]xz_scratch_lenScratch length in bytes.
[out]out_lenReceives the unwrapped byte count.
Returns
ra8_err_t status from the wrapper decoder.
Return values
k_ra8_okWrapper decoded and verified into payload.
k_ra8_err_*Any bounded unwrap failure (propagated verbatim).
Precondition
The leading magic matched the selected wrapper.
payload holds payload_cap writable bytes.
Postcondition
On k_ra8_ok, payload[0..*out_len) holds the inner container.
On any error the open is abandoned (fail-closed).
Note
Not thread-safe (single-client decoder states).
Since
Version 0.1.0

Definition at line 79 of file comic_wrapped.c.

References unarch_gzip_unwrap(), and unarch_xz_unwrap().

Referenced by comic_open_wrapped().