diff --git a/.codeqlmanifest.json b/.codeqlmanifest.json index ac468d9838..d6277f5949 100644 --- a/.codeqlmanifest.json +++ b/.codeqlmanifest.json @@ -1 +1 @@ -{ "provide": [ "codeql_modules/*/.codeqlmanifest.json", "cpp/.codeqlmanifest.json", "c/.codeqlmanifest.json"] } +{ "provide": [ "cpp/*/src/qlpack.yml", "cpp/*/test/qlpack.yml", "c/*/src/qlpack.yml", "c/*/test/qlpack.yml" ] } diff --git a/.github/actions/install-codeql-packs/action.yml b/.github/actions/install-codeql-packs/action.yml new file mode 100644 index 0000000000..2e6d5f1a2e --- /dev/null +++ b/.github/actions/install-codeql-packs/action.yml @@ -0,0 +1,25 @@ +name: Install CodeQL library pack dependencies +description: | + Downloads any necessary CodeQL library packs needed by packs in the repo. +inputs: + cli_path: + description: | + The path to the CodeQL CLI directory. + required: false + + mode: + description: | + The `--mode` option to `codeql pack install`. + required: true + default: verify + +runs: + using: composite + steps: + - name: Install CodeQL library packs + shell: bash + env: + CODEQL_CLI: ${{ inputs.cli_path }} + run: | + PATH=$PATH:$CODEQL_CLI + python scripts/install-packs.py --mode ${{ inputs.mode }} diff --git a/.github/workflows/code-scanning-pack-gen.yml b/.github/workflows/code-scanning-pack-gen.yml index 8c9fa46725..ca03cb01a5 100644 --- a/.github/workflows/code-scanning-pack-gen.yml +++ b/.github/workflows/code-scanning-pack-gen.yml @@ -59,6 +59,11 @@ jobs: codeql-home: ${{ github.workspace }}/codeql_home add-to-path: false + - name: Install CodeQL packs + uses: ./.github/actions/install-codeql-packs + with: + cli_path: ${{ github.workspace }}/codeql_home/codeql + - name: Checkout external help files continue-on-error: true id: checkout-external-help-files @@ -82,8 +87,8 @@ jobs: run: | PATH=$PATH:$CODEQL_HOME/codeql - codeql query compile --search-path cpp --threads 0 cpp - codeql query compile --search-path c --search-path cpp --threads 0 c + codeql query compile --threads 0 cpp + codeql query compile --threads 0 c cd .. zip -r codeql-coding-standards/code-scanning-cpp-query-pack.zip codeql-coding-standards/c/ codeql-coding-standards/cpp/ codeql-coding-standards/.codeqlmanifest.json codeql-coding-standards/supported_codeql_configs.json codeql-coding-standards/scripts/configuration codeql-coding-standards/scripts/reports codeql-coding-standards/scripts/shared codeql-coding-standards/scripts/guideline_recategorization codeql-coding-standards/scripts/shared codeql-coding-standards/scripts/schemas diff --git a/.github/workflows/codeql_unit_tests.yml b/.github/workflows/codeql_unit_tests.yml index b23bc0cc19..aa47483ee4 100644 --- a/.github/workflows/codeql_unit_tests.yml +++ b/.github/workflows/codeql_unit_tests.yml @@ -66,11 +66,16 @@ jobs: codeql-home: ${{ github.workspace }}/codeql_home add-to-path: false + - name: Install CodeQL packs + uses: ./.github/actions/install-codeql-packs + with: + cli_path: ${{ github.workspace }}/codeql_home/codeql + - name: Pre-Compile Queries id: pre-compile-queries run: | - ${{ github.workspace }}/codeql_home/codeql/codeql query compile --search-path cpp --threads 0 cpp - ${{ github.workspace }}/codeql_home/codeql/codeql query compile --search-path c --search-path cpp --threads 0 c + ${{ github.workspace }}/codeql_home/codeql/codeql query compile --threads 0 cpp + ${{ github.workspace }}/codeql_home/codeql/codeql query compile --threads 0 c - name: Run test suites @@ -122,18 +127,11 @@ jobs: os.makedirs(os.path.dirname(test_report_path), exist_ok=True) test_report_file = open(test_report_path, 'w') files_to_close.append(test_report_file) - if "${{ matrix.language }}".casefold() == "c".casefold(): - # c tests require cpp -- but we don't want c things on the cpp - # path in case of design errors. - cpp_language_root = Path(workspace, 'cpp') - procs.append(subprocess.Popen([codeql_bin, "test", "run", "--failing-exitcode=122", f"--slice={slice}/{num_slices}", "--ram=2048", "--format=json", f'--search-path={cpp_language_root}', f'--search-path={language_root}', *test_roots], stdout=test_report_file, stderr=subprocess.PIPE)) - else: - procs.append(subprocess.Popen([codeql_bin, "test", "run", "--failing-exitcode=122", f"--slice={slice}/{num_slices}", "--ram=2048", "--format=json", f'--search-path={language_root}', f'--search-path={language_root}', *test_roots], stdout=test_report_file, stderr=subprocess.PIPE)) + procs.append(subprocess.Popen([codeql_bin, "test", "run", "--failing-exitcode=122", f"--slice={slice}/{num_slices}", "--ram=2048", "--format=json", *test_roots], stdout=test_report_file, stderr=subprocess.PIPE)) for p in procs: - p.wait() + _, err = p.communicate() if p.returncode != 0: - _, err = p.communicate() if p.returncode == 122: # Failed because a test case failed, so just print the regular output. # This will allow us to proceed to validate-test-results, which will fail if diff --git a/.github/workflows/standard_library_upgrade_tests.yml b/.github/workflows/standard_library_upgrade_tests.yml index a03b43c36f..aac2fd1e0e 100644 --- a/.github/workflows/standard_library_upgrade_tests.yml +++ b/.github/workflows/standard_library_upgrade_tests.yml @@ -116,7 +116,7 @@ jobs: stdlib_path = os.path.join(codeql_home, 'codeql-stdlib') cpp_test_root = Path(stdlib_path, 'cpp/ql/test') print(f"Executing tests found (recursively) in the directory '{cpp_test_root}'") - cp = subprocess.run([codeql_bin, "test", "run", "--format=json", f'--search-path={stdlib_path}', cpp_test_root], stdout=test_report_file, stderr=subprocess.PIPE) + cp = subprocess.run([codeql_bin, "test", "run", "--format=json", cpp_test_root], stdout=test_report_file, stderr=subprocess.PIPE) if cp.returncode != 0: print_error_and_fail(f"Failed to run tests with return code {cp.returncode} and error {cp.stderr}") diff --git a/.github/workflows/verify-standard-library-dependencies.yml b/.github/workflows/verify-standard-library-dependencies.yml new file mode 100644 index 0000000000..0b05736ddb --- /dev/null +++ b/.github/workflows/verify-standard-library-dependencies.yml @@ -0,0 +1,79 @@ +name: Verify Standard Library Dependencies + +# Run this workflow every time the "supported_codeql_configs.json" file or a "qlpack.yml" file is changed +on: + pull_request: + branches: + - main + - "rc/**" + - next + paths: + - "supported_codeql_configs.json" + - "qlpack.yml" + workflow_dispatch: + +jobs: + prepare-matrix: + name: Prepare CodeQL configuration matrix + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.export-matrix.outputs.matrix }} + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Export unit test matrix + id: export-matrix + run: | + echo "::set-output name=matrix::$( + jq --compact-output \ + '.supported_environment | map([.+{os: "ubuntu-20.04-xl", codeql_standard_library_ident : .codeql_standard_library | sub("\/"; "_")}]) | flatten | {include: .}' \ + supported_codeql_configs.json + )" + + verify-dependencies: + name: Verify dependencies + needs: prepare-matrix + + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: ${{fromJSON(needs.prepare-matrix.outputs.matrix)}} + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Setup Python 3 + uses: actions/setup-python@v4 + with: + python-version: "3.9" + + - name: Cache CodeQL + id: cache-codeql + uses: actions/cache@v2.1.3 + with: + # A list of files, directories, and wildcard patterns to cache and restore + path: ${{github.workspace}}/codeql_home + # An explicit key for restoring and saving the cache + key: codeql-home-${{matrix.os}}-${{matrix.codeql_cli}}-${{matrix.codeql_standard_library}} + + - name: Install CodeQL + if: steps.cache-codeql.outputs.cache-hit != 'true' + uses: ./.github/actions/install-codeql + with: + codeql-cli-version: ${{matrix.codeql_cli}} + codeql-stdlib-version: ${{matrix.codeql_standard_library}} + codeql-home: ${{ github.workspace }}/codeql_home + + - name: Verify dependencies + shell: bash + env: + CLI_PATH: ${{ github.workspace }}/codeql_home/codeql + STDLIB_PATH: ${{ github.workspace }}/codeql_home/codeql-stdlib + run: | + PATH=$PATH:$CLI_PATH + ls $STDLIB_PATH + pip install -r scripts/requirements.txt + python3 scripts/verify-standard-library-version.py --codeql-repo $STDLIB_PATH --mode verify + diff --git a/.gitignore b/.gitignore index 5466e33c8f..360134b51c 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,6 @@ # C/C++ build artifacts *.o /databases/ + +# CodeQL build artifacts +**/.codeql/** diff --git a/c/.codeqlmanifest.json b/c/.codeqlmanifest.json deleted file mode 100644 index 384848fdd1..0000000000 --- a/c/.codeqlmanifest.json +++ /dev/null @@ -1,3 +0,0 @@ -{ "provide": [ - "*/src/qlpack.yml", - "*/test/qlpack.yml" ] } diff --git a/c/cert/src/codeql-pack.lock.yml b/c/cert/src/codeql-pack.lock.yml new file mode 100644 index 0000000000..b0f02a9d1f --- /dev/null +++ b/c/cert/src/codeql-pack.lock.yml @@ -0,0 +1,6 @@ +--- +dependencies: + codeql/cpp-all: + version: 0.2.3 +compiled: false +lockVersion: 1.0.0 diff --git a/c/cert/src/codeql-suites/cert-default.qls b/c/cert/src/codeql-suites/cert-default.qls index c8652930e9..7ad2fc1a99 100644 --- a/c/cert/src/codeql-suites/cert-default.qls +++ b/c/cert/src/codeql-suites/cert-default.qls @@ -1,5 +1,5 @@ - description: CERT C 2016 (Default) -- qlpack: cert-c-coding-standards +- qlpack: codeql/cert-c-coding-standards - include: kind: - problem diff --git a/c/cert/src/qlpack.yml b/c/cert/src/qlpack.yml index 746f1c3d84..4e8696753c 100644 --- a/c/cert/src/qlpack.yml +++ b/c/cert/src/qlpack.yml @@ -1,4 +1,6 @@ -name: cert-c-coding-standards +name: codeql/cert-c-coding-standards version: 2.13.0-dev suites: codeql-suites -libraryPathDependencies: common-c-coding-standards \ No newline at end of file +dependencies: + codeql/common-c-coding-standards: '*' + codeql/cpp-all: 0.2.3 diff --git a/c/cert/test/codeql-pack.lock.yml b/c/cert/test/codeql-pack.lock.yml new file mode 100644 index 0000000000..b0f02a9d1f --- /dev/null +++ b/c/cert/test/codeql-pack.lock.yml @@ -0,0 +1,6 @@ +--- +dependencies: + codeql/cpp-all: + version: 0.2.3 +compiled: false +lockVersion: 1.0.0 diff --git a/c/cert/test/qlpack.yml b/c/cert/test/qlpack.yml index 0bd9b78912..94d0f1f703 100644 --- a/c/cert/test/qlpack.yml +++ b/c/cert/test/qlpack.yml @@ -1,4 +1,5 @@ -name: cert-c-coding-standards-tests +name: codeql/cert-c-coding-standards-tests version: 2.13.0-dev -libraryPathDependencies: cert-c-coding-standards -extractor: cpp \ No newline at end of file +extractor: cpp +dependencies: + codeql/cert-c-coding-standards: '*' diff --git a/c/common/src/codeql-pack.lock.yml b/c/common/src/codeql-pack.lock.yml new file mode 100644 index 0000000000..b0f02a9d1f --- /dev/null +++ b/c/common/src/codeql-pack.lock.yml @@ -0,0 +1,6 @@ +--- +dependencies: + codeql/cpp-all: + version: 0.2.3 +compiled: false +lockVersion: 1.0.0 diff --git a/c/common/src/qlpack.yml b/c/common/src/qlpack.yml index 6ca9a439e0..32d6970588 100644 --- a/c/common/src/qlpack.yml +++ b/c/common/src/qlpack.yml @@ -1,3 +1,5 @@ -name: common-c-coding-standards +name: codeql/common-c-coding-standards version: 2.13.0-dev -libraryPathDependencies: common-cpp-coding-standards +dependencies: + codeql/common-cpp-coding-standards: '*' + codeql/cpp-all: 0.2.3 diff --git a/c/common/test/codeql-pack.lock.yml b/c/common/test/codeql-pack.lock.yml new file mode 100644 index 0000000000..b0f02a9d1f --- /dev/null +++ b/c/common/test/codeql-pack.lock.yml @@ -0,0 +1,6 @@ +--- +dependencies: + codeql/cpp-all: + version: 0.2.3 +compiled: false +lockVersion: 1.0.0 diff --git a/c/common/test/qlpack.yml b/c/common/test/qlpack.yml index d50e9ff946..1988c80f77 100644 --- a/c/common/test/qlpack.yml +++ b/c/common/test/qlpack.yml @@ -1,4 +1,5 @@ -name: common-c-coding-standards-tests +name: codeql/common-c-coding-standards-tests version: 2.13.0-dev -libraryPathDependencies: common-c-coding-standards extractor: cpp +dependencies: + codeql/common-c-coding-standards: '*' diff --git a/c/misra/src/codeql-pack.lock.yml b/c/misra/src/codeql-pack.lock.yml new file mode 100644 index 0000000000..b0f02a9d1f --- /dev/null +++ b/c/misra/src/codeql-pack.lock.yml @@ -0,0 +1,6 @@ +--- +dependencies: + codeql/cpp-all: + version: 0.2.3 +compiled: false +lockVersion: 1.0.0 diff --git a/c/misra/src/codeql-suites/misra-default.qls b/c/misra/src/codeql-suites/misra-default.qls index d32637556d..473232e741 100644 --- a/c/misra/src/codeql-suites/misra-default.qls +++ b/c/misra/src/codeql-suites/misra-default.qls @@ -1,5 +1,5 @@ - description: MISRA C 2012 (Default) -- qlpack: misra-c-coding-standards +- qlpack: codeql/misra-c-coding-standards - include: kind: - problem diff --git a/c/misra/src/qlpack.yml b/c/misra/src/qlpack.yml index 8397e6062b..e885ea299c 100644 --- a/c/misra/src/qlpack.yml +++ b/c/misra/src/qlpack.yml @@ -1,4 +1,6 @@ -name: misra-c-coding-standards +name: codeql/misra-c-coding-standards version: 2.13.0-dev suites: codeql-suites -libraryPathDependencies: common-c-coding-standards +dependencies: + codeql/common-c-coding-standards: '*' + codeql/cpp-all: 0.2.3 diff --git a/c/misra/test/codeql-pack.lock.yml b/c/misra/test/codeql-pack.lock.yml new file mode 100644 index 0000000000..b0f02a9d1f --- /dev/null +++ b/c/misra/test/codeql-pack.lock.yml @@ -0,0 +1,6 @@ +--- +dependencies: + codeql/cpp-all: + version: 0.2.3 +compiled: false +lockVersion: 1.0.0 diff --git a/c/misra/test/qlpack.yml b/c/misra/test/qlpack.yml index 1d997a60a3..80f708e69a 100644 --- a/c/misra/test/qlpack.yml +++ b/c/misra/test/qlpack.yml @@ -1,4 +1,5 @@ -name: misra-c-coding-standards-tests +name: codeql/misra-c-coding-standards-tests version: 2.13.0-dev -libraryPathDependencies: misra-c-coding-standards -extractor: cpp \ No newline at end of file +extractor: cpp +dependencies: + codeql/misra-c-coding-standards: '*' diff --git a/cpp/.codeqlmanifest.json b/cpp/.codeqlmanifest.json deleted file mode 100644 index 384848fdd1..0000000000 --- a/cpp/.codeqlmanifest.json +++ /dev/null @@ -1,3 +0,0 @@ -{ "provide": [ - "*/src/qlpack.yml", - "*/test/qlpack.yml" ] } diff --git a/cpp/autosar/src/codeql-pack.lock.yml b/cpp/autosar/src/codeql-pack.lock.yml new file mode 100644 index 0000000000..b0f02a9d1f --- /dev/null +++ b/cpp/autosar/src/codeql-pack.lock.yml @@ -0,0 +1,6 @@ +--- +dependencies: + codeql/cpp-all: + version: 0.2.3 +compiled: false +lockVersion: 1.0.0 diff --git a/cpp/autosar/src/codeql-suites/autosar-advisory.qls b/cpp/autosar/src/codeql-suites/autosar-advisory.qls index 163de00856..6460375091 100644 --- a/cpp/autosar/src/codeql-suites/autosar-advisory.qls +++ b/cpp/autosar/src/codeql-suites/autosar-advisory.qls @@ -1,5 +1,5 @@ - description: AUTOSAR C++14 Guidelines 20-11 (Advisory) -- qlpack: autosar-cpp-coding-standards +- qlpack: codeql/autosar-cpp-coding-standards - include: kind: - problem diff --git a/cpp/autosar/src/codeql-suites/autosar-audit.qls b/cpp/autosar/src/codeql-suites/autosar-audit.qls index 6e77e82e77..25f4f1c41c 100644 --- a/cpp/autosar/src/codeql-suites/autosar-audit.qls +++ b/cpp/autosar/src/codeql-suites/autosar-audit.qls @@ -1,5 +1,5 @@ - description: AUTOSAR C++14 Guidelines 20-11 (Audit) -- qlpack: autosar-cpp-coding-standards +- qlpack: codeql/autosar-cpp-coding-standards - include: kind: - problem diff --git a/cpp/autosar/src/codeql-suites/autosar-default.qls b/cpp/autosar/src/codeql-suites/autosar-default.qls index 0296cc54f8..e57d0739d6 100644 --- a/cpp/autosar/src/codeql-suites/autosar-default.qls +++ b/cpp/autosar/src/codeql-suites/autosar-default.qls @@ -1,5 +1,5 @@ - description: AUTOSAR C++14 Guidelines 20-11 (Default) -- qlpack: autosar-cpp-coding-standards +- qlpack: codeql/autosar-cpp-coding-standards - include: kind: - problem diff --git a/cpp/autosar/src/codeql-suites/autosar-required.qls b/cpp/autosar/src/codeql-suites/autosar-required.qls index b79562c66c..aa4173462c 100644 --- a/cpp/autosar/src/codeql-suites/autosar-required.qls +++ b/cpp/autosar/src/codeql-suites/autosar-required.qls @@ -1,5 +1,5 @@ - description: AUTOSAR C++14 Guidelines 20-11 (Required) -- qlpack: autosar-cpp-coding-standards +- qlpack: codeql/autosar-cpp-coding-standards - include: kind: - problem diff --git a/cpp/autosar/src/codeql-suites/autosar-single-translation-unit.qls b/cpp/autosar/src/codeql-suites/autosar-single-translation-unit.qls index 6ba3032fa8..d56a7e306a 100644 --- a/cpp/autosar/src/codeql-suites/autosar-single-translation-unit.qls +++ b/cpp/autosar/src/codeql-suites/autosar-single-translation-unit.qls @@ -1,5 +1,5 @@ - description: AUTOSAR C++14 Guidelines 20-11 (Single Translation Unit) -- qlpack: autosar-cpp-coding-standards +- qlpack: codeql/autosar-cpp-coding-standards - include: kind: - problem diff --git a/cpp/autosar/src/qlpack.yml b/cpp/autosar/src/qlpack.yml index c807587e7e..2c9e235ac4 100644 --- a/cpp/autosar/src/qlpack.yml +++ b/cpp/autosar/src/qlpack.yml @@ -1,4 +1,6 @@ -name: autosar-cpp-coding-standards +name: codeql/autosar-cpp-coding-standards version: 2.13.0-dev suites: codeql-suites -libraryPathDependencies: common-cpp-coding-standards +dependencies: + codeql/common-cpp-coding-standards: '*' + codeql/cpp-all: 0.2.3 diff --git a/cpp/autosar/test/codeql-pack.lock.yml b/cpp/autosar/test/codeql-pack.lock.yml new file mode 100644 index 0000000000..b0f02a9d1f --- /dev/null +++ b/cpp/autosar/test/codeql-pack.lock.yml @@ -0,0 +1,6 @@ +--- +dependencies: + codeql/cpp-all: + version: 0.2.3 +compiled: false +lockVersion: 1.0.0 diff --git a/cpp/autosar/test/qlpack.yml b/cpp/autosar/test/qlpack.yml index 8e4ce61a25..9757b3dc4e 100644 --- a/cpp/autosar/test/qlpack.yml +++ b/cpp/autosar/test/qlpack.yml @@ -1,4 +1,5 @@ -name: autosar-cpp-coding-standards-tests +name: codeql/autosar-cpp-coding-standards-tests version: 2.13.0-dev -libraryPathDependencies: autosar-cpp-coding-standards extractor: cpp +dependencies: + codeql/autosar-cpp-coding-standards: '*' diff --git a/cpp/cert/src/codeql-pack.lock.yml b/cpp/cert/src/codeql-pack.lock.yml new file mode 100644 index 0000000000..b0f02a9d1f --- /dev/null +++ b/cpp/cert/src/codeql-pack.lock.yml @@ -0,0 +1,6 @@ +--- +dependencies: + codeql/cpp-all: + version: 0.2.3 +compiled: false +lockVersion: 1.0.0 diff --git a/cpp/cert/src/codeql-suites/cert-default.qls b/cpp/cert/src/codeql-suites/cert-default.qls index 6ec40af9b9..a003e05ed2 100644 --- a/cpp/cert/src/codeql-suites/cert-default.qls +++ b/cpp/cert/src/codeql-suites/cert-default.qls @@ -1,5 +1,5 @@ - description: CERT C++ 2016 (Default) -- qlpack: cert-cpp-coding-standards +- qlpack: codeql/cert-cpp-coding-standards - include: kind: - problem diff --git a/cpp/cert/src/codeql-suites/cert-single-translation-unit.qls b/cpp/cert/src/codeql-suites/cert-single-translation-unit.qls index ca1315d6ff..0d3f99cbf0 100644 --- a/cpp/cert/src/codeql-suites/cert-single-translation-unit.qls +++ b/cpp/cert/src/codeql-suites/cert-single-translation-unit.qls @@ -1,5 +1,5 @@ - description: CERT C++ 2016 (Single Translation Unit) -- qlpack: cert-cpp-coding-standards +- qlpack: codeql/cert-cpp-coding-standards - include: kind: - problem diff --git a/cpp/cert/src/qlpack.yml b/cpp/cert/src/qlpack.yml index 43fc36ae8e..b2bfe797ba 100644 --- a/cpp/cert/src/qlpack.yml +++ b/cpp/cert/src/qlpack.yml @@ -1,4 +1,6 @@ -name: cert-cpp-coding-standards +name: codeql/cert-cpp-coding-standards version: 2.13.0-dev suites: codeql-suites -libraryPathDependencies: common-cpp-coding-standards +dependencies: + codeql/cpp-all: 0.2.3 + codeql/common-cpp-coding-standards: '*' diff --git a/cpp/cert/test/codeql-pack.lock.yml b/cpp/cert/test/codeql-pack.lock.yml new file mode 100644 index 0000000000..b0f02a9d1f --- /dev/null +++ b/cpp/cert/test/codeql-pack.lock.yml @@ -0,0 +1,6 @@ +--- +dependencies: + codeql/cpp-all: + version: 0.2.3 +compiled: false +lockVersion: 1.0.0 diff --git a/cpp/cert/test/qlpack.yml b/cpp/cert/test/qlpack.yml index 3d68f359f7..f5fc44e682 100644 --- a/cpp/cert/test/qlpack.yml +++ b/cpp/cert/test/qlpack.yml @@ -1,4 +1,5 @@ -name: cert-cpp-coding-standards-tests +name: codeql/cert-cpp-coding-standards-tests version: 2.13.0-dev -libraryPathDependencies: cert-cpp-coding-standards extractor: cpp +dependencies: + codeql/cert-cpp-coding-standards: '*' diff --git a/cpp/common/src/codeql-pack.lock.yml b/cpp/common/src/codeql-pack.lock.yml new file mode 100644 index 0000000000..b0f02a9d1f --- /dev/null +++ b/cpp/common/src/codeql-pack.lock.yml @@ -0,0 +1,6 @@ +--- +dependencies: + codeql/cpp-all: + version: 0.2.3 +compiled: false +lockVersion: 1.0.0 diff --git a/cpp/common/src/codingstandards/cpp/Config.qll b/cpp/common/src/codingstandards/cpp/Config.qll index 7d12340719..5ce3f7a035 100644 --- a/cpp/common/src/codingstandards/cpp/Config.qll +++ b/cpp/common/src/codingstandards/cpp/Config.qll @@ -8,7 +8,7 @@ import codingstandards.cpp.exclusions.RuleMetadata import codingstandards.cpp.deviations.Deviations /** A `coding-standards.xml` configuration file (usually generated from an YAML configuration file). */ -class CodingStandardsFile extends XMLFile { +class CodingStandardsFile extends XmlFile { CodingStandardsFile() { this.getBaseName() = "coding-standards.xml" and // Must be within the users source code. @@ -16,12 +16,12 @@ class CodingStandardsFile extends XMLFile { } } -class CodingStandardsConfigSection extends XMLElement { +class CodingStandardsConfigSection extends XmlElement { CodingStandardsConfigSection() { getParent() instanceof CodingStandardsConfig } } /** A "Coding Standards" configuration file */ -class CodingStandardsConfig extends XMLElement { +class CodingStandardsConfig extends XmlElement { CodingStandardsConfig() { any(CodingStandardsFile csf).getARootElement() = this and this.getName() = "codingstandards" diff --git a/cpp/common/src/codingstandards/cpp/deviations/Deviations.qll b/cpp/common/src/codingstandards/cpp/deviations/Deviations.qll index 9399607e3d..4dfadd12eb 100644 --- a/cpp/common/src/codingstandards/cpp/deviations/Deviations.qll +++ b/cpp/common/src/codingstandards/cpp/deviations/Deviations.qll @@ -17,7 +17,7 @@ predicate applyDeviationsAtQueryLevel() { } /** An element which tells the analysis whether to report deviated results. */ -class CodingStandardsReportDeviatedAlerts extends XMLElement { +class CodingStandardsReportDeviatedAlerts extends XmlElement { CodingStandardsReportDeviatedAlerts() { getParent() instanceof CodingStandardsConfig and hasName("report-deviated-alerts") @@ -35,7 +35,7 @@ class DeviationPermits extends CodingStandardsConfigSection { } /** A deviation permit record, that is specified by a permit identifier */ -class DeviationPermit extends XMLElement { +class DeviationPermit extends XmlElement { DeviationPermit() { getParent() instanceof DeviationPermits and hasName("deviation-permits-entry") @@ -118,7 +118,7 @@ class DeviationPermit extends XMLElement { } /** A deviation record, that is a specified rule or query */ -class DeviationRecord extends XMLElement { +class DeviationRecord extends XmlElement { DeviationRecord() { getParent() instanceof DeviationRecords and hasName("deviations-entry") @@ -134,13 +134,13 @@ class DeviationRecord extends XMLElement { private string getRawPermitId() { result = getAChild("permit-id").getTextValue() } - private XMLElement getRawRaisedBy() { result = getAChild("raised-by") } + private XmlElement getRawRaisedBy() { result = getAChild("raised-by") } private string getRawRaisedByName() { result = getRawRaisedBy().getAChild("name").getTextValue() } private string getRawRaisedByDate() { result = getRawRaisedBy().getAChild("date").getTextValue() } - private XMLElement getRawApprovedBy() { result = getAChild("approved-by") } + private XmlElement getRawApprovedBy() { result = getAChild("approved-by") } private string getRawApprovedByName() { result = getRawApprovedBy().getAChild("name").getTextValue() diff --git a/cpp/common/src/codingstandards/cpp/guideline_recategorizations/GuidelineRecategorizations.qll b/cpp/common/src/codingstandards/cpp/guideline_recategorizations/GuidelineRecategorizations.qll index ff148a4a72..ec5731f1bf 100644 --- a/cpp/common/src/codingstandards/cpp/guideline_recategorizations/GuidelineRecategorizations.qll +++ b/cpp/common/src/codingstandards/cpp/guideline_recategorizations/GuidelineRecategorizations.qll @@ -12,7 +12,7 @@ class GuidelineRecategorizations extends CodingStandardsConfigSection { GuidelineRecategorizations() { hasName("guideline-recategorizations") } } -class GuidelineRecategorization extends XMLElement { +class GuidelineRecategorization extends XmlElement { GuidelineRecategorization() { getParent() instanceof GuidelineRecategorizations and hasName("guideline-recategorizations-entry") diff --git a/cpp/common/src/qlpack.yml b/cpp/common/src/qlpack.yml index 2bf17bb4d1..f52cad36f0 100644 --- a/cpp/common/src/qlpack.yml +++ b/cpp/common/src/qlpack.yml @@ -1,3 +1,4 @@ -name: common-cpp-coding-standards +name: codeql/common-cpp-coding-standards version: 2.13.0-dev -libraryPathDependencies: codeql-cpp +dependencies: + codeql/cpp-all: 0.2.3 diff --git a/cpp/common/test/codeql-pack.lock.yml b/cpp/common/test/codeql-pack.lock.yml new file mode 100644 index 0000000000..b0f02a9d1f --- /dev/null +++ b/cpp/common/test/codeql-pack.lock.yml @@ -0,0 +1,6 @@ +--- +dependencies: + codeql/cpp-all: + version: 0.2.3 +compiled: false +lockVersion: 1.0.0 diff --git a/cpp/common/test/qlpack.yml b/cpp/common/test/qlpack.yml index 54337ac6b1..ab68ae894e 100644 --- a/cpp/common/test/qlpack.yml +++ b/cpp/common/test/qlpack.yml @@ -1,4 +1,5 @@ -name: common-cpp-coding-standards-tests +name: codeql/common-cpp-coding-standards-tests version: 2.13.0-dev -libraryPathDependencies: common-cpp-coding-standards extractor: cpp +dependencies: + codeql/common-cpp-coding-standards: '*' diff --git a/cpp/misra/src/codeql-pack.lock.yml b/cpp/misra/src/codeql-pack.lock.yml new file mode 100644 index 0000000000..b0f02a9d1f --- /dev/null +++ b/cpp/misra/src/codeql-pack.lock.yml @@ -0,0 +1,6 @@ +--- +dependencies: + codeql/cpp-all: + version: 0.2.3 +compiled: false +lockVersion: 1.0.0 diff --git a/cpp/misra/src/qlpack.yml b/cpp/misra/src/qlpack.yml index 09e0ac17df..98e6234d99 100644 --- a/cpp/misra/src/qlpack.yml +++ b/cpp/misra/src/qlpack.yml @@ -1,3 +1,5 @@ -name: misra-cpp-coding-standards +name: codeql/misra-cpp-coding-standards version: 2.13.0-dev -libraryPathDependencies: common-cpp-coding-standards +dependencies: + codeql/common-cpp-coding-standards: '*' + codeql/cpp-all: 0.2.3 diff --git a/cpp/misra/test/codeql-pack.lock.yml b/cpp/misra/test/codeql-pack.lock.yml new file mode 100644 index 0000000000..b0f02a9d1f --- /dev/null +++ b/cpp/misra/test/codeql-pack.lock.yml @@ -0,0 +1,6 @@ +--- +dependencies: + codeql/cpp-all: + version: 0.2.3 +compiled: false +lockVersion: 1.0.0 diff --git a/cpp/misra/test/qlpack.yml b/cpp/misra/test/qlpack.yml index a01fec91ea..bc07630c8f 100644 --- a/cpp/misra/test/qlpack.yml +++ b/cpp/misra/test/qlpack.yml @@ -1,4 +1,5 @@ -name: misra-cpp-coding-standards-tests +name: codeql/misra-cpp-coding-standards-tests version: 2.13.0-dev -libraryPathDependencies: misra-cpp-coding-standards extractor: cpp +dependencies: + codeql/misra-cpp-coding-standards: '*' \ No newline at end of file diff --git a/cpp/report/src/codeql-pack.lock.yml b/cpp/report/src/codeql-pack.lock.yml new file mode 100644 index 0000000000..b0f02a9d1f --- /dev/null +++ b/cpp/report/src/codeql-pack.lock.yml @@ -0,0 +1,6 @@ +--- +dependencies: + codeql/cpp-all: + version: 0.2.3 +compiled: false +lockVersion: 1.0.0 diff --git a/cpp/report/src/qlpack.yml b/cpp/report/src/qlpack.yml index cb0a7c048e..974b048917 100644 --- a/cpp/report/src/qlpack.yml +++ b/cpp/report/src/qlpack.yml @@ -1,3 +1,4 @@ -name: report-cpp-coding-standards +name: codeql/report-cpp-coding-standards version: 2.13.0-dev -libraryPathDependencies: codeql-cpp +dependencies: + codeql/cpp-all: 0.2.3 diff --git a/docs/development_handbook.md b/docs/development_handbook.md index d35c03f2d2..87028595a3 100644 --- a/docs/development_handbook.md +++ b/docs/development_handbook.md @@ -31,8 +31,11 @@ | 0.23.0 | 2022-07-05 | Remco Vermeulen | Update text to consider both the C++ and the C standards. | | 0.24.0 | 2022-07-05 | Remco Vermeulen | Update release process to include steps for external help files. | | 0.25.0 | 2022-07-22 | Jeroen Ketema | Document the existence and purpose of the `next` branch. | -| 0.26.0 | 2022-08-10 | Remco Vermeulen | Address incorrect package file generation command. This was missing the required language argument. | -| 0.27.0 | 2022-11-08 | Luke Cartey | Update the versions of C we intend to support to exclude C90, which reflects the intended scope at the outset of the project. | +| 0.26.0 | 2022-08-10 | Remco Vermeulen | Address incorrect package file generation command. This was missing the required language argument. + | +| 0.27.0 | 2022-11-08 | Luke Cartey | Update the versions of C we intend to support to exclude C90, which reflects the intended scope at the outset of the project. + | +| 0.28.0 | 2023-01-27 | David Bartolomeo | Add section on installing QL dependencies and update CLI commands to account for the migration to CodeQL packs. ## Scope of work @@ -333,6 +336,12 @@ A query **must** include: All public predicates, classes, modules and files should be documented with QLDoc. All QLDoc should follow the [QLDoc style guide](https://github.com/github/codeql/blob/main/docs/qldoc-style-guide.md). +### Installing QL dependencies + +All of our query and library packs depend on the standard CodeQL library for C++, `codeql/cpp-all`. This dependency is specified in the `qlpack.yml` file for each of our packs. Before compiling, running, or testing any of our queries or libraries, you must download the proper dependencies by running `python3 scripts/install-packs.py`. This will download the appropriate version of the standard library from the public package registry, installing it in a cache in your `~/.codeql` directory. When compiling queries or running tests, the QL compiler will pick up the appropriate dependencies from this cache without any need to specify an additional library search path on the command line. + +Because the downloaded packs are cached, it is only necessary to run `install-packs.py` once each time we upgrade to a new standard library version. It does not hurt to run it more often; if all necessary packs are already in the download cache, then it will complete quickly without trying to download anything. + ### Unit testing Every query which implements a rule **must** include: @@ -346,11 +355,10 @@ During query development in VS Code, the unit tests can be run using the [testin Unit tests can also be run on the command line using the CodeQL CLI. With an appropriate CodeQL CLI (as specified in the `supported_codeql_configs.json` at the root of the repository), you can run the following from the root of the repository: ``` -codeql test run --show-extractor-output --search-path . path/to/test/directory +codeql test run --show-extractor-output path/to/test/directory ``` * `--show-extractor-output` - this shows the output from the extractor. It is most useful when the test fails because the file is not valid C++, where the extractor output will include the compilation failure. This is not shown in VS Code. -* `--search-path .` - this allows the CodeQL CLI to discover all the QL packs within our repository. * `path/to/test/directory` - this can be a qlref file (like `cpp/autosar/test/rules/A15-2-2/`), a rule directory (`cpp/autosar/test/rules/A15-2-2/`) or a test qlpack (`cpp/autosar/test/`). For more details on running unit tests with the CodeQL CLI see the [Testing custom queries](https://codeql.github.com/docs/codeql-cli/testing-custom-queries/) help topic. @@ -669,7 +677,6 @@ ls cpp/cert/src/$(cat cpp/cert/test/rules/EXP52-CPP/DoNotRelyOnSideEffectsInDecl # Run a test. See # https://github.com/github/codeql-coding-standards/blob/main/development_handbook.md#unit-testing codeql test run --show-extractor-output \ - --search-path . \ cpp/cert/test/rules/EXP52-CPP/DoNotRelyOnSideEffectsInDeclTypeOperand.qlref # Get a db error? Applying the recommended fix @@ -687,7 +694,7 @@ codeql test run --show-extractor-output \ # If the expected output is not yet present, it is printed as a diff: mv cpp/cert/test/rules/EXP52-CPP/DoNotRelyOnSideEffectsInDeclTypeOperand.expected foo -codeql test run --show-extractor-output --search-path . \ +codeql test run --show-extractor-output \ cpp/cert/test/rules/EXP52-CPP/DoNotRelyOnSideEffectsInDeclTypeOperand.qlref # The actual output can be accepted via codeql test accept (which moves some files): diff --git a/scripts/get_workspace_packs.py b/scripts/get_workspace_packs.py new file mode 100644 index 0000000000..fc9054c641 --- /dev/null +++ b/scripts/get_workspace_packs.py @@ -0,0 +1,14 @@ +import glob +import json +import os + +def get_workspace_packs(root): + # Find the packs by globbing using the 'provide' patterns in the manifest. + os.chdir(root) + with open('.codeqlmanifest.json') as manifest_file: + manifest = json.load(manifest_file) + packs = [] + for pattern in manifest['provide']: + packs.extend(glob.glob(pattern, recursive=True)) + + return packs diff --git a/scripts/install-packs.py b/scripts/install-packs.py new file mode 100644 index 0000000000..a0286e2228 --- /dev/null +++ b/scripts/install-packs.py @@ -0,0 +1,23 @@ +import argparse +import os +import subprocess +import get_workspace_packs + +parser = argparse.ArgumentParser(description="Install CodeQL library pack dependencies.") +parser.add_argument('--mode', required=False, choices=['use-lock', 'update', 'verify', 'no-lock'], default="use-lock", help="Installation mode, identical to the `--mode` argument to `codeql pack install`") +parser.add_argument('--codeql', required=False, default='codeql', help="Path to the `codeql` executable.") +args = parser.parse_args() + +# Find the root of the repo +root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + +packs = get_workspace_packs.get_workspace_packs(root) + +# Find the CodeQL packs in the repo. This can also return packs outside of the repo, if those packs +# are installed in a sibling directory to the CLI. +for pack in packs: + pack_path = os.path.join(root, pack) + # Run `codeql pack install` to install dependencies. + command = [args.codeql, 'pack', 'install', '--mode', args.mode, pack_path] + print(f'Running `{" ".join(command)}`') + subprocess.check_call(command) diff --git a/scripts/verify-standard-library-version.py b/scripts/verify-standard-library-version.py new file mode 100644 index 0000000000..0b46068e1d --- /dev/null +++ b/scripts/verify-standard-library-version.py @@ -0,0 +1,68 @@ +import argparse +import json +import os +import subprocess +import yaml +import get_workspace_packs + +def get_codeql_packs(codeql_repo, codeql): + command = [codeql, 'resolve', 'qlpacks', '--additional-packs', codeql_repo, '--format', 'json'] + print(f'Running `{" ".join(command)}`') + packs_json = subprocess.check_output(command) + print(packs_json) + packs = json.loads(packs_json) + return packs + +parser = argparse.ArgumentParser(description='Ensure that CodeQL library pack dependency versions match the supported configuration.') +parser.add_argument('--codeql-repo', required=True, help='Path to checkout of `github/codeql` repo at desired branch.') +parser.add_argument('--mode', required=False, choices=['verify', 'update'], default='verify', help="`verify` to fail on mismatch; `update` to change `qlpack.lock.yml` files to use new version.") +parser.add_argument('--codeql', required=False, default='codeql', help='Path to the `codeql` executable.') +args = parser.parse_args() + +# Find the root of the repo +root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + +# Get the packs for the repo's workspace. +workspace_packs = get_workspace_packs.get_workspace_packs(root) + +# Get the packs from the `codeql` repo checkout. +codeql_packs = get_codeql_packs(args.codeql_repo, args.codeql) + +failed = False +for pack in workspace_packs: + pack_path = os.path.join(root, pack) + + print(f"Scanning dependencies of '{pack_path}'...") + + # Read our pack's configuration file. + with open(pack_path) as pack_file: + pack_yaml = yaml.safe_load(pack_file) + + updated = False + if 'dependencies' in pack_yaml: + dependencies = pack_yaml['dependencies'] + for ref_name in dependencies: + ref_version = dependencies[ref_name] + if ref_name in codeql_packs: + # Found this reference in the `codeql` repo. The version of the reference should match + # the version of that pack in the `codeql` repo. + lib_path = codeql_packs[ref_name][0] + lib_path = os.path.join(lib_path, 'qlpack.yml') + with open(lib_path) as lib_file: + lib_yaml = yaml.safe_load(lib_file) + lib_version = lib_yaml['version'] + if ref_version != lib_version: + print(f"Mismatched versions for '{ref_name}', referenced from '{pack_path}'. " + + f"referenced version is '{ref_version}', but should be '{lib_version}'.") + if args.mode == 'verify': + failed = True # Report an error at the end. + else: + pack_yaml['dependencies'][ref_name] = lib_version + updated = True # Update our pack in-place. + + if updated: + print(f"Updating '{pack_path}'...") + with open(pack_path, 'w', newline='\n') as pack_file: # Always use LF even on Windows + yaml.safe_dump(pack_yaml, pack_file, sort_keys=False) + +exit(1 if failed else 0)