Skip to content

BufReadFmt

Description

Read raw bytes from the cursor iter according to fmtstr. Only {<Nr} (LE) and {>Nr} (BE) directives with N in {1, 2, 4, 8} are accepted; the destination variable’s natural width must match the spec width.

Success

Returns true; iter advances past the consumed bytes and every destination variable is filled.

Failure

Returns false on format-parse error or cursor overflow. iter and destination variables may be left partially updated by directives that ran before the failure.

Usage example (Cross-references)

Usage examples (Cross-references)
        BufIter c = BufIterFromBuf(&m->data);
        u32     magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags, reserved;
        if (!BufReadFmt(
                &c,
                FMT_MACHO_HEADER_LE,
        IterMustMove(cmd, 16);
        u32 maxprot, initprot;
        if (!BufReadFmt(
                cmd,
                FMT_MACHO_SEGMENT64_BODY_LE,
            IterMustMove(&sec_it, 16);
            u32 align, reloff, nreloc, reserved1, reserved2, reserved3;
            if (!BufReadFmt(
                    &sec_it,
                    FMT_MACHO_SECTION64_BODY_LE,
        }
        IterMustMove(cmd, 8); // skip cmd + cmdsize prefix
        if (!BufReadFmt(cmd, FMT_MACHO_SYMTAB_BODY_LE, ctx->symoff, ctx->nsyms, ctx->stroff, ctx->strsize)) {
            LOG_ERROR("MachO: LC_SYMTAB body truncated");
            return false;
            BufIter prefix = IterCarve(&walker, 8);
            u32     cmd, cmdsize;
            if (!BufReadFmt(&prefix, FMT_MACHO_LC_PREFIX_LE, cmd, cmdsize)) {
                LOG_ERROR("MachO: load command prefix truncated at {}", i);
                return false;
            u16 n_desc;
            u64 n_value;
            if (!BufReadFmt(&tab, FMT_MACHO_NLIST64_LE, n_strx, n_type, n_sect, n_desc, n_value)) {
                LOG_ERROR("MachO: nlist_64 truncated at index {}", i);
                return false;
        u64 entry = 0, phoff = 0, shoff = 0;
    
        BufReadFmt(
            &iter,
            FMT_EHDR64_LE,
            u32 name = 0, type = 0, link = 0, info = 0;
            u64 flags = 0, addr = 0, offset = 0, size_ = 0, addralign = 0, entsize = 0;
            BufReadFmt(&iter, FMT_SHDR64_LE, name, type, flags, addr, offset, size_, link, info, addralign, entsize);
            shstr_off  = offset;
            shstr_size = size_;
            u64 flags = 0, addr = 0, offset = 0, size_ = 0, addralign = 0, entsize = 0;
    
            BufReadFmt(&iter, FMT_SHDR64_LE, name, type, flags, addr, offset, size_, link, info, addralign, entsize);
    
            ElfSection s;
            u64 value = 0, size_ = 0;
    
            BufReadFmt(&iter, FMT_SYM64_LE, name, info, other, shndx, value, size_);
    
            ElfSymbol s;
        u8 raw_lb      = 0;
        if (version >= 4) {
            if (!BufReadFmt(
                    cur,
                    FMT_DWARF_LINE_HDR_V4_TAIL_LE,
            }
        } else {
            if (!BufReadFmt(
                    cur,
                    FMT_DWARF_LINE_HDR_V3_TAIL_LE,
            u8  addr_size;
            // DWARF v4 CU header tail after unit_length: 2 + 4 + 1 bytes.
            if (!BufReadFmt(&info_cur, "{<2r}{<4r}{<1r}", version, abbrev_offset, addr_size)) {
                ok = false;
                break;
        BufIter sb = BufIterFromMemory(BufData(&self->data) + 32, BufLength(&self->data) - 32);
        u32     free_blk, num_blocks, unknown;
        if (!BufReadFmt(
                &sb,
                FMT_PDB_SUPERBLOCK_LE,
                break;
            BufIter bi = BufIterFromMemory(VecBegin(&buf), VecCapacity(&buf));
            if (!BufReadFmt(&bi, FMT_PDB_INFO_LE, self->info.version, self->info.signature, self->info.age)) {
                LOG_ERROR("PDB: info stream prefix truncated");
                break;
    
            BufIter bi = BufIterFromMemory(VecBegin(&hdr), VecCapacity(&hdr));
            if (!BufReadFmt(
                    &bi,
                    FMT_PDB_DBI_HEADER_LE,
                u32     flags, offset;
                u16     segment;
                if (!BufReadFmt(&body, FMT_S_PUB32_PREFIX_LE, flags, offset, segment)) {
                    cur = next;
                    continue;
        u16 type_bits, class_bits, rdlength;
        u32 ttl;
        if (!BufReadFmt(it, "{>2r}{>2r}{>4r}{>2r}", type_bits, class_bits, ttl, rdlength)) {
            return false;
        }
        BufIter it = BufIterFromMemory(buf, len);
        u16     flags, qd, an, ns, ar;
        if (!BufReadFmt(&it, "{>2r}{>2r}{>2r}{>2r}{>2r}{>2r}", out->id, flags, qd, an, ns, ar)) {
            return false;
        }
            StrDeinit(&dummy);
            u16 qtype, qclass;
            if (!BufReadFmt(&it, "{>2r}{>2r}", qtype, qclass)) {
                return false;
            }
        u16 machine, num_sec, size_opt, chars;
        u32 timestamp, sym_ptr, num_sym;
        if (!BufReadFmt(&c, FMT_PE_FILE_HEADER_LE, machine, num_sec, timestamp, sym_ptr, num_sym, size_opt, chars)) {
            LOG_ERROR("PE: file header truncated");
            return false;
        if (is64) {
            u64 stack_res, stack_com, heap_res, heap_com;
            if (!BufReadFmt(
                    &c,
                    FMT_PE_OPT_HDR_PE32PLUS_LE,
        } else {
            u32 base_of_data, image_base32, stack_res, stack_com, heap_res, heap_com;
            if (!BufReadFmt(
                    &c,
                    FMT_PE_OPT_HDR_PE32_LE,
            u32 ptr_relocs, ptr_linenums;
            u16 num_relocs, num_linenums;
            if (!BufReadFmt(
                    &c,
                    FMT_PE_SECTION_HEADER_LE,
            u32     charac, ts, type, sz, raddr, rptr;
            u16     ver_maj, ver_min;
            if (!BufReadFmt(&c, FMT_PE_DEBUG_DIR_LE, charac, ts, ver_maj, ver_min, type, sz, raddr, rptr))
                return;
            (void)charac;
        u32     v32;
        u64     v64;
        bool    ok = BufReadFmt(&it, "{<2r}{>4r}{<8r}", v16, v32, v64);
        ok         = ok && v16 == 0x1234 && v32 == 0xDEADBEEF && v64 == 0x0102030405060708ull;
        ok         = ok && IterRemainingLength(&it) == 0;
        u16     v16   = 0;
        u32     v32   = 0;
        bool    ok    = !BufReadFmt(&it, "{<2r}{<4r}", v16, v32);
        // Atomic rollback: pos restored, output vars left as initialized.
        ok = ok && it.pos == entry && v32 == 0;
Last updated on