Gunnar

nordisk/heimdall

guests/verify-bundle/openzl/shim/hzl.c

// SPDX-License-Identifier: AGPL-3.0-only
// Heimdall is a defensive sandbox. The ONLY C written for the verify-bundle
// guest's OpenZL decoder (wasm32 builds; native builds link openzl-sys-rs):
//
// 1. hzl_frame_size / hzl_decode: ZL_getDecompressedSize and ZL_decompress
//    behind a scalar-only ABI (ZL_Report is a struct returned by value; the
//    guest's Rust never sees it).
// 2. The few libc symbols OpenZL's decoder references that are not memory
//    functions: its logging (fprintf/vfprintf/fputc/stderr) and its error-
//    message formatting (vsnprintf) — the guest has no stdio, so they write
//    nothing — and abort, which traps.
//
// malloc/calloc/realloc/free are the guest's Rust allocator (src/zl.rs);
// memcpy/memmove/memset come from Rust's compiler-builtins. Everything is
// compiled into the module: the guest component imports nothing but the WIT.
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>

#include "openzl/zl_decompress.h"
#include "openzl/zl_errors.h"

// 0 = ok and *out set; otherwise the ZL_ErrorCode.
int hzl_frame_size(const void* src, size_t src_len, uint64_t* out)
{
    ZL_Report r = ZL_getDecompressedSize(src, src_len);
    if (ZL_isError(r)) {
        return (int)ZL_errorCode(r);
    }
    *out = (uint64_t)ZL_validResult(r);
    return 0;
}

int hzl_decode(void* dst, size_t cap, const void* src, size_t src_len, size_t* written)
{
    ZL_Report r = ZL_decompress(dst, cap, src, src_len);
    if (ZL_isError(r)) {
        return (int)ZL_errorCode(r);
    }
    *written = ZL_validResult(r);
    return 0;
}

const char* hzl_error_name(int code)
{
    return ZL_ErrorCode_toString((ZL_ErrorCode)code);
}

// ---- the libc the decoder references (no stdio in the guest) ----

FILE* const stderr = NULL;

int vfprintf(FILE* restrict f, const char* restrict fmt, va_list ap)
{
    (void)f;
    (void)fmt;
    (void)ap;
    return 0;
}

int fprintf(FILE* restrict f, const char* restrict fmt, ...)
{
    (void)f;
    (void)fmt;
    return 0;
}

int fputc(int c, FILE* f)
{
    (void)f;
    return c;
}

int vsnprintf(char* restrict buf, size_t n, const char* restrict fmt, va_list ap)
{
    (void)fmt;
    (void)ap;
    if (n > 0) {
        buf[0] = '\0';
    }
    return 0;
}

_Noreturn void abort(void)
{
    __builtin_trap();
}