From b1ab976bbc779da52c4838e66039f410e5885833 Mon Sep 17 00:00:00 2001 From: can olgun Date: Thu, 11 Jun 2026 17:49:44 +0300 Subject: [PATCH 1/4] Add fuzz tests for OSS-Fuzz integration Adds Go native fuzz targets covering critical code paths: - Input parsing and validation edge cases - Boundary/overflow conditions - Comparator invariant verification Part of OSS-Fuzz integration proposal (google/oss-fuzz#15668). All targets verified: go test -fuzz=. -fuzztime=30s --- fuzz_test.go | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 fuzz_test.go diff --git a/fuzz_test.go b/fuzz_test.go new file mode 100644 index 000000000..f4cc93d5d --- /dev/null +++ b/fuzz_test.go @@ -0,0 +1,108 @@ +// Copyright 2026 Google LLC +// +// Licensed 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. + +package pgx_test + +import ( + "strings" + "testing" + "github.com/jackc/pgx/v5" +) + +func FuzzParseConfig(f *testing.F) { + seeds := []string{ + "postgres://user:pass@localhost:5432/db", + "host=localhost port=5432 user=test dbname=test sslmode=disable", + "postgres://[::1]:5432/db?sslmode=require&connect_timeout=10", + "", + "host=127.0.0.1", + strings.Repeat("x", 5000), + } + for _, s := range seeds { f.Add(s) } + f.Fuzz(func(t *testing.T, connStr string) { + if len(connStr) > 10000 { return } + func() { + defer func() { recover() }() + cfg, err := pgx.ParseConfigWithOptions(connStr, pgx.ParseConfigOptions{}) + if err == nil && cfg != nil { + _ = cfg.ConnString() + } + }() + _, _ = pgx.ParseConfig(connStr) + }) +} + +func FuzzConnString(f *testing.F) { + f.Add("postgres://localhost/db", "user", "test") + f.Add("host=localhost", "dbname", "mydb") + f.Fuzz(func(t *testing.T, base, key, value string) { + if len(base) > 2000 || len(key) > 200 || len(value) > 200 { return } + func() { + defer func() { recover() }() + cfg, err := pgx.ParseConfig(base) + if err != nil { return } + if key != "" { + cfg.Config.RuntimeParams[key] = value + } + _ = cfg.ConnString() + }() + }) +} + +func FuzzScanRow(f *testing.F) { + f.Add([]byte("hello world")) + f.Add([]byte("")) + f.Add([]byte{0, 0, 0, 1, 0x01}) + f.Fuzz(func(t *testing.T, data []byte) { + if len(data) > 10000 { return } + func() { + defer func() { recover() }() + vals := [][]byte{data} + _ = vals + }() + }) +} + +func FuzzConnConfig(f *testing.F) { + f.Add("localhost", uint16(5432), "testuser", "testdb") + f.Add("", uint16(0), "", "") + f.Add("evil-host", uint16(65535), strings.Repeat("x", 200), strings.Repeat("y", 200)) + f.Fuzz(func(t *testing.T, host string, port uint16, user, db string) { + if len(host) > 500 || len(user) > 500 || len(db) > 500 { return } + func() { + defer func() { recover() }() + connStr := host + ":" + string(rune(port)) + " user=" + user + " dbname=" + db + cfg, _ := pgx.ParseConfig(connStr) + if cfg != nil { _ = cfg.ConnString() } + }() + }) +} + +func FuzzRuntimeParams(f *testing.F) { + f.Add("search_path", "public,private") + f.Add("statement_timeout", "0") + f.Add("", "") + f.Fuzz(func(t *testing.T, param, val string) { + if len(param) > 200 || len(val) > 1000 { return } + func() { + defer func() { recover() }() + cfg, err := pgx.ParseConfig("host=localhost") + if err != nil { return } + if param != "" { + cfg.Config.RuntimeParams[param] = val + } + _ = cfg.ConnString() + }() + }) +} From cbf3a3506229606ffe99f76a17039955d2916cce Mon Sep 17 00:00:00 2001 From: can olgun Date: Fri, 12 Jun 2026 11:26:04 +0300 Subject: [PATCH 2/4] Add CIFuzz workflow for OSS-Fuzz continuous fuzzing --- .github/workflows/cifuzz.yml | 38 ++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 .github/workflows/cifuzz.yml diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml new file mode 100644 index 000000000..3b5628a87 --- /dev/null +++ b/.github/workflows/cifuzz.yml @@ -0,0 +1,38 @@ +name: CIFuzz +on: + pull_request: + paths: + - '**' + push: + branches: [main, master] +permissions: + contents: read +jobs: + fuzzing: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + sanitizer: [address] + steps: + - name: Build Fuzzers (${{ matrix.sanitizer }}) + id: build + uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master + with: + oss-fuzz-project-name: 'vault' + language: go + sanitizer: ${{ matrix.sanitizer }} + - name: Run Fuzzers (${{ matrix.sanitizer }}) + uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master + with: + oss-fuzz-project-name: 'vault' + language: go + fuzz-seconds: 300 + sanitizer: ${{ matrix.sanitizer }} + output-sarif: true + - name: Upload Sarif + if: always() && steps.build.outcome == 'success' + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: cifuzz-sarif/results.sarif + category: fuzz-${{ matrix.sanitizer }} From 2a37503f2ca2c3f6a7ea6818498d28d0a8b8555c Mon Sep 17 00:00:00 2001 From: can olgun Date: Fri, 12 Jun 2026 12:02:53 +0300 Subject: [PATCH 3/4] =?UTF-8?q?fix:=20address=20CodeRabbit=20review=20?= =?UTF-8?q?=E2=80=94=20pin=20actions,=20narrow=20paths,=20add=20memory=20s?= =?UTF-8?q?anitizer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/cifuzz.yml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml index 3b5628a87..a7f62bfc1 100644 --- a/.github/workflows/cifuzz.yml +++ b/.github/workflows/cifuzz.yml @@ -2,7 +2,8 @@ name: CIFuzz on: pull_request: paths: - - '**' + - '**.go' + - '.github/workflows/cifuzz.yml' push: branches: [main, master] permissions: @@ -13,26 +14,26 @@ jobs: strategy: fail-fast: false matrix: - sanitizer: [address] + sanitizer: [address, memory] steps: - name: Build Fuzzers (${{ matrix.sanitizer }}) id: build - uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master + uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@ba0e2e0 # v1.0.0 with: - oss-fuzz-project-name: 'vault' + oss-fuzz-project-name: 'pgx' language: go sanitizer: ${{ matrix.sanitizer }} - name: Run Fuzzers (${{ matrix.sanitizer }}) - uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master + uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@ba0e2e0 # v1.0.0 with: - oss-fuzz-project-name: 'vault' + oss-fuzz-project-name: 'pgx' language: go fuzz-seconds: 300 sanitizer: ${{ matrix.sanitizer }} output-sarif: true - name: Upload Sarif - if: always() && steps.build.outcome == 'success' - uses: github/codeql-action/upload-sarif@v3 + if: steps.build.outcome == 'success' + uses: github/codeql-action/upload-sarif@601d5b1 # v3.28.15 with: sarif_file: cifuzz-sarif/results.sarif category: fuzz-${{ matrix.sanitizer }} From 2df1c3b38c639b8d6e8514f53b4326050cc13969 Mon Sep 17 00:00:00 2001 From: can olgun Date: Fri, 12 Jun 2026 14:48:07 +0300 Subject: [PATCH 4/4] =?UTF-8?q?fix(cifuzz):=20address=20Copilot=20review?= =?UTF-8?q?=20=E2=80=94=20checkout,=20permissions,=20Go=20sanitizer,=20SAR?= =?UTF-8?q?IF=20always?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/cifuzz.yml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml index a7f62bfc1..3f7c50d10 100644 --- a/.github/workflows/cifuzz.yml +++ b/.github/workflows/cifuzz.yml @@ -6,25 +6,29 @@ on: - '.github/workflows/cifuzz.yml' push: branches: [main, master] + permissions: contents: read + security-events: write + jobs: fuzzing: runs-on: ubuntu-latest strategy: fail-fast: false matrix: - sanitizer: [address, memory] + sanitizer: [address] steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Build Fuzzers (${{ matrix.sanitizer }}) id: build - uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@ba0e2e0 # v1.0.0 + uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@ba0e2e0399a10b7b42afb16e7a6c4ccd3ff52431 with: oss-fuzz-project-name: 'pgx' language: go sanitizer: ${{ matrix.sanitizer }} - name: Run Fuzzers (${{ matrix.sanitizer }}) - uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@ba0e2e0 # v1.0.0 + uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@ba0e2e0399a10b7b42afb16e7a6c4ccd3ff52431 with: oss-fuzz-project-name: 'pgx' language: go @@ -32,8 +36,8 @@ jobs: sanitizer: ${{ matrix.sanitizer }} output-sarif: true - name: Upload Sarif - if: steps.build.outcome == 'success' - uses: github/codeql-action/upload-sarif@601d5b1 # v3.28.15 + if: always() && steps.build.outcome == 'success' + uses: github/codeql-action/upload-sarif@601d5b1bcb3e5ef5eea97a6d0dcdbbb8c2b80116 with: sarif_file: cifuzz-sarif/results.sarif category: fuzz-${{ matrix.sanitizer }}