shithub: libtags

ref: 4a7f42e378e27bf70c928b411ac859c870c23f24
dir: /harness.c/

View raw version
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "tags.h"

typedef struct Aux Aux;

struct Aux {
	const uint8_t *in;
	int sz;
	int off;
};

#define USED(x) (void)x

#ifndef __AFL_FUZZ_TESTCASE_LEN
  ssize_t fuzz_len;
  #define __AFL_FUZZ_TESTCASE_LEN fuzz_len
  unsigned char fuzz_buf[1024000];
  #define __AFL_FUZZ_TESTCASE_BUF fuzz_buf
  #define __AFL_FUZZ_INIT() void sync(void);
  #define __AFL_LOOP(x) ((fuzz_len = read(0, fuzz_buf, sizeof(fuzz_buf))) > 0 ? 1 : 0)
  #define __AFL_INIT() sync()
#endif

__AFL_FUZZ_INIT()

static void
tag(Tagctx *ctx, int t, Tag *tag)
{
	if(t == Timage){
		static uint8_t *buf;
		static int bufsz;
		int size = tag->image.size;
		if(bufsz < size){
			buf = realloc(buf, size);
			bufsz = size;
		}
		Aux *aux = ctx->aux;
		memcpy(buf, aux->in+tag->image.offset, size);
		if(tag->image.decode != NULL)
			tag->image.decode(buf, &size);
		assert(size >= 0 && size <= bufsz);
	}
}

static void
toc(Tagctx *ctx, int ms, int offset)
{
	USED(ctx); USED(ms); USED(offset);
}

static int
ctxread(Tagctx *ctx, void *buf, int cnt)
{
	Aux *aux = ctx->aux;
	int max = aux->sz - aux->off;
	if(cnt < 0)
		cnt = 0;
	else if(cnt > max)
		cnt = max;
	memcpy(buf, aux->in, cnt);
	aux->off += cnt;
	return cnt;
}

static int
ctxseek(Tagctx *ctx, int offset, int whence)
{
	Aux *aux = ctx->aux;
	if(whence == 0)
		aux->off = offset;
	else if(whence == 1)
		aux->off += offset;
	else if(whence == 2)
		aux->off = aux->sz + offset;
	if(aux->off < 0)
		aux->off = 0;
	else if(aux->off > aux->sz)
		aux->off = aux->sz;
	return aux->off;
}

int
main(int argc, char **argv)
{
	char buf[256];
	Aux aux;
	Tagctx ctx = {
		.read = ctxread,
		.seek = ctxseek,
		.tag = tag,
		.toc = toc,
		.buf = buf,
		.bufsz = sizeof(buf),
		.aux = &aux,
	};

	USED(argc); USED(argv);

	#ifdef __AFL_HAVE_MANUAL_CONTROL
	__AFL_INIT();
	#endif

	aux.in = __AFL_FUZZ_TESTCASE_BUF;
	while(__AFL_LOOP(10000)){
		aux.sz = __AFL_FUZZ_TESTCASE_LEN;
		if(aux.sz < 8)
			continue;
		aux.off = 0;
		tagsget(&ctx);
	}

	return 0;
}