# ASan regression run inside an AddressSanitizer-instrumented PostgreSQL.
#
# The whole recipe is scripts/asan-check.sh, so a local run
#     bash scripts/asan-check.sh
# is exactly this job.  The SERVER is instrumented, not just pg_tre: the 4.2.0
# similarity crash was an out-of-bounds store performed by PostgreSQL's own
# pg_mb2wchar_with_len() into a pg_tre stack variable, invisible to ASan on
# pg_tre.so alone.  Validated to go red on that bug (exit 2,
# "stack-buffer-overflow ... trgm_set src/query/trgm_similarity.c:94") and
# green on HEAD (47/47, no report).
#
# Scope: without PostgreSQL's memory-context poison/unpoison patch this catches
# direct OOB reads/writes, use-after-free, double-free and UB in pg_tre's code
# and in server code it drives, but not writes to a chunk after its memory
# context is reset.  detect_leaks=0 because PostgreSQL leaks
# transaction-lifetime allocations into long-lived contexts by design.
name: Sanitizer test

on:
  push:
    branches: [main]
    paths:
      - 'src/**'
      - 'include/**'
      - 'test/**'
      - 'sql/**'
      - 'Makefile'
      - 'pg_tre.control'
      - 'scripts/asan-check.sh'
      - '.github/workflows/sanitizer-build-and-test.yml'
  workflow_dispatch:

jobs:
  sanitizer:
    name: PG${{ matrix.pg }} ASan
    runs-on: ubuntu-24.04
    timeout-minutes: 90
    strategy:
      fail-fast: false
      matrix:
        pg: ["18.0"]

    steps:
      - name: Lower ASLR entropy for AddressSanitizer (Ubuntu 24.04 runner)
        # Ubuntu 24.04's default vm.mmap_rnd_bits (32) exceeds what ASan's
        # shadow-memory mapping supports, so an ASan binary aborts at startup
        # before any user code runs.  Lowering it (and disabling ASLR on the
        # newest kernels) is the documented workaround.  Kernel-global, so it
        # must run before any instrumented binary in later steps.
        run: |
          sudo sysctl -w vm.mmap_rnd_bits=28
          sudo sysctl -w kernel.randomize_va_space=0

      - name: Install build deps
        run: |
          sudo apt-get update
          sudo apt-get install -y --no-install-recommends \
            build-essential flex bison pkg-config git curl bzip2 \
            autoconf automake libtool gettext autopoint m4 locales

      - uses: actions/checkout@v4
        with:
          submodules: true

      - name: Cache ASan PostgreSQL ${{ matrix.pg }}
        id: cache-pg
        uses: actions/cache@v4
        with:
          path: ~/pg-asan-${{ matrix.pg }}
          key: pg-asan-${{ matrix.pg }}-ubuntu24-${{ hashFiles('scripts/asan-check.sh') }}

      - name: Build + run under ASan
        env:
          PG_VERSION: ${{ matrix.pg }}
          ASAN_WORK: ${{ runner.temp }}/pg_tre-asan
        run: ASAN_PREFIX="$HOME/pg-asan-${{ matrix.pg }}" bash scripts/asan-check.sh

      - name: Upload sanitizer reports on failure
        if: failure()
        uses: actions/upload-artifact@v4
        with:
          name: sanitizer-logs-pg${{ matrix.pg }}
          path: |
            ${{ runner.temp }}/pg_tre-asan/reports/
            ${{ runner.temp }}/pg_tre-asan/server.log
            ${{ runner.temp }}/pg_tre-asan/regress.log
            test/results/
          retention-days: 14
