From: Andrew Dunstan Date: Fri, 10 Apr 2026 13:53:58 +0000 (-0400) Subject: Revert "Add built-in fuzzing harnesses for security testing." X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=eec8e234bdcbe43e0407b03c44484bf75423d515;p=thirdparty%2Fpostgresql.git Revert "Add built-in fuzzing harnesses for security testing." This reverts commit 4a18907b412e77684bf888ad6d1b4844d220196a. inadvertenly pushed, mea culpa --- diff --git a/meson_options.txt b/meson_options.txt index 4f60abccdc3..6a793f3e479 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -43,9 +43,6 @@ option('cassert', type: 'boolean', value: false, option('tap_tests', type: 'feature', value: 'auto', description: 'Enable TAP tests') -option('fuzzing', type: 'boolean', value: false, - description: 'Build fuzz testing targets') - option('injection_points', type: 'boolean', value: false, description: 'Enable injection points') diff --git a/src/test/fuzzing/fuzz_b64decode.c b/src/test/fuzzing/fuzz_b64decode.c deleted file mode 100644 index f388aaf6908..00000000000 --- a/src/test/fuzzing/fuzz_b64decode.c +++ /dev/null @@ -1,98 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fuzz_b64decode.c - * Fuzzing harness for pg_b64_decode() - * - * Copyright (c) 2026, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/test/fuzzing/fuzz_b64decode.c - * - * This harness feeds arbitrary byte sequences to pg_b64_decode(), - * which decodes base64-encoded data per RFC 4648. The function is - * a pure computation with no global state. - * - *------------------------------------------------------------------------- - */ - -#include "postgres_fe.h" - -#include - -#include "common/base64.h" - -int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); - -int -LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) -{ - int dstlen; - uint8 *dst; - - if (size == 0) - return 0; - - /* Allocate a buffer large enough for any valid decoding */ - dstlen = pg_b64_dec_len((int) size); - dst = malloc(dstlen); - if (!dst) - return 0; - - (void) pg_b64_decode((const char *) data, (int) size, dst, dstlen); - - free(dst); - return 0; -} - -#ifdef STANDALONE_FUZZ_TARGET -int -main(int argc, char **argv) -{ - int i; - int ret = 0; - - for (i = 1; i < argc; i++) - { - FILE *f = fopen(argv[i], "rb"); - long len; - uint8_t *buf; - size_t n_read; - - if (!f) - { - fprintf(stderr, "%s: could not open %s: %m\n", argv[0], argv[i]); - ret = 1; - continue; - } - - fseek(f, 0, SEEK_END); - len = ftell(f); - fseek(f, 0, SEEK_SET); - - if (len < 0) - { - fprintf(stderr, "%s: could not determine size of %s\n", - argv[0], argv[i]); - fclose(f); - ret = 1; - continue; - } - - buf = malloc(len); - if (!buf) - { - fprintf(stderr, "%s: out of memory\n", argv[0]); - fclose(f); - return 1; - } - - n_read = fread(buf, 1, len, f); - fclose(f); - - LLVMFuzzerTestOneInput(buf, n_read); - free(buf); - } - - return ret; -} -#endif /* STANDALONE_FUZZ_TARGET */ diff --git a/src/test/fuzzing/fuzz_conninfo.c b/src/test/fuzzing/fuzz_conninfo.c deleted file mode 100644 index 61993704bb5..00000000000 --- a/src/test/fuzzing/fuzz_conninfo.c +++ /dev/null @@ -1,105 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fuzz_conninfo.c - * Fuzzing harness for libpq connection string parsing - * - * Copyright (c) 2026, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/test/fuzzing/fuzz_conninfo.c - * - * This harness feeds arbitrary byte sequences to PQconninfoParse(), - * which parses both key=value connection strings and PostgreSQL URIs - * (postgresql://...). The function is completely standalone and - * requires no database connection or other initialization. - * - *------------------------------------------------------------------------- - */ - -#include "postgres_fe.h" - -#include - -#include "libpq-fe.h" - -int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); - -int -LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) -{ - char *str; - char *errmsg = NULL; - PQconninfoOption *opts; - - if (size == 0) - return 0; - - /* PQconninfoParse expects a NUL-terminated string */ - str = malloc(size + 1); - if (!str) - return 0; - memcpy(str, data, size); - str[size] = '\0'; - - opts = PQconninfoParse(str, &errmsg); - if (opts) - PQconninfoFree(opts); - if (errmsg) - PQfreemem(errmsg); - - free(str); - return 0; -} - -#ifdef STANDALONE_FUZZ_TARGET -int -main(int argc, char **argv) -{ - int i; - int ret = 0; - - for (i = 1; i < argc; i++) - { - FILE *f = fopen(argv[i], "rb"); - long len; - uint8_t *buf; - size_t n_read; - - if (!f) - { - fprintf(stderr, "%s: could not open %s: %m\n", argv[0], argv[i]); - ret = 1; - continue; - } - - fseek(f, 0, SEEK_END); - len = ftell(f); - fseek(f, 0, SEEK_SET); - - if (len < 0) - { - fprintf(stderr, "%s: could not determine size of %s\n", - argv[0], argv[i]); - fclose(f); - ret = 1; - continue; - } - - buf = malloc(len); - if (!buf) - { - fprintf(stderr, "%s: out of memory\n", argv[0]); - fclose(f); - return 1; - } - - n_read = fread(buf, 1, len, f); - fclose(f); - - LLVMFuzzerTestOneInput(buf, n_read); - free(buf); - } - - return ret; -} -#endif /* STANDALONE_FUZZ_TARGET */ diff --git a/src/test/fuzzing/fuzz_json.c b/src/test/fuzzing/fuzz_json.c deleted file mode 100644 index b265ddf0b24..00000000000 --- a/src/test/fuzzing/fuzz_json.c +++ /dev/null @@ -1,104 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fuzz_json.c - * Fuzzing harness for the non-incremental JSON parser - * - * Copyright (c) 2026, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/test/fuzzing/fuzz_json.c - * - * This harness feeds arbitrary byte sequences to pg_parse_json() via - * makeJsonLexContextCstringLen(). It uses the null semantic action so - * that only lexing and structural validation are exercised. - * - * Build with a fuzzing engine (e.g. libFuzzer via -fsanitize=fuzzer) - * or in standalone mode, which reads files named on the command line. - * - *------------------------------------------------------------------------- - */ - -#include "postgres_fe.h" - -#include - -#include "common/jsonapi.h" -#include "mb/pg_wchar.h" - -/* - * Entry point for libFuzzer and other engines that call - * LLVMFuzzerTestOneInput(). - */ -int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); - -int -LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) -{ - JsonLexContext lex; - - if (size == 0) - return 0; - - makeJsonLexContextCstringLen(&lex, (const char *) data, size, - PG_UTF8, true); - setJsonLexContextOwnsTokens(&lex, true); - - (void) pg_parse_json(&lex, &nullSemAction); - - freeJsonLexContext(&lex); - - return 0; -} - -#ifdef STANDALONE_FUZZ_TARGET -int -main(int argc, char **argv) -{ - int i; - int ret = 0; - - for (i = 1; i < argc; i++) - { - FILE *f = fopen(argv[i], "rb"); - long len; - uint8_t *buf; - size_t n_read; - - if (!f) - { - fprintf(stderr, "%s: could not open %s: %m\n", argv[0], argv[i]); - ret = 1; - continue; - } - - fseek(f, 0, SEEK_END); - len = ftell(f); - fseek(f, 0, SEEK_SET); - - if (len < 0) - { - fprintf(stderr, "%s: could not determine size of %s\n", - argv[0], argv[i]); - fclose(f); - ret = 1; - continue; - } - - buf = malloc(len); - if (!buf) - { - fprintf(stderr, "%s: out of memory\n", argv[0]); - fclose(f); - return 1; - } - - n_read = fread(buf, 1, len, f); - fclose(f); - - LLVMFuzzerTestOneInput(buf, n_read); - free(buf); - } - - return ret; -} -#endif /* STANDALONE_FUZZ_TARGET */ diff --git a/src/test/fuzzing/fuzz_json_incremental.c b/src/test/fuzzing/fuzz_json_incremental.c deleted file mode 100644 index 7692f5ca371..00000000000 --- a/src/test/fuzzing/fuzz_json_incremental.c +++ /dev/null @@ -1,127 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fuzz_json_incremental.c - * Fuzzing harness for the incremental JSON parser - * - * Copyright (c) 2026, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/test/fuzzing/fuzz_json_incremental.c - * - * This harness feeds arbitrary byte sequences to - * pg_parse_json_incremental() in small chunks, exercising the - * incremental lexer's boundary handling. The first byte of the input - * is used to vary the chunk size so that the fuzzer can explore - * different splitting strategies. - * - *------------------------------------------------------------------------- - */ - -#include "postgres_fe.h" - -#include - -#include "common/jsonapi.h" -#include "mb/pg_wchar.h" - -int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); - -int -LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) -{ - JsonLexContext lex; - size_t chunk_size; - size_t offset; - - if (size < 2) - return 0; - - /* - * Use the first byte to select a chunk size between 1 and 128. This lets - * the fuzzer explore different ways of splitting the same input across - * incremental parse calls. - */ - chunk_size = (data[0] % 128) + 1; - data++; - size--; - - makeJsonLexContextIncremental(&lex, PG_UTF8, true); - setJsonLexContextOwnsTokens(&lex, true); - - offset = 0; - while (offset < size) - { - size_t remaining = size - offset; - size_t to_feed = (remaining < chunk_size) ? remaining : chunk_size; - bool is_last = (offset + to_feed >= size); - JsonParseErrorType result; - - result = pg_parse_json_incremental(&lex, &nullSemAction, - (const char *) data + offset, - to_feed, is_last); - - offset += to_feed; - - if (result != JSON_SUCCESS && result != JSON_INCOMPLETE) - break; - if (result == JSON_SUCCESS) - break; - } - - freeJsonLexContext(&lex); - - return 0; -} - -#ifdef STANDALONE_FUZZ_TARGET -int -main(int argc, char **argv) -{ - int i; - int ret = 0; - - for (i = 1; i < argc; i++) - { - FILE *f = fopen(argv[i], "rb"); - long len; - uint8_t *buf; - size_t n_read; - - if (!f) - { - fprintf(stderr, "%s: could not open %s: %m\n", argv[0], argv[i]); - ret = 1; - continue; - } - - fseek(f, 0, SEEK_END); - len = ftell(f); - fseek(f, 0, SEEK_SET); - - if (len < 0) - { - fprintf(stderr, "%s: could not determine size of %s\n", - argv[0], argv[i]); - fclose(f); - ret = 1; - continue; - } - - buf = malloc(len); - if (!buf) - { - fprintf(stderr, "%s: out of memory\n", argv[0]); - fclose(f); - return 1; - } - - n_read = fread(buf, 1, len, f); - fclose(f); - - LLVMFuzzerTestOneInput(buf, n_read); - free(buf); - } - - return ret; -} -#endif /* STANDALONE_FUZZ_TARGET */ diff --git a/src/test/fuzzing/fuzz_parsepgarray.c b/src/test/fuzzing/fuzz_parsepgarray.c deleted file mode 100644 index 38c67dae419..00000000000 --- a/src/test/fuzzing/fuzz_parsepgarray.c +++ /dev/null @@ -1,102 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fuzz_parsepgarray.c - * Fuzzing harness for parsePGArray() - * - * Copyright (c) 2026, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/test/fuzzing/fuzz_parsepgarray.c - * - * This harness feeds arbitrary byte sequences to parsePGArray(), - * which parses PostgreSQL array literal syntax ({elem,"elem",...}) - * including nested arrays, quoted elements, and backslash escaping. - * The function is standalone and requires no database connection. - * - *------------------------------------------------------------------------- - */ - -#include "postgres_fe.h" - -#include - -#include "fe_utils/string_utils.h" - -int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); - -int -LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) -{ - char *str; - char **items = NULL; - int nitems = 0; - - if (size == 0) - return 0; - - /* parsePGArray expects a NUL-terminated string */ - str = malloc(size + 1); - if (!str) - return 0; - memcpy(str, data, size); - str[size] = '\0'; - - (void) parsePGArray(str, &items, &nitems); - free(items); - - free(str); - return 0; -} - -#ifdef STANDALONE_FUZZ_TARGET -int -main(int argc, char **argv) -{ - int i; - int ret = 0; - - for (i = 1; i < argc; i++) - { - FILE *f = fopen(argv[i], "rb"); - long len; - uint8_t *buf; - size_t n_read; - - if (!f) - { - fprintf(stderr, "%s: could not open %s: %m\n", argv[0], argv[i]); - ret = 1; - continue; - } - - fseek(f, 0, SEEK_END); - len = ftell(f); - fseek(f, 0, SEEK_SET); - - if (len < 0) - { - fprintf(stderr, "%s: could not determine size of %s\n", - argv[0], argv[i]); - fclose(f); - ret = 1; - continue; - } - - buf = malloc(len); - if (!buf) - { - fprintf(stderr, "%s: out of memory\n", argv[0]); - fclose(f); - return 1; - } - - n_read = fread(buf, 1, len, f); - fclose(f); - - LLVMFuzzerTestOneInput(buf, n_read); - free(buf); - } - - return ret; -} -#endif /* STANDALONE_FUZZ_TARGET */ diff --git a/src/test/fuzzing/fuzz_pgbench_expr.c b/src/test/fuzzing/fuzz_pgbench_expr.c deleted file mode 100644 index a326fa7d307..00000000000 --- a/src/test/fuzzing/fuzz_pgbench_expr.c +++ /dev/null @@ -1,211 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fuzz_pgbench_expr.c - * Fuzzing harness for the pgbench expression parser - * - * Copyright (c) 2026, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/test/fuzzing/fuzz_pgbench_expr.c - * - * This harness feeds arbitrary byte sequences to the pgbench expression - * parser (expr_yyparse). The parser exercises a Bison grammar and Flex - * lexer that handle arithmetic expressions, function calls, boolean - * operators, and CASE expressions. - * - * The pgbench expression parser normally calls syntax_error() on any - * parse error, which calls exit(1). This harness provides replacement - * definitions of syntax_error(), strtoint64(), and strtodouble() so - * that the generated parser and lexer objects can link without pulling - * in pgbench.c. Our syntax_error() uses longjmp to recover rather - * than exiting. - * - *------------------------------------------------------------------------- - */ - -#include "postgres_fe.h" - -#include -#include - -#include "pgbench.h" -#include "fe_utils/psqlscan.h" - -static sigjmp_buf fuzz_jmp_buf; - -static void free_pgbench_expr(PgBenchExpr *expr); - -static const PsqlScanCallbacks fuzz_callbacks = { - NULL, /* no variable lookup needed */ -}; - -int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); - -/* - * Replacement for pgbench.c's syntax_error(). Instead of calling exit(), - * we longjmp back to the fuzzer's recovery point. - */ -void -syntax_error(const char *source, int lineno, const char *line, - const char *command, const char *msg, - const char *more, int column) -{ - siglongjmp(fuzz_jmp_buf, 1); -} - -/* - * Replacement for pgbench.c's strtoint64(). - */ -bool -strtoint64(const char *str, bool errorOK, int64 *result) -{ - char *end; - - errno = 0; - *result = strtoi64(str, &end, 10); - - if (errno == ERANGE || errno != 0 || end == str || *end != '\0') - return false; - return true; -} - -/* - * Replacement for pgbench.c's strtodouble(). - */ -bool -strtodouble(const char *str, bool errorOK, double *dv) -{ - char *end; - - errno = 0; - *dv = strtod(str, &end); - - if (errno == ERANGE || errno != 0 || end == str || *end != '\0') - return false; - return true; -} - -/* - * Recursively free a PgBenchExpr tree. - */ -static void -free_pgbench_expr(PgBenchExpr *expr) -{ - PgBenchExprLink *link; - PgBenchExprLink *next; - - if (expr == NULL) - return; - - switch (expr->etype) - { - case ENODE_CONSTANT: - break; - case ENODE_VARIABLE: - pg_free(expr->u.variable.varname); - break; - case ENODE_FUNCTION: - for (link = expr->u.function.args; link != NULL; link = next) - { - next = link->next; - free_pgbench_expr(link->expr); - pg_free(link); - } - break; - } - - pg_free(expr); -} - -int -LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) -{ - char *str; - PsqlScanState sstate; - yyscan_t yyscanner; - PgBenchExpr *result = NULL; - - if (size == 0) - return 0; - - /* expr_yyparse needs a NUL-terminated string */ - str = malloc(size + 1); - if (!str) - return 0; - memcpy(str, data, size); - str[size] = '\0'; - - sstate = psql_scan_create(&fuzz_callbacks); - psql_scan_setup(sstate, str, (int) size, 0, true); - - yyscanner = expr_scanner_init(sstate, "fuzz", 1, 0, "\\set"); - - if (sigsetjmp(fuzz_jmp_buf, 0) == 0) - { - (void) expr_yyparse(&result, yyscanner); - } - - /* Clean up regardless of success or longjmp */ - expr_scanner_finish(yyscanner); - psql_scan_finish(sstate); - psql_scan_destroy(sstate); - - if (result) - free_pgbench_expr(result); - - free(str); - return 0; -} - -#ifdef STANDALONE_FUZZ_TARGET -int -main(int argc, char **argv) -{ - int i; - int ret = 0; - - for (i = 1; i < argc; i++) - { - FILE *f = fopen(argv[i], "rb"); - long len; - uint8_t *buf; - size_t n_read; - - if (!f) - { - fprintf(stderr, "%s: could not open %s: %m\n", argv[0], argv[i]); - ret = 1; - continue; - } - - fseek(f, 0, SEEK_END); - len = ftell(f); - fseek(f, 0, SEEK_SET); - - if (len < 0) - { - fprintf(stderr, "%s: could not determine size of %s\n", - argv[0], argv[i]); - fclose(f); - ret = 1; - continue; - } - - buf = malloc(len); - if (!buf) - { - fprintf(stderr, "%s: out of memory\n", argv[0]); - fclose(f); - return 1; - } - - n_read = fread(buf, 1, len, f); - fclose(f); - - LLVMFuzzerTestOneInput(buf, n_read); - free(buf); - } - - return ret; -} -#endif /* STANDALONE_FUZZ_TARGET */ diff --git a/src/test/fuzzing/fuzz_pglz.c b/src/test/fuzzing/fuzz_pglz.c deleted file mode 100644 index b1912e342d8..00000000000 --- a/src/test/fuzzing/fuzz_pglz.c +++ /dev/null @@ -1,127 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fuzz_pglz.c - * Fuzzing harness for the PostgreSQL LZ decompressor - * - * Copyright (c) 2026, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/test/fuzzing/fuzz_pglz.c - * - * This harness feeds arbitrary byte sequences to pglz_decompress(), - * which decompresses PostgreSQL's native LZ-compressed data. The - * decompressor is a pure function with no global state, making it - * ideal for fuzzing. - * - * The first 4 bytes of the fuzzer input are interpreted as the - * claimed raw (uncompressed) size in little-endian byte order, - * capped at 1 MB. The remaining bytes are the compressed payload. - * - *------------------------------------------------------------------------- - */ - -#include "postgres_fe.h" - -#include -#include - -#include "common/pg_lzcompress.h" - -#define MAX_RAW_SIZE (1024 * 1024) - -int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); - -int -LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) -{ - int32 rawsize; - char *dest; - - /* Need at least 4 bytes for the raw size, plus some compressed data */ - if (size < 5) - return 0; - - /* Extract claimed raw size from first 4 bytes (little-endian) */ - rawsize = (int32) data[0] | - ((int32) data[1] << 8) | - ((int32) data[2] << 16) | - ((int32) data[3] << 24); - - /* Reject nonsensical sizes */ - if (rawsize <= 0 || rawsize > MAX_RAW_SIZE) - return 0; - - dest = malloc(rawsize); - if (!dest) - return 0; - - /* Try decompression with completeness check */ - (void) pglz_decompress((const char *) data + 4, - (int32) (size - 4), - dest, - rawsize, - true); - - /* Also try without completeness check to exercise that path */ - (void) pglz_decompress((const char *) data + 4, - (int32) (size - 4), - dest, - rawsize, - false); - - free(dest); - return 0; -} - -#ifdef STANDALONE_FUZZ_TARGET -int -main(int argc, char **argv) -{ - int i; - int ret = 0; - - for (i = 1; i < argc; i++) - { - FILE *f = fopen(argv[i], "rb"); - long len; - uint8_t *buf; - size_t n_read; - - if (!f) - { - fprintf(stderr, "%s: could not open %s: %m\n", argv[0], argv[i]); - ret = 1; - continue; - } - - fseek(f, 0, SEEK_END); - len = ftell(f); - fseek(f, 0, SEEK_SET); - - if (len < 0) - { - fprintf(stderr, "%s: could not determine size of %s\n", - argv[0], argv[i]); - fclose(f); - ret = 1; - continue; - } - - buf = malloc(len); - if (!buf) - { - fprintf(stderr, "%s: out of memory\n", argv[0]); - fclose(f); - return 1; - } - - n_read = fread(buf, 1, len, f); - fclose(f); - - LLVMFuzzerTestOneInput(buf, n_read); - free(buf); - } - - return ret; -} -#endif /* STANDALONE_FUZZ_TARGET */ diff --git a/src/test/fuzzing/fuzz_rawparser.c b/src/test/fuzzing/fuzz_rawparser.c deleted file mode 100644 index ba5f70c8d7c..00000000000 --- a/src/test/fuzzing/fuzz_rawparser.c +++ /dev/null @@ -1,162 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fuzz_rawparser.c - * Fuzzing harness for the PostgreSQL raw SQL parser - * - * Copyright (c) 2026, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/test/fuzzing/fuzz_rawparser.c - * - * This harness feeds arbitrary byte sequences to raw_parser(), which - * performs lexical and grammatical analysis of SQL statements. It - * performs minimal backend initialization (just the memory-context - * subsystem) and catches all parser errors via PG_TRY/PG_CATCH. - * - * The harness links against postgres_lib using archive semantics. - * It provides stub definitions for symbols normally supplied by - * main/main.c (progname, parse_dispatch_option) so that the linker - * does not pull in main.o and conflict with the harness's own main(). - * - *------------------------------------------------------------------------- - */ - -#include "postgres.h" - -#include - -#include "mb/pg_wchar.h" -#include "miscadmin.h" -#include "parser/parser.h" -#include "postmaster/postmaster.h" -#include "utils/memutils.h" -#include "utils/palloc.h" - -/* - * Stub definitions for symbols that main/main.c normally provides. - * By defining them here we prevent the archive linker from pulling in - * main.o (which defines its own main()). - */ -const char *progname = "fuzz_rawparser"; - -DispatchOption -parse_dispatch_option(const char *name) -{ - return DISPATCH_POSTMASTER; -} - -static bool initialized = false; - -static void fuzz_initialize(void); - -int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); - -/* - * One-time initialization: set up memory contexts and encoding. - */ -static void -fuzz_initialize(void) -{ - MemoryContextInit(); - SetDatabaseEncoding(PG_UTF8); - SetMessageEncoding(PG_UTF8); -} - -int -LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) -{ - char *str; - MemoryContext fuzz_context; - MemoryContext oldcontext; - - if (!initialized) - { - fuzz_initialize(); - initialized = true; - } - - if (size == 0) - return 0; - - /* - * Create a temporary memory context for each parse attempt so that all - * allocations made by the parser are freed afterwards. - */ - fuzz_context = AllocSetContextCreate(TopMemoryContext, - "Fuzz Context", - ALLOCSET_DEFAULT_SIZES); - oldcontext = MemoryContextSwitchTo(fuzz_context); - - /* raw_parser() expects a NUL-terminated string */ - str = palloc(size + 1); - memcpy(str, data, size); - str[size] = '\0'; - - PG_TRY(); - { - (void) raw_parser(str, RAW_PARSE_DEFAULT); - } - PG_CATCH(); - { - FlushErrorState(); - } - PG_END_TRY(); - - MemoryContextSwitchTo(oldcontext); - MemoryContextDelete(fuzz_context); - - return 0; -} - -#ifdef STANDALONE_FUZZ_TARGET -int -main(int argc, char **argv) -{ - int i; - int ret = 0; - - for (i = 1; i < argc; i++) - { - FILE *f = fopen(argv[i], "rb"); - long len; - uint8_t *buf; - size_t n_read; - - if (!f) - { - fprintf(stderr, "%s: could not open %s: %m\n", argv[0], argv[i]); - ret = 1; - continue; - } - - fseek(f, 0, SEEK_END); - len = ftell(f); - fseek(f, 0, SEEK_SET); - - if (len < 0) - { - fprintf(stderr, "%s: could not determine size of %s\n", - argv[0], argv[i]); - fclose(f); - ret = 1; - continue; - } - - buf = malloc(len); - if (!buf) - { - fprintf(stderr, "%s: out of memory\n", argv[0]); - fclose(f); - return 1; - } - - n_read = fread(buf, 1, len, f); - fclose(f); - - LLVMFuzzerTestOneInput(buf, n_read); - free(buf); - } - - return ret; -} -#endif /* STANDALONE_FUZZ_TARGET */ diff --git a/src/test/fuzzing/fuzz_regex.c b/src/test/fuzzing/fuzz_regex.c deleted file mode 100644 index 584ee32bdd6..00000000000 --- a/src/test/fuzzing/fuzz_regex.c +++ /dev/null @@ -1,193 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fuzz_regex.c - * Fuzzing harness for the PostgreSQL regular expression engine - * - * Copyright (c) 2026, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/test/fuzzing/fuzz_regex.c - * - * This harness feeds arbitrary byte sequences to pg_regcomp() and - * pg_regexec(), exercising the full POSIX/ARE regex compiler and - * executor. The first byte selects regex flags; the remaining bytes - * are split between the regex pattern and a test subject string. - * - * The harness links against postgres_lib using archive semantics. - * - *------------------------------------------------------------------------- - */ - -#include "postgres.h" - -#include - -#include "catalog/pg_collation.h" -#include "mb/pg_wchar.h" -#include "miscadmin.h" -#include "postmaster/postmaster.h" -#include "regex/regex.h" -#include "utils/memutils.h" -#include "utils/palloc.h" - -/* Stubs for symbols from main/main.c */ -const char *progname = "fuzz_regex"; - -DispatchOption -parse_dispatch_option(const char *name) -{ - return DISPATCH_POSTMASTER; -} - -static bool initialized = false; - -static void fuzz_initialize(void); - -int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); - -static void -fuzz_initialize(void) -{ - MemoryContextInit(); - SetDatabaseEncoding(PG_UTF8); - SetMessageEncoding(PG_UTF8); -} - -int -LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) -{ - uint8_t flags_byte; - int re_flags; - size_t pat_len; - size_t subj_len; - const char *pat_start; - const char *subj_start; - pg_wchar *pat_wchar; - pg_wchar *subj_wchar; - int pat_wlen; - int subj_wlen; - regex_t re; - regmatch_t matches[10]; - MemoryContext fuzz_context; - MemoryContext oldcontext; - - if (!initialized) - { - fuzz_initialize(); - initialized = true; - } - - /* Need at least flags byte + 1 byte of pattern */ - if (size < 2) - return 0; - - /* - * First byte selects regex flags. We map bits to useful flag combinations - * to get good coverage of different regex modes. - */ - flags_byte = data[0]; - re_flags = REG_ADVANCED; - if (flags_byte & 0x01) - re_flags = REG_EXTENDED; /* ERE instead of ARE */ - if (flags_byte & 0x02) - re_flags |= REG_ICASE; - if (flags_byte & 0x04) - re_flags |= REG_NEWLINE; - if (flags_byte & 0x08) - re_flags |= REG_NOSUB; - - data++; - size--; - - /* Split remaining input: first half pattern, second half subject */ - pat_len = size / 2; - if (pat_len == 0) - pat_len = 1; - subj_len = size - pat_len; - - pat_start = (const char *) data; - subj_start = (const char *) data + pat_len; - - fuzz_context = AllocSetContextCreate(TopMemoryContext, - "Fuzz Context", - ALLOCSET_DEFAULT_SIZES); - oldcontext = MemoryContextSwitchTo(fuzz_context); - - /* Convert to pg_wchar for the regex API */ - pat_wchar = palloc((pat_len + 1) * sizeof(pg_wchar)); - pat_wlen = pg_mb2wchar_with_len(pat_start, pat_wchar, (int) pat_len); - - if (pg_regcomp(&re, pat_wchar, pat_wlen, re_flags, C_COLLATION_OID) == 0) - { - /* Compile succeeded — try executing against the subject */ - if (subj_len > 0) - { - subj_wchar = palloc((subj_len + 1) * sizeof(pg_wchar)); - subj_wlen = pg_mb2wchar_with_len(subj_start, subj_wchar, - (int) subj_len); - - (void) pg_regexec(&re, subj_wchar, subj_wlen, 0, NULL, - lengthof(matches), matches, 0); - } - - pg_regfree(&re); - } - - MemoryContextSwitchTo(oldcontext); - MemoryContextDelete(fuzz_context); - - return 0; -} - -#ifdef STANDALONE_FUZZ_TARGET -int -main(int argc, char **argv) -{ - int i; - int ret = 0; - - for (i = 1; i < argc; i++) - { - FILE *f = fopen(argv[i], "rb"); - long len; - uint8_t *buf; - size_t n_read; - - if (!f) - { - fprintf(stderr, "%s: could not open %s: %m\n", argv[0], argv[i]); - ret = 1; - continue; - } - - fseek(f, 0, SEEK_END); - len = ftell(f); - fseek(f, 0, SEEK_SET); - - if (len < 0) - { - fprintf(stderr, "%s: could not determine size of %s\n", - argv[0], argv[i]); - fclose(f); - ret = 1; - continue; - } - - buf = malloc(len); - if (!buf) - { - fprintf(stderr, "%s: out of memory\n", argv[0]); - fclose(f); - return 1; - } - - n_read = fread(buf, 1, len, f); - fclose(f); - - LLVMFuzzerTestOneInput(buf, n_read); - free(buf); - } - - return ret; -} -#endif /* STANDALONE_FUZZ_TARGET */ diff --git a/src/test/fuzzing/fuzz_saslprep.c b/src/test/fuzzing/fuzz_saslprep.c deleted file mode 100644 index 77170769c7a..00000000000 --- a/src/test/fuzzing/fuzz_saslprep.c +++ /dev/null @@ -1,104 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fuzz_saslprep.c - * Fuzzing harness for pg_saslprep() - * - * Copyright (c) 2026, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/test/fuzzing/fuzz_saslprep.c - * - * This harness feeds arbitrary byte sequences to pg_saslprep(), - * which performs SASLprep normalization (RFC 4013) on UTF-8 strings. - * This involves Unicode NFKC normalization, character mapping, and - * prohibited character detection. The function is standalone and - * requires no database connection. - * - *------------------------------------------------------------------------- - */ - -#include "postgres_fe.h" - -#include - -#include "common/saslprep.h" - -int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); - -int -LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) -{ - char *str; - char *output = NULL; - - if (size == 0) - return 0; - - /* pg_saslprep expects a NUL-terminated string */ - str = malloc(size + 1); - if (!str) - return 0; - memcpy(str, data, size); - str[size] = '\0'; - - (void) pg_saslprep(str, &output); - - if (output) - free(output); - - free(str); - return 0; -} - -#ifdef STANDALONE_FUZZ_TARGET -int -main(int argc, char **argv) -{ - int i; - int ret = 0; - - for (i = 1; i < argc; i++) - { - FILE *f = fopen(argv[i], "rb"); - long len; - uint8_t *buf; - size_t n_read; - - if (!f) - { - fprintf(stderr, "%s: could not open %s: %m\n", argv[0], argv[i]); - ret = 1; - continue; - } - - fseek(f, 0, SEEK_END); - len = ftell(f); - fseek(f, 0, SEEK_SET); - - if (len < 0) - { - fprintf(stderr, "%s: could not determine size of %s\n", - argv[0], argv[i]); - fclose(f); - ret = 1; - continue; - } - - buf = malloc(len); - if (!buf) - { - fprintf(stderr, "%s: out of memory\n", argv[0]); - fclose(f); - return 1; - } - - n_read = fread(buf, 1, len, f); - fclose(f); - - LLVMFuzzerTestOneInput(buf, n_read); - free(buf); - } - - return ret; -} -#endif /* STANDALONE_FUZZ_TARGET */ diff --git a/src/test/fuzzing/fuzz_typeinput.c b/src/test/fuzzing/fuzz_typeinput.c deleted file mode 100644 index ee5e8135d5d..00000000000 --- a/src/test/fuzzing/fuzz_typeinput.c +++ /dev/null @@ -1,218 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fuzz_typeinput.c - * Fuzzing harness for PostgreSQL type input functions - * - * Copyright (c) 2026, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/test/fuzzing/fuzz_typeinput.c - * - * This harness feeds arbitrary byte sequences to the backend's type - * input functions: numeric_in, date_in, timestamp_in, timestamptz_in, - * and interval_in. These functions parse textual representations of - * data types and are a key part of PostgreSQL's input validation. - * - * The first byte of input selects which type parser to call; the - * remaining bytes are the type-input string. All functions support - * soft error handling via ErrorSaveContext, so errors are caught - * without ereport/PG_TRY. PG_TRY/PG_CATCH is used as a safety net - * for any unexpected hard errors. - * - * The harness links against postgres_lib using archive semantics. - * - *------------------------------------------------------------------------- - */ - -#include "postgres.h" - -#include - -#include "fmgr.h" -#include "mb/pg_wchar.h" -#include "miscadmin.h" -#include "nodes/miscnodes.h" -#include "pgtime.h" -#include "postmaster/postmaster.h" -#include "utils/builtins.h" -#include "utils/datetime.h" -#include "utils/memutils.h" -#include "utils/numeric.h" -#include "utils/palloc.h" -#include "utils/timestamp.h" - -/* Stubs for symbols from main/main.c */ -const char *progname = "fuzz_typeinput"; - -DispatchOption -parse_dispatch_option(const char *name) -{ - return DISPATCH_POSTMASTER; -} - -/* Type selector values */ -#define FUZZ_NUMERIC 0 -#define FUZZ_DATE 1 -#define FUZZ_TIMESTAMP 2 -#define FUZZ_TIMESTAMPTZ 3 -#define FUZZ_INTERVAL 4 -#define FUZZ_NTYPES 5 - -static bool initialized = false; - -static void fuzz_initialize(void); - -int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); - -static void -fuzz_initialize(void) -{ - MemoryContextInit(); - SetDatabaseEncoding(PG_UTF8); - SetMessageEncoding(PG_UTF8); - - /* - * Initialize timezone subsystem. Use "GMT" because it is resolved - * without filesystem access (the timezone data directory may not exist in - * a fuzzing build). - */ - pg_timezone_initialize(); -} - -int -LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) -{ - char *str; - int type_sel; - - LOCAL_FCINFO(fcinfo, 3); - ErrorSaveContext escontext; - MemoryContext fuzz_context; - MemoryContext oldcontext; - - if (!initialized) - { - fuzz_initialize(); - initialized = true; - } - - /* Need at least type selector + 1 byte of input */ - if (size < 2) - return 0; - - type_sel = data[0] % FUZZ_NTYPES; - data++; - size--; - - fuzz_context = AllocSetContextCreate(TopMemoryContext, - "Fuzz Context", - ALLOCSET_DEFAULT_SIZES); - oldcontext = MemoryContextSwitchTo(fuzz_context); - - /* Build a NUL-terminated string from the input */ - str = palloc(size + 1); - memcpy(str, data, size); - str[size] = '\0'; - - /* Set up ErrorSaveContext for soft error handling */ - memset(&escontext, 0, sizeof(escontext)); - escontext.type = T_ErrorSaveContext; - escontext.error_occurred = false; - escontext.details_wanted = false; - - /* Set up FunctionCallInfo */ - memset(fcinfo, 0, SizeForFunctionCallInfo(3)); - fcinfo->nargs = 3; - fcinfo->args[0].value = CStringGetDatum(str); - fcinfo->args[0].isnull = false; - fcinfo->args[1].value = ObjectIdGetDatum(InvalidOid); /* typelem */ - fcinfo->args[1].isnull = false; - fcinfo->args[2].value = Int32GetDatum(-1); /* typmod */ - fcinfo->args[2].isnull = false; - fcinfo->context = (Node *) &escontext; - - PG_TRY(); - { - switch (type_sel) - { - case FUZZ_NUMERIC: - (void) numeric_in(fcinfo); - break; - case FUZZ_DATE: - (void) date_in(fcinfo); - break; - case FUZZ_TIMESTAMP: - (void) timestamp_in(fcinfo); - break; - case FUZZ_TIMESTAMPTZ: - (void) timestamptz_in(fcinfo); - break; - case FUZZ_INTERVAL: - (void) interval_in(fcinfo); - break; - } - } - PG_CATCH(); - { - FlushErrorState(); - } - PG_END_TRY(); - - MemoryContextSwitchTo(oldcontext); - MemoryContextDelete(fuzz_context); - - return 0; -} - -#ifdef STANDALONE_FUZZ_TARGET -int -main(int argc, char **argv) -{ - int i; - int ret = 0; - - for (i = 1; i < argc; i++) - { - FILE *f = fopen(argv[i], "rb"); - long len; - uint8_t *buf; - size_t n_read; - - if (!f) - { - fprintf(stderr, "%s: could not open %s: %m\n", argv[0], argv[i]); - ret = 1; - continue; - } - - fseek(f, 0, SEEK_END); - len = ftell(f); - fseek(f, 0, SEEK_SET); - - if (len < 0) - { - fprintf(stderr, "%s: could not determine size of %s\n", - argv[0], argv[i]); - fclose(f); - ret = 1; - continue; - } - - buf = malloc(len); - if (!buf) - { - fprintf(stderr, "%s: out of memory\n", argv[0]); - fclose(f); - return 1; - } - - n_read = fread(buf, 1, len, f); - fclose(f); - - LLVMFuzzerTestOneInput(buf, n_read); - free(buf); - } - - return ret; -} -#endif /* STANDALONE_FUZZ_TARGET */ diff --git a/src/test/fuzzing/fuzz_unescapebytea.c b/src/test/fuzzing/fuzz_unescapebytea.c deleted file mode 100644 index a900344b4c1..00000000000 --- a/src/test/fuzzing/fuzz_unescapebytea.c +++ /dev/null @@ -1,103 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fuzz_unescapebytea.c - * Fuzzing harness for PQunescapeBytea() - * - * Copyright (c) 2026, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/test/fuzzing/fuzz_unescapebytea.c - * - * This harness feeds arbitrary byte sequences to PQunescapeBytea(), - * which decodes bytea escape formats: hex (\xDEAD...) and legacy - * backslash-octal (\352\273\276...). The function is completely - * standalone and requires no database connection. - * - *------------------------------------------------------------------------- - */ - -#include "postgres_fe.h" - -#include - -#include "libpq-fe.h" - -int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); - -int -LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) -{ - char *str; - size_t resultlen; - unsigned char *result; - - if (size == 0) - return 0; - - /* PQunescapeBytea expects a NUL-terminated string */ - str = malloc(size + 1); - if (!str) - return 0; - memcpy(str, data, size); - str[size] = '\0'; - - result = PQunescapeBytea((const unsigned char *) str, &resultlen); - if (result) - PQfreemem(result); - - free(str); - return 0; -} - -#ifdef STANDALONE_FUZZ_TARGET -int -main(int argc, char **argv) -{ - int i; - int ret = 0; - - for (i = 1; i < argc; i++) - { - FILE *f = fopen(argv[i], "rb"); - long len; - uint8_t *buf; - size_t n_read; - - if (!f) - { - fprintf(stderr, "%s: could not open %s: %m\n", argv[0], argv[i]); - ret = 1; - continue; - } - - fseek(f, 0, SEEK_END); - len = ftell(f); - fseek(f, 0, SEEK_SET); - - if (len < 0) - { - fprintf(stderr, "%s: could not determine size of %s\n", - argv[0], argv[i]); - fclose(f); - ret = 1; - continue; - } - - buf = malloc(len); - if (!buf) - { - fprintf(stderr, "%s: out of memory\n", argv[0]); - fclose(f); - return 1; - } - - n_read = fread(buf, 1, len, f); - fclose(f); - - LLVMFuzzerTestOneInput(buf, n_read); - free(buf); - } - - return ret; -} -#endif /* STANDALONE_FUZZ_TARGET */ diff --git a/src/test/fuzzing/meson.build b/src/test/fuzzing/meson.build deleted file mode 100644 index f05267da57f..00000000000 --- a/src/test/fuzzing/meson.build +++ /dev/null @@ -1,203 +0,0 @@ -# Copyright (c) 2026, PostgreSQL Global Development Group - -# Fuzzing harnesses for security testing. -# -# Build with: -# meson setup build -Dfuzzing=true -# -# For libFuzzer (recommended), also pass sanitizer flags: -# meson setup build -Dfuzzing=true \ -# -Dc_args='-fsanitize=fuzzer-no-link' \ -# -Dc_link_args='-fsanitize=fuzzer' -# -# Without a fuzzer engine the harnesses are built in standalone mode: -# each reads input from files named on the command line. - -if not get_option('fuzzing') - subdir_done() -endif - -# Detect whether a fuzzer engine (e.g. libFuzzer) is available. -# If so, link fuzzer executables with -fsanitize=fuzzer so that the -# engine provides main(). Otherwise compile with STANDALONE_FUZZ_TARGET -# so the harnesses supply their own main() that reads from files. - -fuzz_c_args = [] -fuzz_link_args = [] - -if cc.has_argument('-fsanitize=fuzzer-no-link') - fuzzer_has_engine = cc.links(''' - #include - #include - int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) - { return 0; } - ''', - args: ['-fsanitize=fuzzer'], - name: 'libFuzzer support') -else - fuzzer_has_engine = false -endif - -if fuzzer_has_engine - fuzz_link_args += ['-fsanitize=fuzzer'] -else - fuzz_c_args += ['-DSTANDALONE_FUZZ_TARGET'] -endif - -# --- Frontend targets (no backend dependencies) --- - -fuzz_json = executable('fuzz_json', - 'fuzz_json.c', - c_args: fuzz_c_args, - link_args: fuzz_link_args, - dependencies: [frontend_code], - kwargs: default_bin_args + { - 'install': false, - }, -) - -fuzz_json_incremental = executable('fuzz_json_incremental', - 'fuzz_json_incremental.c', - c_args: fuzz_c_args, - link_args: fuzz_link_args, - dependencies: [frontend_code], - kwargs: default_bin_args + { - 'install': false, - }, -) - -fuzz_conninfo = executable('fuzz_conninfo', - 'fuzz_conninfo.c', - c_args: fuzz_c_args, - link_args: fuzz_link_args, - dependencies: [frontend_code, libpq], - kwargs: default_bin_args + { - 'install': false, - }, -) - -fuzz_pglz = executable('fuzz_pglz', - 'fuzz_pglz.c', - c_args: fuzz_c_args, - link_args: fuzz_link_args, - dependencies: [frontend_code], - kwargs: default_bin_args + { - 'install': false, - }, -) - -fuzz_unescapebytea = executable('fuzz_unescapebytea', - 'fuzz_unescapebytea.c', - c_args: fuzz_c_args, - link_args: fuzz_link_args, - dependencies: [frontend_code, libpq], - kwargs: default_bin_args + { - 'install': false, - }, -) - -fuzz_b64decode = executable('fuzz_b64decode', - 'fuzz_b64decode.c', - c_args: fuzz_c_args, - link_args: fuzz_link_args, - dependencies: [frontend_code], - kwargs: default_bin_args + { - 'install': false, - }, -) - -fuzz_saslprep = executable('fuzz_saslprep', - 'fuzz_saslprep.c', - c_args: fuzz_c_args, - link_args: fuzz_link_args, - dependencies: [frontend_code], - kwargs: default_bin_args + { - 'install': false, - }, -) - -fuzz_parsepgarray = executable('fuzz_parsepgarray', - 'fuzz_parsepgarray.c', - c_args: fuzz_c_args, - link_args: fuzz_link_args, - dependencies: [frontend_code, libpq], - kwargs: default_bin_args + { - 'install': false, - }, -) - -# The pgbench expression parser is built from generated Bison/Flex -# sources. We reference the same custom_target outputs used by the -# pgbench build, and provide our own syntax_error() / strtoint64() / -# strtodouble() so we don't pull in pgbench.c (which has its own -# main() and calls exit() on parse errors). - -exprscan_fuzz = custom_target('exprscan_fuzz', - input: files('../../bin/pgbench/exprscan.l'), - output: 'exprscan.c', - command: flex_cmd, -) - -exprparse_fuzz = custom_target('exprparse_fuzz', - input: files('../../bin/pgbench/exprparse.y'), - kwargs: bison_kw, -) - -fuzz_pgbench_expr = executable('fuzz_pgbench_expr', - 'fuzz_pgbench_expr.c', - exprscan_fuzz, - exprparse_fuzz, - c_args: fuzz_c_args, - link_args: fuzz_link_args, - include_directories: include_directories('../../bin/pgbench'), - dependencies: [frontend_code, libpq], - kwargs: default_bin_args + { - 'install': false, - }, -) - -# --- Backend targets --- -# -# These link against postgres_lib using standard archive semantics -# (link_with), so only objects needed to resolve symbols are pulled in. -# The harness provides stub definitions for symbols exported by -# main/main.c, preventing the archive linker from pulling in main.o -# (which would conflict with the harness's own main()). -# -# Backend code uses function-pointer casts in hash tables (dynahash.c) -# that trigger UBSan's -fsanitize=function check. This is a known -# benign pattern; when using -fsanitize=undefined, also pass -# -fno-sanitize=function in the top-level c_args to suppress it. - -fuzz_rawparser = executable('fuzz_rawparser', - 'fuzz_rawparser.c', - c_args: fuzz_c_args, - link_args: fuzz_link_args, - link_with: [postgres_lib], - dependencies: backend_build_deps, - kwargs: default_bin_args + { - 'install': false, - }, -) - -fuzz_regex = executable('fuzz_regex', - 'fuzz_regex.c', - c_args: fuzz_c_args, - link_args: fuzz_link_args, - link_with: [postgres_lib], - dependencies: backend_build_deps, - kwargs: default_bin_args + { - 'install': false, - }, -) - -fuzz_typeinput = executable('fuzz_typeinput', - 'fuzz_typeinput.c', - c_args: fuzz_c_args, - link_args: fuzz_link_args, - link_with: [postgres_lib], - dependencies: backend_build_deps, - kwargs: default_bin_args + { - 'install': false, - }, -) diff --git a/src/test/meson.build b/src/test/meson.build index 76387524c4c..cd45cbf57fb 100644 --- a/src/test/meson.build +++ b/src/test/meson.build @@ -25,6 +25,4 @@ if icu.found() subdir('icu') endif -subdir('fuzzing') - subdir('perl')