ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
mdl_verify.c
Go to the documentation of this file.
1
11#include "mdl_verify.h"
12
13#include <ctype.h>
14#include <limits.h>
15#include <string.h>
16
17#include "jof.h"
18#include "mdl_verify_internal.h"
20#include "miniz.h"
21#include "ra8_attributes.h"
22
24typedef struct {
25 size_t bytes;
26 max_align_t align;
28
29RA8_PRIV void*
30priv_mdl_verify_workspace_take(mdl_export_workspace_t* workspace, size_t bytes, size_t alignment)
31{
32 if ((bytes == 0U) || (alignment == 0U) || ((alignment & (alignment - 1U)) != 0U)) {
33 return nullptr;
34 }
35 const size_t mask = alignment - 1U;
36 uintptr_t base = 0U;
37 static_assert(sizeof(base) >= sizeof(workspace->data), "uintptr_t must preserve object pointers");
38 (void)memcpy((void*)&base, (const void*)&workspace->data, sizeof(workspace->data));
39 if ((workspace->used > (size_t)(UINTPTR_MAX - base)) ||
40 ((base + (uintptr_t)workspace->used) > (UINTPTR_MAX - (uintptr_t)mask))) {
41 return nullptr;
42 }
43 const uintptr_t cursor = base + (uintptr_t)workspace->used;
44 const uintptr_t aligned = (cursor + (uintptr_t)mask) & ~(uintptr_t)mask;
45 const size_t start = (size_t)(aligned - base);
46 if ((start > workspace->cap) || (bytes > (workspace->cap - start))) {
47 return nullptr;
48 }
49 workspace->used = start + bytes;
50 if (workspace->used > workspace->high_water) {
51 workspace->high_water = workspace->used;
52 }
53 return &workspace->data[start];
54}
55
62RA8_INTERNAL static bool internal_ends_ci(const char* text, const char* suffix)
63{
64 const size_t text_len = strlen(text);
65 const size_t suffix_len = strlen(suffix);
66 if (suffix_len > text_len) {
67 return false;
68 }
69 for (size_t i = 0U; i < suffix_len; ++i) {
70 const unsigned char left = (unsigned char)text[text_len - suffix_len + i];
71 const unsigned char right = (unsigned char)suffix[i];
72 if (tolower(left) != tolower(right)) {
73 return false;
74 }
75 }
76 return true;
77}
78
79RA8_PRIV bool priv_mdl_verify_is_image(const char* name)
80{
81 return internal_ends_ci(name, ".jpg") || internal_ends_ci(name, ".jpeg") ||
82 internal_ends_ci(name, ".png") || internal_ends_ci(name, ".webp") ||
83 internal_ends_ci(name, ".gif") || internal_ends_ci(name, ".bmp");
84}
85
87{
88 if ((name == nullptr) || (name[0] == '\0') || (name[0] == '/') || (name[0] == '\\')) {
89 return false;
90 }
91 const char* segment = name;
92 for (const char* cursor = name;; ++cursor) {
93 if ((*cursor == '\\') || (*cursor == '/') || (*cursor == '\0')) {
94 const size_t bytes = (size_t)(cursor - segment);
95 if ((*cursor == '\\') || (bytes == 0U) || ((bytes == 1U) && (segment[0] == '.')) ||
96 ((bytes == 2U) && (segment[0] == '.') && (segment[1] == '.'))) {
97 return false;
98 }
99 if (*cursor == '\0') {
100 return true;
101 }
102 segment = cursor + 1;
103 }
104 }
105}
106
107ra8_err_t mdl_format_from_path(const char* path, mdl_format_t* out_format)
108{
109 if ((path == nullptr) || (out_format == nullptr)) {
111 }
112 static const struct {
113 const char* suffix;
114 mdl_format_t format;
115 } formats[] = {{".cbt.gz", k_mdl_format_cbt_gz},
116 {".rabook", k_mdl_format_rabook},
117 {".epub", k_mdl_format_epub},
118 {".cbz", k_mdl_format_cbz},
119 {".cbt", k_mdl_format_cbt},
120 {".jof", k_mdl_format_jof}};
121 for (size_t i = 0U; i < (sizeof(formats) / sizeof(formats[0])); ++i) {
122 if (internal_ends_ci(path, formats[i].suffix)) {
123 *out_format = formats[i].format;
124 return k_ra8_ok;
125 }
126 }
127 *out_format = k_mdl_format_invalid;
129}
130
132{
133 return (format == k_mdl_format_cbz) || (format == k_mdl_format_cbt) ||
134 (format == k_mdl_format_cbt_gz) || (format == k_mdl_format_epub) ||
135 (format == k_mdl_format_jof) || (format == k_mdl_format_rabook);
136}
137
138RA8_PRIV void* priv_mdl_verify_arena_alloc(void* opaque, size_t items, size_t size)
139{
140 mdl_verify_arena_t* arena = (mdl_verify_arena_t*)opaque;
141 if ((items != 0U) && (size > (SIZE_MAX / items))) {
142 arena->exhausted = true;
143 return nullptr;
144 }
145 const size_t bytes = items * size;
146 if (bytes > (SIZE_MAX - sizeof(mdl_alloc_header_t))) {
147 arena->exhausted = true;
148 return nullptr;
149 }
150 mdl_alloc_header_t* header =
152 sizeof(*header) + bytes,
153 _Alignof(max_align_t));
154 if (header == nullptr) {
155 arena->exhausted = true;
156 return nullptr;
157 }
158 header->bytes = bytes;
159 return (void*)(header + 1);
160}
161
162RA8_PRIV void priv_mdl_verify_arena_free(void* opaque, void* address)
163{
164 (void)opaque;
165 (void)address;
166}
167
169RA8_INTERNAL static void*
170internal_arena_realloc(void* opaque, void* address, size_t items, size_t size)
171{
172 if (address == nullptr) {
173 return priv_mdl_verify_arena_alloc(opaque, items, size);
174 }
175 if ((items != 0U) && (size > (SIZE_MAX / items))) {
176 ((mdl_verify_arena_t*)opaque)->exhausted = true;
177 return nullptr;
178 }
179 mdl_alloc_header_t* previous = ((mdl_alloc_header_t*)address) - 1;
180 void* next = priv_mdl_verify_arena_alloc(opaque, items, size);
181 if (next != nullptr) {
182 const size_t next_bytes = items * size;
183 memcpy(next, address, previous->bytes < next_bytes ? previous->bytes : next_bytes);
184 }
185 return next;
186}
187
195internal_io_open(mdl_storage_t* storage, const char* path, mdl_verify_io_t* io)
196{
197 *io = (mdl_verify_io_t){.storage = storage, .read_error = k_ra8_ok};
198 io->file = &io->owned_file;
199 ra8_err_t error = fw_fs_open(&storage->fs->streams,
200 path,
202 io->file,
203 storage->file_workspace,
204 storage->file_workspace_bytes);
205 if (error != k_ra8_ok) {
206 return error;
207 }
208 io->owned = true;
209 error = fw_fs_file_size(io->file, &io->size_bytes);
210 if (error != k_ra8_ok) {
211 (void)fw_fs_close(io->file);
212 io->owned = false;
213 }
214 return error;
215}
216
224{
225 if (!io->owned) {
226 return prior;
227 }
228 const ra8_err_t close_error = fw_fs_close(io->file);
229 io->owned = false;
230 return (prior == k_ra8_ok) ? close_error : prior;
231}
232
234 uint8_t* destination,
235 size_t length,
236 size_t* out_read)
237{
238 size_t total = 0U;
239 while (total < length) {
240 const size_t remaining = length - total;
241 const uint32_t chunk = (remaining > UINT32_MAX) ? UINT32_MAX : (uint32_t)remaining;
242 uint32_t got = 0U;
243 const ra8_err_t err = fw_fs_read(io->file, destination + total, chunk, &got);
244 if (err != k_ra8_ok) {
245 *out_read = total;
246 return err;
247 }
248 total += got;
249 if (got == 0U) {
250 break;
251 }
252 }
253 *out_read = total;
254 return k_ra8_ok;
255}
256
263RA8_INTERNAL static size_t
264internal_zip_read(void* opaque, mz_uint64 offset, void* destination, size_t length)
265{
266 mdl_verify_io_t* io = (mdl_verify_io_t*)opaque;
267 if ((io->read_error != k_ra8_ok) || (offset > io->size_bytes)) {
268 return 0U;
269 }
270 const uint64_t available = io->size_bytes - offset;
271 if ((uint64_t)length > available) {
272 length = (size_t)available;
273 }
274 ra8_err_t error = fw_fs_seek(io->file, offset);
275 size_t got = 0U;
276 if (error == k_ra8_ok) {
277 error = priv_mdl_verify_io_read_up_to(io, (uint8_t*)destination, length, &got);
278 }
279 if ((error == k_ra8_ok) && (got != length)) {
281 }
282 if (error != k_ra8_ok) {
283 io->read_error = error;
284 }
285 return got;
286}
287
294RA8_INTERNAL static size_t
295internal_discard_zip(void* opaque, mz_uint64 offset, const void* data, size_t bytes)
296{
297 (void)opaque;
298 (void)offset;
299 (void)data;
300 return bytes;
301}
302
304typedef struct {
305 size_t members;
306 size_t pages;
307 bool mimetype;
309 bool opf;
310 bool nav;
313
321internal_zip_member(mz_zip_archive* zip, mz_uint index, mdl_zip_scan_t* scan)
322{
323 mz_zip_archive_file_stat member;
324 if (mz_zip_reader_file_stat(zip, index, &member) == MZ_FALSE) {
326 }
327 if (!priv_mdl_verify_safe_member_name(member.m_filename)) {
329 }
330 if (!member.m_is_directory &&
331 (mz_zip_reader_extract_to_callback(zip, index, internal_discard_zip, nullptr, 0) ==
332 MZ_FALSE)) {
334 }
335 const char* name = member.m_filename;
336 scan->pages += priv_mdl_verify_is_image(name) ? 1U : 0U;
337 scan->comicinfo = scan->comicinfo || internal_ends_ci(name, "ComicInfo.xml");
338 scan->mimetype = scan->mimetype || (strcmp(name, "mimetype") == 0);
339 scan->container = scan->container || (strcmp(name, "META-INF/container.xml") == 0);
340 scan->opf = scan->opf || internal_ends_ci(name, ".opf");
341 scan->nav = scan->nav || internal_ends_ci(name, "nav.xhtml");
342 return k_ra8_ok;
343}
344
353{
354 if ((scan->members == 0U) || (scan->pages == 0U)) {
356 }
357 if ((format == k_mdl_format_cbz) && !scan->comicinfo) {
359 }
360 if ((format == k_mdl_format_epub) &&
361 !(scan->mimetype && scan->container && scan->opf && scan->nav)) {
363 }
364 report->page_count = scan->pages;
365 report->member_count = scan->members;
366 report->metadata_present = (format == k_mdl_format_cbz) ? scan->comicinfo : scan->opf;
367 return k_ra8_ok;
368}
369
377 mdl_format_t format,
378 mdl_export_workspace_t* workspace,
379 mdl_verify_report_t* report)
380{
381 mdl_verify_arena_t arena = {.workspace = workspace};
382 mz_zip_archive zip = {};
383 zip.m_pAlloc = priv_mdl_verify_arena_alloc;
384 zip.m_pFree = priv_mdl_verify_arena_free;
385 zip.m_pRealloc = internal_arena_realloc;
386 zip.m_pAlloc_opaque = &arena;
387 zip.m_pRead = internal_zip_read;
388 zip.m_pIO_opaque = io;
389 ra8_err_t error;
390 if ((io->size_bytes == 0U) || (mz_zip_reader_init(&zip, io->size_bytes, 0) == MZ_FALSE)) {
392 } else {
393 const mz_uint total = mz_zip_reader_get_num_files(&zip);
394 mdl_zip_scan_t scan = {.members = total};
396 for (mz_uint i = 0U; (error == k_ra8_ok) && (i < total); ++i) {
397 error = internal_zip_member(&zip, i, &scan);
398 }
399 if ((error == k_ra8_ok) && (mz_zip_reader_end(&zip) == MZ_FALSE)) {
401 }
402 if (arena.exhausted) {
404 } else if (error == k_ra8_ok) {
405 error = internal_zip_semantics(format, &scan, report);
406 }
407 }
408 if (io->read_error != k_ra8_ok) {
409 error = io->read_error;
410 }
411 return error;
412}
413
421internal_jof_pread(void* opaque, uint64_t offset, uint8_t* destination, size_t length, size_t* got)
422{
423 mdl_verify_io_t* io = (mdl_verify_io_t*)opaque;
424 *got = 0U;
425 if (offset > io->size_bytes) {
426 return k_ra8_ok;
427 }
428 const uint64_t available = io->size_bytes - offset;
429 if ((uint64_t)length > available) {
430 length = (size_t)available;
431 }
432 const ra8_err_t error = fw_fs_seek(io->file, offset);
433 return (error == k_ra8_ok) ? priv_mdl_verify_io_read_up_to(io, destination, length, got) : error;
434}
435
443{
444 ra8_err_t error;
445 if (io->size_bytes == 0U) {
447 } else {
448 jof_info_t info;
449 error = jof_parse(internal_jof_pread, io, io->size_bytes, &info);
450 if (error == k_ra8_ok) {
451 report->page_count = 1U;
452 report->member_count = info.tile_count;
453 }
454 }
455 return error;
456}
457
465 mdl_format_t format,
466 mdl_export_workspace_t* workspace,
467 mdl_verify_report_t* report)
468{
469 switch (format) {
470 case k_mdl_format_cbz:
472 return internal_verify_zip(io, format, workspace, report);
473 case k_mdl_format_cbt:
474 return priv_mdl_verify_tar(io, report);
475 case k_mdl_format_jof:
476 return internal_verify_jof(io, report);
478 return priv_mdl_verify_gzip_tar(io, workspace, report);
480 return priv_mdl_verify_rabook(io->file, io->size_bytes, workspace, report);
481 case k_mdl_format_cbr:
486 default:
488 }
489}
490
492 mdl_format_t format,
493 fw_fs_file_t* file,
494 uint64_t size_bytes,
495 mdl_export_workspace_t* workspace,
496 mdl_verify_report_t* report)
497{
498 if ((storage == nullptr) || (storage->io_buffer == nullptr) || (storage->io_buffer_bytes == 0U) ||
499 (file == nullptr) || (workspace == nullptr) || (workspace->data == nullptr) ||
500 (report == nullptr)) {
502 }
503 workspace->used = 0U;
504 workspace->high_water = 0U;
505 mdl_verify_report_t candidate = {.format = format};
506 mdl_verify_io_t io = {.storage = storage,
507 .file = file,
508 .size_bytes = size_bytes,
509 .read_error = k_ra8_ok};
510 ra8_err_t error = fw_fs_seek(file, 0U);
511 if (error == k_ra8_ok) {
512 error = internal_verify_borrowed(&io, format, workspace, &candidate);
513 }
514 if (error == k_ra8_ok) {
515 *report = candidate;
516 }
517 return error;
518}
519
521 mdl_format_t format,
522 const char* path,
523 mdl_export_workspace_t* workspace,
524 mdl_verify_report_t* report)
525{
526 if ((storage == nullptr) || (storage->fs == nullptr) || (storage->file_workspace == nullptr) ||
527 (storage->file_workspace_bytes == 0U) || (storage->io_buffer == nullptr) ||
528 (storage->io_buffer_bytes == 0U) || (path == nullptr) || (workspace == nullptr) ||
529 (workspace->data == nullptr) || (report == nullptr)) {
531 }
532 workspace->used = 0U;
533 workspace->high_water = 0U;
535 ra8_err_t error = internal_io_open(storage, path, &io);
536 mdl_verify_report_t candidate;
537 if (error == k_ra8_ok) {
538 error = mdl_verify_open_file(storage, format, io.file, io.size_bytes, workspace, &candidate);
539 error = internal_io_close(&io, error);
540 }
541 if (error == k_ra8_ok) {
542 *report = candidate;
543 }
544 return error;
545}
ra8_err_t fw_fs_open(const fw_fs_stream_port_t *streams, const char *path, fw_fs_open_mode_t mode, fw_fs_file_t *file, void *workspace, uint32_t workspace_size)
Open a file into a caller-owned handle and backend workspace.
Definition fw_if_fs.c:648
ra8_err_t fw_fs_read(fw_fs_file_t *file, uint8_t *dst, uint32_t cap, uint32_t *out_read)
Read up to cap bytes; zero bytes is EOF.
Definition fw_if_fs.c:699
ra8_err_t fw_fs_close(fw_fs_file_t *file)
Close and consume an open handle.
Definition fw_if_fs.c:783
ra8_err_t fw_fs_seek(fw_fs_file_t *file, uint64_t absolute_offset)
Seek to an absolute byte offset from the beginning.
Definition fw_if_fs.c:736
ra8_err_t fw_fs_file_size(fw_fs_file_t *file, uint64_t *out_size)
Report the open file's current length.
Definition fw_if_fs.c:758
@ k_fw_fs_open_read
Existing file, read-only.
JOF band-tile atlas: the display-native normalized image format (#231, shared with the longstrip scro...
ra8_err_t jof_parse(jof_pread_fn pread, void *pread_ctx, uint64_t total_size, jof_info_t *out_info)
Parse + validate a JOF atlas's header, footer and index bounds.
Definition jof.c:379
struct mdl_export_workspace mdl_export_workspace_t
Caller-owned bounded arena for all exporter scratch state.
mdl_format_t
Artifact format selected by a media-download composition root.
Definition mdl_format.h:35
@ k_mdl_format_cbz
ZIP of images (.cbz).
Definition mdl_format.h:37
@ k_mdl_format_invalid
Unrecognized or unsupported selection.
Definition mdl_format.h:45
@ k_mdl_format_loose
Leave loose page images.
Definition mdl_format.h:36
@ k_mdl_format_cbr
Reserved RAR output.
Definition mdl_format.h:39
@ k_mdl_format_epub
Fixed-layout EPUB (.epub).
Definition mdl_format.h:42
@ k_mdl_format_cbt_gz
Gzip-compressed tar (.cbt.gz).
Definition mdl_format.h:41
@ k_mdl_format_cbt_xz
Reserved xz-compressed tar output.
Definition mdl_format.h:40
@ k_mdl_format_rabook
Chunked reader-native book (.rabook).
Definition mdl_format.h:44
@ k_mdl_format_jof
Native JOF tile atlas per page (.jof).
Definition mdl_format.h:43
@ k_mdl_format_cbt
Tar of images (.cbt).
Definition mdl_format.h:38
static bool internal_ends_ci(const char *text, const char *suffix)
Test a suffix without case sensitivity.
Definition mdl_verify.c:62
ra8_err_t mdl_verify_open_file(mdl_storage_t *storage, mdl_format_t format, fw_fs_file_t *file, uint64_t size_bytes, mdl_export_workspace_t *workspace, mdl_verify_report_t *report)
Validate an artifact through a borrowed open filesystem handle.
Definition mdl_verify.c:491
void priv_mdl_verify_arena_free(void *opaque, void *address)
Accept a miniz free for a monotonic arena.
Definition mdl_verify.c:162
ra8_err_t mdl_verify_file(mdl_storage_t *storage, mdl_format_t format, const char *path, mdl_export_workspace_t *workspace, mdl_verify_report_t *report)
Validate a completed artifact using caller-owned scratch only.
Definition mdl_verify.c:520
bool mdl_format_is_verifiable(mdl_format_t format)
Report whether a format has an in-process structural validator.
Definition mdl_verify.c:131
static ra8_err_t internal_io_close(mdl_verify_io_t *io, ra8_err_t prior)
Close an input without masking prior failure.
Definition mdl_verify.c:223
static ra8_err_t internal_io_open(mdl_storage_t *storage, const char *path, mdl_verify_io_t *io)
Open a portable read-only input.
Definition mdl_verify.c:195
ra8_err_t mdl_format_from_path(const char *path, mdl_format_t *out_format)
Infer an artifact format from its complete path suffix.
Definition mdl_verify.c:107
static ra8_err_t internal_zip_member(mz_zip_archive *zip, mz_uint index, mdl_zip_scan_t *scan)
Validate one ZIP member.
Definition mdl_verify.c:321
static ra8_err_t internal_verify_borrowed(mdl_verify_io_t *io, mdl_format_t format, mdl_export_workspace_t *workspace, mdl_verify_report_t *report)
Dispatch validation over one borrowed input.
Definition mdl_verify.c:464
ra8_err_t priv_mdl_verify_io_read_up_to(mdl_verify_io_t *io, uint8_t *destination, size_t length, size_t *out_read)
Read up to a requested portable span.
Definition mdl_verify.c:233
static void * internal_arena_realloc(void *opaque, void *address, size_t items, size_t size)
Grow a miniz span by copying it to the next arena allocation.
Definition mdl_verify.c:170
static ra8_err_t internal_verify_zip(mdl_verify_io_t *io, mdl_format_t format, mdl_export_workspace_t *workspace, mdl_verify_report_t *report)
Validate a ZIP-backed artifact.
Definition mdl_verify.c:376
bool priv_mdl_verify_safe_member_name(const char *name)
Reject unsafe archive member paths.
Definition mdl_verify.c:86
static size_t internal_zip_read(void *opaque, mz_uint64 offset, void *destination, size_t length)
Adapt portable reads to miniz.
Definition mdl_verify.c:264
static ra8_err_t internal_verify_jof(mdl_verify_io_t *io, mdl_verify_report_t *report)
Validate a JOF artifact.
Definition mdl_verify.c:442
static ra8_err_t internal_jof_pread(void *opaque, uint64_t offset, uint8_t *destination, size_t length, size_t *got)
Adapt JOF positioned reads.
Definition mdl_verify.c:421
void * priv_mdl_verify_workspace_take(mdl_export_workspace_t *workspace, size_t bytes, size_t alignment)
Reserve one aligned span from the verifier's caller-owned arena.
Definition mdl_verify.c:30
void * priv_mdl_verify_arena_alloc(void *opaque, size_t items, size_t size)
Allocate one aligned miniz span from a monotonic arena.
Definition mdl_verify.c:138
static size_t internal_discard_zip(void *opaque, mz_uint64 offset, const void *data, size_t bytes)
Discard verified ZIP output.
Definition mdl_verify.c:295
static ra8_err_t internal_zip_semantics(mdl_format_t format, const mdl_zip_scan_t *scan, mdl_verify_report_t *report)
Enforce ZIP format semantics.
Definition mdl_verify.c:352
bool priv_mdl_verify_is_image(const char *name)
Recognize supported image suffixes.
Definition mdl_verify.c:79
Bounded, no-heap structural validation of mdl artifacts.
Private bounded validator seams shared by the mdl verifiers.
ra8_err_t priv_mdl_verify_tar(mdl_verify_io_t *io, mdl_verify_report_t *report)
Validate an uncompressed CBT.
@ k_verify_member_max
Maximum archive member count.
ra8_err_t priv_mdl_verify_gzip_tar(mdl_verify_io_t *io, mdl_export_workspace_t *workspace, mdl_verify_report_t *report)
Validate a gzip-compressed CBT.
ra8_err_t priv_mdl_verify_rabook(fw_fs_file_t *file, uint64_t size_bytes, mdl_export_workspace_t *workspace, mdl_verify_report_t *report)
Strictly validate one borrowed RBKC .rabook file.
Private strict RBKC validator seam for media downloader artifacts.
Annotation-attribute framework macros for ra8-firmware.
#define RA8_PRIV
Module-private helper: shared across TUs but only inside one library.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
@ k_ra8_err_not_supported
Requested feature not compiled in, not wired, or not supported by this MCU variant.
Definition ra8_err.h:180
@ k_ra8_err_invalid_arg
Invalid function argument.
Definition ra8_err.h:152
@ k_ra8_err_validation_failed
Validation rule failed (caller-supplied invariant not satisfied).
Definition ra8_err.h:459
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
@ k_ra8_err_invalid_size
Invalid size parameter (too large, too small, or misaligned).
Definition ra8_err.h:167
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
int strcmp(const char *s1, const char *s2)
Compare two null-terminated strings.
size_t strlen(const char *s)
Calculate string length.
void * memcpy(void *dst, const void *src, size_t n)
Copy memory area between non-overlapping regions.
Caller-owned open file; fields are private to the facade.
fw_fs_stream_port_t streams
Byte-stream operations.
Parsed + validated geometry of one JOF atlas.
Definition jof.h:208
uint32_t tile_count
Total tiles (== cols * rows).
Definition jof.h:217
Header stored before each monotonic miniz allocation.
Definition mdl_verify.c:24
max_align_t align
Forces maximum payload alignment.
Definition mdl_verify.c:26
size_t bytes
Payload extent.
Definition mdl_verify.c:25
size_t high_water
Largest used value observed.
Definition mdl_export.h:221
size_t used
Current allocation high edge.
Definition mdl_export.h:220
size_t cap
Total arena capacity.
Definition mdl_export.h:219
uint8_t * data
Writable arena bytes.
Definition mdl_export.h:218
One non-reentrant downloader filesystem dependency bundle.
Definition mdl_storage.h:40
uint32_t file_workspace_bytes
File workspace extent.
Definition mdl_storage.h:45
uint8_t * io_buffer
Caller-owned stream scratch.
Definition mdl_storage.h:44
const fw_fs_t * fs
Injected portable filesystem.
Definition mdl_storage.h:41
void * file_workspace
Open-file backend state.
Definition mdl_storage.h:42
uint32_t io_buffer_bytes
Stream scratch extent.
Definition mdl_storage.h:47
Allocation bridge retaining an explicit capacity failure.
bool exhausted
An allocation did not fit.
mdl_export_workspace_t * workspace
Caller-owned bump arena.
One open portable input and its immutable size snapshot.
uint64_t size_bytes
Length observed after open.
Semantic markers accumulated while scanning ZIP members.
Definition mdl_verify.c:304
bool mimetype
EPUB mimetype found.
Definition mdl_verify.c:307
size_t pages
Image member count.
Definition mdl_verify.c:306
bool opf
EPUB package document found.
Definition mdl_verify.c:309
bool nav
EPUB navigation found.
Definition mdl_verify.c:310
bool comicinfo
CBZ ComicInfo.xml found.
Definition mdl_verify.c:311
bool container
EPUB container.xml found.
Definition mdl_verify.c:308
size_t members
Total member count.
Definition mdl_verify.c:305