Closed github-learning-lab[bot] closed 3 years ago
exists
quantifierSo far, we have declared variables in the from
section of a query clause. Sometimes we need temporary variables in other parts of the query, and don't want to expose them in the query clause. The exists
keyword helps us do this. It is a quantifier: it introduces temporary variables and checks if they satisfy a particular condition.
To understand how exists
works, visit the documentation.
Then look at this example from the QL detective tutorials:
from Person p
where exists(string c | p.getColorHair() = c)
select p
This query selects all persons with a hair color that is a string
. So we'll get all persons that are not bald, since we are able to find a c
that defines their hair color. We don't really need c
in the query except to know that it exists.
NetworkByteSwap
classEdit the file 9_class_network_byteswap.ql
with the template below:
import cpp
class NetworkByteSwap extends Expr {
NetworkByteSwap () {
// TODO: replace <class> and <var>
exists(<class> <var> |
// TODO: <condition>
)
}
}
from NetworkByteSwap n
select n, "Network byte swap"
extends Expr
, which means it is a subclass of Expr
, and it begins by taking all values from Expr
. Now you need to restrict it to only the expressions we are interested in, which satisfy the condition of step 8.
NetworkByteSwap() { ... }
. The template includes the exists
quantifier, which will help.exists
that refers to a macro invocation.exists
. Use the same logic from the where
section of your query in step 8.select
section of your query in step 8. You can refer to the macro invocation using the name of the variable you created, and you can refer to the expression using the this
variable.Congratulations, looks like the query you introduced in 836eff5da3cd85ad33b2d322305f292d857096d4 finds the correct results!
If you created a pull request, merge it.
Let's continue to the next step.
Step 9: Write your own class
In this step we will learn how to write our own CodeQL classes. This will help us make the logic of our query more readable, easier to reuse, and easier to refine.
We'd like to find the same results as in the previous step, i.e. the top level expressions that correspond to the
ntohl
,ntohs
andntohll
macro invocations. It would be useful if we could refer to all such expressions directly, just like we can useMacroInvocation
from the standard library to refer to all macro invocations.We will define a class to describe exactly this set of expressions, and use it in the last step of this course.
The
Expr
class is the set of all expressions, and we are interested in a more specific set of expressions, so the class we write will be a subclass ofExpr
.