Tom Hvitved
6135b5b7eb
C#: Updated expected test output
2019-03-04 13:19:00 +01:00
Tom Hvitved
2e1ba7b1f9
C#: Speedup `Implements.qll`
2019-03-04 13:19:00 +01:00
calum
f7b4985ed1
C#: Fix merge conflict.
2019-03-04 09:54:48 +00:00
calum
741666d561
C#: Address review comment.
2019-03-04 09:54:40 +00:00
calum
d77b60bba8
C#: Add `preservesValue` to `NonLocalJumpNode.getAJumpSuccessor`. Allow `DataFlow::Configuration::isAdditionalFlowStep` to jump between callables.
2019-03-04 09:54:28 +00:00
calum
7343e70151
C#: Fix tests
2019-03-04 09:54:12 +00:00
calum
74b30d6071
C#: Model EntityFramework
2019-03-04 09:53:49 +00:00
calum
7010ca8cf3
C#: Fix whitespace in test.
2019-03-04 09:53:37 +00:00
Tom Hvitved
51e5a301cd
Merge pull request #956 from raulgarciamsft/users/raulga/ICryptoTransform
...
Detect usage of ICryptoTransform that would be thread-unsafe
2019-03-01 11:49:27 +01:00
Calum Grant
c945b7793c
Merge pull request #944 from hvitved/csharp/cfg/accessor-call
...
C#: Improve CFG for assignments
2019-02-28 09:34:56 +00:00
Raul Garcia
1ae18974d8
Fixing bugs found during Code Review.
2019-02-27 18:41:23 -08:00
Tom Hvitved
4cbbe37b1e
C#: Updated expected test output
2019-02-27 19:25:14 +01:00
Tom Hvitved
996b0efa47
C#: Address review comments
2019-02-27 13:49:15 +01:00
Tom Hvitved
7027cd36c6
C#: Speedup `isGuardedByNode()`
2019-02-27 13:29:14 +01:00
Tom Hvitved
72384e57e1
C#: Speedup `Assertion::strictlyDominates()`
2019-02-27 13:29:14 +01:00
Tom Hvitved
baa596ce6c
C#: Speedup `ControlFlowElement::controlsBlock()`
2019-02-27 13:29:14 +01:00
Raul Garcia
f8ae56a27c
Improving documentation
2019-02-26 16:22:39 -08:00
Calum Grant
5c2804d3ac
Merge pull request #968 from hvitved/csharp/dataflow-performance
...
C#: Improve join orders in `DataFlow` module
2019-02-26 17:34:16 +00:00
Tom Hvitved
8abf76b618
C#: Reduce size of `getAThrownException()`
...
In the precense of multiple core libraries, `getAThrownException()` would return
multiple copies of the same exception, say `System.OverflowException`, one for each
core library. With this change we try to identify which core library a given control
flow element was compiled against, and only return the corresponding version.
2019-02-26 15:11:45 +01:00
Raul Garcia
9bb7816a3c
Making changes based on feedback.
2019-02-22 10:10:20 -08:00
Tom Hvitved
116997cf85
Merge pull request #961 from calumgrant/cs/cve-2019-0657
...
C#: Update cs/use-of-vulnerable-package to detect CVE-2019-0657
2019-02-22 18:01:58 +01:00
Calum Grant
cd721f38b8
Merge pull request #967 from hvitved/csharp/ssa/block-precedes-var
...
C#: Use explict recursion in `blockPrecedesVar()`
2019-02-22 14:08:26 +00:00
Calum Grant
e93140d136
Merge pull request #959 from hvitved/csharp/dispose-not-called-on-exc-performance
...
C#: Improve performance of `cs/dispose-not-called-on-throw`
2019-02-22 14:04:48 +00:00
Tom Hvitved
74377a28c9
C#: Improve join orders in `DataFlow` module
2019-02-22 09:31:19 +01:00
Tom Hvitved
f02ef51459
C#: Use explict recursion in `blockPrecedesVar()`
2019-02-21 17:14:23 +01:00
calum
15341965e0
C#: Update cs/use-of-vulnerable-package to detect CVE-2019-0657
2019-02-21 11:48:48 +00:00
Tom Hvitved
f8bb00a81c
C#: Cache `Call::getArgumentForParameter()`
2019-02-21 11:41:40 +01:00
Tom Hvitved
c8eb537591
C#: Improve performance of `cs/dispose-not-called-on-throw`
2019-02-21 11:20:54 +01:00
Tom Hvitved
c3a62b3656
C#: Always inline `ControlFlowElement::[reachableFrom|getAReachableElement]()`
2019-02-21 11:20:47 +01:00
Tom Hvitved
a382a5876f
Merge pull request #808 from calumgrant/cs/double-checked-locks
...
C#: Work on cs/unsafe-double-checked-lock
2019-02-21 11:17:35 +01:00
Raul Garcia
7d197692ac
Adding a new rule for detecting usage of static objects that implement ICryptoTransform that would be thread-unsafe, and potentially result in incorrect cryptographic results.
2019-02-20 17:07:04 -08:00
calum
40f3b8b439
C#: Address review comments (documentation).
2019-02-20 18:00:30 +00:00
calum
b0e2e436a7
C#: Fix documentation.
2019-02-18 09:37:10 +00:00
Tom Hvitved
5ce9b25ec9
C#: Improve CFG for assignments
...
Write accesses in assignments, such as the access to `x` in `x = 0` are not
evaluated, so they should not have entries in the control flow graph. However,
qualifiers (and indexer arguments) should still be evaluated, for example in
```
x.Foo.Bar = 0;
```
the CFG should be `x --> x.Foo --> 0 --> x.Foo.Bar = 0` (as opposed to
`x --> x.Foo --> x.Foo.Bar --> 0 --> x.Foo.Bar = 0`, prior to this change).
A special case is assignments via acessors (properties, indexers, and event
adders), where we do want to include the access in the control flow graph,
as it represents the accessor call:
```
x.Prop = 0;
```
But instead of `x --> x.set_Prop --> 0 --> x.Prop = 0` the CFG should be
`x --> 0 --> x.set_Prop --> x.Prop = 0`, as the setter is called *after* the
assigned value has been evaluated.
An even more special case is tuple assignments via accessors:
```
(x.Prop1, y.Prop2) = (0, 1);
```
Here the CFG should be
`x --> y --> 0 --> 1 --> x.set_Prop1 --> y.set_Prop2 --> (x.Prop1, y.Prop2) = (0, 1)`.
2019-02-16 19:19:24 +01:00
Tom Hvitved
096757dadf
C#: Add CFG tests for accessor calls
2019-02-14 20:24:04 +01:00
Tom Hvitved
0cb2c0994a
Merge pull request #930 from calumgrant/cs/suppress-alerts
...
C#: Add some alert suppression comments
2019-02-13 09:34:18 +01:00
Anders Schack-Mulligen
fc9c7ea55a
CSharp: Autoformat qls
2019-02-12 14:38:42 +01:00
Anders Schack-Mulligen
bcaaebfe7e
CSharp: Autoformat qlls
2019-02-12 14:38:42 +01:00
calum
884af9bd7f
C#: Fix alert.
2019-02-12 13:34:33 +00:00
calum
e18eeb8d2a
C#: Address review comments.
2019-02-12 12:56:58 +00:00
calum
1e1784239c
C#: Alert suppression comments for lgtm[cs/catch-of-all-exceptions
2019-02-12 12:45:22 +00:00
calum
33e6b5e55f
C#: Fix tests
2019-02-12 10:59:31 +00:00
Calum Grant
0513828000
Merge pull request #922 from hvitved/csharp/cfg/remove-exception-edges
...
C#: Remove some impossible CFG exception edges
2019-02-12 10:42:07 +00:00
Calum Grant
e10ea73a07
Merge pull request #901 from hvitved/csharp/conditional-assign-join-order
...
C#: Improve join order in `conditionalAssign()`
2019-02-12 10:39:49 +00:00
Calum Grant
b557b7b438
Merge pull request #895 from hvitved/csharp/get-a-thrown-exception
...
C#: Avoid using `ExceptionClass` in deliberate Cartesian products
2019-02-12 09:49:03 +00:00
calum
b51eb2cb92
C#: Fix tags in documentation.
2019-02-11 17:52:55 +00:00
calum
8bb1af884a
C# extractor: Limit string literals to 1MB. This is made more complicated by the fact that we need to limit the number of bytes to output, rather than the number of characters.
2019-02-11 17:36:23 +00:00
Tom Hvitved
8cb8c967d2
C#: Remove some impossible CFG exception edges
2019-02-11 16:17:01 +01:00
Tom Hvitved
6ff4206d53
C#: Add CFG test
2019-02-11 16:03:25 +01:00
Tom Hvitved
14bdea1cf2
Merge pull request #847 from calumgrant/cs/json.net
...
C#: Model Json.NET dataflow
2019-02-11 15:48:01 +01:00
calum
d18bbf6a73
C#: Make query only apply to reftypes, since I believe valuetypes are safe or cannot be fixed trivially using the volatile keyword.
2019-02-08 15:18:29 +00:00
calum
b473d2f7a8
C#: Update change notes. Decrease the priority of this query because the `volatile` keyword is no longer needed on modern .Net runtimes.
2019-02-08 14:59:45 +00:00
calum
7addd41e38
C#: Fixes to double-checked lock.
2019-02-08 14:57:57 +00:00
calum
c9cf183878
C#: Fix merge conflicts.
2019-02-08 14:38:51 +00:00
calum
08d13ea363
C#: Address review comments.
2019-02-08 14:38:51 +00:00
calum
7f7a92d092
C#: Model Json.NET dataflow.
2019-02-08 14:37:54 +00:00
Tom Hvitved
e663abd5da
C#: Avoid using `ExceptionClass` in deliberate Cartesian products
...
Using the class `ExceptionClass` in combination with a deliberate Cartesian
product can lead to bad join orders, for example
```
EVALUATE NONRECURSIVE RELATION:
Completion::TriedControlFlowElement::getAThrownException_dispred#ff(int this, int result) :-
{1} r1 = JOIN Expr::Expr::getType_dispred#ff_10#join_rhs WITH @integral_type#f ON Expr::Expr::getType_dispred#ff_10#join_rhs.<0>=@integral_type#f.<0> OUTPUT FIELDS {Expr::Expr::getType_dispred#ff_10#join_rhs.<1>}
{1} r2 = JOIN r1 WITH @un_op#f ON r1.<0>=@un_op#f.<0> OUTPUT FIELDS {r1.<0>}
{1} r3 = JOIN r2 WITH Stmt::TryStmt::getATriedElement#ff_1#join_rhs ON r2.<0>=Stmt::TryStmt::getATriedElement#ff_1#join_rhs.<0> OUTPUT FIELDS {r2.<0>}
{2} r4 = JOIN r3 WITH Stmt::ExceptionClass#f CARTESIAN PRODUCT OUTPUT FIELDS {Stmt::ExceptionClass#f.<0>,r3.<0>}
{2} r5 = JOIN r4 WITH System::SystemOverflowExceptionClass#class#f ON r4.<0>=System::SystemOverflowExceptionClass#class#f.<0> OUTPUT FIELDS {r4.<1>,r4.<0>}
```
where the CP is made with `ExceptionClass` rather than `SystemOverflowExceptionClass`
directly.
2019-02-07 20:42:21 +01:00
Tom Hvitved
e074daee74
C#: Limit number of non-required CFG splits
2019-02-07 20:40:20 +01:00
Tom Hvitved
7d11eb5758
C#: Add CFG test with exponential splitting
...
This test times out as it would require constructing 2^40 copies of the same node.
2019-02-07 20:40:20 +01:00
Tom Hvitved
ab8ad9f8e6
C#: Improve a few join-orders in CFG splitting library
2019-02-07 20:40:20 +01:00
semmle-qlci
87c5872bc5
Merge pull request #903 from hvitved/csharp/successor-type-qldoc
...
Approved by calumgrant
2019-02-07 19:38:58 +00:00
calum
8afbd2d897
C#: Extend TrivialProperty to also include CIL::TrivialProperty
2019-02-07 12:05:42 +00:00
Tom Hvitved
ba575db93b
C#: Add QL doc to `SuccessorType.qll`
2019-02-07 12:09:09 +01:00
Calum Grant
383e82a3f3
Merge pull request #886 from hvitved/csharp/cfg/restructure
...
C#: Split up `ControlFlowGraph.qll` into multiple files
2019-02-07 11:06:19 +00:00
Tom Hvitved
5f027e1761
Merge pull request #860 from calumgrant/cs/library-flow
...
C#: Refactor LibraryTypeDataFlow
2019-02-07 11:52:05 +01:00
Calum Grant
4274bb136f
Merge pull request #892 from hvitved/csharp/get-arg-for-param-bad-magic
...
C#: Prevent bad magic in `getArgumentForParameter()`
2019-02-07 10:50:21 +00:00
Calum Grant
73d56e1bdb
Merge pull request #881 from hvitved/csharp/remove-get-url
...
C#: Remove `getUrl()` predicate
2019-02-07 10:47:56 +00:00
Tom Hvitved
23e63e983c
C#: Improve join order in `conditionalAssign()`
...
Fixes a bad join-order in `Guards::Internal::conditionalAssign#ffff#antijoin_rhs#1`:
```
[2019-01-25 14:12:03] (377s) Starting to evaluate predicate Guards::Internal::conditionalAssign#ffff#antijoin_rhs#1
[2019-01-25 14:20:41] (895s) Tuple counts:
9302551 ~1% {7} r1 = JOIN ControlFlowGraph::ControlFlow::Internal::PreSsa::Definition::getAPhiInput_dispred#ff WITH Guards::Internal::conditionalAssign#ffff#shared#1 ON ControlFlowGraph::ControlFlow::Internal::PreSsa::Definition::getAPhiInput_dispred#ff.<0>=Guards::Internal::conditionalAssign#ffff#shared#1.<0> OUTPUT FIELDS {ControlFlowGraph::ControlFlow::Internal::PreSsa::Definition::getAPhiInput_dispred#ff.<1>,Guards::Internal::conditionalAssign#ffff#shared#1.<1>,Guards::Internal::conditionalAssign#ffff#shared#1.<2>,Guards::Internal::conditionalAssign#ffff#shared#1.<0>,Guards::Internal::conditionalAssign#ffff#shared#1.<3>,Guards::Internal::conditionalAssign#ffff#shared#1.<4>,Guards::Internal::conditionalAssign#ffff#shared#1.<5>}
9302551 ~7% {8} r2 = JOIN r1 WITH ControlFlowGraph::ControlFlow::Internal::PreSsa::Definition::getBasicBlock_dispred#ff ON r1.<0>=ControlFlowGraph::ControlFlow::Internal::PreSsa::Definition::getBasicBlock_dispred#ff.<0> OUTPUT FIELDS {r1.<1>,ControlFlowGraph::ControlFlow::Internal::PreSsa::Definition::getBasicBlock_dispred#ff.<1>,r1.<2>,r1.<3>,r1.<4>,r1.<5>,r1.<6>,r1.<0>}
1223774650 ~0% {8} r3 = JOIN r2 WITH Guards::Internal::Guard::preControlsDirect_dispred#fff ON r2.<0>=Guards::Internal::Guard::preControlsDirect_dispred#fff.<0> AND r2.<1>=Guards::Internal::Guard::preControlsDirect_dispred#fff.<1> OUTPUT FIELDS {r2.<6>,Guards::Internal::Guard::preControlsDirect_dispred#fff.<2>,r2.<0>,r2.<2>,r2.<3>,r2.<4>,r2.<5>,r2.<7>}
80626 ~0% {7} r4 = JOIN r3 WITH Guards::AbstractValue::getDualValue_dispred#ff ON r3.<0>=Guards::AbstractValue::getDualValue_dispred#ff.<0> AND r3.<1>=Guards::AbstractValue::getDualValue_dispred#ff.<1> OUTPUT FIELDS {r3.<2>,r3.<3>,r3.<4>,r3.<5>,r3.<6>,r3.<0>,r3.<7>}
9293564 ~0% {7} r5 = Guards::Internal::conditionalAssign#ffff#shared#2 AND NOT Guards::Internal::conditionalAssign#ffff#antijoin_rhs(Guards::Internal::conditionalAssign#ffff#shared#2.<0>,Guards::Internal::conditionalAssign#ffff#shared#2.<1>,Guards::Internal::conditionalAssign#ffff#shared#2.<2>,Guards::Internal::conditionalAssign#ffff#shared#2.<3>,Guards::Internal::conditionalAssign#ffff#shared#2.<4>,Guards::Internal::conditionalAssign#ffff#shared#2.<5>,Guards::Internal::conditionalAssign#ffff#shared#2.<6>)
9293564 ~1% {7} r6 = SCAN r5 OUTPUT FIELDS {r5.<6>,r5.<0>,r5.<1>,r5.<2>,r5.<3>,r5.<4>,r5.<5>}
9293564 ~2% {8} r7 = JOIN r6 WITH ControlFlowGraph::ControlFlow::Internal::PreSsa::Definition::getBasicBlock_dispred#ff ON r6.<0>=ControlFlowGraph::ControlFlow::Internal::PreSsa::Definition::getBasicBlock_dispred#ff.<0> OUTPUT FIELDS {ControlFlowGraph::ControlFlow::Internal::PreSsa::Definition::getBasicBlock_dispred#ff.<1>,r6.<2>,r6.<1>,r6.<3>,r6.<4>,r6.<5>,r6.<6>,r6.<0>}
1940 ~2% {7} r8 = JOIN r7 WITH ControlFlowGraph::ControlFlow::Internal::PreBasicBlocks::PreBasicBlock::dominates_dispred#ff ON r7.<0>=ControlFlowGraph::ControlFlow::Internal::PreBasicBlocks::PreBasicBlock::dominates_dispred#ff.<0> AND r7.<1>=ControlFlowGraph::ControlFlow::Internal::PreBasicBlocks::PreBasicBlock::dominates_dispred#ff.<1> OUTPUT FIELDS {r7.<2>,r7.<1>,r7.<3>,r7.<4>,r7.<5>,r7.<6>,r7.<7>}
82566 ~0% {7} r9 = r4 \/ r8
return r9
```
2019-02-07 10:35:31 +01:00
calum
ce7e9901cc
C#: Address review comments.
2019-02-06 17:15:43 +00:00
Tom Hvitved
8812f26517
C#: Address review comments
2019-02-06 13:17:47 +01:00
Tom Hvitved
c3378c44a1
C#: Prevent bad magic in `getArgumentForParameter()`
2019-02-06 13:09:56 +01:00
Calum Grant
dd75e5bce3
Merge pull request #877 from hvitved/csharp/matches-handle
...
C#: Use `matchesHandle()` instead of `getLabel()`
2019-02-06 11:02:09 +00:00
semmle-qlci
4b81ffab96
Merge pull request #869 from hvitved/csharp/autoformat
...
Approved by calumgrant
2019-02-05 16:35:10 +00:00
Tom Hvitved
37c55750f7
Merge pull request #873 from calumgrant/cs/format-getresource-strings
...
C#: Fix FP in cs/format-argument-unused
2019-02-05 17:12:04 +01:00
Tom Hvitved
23b9b1eb72
C#: Cache `Splits::toString()`
2019-02-05 15:01:25 +01:00
Tom Hvitved
8c7c582e07
C#: Move successor types into own file
2019-02-05 14:27:09 +01:00
Tom Hvitved
0992e01f91
C#: Move `Splitting` and `Reachability` modules into own file
2019-02-05 14:27:09 +01:00
Tom Hvitved
3503e9b57e
C#: Move `PreSsa` module into own file
2019-02-05 14:27:09 +01:00
Tom Hvitved
5306d1ea0d
C#: Move `PreBasicBlocks` module into own file
2019-02-05 13:41:50 +01:00
Tom Hvitved
83fb32828f
C#: Move `NonReturning` module into own file
2019-02-05 11:50:03 +01:00
Tom Hvitved
64539b0263
C#: Move `Completion.qll`
2019-02-05 11:45:33 +01:00
Tom Hvitved
0211837e24
C#: Remove `getUrl()` predicate
2019-02-05 11:07:13 +01:00
Tom Hvitved
d829d98165
Merge branch 'master' into csharp/autoformat
2019-02-05 10:37:42 +01:00
Tom Hvitved
13503d068c
C#: Use `matchesHandle()` instead of `getLabel()`
2019-02-04 16:20:47 +01:00
Tom Hvitved
b4b6fdd12b
C#: Revert recent change to `AccessorCall`
...
The recent change to `AccessorCall` on dd99525566
resulted
in some bad join-orders, so I have (partly) reverted them. This means that the issues
orignally addressed by that change are now reintroduced, and I plan to instead apply a
fix to the CFG, which--unlike the original fix--should be able to handle multi-property-tuple
assignments.
2019-02-04 15:14:18 +01:00
calum
7d17724cae
C#: The empty string is not considered a format string for this query.
2019-02-04 12:53:12 +00:00
calum
eb0036172e
C#: Add test for false-positive.
2019-02-04 12:30:43 +00:00
calum
f8870e78e7
C#: Fix test.
2019-02-04 11:51:04 +00:00
Tom Hvitved
910995af90
C#: Autoformat QL code
2019-02-04 10:32:30 +01:00
Robert Marsh
e1d289ffb4
Merge pull request #759 from calumgrant/cs/interface-tostring
...
C#: Remove FPs from cs/call-to-object-tostring
2019-01-31 12:03:49 -08:00
Robert Marsh
f3b4cb4640
Merge pull request #848 from calumgrant/cs/lgtm-suppress-alerts
...
C#: Suppress cs/catch-of-all-exceptions
2019-01-31 12:03:26 -08:00
calum
5144f89a5b
C#: Fix dataflow.
2019-01-31 19:53:46 +00:00
calum
92eb857dac
C#: Add documentation.
2019-01-31 17:46:28 +00:00
calum
4274854f0f
C#: Refactor TCallableFlowSinkDelegateArg
2019-01-31 16:03:23 +00:00
calum
713c7a8c20
C#: Refactor TCallableFlowSourceDelegateArg
2019-01-31 15:42:09 +00:00
calum
18ff4583ef
C#: Refactor TCallableFlowSourceArg to remove callable.
2019-01-31 12:05:26 +00:00
Felicity Chapman
54242f4009
Merge pull request #849 from jf205/locations
...
Update links to QL help topics in GH repo files (SD-2999)
2019-01-30 11:06:22 +00:00
Calum Grant
9b7f4a8ce5
Merge pull request #845 from hvitved/csharp/get-type-non-null
...
C#: Teach guards library about `object.GetType()`
2019-01-30 10:08:05 +00:00
Calum Grant
722402fc89
Merge pull request #825 from hvitved/csharp/cfg/splitting-performance
...
C#: Improve performance of CFG split set computation
2019-01-30 10:05:25 +00:00
james
7cc1442ecb
Update link text
2019-01-30 09:44:07 +00:00
james
a98aae0a24
update links to lgtm.com/docs
2019-01-30 08:02:03 +00:00
james
81137aa7b4
update links to locations in .ql files
2019-01-30 08:02:02 +00:00
james
9d1a050f35
update links to locations in .qll files
2019-01-30 08:01:49 +00:00
calum
f39daaeeab
C#: Suppress cs/catch-of-all-exceptions
2019-01-29 18:22:12 +00:00
calum
d63df71a8a
C#: Fix merge conflict.
2019-01-29 18:15:33 +00:00
calum
423513169f
C#: Address review comments. Introduce `Member::isEffectivelyPublic()` because `isEffectivelyPrivate` and `isEffectivelyInternal` are almost always used together.
2019-01-29 18:05:29 +00:00
calum
931b6b4ee5
C#: Exclude interfaces and abstract classes from cs/call-to-object-tostring
2019-01-29 18:04:26 +00:00
Tom Hvitved
16d3399039
C#: Teach guards library about `object.GetType()`
2019-01-29 16:40:36 +01:00
Tom Hvitved
87bb4a1d56
C#: Add null guard test involving `GetType()`
2019-01-29 16:32:13 +01:00
Calum Grant
c86e6bd6ff
Merge pull request #826 from hvitved/csharp/autobuild/dotnet-install-script-cleanup
...
C#: Cleanup dotnet install script after installation in autobuilder
2019-01-28 16:33:55 +00:00
Calum Grant
eef1abfa69
Merge pull request #743 from hvitved/csharp/dataflow-splitting
...
C#: Teach data flow library about CFG splitting
2019-01-28 16:31:24 +00:00
Tom Hvitved
86721ff800
C#: Add more documentation to `SuccSplits` module
2019-01-28 14:12:17 +01:00
Tom Hvitved
ed8112a538
C#: Cleanup dotnet install script after installation in autobuilder
2019-01-25 15:26:03 +01:00
Tom Hvitved
50522caa6e
C#: Improve performance of CFG split set computation
...
Rewrite the predicate `succSplits()` and the construction of the IPA type `TSplits`.
The two are now mutually dependent, see more in the comment for the module
`SuccSplits`.
2019-01-25 14:35:56 +01:00
Tom Hvitved
078becc57b
C#: Address review comments
2019-01-25 12:06:34 +01:00
Calum Grant
c6d0600e76
Merge pull request #798 from hvitved/csharp/accessor-calls
...
C#: Redefine `AccessorCall`
2019-01-24 10:21:32 +00:00
calum
420c943cce
C#: Fix FP in cs/call-to-object-tostring
2019-01-23 16:14:25 +00:00
Tom Hvitved
779039b8bb
C#: Address review comments
2019-01-23 08:56:39 +01:00
calum
790db3ab67
C#: Address review comments.
2019-01-22 17:29:58 +00:00
calum
c9ffb38e4b
C#: Add sources and sinks in Winforms. Update some queries with new sources and sinks.
2019-01-18 15:42:44 +00:00
Tom Hvitved
dd99525566
C#: Redefine `AccessorCall`
...
The syntactic node assiociated with accessor calls was previously always the
underlying member access. For example, in
```
x.Prop = y.Prop;
```
the implicit call to `x.set_Prop()` was at the syntactic node `x.Prop`, while the
implicit call to `y.get_Prop()` was at the syntactic node `y.Prop`.
However, this breaks the invariant that arguments to calls dominate the call itself,
as the argument `y.Prop` for the implicit `value` parameter in `x.set_Prop()` will
be evaluated after the call (the left-hand side in an assignment is evaluated before
the right-hand side).
The solution is to redefine the access call to `x.set_Prop()` to point to the whole
assignment `x.Prop = y.Prop`, instead of the access `x.Prop`. For reads, we still want
to associate the accessor call with the member access.
A corner case arises when multiple setters are called in a tuple assignment:
```
(x.Prop1, x.Prop2) = (0, 1)
```
In this case, we cannot associate the assignment with both `x.set_Prop1()` and
`x.set_Prop2()`, so we instead revert to using the underlying member accesses as
before.
2019-01-18 13:56:23 +01:00
Tom Hvitved
2caf724826
C#: Add more tests
2019-01-18 12:07:22 +01:00
Tom Hvitved
9031e19c88
C#: Recognize `ref` assignments through delegate calls
2019-01-16 15:53:31 +01:00
Tom Hvitved
fc5076b466
C#: Add test for assignment through delegate `ref` argument
2019-01-16 15:22:45 +01:00
Tom Hvitved
b2f99dbbc7
C#: Teach data flow library about CFG splitting
...
Data flow nodes for expressions do not take CFG splitting into account. Example:
```
if (b)
x = tainted;
x = x.ToLower();
if (!b)
Use(x);
```
Flow is incorrectly reported from `tainted` to `x` in `Use(x)`, because the step
from `tainted` to `x.ToLower()` throws away the information that `b = true`.
The solution is to remember the splitting in data flow expression nodes, that is,
to represent the exact control flow node instead of just the expression. With that
we get flow from `tainted` to `[b = true] x.ToLower()`, but not from `tainted` to
`[b = false] x.ToLower()`.
The data flow API remains unchanged, but in order for analyses to fully benefit from
CFG splitting, sanitizers in particular should be CFG-based instead of expression-based:
```
if (b)
x = tainted;
if (IsInvalid(x))
return;
Use(x);
```
If the call to `IsInvalid()` is a sanitizer, then defining an expression node to be
a sanitizer using `GuardedExpr` will be too conservative (`x` in `Use(x)` is in fact
not guarded). However, `[b = true] x` in `[b = true] Use(x)` is guarded, and to help
defining guard-based sanitizers, the class `GuardedDataFlowNode` has been introduced.
2019-01-16 10:39:27 +01:00
Tom Hvitved
f768abb0e6
C#: Add data flow test with CFG splitting
2019-01-16 10:29:26 +01:00
Tom Hvitved
abb3f71ec8
C#: Add `GuardedControlFlowNode`
2019-01-16 10:29:26 +01:00
Tom Hvitved
f323049b9d
C#: CFG for expressions without enclosing callables, e.g. field initializers
2019-01-16 10:29:26 +01:00
Tom Hvitved
901f389a7d
C#: Add CFG tests for field/property initializers
2019-01-16 10:29:26 +01:00
Calum Grant
6cc4c2d31f
Merge pull request #762 from hvitved/csharp/autoformat/libraries
...
C#: Autoformat QLL files
2019-01-15 12:19:50 +00:00
Calum Grant
d4d5c47adb
Merge pull request #749 from hvitved/csharp/remove-def-use
...
C#: Remove `DefUse.qll`
2019-01-15 10:52:39 +00:00
Tom Hvitved
f90b0fd16f
C#: Convert some multi-line comments
2019-01-14 14:08:54 +01:00
Tom Hvitved
b81d2ca8fa
C#: Autoformat QLL files
2019-01-14 14:08:54 +01:00
Tom Hvitved
bbc49dce40
Merge pull request #755 from calumgrant/cs/extractor-alerts
...
C#: Fix some LGTM alerts on the extractor
2019-01-14 10:47:44 +01:00
semmle-qlci
b78fcd39be
Merge pull request #745 from hvitved/csharp/query/missed-readonly-modifier
...
Approved by calumgrant
2019-01-14 08:43:59 +00:00
semmle-qlci
3fe9f92817
Merge pull request #746 from hvitved/csharp/is-valid-explicit-params-type
...
Approved by calumgrant
2019-01-14 08:43:30 +00:00
calum
e76eb1641a
C#: Address review comment.
2019-01-11 16:13:04 +00:00
Tom Hvitved
36e4b879e9
C#: Remove comment
2019-01-11 14:32:34 +01:00
Tom Hvitved
390ebc96ae
C#: Autoformat QL files
2019-01-11 13:55:28 +01:00
calum
de4f592bba
C#: Add alert suppression comments for cs/similar-file
2019-01-11 12:36:20 +00:00
calum
a44a86bf6f
C#: Add alert suppression comments. Rename e to ex in catch clauses for consistency.
2019-01-11 12:32:24 +00:00
calum
fb0cae87a8
C#: Fix some alerts, and fix a potential NullReferenceException.
2019-01-11 12:12:11 +00:00
Tom Hvitved
c06fc2af09
C#: Remove `DefUse.qll`
2019-01-11 09:35:38 +01:00
Tom Hvitved
0f7dc51e89
C#: Fix performance issue in `isValidExplicitParamsType()`
2019-01-10 21:19:23 +01:00
Tom Hvitved
2197736128
C#: Speedup `cs/missed-readonly-modifier`
2019-01-10 20:57:36 +01:00
Calum Grant
89becbce9a
Merge pull request #726 from hvitved/csharp/cfg/foreach-multi-variables
...
C#: Fix CFG for `foreach` statements with tuple declarations
2019-01-09 14:47:01 +00:00
Calum Grant
bd9a2d71ba
Merge pull request #719 from hvitved/csharp/autoformat/queries
...
C#: Autoformat QL queries
2019-01-09 10:48:22 +00:00
Calum Grant
6f827140d7
Merge pull request #710 from hvitved/csharp/extractor/standalone-runtimes
...
C#: Improve logic for looking up .NET runtime in standalone mode
2019-01-07 10:22:17 +00:00
Pavel Avgustinov
42cf76027a
Merge branch 'cs/assembly-labels' of https://github.com/calumgrant/ql into HEAD
2019-01-04 18:23:49 +00:00
Tom Hvitved
6fccfa3b0a
C#: Fix CFG for `foreach` statements with tuple declarations
2019-01-04 18:51:55 +01:00
Tom Hvitved
72b3514970
C#: Add CFG tests for `foreach` statements with multipe variable declarations
2019-01-04 18:17:48 +01:00
calum
651d207d0d
C#: Fix assembly labels.
2019-01-04 16:19:43 +00:00
Max Schaefer
b4f400fb23
Merge remote-tracking branch 'upstream/next' into qlucie/master
2019-01-04 10:35:57 +00:00
Tom Hvitved
c962f55cd0
C#: Address review comments
2019-01-04 11:32:23 +01:00
semmle-qlci
c0868bcb9e
Merge pull request #708 from hvitved/csharp/ssa-read-splitting
...
Approved by calumgrant
2019-01-03 17:59:55 +00:00
Tom Hvitved
f187e7444c
C#: Autoformat follow-up changes
2019-01-02 13:51:30 +01:00
Tom Hvitved
daa45322b1
C#: Autoformat QL queries
2019-01-02 12:59:07 +01:00
Tom Hvitved
412248c77f
C#: Address review comments
2019-01-02 10:42:08 +01:00
Tom Hvitved
2427f0ada9
C#: Remove redundant cast
2019-01-02 10:09:24 +01:00
Tom Hvitved
5879e58741
C#: Account for CFG splitting in `AssignableDefinition::getAFirstRead()` and `AssignableRead::getANextRead()`
2019-01-02 09:50:13 +01:00
Tom Hvitved
f06a20f666
C#: Add SSA tests with CFG splitting
2019-01-02 09:48:04 +01:00
calum
0fe0544769
C#: Fix extraction error when Event accessors are ordinary methods.
2018-12-31 14:20:47 +00:00
calum
6267946768
C#: Revert breaking change
2018-12-21 14:39:01 +00:00
calumgrant
1b11abfec7
Merge pull request #709 from hvitved/csharp/autoformat/tests
...
C#: Autoformat QL tests
2018-12-21 11:12:31 +00:00
Tom Hvitved
5478155155
Merge pull request #615 from calumgrant/cs/extractor-caching
...
C# extractor: Improve performance by changing the caching
2018-12-21 09:36:43 +01:00
calum
d73b28efe4
C#: Address review comments.
...
Add more tests for duplicated entities, and fix some duplicated entities.
Update the TupleTypes output - some extraneous results gone so it's probably better.
2018-12-20 20:23:12 +00:00
Tom Hvitved
af38a2b9c5
Merge branch 'master' into csharp/autoformat/tests
2018-12-20 20:59:10 +01:00
calumgrant
a6003533a4
Merge pull request #692 from hvitved/csharp/maybe-null-as-expression
...
C#: Consider `as` expressions as maybe-`null` in `cs/dereferenced-value-may-be-null`
2018-12-20 18:49:33 +00:00
calumgrant
7dd263b413
Merge pull request #689 from hvitved/csharp/remove-get-url
...
C#: Remove `getUrl()` predicates
2018-12-20 18:49:15 +00:00
calum
f5cfd93d8d
C#: Use pattern matching.
2018-12-20 14:38:49 +00:00
Tom Hvitved
9f375de716
C#: Improve logic for looking up .NET runtime in standalone mode
...
Instead of only considering a fixed set of paths for `dotnet` and `mono`,
first attempt to lookup the paths based on the `PATH` environment variable.
This change also fixes a potential `System.IO.DirectoryNotFoundException` exception,
which could be thrown when the `shared/Microsoft.NETCore.App` folder was not
present.
2018-12-20 15:34:15 +01:00
Tom Hvitved
33fcbc958d
C#: Consider `as` expressions as maybe-`null` in `cs/dereferenced-value-may-be-null`
2018-12-20 14:54:48 +01:00
Tom Hvitved
ccda1c8d3d
C#: Add nullness test using an `as` expression
2018-12-20 14:54:48 +01:00
Tom Hvitved
c66f67dfac
C#: Address review comment
2018-12-20 14:49:56 +01:00
calum
d687dd9deb
C#: Address review comments. Replace GetHashValue() with MetadataTokens.GetToken().
...
C#: Make path IDs consistent.
2018-12-20 13:02:25 +00:00
Tom Hvitved
231465143d
C#: Autoformat QL tests
2018-12-20 10:19:59 +01:00
Tom Hvitved
546d750045
C#: Reintroduce `getURL()`
...
It turns out that we still need `getURL()` to account for cases where there is no
`getLocation()`. Not having `getURL()` for entities without a `getLocation()` results
in a `file://0:0:0:0` URL, which is not rendered in QL4E, unlike a `""` URL.
2018-12-19 20:47:33 +01:00
Tom Hvitved
b2500a0c26
Merge branch 'master' into csharp/maybe-null-path-query
2018-12-19 20:22:19 +01:00
semmle-qlci
83ccddff7a
Merge pull request #707 from hvitved/csharp/bounded-fast-tc
...
Approved by calumgrant
2018-12-19 19:20:42 +00:00
calum
efe2fb502e
C#: Convert libraries to use `matchesHandle` instead of `getLabel`.
2018-12-19 15:22:53 +00:00
calum
2acde22f43
C#: Add QL and tests for handles.
2018-12-19 15:22:53 +00:00
calum
0ee209e6a4
C#: Update db stats.
2018-12-19 15:22:53 +00:00
calum
fb8895bdc7
C#: Extract metadata handle information.
2018-12-19 15:22:53 +00:00
Tom Hvitved
10627738d0
C#: Introduce `Ssa::Definition::getElement()` and `AssignableDefinition::getElement()`
2018-12-19 14:56:56 +01:00
calumgrant
e15481a622
Merge pull request #702 from hvitved/csharp/remove-deprecated
...
C#: Remove deprecated predicates
2018-12-19 12:10:49 +00:00
calum
6a54a6d3e5
C#: Fix changed unit tests.
2018-12-19 11:03:05 +00:00
calum
93ce34ad58
C#: Add a new object->entity cache.
2018-12-19 10:40:07 +00:00
calum
88734f1f8a
C#: Fix label conflicts.
...
C#: Remove unnecessary code from Property.
2018-12-19 10:40:07 +00:00
calum
a7cdf528dd
C#: Improve performance by mapping directly from entities to labels.
2018-12-19 10:40:06 +00:00
Tom Hvitved
e5cbac5c13
C#: Replace a use of `boundedFastTC` with `fastTC`
2018-12-19 11:37:22 +01:00
calumgrant
b051b7546d
Merge pull request #638 from hvitved/csharp/split-dominance-performance
...
C#: Speedup `Assertions::strictlyDominates()` and `ControlFlowElement::controlsBlock()`
2018-12-18 13:05:36 +00:00
Tom Hvitved
edf1df1577
C#: Remove tests for deprecated predicates
2018-12-18 10:43:12 +01:00
Tom Hvitved
d9ae5933d4
C#: Remove deprecated predicates
2018-12-17 16:20:41 +01:00
Tom Hvitved
e14259126e
Merge pull request #658 from calumgrant/cs/extractor/for-is
...
C#: Fix extraction bug for variable declarations in for condition
2018-12-17 16:16:00 +01:00
Tom Hvitved
e822510d6b
C#: Fix typo
2018-12-17 15:33:05 +01:00
calumgrant
6648c8414f
Merge pull request #680 from hvitved/csharp/data-flow-performance-tweaks
...
C#: Minor data flow performance tweaks
2018-12-17 14:25:51 +00:00
calumgrant
dbd0c7e80a
Merge pull request #674 from hvitved/csharp/cache-get-label
...
C#: Cache `NamedElement::getLabel()`
2018-12-17 14:24:01 +00:00
calumgrant
f50d0e373a
Merge pull request #642 from hvitved/csharp/extractor/nullness-refactorings
...
C#: nullness related extractor refactorings
2018-12-17 14:16:51 +00:00
Tom Hvitved
5f269b2d87
Merge branch 'master' into cs/extractor/for-is
2018-12-17 11:14:50 +01:00
Tom Hvitved
ada0115d6a
C#: Remove `getUrl()` predicates
...
As described on https://lgtm.com/help/ql/locations#providing-location-information ,
there is no need to provide a `getUrl()` predicate, when there is a `getLocation()`
predicate. Not only is it redundant, but it can also be slow because of string
construction.
2018-12-17 10:52:24 +01:00
Tom Hvitved
91e4f7ad83
C#: Make `cs/dereferenced-value-may-be-null` a path query
2018-12-14 12:07:16 +00:00
Tom Hvitved
e2f271bddb
C#: Add more guard implication steps
2018-12-14 12:03:32 +00:00
Tom Hvitved
078dc7b6c0
C#: Fix false positives in `cs/dereferenced-value-may-be-null`
2018-12-14 12:03:32 +00:00
Tom Hvitved
287ce4e683
C#: Add more nullness tests
2018-12-14 12:03:32 +00:00
Tom Hvitved
654f2ae290
C#: Address review comment
2018-12-14 10:38:34 +00:00
Aditya Sharad
7bc729a7dc
Merge master into next.
2018-12-14 10:16:47 +00:00
Tom Hvitved
56b80ae13a
C#: Add `getALocation()` for namespaces and namespace declarations
2018-12-14 10:16:20 +00:00
Tom Hvitved
b11d5c5075
Merge pull request #679 from calumgrant/cs/omitted-array-size
...
C#: Extract stackalloc initializers
2018-12-14 07:48:46 +01:00
Aditya Sharad
f71e5ac338
Merge master into next.
2018-12-13 17:57:31 +00:00
calum
9fba643fb0
C#: Address review comments.
2018-12-13 13:53:58 +00:00
calumgrant
16c065274d
Merge pull request #666 from hvitved/csharp/useless-upcast-performance
...
C#: Improve performance of `cs/useless-upcast`
2018-12-13 12:04:12 +00:00
Tom Hvitved
b155a0f5fb
C#: Avoid computing CIL strings and non-PDB locations in data flow library
...
Computing strings and locations for CIL instructions can be quite time consuming.
The CIL `toString()`s are not very helpful in path explanations, and their locations
are only useful when a PDB source file exists. Therefore, produce a simple constant
`toString()`, and restrict locations to those in PDB files.
2018-12-12 21:58:16 +01:00
Tom Hvitved
344466a8c1
C#: Cache `DataFlow::Node::getEnclosingCallable()`
2018-12-12 21:49:21 +01:00
Aditya Sharad
f92456fcad
Merge master into next.
...
Conflict in `cpp/ql/test/library-tests/sideEffects/functions/sideEffects.expected`,
resolved by accepting test output (combining changes).
2018-12-12 17:26:18 +00:00
Aditya Sharad
41a48078f7
Merge pull request #673 from calumgrant/cs/sync-files
...
C#: Sync samples and qltest cases
2018-12-12 17:10:00 +00:00
calumgrant
8e546a30b0
Merge pull request #637 from hvitved/csharp/cfg/throwing-callable
...
C#: Fix a bug in `ThrowingCallable`
2018-12-12 16:58:28 +00:00
calum
2bbd55519b
C#: Add tests for C# 7.3 features.
2018-12-12 16:44:55 +00:00
Tom Hvitved
74167e478a
C#: Cache `NamedElement::getLabel()`
2018-12-12 13:16:28 +01:00
Tom Hvitved
6918dad1db
C#: Refactor `localFlowStep()`
...
Using the `forceCachingInSameStage()` trick, we can get rid of the non-cached version
of local flow, while still computing it in the same stage.
2018-12-12 13:14:22 +01:00
Tom Hvitved
1366638f06
C#: Fix whitespaces
2018-12-12 13:13:13 +01:00
calum
3037b2b197
C#: Sync the -Good and -Bad files in the qltest to match the sample.
2018-12-12 11:36:00 +00:00
calum
1df1b0c28e
C#: Refactor ArrayCreations to allow stackalloc arrays to have initializers (C# 7.3).
2018-12-12 11:05:34 +00:00
Tom Hvitved
7422947e78
C#: Improve performance of `cs/useless-upcast`
2018-12-11 17:48:04 +01:00
Tom Hvitved
e80837681f
C#: Refactor LINQ logic
...
Factor `ClauseCall` out into three classes to make it clear when the fields
`operand` and `declaration` can be `null`.
2018-12-11 16:04:25 +01:00
Aditya Sharad
dde42a5723
Merge rc/1.19 into next.
2018-12-11 14:38:58 +00:00
calum
8d072863df
C#: Reorder for statements to ensure variables declared in the condition are declared before they are used.
2018-12-11 10:31:45 +00:00
Tom Hvitved
1e9fe0046a
C#: Address review comments
2018-12-10 15:31:23 +01:00
calumgrant
67d4099e3f
Merge pull request #593 from hvitved/csharp/nullness
...
C#: Rewrite nullness queries
2018-12-07 15:57:27 +00:00
Tom Hvitved
6411d1c7dd
C#: Refactor operator call logic
...
Refactored to make it clear when `@operator.Symbol as IMethodSymbol` can be `null`.
2018-12-07 15:47:20 +01:00
Tom Hvitved
e05bbb0f10
C#: Fix always-`null` bug in TRAP writer
2018-12-07 15:46:27 +01:00
Tom Hvitved
664453707a
C#: Speedup `Assertions::strictlyDominates()` and `ControlFlowElement::controlsBlock()`
...
Only calculate dominance by explicit recursion for split nodes; all other nodes
can use regular CFG dominance.
2018-12-07 12:03:12 +01:00
Tom Hvitved
c887dc89dc
C#: Fix a bug in `ThrowingCallable`
...
A method such as
```
void M()
{
throw new Exception();
}
```
was incorrectly not categorized as a `ThrowingCallable`, that is, a callable
that always throws an exception upon invocation.
2018-12-07 10:56:11 +01:00
Tom Hvitved
243af36167
C#: Add more CFG tests with throwing methods
2018-12-07 10:43:45 +01:00
Tom Hvitved
fce805834e
C#: Address review comments
2018-12-07 09:40:49 +01:00
calum
919d7cbf01
C#: Fix [INVALID_KEY] errors.
2018-12-05 13:55:55 +00:00
Tom Hvitved
ad77afef04
C#: Autobuilder fixes
...
This commit fixes a few issues that were identified during the last dist upgrade,
and which were introduced/revealed on 836daaf07b
.
- Expand environment variables that are passed from `lgtm.yml` to the autobuilder,
for example `solution: $LGTM_SRC/mysolution.sln`.
- Distinguish between when a build rule is applied automatically and when it is applied
manually via `lgtm.yml`.
- Catch `FileNotFoundException`s when parsing project files and solution files.
2018-12-04 14:03:39 +01:00
Tom Hvitved
4739a6334e
C#: Fix a bug and generalize guards implication logic
2018-12-03 15:33:00 +01:00
calumgrant
43d14ce011
Merge pull request #586 from hvitved/csharp/cfg/field-split
...
C#: Handle multiple-field Boolean CFG splitting
2018-12-03 12:52:43 +00:00
Tom Hvitved
3b0d1599ad
C#: Teach guards library about unique assignments
...
For example, in
```
void M(object x)
{
var y = x == null ? 1 : 2;
if (y == 2)
x.ToString();
}
```
the guard `y == 2` implies that the guard `x == null` must be false,
as the assignment of `2` to `y` is unique.
2018-11-30 17:43:10 +01:00
Tom Hvitved
ab9aa7d338
C#: Teach guards library about conditional assignments
...
For example, in
```
void M(object x)
{
var y = x != null ? "" : null;
if (y != null)
x.ToString();
}
```
the guard `y != null` implies that the guard `x != null` must be true.
2018-11-30 17:41:36 +01:00
Tom Hvitved
80144a00c8
C#: Update nullness analyses
...
Port the SSA-based logic from the Java nullness analyses.
2018-11-30 17:41:31 +01:00
Tom Hvitved
d2a431e6f3
C#: Add more nullness tests
...
Port many of the nullness test from Java, as well as add new tests.
2018-11-30 17:02:05 +01:00
calumgrant
1c2dd3e7b9
Merge pull request #570 from hvitved/csharp/ssa/split-to-string
...
C#: Include CFG splits in `Ssa::Definition::toString()`
2018-11-30 15:04:36 +00:00
calumgrant
08f5c2b6a6
Merge pull request #567 from hvitved/csharp/guards-splitting
...
C#: Account for split SSA definitions in guards library
2018-11-30 14:57:57 +00:00
calumgrant
ca72c8ebfe
Merge pull request #579 from hvitved/csharp/guards-loop
...
C#: Fix bug in guards library when the guarded expression is in a loop
2018-11-30 10:27:21 +00:00
Tom Hvitved
05b9519e9a
C#: Handle multiple-field Boolean CFG splitting
...
The internal pre-SSA library was extended on 3e78c2671f
to include fields/properties that are local-scope-like. The CFG splitting logic
uses ranking of SSA definitions to define an (arbitrary) order of splits, but for
fields/properties the implicit entry definition all have the same line and column.
In effect, such SSA definitions incorrectly get the same rank. Adding the name
of the field/property to the lexicographic ordering resolves the issue.
2018-11-30 10:57:34 +01:00
Tom Hvitved
610be85c8c
C#: Add CFG test for multiple-field Boolean splitting
2018-11-30 10:32:08 +01:00
Jonas Jensen
9babb4366b
Merge remote-tracking branch 'upstream/master' into mergeback-20181130
2018-11-30 10:13:33 +01:00
Tom Hvitved
8bd8975795
Merge pull request #568 from calumgrant/cs/index-out-of-bounds
...
C#: Fix false-positives in cs/index-out-of-bounds
2018-11-29 18:40:05 +01:00
Tom Hvitved
a12a72e90f
C#: Fix bug in guards library when the guarded expression is in a loop
...
Follow-up on 03e69e9945
.
2018-11-29 15:53:03 +01:00