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

Module-private tar field/record parsers shared across the tar TUs. More...

#include <stddef.h>
#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_err.h"
#include "unarch_tar.h"
Include dependency graph for unarch_tar_internal.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Enumerations

enum  ra8_tar_layout_t : uint16_t {
  k_ra8_tar_off_name = 0U ,
  k_ra8_tar_len_name = 100U ,
  k_ra8_tar_off_size = 124U ,
  k_ra8_tar_len_size = 12U ,
  k_ra8_tar_off_chksum = 148U ,
  k_ra8_tar_len_chksum = 8U ,
  k_ra8_tar_off_type = 156U ,
  k_ra8_tar_off_magic = 257U ,
  k_ra8_tar_len_magic = 5U ,
  k_ra8_tar_off_magic_term = 262U ,
  k_ra8_tar_off_prefix = 345U ,
  k_ra8_tar_len_prefix = 155U
}
 Byte offsets / lengths of the ustar header fields this reader uses. More...
enum  ra8_tar_type_t : uint8_t {
  k_ra8_tar_type_file = 0U ,
  k_ra8_tar_type_dir = 1U ,
  k_ra8_tar_type_pax = 2U ,
  k_ra8_tar_type_meta = 3U ,
  k_ra8_tar_type_longname = 4U ,
  k_ra8_tar_type_other = 5U
}
 Normalised classification of a header block's typeflag. More...

Functions

ra8_err_t priv_unarch_tar_num (const uint8_t *field, size_t len, uint64_t *out)
 Decode a tar numeric field (octal ASCII or GNU base-256).
bool priv_unarch_tar_block_zero (const uint8_t *block)
 Whether a header block is all zero bytes (end-of-archive marker).
bool priv_unarch_tar_checksum_ok (const uint8_t *block)
 Verify a header block's checksum (unsigned byte sum).
bool priv_unarch_tar_magic_ok (const uint8_t *block)
 Whether a header block carries the ustar / GNU magic.
ra8_tar_type_t priv_unarch_tar_classify (uint8_t typeflag)
 Classify a header block's typeflag byte.
ra8_err_t priv_unarch_tar_pax_parse (const uint8_t *data, size_t len, char *name_buf, uint16_t name_cap, uint16_t *name_len, bool *have_path, uint64_t *size_ovr, bool *have_size)
 Parse pax extended-header records, extracting path / size.

Detailed Description

Module-private tar field/record parsers shared across the tar TUs.

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

The tar walker's untrusted-byte parsers live in their own TU (unarch_tar_fields.c) behind these TU-external declarations so the host tests can drive every validation branch directly with hostile field bytes (see CLAUDE.md "Test access to internal symbols"). Production callers are exclusively unarch_tar.c; nothing outside the module and tests/ may include this header.

Since
Version 0.1.0

Definition in file unarch_tar_internal.h.

Enumeration Type Documentation

◆ ra8_tar_layout_t

enum ra8_tar_layout_t : uint16_t

Byte offsets / lengths of the ustar header fields this reader uses.

From the POSIX.1-2017 pax Interchange Format header block layout; named per the no-magic-numbers rule.

Since
Version 0.1.0
Enumerator
k_ra8_tar_off_name 

name field offset.

k_ra8_tar_len_name 

name field length.

k_ra8_tar_off_size 

size field offset.

k_ra8_tar_len_size 

size field length.

k_ra8_tar_off_chksum 

chksum field offset.

k_ra8_tar_len_chksum 

chksum field length.

k_ra8_tar_off_type 

typeflag byte offset.

k_ra8_tar_off_magic 

magic field offset.

k_ra8_tar_len_magic 

Compared magic length ("ustar").

k_ra8_tar_off_magic_term 

Byte after "ustar" (NUL or ' ').

k_ra8_tar_off_prefix 

prefix field offset.

k_ra8_tar_len_prefix 

prefix field length.

Definition at line 41 of file unarch_tar_internal.h.

◆ ra8_tar_type_t

enum ra8_tar_type_t : uint8_t

Normalised classification of a header block's typeflag.

Collapses the tar typeflag byte onto the five shapes the walker handles distinctly; every unknown flag maps to k_ra8_tar_type_other (enumerated, skipped by size).

Since
Version 0.1.0
Enumerator
k_ra8_tar_type_file 

Regular file ('0' or NUL).

k_ra8_tar_type_dir 

Directory ('5').

k_ra8_tar_type_pax 

pax extended header ('x').

k_ra8_tar_type_meta 

Skipped meta: 'g' global, 'K' longlink.

k_ra8_tar_type_longname 

GNU longname data ('L').

k_ra8_tar_type_other 

Any other member kind (skipped).

Definition at line 64 of file unarch_tar_internal.h.

Function Documentation

◆ priv_unarch_tar_block_zero()

bool priv_unarch_tar_block_zero ( const uint8_t * block)
nodiscard

Whether a header block is all zero bytes (end-of-archive marker).

tar terminates an archive with two zero blocks; this walker treats the first as a clean end (tolerant of single-block writers, harmless for hostile input – end is end).

Parameters
[in]blockOne k_unarch_tar_block byte block (non-NULL).
Returns
Whether every byte is zero.
Return values
trueEnd-of-archive marker.
falseAt least one non-zero byte.
Precondition
block holds a full block of readable bytes.
block is non-NULL (caller-guarded).
Postcondition
No state is modified (pure read).
The result depends only on the block bytes.
Note
Thread-safe: pure read.
MC/DC:
Promoted to TU-external linkage for direct test access (no compound decisions; the scan is a single-condition loop).
Since
Version 0.1.0

Definition at line 162 of file unarch_tar_fields.c.

References k_unarch_tar_block, and RA8_PRIV.

Referenced by unarch_tar_next().

◆ priv_unarch_tar_checksum_ok()

bool priv_unarch_tar_checksum_ok ( const uint8_t * block)
nodiscard

Verify a header block's checksum (unsigned byte sum).

Sums all block bytes with the chksum field replaced by spaces (per the tar specification) and compares against the octal value stored in the chksum field. A field that fails octal decode fails the check.

Parameters
[in]blockOne k_unarch_tar_block byte block (non-NULL).
Returns
Whether the stored checksum matches the computed sum.
Return values
trueChecksum holds.
falseMismatch or undecodable chksum field.
Precondition
block holds a full block of readable bytes.
block is non-NULL (caller-guarded).
Postcondition
No state is modified (pure read).
The result depends only on the block bytes.
Note
Thread-safe: pure read.
MC/DC:
Promoted to TU-external linkage so tests can drive the mismatch and undecodable-field arms directly.
Since
Version 0.1.0

Definition at line 172 of file unarch_tar_fields.c.

References internal_octal(), k_ra8_ok, k_ra8_tar_len_chksum, k_ra8_tar_off_chksum, k_tar_chksum_space, k_unarch_tar_block, and RA8_PRIV.

Referenced by internal_decode_header(), and unarch_tar_probe().

◆ priv_unarch_tar_classify()

ra8_tar_type_t priv_unarch_tar_classify ( uint8_t typeflag)
nodiscard

Classify a header block's typeflag byte.

Maps the tar typeflag onto ra8_tar_type_t: regular file ('0' / NUL), directory ('5'), pax extended header ('x'), skipped meta ('g' global, 'K' GNU longlink), GNU longname ('L'), and everything else as an enumerated-but-skipped member.

Parameters
[in]typeflagThe header's typeflag byte.
Returns
The normalised ra8_tar_type_t class.
Return values
k_ra8_tar_type_otherFor any flag this reader does not handle.
Precondition
None – every byte value maps to a class.
The caller applies the class, not the raw flag.
Postcondition
No state is modified (pure mapping).
The result depends only on typeflag.
Note
Thread-safe: pure mapping.
MC/DC:
Promoted to TU-external linkage for direct test access (single-condition comparisons only).
Since
Version 0.1.0

Definition at line 200 of file unarch_tar_fields.c.

References k_ra8_tar_type_dir, k_ra8_tar_type_file, k_ra8_tar_type_longname, k_ra8_tar_type_meta, k_ra8_tar_type_other, k_ra8_tar_type_pax, and RA8_PRIV.

Referenced by internal_decode_header().

◆ priv_unarch_tar_magic_ok()

bool priv_unarch_tar_magic_ok ( const uint8_t * block)
nodiscard

Whether a header block carries the ustar / GNU magic.

Requires "ustar" at the magic offset followed by NUL (POSIX) or space (old GNU). Pre-POSIX v7 headers carry no magic and are rejected – every modern tar writer emits ustar.

Parameters
[in]blockOne k_unarch_tar_block byte block (non-NULL).
Returns
Whether the magic matches either dialect.
Return values
truePOSIX ustar or old-GNU magic.
falseAnything else (including v7 headers).
Precondition
block holds a full block of readable bytes.
block is non-NULL (caller-guarded).
Postcondition
No state is modified (pure read).
The result depends only on the magic bytes.
Note
Thread-safe: pure read.
MC/DC:
Promoted to TU-external linkage so tests can drive the NUL-vs-space terminator compound directly.
Since
Version 0.1.0

Definition at line 188 of file unarch_tar_fields.c.

References k_ra8_tar_off_magic, k_ra8_tar_off_magic_term, and RA8_PRIV.

Referenced by internal_decode_header(), and unarch_tar_probe().

◆ priv_unarch_tar_num()

ra8_err_t priv_unarch_tar_num ( const uint8_t * field,
size_t len,
uint64_t * out )
nodiscard

Decode a tar numeric field (octal ASCII or GNU base-256).

Octal fields may carry leading spaces and are terminated by NUL or space; any other byte, an empty field, or 64-bit overflow is rejected. A field whose first byte has the top bit set is GNU base-256 (big-endian binary): negative values and values over 64 bits are rejected.

Parameters
[in]fieldField bytes (non-NULL).
[in]lenField length in bytes (> 0).
[out]outReceives the decoded value (non-NULL).
Returns
ra8_err_t Error code.
Return values
k_ra8_okValue decoded into out.
k_ra8_err_null_ptrfield or out was NULL.
k_ra8_err_validation_failedEmpty, malformed, negative, or overflowing field.
Precondition
field holds len readable bytes.
len is a real header-field length (bounded by the block size).
Postcondition
On k_ra8_ok, *out holds the exact field value.
On any error *out is 0.
Note
Thread-safe: pure read.
MC/DC:
Promoted to TU-external linkage so tests can drive the octal-digit range compounds and the base-256 fit checks with hostile field bytes.
Since
Version 0.1.0

Definition at line 148 of file unarch_tar_fields.c.

References internal_base256(), internal_octal(), k_ra8_err_validation_failed, k_tar_b256_flag, RA8_CHECK_NULL_PTR, RA8_PRIV, and s_tag_tar_f.

Referenced by internal_decode_header().

◆ priv_unarch_tar_pax_parse()

ra8_err_t priv_unarch_tar_pax_parse ( const uint8_t * data,
size_t len,
char * name_buf,
uint16_t name_cap,
uint16_t * name_len,
bool * have_path,
uint64_t * size_ovr,
bool * have_size )
nodiscard

Parse pax extended-header records, extracting path / size.

Walks the "%d key=value\n" record stream fail-closed: a record whose declared length is non-decimal, too small, overruns the data, or lacks the '=' / trailing newline rejects the whole header. A path record is copied into name_buf (clamped to name_cap) and a size record is decimal-decoded with overflow checks; every other key is skipped.

Parameters
[in]datapax data bytes (non-NULL).
[in]lenpax data length (<= k_unarch_tar_pax_max).
[out]name_bufBuffer for a path value (may be NULL if name_cap is 0).
[in]name_capCapacity of name_buf in bytes.
[out]name_lenReceives the copied path length (non-NULL).
[out]have_pathSet true when a path record was applied (non-NULL).
[out]size_ovrReceives a decoded size value (non-NULL).
[out]have_sizeSet true when a size record was applied (non-NULL).
Returns
ra8_err_t Error code.
Return values
k_ra8_okRecords parsed; overrides reported.
k_ra8_err_null_ptrA required pointer was NULL.
k_ra8_err_validation_failedA malformed record (bad length, missing '=', missing newline, bad size value).
Precondition
data holds len readable bytes.
The output flags are initialised by the caller (false / 0).
Postcondition
On k_ra8_ok the flags reflect exactly the records present.
On any error the walk must reject the member (fail-closed).
Note
Thread-safe: writes only through its out-parameters.
MC/DC:
Promoted to TU-external linkage so tests can drive every malformed record shape (length, delimiter, terminator, value) directly.
Since
Version 0.1.0

Definition at line 388 of file unarch_tar_fields.c.

References internal_pax_apply(), internal_pax_reclen(), k_ra8_err_validation_failed, k_ra8_ok, RA8_CHECK_NULL_PTR, RA8_PRIV, and s_tag_tar_f.

Referenced by internal_meta_consume().