]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Revert "Add built-in fuzzing harnesses for security testing."
authorAndrew Dunstan <andrew@dunslane.net>
Fri, 10 Apr 2026 13:53:58 +0000 (09:53 -0400)
committerAndrew Dunstan <andrew@dunslane.net>
Fri, 10 Apr 2026 13:53:58 +0000 (09:53 -0400)
This reverts commit 4a18907b412e77684bf888ad6d1b4844d220196a.

inadvertenly pushed, mea culpa

15 files changed:
meson_options.txt
src/test/fuzzing/fuzz_b64decode.c [deleted file]
src/test/fuzzing/fuzz_conninfo.c [deleted file]
src/test/fuzzing/fuzz_json.c [deleted file]
src/test/fuzzing/fuzz_json_incremental.c [deleted file]
src/test/fuzzing/fuzz_parsepgarray.c [deleted file]
src/test/fuzzing/fuzz_pgbench_expr.c [deleted file]
src/test/fuzzing/fuzz_pglz.c [deleted file]
src/test/fuzzing/fuzz_rawparser.c [deleted file]
src/test/fuzzing/fuzz_regex.c [deleted file]
src/test/fuzzing/fuzz_saslprep.c [deleted file]
src/test/fuzzing/fuzz_typeinput.c [deleted file]
src/test/fuzzing/fuzz_unescapebytea.c [deleted file]
src/test/fuzzing/meson.build [deleted file]
src/test/meson.build

index 4f60abccdc3a0047c44a69f6e37483512b050b2b..6a793f3e4794374a7c4d8e12a8c46f5b5c55ef5c 100644 (file)
@@ -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 (file)
index f388aaf..0000000
+++ /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 <stdio.h>
-
-#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 (file)
index 6199370..0000000
+++ /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 <stdio.h>
-
-#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 (file)
index b265ddf..0000000
+++ /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 <stdio.h>
-
-#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 (file)
index 7692f5c..0000000
+++ /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 <stdio.h>
-
-#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 (file)
index 38c67da..0000000
+++ /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 <stdio.h>
-
-#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 (file)
index a326fa7..0000000
+++ /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 <setjmp.h>
-#include <stdio.h>
-
-#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 (file)
index b1912e3..0000000
+++ /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 <stdio.h>
-#include <string.h>
-
-#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 (file)
index ba5f70c..0000000
+++ /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 <stdio.h>
-
-#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 (file)
index 584ee32..0000000
+++ /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 <stdio.h>
-
-#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 (file)
index 7717076..0000000
+++ /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 <stdio.h>
-
-#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 (file)
index ee5e813..0000000
+++ /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 <stdio.h>
-
-#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 (file)
index a900344..0000000
+++ /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 <stdio.h>
-
-#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 (file)
index f05267d..0000000
+++ /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 <stdint.h>
-    #include <stddef.h>
-    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,
-  },
-)
index 76387524c4cbf906dce0b5b4af069e630e75d0b7..cd45cbf57fb0f8e94965c7743bfc41fe937cfcbf 100644 (file)
@@ -25,6 +25,4 @@ if icu.found()
   subdir('icu')
 endif
 
-subdir('fuzzing')
-
 subdir('perl')