# fuzz/Makefile.fuzz - out-of-tree libFuzzer build for the pg_tre regex parser. # # Usage: # cd fuzz # make -f Makefile.fuzz # ./pg_tre_fuzz corpus -max_total_time=900 -rss_limit_mb=2048 -detect_leaks=0 # # Requires: clang with libFuzzer support (clang 12+). PG_CONFIG ?= $(HOME)/.pgrx/18.3/pgrx-install/bin/pg_config ifeq ($(shell test -x $(PG_CONFIG) && echo yes),yes) PG_INCLUDEDIR_SERVER := $(shell $(PG_CONFIG) --includedir-server) PG_INCLUDEDIR := $(shell $(PG_CONFIG) --includedir) PG_LIBDIR := $(shell $(PG_CONFIG) --libdir) else $(error PG_CONFIG=$(PG_CONFIG) is not executable. Set PG_CONFIG to a valid pg_config path.) endif CC := clang # libFuzzer + ASan + symbols + frame pointers for useful stack traces. CFLAGS := -fsanitize=fuzzer,address -g -O1 -fno-omit-frame-pointer # Real PG18 headers come from the server include tree (backend) plus the # internal include tree (postgres_fe.h, c.h, port.h). CFLAGS += -I$(PG_INCLUDEDIR_SERVER) CFLAGS += -I$(PG_INCLUDEDIR)/internal CFLAGS += -I../include CFLAGS += -I../vendor/tre/lib # PostgreSQL-compatible warnings, minus the ones clang doesn't support. CFLAGS += -Wall -Wmissing-prototypes -Wpointer-arith CFLAGS += -Wendif-labels -Wmissing-format-attribute CFLAGS += -Wcast-function-type -Wformat-security CFLAGS += -fno-strict-aliasing -fwrapv # Some pg_tre / vendor sources still mix decls and statements. CFLAGS += -Wno-declaration-after-statement # Define PG_TRE_FUZZ to guard PostgreSQL-only code paths. CFLAGS += -DPG_TRE_FUZZ # libpgcommon supplies palloc/palloc0/pfree/repalloc, the StringInfo # routines, pg_utf_mblen_private, psprintf, pstrdup, etc. libpgport # supplies pg_snprintf, pg_fprintf, pg_strerror, etc. Standard system # libs round it out. PG_LIBS := $(PG_LIBDIR)/libpgcommon.a $(PG_LIBDIR)/libpgport.a LDLIBS := $(PG_LIBS) -lz -lm -lpthread # Source files compiled into the fuzz binary. QUERY_SRCS := ../src/query/parser.c \ ../src/query/tokens.c \ ../src/query/regex_ast.c \ ../src/query/extract.c \ ../src/query/tiling.c \ ../src/query/uleven.c \ ../src/query/tre_grammar.c \ ../src/query/trigram.c UTIL_SRCS := ../src/util/hash.c \ ../src/util/utf8.c FUZZ_SRCS := parse_regex_fuzz.c pg_backend_stub.c ALL_SRCS := $(QUERY_SRCS) $(UTIL_SRCS) $(FUZZ_SRCS) OBJS := $(ALL_SRCS:.c=.o) TARGET := pg_tre_fuzz GRAMMAR_FILE := ../src/query/tre_grammar.c ifeq ($(wildcard $(GRAMMAR_FILE)),) $(error $(GRAMMAR_FILE) not found. Run 'make' in the parent directory first to generate the parser.) endif all: $(TARGET) $(TARGET): $(OBJS) $(CC) $(CFLAGS) -o $@ $^ $(LDLIBS) %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< clean: rm -f $(TARGET) $(OBJS) rm -f *.log crash-* leak-* oom-* slow-* .PHONY: all clean