Skip to content

feat(codeql): Add CPP analysis #11682

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 129 additions & 0 deletions .github/scripts/process_sarif.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
#!/usr/bin/env python3

# This script is used to process the SARIF file generated by CodeQL and
# to rename files back to .ino and adjust line numbers to match the original .ino files.

import json
import sys
import os

def process_artifact_location(artifact_location, renamed_files):
"""
Process a single artifact location to rename .cpp files back to .ino
"""
if 'uri' in artifact_location:
uri = artifact_location['uri']
if uri in renamed_files:
print(f"Renaming file: {uri} -> {renamed_files[uri]}")
artifact_location['uri'] = renamed_files[uri]
return True
return False

def process_region(region):
"""
Adjust line numbers in a region by decreasing them by 1
"""
if 'startLine' in region:
region['startLine'] = max(1, region['startLine'] - 1)
if 'endLine' in region:
region['endLine'] = max(1, region['endLine'] - 1)

def process_physical_location(physical_location, renamed_files):
"""
Process a physical location to rename files and adjust line numbers
"""
file_renamed = False

if 'artifactLocation' in physical_location:
if process_artifact_location(physical_location['artifactLocation'], renamed_files):
file_renamed = True

# Adjust line numbers if the file was renamed
if file_renamed and 'region' in physical_location:
process_region(physical_location['region'])

return file_renamed


def process_sarif_file(sarif_file, renamed_files_file):
"""
Process SARIF file to rename files back to .ino and adjust line numbers
"""
# Read the renamed files mapping
with open(renamed_files_file, 'r') as f:
renamed_files = json.load(f)

print(f"Loaded {len(renamed_files)} file mappings:")
for cpp_file, ino_file in renamed_files.items():
print(f" {cpp_file} -> {ino_file}")


# Read the SARIF file
with open(sarif_file, 'r') as f:
sarif_data = json.load(f)

files_processed = 0

# Process each run
if 'runs' in sarif_data:
for run in sarif_data['runs']:
# Process results
if 'results' in run:
for result in run['results']:
# Process all locations in the result
if 'locations' in result:
for location in result['locations']:
if 'physicalLocation' in location:
if process_physical_location(location['physicalLocation'], renamed_files):
files_processed += 1

# Process related locations if they exist
if 'relatedLocations' in result:
for location in result['relatedLocations']:
if 'physicalLocation' in location:
if process_physical_location(location['physicalLocation'], renamed_files):
files_processed += 1

# Process artifacts if they exist
if 'artifacts' in run:
for artifact in run['artifacts']:
if 'location' in artifact and 'uri' in artifact['location']:
uri = artifact['location']['uri']
if uri in renamed_files:
artifact['location']['uri'] = renamed_files[uri]
files_processed += 1

print(f"Processed {files_processed} file references")

# Write the processed SARIF file
with open(sarif_file, 'w') as f:
json.dump(sarif_data, f, indent=2)

def main():
if len(sys.argv) != 3:
print("Usage: python3 sarif_nobuild.py <sarif_file> <renamed_files_file>")
sys.exit(1)

sarif_file = sys.argv[1]
renamed_files_file = sys.argv[2]

# Check if files exist
if not os.path.exists(sarif_file):
print(f"SARIF file not found: {sarif_file}")
sys.exit(1)

if not os.path.exists(renamed_files_file):
print(f"Renamed files mapping not found: {renamed_files_file}")
sys.exit(1)

try:
process_sarif_file(sarif_file, renamed_files_file)
print("SARIF file processed successfully")
except Exception as e:
print(f"Error processing SARIF file: {e}")
import traceback
traceback.print_exc()
sys.exit(1)

if __name__ == "__main__":
main()
55 changes: 54 additions & 1 deletion .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ on:
- master
pull_request:
paths:
- "**/*.c"
- "**/*.cpp"
- "**/*.h"
- "**/*.ino"
- "**/*.py"
- ".github/workflows/*.yml"
- ".github/workflows/*.yaml"
Expand All @@ -17,19 +21,68 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
language: [python, actions]
language: [python, actions, cpp]

steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Process .ino files
if: matrix.language == 'cpp'
run: |
# Create a mapping file to track renamed files
echo "{}" > renamed_files.json

# Find all .ino files and process them
find . -name "*.ino" -type f | while read -r file; do
echo "Processing $file"

# Get the relative path from repository root
rel_path=$(realpath --relative-to=. "$file")
cpp_path="${rel_path%.ino}.cpp"

# Create new .cpp file with Arduino.h include
echo "#include <Arduino.h>" > "$cpp_path"

# Append the original content
cat "$file" >> "$cpp_path"

# Update the mapping file
jq --arg ino "$rel_path" --arg cpp "$cpp_path" '. += {($cpp): $ino}' renamed_files.json > temp.json && mv temp.json renamed_files.json

# Remove the original .ino file
rm "$file"

echo "Converted $file to $cpp_path"
done

echo "Renamed files mapping:"
cat renamed_files.json

- name: Initialize CodeQL
uses: github/codeql-action/init@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
with:
build-mode: none
languages: ${{ matrix.language }}
config-file: ./.github/codeql/codeql-config.yml

- name: Run CodeQL Analysis
uses: github/codeql-action/analyze@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
with:
category: "/language:${{ matrix.language }}"
output: sarif-results
upload: failure-only

- name: Process SARIF file
if: matrix.language == 'cpp'
run: |
sarif_file="sarif-results/${{ matrix.language }}.sarif"

# Run the Python script to process the SARIF file
python3 .github/scripts/process_sarif.py "$sarif_file" "renamed_files.json"

- name: Upload SARIF file
uses: github/codeql-action/upload-sarif@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
with:
sarif_file: sarif-results/${{ matrix.language }}.sarif
category: "/language:${{ matrix.language }}"
Loading