BufLength
Description
Current byte count of b. Read-only (the comma-expression form rejects BufLength(b) = n at compile time – use BufResize).
Usage example (Cross-references)
Usage examples (Cross-references)
- In
Io.c:1120:
bool ok = render_binary_fmt(&tmp, fmtstr, argv, argc);
if (ok) {
if (offset > BufLength(out) || StrLen(&tmp) > BufLength(out) - offset) {
LOG_ERROR(
"BufPatchFmt: write of {} bytes at offset {} exceeds buf length {}",- In
Io.c:1125:
StrLen(&tmp),
offset,
BufLength(out)
);
ok = false;- In
MachO.c:120:
static bool decode_header(MachoContext *ctx) {
Macho *m = ctx->out;
if (BufLength(&m->data) < MH_HEADER_64_SIZE) {
LOG_ERROR("MachO: file too small for header");
return false;- In
MachO.c:281:
static bool walk_load_commands(MachoContext *ctx) {
if ((u64)MH_HEADER_64_SIZE + ctx->sizeofcmds > BufLength(&ctx->out->data)) {
LOG_ERROR("MachO: load commands overrun file");
return false;- In
MachO.c:345:
}
u64 tab_end = (u64)ctx->symoff + (u64)ctx->nsyms * NLIST64_SIZE;
if (tab_end > BufLength(&ctx->out->data)) {
LOG_ERROR("MachO: symtab past EOF");
return false;- In
MachO.c:350:
}
u64 str_end = (u64)ctx->stroff + ctx->strsize;
if (str_end > BufLength(&ctx->out->data)) {
LOG_ERROR("MachO: symbol strtab past EOF");
return false;- In
Elf.c:110:
static bool elf_range_ok(const Elf *self, u64 offset, u64 size) {
if (offset > BufLength(&self->data))
return false;
if (size > BufLength(&self->data))- In
Elf.c:112:
if (offset > BufLength(&self->data))
return false;
if (size > BufLength(&self->data))
return false;
// After the two checks above both `offset` and `size` are
- In
Elf.c:116:
// After the two checks above both `offset` and `size` are
// bounded by `data_size`; subtracting cannot wrap.
if (size > BufLength(&self->data) - offset)
return false;
return true;- In
Elf.c:126:
static bool elf_decode_header(Elf *self) {
if (BufLength(&self->data) < EI_NIDENT + EHDR64_SIZE_AFTER_IDENT) {
LOG_ERROR("Elf: file too small for ELF64 header ({} bytes)", (u64)BufLength(&self->data));
return false;- In
Elf.c:127:
static bool elf_decode_header(Elf *self) {
if (BufLength(&self->data) < EI_NIDENT + EHDR64_SIZE_AFTER_IDENT) {
LOG_ERROR("Elf: file too small for ELF64 header ({} bytes)", (u64)BufLength(&self->data));
return false;
}- In
Pdb.c:89:
static const u8 *block_ptr(const Pdb *self, u32 block_id) {
u64 off = (u64)block_id * self->block_size;
if (off + self->block_size > BufLength(&self->data))
return NULL;
return BufData(&self->data) + off;- In
Pdb.c:137:
static bool parse_superblock(Pdb *self, u32 *out_num_dir_bytes, u32 *out_block_map_addr) {
if (BufLength(&self->data) < SUPERBLOCK_SIZE) {
LOG_ERROR("PDB: file too small for MSF superblock");
return false;- In
Pdb.c:145:
return false;
}
BufIter sb = BufIterFromMemory(BufData(&self->data) + 32, BufLength(&self->data) - 32);
u32 free_blk, num_blocks, unknown;
if (!BufReadFmt(- In
Pdb.c:167:
return false;
}
if ((u64)num_blocks * self->block_size != BufLength(&self->data)) {
// Some PDBs come with trailing padding; the spec says num_blocks
// * block_size should equal file size. We warn but don't fail.
- In
Pe.c:159:
// DOS header gives us e_lfanew, the offset to the NT headers.
static bool pe_decode_dos(PeContext *ctx) {
if (BufLength(&ctx->out->data) < 64) {
LOG_ERROR("PE: file too small for DOS header");
return false;- In
Pe.c:175:
BufIter c = BufIterFromMemory(
BufData(&ctx->out->data) + DOS_E_LFANEW_OFFSET,
BufLength(&ctx->out->data) - DOS_E_LFANEW_OFFSET
);
if (!BufReadU32LE(&c, &e_lfanew))- In
Pe.c:179:
if (!BufReadU32LE(&c, &e_lfanew))
return false;
if (e_lfanew >= BufLength(&ctx->out->data)) {
LOG_ERROR("PE: e_lfanew past EOF");
return false;- In
Pe.c:190:
static bool pe_decode_nt(PeContext *ctx, u64 *out_opt_offset) {
BufIter c =
BufIterFromMemory(BufData(&ctx->out->data) + ctx->nt_offset, BufLength(&ctx->out->data) - ctx->nt_offset);
u32 sig;
if (!BufReadU32LE(&c, &sig) || sig != NT_SIGNATURE) {- In
Pe.c:216:
// NumberOfRvaAndSizes, and the DataDirectory[DEBUG] entry.
static bool pe_decode_optional(PeContext *ctx, u64 opt_offset) {
if (opt_offset > BufLength(&ctx->out->data) || ctx->opt_hdr_size > BufLength(&ctx->out->data) - opt_offset) {
LOG_ERROR("PE: optional header overruns file");
return false;- In
Pe.c:370:
static bool pe_decode_sections(PeContext *ctx, u64 opt_offset) {
u64 sec_offset = opt_offset + ctx->opt_hdr_size;
BufIter c = BufIterFromMemory(BufData(&ctx->out->data) + sec_offset, BufLength(&ctx->out->data) - sec_offset);
for (u32 i = 0; i < ctx->num_sections; ++i) {- In
Pe.c:432:
};
u32 num_entries = ctx->debug_dir_size / DEBUG_ENTRY_SIZE;
if (dir_offset + (u64)num_entries * DEBUG_ENTRY_SIZE > BufLength(&ctx->out->data)) {
LOG_ERROR("PE: debug directory overruns file");
return;- In
Pe.c:439:
for (u32 i = 0; i < num_entries; ++i) {
u64 entry_off = dir_offset + (u64)i * DEBUG_ENTRY_SIZE;
BufIter c = BufIterFromMemory(BufData(&ctx->out->data) + entry_off, BufLength(&ctx->out->data) - entry_off);
u32 charac, ts, type, sz, raddr, rptr;
u16 ver_maj, ver_min;- In
Pe.c:451:
if (type != IMAGE_DEBUG_TYPE_CODEVIEW)
continue;
if (rptr + (u64)sz > BufLength(&ctx->out->data)) {
LOG_ERROR("PE: codeview record points outside file");
continue;- In
Pe.c:591:
if (rva >= vstart && (u64)rva < vend) {
u64 off = (u64)s->raw_offset + ((u64)rva - vstart);
if (off >= BufLength(&self->data))
return false;
*out_offset = off;- In
Buf.c:16:
DefaultAllocator alloc = DefaultAllocatorInit();
Buf b = BufInit(&alloc);
bool ok = BufLength(&b) == 0;
BufWriteU8(&b, 0x42);
BufWriteU8(&b, 0x43);- In
Buf.c:19:
BufWriteU8(&b, 0x42);
BufWriteU8(&b, 0x43);
ok = ok && BufLength(&b) == 2 && BufData(&b)[0] == 0x42 && BufData(&b)[1] == 0x43;
BufClear(&b);
ok = ok && BufLength(&b) == 0;- In
Buf.c:21:
ok = ok && BufLength(&b) == 2 && BufData(&b)[0] == 0x42 && BufData(&b)[1] == 0x43;
BufClear(&b);
ok = ok && BufLength(&b) == 0;
BufDeinit(&b);
DefaultAllocatorDeinit(&alloc);- In
Buf.c:44:
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // u64 BE
};
bool ok = BufLength(&b) == sizeof(expect) && MemCompare(BufData(&b), expect, sizeof(expect)) == 0;
BufDeinit(&b);
DefaultAllocatorDeinit(&alloc);- In
Buf.c:58:
BufWriteULeb128(&b, 16384);
const u8 expect_uleb[] = {0x00, 0x7F, 0x80, 0x01, 0x80, 0x80, 0x01};
if (BufLength(&b) != sizeof(expect_uleb) || MemCompare(BufData(&b), expect_uleb, sizeof(expect_uleb)) != 0) {
BufDeinit(&b);
DefaultAllocatorDeinit(&alloc);- In
Buf.c:70:
BufWriteSLeb128(&b, -64);
const u8 expect_sleb[] = {0x00, 0x7F, 0xC0, 0x00, 0x40};
bool ok = BufLength(&b) == sizeof(expect_sleb) && MemCompare(BufData(&b), expect_sleb, sizeof(expect_sleb)) == 0;
BufDeinit(&b);- In
Buf.c:82:
BufWriteZstr(&b, "hi");
const u8 expect[] = {'h', 'i', 0};
bool ok = BufLength(&b) == sizeof(expect) && MemCompare(BufData(&b), expect, sizeof(expect)) == 0;
BufDeinit(&b);
DefaultAllocatorDeinit(&alloc);- In
Buf.c:158:
bool ok = BufAppendFmt(&b, "{<2r}{>4r}", (u16)0xCAFE, (u32)0xDEADBEEF);
const u8 expect[] = {0x99, 0xFE, 0xCA, 0xDE, 0xAD, 0xBE, 0xEF};
ok = ok && BufLength(&b) == sizeof(expect) && MemCompare(BufData(&b), expect, sizeof(expect)) == 0;
BufDeinit(&b);
DefaultAllocatorDeinit(&alloc);- In
Buf.c:172:
bool ok = BufWriteFmt(&b, "{<2r}", (u16)0x1234);
const u8 expect[] = {0x34, 0x12};
ok = ok && BufLength(&b) == sizeof(expect) && MemCompare(BufData(&b), expect, sizeof(expect)) == 0;
BufDeinit(&b);
DefaultAllocatorDeinit(&alloc);- In
Buf.c:200:
0x11
};
ok = ok && BufLength(&b) == sizeof(expect) && MemCompare(BufData(&b), expect, sizeof(expect)) == 0;
// Out-of-range patch must fail and leave the buf unchanged.
- In
Buf.c:204:
// Out-of-range patch must fail and leave the buf unchanged.
Buf snapshot = BufInit(&alloc);
BufPushBytes(&snapshot, BufData(&b), BufLength(&b));
ok = ok && !BufPatchFmt(&b, BufLength(&b), "{<2r}", (u16)0);
ok = ok && BufLength(&b) == BufLength(&snapshot);- In
Buf.c:205:
Buf snapshot = BufInit(&alloc);
BufPushBytes(&snapshot, BufData(&b), BufLength(&b));
ok = ok && !BufPatchFmt(&b, BufLength(&b), "{<2r}", (u16)0);
ok = ok && BufLength(&b) == BufLength(&snapshot);
ok = ok && MemCompare(BufData(&b), BufData(&snapshot), BufLength(&b)) == 0;- In
Buf.c:206:
BufPushBytes(&snapshot, BufData(&b), BufLength(&b));
ok = ok && !BufPatchFmt(&b, BufLength(&b), "{<2r}", (u16)0);
ok = ok && BufLength(&b) == BufLength(&snapshot);
ok = ok && MemCompare(BufData(&b), BufData(&snapshot), BufLength(&b)) == 0;
BufDeinit(&snapshot);- In
Buf.c:207:
ok = ok && !BufPatchFmt(&b, BufLength(&b), "{<2r}", (u16)0);
ok = ok && BufLength(&b) == BufLength(&snapshot);
ok = ok && MemCompare(BufData(&b), BufData(&snapshot), BufLength(&b)) == 0;
BufDeinit(&snapshot);- In
Dns.c:25:
0x00, 0x00, 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
0x03, 'c', 'o', 'm', 0x00, 0x00, 0x01, 0x00, 0x01};
bool match = ok && BufLength(&buf) == sizeof(expected);
for (u64 i = 0; match && i < sizeof(expected); ++i) {
if (BufData(&buf)[i] != expected[i]) {- In
Dns.c:46:
bool ok = DnsBuildQuery(&no_dot, 1, "a.b.c", DNS_TYPE_AAAA) && DnsBuildQuery(&w_dot, 1, "a.b.c.", DNS_TYPE_AAAA);
bool match = ok && BufLength(&no_dot) == BufLength(&w_dot);
for (u64 i = 0; match && i < BufLength(&no_dot); ++i) {
if (BufData(&no_dot)[i] != BufData(&w_dot)[i]) {- In
Dns.c:47:
bool match = ok && BufLength(&no_dot) == BufLength(&w_dot);
for (u64 i = 0; match && i < BufLength(&no_dot); ++i) {
if (BufData(&no_dot)[i] != BufData(&w_dot)[i]) {
match = false;
Last updated on