Blame src/regression/flockfile-list.c

Szabolcs Nagy 50ab48
// commit: 3e936ce81bbbcc968f576aedbd5203621839f152 2014-09-19
Szabolcs Nagy 50ab48
// flockfile linked list handling was broken
Szabolcs Nagy 50ab48
#include <errno.h>
Szabolcs Nagy 50ab48
#include <stdio.h>
Szabolcs Nagy 50ab48
#include <stdlib.h>
Szabolcs Nagy 50ab48
#include <string.h>
Szabolcs Nagy 50ab48
#include "test.h"
Szabolcs Nagy 50ab48
Szabolcs Nagy 7b91ce
#define t_fatal(...) (t_error(__VA_ARGS__), _Exit(t_status))
Szabolcs Nagy 7b91ce
#define length(a) (sizeof(a)/sizeof*(a))
Szabolcs Nagy 7b91ce
Szabolcs Nagy 7b91ce
// interpose malloc functions
Szabolcs Nagy 7b91ce
// freed memory is not reused, it is checked for clobber.
Szabolcs Nagy 7b91ce
Szabolcs Nagy 7b91ce
static unsigned char buf[1<<20];
Szabolcs Nagy 7b91ce
static size_t pos;
Szabolcs Nagy 7b91ce
static struct {
Szabolcs Nagy 7b91ce
	size_t pos;
Szabolcs Nagy 7b91ce
	size_t n;
Szabolcs Nagy 7b91ce
	int freed;
Szabolcs Nagy 7b91ce
} alloc[100];
Szabolcs Nagy 7b91ce
static int idx;
Szabolcs Nagy 7b91ce
Szabolcs Nagy 7b91ce
void *malloc(size_t n)
Szabolcs Nagy 7b91ce
{
Szabolcs Nagy 7b91ce
	if (n == 0) n++;
Szabolcs Nagy 7b91ce
	if (n > sizeof buf - pos)
Szabolcs Nagy 7b91ce
		t_fatal("test buffer is small, pos: %zu, need: %zu\n", pos, n);
Szabolcs Nagy 7b91ce
	if (idx >= length(alloc))
Szabolcs Nagy 7b91ce
		t_fatal("test buffer is small, idx: %d\n", idx);
Szabolcs Nagy 7b91ce
	void *p = buf + pos;
Szabolcs Nagy 7b91ce
	alloc[idx].pos = pos;
Szabolcs Nagy 7b91ce
	alloc[idx].n = n;
Szabolcs Nagy 7b91ce
	pos += n;
Szabolcs Nagy 7b91ce
	idx++;
Szabolcs Nagy 7b91ce
	return p;
Szabolcs Nagy 7b91ce
}
Szabolcs Nagy 7b91ce
Szabolcs Nagy 7b91ce
void *calloc(size_t n, size_t m)
Szabolcs Nagy 7b91ce
{
Szabolcs Nagy 7b91ce
	return memset(malloc(n*m), 0, n*m);
Szabolcs Nagy 7b91ce
}
Szabolcs Nagy 7b91ce
Szabolcs Nagy 7b91ce
void *aligned_alloc(size_t a, size_t n)
Szabolcs Nagy 7b91ce
{
Szabolcs Nagy 7b91ce
	t_fatal("aligned_alloc is unsupported\n");
Szabolcs Nagy 7b91ce
}
Szabolcs Nagy 7b91ce
Szabolcs Nagy 7b91ce
static int findidx(void *p)
Szabolcs Nagy 7b91ce
{
Szabolcs Nagy 7b91ce
	size_t pos = (unsigned char *)p - buf;
Szabolcs Nagy 7b91ce
	for (int i=0; i
Szabolcs Nagy 7b91ce
		if (alloc[i].pos == pos)
Szabolcs Nagy 7b91ce
			return i;
Szabolcs Nagy 7b91ce
	t_fatal("%p is not an allocated pointer\n", p);
Szabolcs Nagy 7b91ce
	return -1;
Szabolcs Nagy 7b91ce
}
Szabolcs Nagy 7b91ce
Szabolcs Nagy 7b91ce
void *realloc(void *p, size_t n)
Szabolcs Nagy 7b91ce
{
Szabolcs Nagy 7b91ce
	void *q = malloc(n);
Szabolcs Nagy 7b91ce
	size_t m = alloc[findidx(p)].n;
Szabolcs Nagy 7b91ce
	memcpy(q, p, m < n ? m : n);
Szabolcs Nagy 7b91ce
	free(p);
Szabolcs Nagy 7b91ce
	return q;
Szabolcs Nagy 7b91ce
}
Szabolcs Nagy 7b91ce
Szabolcs Nagy 7b91ce
void free(void *p)
Szabolcs Nagy 7b91ce
{
Szabolcs Nagy 7b91ce
	if (p == 0) return;
Szabolcs Nagy 7b91ce
	int i = findidx(p);
Szabolcs Nagy 7b91ce
	memset(p, 42, alloc[i].n);
Szabolcs Nagy 7b91ce
	alloc[i].freed = 1;
Szabolcs Nagy 7b91ce
}
Szabolcs Nagy 7b91ce
Szabolcs Nagy 7b91ce
static void checkfreed(void)
Szabolcs Nagy 7b91ce
{
Szabolcs Nagy 7b91ce
	for (int i=0; i
Szabolcs Nagy 7b91ce
		if (alloc[i].freed)
Szabolcs Nagy 7b91ce
			for (size_t j=0; j
Szabolcs Nagy 7b91ce
				if (buf[alloc[i].pos + j] != 42) {
Szabolcs Nagy 7b91ce
					t_error("freed allocation %d (pos: %zu, len: %zu) is clobbered\n", i, alloc[i].pos, alloc[i].n);
Szabolcs Nagy 7b91ce
					break;
Szabolcs Nagy 7b91ce
				}
Szabolcs Nagy 7b91ce
}
Szabolcs Nagy 7b91ce
Szabolcs Nagy 50ab48
int main()
Szabolcs Nagy 50ab48
{
Szabolcs Nagy 50ab48
	FILE *f = tmpfile();
Szabolcs Nagy 50ab48
	FILE *g = tmpfile();
Szabolcs Nagy 50ab48
	flockfile(g);
Szabolcs Nagy 50ab48
	flockfile(f);
Szabolcs Nagy 50ab48
	funlockfile(g);
Szabolcs Nagy 50ab48
	fclose(g);
Szabolcs Nagy 50ab48
	/* may corrupt memory */
Szabolcs Nagy 50ab48
	funlockfile(f);
Szabolcs Nagy 7b91ce
	checkfreed();
Szabolcs Nagy 50ab48
	return t_status;
Szabolcs Nagy 50ab48
}