diff options
Diffstat (limited to '.github')
| -rw-r--r-- | .github/workflows/build-and-test.yml | 53 | ||||
| -rw-r--r-- | .github/workflows/clang_format.yml | 39 | ||||
| -rw-r--r-- | .github/workflows/codespell.yml | 28 | ||||
| -rw-r--r-- | .github/workflows/coverage.yml | 77 | ||||
| -rw-r--r-- | .github/workflows/fuzzing.yml | 105 | ||||
| -rw-r--r-- | .github/workflows/windows.yml | 117 |
6 files changed, 390 insertions, 29 deletions
diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index f330d27..8653739 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -1,7 +1,7 @@ # Copyright (C) 2021 Sebastian Pipping <sebastian@pipping.org> # Licensed under the MIT license -name: Build and test +name: Build and test (Linux) on: pull_request: @@ -11,30 +11,30 @@ on: jobs: build_and_test: - name: Build and test + name: Build and test (Linux) strategy: matrix: include: - name: Native Linux cmake_args: >- - -DCMAKE_C_COMPILER=clang-18 - -DCMAKE_CXX_COMPILER=clang++-18 + -DCMAKE_C_COMPILER=clang-21 + -DCMAKE_CXX_COMPILER=clang++-21 cflags: >- -fsanitize=address,undefined,leak -fno-sanitize-recover=all -fno-omit-frame-pointer ldflags: >- -fsanitize=address,undefined,leak - - name: MingGW on Linux + - name: MinGW on Linux cmake_args: >- -DCMAKE_C_COMPILER=i686-w64-mingw32-gcc -DCMAKE_CXX_COMPILER=i686-w64-mingw32-g++ -DCMAKE_SYSTEM_NAME=Windows -DWIN32=ON -DMINGW=ON - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Add Clang/LLVM repositories (Non-MinGW) if: "${{ ! contains(matrix.cmake_args, 'mingw') }}" @@ -42,7 +42,7 @@ jobs: set -x source /etc/os-release wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - - sudo add-apt-repository "deb http://apt.llvm.org/${UBUNTU_CODENAME}/ llvm-toolchain-${UBUNTU_CODENAME}-18 main" + sudo add-apt-repository "deb http://apt.llvm.org/${UBUNTU_CODENAME}/ llvm-toolchain-${UBUNTU_CODENAME}-21 main" - name: Install build dependencies run: |- @@ -59,20 +59,7 @@ jobs: - name: Install build dependencies (MinGW) if: "${{ contains(matrix.cmake_args, 'mingw') }}" run: |- - set -x -u -o pipefail - source /etc/os-release - - # Get rid of packages installed from ppa:ondrej/php so that we will be able to install wine32:i386 without conflicts - # (see issue https://github.com/actions/virtual-environments/issues/4589) - # In detail we: - # 1. Remove all packages that ppa:ondrej/php has but plain Ubuntu doesn't, e.g. everything PHP - # 2. Revert (remaining) packages that ppa:ondrej/php and plain Ubuntu share, back to the plain Ubuntu version - # 3. Assert that no packages from ppa:ondrej/php are left installed - dpkg -l | grep '^ii' | fgrep deb.sury.org | awk '{print $2}' | grep '^php' \ - | xargs -r -t sudo apt-get remove --yes libpcre2-posix3 libzip4 - dpkg -l | grep '^ii' | fgrep deb.sury.org | awk '{print $2}' | sed "s,\$,/${UBUNTU_CODENAME}," \ - | xargs -r -t sudo apt-get install --yes --no-install-recommends --allow-downgrades -V - ! dpkg -l | grep '^ii' | fgrep deb.sury.org + set -x # Install 32bit Wine sudo dpkg --add-architecture i386 # for wine32 @@ -86,8 +73,8 @@ jobs: if: "${{ ! contains(matrix.cmake_args, 'mingw') }}" run: |- sudo apt-get install --yes --no-install-recommends -V \ - clang-18 \ - libclang-rt-18-dev + clang-21 \ + libclang-rt-21-dev - name: Build, test and install run: |- @@ -103,8 +90,8 @@ jobs: ( cd googletest-release-${GTEST_VERSION}/ - # Silence warning "Compatibility with CMake < 2.8.12 will be removed" - find -name CMakeLists.txt -print -exec sed 's/cmake_minimum_required.*/cmake_minimum_required(VERSION 3.5.0)/' -i {} \; + # Silence warning "Compatibility with CMake < 3.10 will be removed" + find -name CMakeLists.txt -print -exec sed 's/cmake_minimum_required.*/cmake_minimum_required(VERSION 3.10.0)/' -i {} \; cmake \ -DBUILD_SHARED_LIBS=ON \ @@ -129,8 +116,8 @@ jobs: -Wextra -pedantic ) - CFLAGS="${compile_flags[*]} -std=c89" - CXXFLAGS="${compile_flags[*]} -std=c++98" + CFLAGS="${compile_flags[*]} -std=c99" + CXXFLAGS="${compile_flags[*]} -std=c++11" LDFLAGS='-g ${{ matrix.ldflags }}' cmake_args=( -DCMAKE_INSTALL_PREFIX:PATH=${GTEST_PREFIX} @@ -148,6 +135,7 @@ jobs: ${{ matrix.cmake_args }} + -DURIPARSER_BUILD_TESTS=ON -DURIPARSER_WARNINGS_AS_ERRORS=ON ) cmake "${cmake_args[@]}" -DCMAKE_INSTALL_INCLUDEDIR=include123 .. @@ -157,12 +145,19 @@ jobs: # NOTE: We need to copy some .dll files next to the # Windows binaries so that they are ready to be executed if [[ "${{ matrix.cmake_args }}" == *mingw* ]]; then - cp /usr/lib/gcc/i686-w64-mingw32/*-posix/libgcc_s_sjlj-1.dll ./ + cp /usr/lib/gcc/i686-w64-mingw32/*-posix/libgcc_s_dw2-1.dll ./ cp /usr/lib/gcc/i686-w64-mingw32/*-posix/libstdc++-6.dll ./ cp /usr/i686-w64-mingw32/lib/libwinpthread-1.dll ./ cp "${GTEST_PREFIX}"/bin/libgtest.dll ./ fi + # Configure UBSan to show (non-default) stack traces for runtime errors + # NOTE: "halt_on_error=1" we don't need to add because of the + # -fno-sanitize-recover=all for CFLAGS further up. + # NOTE: "abort_on_error=1" we don't need here because to CI, + # a non-zero exit code is all that matters. + export UBSAN_OPTIONS='print_stacktrace=1' + make VERBOSE=1 test ARGS=--verbose cat Testing/Temporary/LastTest.log diff --git a/.github/workflows/clang_format.yml b/.github/workflows/clang_format.yml new file mode 100644 index 0000000..7ac9268 --- /dev/null +++ b/.github/workflows/clang_format.yml @@ -0,0 +1,39 @@ +# Copyright (C) 2025 Sebastian Pipping <sebastian@pipping.org> +# Licensed under the MIT license + +name: Enforce clang-format clean code + +on: + pull_request: + push: + schedule: + - cron: '0 2 * * 5' # Every Friday at 2am + workflow_dispatch: + +permissions: + contents: read + +jobs: + clang_format: + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Install Clang 21 + run: |- + set -x + source /etc/os-release + wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - + sudo add-apt-repository "deb https://apt.llvm.org/${UBUNTU_CODENAME}/ llvm-toolchain-${UBUNTU_CODENAME}-21 main" + sudo apt-get update # due to new repository + sudo apt-get install --yes --no-install-recommends -V \ + clang-format-21 + echo /usr/lib/llvm-21/bin >>"${GITHUB_PATH}" + + - name: Enforce clang-format clean code + run: | + set -x -o pipefail + clang-format --version + git ls-files \*.cpp \*.c \*.h \*.h.in | xargs clang-format -i + sed 's,#\( \+\)cmakedefine,#cmakedefine,' -i.bak src/UriConfig.h.in # this helps Meson + git -c color.ui=always diff --exit-code # i.e. fail CI for non-empty diff diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml new file mode 100644 index 0000000..61af9fb --- /dev/null +++ b/.github/workflows/codespell.yml @@ -0,0 +1,28 @@ +# Copyright (C) 2025 Sebastian Pipping <sebastian@pipping.org> +# Licensed under the MIT license + +name: Enforce codespell-clean spelling + +on: + pull_request: + push: + schedule: + - cron: '0 4 * * 5' # Every Friday at 4am + workflow_dispatch: + +permissions: + contents: read + +jobs: + checks: + name: Enforce codespell-clean spelling + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: codespell-project/actions-codespell@8f01853be192eb0f849a5c7d721450e7a467c579 # v2.2 + with: + # "inout" is from "<b>INOUT</b>" markers + # "puls" is for last name "Puls" in files THANKS and ChangeLog + # "worstcase" is from variable name "worstCase" in file src/UriQuery.c + ignore_words_list: inout,puls,worstcase + skip: ./doc/rfc1866.htm,./doc/rfc3513.htm,./doc/rfc3986.htm diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 0000000..39e4bb1 --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,77 @@ +# Copyright (C) 2025 Sebastian Pipping <sebastian@pipping.org> +# Licensed under the MIT license + +name: Run tests under coverage + +on: + pull_request: + push: + schedule: + - cron: '0 2 * * 5' # Every Friday at 2am + workflow_dispatch: + +permissions: + contents: read + +jobs: + test_coverage: + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Install Clang 21 + run: |- + set -x + source /etc/os-release + wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - + sudo add-apt-repository "deb https://apt.llvm.org/${UBUNTU_CODENAME}/ llvm-toolchain-${UBUNTU_CODENAME}-21 main" + sudo apt-get update # due to new repository + sudo apt-get install --yes --no-install-recommends -V \ + clang-21 \ + libclang-rt-21-dev \ + llvm-21 + echo /usr/lib/llvm-21/bin >>"${GITHUB_PATH}" + + - name: Install other build dependencies + run: |- + set -x + sudo apt-get install --yes --no-install-recommends -V \ + libgtest-dev + + - name: Build uriparser fuzzers + run: | + args=( + # Build nothing but the test suite + -DURIPARSER_BUILD_DOCS=OFF + -DURIPARSER_BUILD_TESTS=ON + -DURIPARSER_BUILD_TOOLS=OFF + -DURIPARSER_ENABLE_INSTALL=OFF + + # Tune compilation to use Clang with code coverage + -DCMAKE_C_COMPILER=clang-21 + -DCMAKE_CXX_COMPILER=clang++-21 + -DCMAKE_{C,CXX}_FLAGS='-Wall -Wextra -pedantic -O2 -g -fprofile-instr-generate -fcoverage-mapping' + -DURIPARSER_WARNINGS_AS_ERRORS=ON + ) + set -x -o pipefail + cmake "${args[@]}" -S . -B build + make -C build VERBOSE=1 -j$(nproc) + + - name: Run tests under coverage + run: | + CTEST_OUTPUT_ON_FAILURE=1 make -C build all test + + - name: Generate reports + run: | + set -x -o pipefail + mkdir coverage/ + llvm-profdata merge -sparse build/default.profraw -o coverage/indexed.profraw + llvm-cov show -instr-profile=coverage/indexed.profraw -format=html -output-dir=coverage/html/ build/testrunner + llvm-cov report -instr-profile=coverage/indexed.profraw build/testrunner |& tee coverage/report.txt + + - name: Store coverage report + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: uriparser_coverage_${{ github.sha }} + path: coverage/ + if-no-files-found: error diff --git a/.github/workflows/fuzzing.yml b/.github/workflows/fuzzing.yml new file mode 100644 index 0000000..5b83389 --- /dev/null +++ b/.github/workflows/fuzzing.yml @@ -0,0 +1,105 @@ +# Copyright (C) 2025 Sebastian Pipping <sebastian@pipping.org> +# Licensed under the MIT license + +name: Run fuzzing regression tests + +on: + pull_request: + push: + schedule: + - cron: '0 2 * * 5' # Every Friday at 2am + workflow_dispatch: + +permissions: + contents: read + +jobs: + run_fuzzers: + name: ${{ matrix.fuzzer_name }} + strategy: + fail-fast: false + matrix: + fuzzer_name: + - uri_dissect_query_malloc_fuzzer + - uri_dissect_query_mallocw_fuzzer + - uri_free_fuzzer + - uri_freew_fuzzer + - uri_parse_fuzzer + - uri_parsew_fuzzer + runs-on: ubuntu-24.04 + env: + fuzzer_name: ${{ matrix.fuzzer_name }} + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Install Clang 21 + run: |- + set -x + source /etc/os-release + wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - + sudo add-apt-repository "deb https://apt.llvm.org/${UBUNTU_CODENAME}/ llvm-toolchain-${UBUNTU_CODENAME}-21 main" + sudo apt-get update # due to new repository + sudo apt-get install --yes --no-install-recommends -V \ + clang-21 \ + libclang-rt-21-dev \ + llvm-21 + echo /usr/lib/llvm-21/bin >>"${GITHUB_PATH}" + + - name: Build uriparser fuzzers + run: | + args=( + # Build nothing but fuzzers + -DURIPARSER_BUILD_DOCS=OFF + -DURIPARSER_BUILD_FUZZERS=ON + -DURIPARSER_BUILD_TOOLS=OFF + -DURIPARSER_ENABLE_INSTALL=OFF + -DURIPARSER_OSSFUZZ_BUILD=OFF + + # Tune compilation of fuzzers to use Clang with ASan and UBSan + -DCMAKE_C_COMPILER=clang-21 + -DCMAKE_CXX_COMPILER=clang++-21 + -DCMAKE_{C,CXX}_FLAGS='-Wall -Wextra -pedantic -O1 -g -fsanitize=address,undefined -fno-sanitize-recover=all -fno-omit-frame-pointer -fno-common' + -DCMAKE_{EXE,MODULE,SHARED}_LINKER_FLAGS='-g -fsanitize=address,undefined' + -DURIPARSER_WARNINGS_AS_ERRORS=ON + ) + set -x -o pipefail + cmake "${args[@]}" -S . -B build + make -C build VERBOSE=1 -j$(nproc) + + - name: Download and extract uriparser fuzzing corpora + run: |- + set -x -o pipefail + cd build/ + wget -q "https://storage.googleapis.com/uriparser-backup.clusterfuzz-external.appspot.com/corpus/libFuzzer/uriparser_${fuzzer_name}/public.zip" + unzip -q -d "corpus_${fuzzer_name}" public.zip + rm public.zip + + - name: Run fuzzing regression tests + run: | + fuzz_args=( + -jobs=$(nproc) + -print_final_stats=1 + -rss_limit_mb=2560 # from OSS-Fuzz + -timeout=25 # from OSS-Fuzz + ) + + set -x -o pipefail + cd "build/corpus_${fuzzer_name}/" + + # Configure UBSan to show (non-default) stack traces for runtime errors + # NOTE: "halt_on_error=1" we don't need to add because of the + # -fno-sanitize-recover=all for CFLAGS further up. + # NOTE: "abort_on_error=1" we don't need here because to CI, + # a non-zero exit code is all that matters. + export UBSAN_OPTIONS='print_stacktrace=1' + + find . -type f | sort | xargs -n 1000 "../fuzz/${fuzzer_name}" "${fuzz_args[@]}" + find . -type f | wc -l + + - name: Store fuzzing logs of last batch + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: uriparser_fuzzing_logs_last_${{ github.sha }}_${{ matrix.fuzzer_name }} + path: build/*/fuzz-*.log + if-no-files-found: error diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml new file mode 100644 index 0000000..ec8cee4 --- /dev/null +++ b/.github/workflows/windows.yml @@ -0,0 +1,117 @@ +# Copyright (C) 2025 Sebastian Pipping <sebastian@pipping.org> +# Licensed under the MIT license + +name: Build and test (Windows) + +on: + pull_request: + push: + schedule: + - cron: '0 2 * * 5' # Every Friday at 2am + workflow_dispatch: + +permissions: + contents: read + +jobs: + windows: + name: Build and test (Windows) + strategy: + fail-fast: false + matrix: + include: + # Visual Studio 2022, 32 bit + - runs-on: windows-2022 + cmake_generator: Visual Studio 17 2022 + common_cmake_args: -A Win32 + uriparser_sln: uriparser.sln + + # Visual Studio 2022, 64 bit + - runs-on: windows-2022 + cmake_generator: Visual Studio 17 2022 + common_cmake_args: -A x64 + uriparser_sln: uriparser.sln + + # Visual Studio 2026, 32 bit + - runs-on: windows-2025-vs2026 + cmake_generator: Visual Studio 18 2026 + common_cmake_args: -A Win32 + uriparser_sln: uriparser.slnx + + # Visual Studio 2026, 64 bit + - runs-on: windows-2025-vs2026 + cmake_generator: Visual Studio 18 2026 + common_cmake_args: -A x64 + uriparser_sln: uriparser.slnx + + runs-on: ${{ matrix.runs-on }} + defaults: + run: + shell: bash + env: + CMAKE_GENERATOR: ${{ matrix.cmake_generator }} + COMMON_CMAKE_ARGS: ${{ matrix.common_cmake_args }} + GTEST_VERSION: 1.12.0 + steps: + + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - uses: microsoft/setup-msbuild@30375c66a4eea26614e0d39710365f22f8b0af57 # v3.0.0 + + - name: Build dependency googletest + run: |- + set -x + curl -fsSL -o "release-${GTEST_VERSION}.zip" "https://github.com/google/googletest/archive/release-${GTEST_VERSION}.zip" + unzip -q "release-${GTEST_VERSION}.zip" + + cd "googletest-release-${GTEST_VERSION}" + cmake \ + -G "${CMAKE_GENERATOR}" \ + -DCVF_VERSION="${GTEST_VERSION}" \ + ${COMMON_CMAKE_ARGS} + cmake --build . --config Release -- -m + + # Enrich folder to make FindGTest.cmake happy + mkdir -p googletest/lib + cp -v lib/Release/{gtest,gtest_main}.lib googletest/lib/ + + - name: Configure + run: |- + cmake_args=( + -G "${CMAKE_GENERATOR}" + # NOTE: GTEST_ROOT is relative to source CMakeLists.txt, not the build directory + -DGTEST_ROOT="googletest-release-${GTEST_VERSION}/googletest" + -DURIPARSER_BUILD_DOCS=OFF + -DURIPARSER_BUILD_TESTS=ON + -DURIPARSER_MSVC_STATIC_CRT=ON + -DURIPARSER_WARNINGS_AS_ERRORS=ON + -S . + -B build/ + ${COMMON_CMAKE_ARGS} + ) + set -x + cmake "${cmake_args[@]}" + + - name: Build + env: + uriparser_sln: ${{ matrix.uriparser_sln }} + run: |- + msbuild_args=( + -m + -property:Configuration=Release + ) + set -x + cd build + MSBuild.exe "${msbuild_args[@]}" "${uriparser_sln}" + + - name: Run tests + run: |- + ctest_args=( + --build-config Release + --no-tests=error + --output-on-failure + --parallel 2 + ) + set -x + cd build + ctest "${ctest_args[@]}" |
