Skip to content

Implement first green query for Arduino C++ developers#4

Open
olegoaer wants to merge 4 commits intomainfrom
dev
Open

Implement first green query for Arduino C++ developers#4
olegoaer wants to merge 4 commits intomainfrom
dev

Conversation

@olegoaer
Copy link
Member

This pull request introduces a new CodeQL query to help prevent accidental hardware damage on Arduino devices by detecting unsafe usage of the EEPROM.write method inside the main loop() function. It also adds an example C++ file that illustrates the problematic pattern.

However, the .expected file is missing for now.

@olegoaer olegoaer added the 🗃️ rule rule improvment or rule development or bug label Mar 14, 2026
call.getEnclosingFunction() = loop and

// Guard check: ensures the call isn't wrapped in a conditional
not exists(IfStmt s | s.getAChild*() = call.getEnclosingStmt())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

La Guard est imparfaite,
Elle suppose que le if soit suffisemment discriminant pour protéger le matériel ce dont nous n'avons pas de preuve

where
// Target the Arduino loop() function
loop.getName() = "loop" and
call.getEnclosingFunction() = loop and
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cette détéction de write n'est pas transitive, si une fonction externe appel un write et que cette fonction est présente dans la loop, la requête ne descend pas dans le call graph https://codeql.github.com/docs/codeql-language-guides/refining-a-query-to-account-for-edge-cases/

from Constructor c, Field f where f.getDeclaringType() = c.getDeclaringType() and f.isPrivate() // check for constructor initialization lists as well and not exists(ConstructorFieldInit i | i.getTarget() = f and i.getEnclosingFunction() = c) // check for initializations performed indirectly by methods called // as a result of the constructor being called and not exists(Function fun, Assignment a | c.calls*(fun) and a = f.getAnAssignment() and a.getEnclosingFunction() = fun) // ignore cases where the constructor source code is not available and exists(c.getBlock()) select c, "Constructor does not initialize fields $@.", f, f.getName()

On pourrait les remplacer par

exists(Function loopFn | loopFn.getName() = "loop" and loopFn.calls*(call.getEnclosingFunction()) )

Pour ajouter la transitivité

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🗃️ rule rule improvment or rule development or bug

2 participants