This is an automated email from the ASF dual-hosted git repository. github-merge-queue[bot] pushed a commit to branch gh-readonly-queue/main/pr-2563-9c5e22f359024ff7e729429cf8e898394a29c2d9 in repository https://gitbox.apache.org/repos/asf/datafusion-sqlparser-rs.git
commit 4a609e7cc0d73754f8f03e0bc4011aaf0d288782 Author: Luca Cappelletti <[email protected]> AuthorDate: Wed Sep 23 21:19:51 2026 +0000 Differential Fuzzing (2/3): Check `PostgreSqlDialect` against PostgreSQL's own grammar (#2563) --- .clusterfuzzlite/Dockerfile | 2 ++ docs/fuzzing.md | 2 ++ fuzz/Cargo.toml | 8 +++++++ fuzz/fuzz_targets/fuzz_postgres_accepts.rs | 38 ++++++++++++++++++++++++++++++ 4 files changed, 50 insertions(+) diff --git a/.clusterfuzzlite/Dockerfile b/.clusterfuzzlite/Dockerfile index 579c99ad5..8eba3fdd6 100644 --- a/.clusterfuzzlite/Dockerfile +++ b/.clusterfuzzlite/Dockerfile @@ -16,6 +16,8 @@ # under the License. FROM gcr.io/oss-fuzz-base/base-builder-rust +# pg_query's build script runs bindgen, which needs libclang at build time +RUN apt-get update && apt-get install -y --no-install-recommends libclang-dev && rm -rf /var/lib/apt/lists/* COPY . $SRC/datafusion-sqlparser-rs WORKDIR $SRC/datafusion-sqlparser-rs COPY ./.clusterfuzzlite/build.sh $SRC/ diff --git a/docs/fuzzing.md b/docs/fuzzing.md index 1714e06cd..7c56c0c77 100644 --- a/docs/fuzzing.md +++ b/docs/fuzzing.md @@ -33,6 +33,8 @@ rendered statement no longer parses. `fuzz_sqlite_accepts` compiles the input with a bundled SQLite, without running it, and fails when SQLite accepts SQL that `SQLiteDialect` rejects. Name resolution errors such as a missing table still count as accepted once SQLite has read the statement to its end. +`fuzz_postgres_accepts` parses the input with PostgreSQL's own grammar through `pg_query` and fails when PostgreSQL accepts SQL that `PostgreSqlDialect` rejects. + ClusterFuzzLite runs continuous fuzzing. Every pull request fuzzes for 10 minutes in `code-change` mode, a daily batch job grows the shared corpus stored on the `clusterfuzzlite` branch, and a daily prune compacts it. diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index 4242bf8ce..42c91742b 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -27,6 +27,7 @@ cargo-fuzz = true [dependencies] libfuzzer-sys = "0.4" libsqlite3-sys = { version = "0.38", features = ["bundled"] } +pg_query = "6.2" sqlparser = { path = ".." } # Prevent this from interfering with workspaces @@ -53,3 +54,10 @@ path = "fuzz_targets/fuzz_sqlite_accepts.rs" test = false doc = false bench = false + +[[bin]] +name = "fuzz_postgres_accepts" +path = "fuzz_targets/fuzz_postgres_accepts.rs" +test = false +doc = false +bench = false diff --git a/fuzz/fuzz_targets/fuzz_postgres_accepts.rs b/fuzz/fuzz_targets/fuzz_postgres_accepts.rs new file mode 100644 index 000000000..e387d8ae6 --- /dev/null +++ b/fuzz/fuzz_targets/fuzz_postgres_accepts.rs @@ -0,0 +1,38 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +#![no_main] + +use libfuzzer_sys::fuzz_target; +use sqlparser::dialect::PostgreSqlDialect; +use sqlparser::parser::{Parser, ParserError}; + +fuzz_target!(|sql: &str| { + if sql.contains('\0') { + return; + } + let Ok(parsed) = pg_query::parse(sql) else { + return; + }; + match Parser::parse_sql(&PostgreSqlDialect {}, sql) { + Ok(_) | Err(ParserError::RecursionLimitExceeded) => {} + Err(err) => panic!( + "PostgreSQL {} accepts SQL the PostgreSQL dialect rejects\n sql: {sql:?}\n error: {err}", + parsed.protobuf.version + ), + } +}); --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
