Merge branch 'main' into promote-xxe

This commit is contained in:
Rasmus Wriedt Larsen
2022-04-20 13:42:02 +02:00
307 changed files with 6388 additions and 16068 deletions

View File

@@ -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:

View File

@@ -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: