|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Untrusted-byte parsers for the tar walker: numerics, checksum, pax. More...
#include <string.h>#include "ra8_attributes.h"#include "ra8_check.h"#include "unarch_tar_internal.h"Go to the source code of this file.
Enumerations | |
| enum | tar_field_const_t : uint32_t { k_tar_octal_base = 8U , k_tar_decimal_base = 10U , k_tar_b256_flag = 0x80U , k_tar_b256_negative = 0x40U , k_tar_b256_payload = 0x7FU , k_tar_b256_fit = 8U , k_tar_shift_byte = 8U , k_tar_pax_len_max = 7U , k_tar_chksum_space = (uint32_t)' ' } |
| Grammar constants for the numeric and pax record parsers. More... | |
Functions | |
| static ra8_err_t | internal_octal (const uint8_t *field, size_t len, uint64_t *out) |
| Decode an octal ASCII field (leading spaces, NUL/space terminated). | |
| static ra8_err_t | internal_base256 (const uint8_t *field, size_t len, uint64_t *out) |
| Decode a GNU base-256 (big-endian binary) numeric field. | |
| 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. | |
| static ra8_err_t | internal_pax_reclen (const uint8_t *data, size_t len, size_t *reclen, size_t *body) |
| Decode one pax record's decimal length prefix. | |
| static ra8_err_t | internal_pax_size_value (const uint8_t *val, size_t len, uint64_t *out) |
| Decimal-decode a pax size record value with overflow checks. | |
| static ra8_err_t | internal_pax_apply (const uint8_t *key, size_t key_len, const uint8_t *val, size_t val_len, char *name_buf, uint16_t name_cap, uint16_t *name_len, bool *have_path, uint64_t *size_ovr, bool *have_size) |
| Apply one parsed pax record's key/value to the override outputs. | |
| 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. | |
Variables | |
| static const char *const | s_tag_tar_f = "unarch_tar" |
| Log tag for tar field-parser diagnostics. | |
Untrusted-byte parsers for the tar walker: numerics, checksum, pax.
Every function in this TU consumes raw hostile bytes and must be individually fail-closed; they are TU-external (declared in unarch_tar_internal.h) so the host tests drive each rejection branch directly. Grammar sources: the POSIX.1-2017 pax Interchange Format (header block layout, octal fields, d key=value\n records) and the documented GNU tar base-256 numeric extension. Clean-room: no code from GNU tar / libarchive / busybox.
Definition in file unarch_tar_fields.c.
| enum tar_field_const_t : uint32_t |
Grammar constants for the numeric and pax record parsers.
Definition at line 42 of file unarch_tar_fields.c.
|
static |
Decode a GNU base-256 (big-endian binary) numeric field.
Byte 0 carries the 0x80 marker; the remaining bits are a big-endian two's-complement value. Negative values and values that cannot fit a uint64 are rejected fail-closed.
| [in] | field | Field bytes (byte 0 has the marker set). |
| [in] | len | Field length in bytes. |
| [out] | out | Receives the value. |
| k_ra8_ok | Decoded. |
| k_ra8_err_validation_failed | Negative or over 64 bits. |
field / out are non-NULL (caller-guarded). out is modified. Definition at line 125 of file unarch_tar_fields.c.
References k_ra8_err_validation_failed, k_ra8_ok, k_tar_b256_fit, k_tar_b256_negative, k_tar_b256_payload, and k_tar_shift_byte.
Referenced by priv_unarch_tar_num().
|
static |
Decode an octal ASCII field (leading spaces, NUL/space terminated).
The POSIX numeric field shape. Rejects an empty digit run, a non-octal byte before the terminator, and 64-bit overflow.
| [in] | field | Field bytes. |
| [in] | len | Field length in bytes. |
| [out] | out | Receives the value. |
| k_ra8_ok | Decoded. |
| k_ra8_err_validation_failed | Empty / malformed / overflowing. |
field holds len readable bytes (caller-guarded non-NULL). out is non-NULL (caller-guarded). out is modified. Definition at line 72 of file unarch_tar_fields.c.
References k_ra8_err_validation_failed, k_ra8_ok, and k_tar_octal_base.
Referenced by priv_unarch_tar_checksum_ok(), and priv_unarch_tar_num().
|
static |
Apply one parsed pax record's key/value to the override outputs.
path copies the value into the caller name buffer (clamped); size decimal-decodes it; every other key is ignored.
| [in] | key | Key bytes. |
| [in] | key_len | Key length. |
| [in] | val | Value bytes. |
| [in] | val_len | Value length. |
| [out] | name_buf | Caller name buffer (may be NULL if cap 0). |
| [in] | name_cap | Name buffer capacity. |
| [out] | name_len | Receives a copied path length. |
| [out] | have_path | Set when a path was applied. |
| [out] | size_ovr | Receives a decoded size. |
| [out] | have_size | Set when a size was applied. |
| k_ra8_ok | Record applied or ignored. |
| k_ra8_err_validation_failed | A malformed size value. |
Definition at line 348 of file unarch_tar_fields.c.
References internal_pax_size_value(), k_ra8_ok, and memcpy().
Referenced by priv_unarch_tar_pax_parse().
|
static |
Decode one pax record's decimal length prefix.
Digits up to k_tar_pax_len_max, terminated by one space; the resulting length must cover at least the prefix itself.
| [in] | data | Record bytes. |
| [in] | len | Bytes available from the record start. |
| [out] | reclen | Receives the declared record length. |
| [out] | body | Receives the offset of the first byte after the space. |
| k_ra8_ok | Length decoded. |
| k_ra8_err_validation_failed | Malformed / oversized prefix. |
data holds len readable bytes (caller-guarded non-NULL). reclen / body are non-NULL (caller-owned locals). len. Definition at line 246 of file unarch_tar_fields.c.
References k_ra8_err_validation_failed, k_ra8_ok, k_tar_decimal_base, and k_tar_pax_len_max.
Referenced by priv_unarch_tar_pax_parse().
|
static |
Decimal-decode a pax size record value with overflow checks.
Plain non-negative decimal digits only (the pax size value grammar); an empty value, any non-digit byte, or a value that would overflow uint64 rejects the record fail-closed.
| [in] | val | Value bytes (between '=' and the newline). |
| [in] | len | Value length in bytes. |
| [out] | out | Receives the size. |
| k_ra8_ok | Decoded. |
| k_ra8_err_validation_failed | Empty, non-decimal, or overflowing. |
val holds len readable bytes (caller-guarded non-NULL). out is a caller-owned local (non-NULL). Definition at line 299 of file unarch_tar_fields.c.
References k_ra8_err_validation_failed, k_ra8_ok, and k_tar_decimal_base.
Referenced by internal_pax_apply().
|
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).
| [in] | block | One k_unarch_tar_block byte block (non-NULL). |
| true | End-of-archive marker. |
| false | At least one non-zero byte. |
block holds a full block of readable bytes. block is non-NULL (caller-guarded). Definition at line 162 of file unarch_tar_fields.c.
References k_unarch_tar_block, and RA8_PRIV.
Referenced by unarch_tar_next().
|
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.
| [in] | block | One k_unarch_tar_block byte block (non-NULL). |
| true | Checksum holds. |
| false | Mismatch or undecodable chksum field. |
block holds a full block of readable bytes. block is non-NULL (caller-guarded). 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().
|
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.
| [in] | typeflag | The header's typeflag byte. |
| k_ra8_tar_type_other | For any flag this reader does not handle. |
typeflag.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().
|
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.
| [in] | block | One k_unarch_tar_block byte block (non-NULL). |
| true | POSIX ustar or old-GNU magic. |
| false | Anything else (including v7 headers). |
block holds a full block of readable bytes. block is non-NULL (caller-guarded). 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().
|
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.
| [in] | field | Field bytes (non-NULL). |
| [in] | len | Field length in bytes (> 0). |
| [out] | out | Receives the decoded value (non-NULL). |
| k_ra8_ok | Value decoded into out. |
| k_ra8_err_null_ptr | field or out was NULL. |
| k_ra8_err_validation_failed | Empty, malformed, negative, or overflowing field. |
field holds len readable bytes. len is a real header-field length (bounded by the block size). 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().
|
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.
| [in] | data | pax data bytes (non-NULL). |
| [in] | len | pax data length (<= k_unarch_tar_pax_max). |
| [out] | name_buf | Buffer for a path value (may be NULL if name_cap is 0). |
| [in] | name_cap | Capacity of name_buf in bytes. |
| [out] | name_len | Receives the copied path length (non-NULL). |
| [out] | have_path | Set true when a path record was applied (non-NULL). |
| [out] | size_ovr | Receives a decoded size value (non-NULL). |
| [out] | have_size | Set true when a size record was applied (non-NULL). |
| k_ra8_ok | Records parsed; overrides reported. |
| k_ra8_err_null_ptr | A required pointer was NULL. |
| k_ra8_err_validation_failed | A malformed record (bad length, missing '=', missing newline, bad size value). |
data holds len readable bytes. 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().
|
static |
Log tag for tar field-parser diagnostics.
Definition at line 29 of file unarch_tar_fields.c.
Referenced by priv_unarch_tar_num(), and priv_unarch_tar_pax_parse().