mirror of
https://github.com/github/codeql.git
synced 2025-12-26 21:56:39 +01:00
Merge branch 'main' into promote-xxe
This commit is contained in:
@@ -100,12 +100,12 @@ As a consequence, ``A != B`` has a very different meaning to the :ref:`negation
|
||||
- ``1 = [1 .. 2]`` holds, because ``1 = 1``.
|
||||
- ``not 1 = [1 .. 2]`` doesn't hold, because there is a common value (``1``).
|
||||
|
||||
#. Compare ``1`` and ``none()`` (the "empty set"):
|
||||
- ``1 != none()`` doesn't hold, because there are no values in ``none()``, so no values
|
||||
#. Compare ``1`` and ``int empty() { none() }`` (a predicate defining the empty set of integers):
|
||||
- ``1 != empty()`` doesn't hold, because there are no values in ``empty()``, so no values
|
||||
that are not equal to ``1``.
|
||||
- ``1 = none()`` also doesn't hold, because there are no values in ``none()``, so no values
|
||||
- ``1 = empty()`` also doesn't hold, because there are no values in ``empty()``, so no values
|
||||
that are equal to ``1``.
|
||||
- ``not 1 = none()`` holds, because there are no common values.
|
||||
- ``not 1 = empty()`` holds, because there are no common values.
|
||||
|
||||
.. index:: instanceof
|
||||
.. _type-checks:
|
||||
@@ -295,9 +295,48 @@ necessary, since they highlight the default precedence. You usually only add par
|
||||
override the default precedence, but you can also add them to make your code easier to read
|
||||
(even if they aren't required).
|
||||
|
||||
QL also has two nullary connectives indicating the always true formula,
|
||||
``any()``, and the always false formula, ``none()``.
|
||||
|
||||
The logical connectives in QL work similarly to Boolean connectives in other programming
|
||||
languages. Here is a brief overview:
|
||||
|
||||
.. index:: any, true
|
||||
.. _true:
|
||||
|
||||
``any()``
|
||||
=========
|
||||
|
||||
The built-in predicate ``any()`` is a formula that always holds.
|
||||
|
||||
**Example**
|
||||
|
||||
The following predicate defines the set of all expressions.
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
Expr allExpressions() {
|
||||
any()
|
||||
}
|
||||
|
||||
.. index:: none, false
|
||||
.. _false:
|
||||
|
||||
``none()``
|
||||
==========
|
||||
|
||||
The built-in predicate ``none()`` is a formula that never holds.
|
||||
|
||||
**Example**
|
||||
|
||||
The following predicate defines the empty set of integers.
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
int emptySet() {
|
||||
none()
|
||||
}
|
||||
|
||||
.. index:: not, negation
|
||||
.. _negation:
|
||||
|
||||
|
||||
@@ -387,26 +387,26 @@ from ``OneTwoThree`` and ``int``.
|
||||
Non-extending subtypes
|
||||
======================
|
||||
|
||||
Besides extending base types, classes can also declare `instanceof` relationships with other types.
|
||||
Declaring a class as `instanceof Foo` is roughly equivalent to saying `this instanceof Foo` in the characteristic predicate.
|
||||
The main differences are that you can call methods on Bar via `super` and you can get better optimisation.
|
||||
Besides extending base types, classes can also declare ``instanceof`` relationships with other types.
|
||||
Declaring a class as ``instanceof Foo`` is roughly equivalent to saying ``this instanceof Foo`` in the characteristic predicate.
|
||||
The main differences are that you can call methods on ``Bar`` via ``super`` and you can get better optimisation.
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
class Foo extends int {
|
||||
Foo() { this in [1 .. 10] }
|
||||
|
||||
string foo_method() { result = "foo" }
|
||||
string fooMethod() { result = "foo" }
|
||||
}
|
||||
|
||||
class Bar instanceof Foo {
|
||||
string toString() { result = super.foo_method() }
|
||||
string toString() { result = super.fooMethod() }
|
||||
}
|
||||
|
||||
In this example, the characteristic predicate from `Foo` also applies to `Bar`.
|
||||
However, `foo_method` is not exposed in `Bar`, so the query `select any(Bar b).foo_method()`
|
||||
In this example, the characteristic predicate from ``Foo`` also applies to ``Bar``.
|
||||
However, ``fooMethod`` is not exposed in ``Bar``, so the query ``select any(Bar b).fooMethod()``
|
||||
results in a compile time error. Note from the example that it is still possible to access
|
||||
methods from instanceof supertypes from within the specialising class with the `super` keyword.
|
||||
methods from instanceof supertypes from within the specialising class with the ``super`` keyword.
|
||||
|
||||
Crucially, the instanceof **supertypes** are not **base types**.
|
||||
This means that these supertypes do not participate in overriding, and any fields of such
|
||||
@@ -430,10 +430,10 @@ The following example demonstrates this.
|
||||
override string foo() { result = "bar" }
|
||||
}
|
||||
|
||||
Here, the method `Bar::foo` does not override `Foo::foo`.
|
||||
Instead, it overrides only `Interface::foo`.
|
||||
This means that `select any(Foo f).foo()` yields only `foo`.
|
||||
Had `Bar` been defined as `extends Foo`, then `select any(Foo b)` would yield `bar`.
|
||||
Here, the method ``Bar::foo`` does not override ``Foo::foo``.
|
||||
Instead, it overrides only ``Interface::foo``.
|
||||
This means that ``select any(Foo f).foo()`` yields ``foo``.
|
||||
Had ``Bar`` been defined as ``extends Foo``, then ``select any(Foo f).foo()`` would yield ``bar``.
|
||||
|
||||
.. _character-types:
|
||||
.. _domain-types:
|
||||
|
||||
Reference in New Issue
Block a user