Compare commits

..

955 Commits

Author SHA1 Message Date
Esben Sparre Andreasen
ee314a4dad remove javascript 2021-09-29 11:19:08 +02:00
Mathias Vorreiter Pedersen
8dcf7926de Merge pull request #6760 from andersfugmann/relax_memberMayBeVarSize
Increase precision to high for cpp/static-buffer-overflow
2021-09-29 10:09:11 +02:00
Benjamin Muskalla
d09c3bf863 Merge pull request #6748 from bmuskalla/fixHiddenTypesTestGenerator
Java: Avoid stubbing methods with private parameter types
2021-09-29 09:27:13 +02:00
Anders Schack-Mulligen
1a92fa5d92 Merge pull request #6772 from github/workflow/coverage/update
Update CSV framework coverage reports
2021-09-29 09:25:19 +02:00
github-actions[bot]
8d2ad4ed17 Add changed framework coverage reports 2021-09-29 00:08:05 +00:00
Benjamin Muskalla
5f659f6e48 Merge branch 'main' into fixHiddenTypesTestGenerator 2021-09-28 17:42:39 +02:00
Shati Patel
ee46717c76 Merge pull request #6771 from shati-patel/mergeback-3.2-main
Merge 3.2 into main
2021-09-28 14:52:17 +01:00
Jonas Jensen
914e621d1b Merge pull request #6678 from andersfugmann/refactor_use_of_isGuardPhi
C++: Refactor code to use predicate isGuardPhi/4
2021-09-28 15:45:05 +02:00
Shati Patel
976190e84d Merge pull request #6764 from shati-patel/slides-links
Docs: Fix a few links in the training slides
2021-09-28 14:35:46 +01:00
Mathias Vorreiter Pedersen
06eb93da3f Merge pull request #6769 from github/docfix-dead-links-in-readme
Fix dead links in README.md
2021-09-28 15:21:19 +02:00
Mathias Vorreiter Pedersen
7197f41e75 Fix dead links in README.md 2021-09-28 15:12:36 +02:00
Edoardo Pirovano
5488872044 Merge pull request #6505 from edoardopirovano/trailing-comma
QL Language Spec: Trailing comma in set literal
2021-09-28 13:45:09 +01:00
Chris Smowton
413ac4e8f4 Merge pull request #6684 from owen-mc/java/model/apache-collections-subpackages
Java: model remaining subpackages of Apache Commons Collections
2021-09-28 12:28:48 +01:00
Tony Torralba
cec6cd0830 Merge pull request #6724 from atorralba/atorralba/android-contentprovider-sources
Java: Add sources for content providers in Android
2021-09-28 12:13:54 +02:00
Chris Smowton
39a12a8464 Remove models that are no longer required 2021-09-28 10:48:43 +01:00
Tony Torralba
46eb27cd01 Don't restrict inputs to be ParameterNodes
Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com>
2021-09-28 11:21:56 +02:00
Anders Fugmann
ba98c0c1cb Merge remote-tracking branch 'upstream/main' into relax_memberMayBeVarSize 2021-09-28 11:15:11 +02:00
Anders Schack-Mulligen
fc8b439263 Merge pull request #6740 from aschackmull/java/callback-dispatch
Java: Add callback dispatch to more anonymous classes.
2021-09-28 10:49:27 +02:00
Anders Peter Fugmann
a358ea8667 C++: Apply documentation change suggestion
Co-authored-by: Jonas Jensen <jbj@github.com>
2021-09-28 10:38:02 +02:00
Anders Schack-Mulligen
c294b75f6c Merge pull request #6766 from github/workflow/coverage/update
Update CSV framework coverage reports
2021-09-28 10:35:43 +02:00
Shati Patel
d5e17f9ebf Merge pull request #6765 from shati-patel/docs-config-fixes
Docs: Fix inconsistencies in sphinx config files
2021-09-28 09:18:02 +01:00
Anders Peter Fugmann
c7ea7ca5cd C++: Apply documentation change suggestion
Co-authored-by: Jonas Jensen <jbj@github.com>
2021-09-28 09:40:25 +02:00
Anders Peter Fugmann
49c656d904 C++: Apply documentation change suggestion
Co-authored-by: Jonas Jensen <jbj@github.com>
2021-09-28 09:40:07 +02:00
Anders Fugmann
79549c2285 Merge remote-tracking branch 'upstream/main' into refactor_use_of_isGuardPhi 2021-09-28 09:38:16 +02:00
Owen Mansel-Chan
787f36f056 Add a change note 2021-09-28 07:32:28 +01:00
github-actions[bot]
b7b229d59b Add changed framework coverage reports 2021-09-28 00:08:59 +00:00
shati-patel
64fcbe05c3 Docs: Fix inconsistencies in sphinx config files 2021-09-27 18:54:23 +01:00
shati-patel
31c34870ef Fix warning about "Anonymous hyperlink mismatch" 2021-09-27 18:27:57 +01:00
shati-patel
3c17ac424d Docs: Fix some broken/redirected links 2021-09-27 18:27:30 +01:00
Felicity Chapman
bb6c079e5a Merge pull request #6762 from github/felicitymay-patch-1
Update links to match those on the staging site
2021-09-27 16:49:58 +01:00
Felicity Chapman
a3c1975a84 Update links to match those on the staging site 2021-09-27 16:35:22 +01:00
Owen Mansel-Chan
bdd78d2bc7 Fix stub 2021-09-27 16:24:41 +01:00
Owen Mansel-Chan
29db42c3cd Generate stubs 2021-09-27 16:24:40 +01:00
Owen Mansel-Chan
e6df8164cf Fix up old tests for new helper functions 2021-09-27 16:24:39 +01:00
Owen Mansel-Chan
cf03bd8bd1 Merge new and old tests
# Conflicts:
#	java/ql/test/library-tests/frameworks/apache-collections/TestNew.java
2021-09-27 16:24:38 +01:00
Owen Mansel-Chan
342c14887b Fix existing models for MapUtils 2021-09-27 16:24:37 +01:00
Owen Mansel-Chan
e1101e582e Minor improvement to existing tests 2021-09-27 16:24:37 +01:00
Owen Mansel-Chan
768203bd36 Remove redundant casts 2021-09-27 16:24:36 +01:00
Owen Mansel-Chan
c51fb00082 Add tests for non-public abstract classes 2021-09-27 16:24:35 +01:00
Owen Mansel-Chan
0a92b04c8b Fix up automatically generated tests 2021-09-27 16:24:34 +01:00
Owen Mansel-Chan
15161d8867 Make concrete subclasses of abstract classes 2021-09-27 16:24:33 +01:00
Owen Mansel-Chan
53ee465726 Fix errors in generated tests that stop compilation 2021-09-27 16:24:32 +01:00
Owen Mansel-Chan
a20acfee25 Add automatically generated tests
Also update test.ql to use the new InlineFlowTest.
2021-09-27 16:24:31 +01:00
Owen Mansel-Chan
f69787afd0 Miscellaneous model fixes 2021-09-27 16:24:30 +01:00
Owen Mansel-Chan
9b12980688 Do not model some protected methods 2021-09-27 16:24:29 +01:00
Owen Mansel-Chan
cb0f82c36e Do not modelled protected static inner classes 2021-09-27 16:24:29 +01:00
Owen Mansel-Chan
3b678bfbc5 Address review comments 2021-09-27 16:24:28 +01:00
Owen Mansel-Chan
e1750adc38 Address problems highlighted by generating tests 2021-09-27 16:24:27 +01:00
Owen Mansel-Chan
fd0fb9483e Model the remaining subpackages in Apache Commons Collections 2021-09-27 16:24:26 +01:00
Owen Mansel-Chan
3d1d491e6b Model java.lang.Object.clone() better for access paths.
Model value flow for Element, MapKey and MapValue. This assumes
that clone() is a shallow copy.
2021-09-27 16:24:25 +01:00
Edoardo Pirovano
18020707b8 QL Language Spec: Trailing comma in set literal 2021-09-27 15:57:39 +01:00
Anders Schack-Mulligen
cfa0d46b73 Merge pull request #6097 from atorralba/atorralba/promote-xslt-injection
Java: Promote XSLT Injection from experimental
2021-09-27 13:14:57 +02:00
Anders Schack-Mulligen
e027d514f1 Merge pull request #6037 from atorralba/atorralba/promote-spel-injection
Java: Promote SpEL Injection query from experimental
2021-09-27 13:13:35 +02:00
Tony Torralba
d5f675c2dc Fix unbound field
Add tests for non-exported providers
2021-09-27 12:58:28 +02:00
Tony Torralba
78c12dc505 Move to lib 2021-09-27 12:04:14 +02:00
Tony Torralba
ad08ccb50b Apply suggestion from code review 2021-09-27 12:00:21 +02:00
mc
95751fcc21 Update XsltInjection.qhelp
Made a few minor tweaks during editorial review
2021-09-27 12:00:21 +02:00
Tony Torralba
13417dbf14 Remove DataFlow references from XsltInjection.qll 2021-09-27 12:00:20 +02:00
Tony Torralba
ff21662b23 Refactor XsltInjection.qll 2021-09-27 12:00:18 +02:00
Tony Torralba
6967b06dee Decouple XsltInjection.qll to reuse the taint tracking configuration 2021-09-27 11:59:51 +02:00
Tony Torralba
fc58ada92e Add change note 2021-09-27 11:58:20 +02:00
Tony Torralba
108118afa3 Use InlineExpectationsTest 2021-09-27 11:58:18 +02:00
Tony Torralba
d8bb5273e7 Refactor to use CSV sink models 2021-09-27 11:57:58 +02:00
Tony Torralba
c792567904 Move from experimental 2021-09-27 11:57:53 +02:00
Tony Torralba
6d9a88d1c8 Move to lib 2021-09-27 11:43:46 +02:00
mc
3520fed752 Update SpelInjection.qhelp 2021-09-27 11:40:51 +02:00
Tony Torralba
d10dbbdd9d Apply suggestions from code review
Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>
2021-09-27 11:40:51 +02:00
Tony Torralba
6bf1e87bbe Remove CSV sinks; make imports private 2021-09-27 11:40:47 +02:00
Tony Torralba
91f46624b6 Refactor SpelInjection.qll 2021-09-27 11:40:26 +02:00
Tony Torralba
94f32d2985 Decouple SpelInjection.qll to reuse the taint tracking configuration 2021-09-27 11:39:30 +02:00
Tony Torralba
569426b04e Consider subtypes of Expression and ExpressionParser
Add parseRaw as additional taint step
2021-09-27 11:38:12 +02:00
Tony Torralba
b0852f6c16 Add change note 2021-09-27 11:37:46 +02:00
Tony Torralba
b985ddb868 Use InlineExpectationsTest 2021-09-27 11:37:41 +02:00
Tony Torralba
079769ed2e Refactored SpelInjection.qll to use CSV sink models 2021-09-27 11:36:56 +02:00
Tony Torralba
fc6af0476f Moved from experimental 2021-09-27 11:36:48 +02:00
Anders Fugmann
03bd7d7f96 C++: Update test results from OverflowStatic 2021-09-27 11:23:08 +02:00
Anders Schack-Mulligen
92ffd8c465 Merge pull request #6749 from aschackmull/java/istextblock
Java: Add StringLiteral.isTextBlock().
2021-09-27 10:54:31 +02:00
Jonas Jensen
b0836a620c Merge pull request #6757 from geoffw0/impropnulltest2
C++: Small improvement to cpp/improper-null-termination
2021-09-27 10:52:49 +02:00
Jonas Jensen
06b36f742e Merge pull request #6745 from andersfugmann/handle_overflow_for_upperbound
C++: Handle overflow for upperbound
2021-09-27 10:32:49 +02:00
James Fletcher
c977cfe40a Merge pull request #6754 from github/update-link
Update one more link in the QL training content
2021-09-27 08:33:42 +01:00
Anders Fugmann
e0921ac983 C++: Increase precision of cpp/static-buffer-overflow to high 2021-09-27 09:06:36 +02:00
Geoffrey White
7e7dfe2cc4 C++: Understand format arguments. 2021-09-24 19:25:43 +01:00
Geoffrey White
91a8b9fdd9 C++: Add suggested test (and a good variant). 2021-09-24 18:34:28 +01:00
Alexander Eyers-Taylor
8debae1a3b Merge pull request #6753 from github/aibaars/fix-typo
Fix typo in language spec
2021-09-24 17:21:14 +01:00
Rasmus Wriedt Larsen
547cbb6322 Merge pull request #6331 from porcupineyhairs/pythonXpath
Python : Improve Xpath Injection Query
2021-09-24 18:11:08 +02:00
james
1adc5c2a5b update links correctly 2021-09-24 17:00:59 +01:00
Rasmus Wriedt Larsen
d39df18544 Python: Minor test cleanup 2021-09-24 16:11:27 +02:00
james
e664711f47 make links to slide decks relative 2021-09-24 14:56:48 +01:00
Arthur Baars
7d3a219f63 Fix typo in language spec
Thanks to https://github.com/github/codeql/issues/6750
2021-09-24 15:47:09 +02:00
james
23e4ad1abb update one more link 2021-09-24 14:46:14 +01:00
Geoffrey White
3e1bc66984 Merge pull request #6733 from MathiasVP/fix-qldoc-in-initialize-dynamic-allocation-instruction
C++/C#: Fix QLDoc on `InitializeDynamicAllocationInstruction`.{`getAllocationAddressOperand` and `getAllocationAddress`}
2021-09-24 14:30:03 +01:00
Rasmus Wriedt Larsen
26d2fbd217 Python: Fix new XPath injection query
Fixes the typo `ETXpath` => `ETXPath`
2021-09-24 15:11:34 +02:00
Rasmus Wriedt Larsen
913a679ef5 Python: Replace old XPath injection query 2021-09-24 15:10:41 +02:00
Anders Peter Fugmann
aebde189f8 C++: Apply peer review suggestion
Co-authored-by: Jonas Jensen <jbj@github.com>
2021-09-24 15:09:23 +02:00
Anders Schack-Mulligen
66c206cc61 Merge pull request #6747 from bmuskalla/organizeUtils
Java: Organize `utils` into separate directories
2021-09-24 15:05:51 +02:00
Rasmus Wriedt Larsen
c9640ffdbc Python: Minor adjustments to XPath Injection 2021-09-24 15:02:39 +02:00
Mathias Vorreiter Pedersen
24214002a1 C#/C++: Sync identical files. 2021-09-24 13:13:09 +01:00
Mathias Vorreiter Pedersen
eba1b0bc15 Respond to review comments. 2021-09-24 13:12:58 +01:00
Rasmus Wriedt Larsen
289660067c Merge branch 'main' into pythonXpath 2021-09-24 13:53:38 +02:00
Anders Schack-Mulligen
854f2a046a Java: Add StringLiteral.isTextBlock(). 2021-09-24 13:11:18 +02:00
Mathias Vorreiter Pedersen
69541d3628 Merge pull request #6744 from rdmarsh2/rdmarsh2/dtt-subpath
C++: add subpaths to DefaultTaintTracking
2021-09-24 11:58:31 +01:00
Benjamin Muskalla
70e1724463 Exclude methods with non-public parameter types 2021-09-24 12:41:12 +02:00
Anders Fugmann
cbdabe35de C++: Update test results to reflect changes 2021-09-24 12:29:28 +02:00
Anders Fugmann
c9c41252e3 C++: Update test results in SimpleRangeAnalysis 2021-09-24 12:23:48 +02:00
Anders Fugmann
3437cf2909 C++: only use upperbound if there are no overflows in the guard 2021-09-24 11:46:58 +02:00
Anders Fugmann
d7afd86a27 C++: Add test case exposing problem with overflows for upperBound predicate 2021-09-24 11:44:05 +02:00
Benjamin Muskalla
38ca5aba98 Move test generator into subdirectory 2021-09-24 11:13:04 +02:00
Benjamin Muskalla
4e6a8d991e Move stub generator into subdirectory 2021-09-24 11:12:41 +02:00
Benjamin Muskalla
cb0a567c03 Merge pull request #6743 from github/workflow/coverage/update
Update CSV framework coverage reports
2021-09-24 09:23:35 +02:00
Anders Fugmann
032ac50034 C++: Do not warn on static buffer overflow using loop counters, if the loop counter has been widened 2021-09-24 08:31:36 +02:00
Anders Fugmann
3e5f7d0db5 C++: using buildin offsetof for an array member indexed after end is legal 2021-09-24 08:31:35 +02:00
Anders Fugmann
b08eabec68 C++: Relax predicate memberMayBeVarSize to mark all members of size 0 or 1 as variable sized 2021-09-24 08:31:35 +02:00
Anders Fugmann
a4a9e2aa96 C++: Weaken wording on overflow static alert text 2021-09-24 08:31:35 +02:00
Robert Marsh
3189c578a4 C++: Add QLDoc to subpaths in DefaultTaintTracking 2021-09-23 22:42:38 -07:00
Robert Marsh
c2b356ab08 C++: add subpaths to DefaultTaintTracking 2021-09-23 21:00:45 -07:00
github-actions[bot]
ceb9a0bd6b Add changed framework coverage reports 2021-09-24 00:08:02 +00:00
Anders Schack-Mulligen
a031b2a090 Merge pull request #6493 from atorralba/atorralba/cleartext-storage-query-refactor
Java: Refactor Cleartext Storage queries
2021-09-23 16:31:17 +02:00
Tony Torralba
b52a2cd292 Apply code review comments
Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com>
2021-09-23 15:48:15 +02:00
Anders Schack-Mulligen
6be4b3bac6 Merge pull request #6725 from emilejq/date-format
Java: Remove requirements for final and access mods from DateFormatThreadUnsafe
2021-09-23 15:02:17 +02:00
Anders Schack-Mulligen
4841c3037d Java: Add callback dispatch to more anonymous classes. 2021-09-23 14:34:56 +02:00
Rasmus Wriedt Larsen
f14e3f6007 Merge pull request #5445 from jorgectf/jorgectf/python/ldapinsecureauth
Python: Add LDAP Insecure Authentication query
2021-09-23 11:08:13 +02:00
Emile El-Qawas
83fb41e414 Add visibility constraints; Fix non-compliant code 2021-09-23 09:55:49 +01:00
Tony Torralba
d0b9920cac Fix encryption sanitizer
It now discards sensitive exprs (sources) instead of sinks for better precision
2021-09-23 10:42:30 +02:00
Tony Torralba
51d2b5225e Remove cached property from SensitiveSource::flowsTo 2021-09-23 10:42:30 +02:00
Tony Torralba
563e8a2bd6 Remove unused library 2021-09-23 10:42:30 +02:00
Tony Torralba
a30554e97c Refactored cleartext storage libraries 2021-09-23 10:42:30 +02:00
Rasmus Wriedt Larsen
ef6e502ff0 Python: Make LDAP global options test better
Before it didn't really showcase that we know it can make connections
secure.
2021-09-23 10:18:18 +02:00
Chris Smowton
93daaf5b5b Merge pull request #6174 from joefarebrother/guava-collections
Java: Model Guava collections package
2021-09-23 09:13:24 +01:00
Rasmus Wriedt Larsen
70489b2fc2 Merge branch 'main' into jorgectf/python/ldapinsecureauth 2021-09-23 10:05:56 +02:00
Tom Hvitved
27c45d8dda Merge pull request #6731 from hvitved/remove-reduced-env-var
Remove `CODEQL_REDUCE_FILES_FOLDERS_RELATIONS`
2021-09-23 09:39:17 +02:00
Chris Smowton
3123abfac3 Merge pull request #6711 from bananabr/AndroidLoggingFix
Fix Android logging signature
2021-09-22 17:23:04 +01:00
Joe Farebrother
522c6e01d2 Sort models by class and name 2021-09-22 15:23:01 +01:00
yoff
14a31a2299 Merge pull request #6732 from RasmusWL/minor-sqlalchemy-comment-fixes 2021-09-22 15:15:52 +02:00
Mathias Vorreiter Pedersen
35baff8bac C#/C++: Sync identical files. 2021-09-22 13:32:29 +01:00
Mathias Vorreiter Pedersen
5969c227ab C++: Fix QLDoc on 'getAllocationAddressOperand' and 'getAllocationAddress'. 2021-09-22 13:32:20 +01:00
Rasmus Wriedt Larsen
8badba26b8 Python: Minor SQLALchemy comment fixes 2021-09-22 13:58:29 +02:00
Chris Smowton
24e3ad4e18 Remove unnecessary type constraint 2021-09-22 10:54:24 +01:00
Mathias Vorreiter Pedersen
a66f83644b Merge pull request #6728 from rdmarsh2/rdmarsh/sql-models-followup
C++: Add additional functions to the SQL models
2021-09-22 10:19:51 +01:00
Tom Hvitved
364dab6990 Remove CODEQL_REDUCE_FILES_FOLDERS_RELATIONS 2021-09-22 09:43:56 +02:00
Edoardo Pirovano
b960857fc2 Merge pull request #6722 from edoardopirovano/update-analyze-docs
Update documentation to reflect changes to `database analyze`
2021-09-22 08:29:45 +01:00
yoff
65d3373ad3 Merge pull request #6727 from RasmusWL/fix-sqlalchemy-query
Python: Merge SQLAlchemy TextClause injection into `py/sql-injection`
2021-09-22 09:29:28 +02:00
Robert Marsh
3108817717 C++: Add additional functions to the SQL models 2021-09-21 17:34:01 -07:00
Rasmus Wriedt Larsen
d44f279339 Python: Fix .qhelp 2021-09-21 20:35:03 +02:00
Rasmus Wriedt Larsen
a83bb39d0f Python: Merge SQLAlchemy TextClause injection into py/sql-injection
As discussed in a meeting today, this will end up presenting an query
suite that's easier to use for customers.

Since https://github.com/github/codeql/pull/6589 has JUST been merged,
if we get this change in fast enough, no end-user will ever have run
`py/sqlalchemy-textclause-injection` as part of LGTM.com or Code
Scanning.
2021-09-21 20:21:42 +02:00
Robert Marsh
d62f76afa6 Merge pull request #6133 from MathiasVP/promote-sql-pqxx
C++: Promote `cpp/sql-injection-via-pqxx` out of experimental
2021-09-21 10:13:57 -07:00
Robert Marsh
97c2917c16 Merge pull request #6409 from JordyZomer/main
cpp: Add query to detect unsigned integer to signed integer conversio…
2021-09-21 09:57:44 -07:00
Joe Farebrother
3cd675bfff Manually fill in most of the remaining support method calls 2021-09-21 17:56:18 +01:00
Mathias Vorreiter Pedersen
478093aa89 Update cpp/ql/lib/semmle/code/cpp/models/interfaces/Sql.qll
Co-authored-by: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
2021-09-21 17:51:24 +01:00
Emile El-Qawas
dcae1c5c04 DateFormatThreadUnsafe - Remove requirements for final and access modifiers 2021-09-21 16:50:48 +01:00
Joe Farebrother
6e9bee1be7 Add missing models 2021-09-21 16:32:49 +01:00
Joe Farebrother
25d6e00b1a Implement gen methods for MapDifference 2021-09-21 16:30:12 +01:00
Joe Farebrother
a47897bdf9 Implement Table gen methods 2021-09-21 15:29:06 +01:00
Anders Schack-Mulligen
2c41de6648 Merge pull request #6720 from aschackmull/java/isunreachableincall-joinorder
Java: Fix join-order in isUnreachableInCall.
2021-09-21 16:07:42 +02:00
Anders Schack-Mulligen
dd1bed02e8 Merge pull request #6721 from aschackmull/dataflow/subpaths01-joinorder
Dataflow: Fix join-order in subpaths01
2021-09-21 16:05:41 +02:00
Mathias Vorreiter Pedersen
bd5edc7ae5 Respond to review comments. 2021-09-21 14:29:26 +01:00
Mathias Vorreiter Pedersen
dfe932d053 Add missing conjunct in PostgreSqlEscapeFunction's 'escapesSqlArgument' predicate. 2021-09-21 12:14:45 +01:00
Tony Torralba
99881db8bd Add stubs 2021-09-21 12:10:05 +02:00
Tony Torralba
0c1f3ed0b3 Add tests for ContentProvider sources 2021-09-21 12:09:47 +02:00
Tony Torralba
a811ab3aff Add ContentProvider sources 2021-09-21 12:09:28 +02:00
Edoardo Pirovano
5a28a796af Update documentation to reflect changes to database analyze 2021-09-21 10:16:12 +01:00
yoff
4adb0c75bd Merge pull request #6589 from RasmusWL/promote-sqlalchemy
Python: Promote modeling of SQLAlchemy
2021-09-21 11:08:41 +02:00
Rasmus Wriedt Larsen
4a16be2cba Merge pull request #6557 from yoff/python/port-modification-of-default-value
Python: port modification of default value
2021-09-21 10:12:12 +02:00
Rasmus Wriedt Larsen
f8e6ba633a Python: Fix .expected for new subpaths query predicate 2021-09-21 09:40:13 +02:00
Rasmus Wriedt Larsen
c7c8e2f3e3 Merge branch 'main' into promote-sqlalchemy 2021-09-21 09:36:07 +02:00
Anders Schack-Mulligen
eaf05305ff Merge pull request #6709 from aschackmull/java/local-taint-collections
Java: Add container flow to the local taint flow relation.
2021-09-20 16:04:45 +02:00
Anders Schack-Mulligen
044623a360 Dataflow: Sync. 2021-09-20 14:58:28 +02:00
Anders Schack-Mulligen
07c05528ef Dataflow: Fix join-order in subpaths01. 2021-09-20 14:58:12 +02:00
Anders Schack-Mulligen
c72e385a47 Java: Fix join-order in isUnreachableInCall. 2021-09-20 14:09:09 +02:00
Mathias Vorreiter Pedersen
797966fd3d C++: Change the names of the new classes and predicates to match the upcoming 'CommandExecutionFunction' class. 2021-09-20 11:49:09 +01:00
Tom Hvitved
82d463e86e Merge pull request #6718 from hvitved/csharp/xss-subpath
C#: Add `subpaths` predicate to XSS queries
2021-09-20 12:47:27 +02:00
Rasmus Wriedt Larsen
97c0f1c7b7 Python: Apply suggestions from code review
Co-authored-by: yoff <lerchedahl@gmail.com>
2021-09-20 12:04:46 +02:00
Tom Hvitved
64507ab316 Merge pull request #6712 from hvitved/csharp/subsumption-perf-take2
C#: Speedup type subsumption calculation
2021-09-20 11:59:24 +02:00
Tom Hvitved
b9c4abe7dc C#: Fix qldoc typos 2021-09-20 10:42:01 +02:00
Tom Hvitved
6d315a5d16 C#: Add subpaths predicate to XSS queries 2021-09-20 10:40:54 +02:00
Anders Schack-Mulligen
187b7e117c Merge pull request #6715 from github/workflow/coverage/update
Update CSV framework coverage reports
2021-09-20 10:19:16 +02:00
github-actions[bot]
f0e7be7d56 Add changed framework coverage reports 2021-09-20 00:08:08 +00:00
Tom Hvitved
c6c1ad1b90 C#: Update toString for nested types 2021-09-18 19:51:37 +02:00
Tom Hvitved
07fe29cc67 C#: Speedup type subsumption calculation 2021-09-18 19:51:37 +02:00
Joe Farebrother
4929c66e60 Implement gen methods for collections and maps 2021-09-17 17:37:46 +01:00
Joe Farebrother
3ef09da1df Add models for more of methods; update stubs 2021-09-17 16:57:49 +01:00
Daniel Santos
9e41f43ee2 Fix: android.util.Log is final. No inheritance handling is needed. 2021-09-17 10:15:48 -05:00
Anders Schack-Mulligen
2cbad4aed6 Merge pull request #6600 from atorralba/atorralba/fix-conditionalbypass
Java: Fix performance of the query User-controlled bypass of sensitive method
2021-09-17 16:07:39 +02:00
Tamás Vajk
3247794e2f Merge pull request #6196 from tamasvajk/feature/sql-sinks
C#: Migrate SQL sinks to CSV format
2021-09-17 14:36:57 +02:00
Joe Farebrother
e946f49b64 [Test gen] Gen methods for Set and Iterator 2021-09-17 11:22:50 +01:00
Joe Farebrother
0bff1b4afb Implement get methods 2021-09-17 11:08:09 +01:00
Tamas Vajk
8232698254 C#: Migrate SQL sinks to CSV format 2021-09-17 10:21:31 +02:00
Tamás Vajk
6a78aa7840 Merge pull request #6461 from tamasvajk/feature/service-stack
C#: Add ServiceStack support
2021-09-17 10:16:20 +02:00
Felicity Chapman
7383988988 Merge pull request #6701 from github/docs-4908-training-note-links
Update links in training notes to use CodeQL microsite
2021-09-17 09:00:36 +01:00
james
e906ded0d1 remove java class 2021-09-17 08:48:26 +01:00
Daniel Santos
032a7e71fe Update Logging.qll
Simplified using a set-literal as suggested by @intrigus-lgtm
2021-09-16 13:03:26 -05:00
Ethan Palm
b73a2f7d56 Merge pull request #6667 from ethanpalm/indirect-build-tracing-docs
Add indirect build tracing docs
2021-09-16 12:36:56 -04:00
Ethan P
4d7aa5c945 Update example note 2021-09-16 09:29:35 -07:00
Daniel Santos
af8b2b6d9c Fix Android logging signature in java/ql/src/experimental/semmle/code/java/Logging.qll 2021-09-16 11:24:06 -05:00
james
c36292bfd0 a few more links 2021-09-16 17:03:29 +01:00
Anders Schack-Mulligen
a67db45454 Merge pull request #6612 from Marcono1234/marcono1234/literal-getLiteral-usage
Java: Replace incorrect usage of `Literal.getLiteral()`
2021-09-16 17:00:32 +02:00
Joe Farebrother
1111afc031 Update tests for new support methods; fix bad model 2021-09-16 15:23:03 +01:00
Joe Farebrother
54dbd7c0bd [Test gen] Add more support method implementations 2021-09-16 15:23:03 +01:00
Joe Farebrother
ef5bf87672 [Test gen] Distinguish default support methods 2021-09-16 15:23:03 +01:00
Joe Farebrother
eb45e67784 Generate tests for modified models 2021-09-16 15:23:02 +01:00
Joe Farebrother
1eacbd88b8 Fix up some incorrect models; simplify/remove some redundand ones 2021-09-16 15:23:02 +01:00
Joe Farebrother
a89bd32eb0 Factor out content manipulating methods from tests to a separate file 2021-09-16 15:23:02 +01:00
Joe Farebrother
56a2dc632b Move tests around and remove files used for generating tests 2021-09-16 15:23:02 +01:00
Joe Farebrother
7dded52de2 Add change note 2021-09-16 15:23:02 +01:00
Joe Farebrother
8425a94729 Mark failing tests as missing
I'm not sure why these tests don't work.
2021-09-16 15:23:02 +01:00
Joe Farebrother
7bf55fbc49 Update stubs to not include package protected members 2021-09-16 15:23:02 +01:00
Joe Farebrother
39349f3763 Fix failing test 2021-09-16 15:23:02 +01:00
Joe Farebrother
60c6158152 Fill in implementations of getters for synthetic fields 2021-09-16 15:23:01 +01:00
Joe Farebrother
225e70a8d0 Fill in implementations fo getMapKey/Value 2021-09-16 15:23:01 +01:00
Joe Farebrother
338a6f2114 Fill in implementations for getElement 2021-09-16 15:23:01 +01:00
Joe Farebrother
cd7c7c3152 Implement array getters/constructors in generated tests 2021-09-16 15:23:01 +01:00
Joe Farebrother
84748cda76 Increase field flow branch limit.
I'm a little concerned that this appears to be necassary for tests; as it may mean that results involving these flow steps may not be found in real-world projects.
2021-09-16 15:23:01 +01:00
Joe Farebrother
f94a61cc8a Remove unneeded rows 2021-09-16 15:23:01 +01:00
Joe Farebrother
b51ffadd27 Improve generated tests 2021-09-16 15:23:01 +01:00
Joe Farebrother
0f2c50f1f5 Explicitly add the of and copyOf methods for ImmutableSorted variants of certain types. 2021-09-16 15:23:01 +01:00
Joe Farebrother
c8e2b027ee Add fieldFlowBranchLimit to the tests 2021-09-16 15:23:00 +01:00
Joe Farebrother
839c9e35c8 Simplify synthetic table fields 2021-09-16 15:23:00 +01:00
Joe Farebrother
46eec3c8eb Switch to simpler synthetic field model 2021-09-16 15:23:00 +01:00
Joe Farebrother
6ae11b5b2c Generate stubs.
Some generated stubs were manually adjusted due to minor issues in the stub generator.
In particular, ambiguous references were resolved and references to private classes were removed.
2021-09-16 15:23:00 +01:00
Joe Farebrother
ff733e0334 Fix up issues in generated tests 2021-09-16 15:23:00 +01:00
Joe Farebrother
693d729ec6 Generate tests and fix broken specs 2021-09-16 15:23:00 +01:00
Joe Farebrother
2150c1d58e Remove <> from flow summaries 2021-09-16 15:23:00 +01:00
Joe Farebrother
1273b063f4 Fix test expectations 2021-09-16 15:23:00 +01:00
Joe Farebrother
a755633405 Add the remaining utility classes 2021-09-16 15:22:59 +01:00
Joe Farebrother
19579f0d9a Add more utility class models and reorder existing ones 2021-09-16 15:22:59 +01:00
Joe Farebrother
ca583bffd5 Add Lists and Collections2 utilites 2021-09-16 15:22:59 +01:00
Joe Farebrother
5fee6d2d19 Convert Sets utilities 2021-09-16 15:22:59 +01:00
Joe Farebrother
10f0f3038c Add tables, improve tests, make fixes 2021-09-16 15:22:59 +01:00
Joe Farebrother
73aba09eee Add create methods 2021-09-16 15:22:59 +01:00
Joe Farebrother
035d655e72 Update guava collection flow steps to CSV 2021-09-16 15:22:59 +01:00
Marcono1234
020aa4d94c Java: Address feedback and fix test failures 2021-09-16 14:10:48 +01:00
Marcono1234
58d2d5d14e Java: Replace incorrect usage of Literal.getLiteral() 2021-09-16 14:10:48 +01:00
Tom Hvitved
1c1c46591e Merge pull request #6708 from hvitved/python/files-folders-drop-columns
Python: Drop redundant columns from `files` and `folders` relations
2021-09-16 14:42:15 +02:00
Tom Hvitved
9f10018d48 Address review comment 2021-09-16 13:11:03 +02:00
Taus
783233dfe4 Merge pull request #6696 from yoff/python/copy-multiples-performance-fix-from-ruby
Python: Copy performance fix for `multiples` from ruby
2021-09-16 13:01:07 +02:00
Tony Torralba
f18c163408 Improve handling of the 'author' word as an exception 2021-09-16 11:57:28 +02:00
Tony Torralba
8022530f34 Merge pull request #5983 from atorralba/atorralba/promote-insecure-basic-auth
Java: Promote Insecure Basic Authentication query from experimental
2021-09-16 11:45:30 +02:00
Anders Schack-Mulligen
28e5dcef52 Java: Add container flow to the local taint flow relation. 2021-09-16 11:14:30 +02:00
Tom Hvitved
37ec83a68b Python: Upgrade script 2021-09-16 10:51:27 +02:00
Tom Hvitved
94b5c4eada Python: Drop redundant columns from files and folders relations 2021-09-16 10:51:27 +02:00
Benjamin Muskalla
d3caa80274 Merge pull request #6706 from github/workflow/coverage/update
Update CSV framework coverage reports
2021-09-16 09:58:19 +02:00
Tamas Vajk
f015cea590 Merge branch 'main' into feature/service-stack 2021-09-16 09:42:42 +02:00
Tamas Vajk
05dd3fa0e7 Adjust review findings 2021-09-16 09:42:38 +02:00
Erik Krogh Kristensen
0198cf6318 Merge pull request #6704 from erik-krogh/fix-upgrade
JS: fix dbsheme upgrade from TypeScript 4.4 PR
2021-09-16 08:34:58 +02:00
Anders Schack-Mulligen
236ffc8972 Merge pull request #6700 from aschackmull/dataflow/subpaths-joinorder
Dataflow: Fix bad joinorder in subpaths
2021-09-16 08:22:59 +02:00
github-actions[bot]
563878d28d Add changed framework coverage reports 2021-09-16 00:08:03 +00:00
Erik Krogh Kristensen
5c73fed83a fix dbsheme upgrade from TypeScript 4.4 PR 2021-09-15 22:38:27 +02:00
Ethan P
080867a390 Add reviewer feedback 2021-09-15 11:19:41 -07:00
Nick Rolfe
f76ce8b33b Merge pull request #6686 from hvitved/cpp/files-folders-drop-columns
C++: Drop redundant columns from `files` and `folders` relations
2021-09-15 18:33:20 +01:00
Mathias Vorreiter Pedersen
33ef634ea8 Merge pull request #6679 from andersfugmann/relax_memberMayBeVarSize
Improve precision on OverflowStatic query.
2021-09-15 17:24:10 +01:00
Felicity Chapman
05d83e487d Update all links to CodeQL microsite 2021-09-15 17:08:55 +01:00
Tony Torralba
21079a1315 Fix conditionControlsMethod predicate
Exceptions for throw and return statements were missing the appropriate condition
2021-09-15 17:51:51 +02:00
Tony Torralba
d3cf697b07 QLDoc 2021-09-15 17:32:36 +02:00
Tony Torralba
5ed9949498 Adapt InsecureBasicAuth to the previous commit 2021-09-15 17:20:28 +02:00
Tony Torralba
2e08c5dd2b Refactored HttpsUrls.ql 2021-09-15 17:20:28 +02:00
Tony Torralba
c3c73377b8 Fix scope issues in the Java example 2021-09-15 17:20:28 +02:00
Tony Torralba
023264660b Suggestions from code review 2021-09-15 17:20:28 +02:00
mc
0e7cbbfeb8 Update InsecureBasicAuth.qhelp 2021-09-15 17:20:28 +02:00
mc
e58b90ef1c Added full stops 2021-09-15 17:20:28 +02:00
Tony Torralba
e159351179 Update java/change-notes/2021-06-01-insecure-basic-auth-query.md
Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com>
2021-09-15 17:20:27 +02:00
Tony Torralba
30178d4f23 Decouple InsecureBasicAuth.qll to reuse the taint tracking configuration 2021-09-15 17:20:27 +02:00
Tony Torralba
90df3fa94c Remove CWE reference from qlhelp since it's obtained from metadata 2021-09-15 17:20:27 +02:00
Tony Torralba
49c6a56f97 Add change note 2021-09-15 17:20:27 +02:00
Tony Torralba
148443fae1 Use InlineExpectationsTest 2021-09-15 17:20:27 +02:00
Tony Torralba
2cada386b4 Refactored into InsecureBasicAuth.qll 2021-09-15 17:20:27 +02:00
Tony Torralba
905be67aae Moved from experimental 2021-09-15 17:20:27 +02:00
Anders Schack-Mulligen
c0fd44c909 Dataflow: Sync. 2021-09-15 16:10:54 +02:00
Anders Schack-Mulligen
3abe1b4fc6 Dataflow: Fix bad join-order. 2021-09-15 16:10:30 +02:00
Geoffrey White
c4714b55a3 Merge pull request #6588 from ihsinme/ihsinme-patch-069
CPP: Add query for CWE-675: Duplicate Operations on Resource
2021-09-15 15:10:03 +01:00
Jonas Jensen
65f4ec403f Merge pull request #6593 from geoffw0/samate-move
C++: Add test cases with SAMATE Juliet code snippets to the codeql test suite.
2021-09-15 14:18:08 +02:00
Mathias Vorreiter Pedersen
947ab8a14d Make the QLDoc on 'getAnSqlParameter' more clear. 2021-09-15 13:15:05 +01:00
Erik Krogh Kristensen
3f736d3eb8 Merge pull request #6694 from erik-krogh/owasp-fixes
JS/Java: use the correct cwe tags
2021-09-15 13:46:35 +02:00
CodeQL CI
b228398b87 Merge pull request #6587 from erik-krogh/ts44
Approved by asgerf
2021-09-15 04:00:13 -07:00
Rasmus Lerchedahl Petersen
8ea7a28a77 Python: Unexpose fields as suggested. 2021-09-15 12:32:21 +02:00
yoff
758b6bd4dd Update python/ql/src/semmle/python/functions/ModificationOfParameterWithDefaultCustomizations.qll
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-09-15 12:25:27 +02:00
Geoffrey White
0e7afb24cf Merge pull request #6643 from MathiasVP/add-frontend-and-extractor-diagnostic-query
C++: Add uninterpreted query for obtaining frontend and extraction time
2021-09-15 11:17:58 +01:00
Geoffrey White
9ad51fbc02 C++: Fix the correct test this time. 2021-09-15 11:03:09 +01:00
Erik Krogh Kristensen
cf149bd8c8 add static_initializer as a stmt_parent 2021-09-15 11:54:30 +02:00
Chris Smowton
03db15af9a Merge pull request #6685 from smowton/smowton/admin/android-uri-model
Java: Add models for android.net.Uri[.Builder]
2021-09-15 10:48:33 +01:00
Erik Krogh Kristensen
0b83d033d7 add @static_initializer in the stats file 2021-09-15 11:33:05 +02:00
Jordy Zomer
0f6e845418 Merge branch 'main' of https://github.com/JordyZomer/codeql into main 2021-09-15 10:41:31 +02:00
Jordy Zomer
01a06d1f5c Add filter and format the query 2021-09-15 10:37:40 +02:00
Anders Fugmann
e49cd83868 C++: update change note per suggestion from peer review 2021-09-15 10:31:15 +02:00
Anders Schack-Mulligen
8485b6f0b3 Merge pull request #6691 from bmuskalla/moreStringMethods
Java: Support String#getChars and #translateEscapes
2021-09-15 10:14:54 +02:00
CodeQL CI
220f2ded85 Merge pull request #6698 from asgerf/js/template-self-assignment
Approved by esbena
2021-09-15 01:08:39 -07:00
Anders Schack-Mulligen
3f7d6e6f85 Merge pull request #6136 from smowton/smowton/admin/spring-xss-content-type-sensitivity
Spring HTTP: improve content-type sensitivity
2021-09-15 09:50:56 +02:00
Anders Schack-Mulligen
2a9e3da24f Merge pull request #6697 from github/workflow/coverage/update
Update CSV framework coverage reports
2021-09-15 09:35:09 +02:00
Asger Feldthaus
b5db4047a0 JS: Exclude template files in SelfAssignment 2021-09-15 08:59:47 +02:00
github-actions[bot]
baab70bea6 Add changed framework coverage reports 2021-09-15 00:07:57 +00:00
CodeQL CI
b25b19f71b Merge pull request #6584 from erik-krogh/clipBoard
Approved by esbena
2021-09-14 12:41:49 -07:00
Erik Krogh Kristensen
5a7785776c add upgrade script 2021-09-14 20:43:07 +02:00
Erik Krogh Kristensen
fdbf5f73b1 add JS support for static initializers 2021-09-14 20:40:46 +02:00
Erik Krogh Kristensen
cc0d86403e revert some type changes that are no longer needed 2021-09-14 20:40:46 +02:00
Erik Krogh Kristensen
48b763c7e9 add qldoc to StaticInitializer::getBody 2021-09-14 20:40:46 +02:00
Erik Krogh Kristensen
7ce87a7118 remove stray import 2021-09-14 20:40:46 +02:00
Erik Krogh Kristensen
c8c7a1f772 remove the body field from StaticInitializer and relax the valuye type on MemberDefinition 2021-09-14 20:40:45 +02:00
Erik Krogh Kristensen
e3ed6c2523 refactor StaticInitializer into it's own class 2021-09-14 20:40:45 +02:00
Erik Krogh Kristensen
23e28ae5d4 fix typo in comment
Co-authored-by: Asger F <asgerf@github.com>
2021-09-14 20:40:45 +02:00
Erik Krogh Kristensen
2a03a84315 remove TODO comment
Co-authored-by: Asger F <asgerf@github.com>
2021-09-14 20:40:45 +02:00
Erik Krogh Kristensen
68ab210dc8 update TypeScript version info in versions-compilers.rst 2021-09-14 20:40:45 +02:00
Erik Krogh Kristensen
ffd51e725f add getter for static initializer blocks 2021-09-14 20:40:45 +02:00
Erik Krogh Kristensen
9585481d0b add support for static initializer blocks in TypeScript 2021-09-14 20:40:45 +02:00
Erik Krogh Kristensen
59f15eb4eb add tests for TypeScript 4.4 types 2021-09-14 20:40:45 +02:00
Erik Krogh Kristensen
02a0eed8ee add basic support for TypeScript 4.4 2021-09-14 20:40:45 +02:00
Erik Krogh Kristensen
3b6c8c5191 Merge branch 'main' into clipBoard 2021-09-14 20:21:37 +02:00
CodeQL CI
136d04390d Merge pull request #6695 from erik-krogh/js-add-cwes
Approved by esbena
2021-09-14 11:19:35 -07:00
Geoffrey White
8fd848701e C++: Fix test failure. 2021-09-14 16:38:11 +01:00
Chris Smowton
e5b84fb795 Use InlineFlowTest 2021-09-14 16:37:07 +01:00
Chris Smowton
5d737934c3 Don't inherit models from a final class
Co-authored-by: Tony Torralba <atorralba@users.noreply.github.com>
2021-09-14 16:37:07 +01:00
Chris Smowton
367a53dd71 Add models for android.net.Uri[.Builder] 2021-09-14 16:37:07 +01:00
Chris Smowton
ca87768a93 Merge pull request #6692 from bmuskalla/testGeneratorFlowTest
Java: Test generator uses `InlineFlowTest`
2021-09-14 15:44:24 +01:00
Mathias Vorreiter Pedersen
44dca68463 Merge branch 'main' into promote-sql-pqxx 2021-09-14 15:29:37 +01:00
Chris Smowton
406466de9a Simplify specifiesContentType predicate 2021-09-14 15:24:46 +01:00
Mathias Vorreiter Pedersen
adbeba291b Merge pull request #6687 from MathiasVP/fix-fp-in-av-rule-114
C++: Exclude uninstantiated templates from AV Rule 114.
2021-09-14 15:24:18 +01:00
Chris Smowton
6cff0d0376 Merge pull request #6393 from luchua-bc/java/xss-jsf
Java: CWE-079 Query to detect XSS with JavaServer Faces (JSF)
2021-09-14 15:15:56 +01:00
Anders Fugmann
bc22e0d9aa C++: Update comments on memberMayBeVarSize 2021-09-14 16:04:39 +02:00
Tony Torralba
4e93330cb9 Improved tests
Note that a FN test case was added
2021-09-14 15:51:08 +02:00
Benjamin Muskalla
abd770a027 Avoid empty template in test generator 2021-09-14 15:32:12 +02:00
Chris Smowton
a1ad1ddc10 Deprecated and replace uses of old name ServletWriterSource 2021-09-14 14:21:29 +01:00
Rasmus Lerchedahl Petersen
d37c14880f Python: Copy performance fix 2021-09-14 15:15:50 +02:00
Erik Krogh Kristensen
b936a04826 add some fitting CWEs to existing queries 2021-09-14 14:59:24 +02:00
Ethan Palm
c62a21e04f Apply suggestions from code review
Co-authored-by: Felicity Chapman <felicitymay@github.com>
2021-09-14 08:55:46 -04:00
Erik Krogh Kristensen
6d12c4aab1 use the correct cwe tags 2021-09-14 14:42:23 +02:00
Anders Schack-Mulligen
26eafcb55a Merge pull request #6456 from smowton/smowton/admin/flexjson-unsafe-deserialization
Java: add unsafe-deserialization support for Flexjson
2021-09-14 14:33:22 +02:00
Tony Torralba
0640b41f00 Adjust tests 2021-09-14 13:44:53 +02:00
Rasmus Wriedt Larsen
8b7fad8595 Merge pull request #6283 from tausbn/python-fix-exceptstmt-gettype
Python: Fix `ExceptStmt::getType`
2021-09-14 13:40:33 +02:00
Rasmus Wriedt Larsen
49f5f1e2c2 Merge pull request #6336 from tausbn/python-make-annotated-assignment-a-definitionnode
Python: Two fixes regarding annotated assignments
2021-09-14 13:37:53 +02:00
Chris Smowton
6af5c5fc86 Add change note 2021-09-14 12:36:38 +01:00
Chris Smowton
26dbf058c8 Add reverse import from ExternalFlow.qll 2021-09-14 12:35:33 +01:00
Chris Smowton
fcc0f1d5a7 Expand test to exercise all sinks 2021-09-14 12:27:33 +01:00
Chris Smowton
e439b7d7f8 Remove resource-related sources
These access application-owned resources AFAICT
2021-09-14 12:24:27 +01:00
Tony Torralba
b740cf9664 Add change note 2021-09-14 13:16:47 +02:00
Tony Torralba
097927226b Improved heuristics to increase precision 2021-09-14 13:16:47 +02:00
Tony Torralba
f8d1e2ac11 Refactor tests to use InlineExpectationsTest 2021-09-14 13:16:45 +02:00
Tony Torralba
1f7990d6bb Refactor to use ConditionalBypassQuery.qll 2021-09-14 13:16:09 +02:00
Tony Torralba
a484e9fb06 Use RemoteFlowSource instead of UserInput 2021-09-14 13:16:09 +02:00
Tom Hvitved
b69033f4ff C++: Upgrade script 2021-09-14 13:14:04 +02:00
Tom Hvitved
6c32b92929 C++: Drop redundant columns from files and folders relations 2021-09-14 13:14:04 +02:00
Tom Hvitved
98a12cef26 Merge pull request #6690 from hvitved/js/files-folders-drop-columns
JavaScript: Drop redundant columns from `files` and `folders` relations
2021-09-14 13:13:37 +02:00
Chris Smowton
104873e8ee Autoformat 2021-09-14 12:07:59 +01:00
Chris Smowton
6811441459 Factor JSF source definitions 2021-09-14 12:07:48 +01:00
Chris Smowton
b7fc068cee Move JSFRenderer.qll to lib 2021-09-14 11:49:01 +01:00
Chris Smowton
023c533745 Combine Servlet and JSF vulnerable writer flow-tracking
JSP and Servlet already shared this logic; might as well add JSF into the same mechanism.
2021-09-14 11:48:34 +01:00
Chris Smowton
cb8096f636 Remove JSF XSS Example
Per previous commit, no need for a top-level JSF example
2021-09-14 11:47:37 +01:00
Chris Smowton
cca9ad06b4 Remove JSF example
I don't think we need this: there are lots of possible XSS vectors; we don't need to enumerate every one in the qhelp file.
2021-09-14 11:47:36 +01:00
Chris Smowton
76e4077b56 Delete unused classes 2021-09-14 11:47:35 +01:00
luchua-bc
24addd5c10 Query to detect XSS with JavaServer Faces (JSF) 2021-09-14 11:47:32 +01:00
Chris Smowton
e92b9cbe99 Improve getAProducesExpr documentation 2021-09-14 11:16:45 +01:00
Benjamin Muskalla
f9918cc63c Test generator uses InlineFlowTest 2021-09-14 11:58:56 +02:00
Anders Schack-Mulligen
e71173d953 Merge pull request #6591 from bmuskalla/inlineFlowTest
Java: Simplify setup for flow tests using `InlineExpectationsTest`
2021-09-14 10:31:29 +02:00
Tom Hvitved
57b5b2af2e JavaScript: DB upgrade script 2021-09-14 10:25:53 +02:00
Tom Hvitved
25e1da0150 JavaScript: Update expected test output 2021-09-14 10:25:42 +02:00
Tom Hvitved
63e28c57cd JavaScript: Drop redundant columns from files and folders relations 2021-09-14 10:25:37 +02:00
Benjamin Muskalla
199e015a06 Support missing String methods 2021-09-14 10:22:22 +02:00
jorgectf
b505662ef9 Fix global test and update .expected 2021-09-14 10:20:50 +02:00
Tamás Vajk
d52616b687 Merge pull request #6683 from tamasvajk/feature/csv-coverage-fix
Only leave CSV coverage updater job enabled on github/codeql
2021-09-14 10:13:28 +02:00
Anders Fugmann
3f5ab60fb4 C++: Add DEPRECATED to documentation block 2021-09-14 09:55:19 +02:00
Benjamin Muskalla
93f9097b02 Merge pull request #6689 from github/workflow/coverage/update
Update CSV framework coverage reports
2021-09-14 09:35:31 +02:00
jorgectf
2ccc6dc092 Merge branch 'main' into jorgectf/python/ldapinsecureauth 2021-09-14 09:32:19 +02:00
ihsinme
8fa3cefb8c Update DoubleRelease.ql 2021-09-14 10:31:20 +03:00
ihsinme
d150c9a6be Update DoubleRelease.ql 2021-09-14 08:51:13 +03:00
github-actions[bot]
bf7c26e681 Add changed framework coverage reports 2021-09-14 00:07:57 +00:00
Taus
4d24be04a1 Merge pull request #6688 from RasmusWL/small-fix
Python: Fix `globals() == locals()` FP
2021-09-13 21:50:13 +02:00
Erik Krogh Kristensen
b889674486 add change note 2021-09-13 20:45:35 +02:00
Erik Krogh Kristensen
8569d261f7 add test 2021-09-13 20:43:31 +02:00
Erik Krogh Kristensen
8e98dcefb1 add clipboard data as a RemoteFlowSource 2021-09-13 20:43:31 +02:00
Erik Krogh Kristensen
3983aceb48 recognize types of the form "HTML%Element" as dom values 2021-09-13 20:43:31 +02:00
Erik Krogh Kristensen
bac80bf686 delete ClipboardXss.ql experimental query 2021-09-13 20:43:31 +02:00
Rasmus Wriedt Larsen
f402475dd3 Python: Fix globals() == locals() FP 2021-09-13 20:03:11 +02:00
Rasmus Wriedt Larsen
69fe2a36e5 Python: Add globals() == locals() test 2021-09-13 20:02:08 +02:00
Rasmus Wriedt Larsen
ba7cdec2ea Python: Add some lines in test file
These are just empty now, such that it's obvious the tests didn't
change.
2021-09-13 20:00:50 +02:00
Rasmus Wriedt Larsen
a9694bf0ef Python: Clean whitespace 2021-09-13 19:58:59 +02:00
Mathias Vorreiter Pedersen
a714966e9b Import 'cpp' and add more description. 2021-09-13 18:43:34 +01:00
Ethan P
930a36df37 Add example step for ending build tracing 2021-09-13 13:40:49 -04:00
Mathias Vorreiter Pedersen
034899367d C++: Exclude uninstantiated templates from AV Rule 114. 2021-09-13 18:08:51 +01:00
Ethan P
47a543e086 Add reviewer feedback 2021-09-13 12:02:31 -04:00
Tom Hvitved
3bdc92ba8e Merge pull request #6681 from hvitved/java/files-folders-drop-columns
Java: Drop redundant columns from `files` and `folders` relations
2021-09-13 17:43:31 +02:00
Chris Smowton
122ffca049 Merge pull request #6645 from Marcono1234/marcono1234/spurious-javadoc-param-generic-class
Java: Detect spurious param Javadoc tag of generic classes
2021-09-13 16:41:06 +01:00
Benjamin Muskalla
24d740b2da Merge branch 'main' into inlineFlowTest 2021-09-13 17:15:37 +02:00
Benjamin Muskalla
bf5a46f6d8 Simplify inline tests 2021-09-13 17:08:02 +02:00
Taus
b51ce1d2b3 Merge pull request #6640 from yoff/python-add-parameter-default-value-flow-step
Python: add parameter default value flow step
2021-09-13 17:05:48 +02:00
Anders Schack-Mulligen
7b764aec92 Merge pull request #6682 from aschackmull/java/callbacks
Java: Add support for callback-based library models.
2021-09-13 16:43:03 +02:00
Chris Smowton
3c7b39f089 Add change note 2021-09-13 15:36:26 +01:00
Anders Fugmann
f202ddc5aa C++: Add changenote 2021-09-13 16:31:06 +02:00
Tamas Vajk
80f5ec29d4 Log stdout and stderr in CSV coverage jobs 2021-09-13 16:16:03 +02:00
Tamas Vajk
1d8fae44cc Only leave CSV coverage updater job enabled on github/codeql 2021-09-13 16:15:21 +02:00
Tom Hvitved
b60f1cd531 Java: Upgrade script 2021-09-13 16:09:47 +02:00
Tom Hvitved
9fdcacd865 Java: Drop redundant columns from files and folders relations 2021-09-13 16:09:47 +02:00
Anders Schack-Mulligen
ab862276fc Java: Fix tests. 2021-09-13 16:04:11 +02:00
Anders Schack-Mulligen
12aeaeed56 Java: Address review comment. 2021-09-13 16:03:50 +02:00
Chris Smowton
47b5165f2a Merge pull request #6653 from smowton/smowton/admin/javascript-unpaired-surrogate-test
Java and JS: Add/adapt tests for literals with an unpaired surrogate character
2021-09-13 14:53:23 +01:00
Anders Schack-Mulligen
818e75bb8f Java: Fix compilation error in telemetry lib. 2021-09-13 15:50:21 +02:00
Anders Fugmann
8e9ac18026 C++: Deprecate RangeSSA::isGuardPhi/3 2021-09-13 15:35:05 +02:00
Geoffrey White
902fa7d44a C++: Subsection header. 2021-09-13 14:10:17 +01:00
Geoffrey White
acd1acd869 C++: Give it a section header. 2021-09-13 14:08:18 +01:00
Geoffrey White
befd1a7ccc C++: Rename security tests readme. 2021-09-13 14:06:22 +01:00
Chris Smowton
abdd3a5dbe Adjust Java tests that check for unpaired surrogate extraction 2021-09-13 14:02:05 +01:00
Erik Krogh Kristensen
05cc6bcf8a adjust regexp libraries to how unpaired surrogate are parsed now 2021-09-13 14:02:05 +01:00
Chris Smowton
f24d7c4212 Acknowledge new FPs due to the extractor using U+FFFD for unpaired surrogates
These were already misinterpreted, but the ReDoS code ignored them as they previously appeared to be `?` characters.
2021-09-13 14:02:05 +01:00
Chris Smowton
487ebdf173 Add test for Javascript literal with an unpaired surrogate character 2021-09-13 14:02:05 +01:00
Anders Schack-Mulligen
89a6cdc711 Java: Add support for callback-based library models. 2021-09-13 14:49:28 +02:00
Ian Lynagh
3404bcf265 Merge pull request #6680 from github/igfoo/java_location
Java: Use the standard URL format for Location.toString()
2021-09-13 13:43:32 +01:00
Ian Lynagh
4fbb165dce Java: Use the standard URL format for Location.toString() 2021-09-13 12:53:50 +01:00
Anders Fugmann
9a35a699cb C++: Update tests 2021-09-13 12:10:58 +02:00
Chris Smowton
68ed3250e8 Merge pull request #6478 from smowton/smowton/feature/jax-rs-request-filters
Java: Add sources for Jax-RS filters
2021-09-13 10:59:17 +01:00
Felicity Chapman
1d76578202 Merge pull request #6659 from github/docs-311-update-version
Update version numbers for LGTM Enterprise 1.28
2021-09-13 10:26:52 +01:00
James Fletcher
c86311e879 Merge pull request #6502 from github/dataflow-tutorial
Add data flow debugging guide to CodeQL docs
2021-09-13 10:25:19 +01:00
Anders Fugmann
342b2df93f C++: zero or one byte sized arrays in unions are considered as having the length of the union its a member of 2021-09-13 11:25:04 +02:00
Anders Fugmann
3172d5727a C++: Relax constraints on Buffer::memberMayBeVarSize 2021-09-13 11:15:33 +02:00
yoff
d0563c80be Merge pull request #6665 from smowton/smowton/fix/python-redos-invalid-utf16
ReDoS: fix unpaired surrogate test
2021-09-13 11:14:45 +02:00
Anders Schack-Mulligen
2db039fb77 Merge pull request #6673 from Marcono1234/marcono1234/clone-method-models
Java: Remove duplicate classes modeling Object.clone
2021-09-13 11:13:14 +02:00
Anders Schack-Mulligen
dde07fd2ee Merge pull request #6672 from Marcono1234/marcono1234/functional-interfaces-test
Java: Extend functional interfaces test
2021-09-13 11:13:06 +02:00
Anders Fugmann
4ab9b81a9a C++: Add tests exposing some FP's for OverflowStatic query 2021-09-13 11:09:56 +02:00
Tom Hvitved
4628f880b4 Merge pull request #6489 from hvitved/csharp/files-folders-drop-columns
C#: Drop redundant columns from `files` and `folders` relations
2021-09-13 11:02:13 +02:00
Anders Schack-Mulligen
31739cdae6 Merge pull request #6668 from github/workflow/coverage/update
Update CSV framework coverage reports
2021-09-13 09:50:09 +02:00
Tom Hvitved
2730423ab2 C#: Upgrade script 2021-09-13 09:49:10 +02:00
Tom Hvitved
5d048a9518 C#: Drop redundant columns from files and folders relations 2021-09-13 09:49:09 +02:00
Tamás Vajk
cc1374b832 Merge pull request #6646 from tamasvajk/fix/csv-timeseries
Fix CSV timeseries script to create DB with scheme from correct git SHA
2021-09-13 09:41:56 +02:00
Tom Hvitved
0abfb00032 Merge pull request #6660 from hvitved/csharp/dotnet-exec-tracing-windows
C#: Handle `dotnet exec csc.dll` compiler calls on Windows
2021-09-13 09:07:50 +02:00
github-actions[bot]
26e8e89aca Add changed framework coverage reports 2021-09-13 00:08:00 +00:00
jorgectf
353c0a9ee7 Add missing comment 2021-09-12 20:44:04 +02:00
jorgectf
3cf28ad6ce Merge remote-tracking branch 'origin/main' into jorgectf/python/ldapinsecureauth 2021-09-12 20:36:25 +02:00
jorgectf
18b05bc56e Fix tests and add global option 2021-09-12 20:35:57 +02:00
jorgectf
54012eba23 Optimize getFullHostRegex 2021-09-12 20:13:08 +02:00
Philip Ginsbach
131d63c374 Merge pull request #6592 from github/ginsbach/instanceofDocs
language reference entry for non-extending subtypes
2021-09-12 15:21:41 +01:00
Marcono1234
d117593d72 Java: Remove duplicate classes modeling Object.clone 2021-09-12 02:05:57 +02:00
Marcono1234
5009ed618f Java: Extend functional interfaces test 2021-09-12 01:50:07 +02:00
Andrew Eisenberg
edbaceceb3 Merge pull request #6666 from github/aeisenberg/suites-fix
Remove incorrect `suites` directive
2021-09-10 14:15:10 -07:00
Ethan P
fb22931e2d add indirect build tracing content and example 2021-09-10 16:06:32 -04:00
CodeQL CI
e8fc3c8ead Merge pull request #5888 from erik-krogh/casting
Approved by asgerf
2021-09-10 09:11:39 -07:00
Andrew Eisenberg
9c0f18b88d Remove incorrect directive
This directive should only be in the
pack.
2021-09-10 08:57:37 -07:00
Chris Smowton
95046b9bb1 Factor JaxRS models 2021-09-10 16:36:40 +01:00
Chris Smowton
451a46bf0e Add models for getLanguage, getMediaType 2021-09-10 16:36:38 +01:00
Chris Smowton
5e7a3ca2e6 Model UriInfo.relativize and resolve. 2021-09-10 16:36:37 +01:00
Chris Smowton
62ecab8432 Add change note 2021-09-10 16:36:36 +01:00
Chris Smowton
f1c3a11103 Add sources for Jax-RS filters 2021-09-10 16:36:34 +01:00
Chris Smowton
d83ed33252 Make supertype consideration consistent 2021-09-10 16:27:28 +01:00
Chris Smowton
9b488207eb Add support for the Flexjson framework to the unsafe-deserialization query 2021-09-10 16:27:23 +01:00
Chris Smowton
9d31641bb1 Add change note 2021-09-10 16:10:56 +01:00
Chris Smowton
655236c70d Remove no-longer-needed generic specifiers 2021-09-10 16:10:55 +01:00
Chris Smowton
b47939c737 Note resolved spurious results 2021-09-10 16:10:54 +01:00
Chris Smowton
d940085384 Spring HTTP: inherit produced content-types from surrounding class 2021-09-10 16:10:52 +01:00
Chris Smowton
bdd135dbff Spring HTTP: mark explicitly content-typed body calls as sinks
Previously only the return from the request-handler method constituted a sink, and was filtered by the Produces annotation if any, even though a BodyBuilder could explicitly override.

These sinks are also marked as out-barriers to avoid duplicate paths when the Produces annotation is in agreement.
2021-09-10 16:10:50 +01:00
Chris Smowton
701d0bcdca Spring content types: recognise constant content-type strings 2021-09-10 16:10:48 +01:00
Chris Smowton
4397371a50 Spring constant media types: recognise constant string versions
Previously we only recognised the constant MediaTypes
2021-09-10 16:10:47 +01:00
Chris Smowton
b9b34eb0ee Move Spring XSS sink definition into SpringHttp.qll 2021-09-10 16:10:45 +01:00
Chris Smowton
3b6cc97557 Sanitize Spring bodies directly associated with an XSS-safe Content-Type 2021-09-10 16:10:44 +01:00
Chris Smowton
0ebbb333ba Merge pull request #6564 from haby0/java/xxe/new
Java: Add XXE sinks
2021-09-10 16:04:27 +01:00
Chris Smowton
38cc9bef02 ReDoS: fix unpaired surrogate test
This actually does result in an FP, but this was previously hidden by non-interpretation of '\u' escapes within a raw string.
2021-09-10 15:37:34 +01:00
Chris Smowton
29028c5d46 Update test expectations to account for dataflow subpaths changes 2021-09-10 13:53:41 +01:00
Chris Smowton
2d03840fde Add experimental variants of java/xxe, incorporating new sinks and a version that uses local sources.
Originally authored by @haby0, squashed to clean up a tangled commit history.
2021-09-10 13:49:31 +01:00
Rasmus Lerchedahl Petersen
2eb11731e2 Python: Subpaths in test output 2021-09-10 14:04:57 +02:00
Rasmus Lerchedahl Petersen
02fd63ce20 Merge branch 'main' of github.com:github/codeql into python/port-modification-of-default-value
To get the subpaths.
2021-09-10 14:03:02 +02:00
Rasmus Lerchedahl Petersen
5d137ce9c5 Python: Update test expectations 2021-09-10 13:35:49 +02:00
Rasmus Wriedt Larsen
db78e3a7da Merge pull request #6274 from tausbn/python-api-graphs-import-star
Python: Support `import *` in API graphs
2021-09-10 13:25:41 +02:00
Rasmus Wriedt Larsen
b45743b562 Merge pull request #6312 from tausbn/python-deprecate-importnode
Python: Deprecate `importNode`
2021-09-10 13:12:56 +02:00
CodeQL CI
27f2d417c1 Merge pull request #6652 from asgerf/js/type-tracking-through-callback
Approved by erik-krogh
2021-09-10 04:11:14 -07:00
Rasmus Lerchedahl Petersen
7cfa08abc8 Python: Do not use BarrierGuards
They are simply not right for this problem.
We should not even make them available as an extension point.
2021-09-10 12:48:24 +02:00
Tom Hvitved
649c2ce188 Merge pull request #6586 from hvitved/dataflow/stage2-precise-call-ctx-take2
Data flow: Add precise call contexts to stage 2
2021-09-10 11:34:35 +02:00
Tom Hvitved
af0b9abab7 C#: Handle dotnet exec csc.dll compiler calls on Windows 2021-09-10 11:26:43 +02:00
Anders Fugmann
2c93bce9ad C++: Refactor code to use predicate isGuardPhi/4 2021-09-10 10:53:48 +02:00
CodeQL CI
0673355f31 Merge pull request #6649 from rhysd/discussion-untrusted-inputs
Approved by erik-krogh
2021-09-10 01:44:54 -07:00
Rasmus Lerchedahl Petersen
b20232db3c Python: Simplify guards as suggested 2021-09-10 10:31:48 +02:00
Anders Peter Fugmann
1bbadb57a2 Merge pull request #6568 from andersfugmann/andersfugmann/improve_upper_bound
C++: Improve predicate upperBound in SimpleRangeAnalysis
2021-09-10 09:49:48 +02:00
Erik Krogh Kristensen
a756ffa3a6 use the new instanceof syntax for NodeJSClientRequest 2021-09-10 09:30:37 +02:00
Tom Hvitved
296d10fe2a Data flow: Adjust callMayFlowThroughFwd pragmas 2021-09-10 09:21:24 +02:00
Felicity Chapman
3b3350e648 Correct the Qllexer path for slides 2021-09-10 08:04:07 +01:00
Anders Schack-Mulligen
3e17fdcaa3 Merge pull request #6407 from bmuskalla/charSeqSubSeq
Java: Track taint for CharSequence#subSequence
2021-09-10 09:01:29 +02:00
Felicity Chapman
32b3e416b3 Update version numbers for LGTM E 1.28 2021-09-10 06:54:36 +01:00
rhysd
97ed9edd32 JS: Detect untrusted inputs in 'discussion' and 'discussion_comment' payloads 2021-09-10 10:42:58 +09:00
Chris Smowton
5b8b27a2aa Merge pull request #6651 from smowton/smowton/admin/functional-interface-tests
Add tests for functional interfaces
2021-09-09 22:02:16 +01:00
Tamás Vajk
ad04099ac2 Merge pull request #6630 from tamasvajk/feature/interface-runtimecallable
C# Extend runtime callables to cover interface members with default implementation
2021-09-09 17:24:55 +02:00
Andrew Eisenberg
4c74709019 Merge pull request #6606 from github/aeisenberg/docs
Update the docs about qlpacks
2021-09-09 07:42:24 -07:00
Anders Schack-Mulligen
13c4b93d3d Merge pull request #6648 from aschackmull/java/func-interface
Java: Fix FunctionalInterface.
2021-09-09 16:14:14 +02:00
Benjamin Muskalla
9d5e48430e Merge branch 'main' into charSeqSubSeq 2021-09-09 16:04:36 +02:00
Chris Smowton
a0bf170d02 Add test for functional interfaces 2021-09-09 15:00:42 +01:00
Anders Schack-Mulligen
ec3990c619 Java: Fix FunctionalInterface. 2021-09-09 15:04:22 +02:00
Anders Schack-Mulligen
c4956a4ade Merge pull request #6376 from bmuskalla/thirdpartyapitelemtry
Java: Introduce queries to capture information about 3rd party API usage
2021-09-09 13:55:47 +02:00
Anders Fugmann
270dbd2bf7 C++: Revert peer review suggestion.
The suggested change has a severe impact on row counts, as cpp does not cache
the results for `bbDominates`. Since the `getGuardedUpperBound` predicate the
cost of runtime complexity is considered higher than the benefit of this change.
2021-09-09 13:26:42 +02:00
Anders Fugmann
6c44b0e6e7 C++: Add test case where a guarded block has two predecessors which are both in the dominance domain of the guard 2021-09-09 13:18:49 +02:00
Benjamin Muskalla
c0e65e71b4 Revert "Java: Fix external flow perofrmance with future optimiser."
This reverts commit be1d4c04f2.
2021-09-09 13:06:23 +02:00
Benjamin Muskalla
eef044f4d0 Add test to capture expected parameter format 2021-09-09 13:05:15 +02:00
Tamas Vajk
abe6c90829 Update change note 2021-09-09 13:04:47 +02:00
Tamas Vajk
0a17ab9325 Merge branch 'main' into feature/service-stack 2021-09-09 13:01:43 +02:00
Tamas Vajk
cc7471f37d Fix package separator in timeseries report 2021-09-09 12:53:59 +02:00
Tamas Vajk
cbb37f70c4 Change timeseries CSV report to only include dates when values changed 2021-09-09 11:34:38 +02:00
Benjamin Muskalla
a1b7437f8d Merge branch 'main' into thirdpartyapitelemtry 2021-09-09 11:11:42 +02:00
Tamas Vajk
1fe9e9262f Fix CSV timeseries script to create DB with scheme from correct git SHA 2021-09-09 10:59:52 +02:00
Marcono1234
a173d9593b Java: Detect spurious param Javadoc tag of generic classes 2021-09-09 00:11:02 +02:00
Andrew Eisenberg
fb90bb4241 Remove outdated section
Co-authored-by: Shati Patel <42641846+shati-patel@users.noreply.github.com>
2021-09-08 10:45:50 -07:00
Andrew Eisenberg
ec5435befd Apply suggestions from code review
Co-authored-by: Shati Patel <42641846+shati-patel@users.noreply.github.com>
2021-09-08 08:13:15 -07:00
Philip Ginsbach
55c605998c Update docs/codeql/ql-language-reference/types.rst
Co-authored-by: Nick Rolfe <nickrolfe@github.com>
2021-09-08 15:35:40 +01:00
Benjamin Muskalla
96a34b6165 Fix value flow for fluent api 2021-09-08 16:12:52 +02:00
Anders Schack-Mulligen
5d58edb3b9 Merge pull request #6641 from aschackmull/dataflow/edges-fasttc
Dataflow: Only calculate fastTC for the relevant part of edges.
2021-09-08 15:45:46 +02:00
Mathias Vorreiter Pedersen
44f477d552 C++: Add uninterpreted query for obtaining frontend and extraction time. 2021-09-08 14:32:50 +01:00
Benjamin Muskalla
b47507293a Minor fixes for fluent apis 2021-09-08 15:32:41 +02:00
Tamas Vajk
9ab6c29cd3 Extend runtime callables to cover interface members with default implementation 2021-09-08 15:07:49 +02:00
Rasmus Lerchedahl Petersen
baca9edbb1 Merge branch 'main' of github.com:github/codeql into python-add-parameter-default-value-flow-step 2021-09-08 14:48:13 +02:00
CodeQL CI
cd26d97dd7 Merge pull request #6549 from erik-krogh/moreDom
Approved by asgerf
2021-09-08 05:10:47 -07:00
Chris Smowton
5d37748973 Merge pull request #6631 from github/Claim-Java-16-support
Claim Java 16 support
2021-09-08 12:31:28 +01:00
Benjamin Muskalla
67eaa1b735 Fix qldoc 2021-09-08 13:08:28 +02:00
Asger Feldthaus
db1de18cc2 JS: Support transitive callback-passing 2021-09-08 13:08:16 +02:00
Asger Feldthaus
ceaf2b3727 JS: Rename FlowSteps::callback -> exploratoryCallbackStep 2021-09-08 13:08:12 +02:00
Asger Feldthaus
7c94dd94e9 JS: Add type-tracking steps through callback args 2021-09-08 13:08:05 +02:00
Asger Feldthaus
1f6df4e70d JS: Add callback type tracking test 2021-09-08 13:08:04 +02:00
Anders Schack-Mulligen
1af39f0776 Dataflow: Sync. 2021-09-08 13:02:07 +02:00
Anders Schack-Mulligen
2e9876f58f Dataflow: Only calculate fastTC for the relevant part of edges. 2021-09-08 13:01:29 +02:00
Anders Fugmann
f91bd91d02 C++: Apply suggested change from code review 2021-09-08 12:38:53 +02:00
Anders Schack-Mulligen
2b7882e6e5 Merge pull request #5032 from aschackmull/dataflow/subpaths
Dataflow: Add subpaths query predicate.
2021-09-08 11:52:41 +02:00
Anders Schack-Mulligen
3f5b9d0f54 Merge pull request #6637 from github/alexet/imporve-query
Java: Fix performance issues with future versions of codeql.
2021-09-08 11:16:19 +02:00
Anders Fugmann
e93dc0b4c4 C++: Fix comment in getGuardedUpperBound 2021-09-08 11:06:58 +02:00
Rasmus Lerchedahl Petersen
4a5f70e6c8 Python: Reclassify defaultValueFlowStep
as a `jumpStep`.
2021-09-08 10:05:31 +02:00
jorgectf
4e261c61ae Optimize concatAndCompareAgainstFullHostRegex 2021-09-07 19:05:03 +02:00
jorgectf
800801177d Fix taint tracking comment 2021-09-07 19:02:32 +02:00
jorgectf
b802d7903a Fix OPT_X_TLS_ mandatory options 2021-09-07 19:01:46 +02:00
jorgectf
ee98c0c587 Add start_tls_s() comment and use DataFlow::MethodCallNode instead 2021-09-07 19:00:14 +02:00
Jorge
1bc16fb31e Apply suggestions from code review
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-09-07 18:37:33 +02:00
alexet
81f4822b8d Java: Fix performance with future optimiser by caching a predicate 2021-09-07 16:38:40 +01:00
alexet
be1d4c04f2 Java: Fix external flow perofrmance with future optimiser. 2021-09-07 16:38:39 +01:00
alexet
726feb3f4d Java: Fix magic in TC with future optimiser. 2021-09-07 16:38:39 +01:00
Tamás Vajk
f90d1fd70e Merge pull request #6636 from tamasvajk/fix/stubbing-2
C#: Fix member order (yet again) in stubbing
2021-09-07 17:37:29 +02:00
Benjamin Muskalla
9e66ee1da0 Add example to inline flow test docs 2021-09-07 16:47:02 +02:00
Benjamin Muskalla
3641b28c3e Convert javax-json to InlineFlowTest 2021-09-07 16:47:01 +02:00
Benjamin Muskalla
a6b47208e1 Convert optional to InlineFlowTest 2021-09-07 16:47:01 +02:00
Benjamin Muskalla
2d9b4b33d4 Convert spring to InlineFlowTest 2021-09-07 16:47:01 +02:00
Benjamin Muskalla
da3b7a2b69 Convert json-java to InlineFlowTest 2021-09-07 16:47:00 +02:00
Benjamin Muskalla
ff73e46c95 Convert jackson to InlineFlowTest 2021-09-07 16:47:00 +02:00
Benjamin Muskalla
1ead522705 Convert guava-cache to InlineFlowTest 2021-09-07 16:47:00 +02:00
Benjamin Muskalla
efd5dc94e6 Convert apache-commons-lang3 to InlineFlowTest 2021-09-07 16:47:00 +02:00
Benjamin Muskalla
eba414e31b Convert apache-collections to InlineFlowTest 2021-09-07 16:46:59 +02:00
Benjamin Muskalla
3bc70f0ce6 Convert containerflow to inline flow test 2021-09-07 16:46:59 +02:00
Benjamin Muskalla
7a0fc6ae61 Migrate jaxson to inline test 2021-09-07 16:46:59 +02:00
Benjamin Muskalla
41891959a3 Fix apache test 2021-09-07 16:46:58 +02:00
Benjamin Muskalla
2d13906e0e Simplify jaxrs setup 2021-09-07 16:46:58 +02:00
Benjamin Muskalla
24d43689b2 Simplify test setup 2021-09-07 16:46:58 +02:00
Benjamin Muskalla
8830f1531f Convert some tests to use InlineFlowTest 2021-09-07 16:46:58 +02:00
Benjamin Muskalla
acb055400d Extract inline flow test 2021-09-07 16:46:57 +02:00
Benjamin Muskalla
d1a1f57e77 Convert taint-format test into inline test 2021-09-07 16:46:56 +02:00
Rasmus Wriedt Larsen
995a8192a9 Merge pull request #6635 from github/RasmusWL/fix-csharp-cwe-tag
C#: Fix CWE tag for `cs/insufficient-key-size`
2021-09-07 15:54:42 +02:00
Tom Hvitved
3d4db42da4 Merge pull request #6634 from hvitved/csharp/codeql-manual-build-command
C#: Use explicit Code Analysis build command
2021-09-07 15:31:20 +02:00
Tamas Vajk
469993f6d3 C#: Fix member order (yet again) in stubbing
With explicit interface implementation, the same member name can show up multiple times in a type declaration. This commit defines an explicit order
for these members.
2021-09-07 15:26:03 +02:00
yoff
43effd2b40 Update python/ql/src/semmle/python/functions/ModificationOfParameterWithDefault.qll
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-09-07 15:08:50 +02:00
Taus Brock-Nannestad
bea8a457a2 Merge branch 'main' into python-make-annotated-assignment-a-definitionnode 2021-09-07 15:01:01 +02:00
Taus Brock-Nannestad
1ab86892a0 Merge branch 'main' into python-deprecate-importnode 2021-09-07 14:59:12 +02:00
CodeQL CI
5b229e9392 Merge pull request #6574 from asgerf/js/vue-api-graphs
Approved by erik-krogh
2021-09-07 05:53:30 -07:00
Taus Brock-Nannestad
79c3ccd56e Python: Remove import-helper tests
As discussed, these are all present in the `ApiGraphs` directory
already (except for the dataflow consistency test, which has been
moved there instead).
2021-09-07 14:50:05 +02:00
Tamás Vajk
d7934865c9 Merge pull request #6628 from tamasvajk/feature/fix-stub-escaping
C#: improve stubbing to escape more member names (not just fields)
2021-09-07 14:29:44 +02:00
Benjamin Muskalla
f7ad894495 Fix name of api filter predicate 2021-09-07 14:28:58 +02:00
Taus Brock-Nannestad
5ac32f145f Merge branch 'main' into python-fix-exceptstmt-gettype 2021-09-07 14:21:13 +02:00
Benjamin Muskalla
22df141761 Rename API name predicate 2021-09-07 14:17:13 +02:00
Taus
51c0ceea38 Python: Update test_import_star.py
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-09-07 14:15:48 +02:00
Taus Brock-Nannestad
5f5285955b Merge branch 'main' into python-api-graphs-import-star 2021-09-07 14:13:56 +02:00
Taus
b99c075282 Merge pull request #6460 from yoff/python-regex-parsing-consistency-checks
Python: Add regex parsing consistency checks
2021-09-07 13:33:59 +02:00
Tom Hvitved
bef05f885c C#: Update CIL data flow tests 2021-09-07 13:02:20 +02:00
Anders Schack-Mulligen
f6541811d2 Dataflow: Update more tests. 2021-09-07 13:02:20 +02:00
Anders Schack-Mulligen
f30dad7705 Dataflow: Update test expected outputs. 2021-09-07 13:02:20 +02:00
Rasmus Wriedt Larsen
8f52089475 C#: Fix CWE tag for cs/insufficient-key-size
Since this targets

CWE-326 Inadequate Encryption Strength

> The software stores or transmits sensitive data using an encryption scheme that is theoretically sound, but is not strong enough for the level of protection required.
> \- https://cwe.mitre.org/data/definitions/326.html

and not

CWE-327: Use of a Broken or Risky Cryptographic Algorithm

> The use of a broken or risky cryptographic algorithm is an unnecessary risk that may result in the exposure of sensitive information.
> \- https://cwe.mitre.org/data/definitions/327.html

This matches what we do for similar query in Python: https://github.com/github/codeql/blob/main/python/ql/src/Security/CWE-326/WeakCryptoKey.ql
2021-09-07 12:59:10 +02:00
Anders Schack-Mulligen
7ec1fa2ebe Dataflow: Sync. 2021-09-07 12:51:42 +02:00
Anders Schack-Mulligen
2d7d45a8ac Dataflow: Account for hidden nodes. 2021-09-07 12:51:42 +02:00
Anders Schack-Mulligen
3c3d71d4a0 Dataflow: Sync 2021-09-07 12:51:42 +02:00
Anders Schack-Mulligen
81ed3e7176 Dataflow: Add subpaths query predicate. 2021-09-07 12:51:42 +02:00
Tamás Vajk
1dc712f54d Merge pull request #6629 from tamasvajk/feature/dispatch-fix
C#: Fix dispatch library to handle summarized callables with no runti…
2021-09-07 12:35:45 +02:00
Tamas Vajk
203ca3f91b C#: improve stubbing to escape more member names (not just fields) 2021-09-07 12:34:23 +02:00
Tamás Vajk
7befdc9c5c Merge pull request #6627 from tamasvajk/feature/stub-readme
C#: Add readme to stub folder
2021-09-07 12:09:52 +02:00
Tamás Vajk
c63fd4a254 Merge pull request #6260 from tamasvajk/feature/method-name
C#: Change generic method names to include <> and type args/params
2021-09-07 12:09:27 +02:00
Rasmus Lerchedahl Petersen
fcd346c2af Python: Add flow from default values
to their parameters.
This creates data-flow inconsistencies,
probably because the default values have incorrect enclosing callables
2021-09-07 11:33:09 +02:00
Tom Hvitved
bcaf0658e4 C#: Use explicit Code Analysis build command 2021-09-07 10:58:06 +02:00
Mathias Vorreiter Pedersen
5cecea42e4 Merge pull request #6603 from geoffw0/impropnulltests
C++: Add test cases for cpp/improper-null-termination.
2021-09-07 09:55:36 +01:00
Mathias Vorreiter Pedersen
b7206c1218 Merge pull request #6581 from geoffw0/uncontrolledarith2
CPP: Improvements for cpp/uncontrolled-arithmetic
2021-09-07 09:48:59 +01:00
Anders Fugmann
ebdda885f9 C++: Update test annotation for OverflowStatic 2021-09-07 10:38:16 +02:00
Rasmus Lerchedahl Petersen
e8644f6f2a Python: coment out discriminating test
The test case has different behaviour between py2/3.
When merging this, we should create an issue to resolve it.
2021-09-07 10:30:38 +02:00
Rasmus Lerchedahl Petersen
b48caaf465 Python: fix reference to PrintNode.qll 2021-09-07 10:19:42 +02:00
Rasmus Lerchedahl Petersen
8729701b66 Merge branch 'main' of github.com:github/codeql into python/port-modification-of-default-value
Files have moved around, specifically PrintNode.qll.
2021-09-07 10:13:51 +02:00
Rasmus Lerchedahl Petersen
29cb067769 Python: Remember to update test expectations 2021-09-07 10:13:17 +02:00
Rasmus Lerchedahl Petersen
ae8408bcab Python: Add missing qldoc 2021-09-07 10:09:02 +02:00
Rasmus Lerchedahl Petersen
4998a48f99 Python: Fix simple guards 2021-09-06 22:40:30 +02:00
Chris Smowton
79ff7baaf6 Claim Java 16 support
As of https://github.com/github/codeql/pull/6604 we support all new Java 16 features
2021-09-06 17:17:17 +01:00
yoff
138a7ae67f Merge pull request #6349 from RasmusWL/more-modeling
Python: Improve various library modeling
2021-09-06 17:01:45 +02:00
Tamas Vajk
3a9cf639bd Change ServiceStack redis sinks to code injection instead of SQL injection 2021-09-06 16:59:31 +02:00
Tamas Vajk
5fa9f16c01 Adjust ServiceStack CSV rows with generic method names 2021-09-06 16:45:21 +02:00
yoff
c7146ac10c Update python/ql/src/meta/alerts/RemoteFlowSourcesReach.ql
Co-authored-by: Rasmus Wriedt Larsen <rasmuswl@github.com>
2021-09-06 16:00:58 +02:00
Tamas Vajk
f6366e1e1f Merge branch 'feature/method-name' into feature/service-stack 2021-09-06 15:52:08 +02:00
Tamas Vajk
207d8f6030 Merge branch 'main' into feature/service-stack 2021-09-06 15:46:43 +02:00
Anders Fugmann
9af4d560dd Merge branch 'main' into andersfugmann/improve_upper_bound 2021-09-06 14:26:58 +02:00
Tamas Vajk
5014ef2337 C#: Add ServiceStack support with CSV data model 2021-09-06 14:06:37 +02:00
Tamas Vajk
43ccc14162 Add ServiceStack stubs and empty test referencing it 2021-09-06 14:05:41 +02:00
Tamas Vajk
e3a49f8213 C#: improve stubbing to escape more member names (not just fields) 2021-09-06 14:02:42 +02:00
Tamas Vajk
270b56af1b Extend runtime callables to interface members with default implementation 2021-09-06 14:02:42 +02:00
Tamas Vajk
39a88d2e43 Fix dispatch library to handle summarized callables with no runtime target 2021-09-06 14:02:42 +02:00
Tamas Vajk
648197db35 C#: Fix dispatch library to handle summarized callables with no runtime target 2021-09-06 13:45:43 +02:00
Tamas Vajk
0d88d18781 C#: Add readme to stub folder 2021-09-06 13:42:36 +02:00
Andrew Eisenberg
bb9911e06f Merge pull request #6605 from aeisenberg/aeisenberg/pack/consistency 2021-09-06 04:40:58 -07:00
Rasmus Wriedt Larsen
b28bddd22c Merge pull request #6598 from RasmusWL/fail-on-missing-query-pack
Misc: Make `generate-code-scanning-query-list.py` fail on missing query pack
2021-09-06 13:22:13 +02:00
Tamas Vajk
b7f13a7e1f C#: Change generic method names to include <> and type args/params 2021-09-06 11:48:22 +02:00
Erik Krogh Kristensen
85e1c87d14 use the new non-extending-subtypes syntax 2021-09-06 11:19:50 +02:00
Erik Krogh Kristensen
8d4af3ad81 convert field based range pattern to casting based range pattern 2021-09-06 11:05:23 +02:00
Anders Fugmann
ddbaf585ec Merge branch 'main' into andersfugmann/improve_upper_bound 2021-09-06 10:32:44 +02:00
Anders Fugmann
e4d22ea628 C++: Add comment on why getGuardedUpperBound must have exactly one predecessor 2021-09-06 10:31:32 +02:00
Anders Schack-Mulligen
5a47ddbf77 Merge pull request #6604 from smowton/smowton/admin/marcono-record-tests
Java: Add tests for static and final modifiers relating to record classes
2021-09-06 09:32:32 +02:00
Tamás Vajk
b9ef6c7e55 Merge pull request #6596 from tamasvajk/fix/stub-ordering
C#: Fix ordering of stubbed type members, implemented interfaces, and…
2021-09-06 09:27:19 +02:00
ihsinme
8b0d5a2e7b Update cpp/ql/src/experimental/Security/CWE/CWE-675/DoubleRelease.qhelp
Co-authored-by: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
2021-09-05 22:46:37 +03:00
Andrew Eisenberg
286c102358 Update the docs about qlpacks
This is a first pass to fix obvious holes and outdated information, but
we should rethink these docs completely.
2021-09-03 12:50:25 -07:00
Andrew Eisenberg
6a47fcaf1f Packaging: Normalize all qlpack.yml files for all languages
This commit ensures consistency among all of our qlpacks. Here are the
changes:

1. Ensure only modern references are used (codeql-{lang} is converted to
   codeql/{lang}-all or codeql/{lang}-queries where appropriate).
2. Use consistent version numbers. All languages are at 0.0.2 except
   javascript, which is 0.0.3.
3. Convert all `libraryPathDependencies` to `dependencies` with version
   constraints
4. Dependencies from query packs to other packs are always `"*"` since
   these dependencies are always from source and we should get the
   latest.
5. Dependencies from codeql/{lang}-lib to codeql/{lang}-upgrades must
   be strict since there is a tight connection between the libary
   and its relevant upgrades.
2021-09-03 11:53:28 -07:00
Chris Smowton
23d7633cd5 Add tests for static and final modifiers relating to record classes 2021-09-03 18:20:16 +01:00
Philip Ginsbach
863eede75b easier second example for instanceof extensions 2021-09-03 16:12:52 +01:00
Geoffrey White
4e60fd5fc7 C++:Add the ImproperNullTerminationTainted.ql query to the test. 2021-09-03 15:53:24 +01:00
Tamas Vajk
c02a743835 Revert redundant order by 2021-09-03 16:51:32 +02:00
Geoffrey White
ccf1a44a2b C++: Extend tests for cpp/improper-null-termination. 2021-09-03 15:48:36 +01:00
Benjamin Muskalla
ec0066d5a4 Merge pull request #6597 from bmuskalla/hideStubsInDiff
Java: Hide diff for generated files by default
2021-09-03 15:11:15 +02:00
Rasmus Lerchedahl Petersen
913990bc62 Python: Add suggested comments and test case 2021-09-03 14:40:16 +02:00
yoff
c6eb795e76 Apply suggestions from code review
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-09-03 14:23:57 +02:00
Benjamin Muskalla
51475d2fb0 Merge branch 'main' into thirdpartyapitelemtry 2021-09-03 14:23:31 +02:00
Benjamin Muskalla
f59a5b6574 Hide changes for experimenal stubs 2021-09-03 14:16:04 +02:00
Benjamin Muskalla
ab5c1d6bdd Rework filter to exclude simple constructors 2021-09-03 13:38:01 +02:00
Asger Feldthaus
7149ad8ac4 JS: Also mark uses of the exports object as an export in PackageExports 2021-09-03 13:35:30 +02:00
Chris Smowton
0dd463dd2b Merge pull request #6520 from smowton/smowton/feature/allow-local-interfaces
Java: Allow local interfaces
2021-09-03 12:01:36 +01:00
Philip Ginsbach
cd646c819d explain instanceof extensions via charpred instanceof 2021-09-03 10:55:03 +01:00
Benjamin Muskalla
9ed14b438e Use readble format for APIs 2021-09-03 11:53:18 +02:00
Philip Ginsbach
35b0e83370 simpler first instanceof extension example 2021-09-03 10:52:05 +01:00
Chris Smowton
c20cf23c98 Update stats file dependencies 2021-09-03 10:40:51 +01:00
Benjamin Muskalla
4b02e266fd Fix test as we support explicit collection types 2021-09-03 11:37:39 +02:00
Benjamin Muskalla
7d3131ca49 Move usage count into where clause 2021-09-03 11:32:14 +02:00
Benjamin Muskalla
89ce04dcb9 Pull usage count into where clause 2021-09-03 11:26:22 +02:00
Philip Ginsbach
6e025186ab make clear that instanceof supertypes are not base types 2021-09-03 10:23:58 +01:00
Philip Ginsbach
abaa0633d7 consistently distinguish base types and supertypes 2021-09-03 10:20:14 +01:00
Philip Ginsbach
d2f833d02c deep implications => implications 2021-09-03 10:13:12 +01:00
Benjamin Muskalla
2edb32f344 Fix naming 2021-09-03 10:59:35 +02:00
Rasmus Wriedt Larsen
67df890f68 Misc: Fail by default if query pack can't be found 2021-09-03 10:56:49 +02:00
Chris Smowton
76a41146a8 Merge pull request #6594 from smowton/smowton/fix/stub-arrays-and-bounds
Move unreachable cases of IndirectType into getAContainedType
2021-09-03 09:56:04 +01:00
Benjamin Muskalla
6ede08e3c9 Remove dead code 2021-09-03 10:53:24 +02:00
Benjamin Muskalla
c06e37f3d9 Hide diff for generated files by default 2021-09-03 10:46:52 +02:00
Rasmus Wriedt Larsen
9386a900eb Misc: Clean whitespace in generate-code-scanning-query-list.py 2021-09-03 10:46:25 +02:00
james
8c37e90a77 revert a couple of changes 2021-09-03 09:31:54 +01:00
Geoffrey White
f2047ee4d0 C++: Actually fix expected files after layout changes. 2021-09-03 09:13:41 +01:00
Tamas Vajk
3560853f36 C#: Fix ordering of stubbed type members, implemented interfaces, and location comments 2021-09-03 09:53:34 +02:00
Anders Fugmann
d962fc4ce1 C++: Improve predicate upperBound in SimpleRangeAnalysis
If an expression has an immediate guardPhi node, this is used as a strict upper bound
2021-09-02 21:46:18 +02:00
Anders Fugmann
c110508b4e C++: Add tests to expose potential improvements available to SimpleRangeAnalysis 2021-09-02 21:20:33 +02:00
Chris Smowton
d57bd34575 Update dbscheme stats 2021-09-02 20:14:51 +01:00
Shati Patel
d22620f72f Merge pull request #6575 from shati-patel/docs-copyright-year
Docs: Auto-update copyright year
2021-09-02 18:43:07 +01:00
Chris Smowton
c259d0204a Move unreachable cases of IndirectType into getAContainedType 2021-09-02 17:53:52 +01:00
Geoffrey White
a0b712d44b C++: Add notice about the SAMATE Juliet tests. 2021-09-02 17:34:48 +01:00
Geoffrey White
d73604d1c5 C++: Fix a few glitches and accept line number changes in expected files. 2021-09-02 17:34:47 +01:00
Geoffrey White
f755659f5d C++: More directory structure consistency / cleanup. 2021-09-02 17:34:47 +01:00
Geoffrey White
d1ab2d2e8c C++: Remove some irrelevant macro logic and main functions. 2021-09-02 17:34:46 +01:00
Geoffrey White
fdb4a2acdb C++: Clean up header comments. 2021-09-02 17:34:46 +01:00
Geoffrey White
75d367a6c5 C++: Add ad-hoc SAMATE Juliet test cases (that were previously internal). Directory structures cleaned up in a few places. 2021-09-02 17:34:45 +01:00
Philip Ginsbach
ee13efbffd some whitesapce fixes 2021-09-02 17:31:55 +01:00
Philip Ginsbach
dbda1bf5c0 Update docs/codeql/ql-language-reference/types.rst
Co-authored-by: Chris Smowton <smowton@github.com>
2021-09-02 17:30:36 +01:00
Chris Smowton
b9afccc015 Remove impossible lines from Stubs.qll 2021-09-02 17:14:38 +01:00
james
2e995839bb fix link 2021-09-02 16:46:23 +01:00
james
81a9ce2baa polish text 2021-09-02 16:40:29 +01:00
Philip Ginsbach
dbc95cadb4 language reference entry for non-extending subtypes 2021-09-02 15:23:39 +01:00
Rasmus Wriedt Larsen
9f590dbf2d Python: Fix .expected
After we now model `db.text()` calls from Flask-SQLAlchemy
2021-09-02 16:04:25 +02:00
Rasmus Wriedt Larsen
414bf12f86 Python: Fix DefaultTextClauseConstruction 2021-09-02 16:03:25 +02:00
Rasmus Wriedt Larsen
88c6d4bb20 Python: Fix .qhelp 2021-09-02 16:02:04 +02:00
Chris Smowton
29b9231f49 Rename db types relating to local classes
These now all refer to types or classes-or-interfaces.
2021-09-02 14:51:51 +01:00
Chris Smowton
e8bdc8ba17 Make Member.getEnclosingCallable compatible with local interfaces 2021-09-02 14:51:50 +01:00
Chris Smowton
608d24f75e Rename QL elements that refer to local classes 2021-09-02 14:51:50 +01:00
Chris Smowton
0a5410c2d3 Remove unnecessary charpred 2021-09-02 14:51:49 +01:00
Chris Smowton
474d983f8d Fix typo
Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com>
2021-09-02 14:51:48 +01:00
Chris Smowton
fca561351d Fix typo
Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>
2021-09-02 14:51:48 +01:00
Chris Smowton
ac43ad6da2 Add change note 2021-09-02 14:51:47 +01:00
Chris Smowton
e048a729db Add Interface.isLocal and use it where appropriate
Some EJB logic regrettably needs to be renamed out of the way. Hopefully the churn caused by this is less than would be caused if Interface's isLocal needed to be named differently from Class.isLocal.
2021-09-02 14:51:46 +01:00
Chris Smowton
ca5c2b2acf Fix description wording
Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>
2021-09-02 14:51:46 +01:00
Chris Smowton
9c4a50503c Allow local interfaces
Java 16 permits enums and interfaces to be declared method-locally. Enums are already classes, but interfaces are not (in dbscheme terms), so we need to permit isLocalClass to tag them like it already does classes.
2021-09-02 14:51:45 +01:00
Rasmus Wriedt Larsen
065075056b Python: Highlight how await taint-step works 2021-09-02 15:45:59 +02:00
Rasmus Wriedt Larsen
ad102e2746 Python: Minor cleanup to snippets
As pointed out in review, we don't need this override any more!
2021-09-02 15:40:32 +02:00
CodeQL CI
b4963c7538 Merge pull request #6558 from erik-krogh/redosCasing
Approved by esbena, yoff
2021-09-02 12:20:08 +01:00
Taus
e4fd749a46 Merge pull request #6547 from github/RasmusWL/cwe328-weak-hash
Python: Add CWE-328 to `py/weak-sensitive-data-hashing`
2021-09-02 11:42:31 +02:00
Tamás Vajk
82f61ca015 Merge pull request #6577 from tamasvajk/fix/cil-modified-pointer
C#: Temporarily extract modified pointers as unmodified during CIL ex…
2021-09-02 10:48:51 +02:00
Rasmus Wriedt Larsen
d55f18f8e3 Python: Add modeling of Flask-SQLAlchemy 2021-09-02 10:48:24 +02:00
Rasmus Wriedt Larsen
f1744890b1 Python: Add tests for Flask-SQLAlchemy 2021-09-02 10:48:15 +02:00
Rasmus Wriedt Larsen
c34d6d1162 Python: Add query to handle SQLAlchemy TextClause Injection
instead of doing this via taint-steps. See description in code/tests.
2021-09-02 10:19:57 +02:00
Rasmus Wriedt Larsen
81dbe36e99 Python: Promote SQLAlchemy modeling
Due to the split between `src/` and `lib/`, I was not really able to do
the next step without having moved the SQLAlchemy modeling over to be in
`lib/` as well.
2021-09-02 10:19:57 +02:00
Rasmus Wriedt Larsen
ba99e21875 Python: Remove modeling of sqlescapy PyPI package
I've never seen this being used in real code, and this library doesn't
have a lot of traction, so I would rather not commit to supporting it
(which includes verifying that it actually makes things safe).

Personally I don't think this is the right approach for avoiding SQL
injection either.
2021-09-02 10:19:57 +02:00
Rasmus Wriedt Larsen
91442e100c Python: Model sessionmaker().begin() 2021-09-02 10:19:57 +02:00
Rasmus Wriedt Larsen
feb2303e1f Python: Model the underlying DB-API connection 2021-09-02 10:19:57 +02:00
Rasmus Wriedt Larsen
1ab04a7276 Python: Model Connection.execution_options 2021-09-02 10:19:57 +02:00
Rasmus Wriedt Larsen
2acf518037 Python: Model exec_driver_sql 2021-09-02 10:19:57 +02:00
Rasmus Wriedt Larsen
fe143c7dfa Python: Rewrite most of SQLAlchemy modeling 2021-09-02 10:19:57 +02:00
Rasmus Wriedt Larsen
b39bb24fcf Python: Add more SQLAlchemy tests 2021-09-02 10:19:57 +02:00
Jonas Jensen
1ba26237a7 Merge pull request #6585 from rvermeulen/patch-3
Update qldoc for the Access class
2021-09-02 10:17:36 +02:00
ihsinme
1e88470ad8 Add files via upload 2021-09-02 10:22:49 +03:00
ihsinme
9f4b7255aa Add files via upload 2021-09-02 10:21:07 +03:00
Erik Krogh Kristensen
1ad204d89e make after and TState private in ReDoSUtil 2021-09-02 09:15:43 +02:00
Erik Krogh Kristensen
df04c5044c use concat instead of strictconcat in RegexTreeView.qll 2021-09-02 08:54:39 +02:00
Tom Hvitved
c3ecae503b Data flow: Sync files 2021-09-01 19:58:47 +02:00
Tom Hvitved
136c8b5192 Data flow: Improve callMayFlowThroughFwd join order
Before:
```
[2021-08-25 09:56:29] (1395s) Tuple counts for DataFlowImpl2::Stage3::callMayFlowThroughFwd#ff/2@111fb3:
                      15495496   ~5%         {5} r1 = SCAN DataFlowImpl2::Stage3::fwdFlowOutFromArg#fffff#reorder_0_2_4_1_3 OUTPUT In.3, In.4, In.2 'config', In.0 'call', In.1
                      1450611958 ~6335%      {5} r2 = JOIN r1 WITH DataFlowImpl2::Stage3::fwdFlow#fffff_03412#join_rhs ON FIRST 3 OUTPUT Lhs.3 'call', Lhs.4, Lhs.2 'config', Rhs.3, Rhs.4
                      7043648    ~20415%     {2} r3 = JOIN r2 WITH DataFlowImpl2::Stage3::fwdFlowIsEntered#fffff#reorder_0_3_4_1_2 ON FIRST 5 OUTPUT Lhs.0 'call', Lhs.2 'config'
                                             return r3
```

After:
```
[2021-08-25 10:57:02] (2652s) Tuple counts for DataFlowImpl2::Stage3::callMayFlowThroughFwd#ff/2@d3e27b:
                      15495496 ~0%         {6} r1 = SCAN DataFlowImpl2::Stage3::fwdFlowOutFromArg#fffff#reorder_0_2_4_1_3 OUTPUT In.0 'call', In.1, In.2 'config', In.3, In.4, In.2 'config'
                      9236888  ~22%        {7} r2 = JOIN r1 WITH DataFlowImpl2::Stage3::fwdFlowIsEntered#fffff#reorder_0_3_4_1_2 ON FIRST 3 OUTPUT Lhs.3, Rhs.3, Rhs.4, Lhs.4, Lhs.5, Lhs.0 'call', Lhs.2 'config'
                      7043648  ~20415%     {2} r3 = JOIN r2 WITH DataFlowImpl2::Stage3::fwdFlow#fffff ON FIRST 5 OUTPUT Lhs.5 'call', Lhs.6 'config'
                                           return r3
```
2021-09-01 19:57:29 +02:00
Andrew Eisenberg
10f6cab77e Merge pull request #6583 from github/aeisenberg/query-suite-docs
Docs: Update documentation for query suites
2021-09-01 10:33:22 -07:00
Benjamin Muskalla
ee8958ba03 Fix nodes for local taint test 2021-09-01 15:55:59 +02:00
Benjamin Muskalla
c1d34d7d6f Move Strings to lib 2021-09-01 15:55:39 +02:00
Benjamin Muskalla
190bf90bc8 Replace stringbuilder step with model 2021-09-01 15:41:16 +02:00
Benjamin Muskalla
7ddf7ff211 Track taint from concatenated string 2021-09-01 15:41:16 +02:00
Benjamin Muskalla
d178fe4e5d Fix failing tests 2021-09-01 15:41:16 +02:00
Benjamin Muskalla
93bc8aa7b2 Fix tests to take trim into account 2021-09-01 15:41:15 +02:00
Benjamin Muskalla
7be179cf6c Mark String constructor as propagating taint 2021-09-01 15:41:15 +02:00
Benjamin Muskalla
3928ffd30d Support CharSequence#subSequence 2021-09-01 15:41:15 +02:00
Benjamin Muskalla
b7e608abc9 Model string builder APIs 2021-09-01 15:41:14 +02:00
Benjamin Muskalla
dab626270d Convert Objects API to csv model 2021-09-01 15:41:14 +02:00
Benjamin Muskalla
5df5805d36 Convert strings to summary model 2021-09-01 15:41:14 +02:00
Benjamin Muskalla
e0d978fd58 Migrate String constructor to model 2021-09-01 15:41:13 +02:00
Remco Vermeulen
7310590f90 Update qldoc FunctionAccess class
The `FunctionAccess` class doesn't capture accesses of functions in function call expressions.
This update makes that explicit.
2021-09-01 15:36:00 +02:00
Remco Vermeulen
ffd2a388a9 Update qldoc for the Access class
The access class does not capture function accesses that are part of a function call expression.
This updates makes that explicit
2021-09-01 15:30:33 +02:00
Asger Feldthaus
cc838326e1 JS: Remove old bulk export access getAnExportedModule 2021-09-01 13:28:54 +02:00
Asger Feldthaus
7daa6481e3 JS: Check property name in NodeJSModule.getABulkExportedNode 2021-09-01 13:25:14 +02:00
Asger Feldthaus
4b1f918feb JS: Extend getABulkExportedNode and use it in PackageExports 2021-09-01 13:24:23 +02:00
Chris Smowton
dccdc3be5a Merge pull request #6582 from github/smowton/admin/mention-multiple-sort-criteria
Expression docs: mention multiple sort criteria
2021-09-01 12:22:23 +01:00
Asger Feldthaus
cce3c0256e JS: Update some comments in Vue 2021-09-01 13:04:40 +02:00
Tamás Vajk
e9ff6e8755 Merge pull request #6578 from tamasvajk/fix/cil-local-decoding
C#: Handle non-critical exception in CIL local variable extraction
2021-09-01 12:52:53 +02:00
Erik Krogh Kristensen
a3289fabe1 sync ReDoSUtil with python 2021-09-01 12:47:06 +02:00
Erik Krogh Kristensen
537450606e use a consistent comment about the ignore case flag 2021-09-01 12:46:50 +02:00
Erik Krogh Kristensen
ff74fe1e03 rename hasChildThatMatchesIgnoringCasing to hasChildThatMatchesIgnoringCasingFlags 2021-09-01 12:45:20 +02:00
Erik Krogh Kristensen
75a3f34e86 use if-else in ReDoSUtil::getCanonicalizationFlags
Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
2021-09-01 12:44:02 +02:00
CodeQL CI
29bcd7ca6f Merge pull request #6572 from erik-krogh/live-server
Approved by esbena
2021-09-01 12:41:23 +02:00
Tamás Vajk
50a9b18c92 Merge pull request #6579 from tamasvajk/fix/cil-type-args
C#: Fix completely broken type argument extraction in NoMetadataHandleType
2021-09-01 12:16:15 +02:00
Chris Smowton
303e02fb8a Fix typo
Co-authored-by: Marcono1234 <Marcono1234@users.noreply.github.com>
2021-09-01 10:45:47 +01:00
Erik Krogh Kristensen
f8d46677b9 add RequestExpr as an alias to NodeJSLib::RequestExpr in Connect.qll 2021-09-01 10:11:05 +02:00
Erik Krogh Kristensen
98d018ce26 remove redundant extends clause
Co-authored-by: Esben Sparre Andreasen <esbena@github.com>
2021-09-01 10:09:40 +02:00
Andrew Eisenberg
21c168e229 Apply suggestions from code review
Co-authored-by: Aditya Sharad <6874315+adityasharad@users.noreply.github.com>
2021-08-31 14:47:28 -07:00
Andrew Eisenberg
0923d1fdc1 Docs: Update documentation for query suites
Adds some clarification around the `qlpack` directive.
The semantics has changed. This provides a new example
and some description.
2021-08-31 13:39:04 -07:00
Chris Smowton
c92b7828cb Merge pull request #6580 from smowton/smowton/admin/guava-models-mistakes
Fix minor mistakes in old Guava models
2021-08-31 19:44:23 +01:00
Chris Smowton
a47efc4348 Expression docs: mention multiple sort criteria 2021-08-31 19:18:03 +01:00
Shati Patel
a80a367de4 Merge pull request #6354 from Optixal/docs-js-isuncertain
JS: Fixed description of `isUncertain()` predicate in CodeQL Language Guides: CodeQL Library for JavaScript
2021-08-31 19:13:40 +01:00
Geoffrey White
d6368c3d1b C++: Add QLDoc comments. 2021-08-31 19:03:45 +01:00
Geoffrey White
49807c080b C++: Understand *=. 2021-08-31 18:25:52 +01:00
Geoffrey White
436b18a11f C++: Add test cases. 2021-08-31 18:23:15 +01:00
Geoffrey White
6bbed9d624 C++: Test layout. 2021-08-31 18:09:21 +01:00
Sauyon Lee
7156dee270 Merge pull request #6521 from sauyon/java/test-gen-improvements
Java: generate more realistic tests
2021-08-31 10:06:08 -07:00
Chris Smowton
7977d9c253 Fix minor mistakes in old Guava models
Also add tests for the affected functions
2021-08-31 15:26:09 +01:00
Chris Smowton
b38a23daee Fix test cases featuring primitive arrays
Previously we couldn't print the name of types like `byte[]` for example.
2021-08-31 15:12:47 +01:00
Tamas Vajk
b267d26ff8 C#: Fix completely broken type argument extraction in NoMetadataHandleType 2021-08-31 14:34:27 +02:00
Tamas Vajk
d6ae19c87d C#: Handle non-critical exception in CIL local variable extraction 2021-08-31 14:29:53 +02:00
Tamas Vajk
0ba334bb22 C#: Temporarily extract modified pointers as unmodified during CIL extraction 2021-08-31 14:26:36 +02:00
Erik Krogh Kristensen
28dce6e95a fix non-monotonic recursion in js/missing-rate-limiting 2021-08-31 14:23:23 +02:00
Erik Krogh Kristensen
83252e5ba2 change note 2021-08-31 14:23:23 +02:00
Erik Krogh Kristensen
cecb6c7bdd add model for live-server 2021-08-31 14:23:23 +02:00
Erik Krogh Kristensen
b509627113 add tests for connect 2021-08-31 14:23:23 +02:00
Erik Krogh Kristensen
3d6ab81ab8 refactor the tests for connect 2021-08-31 14:23:23 +02:00
Erik Krogh Kristensen
c6399dbdf4 simplify the connect model by reusing NodeJSLib::RouteHandler 2021-08-31 14:23:23 +02:00
Chris Smowton
f94d8c341d Abbreviate multi-column min 2021-08-31 11:57:49 +01:00
Chris Smowton
510f5abb9a Add missing qldoc 2021-08-31 11:56:03 +01:00
Chris Smowton
5dddc48e60 autoformat 2021-08-31 11:53:13 +01:00
Tom Hvitved
c8a5397085 Merge pull request #6513 from hvitved/csharp/cfg/shared
C#: Make CFG library shared
2021-08-31 11:55:43 +02:00
Asger Feldthaus
27f10123c7 JS: Autoformat 2021-08-31 11:19:11 +02:00
Asger Feldthaus
8833ff7854 JS: Use Vue model in Vuex model 2021-08-31 11:19:10 +02:00
Asger Feldthaus
ebf17e10d6 JS: Fixup in getComponentRef() 2021-08-31 11:19:09 +02:00
Asger Feldthaus
607f2d66b8 JS: Rename getASelfRef to getAnInstanceRef 2021-08-31 11:19:08 +02:00
Asger Feldthaus
999f22f548 JS: Fix getOwnOptionsObject 2021-08-31 11:19:08 +02:00
Asger Feldthaus
9f02ae29ec JS: Autoformat 2021-08-31 11:19:07 +02:00
Asger Feldthaus
7dd65d8ac6 JS: Clean up taint step definitions
These are Unit types and so should be kept private as you can't
use them for anything other than getting all taint steps of a certain
type.

Also factors out accesses to 'this'.
2021-08-31 11:19:06 +02:00
Asger Feldthaus
5b0e26c814 JS: Use API graphs a few more places 2021-08-31 11:19:06 +02:00
Asger Feldthaus
4ff135e827 JS: Port class-based components to API graphs 2021-08-31 11:19:05 +02:00
Asger Feldthaus
5cd0996d92 JS: Deprecate getOwnOptionsObject() 2021-08-31 11:19:04 +02:00
Asger Feldthaus
7be4b76abb JS: Simplify getABoundFunction 2021-08-31 11:19:04 +02:00
Asger Feldthaus
0ee1e8bd97 JS: Rename ExtendedVue to ComponentExtension 2021-08-31 11:19:03 +02:00
Asger Feldthaus
881951368d JS: Merge VueInstance and ExtendedInstance into one case 2021-08-31 11:19:03 +02:00
Asger Feldthaus
ecda79834d JS: Remove getOption(name) override subsumed by new implementation 2021-08-31 11:19:02 +02:00
Asger Feldthaus
e4901eda91 JS: Handle .extend called on any component 2021-08-31 11:19:01 +02:00
Asger Feldthaus
2a79817c3b JS: Add test for "extends" 2021-08-31 11:19:01 +02:00
Asger Feldthaus
4d4443c3cf JS: Use API graphs in getOption(s) 2021-08-31 11:19:00 +02:00
Asger Feldthaus
f450476b27 JS: Improve handling of default exports in Vue 2021-08-31 11:19:00 +02:00
Asger Feldthaus
cd6a60dc70 JS: Treat default-export from .vue file as entry point 2021-08-31 11:18:59 +02:00
Asger Feldthaus
b223049682 JS: Add getComponentRef() 2021-08-31 11:18:58 +02:00
Asger Feldthaus
b9d1b5584e JS: Add API-node version of getOwnOptions 2021-08-31 11:18:58 +02:00
Asger Feldthaus
63b7c6a8d9 JS: Use API:: classes for clarity (no semantic change) 2021-08-31 11:18:57 +02:00
Asger Feldthaus
f7f69dc3ab JS: Make MkExtendedInstance handle cross-module flow 2021-08-31 11:18:56 +02:00
Asger Feldthaus
76c38a564d JS: Port vue() to API graphs 2021-08-31 11:18:56 +02:00
Tom Hvitved
7fc536db15 Data flow: Add precise call contexts to stage 2 2021-08-31 10:44:33 +02:00
CodeQL CI
cf9ab83dee Merge pull request #6498 from bananabr/main
Approved by asgerf
2021-08-31 08:46:11 +02:00
CodeQL CI
c3e122f5fc Merge pull request #6569 from erik-krogh/packageJsonModule
Approved by asgerf
2021-08-31 08:23:45 +02:00
Benjamin Muskalla
09aaa8f78e Merge pull request #6562 from github/workflow/coverage/update
Update CSV framework coverage reports
2021-08-30 21:31:02 +02:00
Rasmus Lerchedahl Petersen
a01fca5d48 Merge branch 'main' of github.com:github/codeql into python-regex-parsing-consistency-checks
To fix conflicts
2021-08-30 18:40:12 +02:00
yoff
13c5857241 Update python/ql/src/semmle/python/RegexTreeView.qll
Co-authored-by: Taus <tausbn@github.com>
2021-08-30 18:38:38 +02:00
Rasmus Lerchedahl Petersen
a855074588 Python: Try to remove py2/3 differences 2021-08-30 15:41:51 +02:00
Rasmus Lerchedahl Petersen
0de621edf9 Python: Add qldoc 2021-08-30 15:03:58 +02:00
Tom Hvitved
789e2e48cf C#: Remove temporary dispatch restriction 2021-08-30 14:49:04 +02:00
Rasmus Lerchedahl Petersen
1903cb8f82 Python: Add change note 2021-08-30 11:27:55 +02:00
Erik Krogh Kristensen
486b283c20 support the "module" field in package.json files 2021-08-30 11:05:32 +02:00
Rasmus Lerchedahl Petersen
a762373ad6 Python: Implement simple barrier guard
The one found in the original test case
2021-08-30 11:04:27 +02:00
Erik Krogh Kristensen
f5a1a12435 support case insensitive regexps in the ReDoS queries 2021-08-30 09:59:33 +02:00
github-actions[bot]
b28e956dd2 Add changed framework coverage reports 2021-08-30 00:08:31 +00:00
Sauyon Lee
adcb90aa8c fixup generateflowtestcase chaneg 2021-08-27 11:25:03 -07:00
Sauyon Lee
23b9028d2c Correctly determine which support method definitions are required 2021-08-27 11:25:03 -07:00
Sauyon Lee
04e04b3031 Use array allocation syntax 2021-08-27 11:25:03 -07:00
Sauyon Lee
97faeb026f Fix side of stack that gen method types are used 2021-08-27 11:25:03 -07:00
Sauyon Lee
119de6c60c Replace type variables before attempting to match to an array generation 2021-08-27 11:25:03 -07:00
Sauyon Lee
9d66761eeb Consider a callable to ambiguous if it has a varargs parameter 2021-08-27 11:25:02 -07:00
Sauyon Lee
0d174f2daf Only include support methods and imports from working test cases 2021-08-27 11:25:02 -07:00
Erik Krogh Kristensen
81742528a2 add test 2021-08-27 10:04:39 +02:00
Erik Krogh Kristensen
1b6e1dbd13 include property writes in super-classes when reading a property in a sub-class 2021-08-27 10:04:39 +02:00
Erik Krogh Kristensen
285c659541 add src as a potential unsafe DOM property name for js/xss-through-dom 2021-08-27 10:04:39 +02:00
jorgectf
64b305cf7a Add .qhelp along with its example 2021-08-26 23:29:45 +02:00
Sauyon Lee
2132ee52d5 Restrict the size of appliesTo for default methods 2021-08-26 08:02:21 -07:00
Sauyon Lee
abf3bbbe8d Add qldoc for public elements 2021-08-26 08:02:21 -07:00
Sauyon Lee
e7611ab641 Move getCall and appliesTo to relevant classes 2021-08-26 08:02:21 -07:00
Sauyon Lee
ce8d14e6ef Add a priority predicate for test generation support methods 2021-08-26 08:02:21 -07:00
Sauyon Lee
1bd5eb5120 Use if statement instead of manual disjuction 2021-08-26 08:02:21 -07:00
Sauyon Lee
73d6177477 Java test gen: make char zero '\0' 2021-08-26 08:02:20 -07:00
Chris Smowton
2b0f6a2723 Java: Generate more realistic tests 2021-08-26 08:02:20 -07:00
Chris Smowton
33c727e6b9 Split up GenerateFlowTestCase.qll
This doesn't change any behaviour or alter any predicate bodies
2021-08-26 08:02:19 -07:00
Rasmus Lerchedahl Petersen
49ae549e89 Python: Implement modifying syntax 2021-08-26 14:29:18 +02:00
Rasmus Lerchedahl Petersen
097c23e437 Python: add inline expectations test
Consider removing the original test
2021-08-26 14:08:52 +02:00
Rasmus Wriedt Larsen
47377c7197 Merge branch 'main' into more-modeling 2021-08-26 13:40:17 +02:00
jorgectf
786edb72df Update .expected 2021-08-26 12:36:34 +02:00
Jorge
d458464e6b Apply suggestions from code review
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-08-26 12:20:09 +02:00
Rasmus Lerchedahl Petersen
d834cec9b9 Python: test simple sanitizer 2021-08-26 11:31:20 +02:00
Rasmus Lerchedahl Petersen
8614563b42 Python: More tests of syntactic constructs 2021-08-26 10:56:41 +02:00
Daniel Santos
b8ce5a63c5 Remove unncessary results
Simplifies query to improve performance by removing unnecessary results.
2021-08-25 17:33:45 -05:00
Rasmus Lerchedahl Petersen
5bff5188ac Python: switch from negative to positive list
This should avoid potentially terrible performance.
Also noted the missing syntactic constructs,
as I went through the documnetation.
2021-08-25 23:52:42 +02:00
Daniel Santos
cd40de7464 Update javascript/ql/src/experimental/Security/CWE-079/ClipboardXss.ql
Typo fix

Co-authored-by: Asger F <asgerf@github.com>
2021-08-25 09:40:55 -05:00
Tom Hvitved
ab2bc38789 C#: Use shared logic in NodeGraph.ql test 2021-08-25 11:35:12 +02:00
Tom Hvitved
d405284d36 C#: Make CFG library shared 2021-08-25 11:35:11 +02:00
Rasmus Wriedt Larsen
605bd19306 Python: Add CWE-328 to py/weak-sensitive-data-hashing
Reading over the description at https://cwe.mitre.org/data/definitions/328.html:

> The product uses a hashing algorithm that produces a hash value that can be used to determine the original input, or to find an input that can produce the same hash, more efficiently than brute force techniques.

For the data that does not require computationally expensive hashing, that will be the exactly problems that this query finds 👍 (that is, MD5, SHA1)
2021-08-25 10:19:22 +02:00
Rasmus Lerchedahl Petersen
e865a290de Python: straight port of query
The old query uses `pointsTo` to limit the sinks
to methods on lists and dictionaries.
That constraint is omitted here which could hurt performance.
2021-08-24 16:35:11 +02:00
Rasmus Lerchedahl Petersen
e3765ced78 Python: Add tests for modification of defaults 2021-08-24 16:35:11 +02:00
james
18440710b4 fix typos 2021-08-23 14:02:53 +01:00
james
66bdbf4a28 address review comments 2021-08-23 11:35:04 +01:00
james
dbf7487a9b address review comments 2021-08-23 11:34:48 +01:00
shati-patel
e1ae531b62 Docs: Auto-update copyright year 2021-08-23 11:11:31 +01:00
Rasmus Lerchedahl Petersen
34d7772a0d Python: Move constraints into pranch charpreds
For sequences and alternations, we require at least one child.
Otherwise, we wish to represent the term differently.
This avoids multiple representations.
2021-08-23 11:44:00 +02:00
Rasmus Lerchedahl Petersen
c4554836ca Python: merge test.py into unittests.py 2021-08-19 10:24:32 +02:00
Rasmus Lerchedahl Petersen
3c647c65bf Python: update comment 2021-08-19 10:21:19 +02:00
Rasmus Lerchedahl Petersen
21f683d531 Python: clean up stray coments 2021-08-18 16:59:35 +02:00
Daniel Santos
5644514606 Update javascript/ql/src/experimental/Security/CWE-079/ClipboardXss.ql
Co-authored-by: Asger F <asgerf@github.com>
2021-08-18 09:52:55 -05:00
james
dcbf766217 add new article to toc 2021-08-18 12:14:48 +01:00
james
8443d344a2 correct article name 2021-08-18 11:58:42 +01:00
james
18b8244406 fix link 2021-08-18 11:47:16 +01:00
james
429decd7b6 tweak sojme text 2021-08-18 11:38:03 +01:00
james
ad2850dd5d add new tutorial 2021-08-18 11:27:53 +01:00
james
babec9bf79 add data flow debugging guide 2021-08-18 11:26:51 +01:00
Daniel Santos
5e155d25b1 new Experimental query ClipboardBasedXss 2021-08-17 12:57:26 -05:00
Benjamin Muskalla
99e19e6d59 Fix predicate to only match the current API 2021-08-17 16:26:08 +02:00
Benjamin Muskalla
035f7b57e9 Improve query name 2021-08-17 16:25:49 +02:00
Rasmus Lerchedahl Petersen
dee5535fbb Python: condense tests
This also avoids potential licensing issues.
2021-08-17 11:24:39 +02:00
Benjamin Muskalla
1d3bcdf522 Align tests with new query structure 2021-08-16 21:55:00 +02:00
Benjamin Muskalla
87ef540b52 Split out queries showing supported APIs 2021-08-16 16:38:32 +02:00
Benjamin Muskalla
89f4a35273 Remove filter to see all unsupported APIs 2021-08-16 15:40:53 +02:00
Rasmus Lerchedahl Petersen
6be78d442c Python: fix compilation 2021-08-16 10:35:33 +02:00
Rasmus Lerchedahl Petersen
2df846ee4b Merge branch 'python-regex-parsing-consistency-checks' of github.com:yoff/codeql into python-regex-parsing-consistency-checks 2021-08-12 13:34:11 +02:00
Rasmus Lerchedahl Petersen
54e65ce765 Python: Add consistency tests
for all the projects that went out of disk as a result of ReDoS
2021-08-12 13:33:44 +02:00
yoff
61bbddeb0c Apply suggestions from code review
Co-authored-by: Erik Krogh Kristensen <erik-krogh@github.com>
2021-08-12 09:39:04 +02:00
Benjamin Muskalla
8aba0b04bc Add QLDoc for all shared libraries 2021-08-11 16:07:24 +02:00
Benjamin Muskalla
26ffe6c03d Add tests for telemetry queries 2021-08-11 15:32:09 +02:00
Benjamin Muskalla
6287e6d8e9 Filter unused API callsites 2021-08-11 15:31:56 +02:00
Benjamin Muskalla
ec7f4d18e1 Avoid duplicates and support modular runtime 2021-08-11 15:31:33 +02:00
Rasmus Lerchedahl Petersen
c08f94ec04 Python: Fix parsing of octal escapes 2021-08-11 15:01:26 +02:00
Rasmus Lerchedahl Petersen
34b054ff53 Python: Add consistency checks 2021-08-11 14:58:27 +02:00
Tamas Vajk
2437546009 Merge branch 'main' into feature/service-stack 2021-08-10 15:16:17 +02:00
Benjamin Muskalla
8127f63b1e Only include APIs without support 2021-08-10 12:05:16 +02:00
Benjamin Muskalla
26d4269071 Use FlowSources for coverage tracking 2021-08-10 12:02:56 +02:00
Benjamin Muskalla
c48586ff80 Implement coverage tracking using dataflow nodes 2021-08-10 11:38:01 +02:00
Benjamin Muskalla
5b55a83aaa Use basename for jars 2021-08-10 11:37:19 +02:00
Jordy Zomer
a3bacc76f1 Update cpp/ql/src/experimental/Security/CWE/CWE-787/UnsignedToSignedPointerArith.ql
Co-authored-by: intrigus-lgtm <60750685+intrigus-lgtm@users.noreply.github.com>
2021-08-05 23:31:12 +02:00
Jordy Zomer
cf40d0ae4d Fix a typo unsiged -> unsigned 2021-08-05 16:40:49 +02:00
Jordy Zomer
489ac04f86 Remove author tag 2021-08-05 12:34:31 +02:00
Jordy Zomer
19bb8e8c17 Make requested changes 2021-08-03 21:54:04 +02:00
Jordy Zomer
e07516585a cpp: Add query to detect unsigned integer to signed integer conversions used in pointer arithmetics 2021-08-03 19:08:47 +02:00
Benjamin Muskalla
60c7003667 Optimize return type check 2021-08-02 17:14:44 +02:00
Benjamin Muskalla
fda394858b Turn external API query into diagnostics query
* Expose (partial) CSV model for the API
* Rework and simplify predicates
2021-08-02 17:14:44 +02:00
Benjamin Muskalla
8595ae71f7 Simplify api coverage detection
Fixes a bug that doesn't take super types into account
when computing the usage of a specific API.
2021-08-02 17:14:44 +02:00
Benjamin Muskalla
3365634259 Expose csv parameter format predicate 2021-08-02 17:14:44 +02:00
Benjamin Muskalla
aab633eced Reformat 2021-08-02 17:14:43 +02:00
Benjamin Muskalla
2064915d3b Fold JDK API query into external API query 2021-08-02 17:14:43 +02:00
Benjamin Muskalla
0c04c9a2c2 Fix aggregation of jar usages 2021-08-02 17:14:43 +02:00
Benjamin Muskalla
722889e881 Make id unique 2021-08-02 17:14:42 +02:00
Benjamin Muskalla
d9285e78c0 Add query to collect external API calls 2021-08-02 17:14:42 +02:00
Benjamin Muskalla
07303ccbb3 Fix formatting 2021-08-02 17:14:42 +02:00
Benjamin Muskalla
b9f6b60c4d Introduce query to capture external libraries 2021-08-02 17:14:41 +02:00
Benjamin Muskalla
32f52ac30d Improve column names 2021-08-02 17:14:41 +02:00
Benjamin Muskalla
18e3763f90 Expose whether APIs are already supported 2021-08-02 17:14:41 +02:00
Benjamin Muskalla
9b6ae9029f Introduce query for capture JDK API usage 2021-08-02 17:14:40 +02:00
Jorge
f02b6d60a5 Merge branch 'github:main' into jorgectf/python/ldapinsecureauth 2021-07-22 18:49:51 +02:00
Shawn P
930d576cfb Fixed isUncertain() description 2021-07-23 00:45:02 +08:00
jorgectf
b03e75e3d1 Extend ldap3's start_tls and fix tests 2021-07-22 18:42:41 +02:00
jorgectf
a34d6d390e Port to ApiGraphs and finish the query 2021-07-22 18:34:57 +02:00
Rasmus Wriedt Larsen
38875ca0c7 Python: Improve handling of async methods 2021-07-22 14:17:07 +02:00
Rasmus Wriedt Larsen
c3f942f899 Python: Provide internal InstanceTaintStepsHelper
I realized that if you ever wanted to the way taint-steps works again,
you would have to go to all the 117 places it has been implemented, and
change EVERY ONE OF THEM :( so trying to solve that problem here.

Not super happy with the name, but that was just the best I could come up with :D
2021-07-22 14:16:50 +02:00
Rasmus Wriedt Larsen
6e9d9fcbbd Python: Improve taint steps in for & iterable unpacking
These were written way before the ones in DataFlowPrivate, but
apparently didn't cover quite as much :|
2021-07-22 14:16:17 +02:00
Rasmus Wriedt Larsen
d3163d8a76 Python: Add iterable-unpacking in for test 2021-07-22 11:59:46 +02:00
Rasmus Wriedt Larsen
e2d3fa7093 Python: Add list-comprehension taint test 2021-07-22 11:59:46 +02:00
Rasmus Wriedt Larsen
f5ae5a581b Python: A bit more additional taint clean up
A few stragglers that did not have the same TODO comments as the others
2021-07-22 11:59:46 +02:00
Rasmus Wriedt Larsen
d2efe0b84d Python: Normalize additional taint steps for modeled classes
Such that it should be next to the other class-related predicates (such
as `instance()`), the class is called `AdditionalTaintStep`, and it
marked private.

I also moved any modeling of attributes as well, while I was at it.
2021-07-22 11:59:46 +02:00
Rasmus Wriedt Larsen
be1cad864b Python: Resolve all meth = obj.meth; meth() TODOs
It would probably have been easier to do this as the _first_ thing...
but that's too late now 😓
2021-07-22 11:59:46 +02:00
Rasmus Wriedt Larsen
6f63c03558 Python: Model http.cookies.Morsel and usage in Tornado 2021-07-22 10:43:18 +02:00
Rasmus Wriedt Larsen
7e09a1cbfd Python: Model tornado.httputil.HTTPHeaders 2021-07-22 10:43:18 +02:00
Rasmus Wriedt Larsen
7020e4132b Python: Model BaseHTTPRequestHandler.rfile as file-like object 2021-07-22 10:43:18 +02:00
Rasmus Wriedt Larsen
d388dd547e Python: Model HTTPMessage from Stdlib 2021-07-22 10:43:18 +02:00
Rasmus Wriedt Larsen
f3ce3933d1 Python: Add AdditionalTaintStep to type-tracking class snippet
I know that the TODO about not having the tools to handling
`meth = obj.meth; meth()` is outdated now that we `DataFlow::MethodCallNode`,
but I'm planning to deal with that later on ;)
2021-07-22 10:43:18 +02:00
Rasmus Wriedt Larsen
dac71ded9d Python: Add Authorization modeling in Flask 2021-07-22 10:43:18 +02:00
Rasmus Wriedt Larsen
133632119d Python: Model werkzeug Headers
Also removed a misleading comment link to method on wrong class :D
2021-07-22 10:43:18 +02:00
Rasmus Wriedt Larsen
4d9c86a252 Python: Model Werkzeug FileStorage.save as FileSystemAccess 2021-07-22 10:43:18 +02:00
Rasmus Wriedt Larsen
9cb4899c5c Python: Add FileStorage modeling in Flask 2021-07-22 10:43:18 +02:00
Rasmus Wriedt Larsen
09b0c300d9 Python: Rewrite werkzeug to avoid InstanceSourceApiNode
InstanceSourceApiNode is a really good idea, but it just happened too
soon. I can't do what I need if I have to supply an API-node. So to
avoid confusion between deprecating to/from InstanceSource in those
classes, I opted to do some major reorganizing as well 👍

Due to aliasing restrictions, I had to use a little trick with the
`WerkzeugOld` module.
2021-07-22 10:43:18 +02:00
Rasmus Wriedt Larsen
04190ea308 Python: Add file-like modeling to werkzeug FileStorage 2021-07-22 10:43:18 +02:00
Rasmus Wriedt Larsen
5f5c0b11c7 Python: Refactor Werkzeugmodeling
Having the additional taint step just next to the other definitions, so
everything is together.
2021-07-22 10:43:18 +02:00
Rasmus Wriedt Larsen
4f4dec50f2 Python: Model ResovlerMatch in Django
Like before, omitted ClassInstantiation
2021-07-22 10:43:13 +02:00
jorgectf
edb273ace5 Merge remote-tracking branch 'origin/jorgectf/python/ldapimproperauth' into jorgectf/python/ldapinsecureauth 2021-07-22 02:51:19 +02:00
Rasmus Wriedt Larsen
6f0a622252 Python: Remove ClassInstantiation from Django UploadedFile
since UploadedFile is the abstract base class, all real usage would be
of one of the subclasses, so removing this to not provide a false hope
that it actually works.

I don't think investing the time into making this work would give any
value, so that's why I didn't do it ;)
2021-07-21 16:35:09 +02:00
Rasmus Wriedt Larsen
7dc6518350 Python: Add FileLikeObject modeling
Such that the result of `request.FILES["key"].file.read()` is tainted
2021-07-21 16:35:09 +02:00
Rasmus Wriedt Larsen
18c0d13efd Python: Model most of UploadedFile in Django 2021-07-21 16:35:09 +02:00
Rasmus Wriedt Larsen
5ec5557203 Python: Model MultiValueDict in Django 2021-07-21 16:35:09 +02:00
Rasmus Wriedt Larsen
95e88c18b9 Python: Minor cleanup 2021-07-21 16:35:09 +02:00
Rasmus Wriedt Larsen
51b543c67c Python: Model taint for django request methods 2021-07-21 16:35:09 +02:00
Rasmus Wriedt Larsen
bced467a88 Python: Refactor django additional step handling
So it matches the new style we're using in aiohttp/twisted/...
2021-07-21 16:35:09 +02:00
Rasmus Wriedt Larsen
ce4b192caa Python: Improve usefulness of RemoteFlowSourcesReach meta query
Before, results from `dca` would look something like

    ## + py/meta/alerts/remote-flow-sources-reach

    - django/django@c2250cf_cb8f: tests/messages_tests/urls.py:38:16:38:48
        reachable with taint-tracking from RemoteFlowSource
    - django/django@c2250cf_cb8f: tests/messages_tests/urls.py:38:9:38:12
        reachable with taint-tracking from RemoteFlowSource

now it should make it easier to spot _what_ it is that actually changed,
since we pretty-print the node.
2021-07-21 16:35:09 +02:00
Rasmus Wriedt Larsen
6aabbf0b9a Python: Add some alert meta queries
Intended for use with dca
2021-07-21 14:53:01 +02:00
Taus
6591a86aad Python: Add test cases
I debated whether to add a
`MISSING: use=moduleImport("builtins").getMember("print").getReturn()`
annotation to the last line.

Ultimately, I decided to add it, as we likely _do_ want this information
to propagate into inner functions (even if the value of `var2` may
change before `func4` is called).
2021-07-20 13:26:35 +00:00
Taus
e53b86fbbc Python: Apply suggestions from code review
Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com>
2021-07-20 15:19:45 +02:00
Taus
bbcbcefedc Python: Add false negative test case. 2021-07-20 12:54:06 +00:00
Taus
233ae5a54b Python: Fix FP in py/unused-local-variable
This is only a temporary fix, as indicated by the TODO comment.

The real underlying issue is the fact that `isUnused` is defined in
terms of the underlying SSA variables (as these are only created
for variables that are actually used), and the fact that annotated
assignments are always considered to redefine their targets, which may
not actually be the case.

Thus, the correct fix would be to change the extractor to _disregard_
mere type annotations for the purposes of figuring out whether an
SSA variable should be created or not.

However, in the short term the present fix is likely sufficient.
2021-07-20 12:13:44 +00:00
Taus
8b3fa789da Python: Add AnnAssign DefinitionNode
This was a source of false positives for the
`py/uninitialized-local-variable` query, as exemplified by the test
case.
2021-07-20 11:57:26 +00:00
Taus
f91e826781 Python: Add test case 2021-07-20 11:57:12 +00:00
Porcuiney Hairs
c6c925d67a Python : Improve Xpath Injection Query 2021-07-20 03:31:30 +05:30
Taus
4f3f93f267 Python: Autoformat 2021-07-16 12:22:24 +00:00
Taus
3fd0ec74f0 Python: Deprecate importNode
Unsurprisingly, the only thing affected by this was the `import-helper`
tests. These have lost all of the results relating to `ImportMember`s,
but apart from that the underlying behaviour should be the same.

I also limited the test to only `CfgNode`s, as a bunch of `EssaNode`s
suddenly appeared when I switched to API graphs.

Finally, I used `API::moduleImport` with a dotted name in the type
tracking tests. This goes against the API graphs interface, but I think
it's more correct for this use case, as these type trackers are doing
the "module attribute lookup" bit manually.
2021-07-16 11:38:30 +00:00
mr-sherman
04940a1105 Create 2021-07-14-service-stack-support.md 2021-07-14 15:54:28 -04:00
Taus
5a9fca48e8 Python: Fix ExceptStmt::getType
We were not supporting `except` statements handling multiple exception
types (specified as a tuple) correctly, instead just returning the
tuple itself as the "type" (which makes little sense).

To fix this, we explicitly extract the elements of this node, in the
case where it _is_ a tuple.

This is a change that can potentially affect many queries (as `getType`
is used in quite a few places), so some care should be taken to
ensure that this does not adversely affect performance.
2021-07-14 14:03:49 +00:00
Taus
ec9063b4a5 Python: Add test case for github/codeql#6227 2021-07-14 13:52:32 +00:00
Taus
c3789811c8 Python: Support import * in API graphs 2021-07-13 18:22:51 +00:00
Taus
8b6b4dde69 Python: Refactor built-ins logic
This will make it possible to reuse for names defined in `import *`.
2021-07-13 18:20:25 +00:00
Taus
df8a6b984a Python: Add import * tests
Moves the current test out of `test.py`, as otherwise any unknown global
(like, say, `sink`) would _also_ be considered to be something
potentially defined in `unknown`.
2021-07-13 17:46:59 +00:00
Mathias Vorreiter Pedersen
90633b9ce1 C++: Make the new SQL abstract classes extend 'Function' instead. This is more in line with how we model RemoteFlowFunction. 2021-06-23 11:49:51 +02:00
Mathias Vorreiter Pedersen
90fe5c5aca C++: Add change-note. 2021-06-22 17:13:07 +02:00
Mathias Vorreiter Pedersen
2e2673aff6 C++: Delete the experimental SqlPqxxTainted query. 2021-06-22 17:13:07 +02:00
Mathias Vorreiter Pedersen
440793b5ff C++: Move the example from the experimental CWE-089 query into a test. 2021-06-22 17:13:06 +02:00
Mathias Vorreiter Pedersen
222cd41aa3 C++: Use the new SQL interface in 'Security.qll' and 'SqlTainted.ql'. 2021-06-22 17:13:06 +02:00
Mathias Vorreiter Pedersen
092fbd60d9 C++: Create a new SQL interface. 2021-06-22 17:13:06 +02:00
mr-sherman
ec48d0ac29 Merge remote-tracking branch 'upstream/main' into service-stack-remote-sink
merging from main because it fell way behind.
2021-05-28 10:30:29 -04:00
mr-sherman
bf2d7b3a16 Added IRestClientAsync methods to external location sink. Removed import from
Remote.qll, as it is un-necessary now.
2021-03-29 14:37:51 -04:00
mr-sherman
13997caa32 feedback from code review 2021-03-26 16:29:14 -04:00
mr-sherman
3e889c398e updated document formatting 2021-03-23 10:09:30 -04:00
mr-sherman
858c0e67a1 added support for remote flow sinks in the form of parameters to the function
ServiceStack.IRestClient.Get()
2021-03-22 19:27:49 -04:00
jorgectf
957b3e1e85 Precision warn 2021-03-18 20:39:53 +01:00
jorgectf
3ce0a9c8c0 Move to experimental folder 2021-03-18 20:20:04 +01:00
jorgectf
7de9214c99 Upload LDAP Insecure authentication query and tests 2021-03-18 17:41:34 +01:00
yo-h
402ed04189 Merge pull request #4844 from johnlugton/servicestack
Add provisional support for ServiceStack framework to feature branch
2020-12-18 16:24:27 -05:00
John Lugton
059d6b0e0f Fix warning in ServiceStack.qll 2020-12-18 08:34:06 -08:00
John Lugton
563dc62c33 Improve qldoc for ServiceStack.qll 2020-12-18 08:23:27 -08:00
John Lugton
3f1f83f667 remove experimental 2020-12-17 16:24:52 -08:00
John Lugton
6d5f9035e6 Minor fixes to XSS:
Only want returns in request methods
Also care about non-string 1st args to HttpResult e.g. streams
2020-12-17 16:17:26 -08:00
John Lugton
7d47bffd53 Tidy up ServiceStack.qll
Use fully qualified names for classes
Make util predicate private
Make naming more consistent with rest of ql libs
2020-12-17 16:17:26 -08:00
Chelsea Boling
d4acccb13c Update sink 2020-12-17 16:17:26 -08:00
Chelsea Boling
0a7e4b6840 Update sink based on feedback 2020-12-17 16:17:26 -08:00
Chelsea Boling
4e0f3a30ee Update sink based on feedback 2020-12-17 16:17:25 -08:00
Chelsea Boling
ba46eaa143 Refactor sink 2020-12-17 16:17:25 -08:00
Chelsea Boling
3c493511e9 Update file 2020-12-17 16:17:25 -08:00
Chelsea Boling
12e8107492 Add example 2020-12-17 16:17:25 -08:00
Chelsea Boling
5c7dedffb3 Update sinks 2020-12-17 16:17:25 -08:00
Chelsea Boling
71a08c3237 Update servicestack lib 2020-12-17 16:17:25 -08:00
John Lugton
d408ae7e10 Split ServiceStack into modules and incorporate into main lib 2020-12-17 16:17:25 -08:00
John Lugton
386eb2d56b move ServiceStack out of microsoft 2020-12-17 16:17:25 -08:00
Chelsea Boling
a2615339f7 Delete ServiceStack.qll 2020-12-17 16:17:24 -08:00
Chelsea Boling
cae6f91729 Create ServiceStack.qll 2020-12-17 16:17:24 -08:00
Chelsea Boling
dbe0170249 Add files via upload 2020-12-17 16:17:24 -08:00
Chelsea Boling
188dbde2d6 Create SQLInjection.ql 2020-12-17 16:17:24 -08:00
Chelsea Boling
96d11b7966 Create ServiceStack.qll 2020-12-17 16:17:24 -08:00
8329 changed files with 117823 additions and 602247 deletions

3
.gitattributes vendored
View File

@@ -48,3 +48,6 @@
*.gif -text
*.dll -text
*.pdb -text
java/ql/test/stubs/**/*.java linguist-generated=true
java/ql/test/experimental/stubs/**/*.java linguist-generated=true

View File

@@ -11,6 +11,8 @@ on:
- 'rc/*'
paths:
- 'csharp/**'
- '.github/codeql/**'
- '.github/workflows/codeql-analysis.yml'
schedule:
- cron: '0 9 * * 1'
@@ -38,8 +40,8 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@main
#- name: Autobuild
# uses: github/codeql-action/autobuild@main
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
@@ -48,9 +50,8 @@ jobs:
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- run: |
dotnet build csharp
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@main

View File

@@ -8,7 +8,7 @@ on:
jobs:
update:
name: Update framework coverage report
if: github.event.repository.fork == false
if: github.repository == 'github/codeql'
runs-on: ubuntu-latest
steps:

View File

@@ -4,8 +4,8 @@ This open source repository contains the standard CodeQL libraries and queries t
## How do I learn CodeQL and run queries?
There is [extensive documentation](https://help.semmle.com/QL/learn-ql/) on getting started with writing CodeQL.
You can use the [interactive query console](https://lgtm.com/help/lgtm/using-query-console) on LGTM.com or the [CodeQL for Visual Studio Code](https://help.semmle.com/codeql/codeql-for-vscode.html) extension to try out your queries on any open source project that's currently being analyzed.
There is [extensive documentation](https://codeql.github.com/docs/) on getting started with writing CodeQL.
You can use the [interactive query console](https://lgtm.com/help/lgtm/using-query-console) on LGTM.com or the [CodeQL for Visual Studio Code](https://codeql.github.com/docs/codeql-for-visual-studio-code/) extension to try out your queries on any open source project that's currently being analyzed.
## Contributing

View File

@@ -462,4 +462,4 @@
"javascript/ql/lib/semmle/javascript/security/performance/SuperlinearBackTracking.qll",
"python/ql/lib/semmle/python/security/performance/SuperlinearBackTracking.qll"
]
}
}

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* The 'Uncontrolled data in SQL query' (cpp/sql-injection) query now supports the `libpqxx` library.

View File

@@ -0,0 +1,4 @@
lgtm,codescanning
* The `SimpleRangeAnalysis` library includes information from the
immediate guard for determining the upper bound of a stack
variable for improved accuracy.

View File

@@ -0,0 +1,4 @@
lgtm,codescanning
* The `memberMayBeVarSize` predicate considers more fields to be variable size.
As a result, the "Static buffer overflow" query (cpp/static-buffer-overflow)
produces fewer false positives.

View File

@@ -0,0 +1,3 @@
lgtm,codescanning
* Increase precision to high for the "Static buffer overflow" query
(`cpp/static-buffer-overflow`). This means the query is run and displayed by default on Code Scanning and LGTM.

View File

@@ -1,3 +1,4 @@
name: codeql-cpp-examples
version: 0.0.0
libraryPathDependencies: codeql/cpp-all
name: codeql/cpp-examples
version: 0.0.2
dependencies:
codeql/cpp-all: "*"

View File

@@ -3,3 +3,5 @@ version: 0.0.2
dbscheme: semmlecode.cpp.dbscheme
extractor: cpp
library: true
dependencies:
codeql/cpp-upgrades: 0.0.2

View File

@@ -171,7 +171,7 @@ class Container extends Locatable, @container {
* To get the full path, use `getAbsolutePath`.
*/
class Folder extends Container, @folder {
override string getAbsolutePath() { folders(underlyingElement(this), result, _) }
override string getAbsolutePath() { folders(underlyingElement(this), result) }
override Location getLocation() {
result.getContainer() = this and
@@ -190,7 +190,7 @@ class Folder extends Container, @folder {
* DEPRECATED: use `getAbsolutePath` instead.
* Gets the name of this folder.
*/
deprecated string getName() { folders(underlyingElement(this), result, _) }
deprecated string getName() { folders(underlyingElement(this), result) }
/**
* DEPRECATED: use `getAbsolutePath` instead.
@@ -208,17 +208,7 @@ class Folder extends Container, @folder {
* DEPRECATED: use `getBaseName` instead.
* Gets the last part of the folder name.
*/
deprecated string getShortName() {
exists(string longnameRaw, string longname |
folders(underlyingElement(this), _, longnameRaw) and
longname = longnameRaw.replaceAll("\\", "/")
|
exists(int index |
result = longname.splitAt("/", index) and
not exists(longname.splitAt("/", index + 1))
)
)
}
deprecated string getShortName() { result = this.getBaseName() }
/**
* DEPRECATED: use `getParentContainer` instead.
@@ -242,7 +232,7 @@ class Folder extends Container, @folder {
* `getStem` and `getExtension`. To get the full path, use `getAbsolutePath`.
*/
class File extends Container, @file {
override string getAbsolutePath() { files(underlyingElement(this), result, _, _, _) }
override string getAbsolutePath() { files(underlyingElement(this), result) }
override string toString() { result = Container.super.toString() }
@@ -336,7 +326,13 @@ class File extends Container, @file {
* for example, for "file.tar.gz", this predicate will have the result
* "tar.gz", while `getExtension` will have the result "gz".
*/
string getExtensions() { files(underlyingElement(this), _, _, result, _) }
string getExtensions() {
exists(string name, int firstDotPos |
name = this.getBaseName() and
firstDotPos = min([name.indexOf("."), name.length() - 1]) and
result = name.suffix(firstDotPos + 1)
)
}
/**
* Gets the short name of this file, that is, the prefix of its base name up
@@ -351,7 +347,16 @@ class File extends Container, @file {
* for example, for "file.tar.gz", this predicate will have the result
* "file", while `getStem` will have the result "file.tar".
*/
string getShortName() { files(underlyingElement(this), _, result, _, _) }
string getShortName() {
exists(string name, int firstDotPos |
name = this.getBaseName() and
firstDotPos = min([name.indexOf("."), name.length()]) and
result = name.prefix(firstDotPos)
)
or
this.getAbsolutePath() = "" and
result = ""
}
}
/**

View File

@@ -2,53 +2,19 @@ import cpp
import semmle.code.cpp.dataflow.DataFlow
/**
* Holds if `v` is a member variable of `c` that looks like it might be variable sized in practice. For
* example:
* Holds if `v` is a member variable of `c` that looks like it might be variable sized
* in practice. For example:
* ```
* struct myStruct { // c
* int amount;
* char data[1]; // v
* };
* ```
* This requires that `v` is an array of size 0 or 1, and `v` is the last member of `c`. In addition,
* there must be at least one instance where a `c` pointer is allocated with additional space. For
* example, holds for `c` if it occurs as
* ```
* malloc(sizeof(c) + 100 * sizeof(char))
* ```
* but not if it only ever occurs as
* ```
* malloc(sizeof(c))
* ```
* This requires that `v` is an array of size 0 or 1.
*/
predicate memberMayBeVarSize(Class c, MemberVariable v) {
exists(int i |
// `v` is the last field in `c`
i = max(int j | c.getCanonicalMember(j) instanceof Field | j) and
v = c.getCanonicalMember(i) and
// v is an array of size at most 1
v.getUnspecifiedType().(ArrayType).getArraySize() <= 1
) and
(
exists(SizeofOperator so |
// `sizeof(c)` is taken
so.(SizeofTypeOperator).getTypeOperand().getUnspecifiedType() = c or
so.(SizeofExprOperator).getExprOperand().getUnspecifiedType() = c
|
// arithmetic is performed on the result
so.getParent*() instanceof AddExpr
)
or
exists(AddressOfExpr aoe |
// `&(c.v)` is taken
aoe.getAddressable() = v
)
or
exists(BuiltInOperationBuiltInOffsetOf oo |
// `offsetof(c, v)` using a builtin
oo.getAChild().(VariableAccess).getTarget() = v
)
)
c = v.getDeclaringType() and
v.getUnspecifiedType().(ArrayType).getArraySize() <= 1
}
/**

View File

@@ -93,6 +93,15 @@ predicate variableMustBeNullTerminated(VariableAccess va) {
fc.getArgument(i) = va
)
or
// String argument to a formatting function (such as `printf`)
exists(int n, FormatLiteral fl |
fc.(FormattingFunctionCall).getConversionArgument(n) = va and
fl = fc.(FormattingFunctionCall).getFormat() and
fl.getConversionType(n) instanceof PointerType and // `%s`, `%ws` etc
not fl.getConversionType(n) instanceof VoidPointerType and // exclude: `%p`
not fl.hasPrecision(n) // exclude: `%.*s`
)
or
// Call to a wrapper function that requires null termination
// (not itself adding a null terminator)
exists(Function wrapper, int i, Parameter p, VariableAccess use |

View File

@@ -923,28 +923,29 @@ private module Stage2 {
ApOption apSome(Ap ap) { result = TBooleanSome(ap) }
class Cc = boolean;
class Cc = CallContext;
class CcCall extends Cc {
CcCall() { this = true }
class CcCall = CallContextCall;
/** Holds if this call context may be `call`. */
predicate matchesCall(DataFlowCall call) { any() }
}
class CcNoCall = CallContextNoCall;
class CcNoCall extends Cc {
CcNoCall() { this = false }
}
Cc ccNone() { result = false }
Cc ccNone() { result instanceof CallContextAny }
private class LocalCc = Unit;
bindingset[call, c, outercc]
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
checkCallContextCall(outercc, call, c) and
if recordDataFlowCallSiteDispatch(call, c)
then result = TSpecificCall(call)
else result = TSomeCall()
}
bindingset[call, c, innercc]
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
checkCallContextReturn(innercc, c, call) and
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
}
bindingset[node, cc, config]
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
@@ -1172,7 +1173,8 @@ private module Stage2 {
fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap,
pragma[only_bind_into](config)) and
fwdFlowOutFromArg(call, out, argAp0, ap, config) and
fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0,
fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc),
pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0),
pragma[only_bind_into](config))
)
}
@@ -1860,7 +1862,8 @@ private module Stage3 {
fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap,
pragma[only_bind_into](config)) and
fwdFlowOutFromArg(call, out, argAp0, ap, config) and
fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0,
fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc),
pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0),
pragma[only_bind_into](config))
)
}
@@ -2117,7 +2120,7 @@ private module Stage3 {
private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) {
exists(AccessPathFront apf |
Stage3::revFlow(node, true, _, apf, config) and
Stage3::fwdFlow(node, true, TAccessPathFrontSome(argApf), apf, config)
Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config)
)
}
@@ -2618,7 +2621,8 @@ private module Stage4 {
fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap,
pragma[only_bind_into](config)) and
fwdFlowOutFromArg(call, out, argAp0, ap, config) and
fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0,
fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc),
pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0),
pragma[only_bind_into](config))
)
}
@@ -3258,24 +3262,16 @@ class PathNode extends TPathNode {
/** Gets the associated configuration. */
Configuration getConfiguration() { none() }
private predicate isHidden() {
hiddenNode(this.(PathNodeImpl).getNodeEx().asNode()) and
not this.isSource() and
not this instanceof PathNodeSink
or
this.(PathNodeImpl).getNodeEx() instanceof TNodeImplicitRead
}
private PathNode getASuccessorIfHidden() {
this.isHidden() and
this.(PathNodeImpl).isHidden() and
result = this.(PathNodeImpl).getASuccessorImpl()
}
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() {
result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and
not this.isHidden() and
not result.isHidden()
not this.(PathNodeImpl).isHidden() and
not result.(PathNodeImpl).isHidden()
}
/** Holds if this node is a source. */
@@ -3287,6 +3283,14 @@ abstract private class PathNodeImpl extends PathNode {
abstract NodeEx getNodeEx();
predicate isHidden() {
hiddenNode(this.getNodeEx().asNode()) and
not this.isSource() and
not this instanceof PathNodeSink
or
this.getNodeEx() instanceof TNodeImplicitRead
}
private string ppAp() {
this instanceof PathNodeSink and result = ""
or
@@ -3313,10 +3317,15 @@ abstract private class PathNodeImpl extends PathNode {
}
/** Holds if `n` can reach a sink. */
private predicate reach(PathNode n) { n instanceof PathNodeSink or reach(n.getASuccessor()) }
private predicate directReach(PathNode n) {
n instanceof PathNodeSink or directReach(n.getASuccessor())
}
/** Holds if `n1.getSucc() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and reach(n2) }
/** Holds if `n` can reach a sink or is used in a subpath. */
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) }
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
@@ -3325,12 +3334,14 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1
*/
module PathGraph {
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
query predicate edges(PathNode a, PathNode b) { pathSucc(a, b) }
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) }
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
reach(n) and key = "semmle.label" and val = n.toString()
}
query predicate subpaths = Subpaths::subpaths/4;
}
/**
@@ -3622,6 +3633,87 @@ private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext c
)
}
private module Subpaths {
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by
* `kind`, `sc`, `apout`, and `innercc`.
*/
pragma[nomagic]
private predicate subpaths01(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
pathIntoCallable(arg, par, _, innercc, sc, _) and
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
unbindConf(arg.getConfiguration()))
}
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by
* `kind`, `sc`, `apout`, and `innercc`.
*/
pragma[nomagic]
private predicate subpaths02(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
subpaths01(arg, par, sc, innercc, kind, out, apout) and
out.asNode() = kind.getAnOutNode(_)
}
pragma[nomagic]
private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() }
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple.
*/
pragma[nomagic]
private predicate subpaths03(
PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout
) {
exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode |
subpaths02(arg, par, sc, innercc, kind, out, apout) and
ret.getNodeEx() = retnode and
kind = retnode.getKind() and
innercc = ret.getCallContext() and
sc = ret.getSummaryCtx() and
ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and
apout = ret.getAp() and
not ret.isHidden()
)
}
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) {
exists(ParamNodeEx p, NodeEx o, AccessPath apout |
pragma[only_bind_into](arg).getASuccessor() = par and
pragma[only_bind_into](arg).getASuccessor() = out and
subpaths03(arg, p, ret, o, apout) and
par.getNodeEx() = p and
out.getNodeEx() = o and
out.getAp() = apout
)
}
/**
* Holds if `n` can reach a return node in a summarized subpath.
*/
predicate retReach(PathNode n) {
subpaths(_, _, n, _)
or
exists(PathNode mid |
retReach(mid) and
n.getASuccessor() = mid and
not subpaths(_, mid, _, _)
)
}
}
/**
* Holds if data can flow (inter-procedurally) from `source` to `sink`.
*

View File

@@ -923,28 +923,29 @@ private module Stage2 {
ApOption apSome(Ap ap) { result = TBooleanSome(ap) }
class Cc = boolean;
class Cc = CallContext;
class CcCall extends Cc {
CcCall() { this = true }
class CcCall = CallContextCall;
/** Holds if this call context may be `call`. */
predicate matchesCall(DataFlowCall call) { any() }
}
class CcNoCall = CallContextNoCall;
class CcNoCall extends Cc {
CcNoCall() { this = false }
}
Cc ccNone() { result = false }
Cc ccNone() { result instanceof CallContextAny }
private class LocalCc = Unit;
bindingset[call, c, outercc]
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
checkCallContextCall(outercc, call, c) and
if recordDataFlowCallSiteDispatch(call, c)
then result = TSpecificCall(call)
else result = TSomeCall()
}
bindingset[call, c, innercc]
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
checkCallContextReturn(innercc, c, call) and
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
}
bindingset[node, cc, config]
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
@@ -1172,7 +1173,8 @@ private module Stage2 {
fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap,
pragma[only_bind_into](config)) and
fwdFlowOutFromArg(call, out, argAp0, ap, config) and
fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0,
fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc),
pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0),
pragma[only_bind_into](config))
)
}
@@ -1860,7 +1862,8 @@ private module Stage3 {
fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap,
pragma[only_bind_into](config)) and
fwdFlowOutFromArg(call, out, argAp0, ap, config) and
fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0,
fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc),
pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0),
pragma[only_bind_into](config))
)
}
@@ -2117,7 +2120,7 @@ private module Stage3 {
private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) {
exists(AccessPathFront apf |
Stage3::revFlow(node, true, _, apf, config) and
Stage3::fwdFlow(node, true, TAccessPathFrontSome(argApf), apf, config)
Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config)
)
}
@@ -2618,7 +2621,8 @@ private module Stage4 {
fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap,
pragma[only_bind_into](config)) and
fwdFlowOutFromArg(call, out, argAp0, ap, config) and
fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0,
fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc),
pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0),
pragma[only_bind_into](config))
)
}
@@ -3258,24 +3262,16 @@ class PathNode extends TPathNode {
/** Gets the associated configuration. */
Configuration getConfiguration() { none() }
private predicate isHidden() {
hiddenNode(this.(PathNodeImpl).getNodeEx().asNode()) and
not this.isSource() and
not this instanceof PathNodeSink
or
this.(PathNodeImpl).getNodeEx() instanceof TNodeImplicitRead
}
private PathNode getASuccessorIfHidden() {
this.isHidden() and
this.(PathNodeImpl).isHidden() and
result = this.(PathNodeImpl).getASuccessorImpl()
}
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() {
result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and
not this.isHidden() and
not result.isHidden()
not this.(PathNodeImpl).isHidden() and
not result.(PathNodeImpl).isHidden()
}
/** Holds if this node is a source. */
@@ -3287,6 +3283,14 @@ abstract private class PathNodeImpl extends PathNode {
abstract NodeEx getNodeEx();
predicate isHidden() {
hiddenNode(this.getNodeEx().asNode()) and
not this.isSource() and
not this instanceof PathNodeSink
or
this.getNodeEx() instanceof TNodeImplicitRead
}
private string ppAp() {
this instanceof PathNodeSink and result = ""
or
@@ -3313,10 +3317,15 @@ abstract private class PathNodeImpl extends PathNode {
}
/** Holds if `n` can reach a sink. */
private predicate reach(PathNode n) { n instanceof PathNodeSink or reach(n.getASuccessor()) }
private predicate directReach(PathNode n) {
n instanceof PathNodeSink or directReach(n.getASuccessor())
}
/** Holds if `n1.getSucc() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and reach(n2) }
/** Holds if `n` can reach a sink or is used in a subpath. */
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) }
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
@@ -3325,12 +3334,14 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1
*/
module PathGraph {
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
query predicate edges(PathNode a, PathNode b) { pathSucc(a, b) }
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) }
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
reach(n) and key = "semmle.label" and val = n.toString()
}
query predicate subpaths = Subpaths::subpaths/4;
}
/**
@@ -3622,6 +3633,87 @@ private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext c
)
}
private module Subpaths {
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by
* `kind`, `sc`, `apout`, and `innercc`.
*/
pragma[nomagic]
private predicate subpaths01(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
pathIntoCallable(arg, par, _, innercc, sc, _) and
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
unbindConf(arg.getConfiguration()))
}
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by
* `kind`, `sc`, `apout`, and `innercc`.
*/
pragma[nomagic]
private predicate subpaths02(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
subpaths01(arg, par, sc, innercc, kind, out, apout) and
out.asNode() = kind.getAnOutNode(_)
}
pragma[nomagic]
private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() }
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple.
*/
pragma[nomagic]
private predicate subpaths03(
PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout
) {
exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode |
subpaths02(arg, par, sc, innercc, kind, out, apout) and
ret.getNodeEx() = retnode and
kind = retnode.getKind() and
innercc = ret.getCallContext() and
sc = ret.getSummaryCtx() and
ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and
apout = ret.getAp() and
not ret.isHidden()
)
}
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) {
exists(ParamNodeEx p, NodeEx o, AccessPath apout |
pragma[only_bind_into](arg).getASuccessor() = par and
pragma[only_bind_into](arg).getASuccessor() = out and
subpaths03(arg, p, ret, o, apout) and
par.getNodeEx() = p and
out.getNodeEx() = o and
out.getAp() = apout
)
}
/**
* Holds if `n` can reach a return node in a summarized subpath.
*/
predicate retReach(PathNode n) {
subpaths(_, _, n, _)
or
exists(PathNode mid |
retReach(mid) and
n.getASuccessor() = mid and
not subpaths(_, mid, _, _)
)
}
}
/**
* Holds if data can flow (inter-procedurally) from `source` to `sink`.
*

View File

@@ -923,28 +923,29 @@ private module Stage2 {
ApOption apSome(Ap ap) { result = TBooleanSome(ap) }
class Cc = boolean;
class Cc = CallContext;
class CcCall extends Cc {
CcCall() { this = true }
class CcCall = CallContextCall;
/** Holds if this call context may be `call`. */
predicate matchesCall(DataFlowCall call) { any() }
}
class CcNoCall = CallContextNoCall;
class CcNoCall extends Cc {
CcNoCall() { this = false }
}
Cc ccNone() { result = false }
Cc ccNone() { result instanceof CallContextAny }
private class LocalCc = Unit;
bindingset[call, c, outercc]
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
checkCallContextCall(outercc, call, c) and
if recordDataFlowCallSiteDispatch(call, c)
then result = TSpecificCall(call)
else result = TSomeCall()
}
bindingset[call, c, innercc]
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
checkCallContextReturn(innercc, c, call) and
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
}
bindingset[node, cc, config]
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
@@ -1172,7 +1173,8 @@ private module Stage2 {
fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap,
pragma[only_bind_into](config)) and
fwdFlowOutFromArg(call, out, argAp0, ap, config) and
fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0,
fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc),
pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0),
pragma[only_bind_into](config))
)
}
@@ -1860,7 +1862,8 @@ private module Stage3 {
fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap,
pragma[only_bind_into](config)) and
fwdFlowOutFromArg(call, out, argAp0, ap, config) and
fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0,
fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc),
pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0),
pragma[only_bind_into](config))
)
}
@@ -2117,7 +2120,7 @@ private module Stage3 {
private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) {
exists(AccessPathFront apf |
Stage3::revFlow(node, true, _, apf, config) and
Stage3::fwdFlow(node, true, TAccessPathFrontSome(argApf), apf, config)
Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config)
)
}
@@ -2618,7 +2621,8 @@ private module Stage4 {
fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap,
pragma[only_bind_into](config)) and
fwdFlowOutFromArg(call, out, argAp0, ap, config) and
fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0,
fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc),
pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0),
pragma[only_bind_into](config))
)
}
@@ -3258,24 +3262,16 @@ class PathNode extends TPathNode {
/** Gets the associated configuration. */
Configuration getConfiguration() { none() }
private predicate isHidden() {
hiddenNode(this.(PathNodeImpl).getNodeEx().asNode()) and
not this.isSource() and
not this instanceof PathNodeSink
or
this.(PathNodeImpl).getNodeEx() instanceof TNodeImplicitRead
}
private PathNode getASuccessorIfHidden() {
this.isHidden() and
this.(PathNodeImpl).isHidden() and
result = this.(PathNodeImpl).getASuccessorImpl()
}
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() {
result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and
not this.isHidden() and
not result.isHidden()
not this.(PathNodeImpl).isHidden() and
not result.(PathNodeImpl).isHidden()
}
/** Holds if this node is a source. */
@@ -3287,6 +3283,14 @@ abstract private class PathNodeImpl extends PathNode {
abstract NodeEx getNodeEx();
predicate isHidden() {
hiddenNode(this.getNodeEx().asNode()) and
not this.isSource() and
not this instanceof PathNodeSink
or
this.getNodeEx() instanceof TNodeImplicitRead
}
private string ppAp() {
this instanceof PathNodeSink and result = ""
or
@@ -3313,10 +3317,15 @@ abstract private class PathNodeImpl extends PathNode {
}
/** Holds if `n` can reach a sink. */
private predicate reach(PathNode n) { n instanceof PathNodeSink or reach(n.getASuccessor()) }
private predicate directReach(PathNode n) {
n instanceof PathNodeSink or directReach(n.getASuccessor())
}
/** Holds if `n1.getSucc() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and reach(n2) }
/** Holds if `n` can reach a sink or is used in a subpath. */
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) }
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
@@ -3325,12 +3334,14 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1
*/
module PathGraph {
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
query predicate edges(PathNode a, PathNode b) { pathSucc(a, b) }
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) }
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
reach(n) and key = "semmle.label" and val = n.toString()
}
query predicate subpaths = Subpaths::subpaths/4;
}
/**
@@ -3622,6 +3633,87 @@ private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext c
)
}
private module Subpaths {
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by
* `kind`, `sc`, `apout`, and `innercc`.
*/
pragma[nomagic]
private predicate subpaths01(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
pathIntoCallable(arg, par, _, innercc, sc, _) and
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
unbindConf(arg.getConfiguration()))
}
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by
* `kind`, `sc`, `apout`, and `innercc`.
*/
pragma[nomagic]
private predicate subpaths02(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
subpaths01(arg, par, sc, innercc, kind, out, apout) and
out.asNode() = kind.getAnOutNode(_)
}
pragma[nomagic]
private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() }
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple.
*/
pragma[nomagic]
private predicate subpaths03(
PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout
) {
exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode |
subpaths02(arg, par, sc, innercc, kind, out, apout) and
ret.getNodeEx() = retnode and
kind = retnode.getKind() and
innercc = ret.getCallContext() and
sc = ret.getSummaryCtx() and
ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and
apout = ret.getAp() and
not ret.isHidden()
)
}
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) {
exists(ParamNodeEx p, NodeEx o, AccessPath apout |
pragma[only_bind_into](arg).getASuccessor() = par and
pragma[only_bind_into](arg).getASuccessor() = out and
subpaths03(arg, p, ret, o, apout) and
par.getNodeEx() = p and
out.getNodeEx() = o and
out.getAp() = apout
)
}
/**
* Holds if `n` can reach a return node in a summarized subpath.
*/
predicate retReach(PathNode n) {
subpaths(_, _, n, _)
or
exists(PathNode mid |
retReach(mid) and
n.getASuccessor() = mid and
not subpaths(_, mid, _, _)
)
}
}
/**
* Holds if data can flow (inter-procedurally) from `source` to `sink`.
*

View File

@@ -923,28 +923,29 @@ private module Stage2 {
ApOption apSome(Ap ap) { result = TBooleanSome(ap) }
class Cc = boolean;
class Cc = CallContext;
class CcCall extends Cc {
CcCall() { this = true }
class CcCall = CallContextCall;
/** Holds if this call context may be `call`. */
predicate matchesCall(DataFlowCall call) { any() }
}
class CcNoCall = CallContextNoCall;
class CcNoCall extends Cc {
CcNoCall() { this = false }
}
Cc ccNone() { result = false }
Cc ccNone() { result instanceof CallContextAny }
private class LocalCc = Unit;
bindingset[call, c, outercc]
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
checkCallContextCall(outercc, call, c) and
if recordDataFlowCallSiteDispatch(call, c)
then result = TSpecificCall(call)
else result = TSomeCall()
}
bindingset[call, c, innercc]
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
checkCallContextReturn(innercc, c, call) and
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
}
bindingset[node, cc, config]
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
@@ -1172,7 +1173,8 @@ private module Stage2 {
fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap,
pragma[only_bind_into](config)) and
fwdFlowOutFromArg(call, out, argAp0, ap, config) and
fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0,
fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc),
pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0),
pragma[only_bind_into](config))
)
}
@@ -1860,7 +1862,8 @@ private module Stage3 {
fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap,
pragma[only_bind_into](config)) and
fwdFlowOutFromArg(call, out, argAp0, ap, config) and
fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0,
fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc),
pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0),
pragma[only_bind_into](config))
)
}
@@ -2117,7 +2120,7 @@ private module Stage3 {
private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) {
exists(AccessPathFront apf |
Stage3::revFlow(node, true, _, apf, config) and
Stage3::fwdFlow(node, true, TAccessPathFrontSome(argApf), apf, config)
Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config)
)
}
@@ -2618,7 +2621,8 @@ private module Stage4 {
fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap,
pragma[only_bind_into](config)) and
fwdFlowOutFromArg(call, out, argAp0, ap, config) and
fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0,
fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc),
pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0),
pragma[only_bind_into](config))
)
}
@@ -3258,24 +3262,16 @@ class PathNode extends TPathNode {
/** Gets the associated configuration. */
Configuration getConfiguration() { none() }
private predicate isHidden() {
hiddenNode(this.(PathNodeImpl).getNodeEx().asNode()) and
not this.isSource() and
not this instanceof PathNodeSink
or
this.(PathNodeImpl).getNodeEx() instanceof TNodeImplicitRead
}
private PathNode getASuccessorIfHidden() {
this.isHidden() and
this.(PathNodeImpl).isHidden() and
result = this.(PathNodeImpl).getASuccessorImpl()
}
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() {
result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and
not this.isHidden() and
not result.isHidden()
not this.(PathNodeImpl).isHidden() and
not result.(PathNodeImpl).isHidden()
}
/** Holds if this node is a source. */
@@ -3287,6 +3283,14 @@ abstract private class PathNodeImpl extends PathNode {
abstract NodeEx getNodeEx();
predicate isHidden() {
hiddenNode(this.getNodeEx().asNode()) and
not this.isSource() and
not this instanceof PathNodeSink
or
this.getNodeEx() instanceof TNodeImplicitRead
}
private string ppAp() {
this instanceof PathNodeSink and result = ""
or
@@ -3313,10 +3317,15 @@ abstract private class PathNodeImpl extends PathNode {
}
/** Holds if `n` can reach a sink. */
private predicate reach(PathNode n) { n instanceof PathNodeSink or reach(n.getASuccessor()) }
private predicate directReach(PathNode n) {
n instanceof PathNodeSink or directReach(n.getASuccessor())
}
/** Holds if `n1.getSucc() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and reach(n2) }
/** Holds if `n` can reach a sink or is used in a subpath. */
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) }
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
@@ -3325,12 +3334,14 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1
*/
module PathGraph {
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
query predicate edges(PathNode a, PathNode b) { pathSucc(a, b) }
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) }
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
reach(n) and key = "semmle.label" and val = n.toString()
}
query predicate subpaths = Subpaths::subpaths/4;
}
/**
@@ -3622,6 +3633,87 @@ private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext c
)
}
private module Subpaths {
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by
* `kind`, `sc`, `apout`, and `innercc`.
*/
pragma[nomagic]
private predicate subpaths01(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
pathIntoCallable(arg, par, _, innercc, sc, _) and
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
unbindConf(arg.getConfiguration()))
}
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by
* `kind`, `sc`, `apout`, and `innercc`.
*/
pragma[nomagic]
private predicate subpaths02(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
subpaths01(arg, par, sc, innercc, kind, out, apout) and
out.asNode() = kind.getAnOutNode(_)
}
pragma[nomagic]
private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() }
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple.
*/
pragma[nomagic]
private predicate subpaths03(
PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout
) {
exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode |
subpaths02(arg, par, sc, innercc, kind, out, apout) and
ret.getNodeEx() = retnode and
kind = retnode.getKind() and
innercc = ret.getCallContext() and
sc = ret.getSummaryCtx() and
ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and
apout = ret.getAp() and
not ret.isHidden()
)
}
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) {
exists(ParamNodeEx p, NodeEx o, AccessPath apout |
pragma[only_bind_into](arg).getASuccessor() = par and
pragma[only_bind_into](arg).getASuccessor() = out and
subpaths03(arg, p, ret, o, apout) and
par.getNodeEx() = p and
out.getNodeEx() = o and
out.getAp() = apout
)
}
/**
* Holds if `n` can reach a return node in a summarized subpath.
*/
predicate retReach(PathNode n) {
subpaths(_, _, n, _)
or
exists(PathNode mid |
retReach(mid) and
n.getASuccessor() = mid and
not subpaths(_, mid, _, _)
)
}
}
/**
* Holds if data can flow (inter-procedurally) from `source` to `sink`.
*

View File

@@ -786,13 +786,18 @@ private module Cached {
}
/**
* Holds if the call context `call` either improves virtual dispatch in
* `callable` or if it allows us to prune unreachable nodes in `callable`.
* Holds if the call context `call` improves virtual dispatch in `callable`.
*/
cached
predicate recordDataFlowCallSite(DataFlowCall call, DataFlowCallable callable) {
predicate recordDataFlowCallSiteDispatch(DataFlowCall call, DataFlowCallable callable) {
reducedViableImplInCallContext(_, callable, call)
or
}
/**
* Holds if the call context `call` allows us to prune unreachable nodes in `callable`.
*/
cached
predicate recordDataFlowCallSiteUnreachable(DataFlowCall call, DataFlowCallable callable) {
exists(Node n | getNodeEnclosingCallable(n) = callable | isUnreachableInCallCached(n, call))
}
@@ -846,6 +851,15 @@ private module Cached {
TAccessPathFrontSome(AccessPathFront apf)
}
/**
* Holds if the call context `call` either improves virtual dispatch in
* `callable` or if it allows us to prune unreachable nodes in `callable`.
*/
predicate recordDataFlowCallSite(DataFlowCall call, DataFlowCallable callable) {
recordDataFlowCallSiteDispatch(call, callable) or
recordDataFlowCallSiteUnreachable(call, callable)
}
/**
* A `Node` at which a cast can occur such that the type should be checked.
*/

View File

@@ -923,28 +923,29 @@ private module Stage2 {
ApOption apSome(Ap ap) { result = TBooleanSome(ap) }
class Cc = boolean;
class Cc = CallContext;
class CcCall extends Cc {
CcCall() { this = true }
class CcCall = CallContextCall;
/** Holds if this call context may be `call`. */
predicate matchesCall(DataFlowCall call) { any() }
}
class CcNoCall = CallContextNoCall;
class CcNoCall extends Cc {
CcNoCall() { this = false }
}
Cc ccNone() { result = false }
Cc ccNone() { result instanceof CallContextAny }
private class LocalCc = Unit;
bindingset[call, c, outercc]
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
checkCallContextCall(outercc, call, c) and
if recordDataFlowCallSiteDispatch(call, c)
then result = TSpecificCall(call)
else result = TSomeCall()
}
bindingset[call, c, innercc]
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
checkCallContextReturn(innercc, c, call) and
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
}
bindingset[node, cc, config]
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
@@ -1172,7 +1173,8 @@ private module Stage2 {
fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap,
pragma[only_bind_into](config)) and
fwdFlowOutFromArg(call, out, argAp0, ap, config) and
fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0,
fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc),
pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0),
pragma[only_bind_into](config))
)
}
@@ -1860,7 +1862,8 @@ private module Stage3 {
fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap,
pragma[only_bind_into](config)) and
fwdFlowOutFromArg(call, out, argAp0, ap, config) and
fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0,
fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc),
pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0),
pragma[only_bind_into](config))
)
}
@@ -2117,7 +2120,7 @@ private module Stage3 {
private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) {
exists(AccessPathFront apf |
Stage3::revFlow(node, true, _, apf, config) and
Stage3::fwdFlow(node, true, TAccessPathFrontSome(argApf), apf, config)
Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config)
)
}
@@ -2618,7 +2621,8 @@ private module Stage4 {
fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap,
pragma[only_bind_into](config)) and
fwdFlowOutFromArg(call, out, argAp0, ap, config) and
fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0,
fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc),
pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0),
pragma[only_bind_into](config))
)
}
@@ -3258,24 +3262,16 @@ class PathNode extends TPathNode {
/** Gets the associated configuration. */
Configuration getConfiguration() { none() }
private predicate isHidden() {
hiddenNode(this.(PathNodeImpl).getNodeEx().asNode()) and
not this.isSource() and
not this instanceof PathNodeSink
or
this.(PathNodeImpl).getNodeEx() instanceof TNodeImplicitRead
}
private PathNode getASuccessorIfHidden() {
this.isHidden() and
this.(PathNodeImpl).isHidden() and
result = this.(PathNodeImpl).getASuccessorImpl()
}
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() {
result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and
not this.isHidden() and
not result.isHidden()
not this.(PathNodeImpl).isHidden() and
not result.(PathNodeImpl).isHidden()
}
/** Holds if this node is a source. */
@@ -3287,6 +3283,14 @@ abstract private class PathNodeImpl extends PathNode {
abstract NodeEx getNodeEx();
predicate isHidden() {
hiddenNode(this.getNodeEx().asNode()) and
not this.isSource() and
not this instanceof PathNodeSink
or
this.getNodeEx() instanceof TNodeImplicitRead
}
private string ppAp() {
this instanceof PathNodeSink and result = ""
or
@@ -3313,10 +3317,15 @@ abstract private class PathNodeImpl extends PathNode {
}
/** Holds if `n` can reach a sink. */
private predicate reach(PathNode n) { n instanceof PathNodeSink or reach(n.getASuccessor()) }
private predicate directReach(PathNode n) {
n instanceof PathNodeSink or directReach(n.getASuccessor())
}
/** Holds if `n1.getSucc() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and reach(n2) }
/** Holds if `n` can reach a sink or is used in a subpath. */
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) }
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
@@ -3325,12 +3334,14 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1
*/
module PathGraph {
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
query predicate edges(PathNode a, PathNode b) { pathSucc(a, b) }
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) }
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
reach(n) and key = "semmle.label" and val = n.toString()
}
query predicate subpaths = Subpaths::subpaths/4;
}
/**
@@ -3622,6 +3633,87 @@ private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext c
)
}
private module Subpaths {
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by
* `kind`, `sc`, `apout`, and `innercc`.
*/
pragma[nomagic]
private predicate subpaths01(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
pathIntoCallable(arg, par, _, innercc, sc, _) and
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
unbindConf(arg.getConfiguration()))
}
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by
* `kind`, `sc`, `apout`, and `innercc`.
*/
pragma[nomagic]
private predicate subpaths02(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
subpaths01(arg, par, sc, innercc, kind, out, apout) and
out.asNode() = kind.getAnOutNode(_)
}
pragma[nomagic]
private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() }
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple.
*/
pragma[nomagic]
private predicate subpaths03(
PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout
) {
exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode |
subpaths02(arg, par, sc, innercc, kind, out, apout) and
ret.getNodeEx() = retnode and
kind = retnode.getKind() and
innercc = ret.getCallContext() and
sc = ret.getSummaryCtx() and
ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and
apout = ret.getAp() and
not ret.isHidden()
)
}
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) {
exists(ParamNodeEx p, NodeEx o, AccessPath apout |
pragma[only_bind_into](arg).getASuccessor() = par and
pragma[only_bind_into](arg).getASuccessor() = out and
subpaths03(arg, p, ret, o, apout) and
par.getNodeEx() = p and
out.getNodeEx() = o and
out.getAp() = apout
)
}
/**
* Holds if `n` can reach a return node in a summarized subpath.
*/
predicate retReach(PathNode n) {
subpaths(_, _, n, _)
or
exists(PathNode mid |
retReach(mid) and
n.getASuccessor() = mid and
not subpaths(_, mid, _, _)
)
}
}
/**
* Holds if data can flow (inter-procedurally) from `source` to `sink`.
*

View File

@@ -9,7 +9,7 @@ import semmle.code.cpp.Enum
private import semmle.code.cpp.dataflow.EscapesTree
/**
* A C/C++ access expression. This refers to a function, variable, or enum constant.
* A C/C++ access expression. This refers to a function (excluding function references in function call expressions), variable, or enum constant.
*/
class Access extends Expr, NameQualifiableElement, @access {
// As `@access` is a union type containing `@routineexpr` (which describes function accesses
@@ -350,6 +350,15 @@ class PointerToFieldLiteral extends ImplicitThisFieldAccess {
* int (*myFunctionPointer)(int) = &myFunctionTarget;
* }
* ```
* This excludes function accesses in function call expressions.
* For example the access `myFunctionTarget` in `myFunction` in the following code:
* ```
* int myFunctionTarget(int);
*
* void myFunction() {
* myFunctionTarget(1);
* }
* ```
*/
class FunctionAccess extends Access, @routineexpr {
FunctionAccess() { not iscall(underlyingElement(this), _) }

View File

@@ -550,6 +550,39 @@ module TaintedWithPath {
)
}
/**
* Holds if there is flow from `arg` to `out` across a call that can by summarized by the flow
* from `par` to `ret` within it, in the graph of data flow path explanations.
*/
query predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out) {
DataFlow3::PathGraph::subpaths(arg.(WrapPathNode).inner(), par.(WrapPathNode).inner(),
ret.(WrapPathNode).inner(), out.(WrapPathNode).inner())
or
// To avoid showing trivial-looking steps, we _replace_ the last node instead
// of adding an edge out of it.
exists(WrapPathNode sinkNode |
DataFlow3::PathGraph::subpaths(arg.(WrapPathNode).inner(), par.(WrapPathNode).inner(),
ret.(WrapPathNode).inner(), sinkNode.inner()) and
out.(FinalPathNode).inner() = adjustedSink(sinkNode.inner().getNode())
)
or
// Same for the first node
exists(WrapPathNode sourceNode |
DataFlow3::PathGraph::subpaths(sourceNode.inner(), par.(WrapPathNode).inner(),
ret.(WrapPathNode).inner(), out.(WrapPathNode).inner()) and
sourceNode.inner().getNode() = getNodeForExpr(arg.(InitialPathNode).inner())
)
or
// Finally, handle the case where the path goes directly from a source to a
// sink, meaning that they both need to be translated.
exists(WrapPathNode sinkNode, WrapPathNode sourceNode |
DataFlow3::PathGraph::subpaths(sourceNode.inner(), par.(WrapPathNode).inner(),
ret.(WrapPathNode).inner(), sinkNode.inner()) and
sourceNode.inner().getNode() = getNodeForExpr(arg.(InitialPathNode).inner()) and
out.(FinalPathNode).inner() = adjustedSink(sinkNode.inner().getNode())
)
}
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
key = "semmle.label" and val = n.toString()

View File

@@ -923,28 +923,29 @@ private module Stage2 {
ApOption apSome(Ap ap) { result = TBooleanSome(ap) }
class Cc = boolean;
class Cc = CallContext;
class CcCall extends Cc {
CcCall() { this = true }
class CcCall = CallContextCall;
/** Holds if this call context may be `call`. */
predicate matchesCall(DataFlowCall call) { any() }
}
class CcNoCall = CallContextNoCall;
class CcNoCall extends Cc {
CcNoCall() { this = false }
}
Cc ccNone() { result = false }
Cc ccNone() { result instanceof CallContextAny }
private class LocalCc = Unit;
bindingset[call, c, outercc]
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
checkCallContextCall(outercc, call, c) and
if recordDataFlowCallSiteDispatch(call, c)
then result = TSpecificCall(call)
else result = TSomeCall()
}
bindingset[call, c, innercc]
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
checkCallContextReturn(innercc, c, call) and
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
}
bindingset[node, cc, config]
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
@@ -1172,7 +1173,8 @@ private module Stage2 {
fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap,
pragma[only_bind_into](config)) and
fwdFlowOutFromArg(call, out, argAp0, ap, config) and
fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0,
fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc),
pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0),
pragma[only_bind_into](config))
)
}
@@ -1860,7 +1862,8 @@ private module Stage3 {
fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap,
pragma[only_bind_into](config)) and
fwdFlowOutFromArg(call, out, argAp0, ap, config) and
fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0,
fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc),
pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0),
pragma[only_bind_into](config))
)
}
@@ -2117,7 +2120,7 @@ private module Stage3 {
private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) {
exists(AccessPathFront apf |
Stage3::revFlow(node, true, _, apf, config) and
Stage3::fwdFlow(node, true, TAccessPathFrontSome(argApf), apf, config)
Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config)
)
}
@@ -2618,7 +2621,8 @@ private module Stage4 {
fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap,
pragma[only_bind_into](config)) and
fwdFlowOutFromArg(call, out, argAp0, ap, config) and
fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0,
fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc),
pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0),
pragma[only_bind_into](config))
)
}
@@ -3258,24 +3262,16 @@ class PathNode extends TPathNode {
/** Gets the associated configuration. */
Configuration getConfiguration() { none() }
private predicate isHidden() {
hiddenNode(this.(PathNodeImpl).getNodeEx().asNode()) and
not this.isSource() and
not this instanceof PathNodeSink
or
this.(PathNodeImpl).getNodeEx() instanceof TNodeImplicitRead
}
private PathNode getASuccessorIfHidden() {
this.isHidden() and
this.(PathNodeImpl).isHidden() and
result = this.(PathNodeImpl).getASuccessorImpl()
}
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() {
result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and
not this.isHidden() and
not result.isHidden()
not this.(PathNodeImpl).isHidden() and
not result.(PathNodeImpl).isHidden()
}
/** Holds if this node is a source. */
@@ -3287,6 +3283,14 @@ abstract private class PathNodeImpl extends PathNode {
abstract NodeEx getNodeEx();
predicate isHidden() {
hiddenNode(this.getNodeEx().asNode()) and
not this.isSource() and
not this instanceof PathNodeSink
or
this.getNodeEx() instanceof TNodeImplicitRead
}
private string ppAp() {
this instanceof PathNodeSink and result = ""
or
@@ -3313,10 +3317,15 @@ abstract private class PathNodeImpl extends PathNode {
}
/** Holds if `n` can reach a sink. */
private predicate reach(PathNode n) { n instanceof PathNodeSink or reach(n.getASuccessor()) }
private predicate directReach(PathNode n) {
n instanceof PathNodeSink or directReach(n.getASuccessor())
}
/** Holds if `n1.getSucc() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and reach(n2) }
/** Holds if `n` can reach a sink or is used in a subpath. */
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) }
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
@@ -3325,12 +3334,14 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1
*/
module PathGraph {
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
query predicate edges(PathNode a, PathNode b) { pathSucc(a, b) }
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) }
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
reach(n) and key = "semmle.label" and val = n.toString()
}
query predicate subpaths = Subpaths::subpaths/4;
}
/**
@@ -3622,6 +3633,87 @@ private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext c
)
}
private module Subpaths {
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by
* `kind`, `sc`, `apout`, and `innercc`.
*/
pragma[nomagic]
private predicate subpaths01(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
pathIntoCallable(arg, par, _, innercc, sc, _) and
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
unbindConf(arg.getConfiguration()))
}
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by
* `kind`, `sc`, `apout`, and `innercc`.
*/
pragma[nomagic]
private predicate subpaths02(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
subpaths01(arg, par, sc, innercc, kind, out, apout) and
out.asNode() = kind.getAnOutNode(_)
}
pragma[nomagic]
private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() }
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple.
*/
pragma[nomagic]
private predicate subpaths03(
PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout
) {
exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode |
subpaths02(arg, par, sc, innercc, kind, out, apout) and
ret.getNodeEx() = retnode and
kind = retnode.getKind() and
innercc = ret.getCallContext() and
sc = ret.getSummaryCtx() and
ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and
apout = ret.getAp() and
not ret.isHidden()
)
}
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) {
exists(ParamNodeEx p, NodeEx o, AccessPath apout |
pragma[only_bind_into](arg).getASuccessor() = par and
pragma[only_bind_into](arg).getASuccessor() = out and
subpaths03(arg, p, ret, o, apout) and
par.getNodeEx() = p and
out.getNodeEx() = o and
out.getAp() = apout
)
}
/**
* Holds if `n` can reach a return node in a summarized subpath.
*/
predicate retReach(PathNode n) {
subpaths(_, _, n, _)
or
exists(PathNode mid |
retReach(mid) and
n.getASuccessor() = mid and
not subpaths(_, mid, _, _)
)
}
}
/**
* Holds if data can flow (inter-procedurally) from `source` to `sink`.
*

View File

@@ -923,28 +923,29 @@ private module Stage2 {
ApOption apSome(Ap ap) { result = TBooleanSome(ap) }
class Cc = boolean;
class Cc = CallContext;
class CcCall extends Cc {
CcCall() { this = true }
class CcCall = CallContextCall;
/** Holds if this call context may be `call`. */
predicate matchesCall(DataFlowCall call) { any() }
}
class CcNoCall = CallContextNoCall;
class CcNoCall extends Cc {
CcNoCall() { this = false }
}
Cc ccNone() { result = false }
Cc ccNone() { result instanceof CallContextAny }
private class LocalCc = Unit;
bindingset[call, c, outercc]
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
checkCallContextCall(outercc, call, c) and
if recordDataFlowCallSiteDispatch(call, c)
then result = TSpecificCall(call)
else result = TSomeCall()
}
bindingset[call, c, innercc]
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
checkCallContextReturn(innercc, c, call) and
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
}
bindingset[node, cc, config]
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
@@ -1172,7 +1173,8 @@ private module Stage2 {
fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap,
pragma[only_bind_into](config)) and
fwdFlowOutFromArg(call, out, argAp0, ap, config) and
fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0,
fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc),
pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0),
pragma[only_bind_into](config))
)
}
@@ -1860,7 +1862,8 @@ private module Stage3 {
fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap,
pragma[only_bind_into](config)) and
fwdFlowOutFromArg(call, out, argAp0, ap, config) and
fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0,
fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc),
pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0),
pragma[only_bind_into](config))
)
}
@@ -2117,7 +2120,7 @@ private module Stage3 {
private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) {
exists(AccessPathFront apf |
Stage3::revFlow(node, true, _, apf, config) and
Stage3::fwdFlow(node, true, TAccessPathFrontSome(argApf), apf, config)
Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config)
)
}
@@ -2618,7 +2621,8 @@ private module Stage4 {
fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap,
pragma[only_bind_into](config)) and
fwdFlowOutFromArg(call, out, argAp0, ap, config) and
fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0,
fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc),
pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0),
pragma[only_bind_into](config))
)
}
@@ -3258,24 +3262,16 @@ class PathNode extends TPathNode {
/** Gets the associated configuration. */
Configuration getConfiguration() { none() }
private predicate isHidden() {
hiddenNode(this.(PathNodeImpl).getNodeEx().asNode()) and
not this.isSource() and
not this instanceof PathNodeSink
or
this.(PathNodeImpl).getNodeEx() instanceof TNodeImplicitRead
}
private PathNode getASuccessorIfHidden() {
this.isHidden() and
this.(PathNodeImpl).isHidden() and
result = this.(PathNodeImpl).getASuccessorImpl()
}
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() {
result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and
not this.isHidden() and
not result.isHidden()
not this.(PathNodeImpl).isHidden() and
not result.(PathNodeImpl).isHidden()
}
/** Holds if this node is a source. */
@@ -3287,6 +3283,14 @@ abstract private class PathNodeImpl extends PathNode {
abstract NodeEx getNodeEx();
predicate isHidden() {
hiddenNode(this.getNodeEx().asNode()) and
not this.isSource() and
not this instanceof PathNodeSink
or
this.getNodeEx() instanceof TNodeImplicitRead
}
private string ppAp() {
this instanceof PathNodeSink and result = ""
or
@@ -3313,10 +3317,15 @@ abstract private class PathNodeImpl extends PathNode {
}
/** Holds if `n` can reach a sink. */
private predicate reach(PathNode n) { n instanceof PathNodeSink or reach(n.getASuccessor()) }
private predicate directReach(PathNode n) {
n instanceof PathNodeSink or directReach(n.getASuccessor())
}
/** Holds if `n1.getSucc() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and reach(n2) }
/** Holds if `n` can reach a sink or is used in a subpath. */
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) }
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
@@ -3325,12 +3334,14 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1
*/
module PathGraph {
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
query predicate edges(PathNode a, PathNode b) { pathSucc(a, b) }
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) }
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
reach(n) and key = "semmle.label" and val = n.toString()
}
query predicate subpaths = Subpaths::subpaths/4;
}
/**
@@ -3622,6 +3633,87 @@ private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext c
)
}
private module Subpaths {
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by
* `kind`, `sc`, `apout`, and `innercc`.
*/
pragma[nomagic]
private predicate subpaths01(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
pathIntoCallable(arg, par, _, innercc, sc, _) and
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
unbindConf(arg.getConfiguration()))
}
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by
* `kind`, `sc`, `apout`, and `innercc`.
*/
pragma[nomagic]
private predicate subpaths02(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
subpaths01(arg, par, sc, innercc, kind, out, apout) and
out.asNode() = kind.getAnOutNode(_)
}
pragma[nomagic]
private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() }
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple.
*/
pragma[nomagic]
private predicate subpaths03(
PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout
) {
exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode |
subpaths02(arg, par, sc, innercc, kind, out, apout) and
ret.getNodeEx() = retnode and
kind = retnode.getKind() and
innercc = ret.getCallContext() and
sc = ret.getSummaryCtx() and
ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and
apout = ret.getAp() and
not ret.isHidden()
)
}
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) {
exists(ParamNodeEx p, NodeEx o, AccessPath apout |
pragma[only_bind_into](arg).getASuccessor() = par and
pragma[only_bind_into](arg).getASuccessor() = out and
subpaths03(arg, p, ret, o, apout) and
par.getNodeEx() = p and
out.getNodeEx() = o and
out.getAp() = apout
)
}
/**
* Holds if `n` can reach a return node in a summarized subpath.
*/
predicate retReach(PathNode n) {
subpaths(_, _, n, _)
or
exists(PathNode mid |
retReach(mid) and
n.getASuccessor() = mid and
not subpaths(_, mid, _, _)
)
}
}
/**
* Holds if data can flow (inter-procedurally) from `source` to `sink`.
*

View File

@@ -923,28 +923,29 @@ private module Stage2 {
ApOption apSome(Ap ap) { result = TBooleanSome(ap) }
class Cc = boolean;
class Cc = CallContext;
class CcCall extends Cc {
CcCall() { this = true }
class CcCall = CallContextCall;
/** Holds if this call context may be `call`. */
predicate matchesCall(DataFlowCall call) { any() }
}
class CcNoCall = CallContextNoCall;
class CcNoCall extends Cc {
CcNoCall() { this = false }
}
Cc ccNone() { result = false }
Cc ccNone() { result instanceof CallContextAny }
private class LocalCc = Unit;
bindingset[call, c, outercc]
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
checkCallContextCall(outercc, call, c) and
if recordDataFlowCallSiteDispatch(call, c)
then result = TSpecificCall(call)
else result = TSomeCall()
}
bindingset[call, c, innercc]
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
checkCallContextReturn(innercc, c, call) and
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
}
bindingset[node, cc, config]
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
@@ -1172,7 +1173,8 @@ private module Stage2 {
fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap,
pragma[only_bind_into](config)) and
fwdFlowOutFromArg(call, out, argAp0, ap, config) and
fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0,
fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc),
pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0),
pragma[only_bind_into](config))
)
}
@@ -1860,7 +1862,8 @@ private module Stage3 {
fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap,
pragma[only_bind_into](config)) and
fwdFlowOutFromArg(call, out, argAp0, ap, config) and
fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0,
fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc),
pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0),
pragma[only_bind_into](config))
)
}
@@ -2117,7 +2120,7 @@ private module Stage3 {
private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) {
exists(AccessPathFront apf |
Stage3::revFlow(node, true, _, apf, config) and
Stage3::fwdFlow(node, true, TAccessPathFrontSome(argApf), apf, config)
Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config)
)
}
@@ -2618,7 +2621,8 @@ private module Stage4 {
fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap,
pragma[only_bind_into](config)) and
fwdFlowOutFromArg(call, out, argAp0, ap, config) and
fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0,
fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc),
pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0),
pragma[only_bind_into](config))
)
}
@@ -3258,24 +3262,16 @@ class PathNode extends TPathNode {
/** Gets the associated configuration. */
Configuration getConfiguration() { none() }
private predicate isHidden() {
hiddenNode(this.(PathNodeImpl).getNodeEx().asNode()) and
not this.isSource() and
not this instanceof PathNodeSink
or
this.(PathNodeImpl).getNodeEx() instanceof TNodeImplicitRead
}
private PathNode getASuccessorIfHidden() {
this.isHidden() and
this.(PathNodeImpl).isHidden() and
result = this.(PathNodeImpl).getASuccessorImpl()
}
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() {
result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and
not this.isHidden() and
not result.isHidden()
not this.(PathNodeImpl).isHidden() and
not result.(PathNodeImpl).isHidden()
}
/** Holds if this node is a source. */
@@ -3287,6 +3283,14 @@ abstract private class PathNodeImpl extends PathNode {
abstract NodeEx getNodeEx();
predicate isHidden() {
hiddenNode(this.getNodeEx().asNode()) and
not this.isSource() and
not this instanceof PathNodeSink
or
this.getNodeEx() instanceof TNodeImplicitRead
}
private string ppAp() {
this instanceof PathNodeSink and result = ""
or
@@ -3313,10 +3317,15 @@ abstract private class PathNodeImpl extends PathNode {
}
/** Holds if `n` can reach a sink. */
private predicate reach(PathNode n) { n instanceof PathNodeSink or reach(n.getASuccessor()) }
private predicate directReach(PathNode n) {
n instanceof PathNodeSink or directReach(n.getASuccessor())
}
/** Holds if `n1.getSucc() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and reach(n2) }
/** Holds if `n` can reach a sink or is used in a subpath. */
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) }
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
@@ -3325,12 +3334,14 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1
*/
module PathGraph {
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
query predicate edges(PathNode a, PathNode b) { pathSucc(a, b) }
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) }
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
reach(n) and key = "semmle.label" and val = n.toString()
}
query predicate subpaths = Subpaths::subpaths/4;
}
/**
@@ -3622,6 +3633,87 @@ private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext c
)
}
private module Subpaths {
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by
* `kind`, `sc`, `apout`, and `innercc`.
*/
pragma[nomagic]
private predicate subpaths01(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
pathIntoCallable(arg, par, _, innercc, sc, _) and
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
unbindConf(arg.getConfiguration()))
}
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by
* `kind`, `sc`, `apout`, and `innercc`.
*/
pragma[nomagic]
private predicate subpaths02(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
subpaths01(arg, par, sc, innercc, kind, out, apout) and
out.asNode() = kind.getAnOutNode(_)
}
pragma[nomagic]
private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() }
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple.
*/
pragma[nomagic]
private predicate subpaths03(
PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout
) {
exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode |
subpaths02(arg, par, sc, innercc, kind, out, apout) and
ret.getNodeEx() = retnode and
kind = retnode.getKind() and
innercc = ret.getCallContext() and
sc = ret.getSummaryCtx() and
ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and
apout = ret.getAp() and
not ret.isHidden()
)
}
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) {
exists(ParamNodeEx p, NodeEx o, AccessPath apout |
pragma[only_bind_into](arg).getASuccessor() = par and
pragma[only_bind_into](arg).getASuccessor() = out and
subpaths03(arg, p, ret, o, apout) and
par.getNodeEx() = p and
out.getNodeEx() = o and
out.getAp() = apout
)
}
/**
* Holds if `n` can reach a return node in a summarized subpath.
*/
predicate retReach(PathNode n) {
subpaths(_, _, n, _)
or
exists(PathNode mid |
retReach(mid) and
n.getASuccessor() = mid and
not subpaths(_, mid, _, _)
)
}
}
/**
* Holds if data can flow (inter-procedurally) from `source` to `sink`.
*

View File

@@ -923,28 +923,29 @@ private module Stage2 {
ApOption apSome(Ap ap) { result = TBooleanSome(ap) }
class Cc = boolean;
class Cc = CallContext;
class CcCall extends Cc {
CcCall() { this = true }
class CcCall = CallContextCall;
/** Holds if this call context may be `call`. */
predicate matchesCall(DataFlowCall call) { any() }
}
class CcNoCall = CallContextNoCall;
class CcNoCall extends Cc {
CcNoCall() { this = false }
}
Cc ccNone() { result = false }
Cc ccNone() { result instanceof CallContextAny }
private class LocalCc = Unit;
bindingset[call, c, outercc]
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
checkCallContextCall(outercc, call, c) and
if recordDataFlowCallSiteDispatch(call, c)
then result = TSpecificCall(call)
else result = TSomeCall()
}
bindingset[call, c, innercc]
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
checkCallContextReturn(innercc, c, call) and
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
}
bindingset[node, cc, config]
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
@@ -1172,7 +1173,8 @@ private module Stage2 {
fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap,
pragma[only_bind_into](config)) and
fwdFlowOutFromArg(call, out, argAp0, ap, config) and
fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0,
fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc),
pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0),
pragma[only_bind_into](config))
)
}
@@ -1860,7 +1862,8 @@ private module Stage3 {
fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap,
pragma[only_bind_into](config)) and
fwdFlowOutFromArg(call, out, argAp0, ap, config) and
fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0,
fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc),
pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0),
pragma[only_bind_into](config))
)
}
@@ -2117,7 +2120,7 @@ private module Stage3 {
private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) {
exists(AccessPathFront apf |
Stage3::revFlow(node, true, _, apf, config) and
Stage3::fwdFlow(node, true, TAccessPathFrontSome(argApf), apf, config)
Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config)
)
}
@@ -2618,7 +2621,8 @@ private module Stage4 {
fwdFlow(out, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), ap,
pragma[only_bind_into](config)) and
fwdFlowOutFromArg(call, out, argAp0, ap, config) and
fwdFlowIsEntered(call, pragma[only_bind_into](cc), pragma[only_bind_into](argAp), argAp0,
fwdFlowIsEntered(pragma[only_bind_into](call), pragma[only_bind_into](cc),
pragma[only_bind_into](argAp), pragma[only_bind_into](argAp0),
pragma[only_bind_into](config))
)
}
@@ -3258,24 +3262,16 @@ class PathNode extends TPathNode {
/** Gets the associated configuration. */
Configuration getConfiguration() { none() }
private predicate isHidden() {
hiddenNode(this.(PathNodeImpl).getNodeEx().asNode()) and
not this.isSource() and
not this instanceof PathNodeSink
or
this.(PathNodeImpl).getNodeEx() instanceof TNodeImplicitRead
}
private PathNode getASuccessorIfHidden() {
this.isHidden() and
this.(PathNodeImpl).isHidden() and
result = this.(PathNodeImpl).getASuccessorImpl()
}
/** Gets a successor of this node, if any. */
final PathNode getASuccessor() {
result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and
not this.isHidden() and
not result.isHidden()
not this.(PathNodeImpl).isHidden() and
not result.(PathNodeImpl).isHidden()
}
/** Holds if this node is a source. */
@@ -3287,6 +3283,14 @@ abstract private class PathNodeImpl extends PathNode {
abstract NodeEx getNodeEx();
predicate isHidden() {
hiddenNode(this.getNodeEx().asNode()) and
not this.isSource() and
not this instanceof PathNodeSink
or
this.getNodeEx() instanceof TNodeImplicitRead
}
private string ppAp() {
this instanceof PathNodeSink and result = ""
or
@@ -3313,10 +3317,15 @@ abstract private class PathNodeImpl extends PathNode {
}
/** Holds if `n` can reach a sink. */
private predicate reach(PathNode n) { n instanceof PathNodeSink or reach(n.getASuccessor()) }
private predicate directReach(PathNode n) {
n instanceof PathNodeSink or directReach(n.getASuccessor())
}
/** Holds if `n1.getSucc() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and reach(n2) }
/** Holds if `n` can reach a sink or is used in a subpath. */
private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) }
/** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */
private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) }
private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2)
@@ -3325,12 +3334,14 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1
*/
module PathGraph {
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
query predicate edges(PathNode a, PathNode b) { pathSucc(a, b) }
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) }
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(PathNode n, string key, string val) {
reach(n) and key = "semmle.label" and val = n.toString()
}
query predicate subpaths = Subpaths::subpaths/4;
}
/**
@@ -3622,6 +3633,87 @@ private predicate pathThroughCallable(PathNodeMid mid, NodeEx out, CallContext c
)
}
private module Subpaths {
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by
* `kind`, `sc`, `apout`, and `innercc`.
*/
pragma[nomagic]
private predicate subpaths01(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
pathIntoCallable(arg, par, _, innercc, sc, _) and
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _,
unbindConf(arg.getConfiguration()))
}
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple and `ret` is determined by
* `kind`, `sc`, `apout`, and `innercc`.
*/
pragma[nomagic]
private predicate subpaths02(
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
NodeEx out, AccessPath apout
) {
subpaths01(arg, par, sc, innercc, kind, out, apout) and
out.asNode() = kind.getAnOutNode(_)
}
pragma[nomagic]
private Configuration getPathNodeConf(PathNode n) { result = n.getConfiguration() }
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple.
*/
pragma[nomagic]
private predicate subpaths03(
PathNode arg, ParamNodeEx par, PathNodeMid ret, NodeEx out, AccessPath apout
) {
exists(SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind, RetNodeEx retnode |
subpaths02(arg, par, sc, innercc, kind, out, apout) and
ret.getNodeEx() = retnode and
kind = retnode.getKind() and
innercc = ret.getCallContext() and
sc = ret.getSummaryCtx() and
ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and
apout = ret.getAp() and
not ret.isHidden()
)
}
/**
* Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
* `ret -> out` is summarized as the edge `arg -> out`.
*/
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) {
exists(ParamNodeEx p, NodeEx o, AccessPath apout |
pragma[only_bind_into](arg).getASuccessor() = par and
pragma[only_bind_into](arg).getASuccessor() = out and
subpaths03(arg, p, ret, o, apout) and
par.getNodeEx() = p and
out.getNodeEx() = o and
out.getAp() = apout
)
}
/**
* Holds if `n` can reach a return node in a summarized subpath.
*/
predicate retReach(PathNode n) {
subpaths(_, _, n, _)
or
exists(PathNode mid |
retReach(mid) and
n.getASuccessor() = mid and
not subpaths(_, mid, _, _)
)
}
}
/**
* Holds if data can flow (inter-procedurally) from `source` to `sink`.
*

View File

@@ -786,13 +786,18 @@ private module Cached {
}
/**
* Holds if the call context `call` either improves virtual dispatch in
* `callable` or if it allows us to prune unreachable nodes in `callable`.
* Holds if the call context `call` improves virtual dispatch in `callable`.
*/
cached
predicate recordDataFlowCallSite(DataFlowCall call, DataFlowCallable callable) {
predicate recordDataFlowCallSiteDispatch(DataFlowCall call, DataFlowCallable callable) {
reducedViableImplInCallContext(_, callable, call)
or
}
/**
* Holds if the call context `call` allows us to prune unreachable nodes in `callable`.
*/
cached
predicate recordDataFlowCallSiteUnreachable(DataFlowCall call, DataFlowCallable callable) {
exists(Node n | getNodeEnclosingCallable(n) = callable | isUnreachableInCallCached(n, call))
}
@@ -846,6 +851,15 @@ private module Cached {
TAccessPathFrontSome(AccessPathFront apf)
}
/**
* Holds if the call context `call` either improves virtual dispatch in
* `callable` or if it allows us to prune unreachable nodes in `callable`.
*/
predicate recordDataFlowCallSite(DataFlowCall call, DataFlowCallable callable) {
recordDataFlowCallSiteDispatch(call, callable) or
recordDataFlowCallSiteUnreachable(call, callable)
}
/**
* A `Node` at which a cast can occur such that the type should be checked.
*/

View File

@@ -1856,12 +1856,12 @@ class InitializeDynamicAllocationInstruction extends SideEffectInstruction {
}
/**
* Gets the address of the allocation this instruction is initializing.
* Gets the operand that represents the address of the allocation this instruction is initializing.
*/
final AddressOperand getAllocationAddressOperand() { result = getAnOperand() }
/**
* Gets the operand for the allocation this instruction is initializing.
* Gets the address for the allocation this instruction is initializing.
*/
final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() }
}

View File

@@ -1856,12 +1856,12 @@ class InitializeDynamicAllocationInstruction extends SideEffectInstruction {
}
/**
* Gets the address of the allocation this instruction is initializing.
* Gets the operand that represents the address of the allocation this instruction is initializing.
*/
final AddressOperand getAllocationAddressOperand() { result = getAnOperand() }
/**
* Gets the operand for the allocation this instruction is initializing.
* Gets the address for the allocation this instruction is initializing.
*/
final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() }
}

View File

@@ -1856,12 +1856,12 @@ class InitializeDynamicAllocationInstruction extends SideEffectInstruction {
}
/**
* Gets the address of the allocation this instruction is initializing.
* Gets the operand that represents the address of the allocation this instruction is initializing.
*/
final AddressOperand getAllocationAddressOperand() { result = getAnOperand() }
/**
* Gets the operand for the allocation this instruction is initializing.
* Gets the address for the allocation this instruction is initializing.
*/
final Instruction getAllocationAddress() { result = getAllocationAddressOperand().getDef() }
}

View File

@@ -33,3 +33,6 @@ private import implementations.Recv
private import implementations.Accept
private import implementations.Poll
private import implementations.Select
private import implementations.MySql
private import implementations.SqLite3
private import implementations.PostgreSql

View File

@@ -0,0 +1,32 @@
/**
* Provides implementation classes modeling the MySql C API.
* See `semmle.code.cpp.models.Models` for usage information.
*/
private import semmle.code.cpp.models.interfaces.Sql
private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs
/**
* The `mysql_query` family of functions from the MySQL C API.
*/
private class MySqlExecutionFunction extends SqlExecutionFunction {
MySqlExecutionFunction() {
this.hasName(["mysql_query", "mysql_real_query", "mysql_real_query_nonblocking"])
}
override predicate hasSqlArgument(FunctionInput input) { input.isParameterDeref(1) }
}
/**
* The `mysql_real_escape_string` family of functions from the MySQL C API.
*/
private class MySqlBarrierFunction extends SqlBarrierFunction {
MySqlBarrierFunction() {
this.hasName(["mysql_real_escape_string", "mysql_real_escape_string_quote"])
}
override predicate barrierSqlArgument(FunctionInput input, FunctionOutput output) {
input.isParameterDeref(2) and
output.isParameterDeref(1)
}
}

View File

@@ -0,0 +1,94 @@
private import semmle.code.cpp.models.interfaces.Sql
private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs
private predicate pqxxTransactionSqlArgument(string function, int arg) {
function = "exec" and arg = 0
or
function = "exec0" and arg = 0
or
function = "exec1" and arg = 0
or
function = "exec_n" and arg = 1
or
function = "exec_params" and arg = 0
or
function = "exec_params0" and arg = 0
or
function = "exec_params1" and arg = 0
or
function = "exec_params_n" and arg = 1
or
function = "query_value" and arg = 0
or
function = "stream" and arg = 0
}
private predicate pqxxConnectionSqlArgument(string function, int arg) {
function = "prepare" and arg = 1
}
private predicate pqxxTransationClassNames(string className, string namespace) {
namespace = "pqxx" and
className in [
"dbtransaction", "nontransaction", "basic_robusttransaction", "robusttransaction",
"subtransaction", "transaction", "basic_transaction", "transaction_base", "work"
]
}
private predicate pqxxConnectionClassNames(string className, string namespace) {
namespace = "pqxx" and
className in ["connection_base", "basic_connection", "connection"]
}
private predicate pqxxEscapeArgument(string function, int arg) {
arg = 0 and
function in ["esc", "esc_raw", "quote", "quote_raw", "quote_name", "quote_table", "esc_like"]
}
private class PostgreSqlExecutionFunction extends SqlExecutionFunction {
PostgreSqlExecutionFunction() {
exists(Class c |
this.getDeclaringType() = c and
// transaction exec and connection prepare variations
(
pqxxTransationClassNames(c.getName(), c.getNamespace().getName()) and
pqxxTransactionSqlArgument(this.getName(), _)
or
pqxxConnectionSqlArgument(this.getName(), _) and
pqxxConnectionClassNames(c.getName(), c.getNamespace().getName())
)
)
}
override predicate hasSqlArgument(FunctionInput input) {
exists(int argIndex |
pqxxTransactionSqlArgument(this.getName(), argIndex)
or
pqxxConnectionSqlArgument(this.getName(), argIndex)
|
input.isParameterDeref(argIndex)
)
}
}
private class PostgreSqlBarrierFunction extends SqlBarrierFunction {
PostgreSqlBarrierFunction() {
exists(Class c |
this.getDeclaringType() = c and
// transaction and connection escape functions
(
pqxxTransationClassNames(c.getName(), c.getNamespace().getName()) or
pqxxConnectionClassNames(c.getName(), c.getNamespace().getName())
) and
pqxxEscapeArgument(this.getName(), _)
)
}
override predicate barrierSqlArgument(FunctionInput input, FunctionOutput output) {
exists(int argIndex |
input.isParameterDeref(argIndex) and
output.isReturnValueDeref() and
pqxxEscapeArgument(this.getName(), argIndex)
)
}
}

View File

@@ -0,0 +1,21 @@
/**
* Provides implementation classes modeling the SQLite C API.
* See `semmle.code.cpp.models.Models` for usage information.
*/
private import semmle.code.cpp.models.interfaces.Sql
private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs
/**
* The `sqlite3_exec` and `sqlite3_prepare` families of functions from the SQLite C API.
*/
private class SqLite3ExecutionFunction extends SqlExecutionFunction {
SqLite3ExecutionFunction() {
this.hasName([
"sqlite3_exec", "sqlite3_prepare", "sqlite3_prepare_v2", "sqlite3_prepare_v3",
"sqlite3_prepare16", "sqlite3_prepare16_v2", "sqlite3_prepare16_v3"
])
}
override predicate hasSqlArgument(FunctionInput input) { input.isParameterDeref(1) }
}

View File

@@ -0,0 +1,30 @@
/**
* Provides abstract classes for modeling functions that execute and escape SQL query strings.
* To extend this QL library, create a QL class extending `SqlExecutionFunction` or `SqlEscapeFunction`
* with a characteristic predicate that selects the function or set of functions you are modeling.
* Within that class, override the predicates provided by the class to match the way a
* parameter flows into the function and, in the case of `SqlEscapeFunction`, out of the function.
*/
private import cpp
/**
* An abstract class that represents a function that executes an SQL query.
*/
abstract class SqlExecutionFunction extends Function {
/**
* Holds if `input` to this function represents SQL code to be executed.
*/
abstract predicate hasSqlArgument(FunctionInput input);
}
/**
* An abstract class that represents a function that is a barrier to an SQL query string.
*/
abstract class SqlBarrierFunction extends Function {
/**
* Holds if the `output` is a barrier to the SQL input `input` such that is it safe to pass to
* an `SqlExecutionFunction`.
*/
abstract predicate barrierSqlArgument(FunctionInput input, FunctionOutput output);
}

View File

@@ -29,8 +29,7 @@ predicate nanExcludingComparison(ComparisonOperation guard, boolean polarity) {
*/
private predicate excludesNan(RangeSsaDefinition def, VariableAccess v) {
exists(VariableAccess inCond, ComparisonOperation guard, boolean branch, StackVariable lsv |
def.isGuardPhi(inCond, guard, branch) and
inCond.getTarget() = lsv and
def.isGuardPhi(lsv, inCond, guard, branch) and
v = def.getAUse(lsv) and
guard.getAnOperand() = inCond and
nanExcludingComparison(guard, branch)

View File

@@ -94,11 +94,21 @@ class RangeSsaDefinition extends ControlFlowNodeBase {
predicate isPhiNode(StackVariable v) { exists(RangeSSA x | x.phi_node(v, this.(BasicBlock))) }
/**
* DEPRECATED: Use isGuardPhi/4 instead
* If this definition is a phi node corresponding to a guard,
* then return the variable and the guard.
* then return the variable access and the guard.
*/
predicate isGuardPhi(VariableAccess v, Expr guard, boolean branch) {
guard_defn(v, guard, this, branch)
deprecated predicate isGuardPhi(VariableAccess va, Expr guard, boolean branch) {
guard_defn(va, guard, this, branch)
}
/**
* If this definition is a phi node corresponding to a guard,
* then return the variable guarded, the variable access and the guard.
*/
predicate isGuardPhi(StackVariable v, VariableAccess va, Expr guard, boolean branch) {
guard_defn(va, guard, this, branch) and
va.getTarget() = v
}
/** Gets the primary location of this definition. */
@@ -133,9 +143,8 @@ class RangeSsaDefinition extends ControlFlowNodeBase {
// below excludes definitions which can only reach guard phi
// nodes by going through the corresponding guard.
not exists(VariableAccess access |
v = access.getTarget() and
pred.contains(access) and
this.isGuardPhi(access, _, _)
this.isGuardPhi(v, access, _, _)
)
)
}

View File

@@ -433,10 +433,7 @@ private predicate exprDependsOnDef(Expr e, RangeSsaDefinition srcDef, StackVaria
private predicate phiDependsOnDef(
RangeSsaDefinition phi, StackVariable v, RangeSsaDefinition srcDef, StackVariable srcVar
) {
exists(VariableAccess access, Expr guard |
access = v.getAnAccess() and
phi.isGuardPhi(access, guard, _)
|
exists(VariableAccess access, Expr guard | phi.isGuardPhi(v, access, guard, _) |
exprDependsOnDef(guard.(ComparisonOperation).getAnOperand(), srcDef, srcVar) or
exprDependsOnDef(access, srcDef, srcVar)
)
@@ -1204,8 +1201,7 @@ private float boolConversionUpperBound(Expr expr) {
*/
private float getPhiLowerBounds(StackVariable v, RangeSsaDefinition phi) {
exists(VariableAccess access, Expr guard, boolean branch, float defLB, float guardLB |
access = v.getAnAccess() and
phi.isGuardPhi(access, guard, branch) and
phi.isGuardPhi(v, access, guard, branch) and
lowerBoundFromGuard(guard, access, guardLB, branch) and
defLB = getFullyConvertedLowerBounds(access)
|
@@ -1230,8 +1226,7 @@ private float getPhiLowerBounds(StackVariable v, RangeSsaDefinition phi) {
/** See comment for `getPhiLowerBounds`, above. */
private float getPhiUpperBounds(StackVariable v, RangeSsaDefinition phi) {
exists(VariableAccess access, Expr guard, boolean branch, float defUB, float guardUB |
access = v.getAnAccess() and
phi.isGuardPhi(access, guard, branch) and
phi.isGuardPhi(v, access, guard, branch) and
upperBoundFromGuard(guard, access, guardUB, branch) and
defUB = getFullyConvertedUpperBounds(access)
|
@@ -1493,8 +1488,7 @@ private predicate isNEPhi(
exists(
ComparisonOperation cmp, boolean branch, Expr linearExpr, Expr rExpr, float p, float q, float r
|
access.getTarget() = v and
phi.isGuardPhi(access, cmp, branch) and
phi.isGuardPhi(v, access, cmp, branch) and
eqOpWithSwapAndNegate(cmp, linearExpr, rExpr, false, branch) and
v.getUnspecifiedType() instanceof IntegralOrEnumType and // Float `!=` is too imprecise
r = getValue(rExpr).toFloat() and
@@ -1503,8 +1497,7 @@ private predicate isNEPhi(
)
or
exists(Expr op, boolean branch, Expr linearExpr, float p, float q |
access.getTarget() = v and
phi.isGuardPhi(access, op, branch) and
phi.isGuardPhi(v, access, op, branch) and
eqZeroWithNegate(op, linearExpr, false, branch) and
v.getUnspecifiedType() instanceof IntegralOrEnumType and // Float `!` is too imprecise
linearAccess(linearExpr, access, p, q) and
@@ -1524,12 +1517,35 @@ private predicate isUnsupportedGuardPhi(Variable v, RangeSsaDefinition phi, Vari
or
eqZeroWithNegate(cmp, _, false, branch)
|
access.getTarget() = v and
phi.isGuardPhi(access, cmp, branch) and
phi.isGuardPhi(v, access, cmp, branch) and
not isNEPhi(v, phi, access, _)
)
}
/**
* Gets the upper bound of the expression, if the expression is guarded.
* An upper bound can only be found, if a guard phi node can be found, and the
* expression has only one immediate predecessor.
*/
private float getGuardedUpperBound(VariableAccess guardedAccess) {
exists(
RangeSsaDefinition def, StackVariable v, VariableAccess guardVa, Expr guard, boolean branch
|
def.isGuardPhi(v, guardVa, guard, branch) and
// If the basic block for the variable access being examined has
// more than one predecessor, the guard phi node could originate
// from one of the predecessors. This is because the guard phi
// node is attached to the block at the end of the edge and not on
// the actual edge. It is therefore not possible to determine which
// edge the guard phi node belongs to. The predicate below ensures
// that there is one predecessor, albeit somewhat conservative.
exists(unique(BasicBlock b | b = def.(BasicBlock).getAPredecessor())) and
guardedAccess = def.getAUse(v) and
result = max(float ub | upperBoundFromGuard(guard, guardVa, ub, branch)) and
not convertedExprMightOverflow(guard.getAChild+())
)
}
cached
private module SimpleRangeAnalysisCached {
/**
@@ -1565,9 +1581,18 @@ private module SimpleRangeAnalysisCached {
*/
cached
float upperBound(Expr expr) {
// Combine the upper bounds returned by getTruncatedUpperBounds into a
// single maximum value.
result = max(float ub | ub = getTruncatedUpperBounds(expr) | ub)
// Combine the upper bounds returned by getTruncatedUpperBounds and
// getGuardedUpperBound into a single maximum value
result = min([max(getTruncatedUpperBounds(expr)), getGuardedUpperBound(expr)])
}
/** Holds if the upper bound of `expr` may have been widened. This means the the upper bound is in practice likely to be overly wide. */
cached
predicate upperBoundMayBeWidened(Expr e) {
isRecursiveExpr(e) and
// Widening is not a problem if the post-analysis in `getGuardedUpperBound` has overridden the widening.
// Note that the RHS of `<` may be multi-valued.
not getGuardedUpperBound(e) < getTruncatedUpperBounds(e)
}
/**

View File

@@ -41,7 +41,8 @@ private predicate stmtDominates(Stmt dominator, Stmt dominated) {
}
/**
* Holds if the value of `use` is guarded to be less than something.
* Holds if the value of `use` is guarded to be less than something, and `e`
* is in code controlled by that guard (where the guard condition held).
*/
pragma[nomagic]
predicate guardedLesser(Operation e, Expr use) {
@@ -67,7 +68,8 @@ predicate guardedLesser(Operation e, Expr use) {
}
/**
* Holds if the value of `use` is guarded to be greater than something.
* Holds if the value of `use` is guarded to be greater than something, and `e`
* is in code controlled by that guard (where the guard condition held).
*/
pragma[nomagic]
predicate guardedGreater(Operation e, Expr use) {
@@ -120,6 +122,10 @@ predicate missingGuardAgainstOverflow(Operation e, VariableAccess use) {
// overflow possible if large or small
e instanceof MulExpr and
not (guardedLesser(e, varUse(v)) and guardedGreater(e, varUse(v)))
or
// overflow possible if large or small
e instanceof AssignMulExpr and
not (guardedLesser(e, varUse(v)) and guardedGreater(e, varUse(v)))
)
}
@@ -147,5 +153,9 @@ predicate missingGuardAgainstUnderflow(Operation e, VariableAccess use) {
// underflow possible if large or small
e instanceof MulExpr and
not (guardedLesser(e, varUse(v)) and guardedGreater(e, varUse(v)))
or
// underflow possible if large or small
e instanceof AssignMulExpr and
not (guardedLesser(e, varUse(v)) and guardedGreater(e, varUse(v)))
)
}

View File

@@ -7,6 +7,7 @@ import semmle.code.cpp.exprs.Expr
import semmle.code.cpp.commons.Environment
import semmle.code.cpp.security.SecurityOptions
import semmle.code.cpp.models.interfaces.FlowSource
import semmle.code.cpp.models.interfaces.Sql
/**
* Extend this class to customize the security queries for
@@ -34,13 +35,11 @@ class SecurityOptions extends string {
* An argument to a function that is passed to a SQL server.
*/
predicate sqlArgument(string function, int arg) {
// MySQL C API
function = "mysql_query" and arg = 1
or
function = "mysql_real_query" and arg = 1
or
// SQLite3 C API
function = "sqlite3_exec" and arg = 1
exists(FunctionInput input, SqlExecutionFunction sql |
sql.hasName(function) and
input.isParameterDeref(arg) and
sql.hasSqlArgument(input)
)
}
/**

View File

@@ -310,23 +310,14 @@ diagnostics(
int location: @location_default ref
);
/*
fromSource(0) = unknown,
fromSource(1) = from source,
fromSource(2) = from library
*/
files(
unique int id: @file,
string name: string ref,
string simple: string ref,
string ext: string ref,
int fromSource: int ref
string name: string ref
);
folders(
unique int id: @folder,
string name: string ref,
string simple: string ref
string name: string ref
);
@container = @folder | @file

View File

@@ -12875,18 +12875,6 @@
<k>name</k>
<v>59320</v>
</e>
<e>
<k>simple</k>
<v>40580</v>
</e>
<e>
<k>ext</k>
<v>97</v>
</e>
<e>
<k>fromSource</k>
<v>10</v>
</e>
</columnsizes>
<dependencies>
<dep>
@@ -12906,54 +12894,6 @@
</val>
</dep>
<dep>
<src>id</src>
<trg>simple</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>59320</v>
</b>
</bs>
</hist>
</val>
</dep>
<dep>
<src>id</src>
<trg>ext</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>59320</v>
</b>
</bs>
</hist>
</val>
</dep>
<dep>
<src>id</src>
<trg>fromSource</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>59320</v>
</b>
</bs>
</hist>
</val>
</dep>
<dep>
<src>name</src>
<trg>id</trg>
<val>
@@ -12969,406 +12909,6 @@
</hist>
</val>
</dep>
<dep>
<src>name</src>
<trg>simple</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>59320</v>
</b>
</bs>
</hist>
</val>
</dep>
<dep>
<src>name</src>
<trg>ext</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>59320</v>
</b>
</bs>
</hist>
</val>
</dep>
<dep>
<src>name</src>
<trg>fromSource</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>59320</v>
</b>
</bs>
</hist>
</val>
</dep>
<dep>
<src>simple</src>
<trg>id</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>30814</v>
</b>
<b>
<a>2</a>
<b>3</b>
<v>6123</v>
</b>
<b>
<a>3</a>
<b>7</b>
<v>3197</v>
</b>
<b>
<a>7</a>
<b>42</b>
<v>444</v>
</b>
</bs>
</hist>
</val>
</dep>
<dep>
<src>simple</src>
<trg>name</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>30814</v>
</b>
<b>
<a>2</a>
<b>3</b>
<v>6123</v>
</b>
<b>
<a>3</a>
<b>7</b>
<v>3197</v>
</b>
<b>
<a>7</a>
<b>42</b>
<v>444</v>
</b>
</bs>
</hist>
</val>
</dep>
<dep>
<src>simple</src>
<trg>ext</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>36277</v>
</b>
<b>
<a>2</a>
<b>3</b>
<v>3739</v>
</b>
<b>
<a>3</a>
<b>6</b>
<v>563</v>
</b>
</bs>
</hist>
</val>
</dep>
<dep>
<src>simple</src>
<trg>fromSource</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>40580</v>
</b>
</bs>
</hist>
</val>
</dep>
<dep>
<src>ext</src>
<trg>id</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>10</v>
</b>
<b>
<a>3</a>
<b>4</b>
<v>10</v>
</b>
<b>
<a>15</a>
<b>16</b>
<v>10</v>
</b>
<b>
<a>38</a>
<b>39</b>
<v>10</v>
</b>
<b>
<a>80</a>
<b>81</b>
<v>10</v>
</b>
<b>
<a>114</a>
<b>115</b>
<v>10</v>
</b>
<b>
<a>441</a>
<b>442</b>
<v>10</v>
</b>
<b>
<a>768</a>
<b>769</b>
<v>10</v>
</b>
<b>
<a>4013</a>
<b>4014</b>
<v>10</v>
</b>
</bs>
</hist>
</val>
</dep>
<dep>
<src>ext</src>
<trg>name</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>10</v>
</b>
<b>
<a>3</a>
<b>4</b>
<v>10</v>
</b>
<b>
<a>15</a>
<b>16</b>
<v>10</v>
</b>
<b>
<a>38</a>
<b>39</b>
<v>10</v>
</b>
<b>
<a>80</a>
<b>81</b>
<v>10</v>
</b>
<b>
<a>114</a>
<b>115</b>
<v>10</v>
</b>
<b>
<a>441</a>
<b>442</b>
<v>10</v>
</b>
<b>
<a>768</a>
<b>769</b>
<v>10</v>
</b>
<b>
<a>4013</a>
<b>4014</b>
<v>10</v>
</b>
</bs>
</hist>
</val>
</dep>
<dep>
<src>ext</src>
<trg>simple</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>10</v>
</b>
<b>
<a>3</a>
<b>4</b>
<v>10</v>
</b>
<b>
<a>15</a>
<b>16</b>
<v>10</v>
</b>
<b>
<a>38</a>
<b>39</b>
<v>10</v>
</b>
<b>
<a>75</a>
<b>76</b>
<v>10</v>
</b>
<b>
<a>112</a>
<b>113</b>
<v>10</v>
</b>
<b>
<a>428</a>
<b>429</b>
<v>10</v>
</b>
<b>
<a>688</a>
<b>689</b>
<v>10</v>
</b>
<b>
<a>2838</a>
<b>2839</b>
<v>10</v>
</b>
</bs>
</hist>
</val>
</dep>
<dep>
<src>ext</src>
<trg>fromSource</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>97</v>
</b>
</bs>
</hist>
</val>
</dep>
<dep>
<src>fromSource</src>
<trg>id</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>5473</a>
<b>5474</b>
<v>10</v>
</b>
</bs>
</hist>
</val>
</dep>
<dep>
<src>fromSource</src>
<trg>name</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>5473</a>
<b>5474</b>
<v>10</v>
</b>
</bs>
</hist>
</val>
</dep>
<dep>
<src>fromSource</src>
<trg>simple</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>3744</a>
<b>3745</b>
<v>10</v>
</b>
</bs>
</hist>
</val>
</dep>
<dep>
<src>fromSource</src>
<trg>ext</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>9</a>
<b>10</b>
<v>10</v>
</b>
</bs>
</hist>
</val>
</dep>
</dependencies>
</relation>
<relation>
@@ -13383,10 +12923,6 @@
<k>name</k>
<v>10817</v>
</e>
<e>
<k>simple</k>
<v>3099</v>
</e>
</columnsizes>
<dependencies>
<dep>
@@ -13406,22 +12942,6 @@
</val>
</dep>
<dep>
<src>id</src>
<trg>simple</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>10817</v>
</b>
</bs>
</hist>
</val>
</dep>
<dep>
<src>name</src>
<trg>id</trg>
<val>
@@ -13437,94 +12957,6 @@
</hist>
</val>
</dep>
<dep>
<src>name</src>
<trg>simple</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>10817</v>
</b>
</bs>
</hist>
</val>
</dep>
<dep>
<src>simple</src>
<trg>id</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>1669</v>
</b>
<b>
<a>2</a>
<b>3</b>
<v>661</v>
</b>
<b>
<a>3</a>
<b>4</b>
<v>433</v>
</b>
<b>
<a>4</a>
<b>17</b>
<v>238</v>
</b>
<b>
<a>27</a>
<b>121</b>
<v>97</v>
</b>
</bs>
</hist>
</val>
</dep>
<dep>
<src>simple</src>
<trg>name</trg>
<val>
<hist>
<budget>12</budget>
<bs>
<b>
<a>1</a>
<b>2</b>
<v>1669</v>
</b>
<b>
<a>2</a>
<b>3</b>
<v>661</v>
</b>
<b>
<a>3</a>
<b>4</b>
<v>433</v>
</b>
<b>
<a>4</a>
<b>17</b>
<v>238</v>
</b>
<b>
<a>27</a>
<b>121</b>
<v>97</v>
</b>
</bs>
</hist>
</val>
</dep>
</dependencies>
</relation>
<relation>

View File

@@ -5,7 +5,7 @@
* @kind problem
* @problem.severity warning
* @security-severity 9.3
* @precision medium
* @precision high
* @id cpp/static-buffer-overflow
* @tags reliability
* security
@@ -55,6 +55,8 @@ predicate overflowOffsetInLoop(BufferAccess bufaccess, string msg) {
loop.counter().getAnAccess() = bufaccess.getArrayOffset() and
// Ensure that we don't have an upper bound on the array index that's less than the buffer size.
not upperBound(bufaccess.getArrayOffset().getFullyConverted()) < bufaccess.bufferSize() and
// The upper bounds analysis must not have been widended
not upperBoundMayBeWidened(bufaccess.getArrayOffset().getFullyConverted()) and
msg =
"Potential buffer-overflow: counter '" + loop.counter().toString() + "' <= " +
loop.limit().toString() + " but '" + bufaccess.buffer().getName() + "' has " +
@@ -130,11 +132,13 @@ predicate outOfBounds(BufferAccess bufaccess, string msg) {
(
access > size
or
access = size and not exists(AddressOfExpr addof | bufaccess = addof.getOperand())
access = size and
not exists(AddressOfExpr addof | bufaccess = addof.getOperand()) and
not exists(BuiltInOperationBuiltInOffsetOf offsetof | offsetof.getAChild() = bufaccess)
) and
msg =
"Potential buffer-overflow: '" + buf + "' has size " + size.toString() + " but '" + buf + "[" +
access.toString() + "]' is accessed here."
access.toString() + "]' may be accessed here."
)
}

View File

@@ -0,0 +1,12 @@
/**
* @name Sum of frontend and extractor time
* @description The sum of elapsed frontend time, and the sum of elapsed extractor time.
* This query is for internal use only and may change without notice.
* @kind table
* @id cpp/frontend-and-extractor-time
*/
import cpp
select sum(Compilation c, float seconds | compilation_time(c, _, 2, seconds) | seconds) as sum_frontend_elapsed_seconds,
sum(Compilation c, float seconds | compilation_time(c, _, 4, seconds) | seconds) as sum_extractor_elapsed_seconds

View File

@@ -30,7 +30,15 @@ class Configuration extends TaintTrackingConfiguration {
}
override predicate isBarrier(Expr e) {
super.isBarrier(e) or e.getUnspecifiedType() instanceof IntegralType
super.isBarrier(e)
or
e.getUnspecifiedType() instanceof IntegralType
or
exists(SqlBarrierFunction sql, int arg, FunctionInput input |
e = sql.getACallToThisFunction().getArgument(arg) and
input.isParameterDeref(arg) and
sql.barrierSqlArgument(input, _)
)
}
}

View File

@@ -3,4 +3,4 @@
- apply: code-scanning-selectors.yml
from: codeql/suite-helpers
- apply: codeql-suites/exclude-slow-queries.yml
from: codeql-cpp
from: codeql/cpp-queries

View File

@@ -3,7 +3,7 @@
- apply: lgtm-selectors.yml
from: codeql/suite-helpers
- apply: codeql-suites/exclude-slow-queries.yml
from: codeql-cpp
from: codeql/cpp-queries
# These are only for IDE use.
- exclude:
tags contain:

View File

@@ -3,4 +3,4 @@
- apply: security-and-quality-selectors.yml
from: codeql/suite-helpers
- apply: codeql-suites/exclude-slow-queries.yml
from: codeql-cpp
from: codeql/cpp-queries

View File

@@ -3,4 +3,4 @@
- apply: security-extended-selectors.yml
from: codeql/suite-helpers
- apply: codeql-suites/exclude-slow-queries.yml
from: codeql-cpp
from: codeql/cpp-queries

View File

@@ -1,28 +0,0 @@
#include <iostream>
#include <stdexcept>
#include <pqxx/pqxx>
int main(int argc, char ** argv) {
if (argc != 2) {
throw std::runtime_error("Give me a string!");
}
pqxx::connection c;
pqxx::work w(c);
// BAD
char *userName = argv[1];
char query1[1000] = {0};
sprintf(query1, "SELECT UID FROM USERS where name = \"%s\"", userName);
pqxx::row r = w.exec1(query1);
w.commit();
std::cout << r[0].as<int>() << std::endl;
// GOOD
pqxx::result r2 = w.exec("SELECT " + w.quote(argv[1]));
w.commit();
std::cout << r2[0][0].c_str() << std::endl;
return 0;
}

View File

@@ -1,31 +0,0 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>The code passes user input as part of a SQL query without escaping special elements.
It generates a SQL query to Postgres using <code>sprintf</code>,
with the user-supplied data directly passed as an argument
to <code>sprintf</code>. This leaves the code vulnerable to attack by SQL Injection.</p>
</overview>
<recommendation>
<p>Use a library routine to escape characters in the user-supplied
string before converting it to SQL. Use <code>esc</code> and <code>quote</code> pqxx library functions.</p>
</recommendation>
<example>
<sample src="SqlPqxxTainted.cpp" />
</example>
<references>
<li>MSDN Library: <a href="https://docs.microsoft.com/en-us/sql/relational-databases/security/sql-injection">SQL Injection</a>.</li>
<!-- LocalWords: SQL CWE
-->
</references>
</qhelp>

View File

@@ -1,113 +0,0 @@
/**
* @name Uncontrolled data in SQL query to Postgres
* @description Including user-supplied data in a SQL query to Postgres
* without neutralizing special elements can make code
* vulnerable to SQL Injection.
* @kind path-problem
* @problem.severity error
* @precision high
* @id cpp/sql-injection-via-pqxx
* @tags security
* external/cwe/cwe-089
*/
import cpp
import semmle.code.cpp.security.Security
import semmle.code.cpp.dataflow.TaintTracking
import DataFlow::PathGraph
predicate pqxxTransationClassNames(string className, string namespace) {
namespace = "pqxx" and
className in [
"dbtransaction", "nontransaction", "basic_robusttransaction", "robusttransaction",
"subtransaction", "transaction", "basic_transaction", "transaction_base", "work"
]
}
predicate pqxxConnectionClassNames(string className, string namespace) {
namespace = "pqxx" and
className in ["connection_base", "basic_connection", "connection"]
}
predicate pqxxTransactionSqlArgument(string function, int arg) {
function = "exec" and arg = 0
or
function = "exec0" and arg = 0
or
function = "exec1" and arg = 0
or
function = "exec_n" and arg = 1
or
function = "exec_params" and arg = 0
or
function = "exec_params0" and arg = 0
or
function = "exec_params1" and arg = 0
or
function = "exec_params_n" and arg = 1
or
function = "query_value" and arg = 0
or
function = "stream" and arg = 0
}
predicate pqxxConnectionSqlArgument(string function, int arg) { function = "prepare" and arg = 1 }
Expr getPqxxSqlArgument() {
exists(FunctionCall fc, Expr e, int argIndex, UserType t |
// examples: 'work' for 'work.exec(...)'; '->' for 'tx->exec()'.
e = fc.getQualifier() and
// to find ConnectionHandle/TransationHandle and similar classes which override '->' operator behavior
// and return pointer to a connection/transation object
e.getType().refersTo(t) and
// transaction exec and connection prepare variations
(
pqxxTransationClassNames(t.getName(), t.getNamespace().getName()) and
pqxxTransactionSqlArgument(fc.getTarget().getName(), argIndex)
or
pqxxConnectionClassNames(t.getName(), t.getNamespace().getName()) and
pqxxConnectionSqlArgument(fc.getTarget().getName(), argIndex)
) and
result = fc.getArgument(argIndex)
)
}
predicate pqxxEscapeArgument(string function, int arg) {
arg = 0 and
function in ["esc", "esc_raw", "quote", "quote_raw", "quote_name", "quote_table", "esc_like"]
}
predicate isEscapedPqxxArgument(Expr argExpr) {
exists(FunctionCall fc, Expr e, int argIndex, UserType t |
// examples: 'work' for 'work.exec(...)'; '->' for 'tx->exec()'.
e = fc.getQualifier() and
// to find ConnectionHandle/TransationHandle and similar classes which override '->' operator behavior
// and return pointer to a connection/transation object
e.getType().refersTo(t) and
// transaction and connection escape functions
(
pqxxTransationClassNames(t.getName(), t.getNamespace().getName()) or
pqxxConnectionClassNames(t.getName(), t.getNamespace().getName())
) and
pqxxEscapeArgument(fc.getTarget().getName(), argIndex) and
// is escaped arg == argExpr
argExpr = fc.getArgument(argIndex)
)
}
class Configuration extends TaintTracking::Configuration {
Configuration() { this = "SqlPqxxTainted" }
override predicate isSource(DataFlow::Node source) { isUserInput(source.asExpr(), _) }
override predicate isSink(DataFlow::Node sink) { sink.asExpr() = getPqxxSqlArgument() }
override predicate isSanitizer(DataFlow::Node node) { isEscapedPqxxArgument(node.asExpr()) }
}
from DataFlow::PathNode source, DataFlow::PathNode sink, Configuration config, string taintCause
where
config.hasFlowPath(source, sink) and
isUserInput(source.getNode().asExpr(), taintCause)
select sink, source, sink, "This argument to a SQL query function is derived from $@", source,
"user input (" + taintCause + ")"

View File

@@ -0,0 +1,13 @@
...
fs = socket(AF_UNIX, SOCK_STREAM, 0)
...
close(fs);
fs = -1; // GOOD
...
...
fs = socket(AF_UNIX, SOCK_STREAM, 0)
...
close(fs);
if(fs) close(fs); // BAD
...

View File

@@ -0,0 +1,26 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Double release of the descriptor can lead to a crash of the program. Requires the attention of developers.</p>
</overview>
<recommendation>
<p>We recommend that you exclude situations of possible double release.</p>
</recommendation>
<example>
<p>The following example demonstrates an erroneous and corrected use of descriptor deallocation.</p>
<sample src="DoubleRelease.c" />
</example>
<references>
<li>
CERT C Coding Standard:
<a href="https://wiki.sei.cmu.edu/confluence/display/c/FIO46-C.+Do+not+access+a+closed+file">FIO46-C. Do not access a closed file</a>.
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,142 @@
/**
* @name Errors When Double Release
* @description Double release of the descriptor can lead to a crash of the program.
* @kind problem
* @id cpp/double-release
* @problem.severity warning
* @precision medium
* @tags security
* external/cwe/cwe-675
* external/cwe/cwe-666
*/
import cpp
import semmle.code.cpp.commons.File
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
import semmle.code.cpp.valuenumbering.HashCons
/**
* A function call that potentially does not return (such as `exit`).
*/
class CallMayNotReturn extends FunctionCall {
CallMayNotReturn() {
// call that is known to not return
not exists(this.(ControlFlowNode).getASuccessor())
or
// call to another function that may not return
exists(CallMayNotReturn exit | getTarget() = exit.getEnclosingFunction())
or
exists(ThrowExpr tex | tex = this.(ControlFlowNode).getASuccessor())
}
}
/** Holds if there are no assignment expressions to the function argument. */
pragma[inline]
predicate checkChangeVariable(FunctionCall fc0, ControlFlowNode fc1, ControlFlowNode fc2) {
not exists(Expr exptmp |
(
exptmp = fc0.getArgument(0).(VariableAccess).getTarget().getAnAssignedValue() or
exptmp.(AddressOfExpr).getOperand() =
fc0.getArgument(0).(VariableAccess).getTarget().getAnAccess()
) and
exptmp = fc1.getASuccessor*() and
exptmp = fc2.getAPredecessor*()
) and
(
(
not fc0.getArgument(0) instanceof PointerFieldAccess and
not fc0.getArgument(0) instanceof ValueFieldAccess
or
fc0.getArgument(0).(VariableAccess).getQualifier() instanceof ThisExpr
)
or
not exists(Expr exptmp |
(
exptmp =
fc0.getArgument(0)
.(VariableAccess)
.getQualifier()
.(VariableAccess)
.getTarget()
.getAnAssignedValue() or
exptmp.(AddressOfExpr).getOperand() =
fc0.getArgument(0)
.(VariableAccess)
.getQualifier()
.(VariableAccess)
.getTarget()
.getAnAccess()
) and
exptmp = fc1.getASuccessor*() and
exptmp = fc2.getAPredecessor*()
)
)
}
/** Holds if the underlying expression is a call to the close function. Provided that the function parameter does not change after the call. */
predicate closeReturn(FunctionCall fc) {
fcloseCall(fc, _) and
checkChangeVariable(fc, fc, fc.getEnclosingFunction())
}
/** Holds if the underlying expression is a call to the close function. Provided that the function parameter does not change before the call. */
predicate closeWithoutChangeBefore(FunctionCall fc) {
fcloseCall(fc, _) and
checkChangeVariable(fc, fc.getEnclosingFunction().getEntryPoint(), fc)
}
/** Holds, if a sequential call of the specified functions is possible, via a higher-level function call. */
predicate callInOtherFunctions(FunctionCall fc, FunctionCall fc1) {
exists(FunctionCall fec1, FunctionCall fec2 |
fc.getEnclosingFunction() != fc1.getEnclosingFunction() and
fec1 = fc.getEnclosingFunction().getACallToThisFunction() and
fec2 = fc1.getEnclosingFunction().getACallToThisFunction() and
fec1.getASuccessor*() = fec2 and
checkChangeVariable(fc, fec1, fec2)
)
}
/** Holds if successive calls to close functions are possible. */
predicate interDoubleCloseFunctions(FunctionCall fc, FunctionCall fc1) {
fcloseCall(fc, _) and
fcloseCall(fc1, _) and
fc != fc1 and
fc.getASuccessor*() = fc1 and
checkChangeVariable(fc, fc, fc1)
}
/** Holds if the first arguments of the two functions are similar. */
predicate similarArguments(FunctionCall fc, FunctionCall fc1) {
globalValueNumber(fc.getArgument(0)) = globalValueNumber(fc1.getArgument(0))
or
fc.getArgument(0).(VariableAccess).getTarget() = fc1.getArgument(0).(VariableAccess).getTarget() and
(
not fc.getArgument(0) instanceof PointerFieldAccess and
not fc.getArgument(0) instanceof ValueFieldAccess
or
fc.getArgument(0).(VariableAccess).getQualifier() instanceof ThisExpr
)
or
fc.getArgument(0).(VariableAccess).getTarget() = fc1.getArgument(0).(VariableAccess).getTarget() and
(
fc.getArgument(0) instanceof PointerFieldAccess or
fc.getArgument(0) instanceof ValueFieldAccess
) and
hashCons(fc.getArgument(0)) = hashCons(fc1.getArgument(0))
}
from FunctionCall fc, FunctionCall fc1
where
not exists(CallMayNotReturn fctmp | fctmp = fc.getASuccessor*()) and
not exists(IfStmt ifs | ifs.getCondition().getAChild*() = fc) and
(
// detecting a repeated call situation within one function
closeReturn(fc) and
closeWithoutChangeBefore(fc1) and
callInOtherFunctions(fc, fc1)
or
// detection of repeated call in different functions
interDoubleCloseFunctions(fc, fc1)
) and
similarArguments(fc, fc1)
select fc, "Second call to the $@ function is possible.", fc1, fc1.getTarget().getName()

View File

@@ -0,0 +1,30 @@
/**
* @name unsigned to signed used in pointer arithmetic
* @description finds unsigned to signed conversions used in pointer arithmetic, potentially causing an out-of-bound access
* @id cpp/sign-conversion-pointer-arithmetic
* @kind problem
* @problem.severity warning
* @tags reliability
* security
* external/cwe/cwe-787
*/
import cpp
import semmle.code.cpp.dataflow.DataFlow
import semmle.code.cpp.security.Overflow
from FunctionCall call, Function f, Parameter p, DataFlow::Node sink, PointerArithmeticOperation pao
where
f = call.getTarget() and
p = f.getAParameter() and
p.getUnspecifiedType().(IntegralType).isSigned() and
call.getArgument(p.getIndex()).getUnspecifiedType().(IntegralType).isUnsigned() and
pao.getAnOperand() = sink.asExpr() and
not exists(Operation a | guardedLesser(a, sink.asExpr())) and
not exists(Operation b | guardedGreater(b, call.getArgument(p.getIndex()))) and
not call.getArgument(p.getIndex()).isConstant() and
DataFlow::localFlow(DataFlow::parameterNode(p), sink) and
p.getUnspecifiedType().getSize() < 8
select call,
"This call: $@ passes an unsigned int to a function that requires a signed int: $@. And then used in pointer arithmetic: $@",
call, call.toString(), f, f.toString(), sink, sink.toString()

View File

@@ -63,6 +63,7 @@ where
functionsMissingReturnStmt(f, blame) and
reachable(blame) and
not functionImperfectlyExtracted(f) and
not f.isFromUninstantiatedTemplate(_) and
(blame = stmt or blame.(Expr).getEnclosingStmt() = stmt) and
msg =
"Function " + f.getName() + " should return a value of type " + f.getType().getName() +

View File

@@ -1,8 +1,8 @@
name: codeql/cpp-queries
version: 0.0.2
dependencies:
codeql/cpp-all: ^0.0.2
codeql/suite-helpers: ^0.0.2
codeql/cpp-all: "*"
codeql/suite-helpers: "*"
suites: codeql-suites
extractor: cpp
defaultSuiteFile: codeql-suites/cpp-code-scanning.qls

View File

@@ -8,6 +8,7 @@ nodes
| test.cpp:23:33:23:37 | size1 | semmle.label | size1 |
| test.cpp:30:27:30:31 | ... * ... | semmle.label | ... * ... |
| test.cpp:31:27:31:31 | ... * ... | semmle.label | ... * ... |
subpaths
#select
| test.cpp:13:33:13:37 | ... * ... | test.cpp:13:33:13:37 | ... * ... | test.cpp:13:33:13:37 | ... * ... | Potentially overflowing value from $@ is used in the size of this allocation. | test.cpp:13:33:13:37 | ... * ... | multiplication |
| test.cpp:15:31:15:35 | ... * ... | test.cpp:15:31:15:35 | ... * ... | test.cpp:15:31:15:35 | ... * ... | Potentially overflowing value from $@ is used in the size of this allocation. | test.cpp:15:31:15:35 | ... * ... | multiplication |

View File

@@ -1,8 +1,12 @@
edges
| test.cpp:45:18:45:23 | buffer | test.cpp:47:10:47:15 | buffer |
| test.cpp:77:16:77:22 | medical | test.cpp:78:24:78:27 | temp |
| test.cpp:81:17:81:20 | call to func | test.cpp:82:24:82:28 | buff5 |
| test.cpp:81:22:81:28 | medical | test.cpp:45:18:45:23 | buffer |
| test.cpp:81:22:81:28 | medical | test.cpp:81:17:81:20 | call to func |
nodes
| test.cpp:45:18:45:23 | buffer | semmle.label | buffer |
| test.cpp:47:10:47:15 | buffer | semmle.label | buffer |
| test.cpp:57:9:57:18 | theZipcode | semmle.label | theZipcode |
| test.cpp:74:24:74:30 | medical | semmle.label | medical |
| test.cpp:77:16:77:22 | medical | semmle.label | medical |
@@ -12,6 +16,8 @@ nodes
| test.cpp:82:24:82:28 | buff5 | semmle.label | buff5 |
| test.cpp:96:37:96:46 | theZipcode | semmle.label | theZipcode |
| test.cpp:99:42:99:51 | theZipcode | semmle.label | theZipcode |
subpaths
| test.cpp:81:22:81:28 | medical | test.cpp:45:18:45:23 | buffer | test.cpp:47:10:47:15 | buffer | test.cpp:81:17:81:20 | call to func |
#select
| test.cpp:57:9:57:18 | theZipcode | test.cpp:57:9:57:18 | theZipcode | test.cpp:57:9:57:18 | theZipcode | This write into the external location 'theZipcode' may contain unencrypted data from $@ | test.cpp:57:9:57:18 | theZipcode | this source. |
| test.cpp:74:24:74:30 | medical | test.cpp:74:24:74:30 | medical | test.cpp:74:24:74:30 | medical | This write into the external location 'medical' may contain unencrypted data from $@ | test.cpp:74:24:74:30 | medical | this source. |

View File

@@ -1,11 +1,18 @@
edges
| A.cpp:23:10:23:10 | c | A.cpp:25:7:25:17 | Chi [c] |
| A.cpp:27:17:27:17 | c | A.cpp:27:22:27:32 | Chi [c] |
| A.cpp:28:8:28:10 | *#this [c] | A.cpp:28:29:28:29 | Store |
| A.cpp:55:5:55:5 | set output argument [c] | A.cpp:56:10:56:10 | b indirection [c] |
| A.cpp:55:8:55:10 | new | A.cpp:27:17:27:17 | c |
| A.cpp:55:8:55:10 | new | A.cpp:55:5:55:5 | set output argument [c] |
| A.cpp:55:12:55:19 | (C *)... | A.cpp:55:8:55:10 | new |
| A.cpp:55:12:55:19 | new | A.cpp:55:8:55:10 | new |
| A.cpp:56:10:56:10 | b indirection [c] | A.cpp:28:8:28:10 | *#this [c] |
| A.cpp:56:10:56:10 | b indirection [c] | A.cpp:56:13:56:15 | call to get |
| A.cpp:57:10:57:25 | new indirection [c] | A.cpp:28:8:28:10 | *#this [c] |
| A.cpp:57:10:57:25 | new indirection [c] | A.cpp:57:28:57:30 | call to get |
| A.cpp:57:11:57:24 | B output argument [c] | A.cpp:57:10:57:25 | new indirection [c] |
| A.cpp:57:11:57:24 | new | A.cpp:23:10:23:10 | c |
| A.cpp:57:11:57:24 | new | A.cpp:57:11:57:24 | B output argument [c] |
| A.cpp:57:17:57:23 | new | A.cpp:57:11:57:24 | new |
| A.cpp:98:12:98:18 | new | A.cpp:100:5:100:13 | Chi [a] |
@@ -14,10 +21,12 @@ edges
| A.cpp:103:14:103:14 | *c [a] | A.cpp:107:16:107:16 | a |
| A.cpp:126:5:126:5 | Chi [c] | A.cpp:131:8:131:8 | f7 output argument [c] |
| A.cpp:126:5:126:5 | set output argument [c] | A.cpp:126:5:126:5 | Chi [c] |
| A.cpp:126:8:126:10 | new | A.cpp:27:17:27:17 | c |
| A.cpp:126:8:126:10 | new | A.cpp:126:5:126:5 | set output argument [c] |
| A.cpp:126:12:126:18 | new | A.cpp:126:8:126:10 | new |
| A.cpp:131:8:131:8 | Chi [c] | A.cpp:132:13:132:13 | c |
| A.cpp:131:8:131:8 | f7 output argument [c] | A.cpp:131:8:131:8 | Chi [c] |
| A.cpp:140:13:140:13 | b | A.cpp:143:7:143:31 | Chi [b] |
| A.cpp:142:7:142:20 | Chi [c] | A.cpp:151:18:151:18 | D output argument [c] |
| A.cpp:142:14:142:20 | new | A.cpp:142:7:142:20 | Chi [c] |
| A.cpp:143:7:143:31 | Chi [b] | A.cpp:151:12:151:24 | D output argument [b] |
@@ -25,6 +34,7 @@ edges
| A.cpp:150:12:150:18 | new | A.cpp:151:12:151:24 | b |
| A.cpp:151:12:151:24 | Chi [b] | A.cpp:152:13:152:13 | b |
| A.cpp:151:12:151:24 | D output argument [b] | A.cpp:151:12:151:24 | Chi [b] |
| A.cpp:151:12:151:24 | b | A.cpp:140:13:140:13 | b |
| A.cpp:151:12:151:24 | b | A.cpp:151:12:151:24 | D output argument [b] |
| A.cpp:151:18:151:18 | Chi [c] | A.cpp:154:13:154:13 | c |
| A.cpp:151:18:151:18 | D output argument [c] | A.cpp:151:18:151:18 | Chi [c] |
@@ -86,21 +96,49 @@ edges
| arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:10:8:10:15 | * ... |
| arrays.cpp:15:14:15:23 | call to user_input | arrays.cpp:16:8:16:13 | access to array |
| arrays.cpp:36:26:36:35 | call to user_input | arrays.cpp:37:24:37:27 | data |
| by_reference.cpp:11:48:11:52 | value | by_reference.cpp:12:5:12:16 | Chi [a] |
| by_reference.cpp:15:26:15:30 | value | by_reference.cpp:16:5:16:19 | Chi [a] |
| by_reference.cpp:19:28:19:32 | value | by_reference.cpp:20:11:20:21 | value |
| by_reference.cpp:20:5:20:8 | setDirectly output argument [a] | by_reference.cpp:20:5:20:8 | Chi [a] |
| by_reference.cpp:20:11:20:21 | value | by_reference.cpp:15:26:15:30 | value |
| by_reference.cpp:20:11:20:21 | value | by_reference.cpp:20:5:20:8 | setDirectly output argument [a] |
| by_reference.cpp:23:34:23:38 | value | by_reference.cpp:24:5:24:17 | value |
| by_reference.cpp:24:5:24:17 | value | by_reference.cpp:11:48:11:52 | value |
| by_reference.cpp:24:5:24:17 | value | by_reference.cpp:24:19:24:22 | nonMemberSetA output argument [a] |
| by_reference.cpp:24:19:24:22 | nonMemberSetA output argument [a] | by_reference.cpp:24:19:24:22 | Chi [a] |
| by_reference.cpp:31:46:31:46 | *s [a] | by_reference.cpp:32:15:32:15 | Store |
| by_reference.cpp:35:9:35:19 | *#this [a] | by_reference.cpp:36:18:36:18 | Store |
| by_reference.cpp:39:9:39:21 | *#this [a] | by_reference.cpp:40:12:40:15 | this indirection [a] |
| by_reference.cpp:40:12:40:15 | this indirection [a] | by_reference.cpp:35:9:35:19 | *#this [a] |
| by_reference.cpp:40:12:40:15 | this indirection [a] | by_reference.cpp:40:18:40:28 | call to getDirectly |
| by_reference.cpp:40:18:40:28 | call to getDirectly | by_reference.cpp:40:18:40:28 | Store |
| by_reference.cpp:43:9:43:27 | *#this [a] | by_reference.cpp:44:26:44:29 | this indirection [a] |
| by_reference.cpp:44:12:44:24 | call to nonMemberGetA | by_reference.cpp:44:12:44:24 | Store |
| by_reference.cpp:44:26:44:29 | this indirection [a] | by_reference.cpp:31:46:31:46 | *s [a] |
| by_reference.cpp:44:26:44:29 | this indirection [a] | by_reference.cpp:44:12:44:24 | call to nonMemberGetA |
| by_reference.cpp:50:3:50:3 | setDirectly output argument [a] | by_reference.cpp:51:8:51:8 | s indirection [a] |
| by_reference.cpp:50:5:50:15 | call to user_input | by_reference.cpp:15:26:15:30 | value |
| by_reference.cpp:50:5:50:15 | call to user_input | by_reference.cpp:50:3:50:3 | setDirectly output argument [a] |
| by_reference.cpp:50:17:50:26 | call to user_input | by_reference.cpp:50:5:50:15 | call to user_input |
| by_reference.cpp:51:8:51:8 | s indirection [a] | by_reference.cpp:35:9:35:19 | *#this [a] |
| by_reference.cpp:51:8:51:8 | s indirection [a] | by_reference.cpp:51:10:51:20 | call to getDirectly |
| by_reference.cpp:56:3:56:3 | setIndirectly output argument [a] | by_reference.cpp:57:8:57:8 | s indirection [a] |
| by_reference.cpp:56:5:56:17 | call to user_input | by_reference.cpp:19:28:19:32 | value |
| by_reference.cpp:56:5:56:17 | call to user_input | by_reference.cpp:56:3:56:3 | setIndirectly output argument [a] |
| by_reference.cpp:56:19:56:28 | call to user_input | by_reference.cpp:56:5:56:17 | call to user_input |
| by_reference.cpp:57:8:57:8 | s indirection [a] | by_reference.cpp:39:9:39:21 | *#this [a] |
| by_reference.cpp:57:8:57:8 | s indirection [a] | by_reference.cpp:57:10:57:22 | call to getIndirectly |
| by_reference.cpp:62:3:62:3 | setThroughNonMember output argument [a] | by_reference.cpp:63:8:63:8 | s indirection [a] |
| by_reference.cpp:62:5:62:23 | call to user_input | by_reference.cpp:23:34:23:38 | value |
| by_reference.cpp:62:5:62:23 | call to user_input | by_reference.cpp:62:3:62:3 | setThroughNonMember output argument [a] |
| by_reference.cpp:62:25:62:34 | call to user_input | by_reference.cpp:62:5:62:23 | call to user_input |
| by_reference.cpp:63:8:63:8 | s indirection [a] | by_reference.cpp:43:9:43:27 | *#this [a] |
| by_reference.cpp:63:8:63:8 | s indirection [a] | by_reference.cpp:63:10:63:28 | call to getThroughNonMember |
| by_reference.cpp:68:3:68:15 | call to user_input | by_reference.cpp:11:48:11:52 | value |
| by_reference.cpp:68:3:68:15 | call to user_input | by_reference.cpp:68:17:68:18 | nonMemberSetA output argument [a] |
| by_reference.cpp:68:17:68:18 | nonMemberSetA output argument [a] | by_reference.cpp:69:22:69:23 | & ... indirection [a] |
| by_reference.cpp:68:21:68:30 | call to user_input | by_reference.cpp:68:3:68:15 | call to user_input |
| by_reference.cpp:69:22:69:23 | & ... indirection [a] | by_reference.cpp:31:46:31:46 | *s [a] |
| by_reference.cpp:69:22:69:23 | & ... indirection [a] | by_reference.cpp:69:8:69:20 | call to nonMemberGetA |
| by_reference.cpp:84:3:84:25 | Chi [a] | by_reference.cpp:102:21:102:39 | taint_inner_a_ptr output argument [a] |
| by_reference.cpp:84:3:84:25 | Chi [a] | by_reference.cpp:106:21:106:41 | taint_inner_a_ptr output argument [a] |
@@ -134,48 +172,73 @@ edges
| by_reference.cpp:128:15:128:23 | Chi | by_reference.cpp:128:15:128:23 | Chi [a] |
| by_reference.cpp:128:15:128:23 | Chi [a] | by_reference.cpp:136:16:136:16 | a |
| by_reference.cpp:128:15:128:23 | taint_a_ref output argument [[]] | by_reference.cpp:128:15:128:23 | Chi |
| complex.cpp:9:7:9:7 | *#this [a_] | complex.cpp:9:20:9:21 | Store |
| complex.cpp:10:7:10:7 | *#this [b_] | complex.cpp:10:20:10:21 | Store |
| complex.cpp:11:17:11:17 | a | complex.cpp:11:22:11:27 | Chi [a_] |
| complex.cpp:12:8:12:11 | *#this [a_] | complex.cpp:12:22:12:27 | Chi [a_] |
| complex.cpp:12:17:12:17 | b | complex.cpp:12:22:12:27 | Chi [b_] |
| complex.cpp:40:17:40:17 | *b [a_] | complex.cpp:42:16:42:16 | f indirection [a_] |
| complex.cpp:40:17:40:17 | *b [b_] | complex.cpp:42:16:42:16 | f indirection [b_] |
| complex.cpp:40:17:40:17 | *b [b_] | complex.cpp:43:16:43:16 | f indirection [b_] |
| complex.cpp:42:16:42:16 | a output argument [b_] | complex.cpp:43:16:43:16 | f indirection [b_] |
| complex.cpp:42:16:42:16 | f indirection [a_] | complex.cpp:9:7:9:7 | *#this [a_] |
| complex.cpp:42:16:42:16 | f indirection [a_] | complex.cpp:42:18:42:18 | call to a |
| complex.cpp:42:16:42:16 | f indirection [b_] | complex.cpp:9:7:9:7 | *#this [b_] |
| complex.cpp:42:16:42:16 | f indirection [b_] | complex.cpp:42:16:42:16 | a output argument [b_] |
| complex.cpp:43:16:43:16 | f indirection [b_] | complex.cpp:10:7:10:7 | *#this [b_] |
| complex.cpp:43:16:43:16 | f indirection [b_] | complex.cpp:43:18:43:18 | call to b |
| complex.cpp:53:12:53:12 | setA output argument [a_] | complex.cpp:59:7:59:8 | b1 indirection [a_] |
| complex.cpp:53:14:53:17 | call to user_input | complex.cpp:11:17:11:17 | a |
| complex.cpp:53:14:53:17 | call to user_input | complex.cpp:53:12:53:12 | setA output argument [a_] |
| complex.cpp:53:19:53:28 | call to user_input | complex.cpp:53:14:53:17 | call to user_input |
| complex.cpp:54:12:54:12 | setB output argument [b_] | complex.cpp:62:7:62:8 | b2 indirection [b_] |
| complex.cpp:54:14:54:17 | call to user_input | complex.cpp:12:17:12:17 | b |
| complex.cpp:54:14:54:17 | call to user_input | complex.cpp:54:12:54:12 | setB output argument [b_] |
| complex.cpp:54:19:54:28 | call to user_input | complex.cpp:54:14:54:17 | call to user_input |
| complex.cpp:55:12:55:12 | setA output argument [a_] | complex.cpp:56:12:56:12 | f indirection [a_] |
| complex.cpp:55:12:55:12 | setA output argument [a_] | complex.cpp:65:7:65:8 | b3 indirection [a_] |
| complex.cpp:55:14:55:17 | call to user_input | complex.cpp:11:17:11:17 | a |
| complex.cpp:55:14:55:17 | call to user_input | complex.cpp:55:12:55:12 | setA output argument [a_] |
| complex.cpp:55:19:55:28 | call to user_input | complex.cpp:55:14:55:17 | call to user_input |
| complex.cpp:56:12:56:12 | f indirection [a_] | complex.cpp:12:8:12:11 | *#this [a_] |
| complex.cpp:56:12:56:12 | f indirection [a_] | complex.cpp:56:12:56:12 | setB output argument [a_] |
| complex.cpp:56:12:56:12 | setB output argument [a_] | complex.cpp:65:7:65:8 | b3 indirection [a_] |
| complex.cpp:56:12:56:12 | setB output argument [b_] | complex.cpp:65:7:65:8 | b3 indirection [b_] |
| complex.cpp:56:14:56:17 | call to user_input | complex.cpp:12:17:12:17 | b |
| complex.cpp:56:14:56:17 | call to user_input | complex.cpp:56:12:56:12 | setB output argument [b_] |
| complex.cpp:56:19:56:28 | call to user_input | complex.cpp:56:14:56:17 | call to user_input |
| complex.cpp:59:7:59:8 | b1 indirection [a_] | complex.cpp:40:17:40:17 | *b [a_] |
| complex.cpp:62:7:62:8 | b2 indirection [b_] | complex.cpp:40:17:40:17 | *b [b_] |
| complex.cpp:65:7:65:8 | b3 indirection [a_] | complex.cpp:40:17:40:17 | *b [a_] |
| complex.cpp:65:7:65:8 | b3 indirection [b_] | complex.cpp:40:17:40:17 | *b [b_] |
| constructors.cpp:18:9:18:9 | *#this [a_] | constructors.cpp:18:22:18:23 | Store |
| constructors.cpp:19:9:19:9 | *#this [b_] | constructors.cpp:19:22:19:23 | Store |
| constructors.cpp:23:13:23:13 | a | constructors.cpp:23:28:23:28 | Chi [a_] |
| constructors.cpp:23:20:23:20 | b | constructors.cpp:23:35:23:35 | Chi [b_] |
| constructors.cpp:23:28:23:28 | Chi [a_] | constructors.cpp:23:35:23:35 | Chi [a_] |
| constructors.cpp:26:15:26:15 | *f [a_] | constructors.cpp:28:10:28:10 | f indirection [a_] |
| constructors.cpp:26:15:26:15 | *f [b_] | constructors.cpp:28:10:28:10 | f indirection [b_] |
| constructors.cpp:26:15:26:15 | *f [b_] | constructors.cpp:29:10:29:10 | f indirection [b_] |
| constructors.cpp:28:10:28:10 | a output argument [b_] | constructors.cpp:29:10:29:10 | f indirection [b_] |
| constructors.cpp:28:10:28:10 | f indirection [a_] | constructors.cpp:18:9:18:9 | *#this [a_] |
| constructors.cpp:28:10:28:10 | f indirection [a_] | constructors.cpp:28:12:28:12 | call to a |
| constructors.cpp:28:10:28:10 | f indirection [b_] | constructors.cpp:18:9:18:9 | *#this [b_] |
| constructors.cpp:28:10:28:10 | f indirection [b_] | constructors.cpp:28:10:28:10 | a output argument [b_] |
| constructors.cpp:29:10:29:10 | f indirection [b_] | constructors.cpp:19:9:19:9 | *#this [b_] |
| constructors.cpp:29:10:29:10 | f indirection [b_] | constructors.cpp:29:12:29:12 | call to b |
| constructors.cpp:34:11:34:20 | call to user_input | constructors.cpp:34:11:34:26 | call to user_input |
| constructors.cpp:34:11:34:26 | Foo output argument [a_] | constructors.cpp:40:9:40:9 | f indirection [a_] |
| constructors.cpp:34:11:34:26 | call to user_input | constructors.cpp:23:13:23:13 | a |
| constructors.cpp:34:11:34:26 | call to user_input | constructors.cpp:34:11:34:26 | Foo output argument [a_] |
| constructors.cpp:35:11:35:26 | Foo output argument [b_] | constructors.cpp:43:9:43:9 | g indirection [b_] |
| constructors.cpp:35:11:35:26 | call to user_input | constructors.cpp:23:20:23:20 | b |
| constructors.cpp:35:11:35:26 | call to user_input | constructors.cpp:35:11:35:26 | Foo output argument [b_] |
| constructors.cpp:35:14:35:23 | call to user_input | constructors.cpp:35:11:35:26 | call to user_input |
| constructors.cpp:36:11:36:20 | call to user_input | constructors.cpp:36:11:36:37 | call to user_input |
| constructors.cpp:36:11:36:37 | Foo output argument [a_] | constructors.cpp:46:9:46:9 | h indirection [a_] |
| constructors.cpp:36:11:36:37 | Foo output argument [b_] | constructors.cpp:46:9:46:9 | h indirection [b_] |
| constructors.cpp:36:11:36:37 | call to user_input | constructors.cpp:23:13:23:13 | a |
| constructors.cpp:36:11:36:37 | call to user_input | constructors.cpp:23:20:23:20 | b |
| constructors.cpp:36:11:36:37 | call to user_input | constructors.cpp:36:11:36:37 | Foo output argument [a_] |
| constructors.cpp:36:11:36:37 | call to user_input | constructors.cpp:36:11:36:37 | Foo output argument [b_] |
| constructors.cpp:36:25:36:34 | call to user_input | constructors.cpp:36:11:36:37 | call to user_input |
@@ -183,26 +246,39 @@ edges
| constructors.cpp:43:9:43:9 | g indirection [b_] | constructors.cpp:26:15:26:15 | *f [b_] |
| constructors.cpp:46:9:46:9 | h indirection [a_] | constructors.cpp:26:15:26:15 | *f [a_] |
| constructors.cpp:46:9:46:9 | h indirection [b_] | constructors.cpp:26:15:26:15 | *f [b_] |
| simple.cpp:18:9:18:9 | *#this [a_] | simple.cpp:18:22:18:23 | Store |
| simple.cpp:19:9:19:9 | *#this [b_] | simple.cpp:19:22:19:23 | Store |
| simple.cpp:20:19:20:19 | a | simple.cpp:20:24:20:29 | Chi [a_] |
| simple.cpp:21:10:21:13 | *#this [a_] | simple.cpp:21:24:21:29 | Chi [a_] |
| simple.cpp:21:19:21:19 | b | simple.cpp:21:24:21:29 | Chi [b_] |
| simple.cpp:26:15:26:15 | *f [a_] | simple.cpp:28:10:28:10 | f indirection [a_] |
| simple.cpp:26:15:26:15 | *f [b_] | simple.cpp:28:10:28:10 | f indirection [b_] |
| simple.cpp:26:15:26:15 | *f [b_] | simple.cpp:29:10:29:10 | f indirection [b_] |
| simple.cpp:28:10:28:10 | a output argument [b_] | simple.cpp:29:10:29:10 | f indirection [b_] |
| simple.cpp:28:10:28:10 | f indirection [a_] | simple.cpp:18:9:18:9 | *#this [a_] |
| simple.cpp:28:10:28:10 | f indirection [a_] | simple.cpp:28:12:28:12 | call to a |
| simple.cpp:28:10:28:10 | f indirection [b_] | simple.cpp:18:9:18:9 | *#this [b_] |
| simple.cpp:28:10:28:10 | f indirection [b_] | simple.cpp:28:10:28:10 | a output argument [b_] |
| simple.cpp:29:10:29:10 | f indirection [b_] | simple.cpp:19:9:19:9 | *#this [b_] |
| simple.cpp:29:10:29:10 | f indirection [b_] | simple.cpp:29:12:29:12 | call to b |
| simple.cpp:39:5:39:5 | setA output argument [a_] | simple.cpp:45:9:45:9 | f indirection [a_] |
| simple.cpp:39:7:39:10 | call to user_input | simple.cpp:20:19:20:19 | a |
| simple.cpp:39:7:39:10 | call to user_input | simple.cpp:39:5:39:5 | setA output argument [a_] |
| simple.cpp:39:12:39:21 | call to user_input | simple.cpp:39:7:39:10 | call to user_input |
| simple.cpp:40:5:40:5 | setB output argument [b_] | simple.cpp:48:9:48:9 | g indirection [b_] |
| simple.cpp:40:7:40:10 | call to user_input | simple.cpp:21:19:21:19 | b |
| simple.cpp:40:7:40:10 | call to user_input | simple.cpp:40:5:40:5 | setB output argument [b_] |
| simple.cpp:40:12:40:21 | call to user_input | simple.cpp:40:7:40:10 | call to user_input |
| simple.cpp:41:5:41:5 | setA output argument [a_] | simple.cpp:42:5:42:5 | h indirection [a_] |
| simple.cpp:41:5:41:5 | setA output argument [a_] | simple.cpp:51:9:51:9 | h indirection [a_] |
| simple.cpp:41:7:41:10 | call to user_input | simple.cpp:20:19:20:19 | a |
| simple.cpp:41:7:41:10 | call to user_input | simple.cpp:41:5:41:5 | setA output argument [a_] |
| simple.cpp:41:12:41:21 | call to user_input | simple.cpp:41:7:41:10 | call to user_input |
| simple.cpp:42:5:42:5 | h indirection [a_] | simple.cpp:21:10:21:13 | *#this [a_] |
| simple.cpp:42:5:42:5 | h indirection [a_] | simple.cpp:42:5:42:5 | setB output argument [a_] |
| simple.cpp:42:5:42:5 | setB output argument [a_] | simple.cpp:51:9:51:9 | h indirection [a_] |
| simple.cpp:42:5:42:5 | setB output argument [b_] | simple.cpp:51:9:51:9 | h indirection [b_] |
| simple.cpp:42:7:42:10 | call to user_input | simple.cpp:21:19:21:19 | b |
| simple.cpp:42:7:42:10 | call to user_input | simple.cpp:42:5:42:5 | setB output argument [b_] |
| simple.cpp:42:12:42:21 | call to user_input | simple.cpp:42:7:42:10 | call to user_input |
| simple.cpp:45:9:45:9 | f indirection [a_] | simple.cpp:26:15:26:15 | *f [a_] |
@@ -212,8 +288,10 @@ edges
| simple.cpp:65:5:65:22 | Store [i] | simple.cpp:66:12:66:12 | Store [i] |
| simple.cpp:65:11:65:20 | call to user_input | simple.cpp:65:5:65:22 | Store [i] |
| simple.cpp:66:12:66:12 | Store [i] | simple.cpp:67:13:67:13 | i |
| simple.cpp:78:9:78:15 | *#this [f1] | simple.cpp:79:19:79:20 | Store |
| simple.cpp:83:9:83:28 | Store [f1] | simple.cpp:84:14:84:20 | this indirection [f1] |
| simple.cpp:83:17:83:26 | call to user_input | simple.cpp:83:9:83:28 | Store [f1] |
| simple.cpp:84:14:84:20 | this indirection [f1] | simple.cpp:78:9:78:15 | *#this [f1] |
| simple.cpp:84:14:84:20 | this indirection [f1] | simple.cpp:84:14:84:20 | call to getf2f1 |
| simple.cpp:92:5:92:22 | Store [i] | simple.cpp:93:20:93:20 | Store [i] |
| simple.cpp:92:11:92:20 | call to user_input | simple.cpp:92:5:92:22 | Store [i] |
@@ -228,6 +306,12 @@ edges
| struct_init.c:27:7:27:16 | call to user_input | struct_init.c:31:23:31:23 | a |
| struct_init.c:36:10:36:24 | & ... indirection [a] | struct_init.c:14:24:14:25 | *ab [a] |
nodes
| A.cpp:23:10:23:10 | c | semmle.label | c |
| A.cpp:25:7:25:17 | Chi [c] | semmle.label | Chi [c] |
| A.cpp:27:17:27:17 | c | semmle.label | c |
| A.cpp:27:22:27:32 | Chi [c] | semmle.label | Chi [c] |
| A.cpp:28:8:28:10 | *#this [c] | semmle.label | *#this [c] |
| A.cpp:28:29:28:29 | Store | semmle.label | Store |
| A.cpp:55:5:55:5 | set output argument [c] | semmle.label | set output argument [c] |
| A.cpp:55:8:55:10 | new | semmle.label | new |
| A.cpp:55:12:55:19 | (C *)... | semmle.label | (C *)... |
@@ -251,9 +335,11 @@ nodes
| A.cpp:131:8:131:8 | Chi [c] | semmle.label | Chi [c] |
| A.cpp:131:8:131:8 | f7 output argument [c] | semmle.label | f7 output argument [c] |
| A.cpp:132:13:132:13 | c | semmle.label | c |
| A.cpp:140:13:140:13 | b | semmle.label | b |
| A.cpp:142:7:142:20 | Chi [c] | semmle.label | Chi [c] |
| A.cpp:142:14:142:20 | new | semmle.label | new |
| A.cpp:143:7:143:31 | Chi [b] | semmle.label | Chi [b] |
| A.cpp:143:7:143:31 | Chi [b] | semmle.label | Chi [b] |
| A.cpp:143:25:143:31 | new | semmle.label | new |
| A.cpp:150:12:150:18 | new | semmle.label | new |
| A.cpp:151:12:151:24 | Chi [b] | semmle.label | Chi [b] |
@@ -336,6 +422,30 @@ nodes
| arrays.cpp:16:8:16:13 | access to array | semmle.label | access to array |
| arrays.cpp:36:26:36:35 | call to user_input | semmle.label | call to user_input |
| arrays.cpp:37:24:37:27 | data | semmle.label | data |
| by_reference.cpp:11:48:11:52 | value | semmle.label | value |
| by_reference.cpp:12:5:12:16 | Chi [a] | semmle.label | Chi [a] |
| by_reference.cpp:15:26:15:30 | value | semmle.label | value |
| by_reference.cpp:16:5:16:19 | Chi [a] | semmle.label | Chi [a] |
| by_reference.cpp:19:28:19:32 | value | semmle.label | value |
| by_reference.cpp:20:5:20:8 | Chi [a] | semmle.label | Chi [a] |
| by_reference.cpp:20:5:20:8 | setDirectly output argument [a] | semmle.label | setDirectly output argument [a] |
| by_reference.cpp:20:11:20:21 | value | semmle.label | value |
| by_reference.cpp:23:34:23:38 | value | semmle.label | value |
| by_reference.cpp:24:5:24:17 | value | semmle.label | value |
| by_reference.cpp:24:19:24:22 | Chi [a] | semmle.label | Chi [a] |
| by_reference.cpp:24:19:24:22 | nonMemberSetA output argument [a] | semmle.label | nonMemberSetA output argument [a] |
| by_reference.cpp:31:46:31:46 | *s [a] | semmle.label | *s [a] |
| by_reference.cpp:32:15:32:15 | Store | semmle.label | Store |
| by_reference.cpp:35:9:35:19 | *#this [a] | semmle.label | *#this [a] |
| by_reference.cpp:36:18:36:18 | Store | semmle.label | Store |
| by_reference.cpp:39:9:39:21 | *#this [a] | semmle.label | *#this [a] |
| by_reference.cpp:40:12:40:15 | this indirection [a] | semmle.label | this indirection [a] |
| by_reference.cpp:40:18:40:28 | Store | semmle.label | Store |
| by_reference.cpp:40:18:40:28 | call to getDirectly | semmle.label | call to getDirectly |
| by_reference.cpp:43:9:43:27 | *#this [a] | semmle.label | *#this [a] |
| by_reference.cpp:44:12:44:24 | Store | semmle.label | Store |
| by_reference.cpp:44:12:44:24 | call to nonMemberGetA | semmle.label | call to nonMemberGetA |
| by_reference.cpp:44:26:44:29 | this indirection [a] | semmle.label | this indirection [a] |
| by_reference.cpp:50:3:50:3 | setDirectly output argument [a] | semmle.label | setDirectly output argument [a] |
| by_reference.cpp:50:5:50:15 | call to user_input | semmle.label | call to user_input |
| by_reference.cpp:50:17:50:26 | call to user_input | semmle.label | call to user_input |
@@ -392,6 +502,17 @@ nodes
| by_reference.cpp:132:14:132:14 | a | semmle.label | a |
| by_reference.cpp:134:29:134:29 | a | semmle.label | a |
| by_reference.cpp:136:16:136:16 | a | semmle.label | a |
| complex.cpp:9:7:9:7 | *#this [a_] | semmle.label | *#this [a_] |
| complex.cpp:9:7:9:7 | *#this [b_] | semmle.label | *#this [b_] |
| complex.cpp:9:20:9:21 | Store | semmle.label | Store |
| complex.cpp:10:7:10:7 | *#this [b_] | semmle.label | *#this [b_] |
| complex.cpp:10:20:10:21 | Store | semmle.label | Store |
| complex.cpp:11:17:11:17 | a | semmle.label | a |
| complex.cpp:11:22:11:27 | Chi [a_] | semmle.label | Chi [a_] |
| complex.cpp:12:8:12:11 | *#this [a_] | semmle.label | *#this [a_] |
| complex.cpp:12:17:12:17 | b | semmle.label | b |
| complex.cpp:12:22:12:27 | Chi [a_] | semmle.label | Chi [a_] |
| complex.cpp:12:22:12:27 | Chi [b_] | semmle.label | Chi [b_] |
| complex.cpp:40:17:40:17 | *b [a_] | semmle.label | *b [a_] |
| complex.cpp:40:17:40:17 | *b [b_] | semmle.label | *b [b_] |
| complex.cpp:42:16:42:16 | a output argument [b_] | semmle.label | a output argument [b_] |
@@ -418,6 +539,16 @@ nodes
| complex.cpp:62:7:62:8 | b2 indirection [b_] | semmle.label | b2 indirection [b_] |
| complex.cpp:65:7:65:8 | b3 indirection [a_] | semmle.label | b3 indirection [a_] |
| complex.cpp:65:7:65:8 | b3 indirection [b_] | semmle.label | b3 indirection [b_] |
| constructors.cpp:18:9:18:9 | *#this [a_] | semmle.label | *#this [a_] |
| constructors.cpp:18:9:18:9 | *#this [b_] | semmle.label | *#this [b_] |
| constructors.cpp:18:22:18:23 | Store | semmle.label | Store |
| constructors.cpp:19:9:19:9 | *#this [b_] | semmle.label | *#this [b_] |
| constructors.cpp:19:22:19:23 | Store | semmle.label | Store |
| constructors.cpp:23:13:23:13 | a | semmle.label | a |
| constructors.cpp:23:20:23:20 | b | semmle.label | b |
| constructors.cpp:23:28:23:28 | Chi [a_] | semmle.label | Chi [a_] |
| constructors.cpp:23:35:23:35 | Chi [a_] | semmle.label | Chi [a_] |
| constructors.cpp:23:35:23:35 | Chi [b_] | semmle.label | Chi [b_] |
| constructors.cpp:26:15:26:15 | *f [a_] | semmle.label | *f [a_] |
| constructors.cpp:26:15:26:15 | *f [b_] | semmle.label | *f [b_] |
| constructors.cpp:28:10:28:10 | a output argument [b_] | semmle.label | a output argument [b_] |
@@ -442,6 +573,17 @@ nodes
| constructors.cpp:43:9:43:9 | g indirection [b_] | semmle.label | g indirection [b_] |
| constructors.cpp:46:9:46:9 | h indirection [a_] | semmle.label | h indirection [a_] |
| constructors.cpp:46:9:46:9 | h indirection [b_] | semmle.label | h indirection [b_] |
| simple.cpp:18:9:18:9 | *#this [a_] | semmle.label | *#this [a_] |
| simple.cpp:18:9:18:9 | *#this [b_] | semmle.label | *#this [b_] |
| simple.cpp:18:22:18:23 | Store | semmle.label | Store |
| simple.cpp:19:9:19:9 | *#this [b_] | semmle.label | *#this [b_] |
| simple.cpp:19:22:19:23 | Store | semmle.label | Store |
| simple.cpp:20:19:20:19 | a | semmle.label | a |
| simple.cpp:20:24:20:29 | Chi [a_] | semmle.label | Chi [a_] |
| simple.cpp:21:10:21:13 | *#this [a_] | semmle.label | *#this [a_] |
| simple.cpp:21:19:21:19 | b | semmle.label | b |
| simple.cpp:21:24:21:29 | Chi [a_] | semmle.label | Chi [a_] |
| simple.cpp:21:24:21:29 | Chi [b_] | semmle.label | Chi [b_] |
| simple.cpp:26:15:26:15 | *f [a_] | semmle.label | *f [a_] |
| simple.cpp:26:15:26:15 | *f [b_] | semmle.label | *f [b_] |
| simple.cpp:28:10:28:10 | a output argument [b_] | semmle.label | a output argument [b_] |
@@ -472,6 +614,8 @@ nodes
| simple.cpp:65:11:65:20 | call to user_input | semmle.label | call to user_input |
| simple.cpp:66:12:66:12 | Store [i] | semmle.label | Store [i] |
| simple.cpp:67:13:67:13 | i | semmle.label | i |
| simple.cpp:78:9:78:15 | *#this [f1] | semmle.label | *#this [f1] |
| simple.cpp:79:19:79:20 | Store | semmle.label | Store |
| simple.cpp:83:9:83:28 | Store [f1] | semmle.label | Store [f1] |
| simple.cpp:83:17:83:26 | call to user_input | semmle.label | call to user_input |
| simple.cpp:84:14:84:20 | call to getf2f1 | semmle.label | call to getf2f1 |
@@ -490,6 +634,49 @@ nodes
| struct_init.c:27:7:27:16 | call to user_input | semmle.label | call to user_input |
| struct_init.c:31:23:31:23 | a | semmle.label | a |
| struct_init.c:36:10:36:24 | & ... indirection [a] | semmle.label | & ... indirection [a] |
subpaths
| A.cpp:55:8:55:10 | new | A.cpp:27:17:27:17 | c | A.cpp:27:22:27:32 | Chi [c] | A.cpp:55:5:55:5 | set output argument [c] |
| A.cpp:56:10:56:10 | b indirection [c] | A.cpp:28:8:28:10 | *#this [c] | A.cpp:28:29:28:29 | Store | A.cpp:56:13:56:15 | call to get |
| A.cpp:57:10:57:25 | new indirection [c] | A.cpp:28:8:28:10 | *#this [c] | A.cpp:28:29:28:29 | Store | A.cpp:57:28:57:30 | call to get |
| A.cpp:57:11:57:24 | new | A.cpp:23:10:23:10 | c | A.cpp:25:7:25:17 | Chi [c] | A.cpp:57:11:57:24 | B output argument [c] |
| A.cpp:126:8:126:10 | new | A.cpp:27:17:27:17 | c | A.cpp:27:22:27:32 | Chi [c] | A.cpp:126:5:126:5 | set output argument [c] |
| A.cpp:151:12:151:24 | b | A.cpp:140:13:140:13 | b | A.cpp:143:7:143:31 | Chi [b] | A.cpp:151:12:151:24 | D output argument [b] |
| by_reference.cpp:20:11:20:21 | value | by_reference.cpp:15:26:15:30 | value | by_reference.cpp:16:5:16:19 | Chi [a] | by_reference.cpp:20:5:20:8 | setDirectly output argument [a] |
| by_reference.cpp:24:5:24:17 | value | by_reference.cpp:11:48:11:52 | value | by_reference.cpp:12:5:12:16 | Chi [a] | by_reference.cpp:24:19:24:22 | nonMemberSetA output argument [a] |
| by_reference.cpp:40:12:40:15 | this indirection [a] | by_reference.cpp:35:9:35:19 | *#this [a] | by_reference.cpp:36:18:36:18 | Store | by_reference.cpp:40:18:40:28 | call to getDirectly |
| by_reference.cpp:44:26:44:29 | this indirection [a] | by_reference.cpp:31:46:31:46 | *s [a] | by_reference.cpp:32:15:32:15 | Store | by_reference.cpp:44:12:44:24 | call to nonMemberGetA |
| by_reference.cpp:50:5:50:15 | call to user_input | by_reference.cpp:15:26:15:30 | value | by_reference.cpp:16:5:16:19 | Chi [a] | by_reference.cpp:50:3:50:3 | setDirectly output argument [a] |
| by_reference.cpp:51:8:51:8 | s indirection [a] | by_reference.cpp:35:9:35:19 | *#this [a] | by_reference.cpp:36:18:36:18 | Store | by_reference.cpp:51:10:51:20 | call to getDirectly |
| by_reference.cpp:56:5:56:17 | call to user_input | by_reference.cpp:19:28:19:32 | value | by_reference.cpp:20:5:20:8 | Chi [a] | by_reference.cpp:56:3:56:3 | setIndirectly output argument [a] |
| by_reference.cpp:57:8:57:8 | s indirection [a] | by_reference.cpp:39:9:39:21 | *#this [a] | by_reference.cpp:40:18:40:28 | Store | by_reference.cpp:57:10:57:22 | call to getIndirectly |
| by_reference.cpp:62:5:62:23 | call to user_input | by_reference.cpp:23:34:23:38 | value | by_reference.cpp:24:19:24:22 | Chi [a] | by_reference.cpp:62:3:62:3 | setThroughNonMember output argument [a] |
| by_reference.cpp:63:8:63:8 | s indirection [a] | by_reference.cpp:43:9:43:27 | *#this [a] | by_reference.cpp:44:12:44:24 | Store | by_reference.cpp:63:10:63:28 | call to getThroughNonMember |
| by_reference.cpp:68:3:68:15 | call to user_input | by_reference.cpp:11:48:11:52 | value | by_reference.cpp:12:5:12:16 | Chi [a] | by_reference.cpp:68:17:68:18 | nonMemberSetA output argument [a] |
| by_reference.cpp:69:22:69:23 | & ... indirection [a] | by_reference.cpp:31:46:31:46 | *s [a] | by_reference.cpp:32:15:32:15 | Store | by_reference.cpp:69:8:69:20 | call to nonMemberGetA |
| complex.cpp:42:16:42:16 | f indirection [a_] | complex.cpp:9:7:9:7 | *#this [a_] | complex.cpp:9:20:9:21 | Store | complex.cpp:42:18:42:18 | call to a |
| complex.cpp:42:16:42:16 | f indirection [b_] | complex.cpp:9:7:9:7 | *#this [b_] | complex.cpp:9:7:9:7 | *#this [b_] | complex.cpp:42:16:42:16 | a output argument [b_] |
| complex.cpp:43:16:43:16 | f indirection [b_] | complex.cpp:10:7:10:7 | *#this [b_] | complex.cpp:10:20:10:21 | Store | complex.cpp:43:18:43:18 | call to b |
| complex.cpp:53:14:53:17 | call to user_input | complex.cpp:11:17:11:17 | a | complex.cpp:11:22:11:27 | Chi [a_] | complex.cpp:53:12:53:12 | setA output argument [a_] |
| complex.cpp:54:14:54:17 | call to user_input | complex.cpp:12:17:12:17 | b | complex.cpp:12:22:12:27 | Chi [b_] | complex.cpp:54:12:54:12 | setB output argument [b_] |
| complex.cpp:55:14:55:17 | call to user_input | complex.cpp:11:17:11:17 | a | complex.cpp:11:22:11:27 | Chi [a_] | complex.cpp:55:12:55:12 | setA output argument [a_] |
| complex.cpp:56:12:56:12 | f indirection [a_] | complex.cpp:12:8:12:11 | *#this [a_] | complex.cpp:12:22:12:27 | Chi [a_] | complex.cpp:56:12:56:12 | setB output argument [a_] |
| complex.cpp:56:14:56:17 | call to user_input | complex.cpp:12:17:12:17 | b | complex.cpp:12:22:12:27 | Chi [b_] | complex.cpp:56:12:56:12 | setB output argument [b_] |
| constructors.cpp:28:10:28:10 | f indirection [a_] | constructors.cpp:18:9:18:9 | *#this [a_] | constructors.cpp:18:22:18:23 | Store | constructors.cpp:28:12:28:12 | call to a |
| constructors.cpp:28:10:28:10 | f indirection [b_] | constructors.cpp:18:9:18:9 | *#this [b_] | constructors.cpp:18:9:18:9 | *#this [b_] | constructors.cpp:28:10:28:10 | a output argument [b_] |
| constructors.cpp:29:10:29:10 | f indirection [b_] | constructors.cpp:19:9:19:9 | *#this [b_] | constructors.cpp:19:22:19:23 | Store | constructors.cpp:29:12:29:12 | call to b |
| constructors.cpp:34:11:34:26 | call to user_input | constructors.cpp:23:13:23:13 | a | constructors.cpp:23:35:23:35 | Chi [a_] | constructors.cpp:34:11:34:26 | Foo output argument [a_] |
| constructors.cpp:35:11:35:26 | call to user_input | constructors.cpp:23:20:23:20 | b | constructors.cpp:23:35:23:35 | Chi [b_] | constructors.cpp:35:11:35:26 | Foo output argument [b_] |
| constructors.cpp:36:11:36:37 | call to user_input | constructors.cpp:23:13:23:13 | a | constructors.cpp:23:35:23:35 | Chi [a_] | constructors.cpp:36:11:36:37 | Foo output argument [a_] |
| constructors.cpp:36:11:36:37 | call to user_input | constructors.cpp:23:20:23:20 | b | constructors.cpp:23:35:23:35 | Chi [b_] | constructors.cpp:36:11:36:37 | Foo output argument [b_] |
| simple.cpp:28:10:28:10 | f indirection [a_] | simple.cpp:18:9:18:9 | *#this [a_] | simple.cpp:18:22:18:23 | Store | simple.cpp:28:12:28:12 | call to a |
| simple.cpp:28:10:28:10 | f indirection [b_] | simple.cpp:18:9:18:9 | *#this [b_] | simple.cpp:18:9:18:9 | *#this [b_] | simple.cpp:28:10:28:10 | a output argument [b_] |
| simple.cpp:29:10:29:10 | f indirection [b_] | simple.cpp:19:9:19:9 | *#this [b_] | simple.cpp:19:22:19:23 | Store | simple.cpp:29:12:29:12 | call to b |
| simple.cpp:39:7:39:10 | call to user_input | simple.cpp:20:19:20:19 | a | simple.cpp:20:24:20:29 | Chi [a_] | simple.cpp:39:5:39:5 | setA output argument [a_] |
| simple.cpp:40:7:40:10 | call to user_input | simple.cpp:21:19:21:19 | b | simple.cpp:21:24:21:29 | Chi [b_] | simple.cpp:40:5:40:5 | setB output argument [b_] |
| simple.cpp:41:7:41:10 | call to user_input | simple.cpp:20:19:20:19 | a | simple.cpp:20:24:20:29 | Chi [a_] | simple.cpp:41:5:41:5 | setA output argument [a_] |
| simple.cpp:42:5:42:5 | h indirection [a_] | simple.cpp:21:10:21:13 | *#this [a_] | simple.cpp:21:24:21:29 | Chi [a_] | simple.cpp:42:5:42:5 | setB output argument [a_] |
| simple.cpp:42:7:42:10 | call to user_input | simple.cpp:21:19:21:19 | b | simple.cpp:21:24:21:29 | Chi [b_] | simple.cpp:42:5:42:5 | setB output argument [b_] |
| simple.cpp:84:14:84:20 | this indirection [f1] | simple.cpp:78:9:78:15 | *#this [f1] | simple.cpp:79:19:79:20 | Store | simple.cpp:84:14:84:20 | call to getf2f1 |
#select
| A.cpp:56:13:56:15 | call to get | A.cpp:55:12:55:19 | (C *)... | A.cpp:56:13:56:15 | call to get | call to get flows from $@ | A.cpp:55:12:55:19 | (C *)... | (C *)... |
| A.cpp:56:13:56:15 | call to get | A.cpp:55:12:55:19 | new | A.cpp:56:13:56:15 | call to get | call to get flows from $@ | A.cpp:55:12:55:19 | new | new |

View File

@@ -1,21 +1,46 @@
edges
| A.cpp:23:10:23:10 | c | A.cpp:25:7:25:17 | ... = ... |
| A.cpp:25:7:25:17 | ... = ... | A.cpp:25:7:25:10 | this [post update] [c] |
| A.cpp:27:17:27:17 | c | A.cpp:27:22:27:32 | ... = ... |
| A.cpp:27:22:27:32 | ... = ... | A.cpp:27:22:27:25 | this [post update] [c] |
| A.cpp:28:8:28:10 | this [c] | A.cpp:28:23:28:26 | this [c] |
| A.cpp:28:23:28:26 | this [c] | A.cpp:28:29:28:29 | c |
| A.cpp:29:23:29:23 | c | A.cpp:31:20:31:20 | c |
| A.cpp:31:14:31:21 | call to B [c] | A.cpp:31:14:31:21 | new [c] |
| A.cpp:31:20:31:20 | c | A.cpp:23:10:23:10 | c |
| A.cpp:31:20:31:20 | c | A.cpp:31:14:31:21 | call to B [c] |
| A.cpp:41:15:41:21 | new | A.cpp:43:10:43:12 | & ... |
| A.cpp:47:12:47:18 | new | A.cpp:48:20:48:20 | c |
| A.cpp:48:12:48:18 | call to make [c] | A.cpp:49:10:49:10 | b [c] |
| A.cpp:48:20:48:20 | c | A.cpp:29:23:29:23 | c |
| A.cpp:48:20:48:20 | c | A.cpp:48:12:48:18 | call to make [c] |
| A.cpp:49:10:49:10 | b [c] | A.cpp:49:13:49:13 | c |
| A.cpp:55:5:55:5 | ref arg b [c] | A.cpp:56:10:56:10 | b [c] |
| A.cpp:55:12:55:19 | new | A.cpp:27:17:27:17 | c |
| A.cpp:55:12:55:19 | new | A.cpp:55:5:55:5 | ref arg b [c] |
| A.cpp:56:10:56:10 | b [c] | A.cpp:28:8:28:10 | this [c] |
| A.cpp:56:10:56:10 | b [c] | A.cpp:56:13:56:15 | call to get |
| A.cpp:57:11:57:24 | call to B [c] | A.cpp:57:11:57:24 | new [c] |
| A.cpp:57:11:57:24 | new [c] | A.cpp:28:8:28:10 | this [c] |
| A.cpp:57:11:57:24 | new [c] | A.cpp:57:28:57:30 | call to get |
| A.cpp:57:17:57:23 | new | A.cpp:23:10:23:10 | c |
| A.cpp:57:17:57:23 | new | A.cpp:57:11:57:24 | call to B [c] |
| A.cpp:64:10:64:15 | call to setOnB [c] | A.cpp:66:10:66:11 | b2 [c] |
| A.cpp:64:21:64:28 | new | A.cpp:64:10:64:15 | call to setOnB [c] |
| A.cpp:64:21:64:28 | new | A.cpp:85:26:85:26 | c |
| A.cpp:66:10:66:11 | b2 [c] | A.cpp:66:14:66:14 | c |
| A.cpp:73:10:73:19 | call to setOnBWrap [c] | A.cpp:75:10:75:11 | b2 [c] |
| A.cpp:73:25:73:32 | new | A.cpp:73:10:73:19 | call to setOnBWrap [c] |
| A.cpp:73:25:73:32 | new | A.cpp:78:27:78:27 | c |
| A.cpp:75:10:75:11 | b2 [c] | A.cpp:75:14:75:14 | c |
| A.cpp:78:27:78:27 | c | A.cpp:81:21:81:21 | c |
| A.cpp:81:10:81:15 | call to setOnB [c] | A.cpp:82:12:82:24 | ... ? ... : ... [c] |
| A.cpp:81:21:81:21 | c | A.cpp:81:10:81:15 | call to setOnB [c] |
| A.cpp:81:21:81:21 | c | A.cpp:85:26:85:26 | c |
| A.cpp:85:26:85:26 | c | A.cpp:90:15:90:15 | c |
| A.cpp:90:7:90:8 | ref arg b2 [c] | A.cpp:91:14:91:15 | b2 [c] |
| A.cpp:90:15:90:15 | c | A.cpp:27:17:27:17 | c |
| A.cpp:90:15:90:15 | c | A.cpp:90:7:90:8 | ref arg b2 [c] |
| A.cpp:98:12:98:18 | new | A.cpp:100:5:100:13 | ... = ... |
| A.cpp:100:5:100:6 | c1 [post update] [a] | A.cpp:101:8:101:9 | c1 [a] |
| A.cpp:100:5:100:13 | ... = ... | A.cpp:100:5:100:6 | c1 [post update] [a] |
@@ -25,9 +50,11 @@ edges
| A.cpp:107:12:107:13 | c1 [a] | A.cpp:107:16:107:16 | a |
| A.cpp:120:12:120:13 | c1 [a] | A.cpp:120:16:120:16 | a |
| A.cpp:126:5:126:5 | ref arg b [c] | A.cpp:131:8:131:8 | ref arg b [c] |
| A.cpp:126:12:126:18 | new | A.cpp:27:17:27:17 | c |
| A.cpp:126:12:126:18 | new | A.cpp:126:5:126:5 | ref arg b [c] |
| A.cpp:131:8:131:8 | ref arg b [c] | A.cpp:132:10:132:10 | b [c] |
| A.cpp:132:10:132:10 | b [c] | A.cpp:132:13:132:13 | c |
| A.cpp:140:13:140:13 | b | A.cpp:143:7:143:31 | ... = ... |
| A.cpp:142:7:142:7 | b [post update] [c] | A.cpp:143:7:143:31 | ... = ... [c] |
| A.cpp:142:7:142:7 | b [post update] [c] | A.cpp:151:18:151:18 | ref arg b [c] |
| A.cpp:142:7:142:20 | ... = ... | A.cpp:142:7:142:7 | b [post update] [c] |
@@ -35,11 +62,13 @@ edges
| A.cpp:143:7:143:10 | this [post update] [b, c] | A.cpp:151:12:151:24 | call to D [b, c] |
| A.cpp:143:7:143:10 | this [post update] [b] | A.cpp:151:12:151:24 | call to D [b] |
| A.cpp:143:7:143:31 | ... = ... | A.cpp:143:7:143:10 | this [post update] [b] |
| A.cpp:143:7:143:31 | ... = ... | A.cpp:143:7:143:10 | this [post update] [b] |
| A.cpp:143:7:143:31 | ... = ... [c] | A.cpp:143:7:143:10 | this [post update] [b, c] |
| A.cpp:143:25:143:31 | new | A.cpp:143:7:143:31 | ... = ... |
| A.cpp:150:12:150:18 | new | A.cpp:151:18:151:18 | b |
| A.cpp:151:12:151:24 | call to D [b, c] | A.cpp:153:10:153:10 | d [b, c] |
| A.cpp:151:12:151:24 | call to D [b] | A.cpp:152:10:152:10 | d [b] |
| A.cpp:151:18:151:18 | b | A.cpp:140:13:140:13 | b |
| A.cpp:151:18:151:18 | b | A.cpp:151:12:151:24 | call to D [b] |
| A.cpp:151:18:151:18 | ref arg b [c] | A.cpp:154:10:154:10 | b [c] |
| A.cpp:152:10:152:10 | d [b] | A.cpp:152:13:152:13 | b |
@@ -49,11 +78,14 @@ edges
| A.cpp:159:12:159:18 | new | A.cpp:160:29:160:29 | b |
| A.cpp:160:18:160:60 | call to MyList [head] | A.cpp:161:38:161:39 | l1 [head] |
| A.cpp:160:29:160:29 | b | A.cpp:160:18:160:60 | call to MyList [head] |
| A.cpp:160:29:160:29 | b | A.cpp:181:15:181:21 | newHead |
| A.cpp:161:18:161:40 | call to MyList [next, head] | A.cpp:162:38:162:39 | l2 [next, head] |
| A.cpp:161:38:161:39 | l1 [head] | A.cpp:161:18:161:40 | call to MyList [next, head] |
| A.cpp:161:38:161:39 | l1 [head] | A.cpp:181:32:181:35 | next [head] |
| A.cpp:162:18:162:40 | call to MyList [next, next, head] | A.cpp:165:10:165:11 | l3 [next, next, head] |
| A.cpp:162:18:162:40 | call to MyList [next, next, head] | A.cpp:167:44:167:44 | l [next, next, head] |
| A.cpp:162:38:162:39 | l2 [next, head] | A.cpp:162:18:162:40 | call to MyList [next, next, head] |
| A.cpp:162:38:162:39 | l2 [next, head] | A.cpp:181:32:181:35 | next [next, head] |
| A.cpp:165:10:165:11 | l3 [next, next, head] | A.cpp:165:14:165:17 | next [next, head] |
| A.cpp:165:14:165:17 | next [next, head] | A.cpp:165:20:165:23 | next [head] |
| A.cpp:165:20:165:23 | next [head] | A.cpp:165:26:165:29 | head |
@@ -62,20 +94,38 @@ edges
| A.cpp:167:47:167:50 | next [head] | A.cpp:169:12:169:12 | l [head] |
| A.cpp:167:47:167:50 | next [next, head] | A.cpp:167:44:167:44 | l [next, head] |
| A.cpp:169:12:169:12 | l [head] | A.cpp:169:15:169:18 | head |
| A.cpp:181:15:181:21 | newHead | A.cpp:183:7:183:20 | ... = ... |
| A.cpp:181:32:181:35 | next [head] | A.cpp:184:7:184:23 | ... = ... [head] |
| A.cpp:181:32:181:35 | next [next, head] | A.cpp:184:7:184:23 | ... = ... [next, head] |
| A.cpp:183:7:183:20 | ... = ... | A.cpp:183:7:183:10 | this [post update] [head] |
| A.cpp:184:7:184:23 | ... = ... [head] | A.cpp:184:7:184:10 | this [post update] [next, head] |
| A.cpp:184:7:184:23 | ... = ... [next, head] | A.cpp:184:7:184:10 | this [post update] [next, next, head] |
| B.cpp:6:15:6:24 | new | B.cpp:7:25:7:25 | e |
| B.cpp:7:16:7:35 | call to Box1 [elem1] | B.cpp:8:25:8:26 | b1 [elem1] |
| B.cpp:7:25:7:25 | e | B.cpp:7:16:7:35 | call to Box1 [elem1] |
| B.cpp:7:25:7:25 | e | B.cpp:33:16:33:17 | e1 |
| B.cpp:8:16:8:27 | call to Box2 [box1, elem1] | B.cpp:9:10:9:11 | b2 [box1, elem1] |
| B.cpp:8:25:8:26 | b1 [elem1] | B.cpp:8:16:8:27 | call to Box2 [box1, elem1] |
| B.cpp:8:25:8:26 | b1 [elem1] | B.cpp:44:16:44:17 | b1 [elem1] |
| B.cpp:9:10:9:11 | b2 [box1, elem1] | B.cpp:9:14:9:17 | box1 [elem1] |
| B.cpp:9:14:9:17 | box1 [elem1] | B.cpp:9:20:9:24 | elem1 |
| B.cpp:15:15:15:27 | new | B.cpp:16:37:16:37 | e |
| B.cpp:16:16:16:38 | call to Box1 [elem2] | B.cpp:17:25:17:26 | b1 [elem2] |
| B.cpp:16:37:16:37 | e | B.cpp:16:16:16:38 | call to Box1 [elem2] |
| B.cpp:16:37:16:37 | e | B.cpp:33:26:33:27 | e2 |
| B.cpp:17:16:17:27 | call to Box2 [box1, elem2] | B.cpp:19:10:19:11 | b2 [box1, elem2] |
| B.cpp:17:25:17:26 | b1 [elem2] | B.cpp:17:16:17:27 | call to Box2 [box1, elem2] |
| B.cpp:17:25:17:26 | b1 [elem2] | B.cpp:44:16:44:17 | b1 [elem2] |
| B.cpp:19:10:19:11 | b2 [box1, elem2] | B.cpp:19:14:19:17 | box1 [elem2] |
| B.cpp:19:14:19:17 | box1 [elem2] | B.cpp:19:20:19:24 | elem2 |
| B.cpp:33:16:33:17 | e1 | B.cpp:35:7:35:22 | ... = ... |
| B.cpp:33:26:33:27 | e2 | B.cpp:36:7:36:22 | ... = ... |
| B.cpp:35:7:35:22 | ... = ... | B.cpp:35:7:35:10 | this [post update] [elem1] |
| B.cpp:36:7:36:22 | ... = ... | B.cpp:36:7:36:10 | this [post update] [elem2] |
| B.cpp:44:16:44:17 | b1 [elem1] | B.cpp:46:7:46:21 | ... = ... [elem1] |
| B.cpp:44:16:44:17 | b1 [elem2] | B.cpp:46:7:46:21 | ... = ... [elem2] |
| B.cpp:46:7:46:21 | ... = ... [elem1] | B.cpp:46:7:46:10 | this [post update] [box1, elem1] |
| B.cpp:46:7:46:21 | ... = ... [elem2] | B.cpp:46:7:46:10 | this [post update] [box1, elem2] |
| C.cpp:18:12:18:18 | call to C [s1] | C.cpp:19:5:19:5 | c [s1] |
| C.cpp:18:12:18:18 | call to C [s3] | C.cpp:19:5:19:5 | c [s3] |
| C.cpp:19:5:19:5 | c [s1] | C.cpp:27:8:27:11 | this [s1] |
@@ -89,8 +139,16 @@ edges
| C.cpp:27:8:27:11 | this [s3] | C.cpp:31:10:31:11 | this [s3] |
| C.cpp:29:10:29:11 | this [s1] | C.cpp:29:10:29:11 | s1 |
| C.cpp:31:10:31:11 | this [s3] | C.cpp:31:10:31:11 | s3 |
| D.cpp:10:11:10:17 | this [elem] | D.cpp:10:30:10:33 | this [elem] |
| D.cpp:10:30:10:33 | this [elem] | D.cpp:10:30:10:33 | elem |
| D.cpp:11:24:11:24 | e | D.cpp:11:29:11:36 | ... = ... |
| D.cpp:11:29:11:36 | ... = ... | D.cpp:11:29:11:32 | this [post update] [elem] |
| D.cpp:17:11:17:17 | this [box, elem] | D.cpp:17:30:17:32 | this [box, elem] |
| D.cpp:17:30:17:32 | this [box, elem] | D.cpp:17:30:17:32 | box [elem] |
| D.cpp:21:30:21:31 | b2 [box, elem] | D.cpp:22:10:22:11 | b2 [box, elem] |
| D.cpp:22:10:22:11 | b2 [box, elem] | D.cpp:17:11:17:17 | this [box, elem] |
| D.cpp:22:10:22:11 | b2 [box, elem] | D.cpp:22:14:22:20 | call to getBox1 [elem] |
| D.cpp:22:14:22:20 | call to getBox1 [elem] | D.cpp:10:11:10:17 | this [elem] |
| D.cpp:22:14:22:20 | call to getBox1 [elem] | D.cpp:22:25:22:31 | call to getElem |
| D.cpp:28:15:28:24 | new | D.cpp:30:5:30:20 | ... = ... |
| D.cpp:30:5:30:5 | b [post update] [box, elem] | D.cpp:31:14:31:14 | b [box, elem] |
@@ -100,6 +158,7 @@ edges
| D.cpp:35:15:35:24 | new | D.cpp:37:21:37:21 | e |
| D.cpp:37:5:37:5 | b [post update] [box, elem] | D.cpp:38:14:38:14 | b [box, elem] |
| D.cpp:37:8:37:10 | ref arg box [elem] | D.cpp:37:5:37:5 | b [post update] [box, elem] |
| D.cpp:37:21:37:21 | e | D.cpp:11:24:11:24 | e |
| D.cpp:37:21:37:21 | e | D.cpp:37:8:37:10 | ref arg box [elem] |
| D.cpp:38:14:38:14 | b [box, elem] | D.cpp:21:30:21:31 | b2 [box, elem] |
| D.cpp:42:15:42:24 | new | D.cpp:44:5:44:26 | ... = ... |
@@ -110,6 +169,7 @@ edges
| D.cpp:49:15:49:24 | new | D.cpp:51:27:51:27 | e |
| D.cpp:51:5:51:5 | ref arg b [box, elem] | D.cpp:52:14:52:14 | b [box, elem] |
| D.cpp:51:8:51:14 | ref arg call to getBox1 [elem] | D.cpp:51:5:51:5 | ref arg b [box, elem] |
| D.cpp:51:27:51:27 | e | D.cpp:11:24:11:24 | e |
| D.cpp:51:27:51:27 | e | D.cpp:51:8:51:14 | ref arg call to getBox1 [elem] |
| D.cpp:52:14:52:14 | b [box, elem] | D.cpp:21:30:21:31 | b2 [box, elem] |
| D.cpp:56:15:56:24 | new | D.cpp:58:5:58:27 | ... = ... |
@@ -223,17 +283,45 @@ edges
| arrays.cpp:44:8:44:25 | access to array [data] | arrays.cpp:44:27:44:30 | data |
| arrays.cpp:44:10:44:17 | indirect [arr, data] | arrays.cpp:44:20:44:22 | arr [data] |
| arrays.cpp:44:20:44:22 | arr [data] | arrays.cpp:44:8:44:25 | access to array [data] |
| by_reference.cpp:11:48:11:52 | value | by_reference.cpp:12:5:12:16 | ... = ... |
| by_reference.cpp:12:5:12:16 | ... = ... | by_reference.cpp:12:5:12:5 | s [post update] [a] |
| by_reference.cpp:15:26:15:30 | value | by_reference.cpp:16:5:16:19 | ... = ... |
| by_reference.cpp:16:5:16:19 | ... = ... | by_reference.cpp:16:5:16:8 | this [post update] [a] |
| by_reference.cpp:19:28:19:32 | value | by_reference.cpp:20:23:20:27 | value |
| by_reference.cpp:20:23:20:27 | value | by_reference.cpp:15:26:15:30 | value |
| by_reference.cpp:20:23:20:27 | value | by_reference.cpp:20:5:20:8 | ref arg this [a] |
| by_reference.cpp:23:34:23:38 | value | by_reference.cpp:24:25:24:29 | value |
| by_reference.cpp:24:25:24:29 | value | by_reference.cpp:11:48:11:52 | value |
| by_reference.cpp:24:25:24:29 | value | by_reference.cpp:24:19:24:22 | ref arg this [a] |
| by_reference.cpp:31:46:31:46 | s [a] | by_reference.cpp:32:12:32:12 | s [a] |
| by_reference.cpp:32:12:32:12 | s [a] | by_reference.cpp:32:15:32:15 | a |
| by_reference.cpp:35:9:35:19 | this [a] | by_reference.cpp:36:12:36:15 | this [a] |
| by_reference.cpp:36:12:36:15 | this [a] | by_reference.cpp:36:18:36:18 | a |
| by_reference.cpp:39:9:39:21 | this [a] | by_reference.cpp:40:12:40:15 | this [a] |
| by_reference.cpp:40:12:40:15 | this [a] | by_reference.cpp:35:9:35:19 | this [a] |
| by_reference.cpp:40:12:40:15 | this [a] | by_reference.cpp:40:18:40:28 | call to getDirectly |
| by_reference.cpp:43:9:43:27 | this [a] | by_reference.cpp:44:26:44:29 | this [a] |
| by_reference.cpp:44:26:44:29 | this [a] | by_reference.cpp:31:46:31:46 | s [a] |
| by_reference.cpp:44:26:44:29 | this [a] | by_reference.cpp:44:12:44:24 | call to nonMemberGetA |
| by_reference.cpp:50:3:50:3 | ref arg s [a] | by_reference.cpp:51:8:51:8 | s [a] |
| by_reference.cpp:50:17:50:26 | call to user_input | by_reference.cpp:15:26:15:30 | value |
| by_reference.cpp:50:17:50:26 | call to user_input | by_reference.cpp:50:3:50:3 | ref arg s [a] |
| by_reference.cpp:51:8:51:8 | s [a] | by_reference.cpp:35:9:35:19 | this [a] |
| by_reference.cpp:51:8:51:8 | s [a] | by_reference.cpp:51:10:51:20 | call to getDirectly |
| by_reference.cpp:56:3:56:3 | ref arg s [a] | by_reference.cpp:57:8:57:8 | s [a] |
| by_reference.cpp:56:19:56:28 | call to user_input | by_reference.cpp:19:28:19:32 | value |
| by_reference.cpp:56:19:56:28 | call to user_input | by_reference.cpp:56:3:56:3 | ref arg s [a] |
| by_reference.cpp:57:8:57:8 | s [a] | by_reference.cpp:39:9:39:21 | this [a] |
| by_reference.cpp:57:8:57:8 | s [a] | by_reference.cpp:57:10:57:22 | call to getIndirectly |
| by_reference.cpp:62:3:62:3 | ref arg s [a] | by_reference.cpp:63:8:63:8 | s [a] |
| by_reference.cpp:62:25:62:34 | call to user_input | by_reference.cpp:23:34:23:38 | value |
| by_reference.cpp:62:25:62:34 | call to user_input | by_reference.cpp:62:3:62:3 | ref arg s [a] |
| by_reference.cpp:63:8:63:8 | s [a] | by_reference.cpp:43:9:43:27 | this [a] |
| by_reference.cpp:63:8:63:8 | s [a] | by_reference.cpp:63:10:63:28 | call to getThroughNonMember |
| by_reference.cpp:68:17:68:18 | ref arg & ... [a] | by_reference.cpp:69:22:69:23 | & ... [a] |
| by_reference.cpp:68:21:68:30 | call to user_input | by_reference.cpp:11:48:11:52 | value |
| by_reference.cpp:68:21:68:30 | call to user_input | by_reference.cpp:68:17:68:18 | ref arg & ... [a] |
| by_reference.cpp:69:22:69:23 | & ... [a] | by_reference.cpp:31:46:31:46 | s [a] |
| by_reference.cpp:69:22:69:23 | & ... [a] | by_reference.cpp:69:8:69:20 | call to nonMemberGetA |
| by_reference.cpp:84:3:84:7 | inner [post update] [a] | by_reference.cpp:102:21:102:39 | ref arg & ... [a] |
| by_reference.cpp:84:3:84:7 | inner [post update] [a] | by_reference.cpp:103:27:103:35 | ref arg inner_ptr [a] |
@@ -308,29 +396,43 @@ edges
| by_reference.cpp:135:8:135:13 | pouter [inner_ptr, a] | by_reference.cpp:135:16:135:24 | inner_ptr [a] |
| by_reference.cpp:135:16:135:24 | inner_ptr [a] | by_reference.cpp:135:27:135:27 | a |
| by_reference.cpp:136:8:136:13 | pouter [a] | by_reference.cpp:136:16:136:16 | a |
| complex.cpp:9:7:9:7 | this [a_] | complex.cpp:9:20:9:21 | this [a_] |
| complex.cpp:9:20:9:21 | this [a_] | complex.cpp:9:20:9:21 | a_ |
| complex.cpp:10:7:10:7 | this [b_] | complex.cpp:10:20:10:21 | this [b_] |
| complex.cpp:10:20:10:21 | this [b_] | complex.cpp:10:20:10:21 | b_ |
| complex.cpp:11:17:11:17 | a | complex.cpp:11:22:11:27 | ... = ... |
| complex.cpp:11:22:11:27 | ... = ... | complex.cpp:11:22:11:23 | this [post update] [a_] |
| complex.cpp:12:17:12:17 | b | complex.cpp:12:22:12:27 | ... = ... |
| complex.cpp:12:22:12:27 | ... = ... | complex.cpp:12:22:12:23 | this [post update] [b_] |
| complex.cpp:40:17:40:17 | b [inner, f, a_] | complex.cpp:42:8:42:8 | b [inner, f, a_] |
| complex.cpp:40:17:40:17 | b [inner, f, b_] | complex.cpp:43:8:43:8 | b [inner, f, b_] |
| complex.cpp:42:8:42:8 | b [inner, f, a_] | complex.cpp:42:10:42:14 | inner [f, a_] |
| complex.cpp:42:10:42:14 | inner [f, a_] | complex.cpp:42:16:42:16 | f [a_] |
| complex.cpp:42:16:42:16 | f [a_] | complex.cpp:9:7:9:7 | this [a_] |
| complex.cpp:42:16:42:16 | f [a_] | complex.cpp:42:18:42:18 | call to a |
| complex.cpp:43:8:43:8 | b [inner, f, b_] | complex.cpp:43:10:43:14 | inner [f, b_] |
| complex.cpp:43:10:43:14 | inner [f, b_] | complex.cpp:43:16:43:16 | f [b_] |
| complex.cpp:43:16:43:16 | f [b_] | complex.cpp:10:7:10:7 | this [b_] |
| complex.cpp:43:16:43:16 | f [b_] | complex.cpp:43:18:43:18 | call to b |
| complex.cpp:53:3:53:4 | b1 [post update] [inner, f, a_] | complex.cpp:59:7:59:8 | b1 [inner, f, a_] |
| complex.cpp:53:6:53:10 | inner [post update] [f, a_] | complex.cpp:53:3:53:4 | b1 [post update] [inner, f, a_] |
| complex.cpp:53:12:53:12 | ref arg f [a_] | complex.cpp:53:6:53:10 | inner [post update] [f, a_] |
| complex.cpp:53:19:53:28 | call to user_input | complex.cpp:11:17:11:17 | a |
| complex.cpp:53:19:53:28 | call to user_input | complex.cpp:53:12:53:12 | ref arg f [a_] |
| complex.cpp:54:3:54:4 | b2 [post update] [inner, f, b_] | complex.cpp:62:7:62:8 | b2 [inner, f, b_] |
| complex.cpp:54:6:54:10 | inner [post update] [f, b_] | complex.cpp:54:3:54:4 | b2 [post update] [inner, f, b_] |
| complex.cpp:54:12:54:12 | ref arg f [b_] | complex.cpp:54:6:54:10 | inner [post update] [f, b_] |
| complex.cpp:54:19:54:28 | call to user_input | complex.cpp:12:17:12:17 | b |
| complex.cpp:54:19:54:28 | call to user_input | complex.cpp:54:12:54:12 | ref arg f [b_] |
| complex.cpp:55:3:55:4 | b3 [post update] [inner, f, a_] | complex.cpp:65:7:65:8 | b3 [inner, f, a_] |
| complex.cpp:55:6:55:10 | inner [post update] [f, a_] | complex.cpp:55:3:55:4 | b3 [post update] [inner, f, a_] |
| complex.cpp:55:12:55:12 | ref arg f [a_] | complex.cpp:55:6:55:10 | inner [post update] [f, a_] |
| complex.cpp:55:19:55:28 | call to user_input | complex.cpp:11:17:11:17 | a |
| complex.cpp:55:19:55:28 | call to user_input | complex.cpp:55:12:55:12 | ref arg f [a_] |
| complex.cpp:56:3:56:4 | b3 [post update] [inner, f, b_] | complex.cpp:65:7:65:8 | b3 [inner, f, b_] |
| complex.cpp:56:6:56:10 | inner [post update] [f, b_] | complex.cpp:56:3:56:4 | b3 [post update] [inner, f, b_] |
| complex.cpp:56:12:56:12 | ref arg f [b_] | complex.cpp:56:6:56:10 | inner [post update] [f, b_] |
| complex.cpp:56:19:56:28 | call to user_input | complex.cpp:12:17:12:17 | b |
| complex.cpp:56:19:56:28 | call to user_input | complex.cpp:56:12:56:12 | ref arg f [b_] |
| complex.cpp:59:7:59:8 | b1 [inner, f, a_] | complex.cpp:40:17:40:17 | b [inner, f, a_] |
| complex.cpp:62:7:62:8 | b2 [inner, f, b_] | complex.cpp:40:17:40:17 | b [inner, f, b_] |
@@ -357,22 +459,43 @@ edges
| conflated.cpp:60:17:60:26 | call to user_input | conflated.cpp:60:3:60:28 | ... = ... |
| conflated.cpp:61:8:61:9 | ll [next, y] | conflated.cpp:61:12:61:15 | next [y] |
| conflated.cpp:61:12:61:15 | next [y] | conflated.cpp:61:18:61:18 | y |
| constructors.cpp:18:9:18:9 | this [a_] | constructors.cpp:18:22:18:23 | this [a_] |
| constructors.cpp:18:22:18:23 | this [a_] | constructors.cpp:18:22:18:23 | a_ |
| constructors.cpp:19:9:19:9 | this [b_] | constructors.cpp:19:22:19:23 | this [b_] |
| constructors.cpp:19:22:19:23 | this [b_] | constructors.cpp:19:22:19:23 | b_ |
| constructors.cpp:23:13:23:13 | a | constructors.cpp:23:28:23:28 | a |
| constructors.cpp:23:20:23:20 | b | constructors.cpp:23:35:23:35 | b |
| constructors.cpp:23:28:23:28 | a | constructors.cpp:23:25:23:29 | constructor init of field a_ [post-this] [a_] |
| constructors.cpp:23:35:23:35 | b | constructors.cpp:23:32:23:36 | constructor init of field b_ [post-this] [b_] |
| constructors.cpp:26:15:26:15 | f [a_] | constructors.cpp:28:10:28:10 | f [a_] |
| constructors.cpp:26:15:26:15 | f [b_] | constructors.cpp:29:10:29:10 | f [b_] |
| constructors.cpp:28:10:28:10 | f [a_] | constructors.cpp:18:9:18:9 | this [a_] |
| constructors.cpp:28:10:28:10 | f [a_] | constructors.cpp:28:12:28:12 | call to a |
| constructors.cpp:29:10:29:10 | f [b_] | constructors.cpp:19:9:19:9 | this [b_] |
| constructors.cpp:29:10:29:10 | f [b_] | constructors.cpp:29:12:29:12 | call to b |
| constructors.cpp:34:11:34:20 | call to user_input | constructors.cpp:23:13:23:13 | a |
| constructors.cpp:34:11:34:20 | call to user_input | constructors.cpp:34:11:34:26 | call to Foo [a_] |
| constructors.cpp:34:11:34:26 | call to Foo [a_] | constructors.cpp:40:9:40:9 | f [a_] |
| constructors.cpp:35:11:35:26 | call to Foo [b_] | constructors.cpp:43:9:43:9 | g [b_] |
| constructors.cpp:35:14:35:23 | call to user_input | constructors.cpp:23:20:23:20 | b |
| constructors.cpp:35:14:35:23 | call to user_input | constructors.cpp:35:11:35:26 | call to Foo [b_] |
| constructors.cpp:36:11:36:20 | call to user_input | constructors.cpp:23:13:23:13 | a |
| constructors.cpp:36:11:36:20 | call to user_input | constructors.cpp:36:11:36:37 | call to Foo [a_] |
| constructors.cpp:36:11:36:37 | call to Foo [a_] | constructors.cpp:46:9:46:9 | h [a_] |
| constructors.cpp:36:11:36:37 | call to Foo [b_] | constructors.cpp:46:9:46:9 | h [b_] |
| constructors.cpp:36:25:36:34 | call to user_input | constructors.cpp:23:20:23:20 | b |
| constructors.cpp:36:25:36:34 | call to user_input | constructors.cpp:36:11:36:37 | call to Foo [b_] |
| constructors.cpp:40:9:40:9 | f [a_] | constructors.cpp:26:15:26:15 | f [a_] |
| constructors.cpp:43:9:43:9 | g [b_] | constructors.cpp:26:15:26:15 | f [b_] |
| constructors.cpp:46:9:46:9 | h [a_] | constructors.cpp:26:15:26:15 | f [a_] |
| constructors.cpp:46:9:46:9 | h [b_] | constructors.cpp:26:15:26:15 | f [b_] |
| qualifiers.cpp:9:21:9:25 | value | qualifiers.cpp:9:30:9:44 | ... = ... |
| qualifiers.cpp:9:30:9:44 | ... = ... | qualifiers.cpp:9:30:9:33 | this [post update] [a] |
| qualifiers.cpp:12:40:12:44 | value | qualifiers.cpp:12:49:12:64 | ... = ... |
| qualifiers.cpp:12:49:12:64 | ... = ... | qualifiers.cpp:12:49:12:53 | inner [post update] [a] |
| qualifiers.cpp:13:42:13:46 | value | qualifiers.cpp:13:51:13:65 | ... = ... |
| qualifiers.cpp:13:51:13:55 | inner [post update] [a] | qualifiers.cpp:13:29:13:33 | inner [a] |
| qualifiers.cpp:13:51:13:65 | ... = ... | qualifiers.cpp:13:51:13:55 | inner [post update] [a] |
| qualifiers.cpp:22:5:22:9 | ref arg outer [inner, a] | qualifiers.cpp:23:10:23:14 | outer [inner, a] |
| qualifiers.cpp:22:5:22:38 | ... = ... | qualifiers.cpp:22:11:22:18 | call to getInner [post update] [a] |
| qualifiers.cpp:22:11:22:18 | call to getInner [post update] [a] | qualifiers.cpp:22:5:22:9 | ref arg outer [inner, a] |
@@ -381,17 +504,20 @@ edges
| qualifiers.cpp:23:16:23:20 | inner [a] | qualifiers.cpp:23:23:23:23 | a |
| qualifiers.cpp:27:5:27:9 | ref arg outer [inner, a] | qualifiers.cpp:28:10:28:14 | outer [inner, a] |
| qualifiers.cpp:27:11:27:18 | ref arg call to getInner [a] | qualifiers.cpp:27:5:27:9 | ref arg outer [inner, a] |
| qualifiers.cpp:27:28:27:37 | call to user_input | qualifiers.cpp:9:21:9:25 | value |
| qualifiers.cpp:27:28:27:37 | call to user_input | qualifiers.cpp:27:11:27:18 | ref arg call to getInner [a] |
| qualifiers.cpp:28:10:28:14 | outer [inner, a] | qualifiers.cpp:28:16:28:20 | inner [a] |
| qualifiers.cpp:28:16:28:20 | inner [a] | qualifiers.cpp:28:23:28:23 | a |
| qualifiers.cpp:32:17:32:21 | ref arg outer [inner, a] | qualifiers.cpp:33:10:33:14 | outer [inner, a] |
| qualifiers.cpp:32:23:32:30 | ref arg call to getInner [a] | qualifiers.cpp:32:17:32:21 | ref arg outer [inner, a] |
| qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:12:40:12:44 | value |
| qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:32:23:32:30 | ref arg call to getInner [a] |
| qualifiers.cpp:33:10:33:14 | outer [inner, a] | qualifiers.cpp:33:16:33:20 | inner [a] |
| qualifiers.cpp:33:16:33:20 | inner [a] | qualifiers.cpp:33:23:33:23 | a |
| qualifiers.cpp:37:19:37:35 | ref arg * ... [a] | qualifiers.cpp:37:26:37:33 | call to getInner [inner post update] [a] |
| qualifiers.cpp:37:20:37:24 | ref arg outer [inner, a] | qualifiers.cpp:38:10:38:14 | outer [inner, a] |
| qualifiers.cpp:37:26:37:33 | call to getInner [inner post update] [a] | qualifiers.cpp:37:20:37:24 | ref arg outer [inner, a] |
| qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:13:42:13:46 | value |
| qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:37:19:37:35 | ref arg * ... [a] |
| qualifiers.cpp:38:10:38:14 | outer [inner, a] | qualifiers.cpp:38:16:38:20 | inner [a] |
| qualifiers.cpp:38:16:38:20 | inner [a] | qualifiers.cpp:38:23:38:23 | a |
@@ -420,17 +546,31 @@ edges
| realistic.cpp:61:25:61:27 | bar [baz, userInput, bufferLen] | realistic.cpp:61:21:61:30 | access to array [baz, userInput, bufferLen] |
| realistic.cpp:61:32:61:34 | baz [userInput, bufferLen] | realistic.cpp:61:37:61:45 | userInput [bufferLen] |
| realistic.cpp:61:37:61:45 | userInput [bufferLen] | realistic.cpp:61:47:61:55 | bufferLen |
| simple.cpp:18:9:18:9 | this [a_] | simple.cpp:18:22:18:23 | this [a_] |
| simple.cpp:18:22:18:23 | this [a_] | simple.cpp:18:22:18:23 | a_ |
| simple.cpp:19:9:19:9 | this [b_] | simple.cpp:19:22:19:23 | this [b_] |
| simple.cpp:19:22:19:23 | this [b_] | simple.cpp:19:22:19:23 | b_ |
| simple.cpp:20:19:20:19 | a | simple.cpp:20:24:20:29 | ... = ... |
| simple.cpp:20:24:20:29 | ... = ... | simple.cpp:20:24:20:25 | this [post update] [a_] |
| simple.cpp:21:19:21:19 | b | simple.cpp:21:24:21:29 | ... = ... |
| simple.cpp:21:24:21:29 | ... = ... | simple.cpp:21:24:21:25 | this [post update] [b_] |
| simple.cpp:26:15:26:15 | f [a_] | simple.cpp:28:10:28:10 | f [a_] |
| simple.cpp:26:15:26:15 | f [b_] | simple.cpp:29:10:29:10 | f [b_] |
| simple.cpp:28:10:28:10 | f [a_] | simple.cpp:18:9:18:9 | this [a_] |
| simple.cpp:28:10:28:10 | f [a_] | simple.cpp:28:12:28:12 | call to a |
| simple.cpp:29:10:29:10 | f [b_] | simple.cpp:19:9:19:9 | this [b_] |
| simple.cpp:29:10:29:10 | f [b_] | simple.cpp:29:12:29:12 | call to b |
| simple.cpp:39:5:39:5 | ref arg f [a_] | simple.cpp:45:9:45:9 | f [a_] |
| simple.cpp:39:12:39:21 | call to user_input | simple.cpp:20:19:20:19 | a |
| simple.cpp:39:12:39:21 | call to user_input | simple.cpp:39:5:39:5 | ref arg f [a_] |
| simple.cpp:40:5:40:5 | ref arg g [b_] | simple.cpp:48:9:48:9 | g [b_] |
| simple.cpp:40:12:40:21 | call to user_input | simple.cpp:21:19:21:19 | b |
| simple.cpp:40:12:40:21 | call to user_input | simple.cpp:40:5:40:5 | ref arg g [b_] |
| simple.cpp:41:5:41:5 | ref arg h [a_] | simple.cpp:51:9:51:9 | h [a_] |
| simple.cpp:41:12:41:21 | call to user_input | simple.cpp:20:19:20:19 | a |
| simple.cpp:41:12:41:21 | call to user_input | simple.cpp:41:5:41:5 | ref arg h [a_] |
| simple.cpp:42:5:42:5 | ref arg h [b_] | simple.cpp:51:9:51:9 | h [b_] |
| simple.cpp:42:12:42:21 | call to user_input | simple.cpp:21:19:21:19 | b |
| simple.cpp:42:12:42:21 | call to user_input | simple.cpp:42:5:42:5 | ref arg h [b_] |
| simple.cpp:45:9:45:9 | f [a_] | simple.cpp:26:15:26:15 | f [a_] |
| simple.cpp:48:9:48:9 | g [b_] | simple.cpp:26:15:26:15 | f [b_] |
@@ -440,10 +580,14 @@ edges
| simple.cpp:65:5:65:22 | ... = ... | simple.cpp:65:5:65:5 | a [post update] [i] |
| simple.cpp:65:11:65:20 | call to user_input | simple.cpp:65:5:65:22 | ... = ... |
| simple.cpp:67:10:67:11 | a2 [i] | simple.cpp:67:13:67:13 | i |
| simple.cpp:78:9:78:15 | this [f2, f1] | simple.cpp:79:16:79:17 | this [f2, f1] |
| simple.cpp:79:16:79:17 | f2 [f1] | simple.cpp:79:19:79:20 | f1 |
| simple.cpp:79:16:79:17 | this [f2, f1] | simple.cpp:79:16:79:17 | f2 [f1] |
| simple.cpp:83:9:83:10 | f2 [post update] [f1] | simple.cpp:83:9:83:10 | this [post update] [f2, f1] |
| simple.cpp:83:9:83:10 | this [post update] [f2, f1] | simple.cpp:84:14:84:20 | this [f2, f1] |
| simple.cpp:83:9:83:28 | ... = ... | simple.cpp:83:9:83:10 | f2 [post update] [f1] |
| simple.cpp:83:17:83:26 | call to user_input | simple.cpp:83:9:83:28 | ... = ... |
| simple.cpp:84:14:84:20 | this [f2, f1] | simple.cpp:78:9:78:15 | this [f2, f1] |
| simple.cpp:84:14:84:20 | this [f2, f1] | simple.cpp:84:14:84:20 | call to getf2f1 |
| simple.cpp:92:5:92:5 | a [post update] [i] | simple.cpp:94:10:94:11 | a2 [i] |
| simple.cpp:92:5:92:22 | ... = ... | simple.cpp:92:5:92:5 | a [post update] [i] |
@@ -477,6 +621,19 @@ edges
| struct_init.c:46:10:46:14 | outer [pointerAB, a] | struct_init.c:46:16:46:24 | pointerAB [a] |
| struct_init.c:46:16:46:24 | pointerAB [a] | struct_init.c:14:24:14:25 | ab [a] |
nodes
| A.cpp:23:10:23:10 | c | semmle.label | c |
| A.cpp:25:7:25:10 | this [post update] [c] | semmle.label | this [post update] [c] |
| A.cpp:25:7:25:17 | ... = ... | semmle.label | ... = ... |
| A.cpp:27:17:27:17 | c | semmle.label | c |
| A.cpp:27:22:27:25 | this [post update] [c] | semmle.label | this [post update] [c] |
| A.cpp:27:22:27:32 | ... = ... | semmle.label | ... = ... |
| A.cpp:28:8:28:10 | this [c] | semmle.label | this [c] |
| A.cpp:28:23:28:26 | this [c] | semmle.label | this [c] |
| A.cpp:28:29:28:29 | c | semmle.label | c |
| A.cpp:29:23:29:23 | c | semmle.label | c |
| A.cpp:31:14:31:21 | call to B [c] | semmle.label | call to B [c] |
| A.cpp:31:14:31:21 | new [c] | semmle.label | new [c] |
| A.cpp:31:20:31:20 | c | semmle.label | c |
| A.cpp:41:15:41:21 | new | semmle.label | new |
| A.cpp:43:10:43:12 | & ... | semmle.label | & ... |
| A.cpp:47:12:47:18 | new | semmle.label | new |
@@ -500,6 +657,14 @@ nodes
| A.cpp:73:25:73:32 | new | semmle.label | new |
| A.cpp:75:10:75:11 | b2 [c] | semmle.label | b2 [c] |
| A.cpp:75:14:75:14 | c | semmle.label | c |
| A.cpp:78:27:78:27 | c | semmle.label | c |
| A.cpp:81:10:81:15 | call to setOnB [c] | semmle.label | call to setOnB [c] |
| A.cpp:81:21:81:21 | c | semmle.label | c |
| A.cpp:82:12:82:24 | ... ? ... : ... [c] | semmle.label | ... ? ... : ... [c] |
| A.cpp:85:26:85:26 | c | semmle.label | c |
| A.cpp:90:7:90:8 | ref arg b2 [c] | semmle.label | ref arg b2 [c] |
| A.cpp:90:15:90:15 | c | semmle.label | c |
| A.cpp:91:14:91:15 | b2 [c] | semmle.label | b2 [c] |
| A.cpp:98:12:98:18 | new | semmle.label | new |
| A.cpp:100:5:100:6 | c1 [post update] [a] | semmle.label | c1 [post update] [a] |
| A.cpp:100:5:100:13 | ... = ... | semmle.label | ... = ... |
@@ -514,11 +679,14 @@ nodes
| A.cpp:131:8:131:8 | ref arg b [c] | semmle.label | ref arg b [c] |
| A.cpp:132:10:132:10 | b [c] | semmle.label | b [c] |
| A.cpp:132:13:132:13 | c | semmle.label | c |
| A.cpp:140:13:140:13 | b | semmle.label | b |
| A.cpp:142:7:142:7 | b [post update] [c] | semmle.label | b [post update] [c] |
| A.cpp:142:7:142:20 | ... = ... | semmle.label | ... = ... |
| A.cpp:142:14:142:20 | new | semmle.label | new |
| A.cpp:143:7:143:10 | this [post update] [b, c] | semmle.label | this [post update] [b, c] |
| A.cpp:143:7:143:10 | this [post update] [b] | semmle.label | this [post update] [b] |
| A.cpp:143:7:143:10 | this [post update] [b] | semmle.label | this [post update] [b] |
| A.cpp:143:7:143:31 | ... = ... | semmle.label | ... = ... |
| A.cpp:143:7:143:31 | ... = ... | semmle.label | ... = ... |
| A.cpp:143:7:143:31 | ... = ... [c] | semmle.label | ... = ... [c] |
| A.cpp:143:25:143:31 | new | semmle.label | new |
@@ -551,6 +719,15 @@ nodes
| A.cpp:167:47:167:50 | next [next, head] | semmle.label | next [next, head] |
| A.cpp:169:12:169:12 | l [head] | semmle.label | l [head] |
| A.cpp:169:15:169:18 | head | semmle.label | head |
| A.cpp:181:15:181:21 | newHead | semmle.label | newHead |
| A.cpp:181:32:181:35 | next [head] | semmle.label | next [head] |
| A.cpp:181:32:181:35 | next [next, head] | semmle.label | next [next, head] |
| A.cpp:183:7:183:10 | this [post update] [head] | semmle.label | this [post update] [head] |
| A.cpp:183:7:183:20 | ... = ... | semmle.label | ... = ... |
| A.cpp:184:7:184:10 | this [post update] [next, head] | semmle.label | this [post update] [next, head] |
| A.cpp:184:7:184:10 | this [post update] [next, next, head] | semmle.label | this [post update] [next, next, head] |
| A.cpp:184:7:184:23 | ... = ... [head] | semmle.label | ... = ... [head] |
| A.cpp:184:7:184:23 | ... = ... [next, head] | semmle.label | ... = ... [next, head] |
| B.cpp:6:15:6:24 | new | semmle.label | new |
| B.cpp:7:16:7:35 | call to Box1 [elem1] | semmle.label | call to Box1 [elem1] |
| B.cpp:7:25:7:25 | e | semmle.label | e |
@@ -567,6 +744,18 @@ nodes
| B.cpp:19:10:19:11 | b2 [box1, elem2] | semmle.label | b2 [box1, elem2] |
| B.cpp:19:14:19:17 | box1 [elem2] | semmle.label | box1 [elem2] |
| B.cpp:19:20:19:24 | elem2 | semmle.label | elem2 |
| B.cpp:33:16:33:17 | e1 | semmle.label | e1 |
| B.cpp:33:26:33:27 | e2 | semmle.label | e2 |
| B.cpp:35:7:35:10 | this [post update] [elem1] | semmle.label | this [post update] [elem1] |
| B.cpp:35:7:35:22 | ... = ... | semmle.label | ... = ... |
| B.cpp:36:7:36:10 | this [post update] [elem2] | semmle.label | this [post update] [elem2] |
| B.cpp:36:7:36:22 | ... = ... | semmle.label | ... = ... |
| B.cpp:44:16:44:17 | b1 [elem1] | semmle.label | b1 [elem1] |
| B.cpp:44:16:44:17 | b1 [elem2] | semmle.label | b1 [elem2] |
| B.cpp:46:7:46:10 | this [post update] [box1, elem1] | semmle.label | this [post update] [box1, elem1] |
| B.cpp:46:7:46:10 | this [post update] [box1, elem2] | semmle.label | this [post update] [box1, elem2] |
| B.cpp:46:7:46:21 | ... = ... [elem1] | semmle.label | ... = ... [elem1] |
| B.cpp:46:7:46:21 | ... = ... [elem2] | semmle.label | ... = ... [elem2] |
| C.cpp:18:12:18:18 | call to C [s1] | semmle.label | call to C [s1] |
| C.cpp:18:12:18:18 | call to C [s3] | semmle.label | call to C [s3] |
| C.cpp:19:5:19:5 | c [s1] | semmle.label | c [s1] |
@@ -582,6 +771,15 @@ nodes
| C.cpp:29:10:29:11 | this [s1] | semmle.label | this [s1] |
| C.cpp:31:10:31:11 | s3 | semmle.label | s3 |
| C.cpp:31:10:31:11 | this [s3] | semmle.label | this [s3] |
| D.cpp:10:11:10:17 | this [elem] | semmle.label | this [elem] |
| D.cpp:10:30:10:33 | elem | semmle.label | elem |
| D.cpp:10:30:10:33 | this [elem] | semmle.label | this [elem] |
| D.cpp:11:24:11:24 | e | semmle.label | e |
| D.cpp:11:29:11:32 | this [post update] [elem] | semmle.label | this [post update] [elem] |
| D.cpp:11:29:11:36 | ... = ... | semmle.label | ... = ... |
| D.cpp:17:11:17:17 | this [box, elem] | semmle.label | this [box, elem] |
| D.cpp:17:30:17:32 | box [elem] | semmle.label | box [elem] |
| D.cpp:17:30:17:32 | this [box, elem] | semmle.label | this [box, elem] |
| D.cpp:21:30:21:31 | b2 [box, elem] | semmle.label | b2 [box, elem] |
| D.cpp:22:10:22:11 | b2 [box, elem] | semmle.label | b2 [box, elem] |
| D.cpp:22:14:22:20 | call to getBox1 [elem] | semmle.label | call to getBox1 [elem] |
@@ -729,6 +927,30 @@ nodes
| arrays.cpp:44:10:44:17 | indirect [arr, data] | semmle.label | indirect [arr, data] |
| arrays.cpp:44:20:44:22 | arr [data] | semmle.label | arr [data] |
| arrays.cpp:44:27:44:30 | data | semmle.label | data |
| by_reference.cpp:11:48:11:52 | value | semmle.label | value |
| by_reference.cpp:12:5:12:5 | s [post update] [a] | semmle.label | s [post update] [a] |
| by_reference.cpp:12:5:12:16 | ... = ... | semmle.label | ... = ... |
| by_reference.cpp:15:26:15:30 | value | semmle.label | value |
| by_reference.cpp:16:5:16:8 | this [post update] [a] | semmle.label | this [post update] [a] |
| by_reference.cpp:16:5:16:19 | ... = ... | semmle.label | ... = ... |
| by_reference.cpp:19:28:19:32 | value | semmle.label | value |
| by_reference.cpp:20:5:20:8 | ref arg this [a] | semmle.label | ref arg this [a] |
| by_reference.cpp:20:23:20:27 | value | semmle.label | value |
| by_reference.cpp:23:34:23:38 | value | semmle.label | value |
| by_reference.cpp:24:19:24:22 | ref arg this [a] | semmle.label | ref arg this [a] |
| by_reference.cpp:24:25:24:29 | value | semmle.label | value |
| by_reference.cpp:31:46:31:46 | s [a] | semmle.label | s [a] |
| by_reference.cpp:32:12:32:12 | s [a] | semmle.label | s [a] |
| by_reference.cpp:32:15:32:15 | a | semmle.label | a |
| by_reference.cpp:35:9:35:19 | this [a] | semmle.label | this [a] |
| by_reference.cpp:36:12:36:15 | this [a] | semmle.label | this [a] |
| by_reference.cpp:36:18:36:18 | a | semmle.label | a |
| by_reference.cpp:39:9:39:21 | this [a] | semmle.label | this [a] |
| by_reference.cpp:40:12:40:15 | this [a] | semmle.label | this [a] |
| by_reference.cpp:40:18:40:28 | call to getDirectly | semmle.label | call to getDirectly |
| by_reference.cpp:43:9:43:27 | this [a] | semmle.label | this [a] |
| by_reference.cpp:44:12:44:24 | call to nonMemberGetA | semmle.label | call to nonMemberGetA |
| by_reference.cpp:44:26:44:29 | this [a] | semmle.label | this [a] |
| by_reference.cpp:50:3:50:3 | ref arg s [a] | semmle.label | ref arg s [a] |
| by_reference.cpp:50:17:50:26 | call to user_input | semmle.label | call to user_input |
| by_reference.cpp:51:8:51:8 | s [a] | semmle.label | s [a] |
@@ -818,6 +1040,18 @@ nodes
| by_reference.cpp:135:27:135:27 | a | semmle.label | a |
| by_reference.cpp:136:8:136:13 | pouter [a] | semmle.label | pouter [a] |
| by_reference.cpp:136:16:136:16 | a | semmle.label | a |
| complex.cpp:9:7:9:7 | this [a_] | semmle.label | this [a_] |
| complex.cpp:9:20:9:21 | a_ | semmle.label | a_ |
| complex.cpp:9:20:9:21 | this [a_] | semmle.label | this [a_] |
| complex.cpp:10:7:10:7 | this [b_] | semmle.label | this [b_] |
| complex.cpp:10:20:10:21 | b_ | semmle.label | b_ |
| complex.cpp:10:20:10:21 | this [b_] | semmle.label | this [b_] |
| complex.cpp:11:17:11:17 | a | semmle.label | a |
| complex.cpp:11:22:11:23 | this [post update] [a_] | semmle.label | this [post update] [a_] |
| complex.cpp:11:22:11:27 | ... = ... | semmle.label | ... = ... |
| complex.cpp:12:17:12:17 | b | semmle.label | b |
| complex.cpp:12:22:12:23 | this [post update] [b_] | semmle.label | this [post update] [b_] |
| complex.cpp:12:22:12:27 | ... = ... | semmle.label | ... = ... |
| complex.cpp:40:17:40:17 | b [inner, f, a_] | semmle.label | b [inner, f, a_] |
| complex.cpp:40:17:40:17 | b [inner, f, b_] | semmle.label | b [inner, f, b_] |
| complex.cpp:42:8:42:8 | b [inner, f, a_] | semmle.label | b [inner, f, a_] |
@@ -874,6 +1108,18 @@ nodes
| conflated.cpp:61:8:61:9 | ll [next, y] | semmle.label | ll [next, y] |
| conflated.cpp:61:12:61:15 | next [y] | semmle.label | next [y] |
| conflated.cpp:61:18:61:18 | y | semmle.label | y |
| constructors.cpp:18:9:18:9 | this [a_] | semmle.label | this [a_] |
| constructors.cpp:18:22:18:23 | a_ | semmle.label | a_ |
| constructors.cpp:18:22:18:23 | this [a_] | semmle.label | this [a_] |
| constructors.cpp:19:9:19:9 | this [b_] | semmle.label | this [b_] |
| constructors.cpp:19:22:19:23 | b_ | semmle.label | b_ |
| constructors.cpp:19:22:19:23 | this [b_] | semmle.label | this [b_] |
| constructors.cpp:23:13:23:13 | a | semmle.label | a |
| constructors.cpp:23:20:23:20 | b | semmle.label | b |
| constructors.cpp:23:25:23:29 | constructor init of field a_ [post-this] [a_] | semmle.label | constructor init of field a_ [post-this] [a_] |
| constructors.cpp:23:28:23:28 | a | semmle.label | a |
| constructors.cpp:23:32:23:36 | constructor init of field b_ [post-this] [b_] | semmle.label | constructor init of field b_ [post-this] [b_] |
| constructors.cpp:23:35:23:35 | b | semmle.label | b |
| constructors.cpp:26:15:26:15 | f [a_] | semmle.label | f [a_] |
| constructors.cpp:26:15:26:15 | f [b_] | semmle.label | f [b_] |
| constructors.cpp:28:10:28:10 | f [a_] | semmle.label | f [a_] |
@@ -892,6 +1138,16 @@ nodes
| constructors.cpp:43:9:43:9 | g [b_] | semmle.label | g [b_] |
| constructors.cpp:46:9:46:9 | h [a_] | semmle.label | h [a_] |
| constructors.cpp:46:9:46:9 | h [b_] | semmle.label | h [b_] |
| qualifiers.cpp:9:21:9:25 | value | semmle.label | value |
| qualifiers.cpp:9:30:9:33 | this [post update] [a] | semmle.label | this [post update] [a] |
| qualifiers.cpp:9:30:9:44 | ... = ... | semmle.label | ... = ... |
| qualifiers.cpp:12:40:12:44 | value | semmle.label | value |
| qualifiers.cpp:12:49:12:53 | inner [post update] [a] | semmle.label | inner [post update] [a] |
| qualifiers.cpp:12:49:12:64 | ... = ... | semmle.label | ... = ... |
| qualifiers.cpp:13:29:13:33 | inner [a] | semmle.label | inner [a] |
| qualifiers.cpp:13:42:13:46 | value | semmle.label | value |
| qualifiers.cpp:13:51:13:55 | inner [post update] [a] | semmle.label | inner [post update] [a] |
| qualifiers.cpp:13:51:13:65 | ... = ... | semmle.label | ... = ... |
| qualifiers.cpp:22:5:22:9 | ref arg outer [inner, a] | semmle.label | ref arg outer [inner, a] |
| qualifiers.cpp:22:5:22:38 | ... = ... | semmle.label | ... = ... |
| qualifiers.cpp:22:11:22:18 | call to getInner [post update] [a] | semmle.label | call to getInner [post update] [a] |
@@ -946,6 +1202,18 @@ nodes
| realistic.cpp:61:32:61:34 | baz [userInput, bufferLen] | semmle.label | baz [userInput, bufferLen] |
| realistic.cpp:61:37:61:45 | userInput [bufferLen] | semmle.label | userInput [bufferLen] |
| realistic.cpp:61:47:61:55 | bufferLen | semmle.label | bufferLen |
| simple.cpp:18:9:18:9 | this [a_] | semmle.label | this [a_] |
| simple.cpp:18:22:18:23 | a_ | semmle.label | a_ |
| simple.cpp:18:22:18:23 | this [a_] | semmle.label | this [a_] |
| simple.cpp:19:9:19:9 | this [b_] | semmle.label | this [b_] |
| simple.cpp:19:22:19:23 | b_ | semmle.label | b_ |
| simple.cpp:19:22:19:23 | this [b_] | semmle.label | this [b_] |
| simple.cpp:20:19:20:19 | a | semmle.label | a |
| simple.cpp:20:24:20:25 | this [post update] [a_] | semmle.label | this [post update] [a_] |
| simple.cpp:20:24:20:29 | ... = ... | semmle.label | ... = ... |
| simple.cpp:21:19:21:19 | b | semmle.label | b |
| simple.cpp:21:24:21:25 | this [post update] [b_] | semmle.label | this [post update] [b_] |
| simple.cpp:21:24:21:29 | ... = ... | semmle.label | ... = ... |
| simple.cpp:26:15:26:15 | f [a_] | semmle.label | f [a_] |
| simple.cpp:26:15:26:15 | f [b_] | semmle.label | f [b_] |
| simple.cpp:28:10:28:10 | f [a_] | semmle.label | f [a_] |
@@ -969,6 +1237,10 @@ nodes
| simple.cpp:65:11:65:20 | call to user_input | semmle.label | call to user_input |
| simple.cpp:67:10:67:11 | a2 [i] | semmle.label | a2 [i] |
| simple.cpp:67:13:67:13 | i | semmle.label | i |
| simple.cpp:78:9:78:15 | this [f2, f1] | semmle.label | this [f2, f1] |
| simple.cpp:79:16:79:17 | f2 [f1] | semmle.label | f2 [f1] |
| simple.cpp:79:16:79:17 | this [f2, f1] | semmle.label | this [f2, f1] |
| simple.cpp:79:19:79:20 | f1 | semmle.label | f1 |
| simple.cpp:83:9:83:10 | f2 [post update] [f1] | semmle.label | f2 [post update] [f1] |
| simple.cpp:83:9:83:10 | this [post update] [f2, f1] | semmle.label | this [post update] [f2, f1] |
| simple.cpp:83:9:83:28 | ... = ... | semmle.label | ... = ... |
@@ -1008,6 +1280,65 @@ nodes
| struct_init.c:43:5:43:7 | & ... [a] | semmle.label | & ... [a] |
| struct_init.c:46:10:46:14 | outer [pointerAB, a] | semmle.label | outer [pointerAB, a] |
| struct_init.c:46:16:46:24 | pointerAB [a] | semmle.label | pointerAB [a] |
subpaths
| A.cpp:31:20:31:20 | c | A.cpp:23:10:23:10 | c | A.cpp:25:7:25:10 | this [post update] [c] | A.cpp:31:14:31:21 | call to B [c] |
| A.cpp:48:20:48:20 | c | A.cpp:29:23:29:23 | c | A.cpp:31:14:31:21 | new [c] | A.cpp:48:12:48:18 | call to make [c] |
| A.cpp:55:12:55:19 | new | A.cpp:27:17:27:17 | c | A.cpp:27:22:27:25 | this [post update] [c] | A.cpp:55:5:55:5 | ref arg b [c] |
| A.cpp:56:10:56:10 | b [c] | A.cpp:28:8:28:10 | this [c] | A.cpp:28:29:28:29 | c | A.cpp:56:13:56:15 | call to get |
| A.cpp:57:11:57:24 | new [c] | A.cpp:28:8:28:10 | this [c] | A.cpp:28:29:28:29 | c | A.cpp:57:28:57:30 | call to get |
| A.cpp:57:17:57:23 | new | A.cpp:23:10:23:10 | c | A.cpp:25:7:25:10 | this [post update] [c] | A.cpp:57:11:57:24 | call to B [c] |
| A.cpp:64:21:64:28 | new | A.cpp:85:26:85:26 | c | A.cpp:91:14:91:15 | b2 [c] | A.cpp:64:10:64:15 | call to setOnB [c] |
| A.cpp:73:25:73:32 | new | A.cpp:78:27:78:27 | c | A.cpp:82:12:82:24 | ... ? ... : ... [c] | A.cpp:73:10:73:19 | call to setOnBWrap [c] |
| A.cpp:81:21:81:21 | c | A.cpp:85:26:85:26 | c | A.cpp:91:14:91:15 | b2 [c] | A.cpp:81:10:81:15 | call to setOnB [c] |
| A.cpp:90:15:90:15 | c | A.cpp:27:17:27:17 | c | A.cpp:27:22:27:25 | this [post update] [c] | A.cpp:90:7:90:8 | ref arg b2 [c] |
| A.cpp:126:12:126:18 | new | A.cpp:27:17:27:17 | c | A.cpp:27:22:27:25 | this [post update] [c] | A.cpp:126:5:126:5 | ref arg b [c] |
| A.cpp:151:18:151:18 | b | A.cpp:140:13:140:13 | b | A.cpp:143:7:143:10 | this [post update] [b] | A.cpp:151:12:151:24 | call to D [b] |
| A.cpp:160:29:160:29 | b | A.cpp:181:15:181:21 | newHead | A.cpp:183:7:183:10 | this [post update] [head] | A.cpp:160:18:160:60 | call to MyList [head] |
| A.cpp:161:38:161:39 | l1 [head] | A.cpp:181:32:181:35 | next [head] | A.cpp:184:7:184:10 | this [post update] [next, head] | A.cpp:161:18:161:40 | call to MyList [next, head] |
| A.cpp:162:38:162:39 | l2 [next, head] | A.cpp:181:32:181:35 | next [next, head] | A.cpp:184:7:184:10 | this [post update] [next, next, head] | A.cpp:162:18:162:40 | call to MyList [next, next, head] |
| B.cpp:7:25:7:25 | e | B.cpp:33:16:33:17 | e1 | B.cpp:35:7:35:10 | this [post update] [elem1] | B.cpp:7:16:7:35 | call to Box1 [elem1] |
| B.cpp:8:25:8:26 | b1 [elem1] | B.cpp:44:16:44:17 | b1 [elem1] | B.cpp:46:7:46:10 | this [post update] [box1, elem1] | B.cpp:8:16:8:27 | call to Box2 [box1, elem1] |
| B.cpp:16:37:16:37 | e | B.cpp:33:26:33:27 | e2 | B.cpp:36:7:36:10 | this [post update] [elem2] | B.cpp:16:16:16:38 | call to Box1 [elem2] |
| B.cpp:17:25:17:26 | b1 [elem2] | B.cpp:44:16:44:17 | b1 [elem2] | B.cpp:46:7:46:10 | this [post update] [box1, elem2] | B.cpp:17:16:17:27 | call to Box2 [box1, elem2] |
| D.cpp:22:10:22:11 | b2 [box, elem] | D.cpp:17:11:17:17 | this [box, elem] | D.cpp:17:30:17:32 | box [elem] | D.cpp:22:14:22:20 | call to getBox1 [elem] |
| D.cpp:22:14:22:20 | call to getBox1 [elem] | D.cpp:10:11:10:17 | this [elem] | D.cpp:10:30:10:33 | elem | D.cpp:22:25:22:31 | call to getElem |
| D.cpp:37:21:37:21 | e | D.cpp:11:24:11:24 | e | D.cpp:11:29:11:32 | this [post update] [elem] | D.cpp:37:8:37:10 | ref arg box [elem] |
| D.cpp:51:27:51:27 | e | D.cpp:11:24:11:24 | e | D.cpp:11:29:11:32 | this [post update] [elem] | D.cpp:51:8:51:14 | ref arg call to getBox1 [elem] |
| by_reference.cpp:20:23:20:27 | value | by_reference.cpp:15:26:15:30 | value | by_reference.cpp:16:5:16:8 | this [post update] [a] | by_reference.cpp:20:5:20:8 | ref arg this [a] |
| by_reference.cpp:24:25:24:29 | value | by_reference.cpp:11:48:11:52 | value | by_reference.cpp:12:5:12:5 | s [post update] [a] | by_reference.cpp:24:19:24:22 | ref arg this [a] |
| by_reference.cpp:40:12:40:15 | this [a] | by_reference.cpp:35:9:35:19 | this [a] | by_reference.cpp:36:18:36:18 | a | by_reference.cpp:40:18:40:28 | call to getDirectly |
| by_reference.cpp:44:26:44:29 | this [a] | by_reference.cpp:31:46:31:46 | s [a] | by_reference.cpp:32:15:32:15 | a | by_reference.cpp:44:12:44:24 | call to nonMemberGetA |
| by_reference.cpp:50:17:50:26 | call to user_input | by_reference.cpp:15:26:15:30 | value | by_reference.cpp:16:5:16:8 | this [post update] [a] | by_reference.cpp:50:3:50:3 | ref arg s [a] |
| by_reference.cpp:51:8:51:8 | s [a] | by_reference.cpp:35:9:35:19 | this [a] | by_reference.cpp:36:18:36:18 | a | by_reference.cpp:51:10:51:20 | call to getDirectly |
| by_reference.cpp:56:19:56:28 | call to user_input | by_reference.cpp:19:28:19:32 | value | by_reference.cpp:20:5:20:8 | ref arg this [a] | by_reference.cpp:56:3:56:3 | ref arg s [a] |
| by_reference.cpp:57:8:57:8 | s [a] | by_reference.cpp:39:9:39:21 | this [a] | by_reference.cpp:40:18:40:28 | call to getDirectly | by_reference.cpp:57:10:57:22 | call to getIndirectly |
| by_reference.cpp:62:25:62:34 | call to user_input | by_reference.cpp:23:34:23:38 | value | by_reference.cpp:24:19:24:22 | ref arg this [a] | by_reference.cpp:62:3:62:3 | ref arg s [a] |
| by_reference.cpp:63:8:63:8 | s [a] | by_reference.cpp:43:9:43:27 | this [a] | by_reference.cpp:44:12:44:24 | call to nonMemberGetA | by_reference.cpp:63:10:63:28 | call to getThroughNonMember |
| by_reference.cpp:68:21:68:30 | call to user_input | by_reference.cpp:11:48:11:52 | value | by_reference.cpp:12:5:12:5 | s [post update] [a] | by_reference.cpp:68:17:68:18 | ref arg & ... [a] |
| by_reference.cpp:69:22:69:23 | & ... [a] | by_reference.cpp:31:46:31:46 | s [a] | by_reference.cpp:32:15:32:15 | a | by_reference.cpp:69:8:69:20 | call to nonMemberGetA |
| complex.cpp:42:16:42:16 | f [a_] | complex.cpp:9:7:9:7 | this [a_] | complex.cpp:9:20:9:21 | a_ | complex.cpp:42:18:42:18 | call to a |
| complex.cpp:43:16:43:16 | f [b_] | complex.cpp:10:7:10:7 | this [b_] | complex.cpp:10:20:10:21 | b_ | complex.cpp:43:18:43:18 | call to b |
| complex.cpp:53:19:53:28 | call to user_input | complex.cpp:11:17:11:17 | a | complex.cpp:11:22:11:23 | this [post update] [a_] | complex.cpp:53:12:53:12 | ref arg f [a_] |
| complex.cpp:54:19:54:28 | call to user_input | complex.cpp:12:17:12:17 | b | complex.cpp:12:22:12:23 | this [post update] [b_] | complex.cpp:54:12:54:12 | ref arg f [b_] |
| complex.cpp:55:19:55:28 | call to user_input | complex.cpp:11:17:11:17 | a | complex.cpp:11:22:11:23 | this [post update] [a_] | complex.cpp:55:12:55:12 | ref arg f [a_] |
| complex.cpp:56:19:56:28 | call to user_input | complex.cpp:12:17:12:17 | b | complex.cpp:12:22:12:23 | this [post update] [b_] | complex.cpp:56:12:56:12 | ref arg f [b_] |
| constructors.cpp:28:10:28:10 | f [a_] | constructors.cpp:18:9:18:9 | this [a_] | constructors.cpp:18:22:18:23 | a_ | constructors.cpp:28:12:28:12 | call to a |
| constructors.cpp:29:10:29:10 | f [b_] | constructors.cpp:19:9:19:9 | this [b_] | constructors.cpp:19:22:19:23 | b_ | constructors.cpp:29:12:29:12 | call to b |
| constructors.cpp:34:11:34:20 | call to user_input | constructors.cpp:23:13:23:13 | a | constructors.cpp:23:25:23:29 | constructor init of field a_ [post-this] [a_] | constructors.cpp:34:11:34:26 | call to Foo [a_] |
| constructors.cpp:35:14:35:23 | call to user_input | constructors.cpp:23:20:23:20 | b | constructors.cpp:23:32:23:36 | constructor init of field b_ [post-this] [b_] | constructors.cpp:35:11:35:26 | call to Foo [b_] |
| constructors.cpp:36:11:36:20 | call to user_input | constructors.cpp:23:13:23:13 | a | constructors.cpp:23:25:23:29 | constructor init of field a_ [post-this] [a_] | constructors.cpp:36:11:36:37 | call to Foo [a_] |
| constructors.cpp:36:25:36:34 | call to user_input | constructors.cpp:23:20:23:20 | b | constructors.cpp:23:32:23:36 | constructor init of field b_ [post-this] [b_] | constructors.cpp:36:11:36:37 | call to Foo [b_] |
| qualifiers.cpp:27:28:27:37 | call to user_input | qualifiers.cpp:9:21:9:25 | value | qualifiers.cpp:9:30:9:33 | this [post update] [a] | qualifiers.cpp:27:11:27:18 | ref arg call to getInner [a] |
| qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:12:40:12:44 | value | qualifiers.cpp:12:49:12:53 | inner [post update] [a] | qualifiers.cpp:32:23:32:30 | ref arg call to getInner [a] |
| qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:13:42:13:46 | value | qualifiers.cpp:13:29:13:33 | inner [a] | qualifiers.cpp:37:19:37:35 | ref arg * ... [a] |
| qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:13:42:13:46 | value | qualifiers.cpp:13:51:13:55 | inner [post update] [a] | qualifiers.cpp:37:19:37:35 | ref arg * ... [a] |
| simple.cpp:28:10:28:10 | f [a_] | simple.cpp:18:9:18:9 | this [a_] | simple.cpp:18:22:18:23 | a_ | simple.cpp:28:12:28:12 | call to a |
| simple.cpp:29:10:29:10 | f [b_] | simple.cpp:19:9:19:9 | this [b_] | simple.cpp:19:22:19:23 | b_ | simple.cpp:29:12:29:12 | call to b |
| simple.cpp:39:12:39:21 | call to user_input | simple.cpp:20:19:20:19 | a | simple.cpp:20:24:20:25 | this [post update] [a_] | simple.cpp:39:5:39:5 | ref arg f [a_] |
| simple.cpp:40:12:40:21 | call to user_input | simple.cpp:21:19:21:19 | b | simple.cpp:21:24:21:25 | this [post update] [b_] | simple.cpp:40:5:40:5 | ref arg g [b_] |
| simple.cpp:41:12:41:21 | call to user_input | simple.cpp:20:19:20:19 | a | simple.cpp:20:24:20:25 | this [post update] [a_] | simple.cpp:41:5:41:5 | ref arg h [a_] |
| simple.cpp:42:12:42:21 | call to user_input | simple.cpp:21:19:21:19 | b | simple.cpp:21:24:21:25 | this [post update] [b_] | simple.cpp:42:5:42:5 | ref arg h [b_] |
| simple.cpp:84:14:84:20 | this [f2, f1] | simple.cpp:78:9:78:15 | this [f2, f1] | simple.cpp:79:19:79:20 | f1 | simple.cpp:84:14:84:20 | call to getf2f1 |
#select
| A.cpp:43:10:43:12 | & ... | A.cpp:41:15:41:21 | new | A.cpp:43:10:43:12 | & ... | & ... flows from $@ | A.cpp:41:15:41:21 | new | new |
| A.cpp:49:13:49:13 | c | A.cpp:47:12:47:18 | new | A.cpp:49:13:49:13 | c | c flows from $@ | A.cpp:47:12:47:18 | new | new |

View File

@@ -594,6 +594,15 @@
| test.c:659:9:659:9 | u | 0 |
| test.c:664:12:664:12 | s | -2147483648 |
| test.c:665:7:665:8 | s2 | -4 |
| test.c:670:7:670:7 | x | -2147483648 |
| test.c:671:9:671:9 | y | -2147483648 |
| test.c:675:7:675:7 | y | -2147483648 |
| test.c:684:7:684:7 | x | -2147483648 |
| test.c:689:7:689:7 | x | -2147483648 |
| test.c:696:8:696:8 | x | 2147483647 |
| test.c:696:12:696:12 | y | 256 |
| test.c:697:9:697:9 | x | 2147483647 |
| test.c:698:9:698:9 | y | 256 |
| test.cpp:10:7:10:7 | b | -2147483648 |
| test.cpp:11:5:11:5 | x | -2147483648 |
| test.cpp:13:10:13:10 | x | -2147483648 |
@@ -647,16 +656,18 @@
| test.cpp:97:10:97:10 | i | -2147483648 |
| test.cpp:97:22:97:22 | i | -2147483648 |
| test.cpp:98:5:98:5 | i | -2147483648 |
| test.cpp:105:7:105:7 | n | -32768 |
| test.cpp:108:7:108:7 | n | 0 |
| test.cpp:109:5:109:5 | n | 1 |
| test.cpp:111:5:111:5 | n | 0 |
| test.cpp:114:8:114:8 | n | 0 |
| test.cpp:115:5:115:5 | n | 0 |
| test.cpp:117:5:117:5 | n | 1 |
| test.cpp:120:3:120:3 | n | 0 |
| test.cpp:120:8:120:8 | n | 1 |
| test.cpp:120:12:120:12 | n | 0 |
| test.cpp:121:4:121:4 | n | 0 |
| test.cpp:121:8:121:8 | n | 0 |
| test.cpp:121:12:121:12 | n | 1 |
| test.cpp:98:9:98:9 | i | -2147483648 |
| test.cpp:99:5:99:5 | i | -2147483648 |
| test.cpp:106:7:106:7 | n | -32768 |
| test.cpp:109:7:109:7 | n | 0 |
| test.cpp:110:5:110:5 | n | 1 |
| test.cpp:112:5:112:5 | n | 0 |
| test.cpp:115:8:115:8 | n | 0 |
| test.cpp:116:5:116:5 | n | 0 |
| test.cpp:118:5:118:5 | n | 1 |
| test.cpp:121:3:121:3 | n | 0 |
| test.cpp:121:8:121:8 | n | 1 |
| test.cpp:121:12:121:12 | n | 0 |
| test.cpp:122:4:122:4 | n | 0 |
| test.cpp:122:8:122:8 | n | 0 |
| test.cpp:122:12:122:12 | n | 1 |

View File

@@ -15,5 +15,5 @@
| test.c:394:20:394:36 | ... ? ... : ... | 0.0 | 0.0 | 100.0 |
| test.c:606:5:606:14 | ... ? ... : ... | 0.0 | 1.0 | 0.0 |
| test.c:607:5:607:14 | ... ? ... : ... | 0.0 | 0.0 | 1.0 |
| test.cpp:120:3:120:12 | ... ? ... : ... | 0.0 | 1.0 | 0.0 |
| test.cpp:121:3:121:12 | ... ? ... : ... | 0.0 | 0.0 | 1.0 |
| test.cpp:121:3:121:12 | ... ? ... : ... | 0.0 | 1.0 | 0.0 |
| test.cpp:122:3:122:12 | ... ? ... : ... | 0.0 | 0.0 | 1.0 |

View File

@@ -15,5 +15,5 @@
| test.c:394:20:394:36 | ... ? ... : ... | 100.0 | 99.0 | 100.0 |
| test.c:606:5:606:14 | ... ? ... : ... | 32767.0 | 32767.0 | 0.0 |
| test.c:607:5:607:14 | ... ? ... : ... | 32767.0 | 0.0 | 32767.0 |
| test.cpp:120:3:120:12 | ... ? ... : ... | 32767.0 | 32767.0 | 0.0 |
| test.cpp:121:3:121:12 | ... ? ... : ... | 32767.0 | 0.0 | 32767.0 |
| test.cpp:121:3:121:12 | ... ? ... : ... | 32767.0 | 32767.0 | 0.0 |
| test.cpp:122:3:122:12 | ... ? ... : ... | 32767.0 | 0.0 | 32767.0 |

View File

@@ -664,3 +664,37 @@ void test_mod(int s) {
int s2 = s % 5;
out(s2); // -4 .. 4
}
void exit(int);
void guard_with_exit(int x, int y) {
if (x) {
if (y != 0) {
exit(0);
}
}
out(y); // ..
// This test ensures that we correctly identify
// that the upper bound for y is max_int when calling `out(y)`.
// The RangeSsa will place guardPhy on `out(y)`, and consequently there is no
// frontier phi node at out(y).
}
void test(int x) {
if (x >= 10) {
return;
}
// The basic below has two predecessors.
label:
out(x);
goto label;
}
void test_overflow() {
const int x = 2147483647; // 2^31-1
const int y = 256;
if ((x + y) <= 512) {
out(x);
out(y);
}
}

View File

@@ -95,6 +95,7 @@ int ref_to_number(int &i, const int &ci, int &aliased) {
return alias;
for (; i <= 12345; i++) { // test that widening works for references
i = i;
i;
}

View File

@@ -584,9 +584,9 @@
| test.c:639:9:639:10 | ss | 2 |
| test.c:645:8:645:8 | s | 2147483647 |
| test.c:645:15:645:15 | s | 127 |
| test.c:645:23:645:23 | s | 15 |
| test.c:646:18:646:18 | s | 15 |
| test.c:646:22:646:22 | s | 15 |
| test.c:645:23:645:23 | s | 9 |
| test.c:646:18:646:18 | s | 9 |
| test.c:646:22:646:22 | s | 9 |
| test.c:647:9:647:14 | result | 127 |
| test.c:653:7:653:7 | i | 0 |
| test.c:654:9:654:9 | i | 2147483647 |
@@ -594,6 +594,15 @@
| test.c:659:9:659:9 | u | 4294967295 |
| test.c:664:12:664:12 | s | 2147483647 |
| test.c:665:7:665:8 | s2 | 4 |
| test.c:670:7:670:7 | x | 2147483647 |
| test.c:671:9:671:9 | y | 2147483647 |
| test.c:675:7:675:7 | y | 2147483647 |
| test.c:684:7:684:7 | x | 2147483647 |
| test.c:689:7:689:7 | x | 15 |
| test.c:696:8:696:8 | x | 2147483647 |
| test.c:696:12:696:12 | y | 256 |
| test.c:697:9:697:9 | x | 2147483647 |
| test.c:698:9:698:9 | y | 256 |
| test.cpp:10:7:10:7 | b | 2147483647 |
| test.cpp:11:5:11:5 | x | 2147483647 |
| test.cpp:13:10:13:10 | x | 2147483647 |
@@ -646,17 +655,19 @@
| test.cpp:95:12:95:16 | alias | 2147483647 |
| test.cpp:97:10:97:10 | i | 65535 |
| test.cpp:97:22:97:22 | i | 32767 |
| test.cpp:98:5:98:5 | i | 32767 |
| test.cpp:105:7:105:7 | n | 32767 |
| test.cpp:108:7:108:7 | n | 32767 |
| test.cpp:109:5:109:5 | n | 32767 |
| test.cpp:111:5:111:5 | n | 0 |
| test.cpp:114:8:114:8 | n | 32767 |
| test.cpp:115:5:115:5 | n | 0 |
| test.cpp:117:5:117:5 | n | 32767 |
| test.cpp:120:3:120:3 | n | 32767 |
| test.cpp:120:8:120:8 | n | 32767 |
| test.cpp:120:12:120:12 | n | 0 |
| test.cpp:121:4:121:4 | n | 32767 |
| test.cpp:121:8:121:8 | n | 0 |
| test.cpp:121:12:121:12 | n | 32767 |
| test.cpp:98:5:98:5 | i | 2147483647 |
| test.cpp:98:9:98:9 | i | 12345 |
| test.cpp:99:5:99:5 | i | 32767 |
| test.cpp:106:7:106:7 | n | 32767 |
| test.cpp:109:7:109:7 | n | 32767 |
| test.cpp:110:5:110:5 | n | 32767 |
| test.cpp:112:5:112:5 | n | 0 |
| test.cpp:115:8:115:8 | n | 32767 |
| test.cpp:116:5:116:5 | n | 0 |
| test.cpp:118:5:118:5 | n | 32767 |
| test.cpp:121:3:121:3 | n | 32767 |
| test.cpp:121:8:121:8 | n | 32767 |
| test.cpp:121:12:121:12 | n | 0 |
| test.cpp:122:4:122:4 | n | 32767 |
| test.cpp:122:8:122:8 | n | 0 |
| test.cpp:122:12:122:12 | n | 32767 |

View File

@@ -1,5 +1,5 @@
name: codeql-cpp-tests
version: 0.0.0
name: codeql/cpp-tests
version: 0.0.2
dependencies:
codeql/cpp-all: "*"
codeql/cpp-queries: "*"

View File

@@ -5,10 +5,10 @@
| test2.c:33:26:33:27 | 46 | Potential buffer-overflow: 'buffer' has size 40 not 46. |
| test2.c:34:22:34:23 | 47 | Potential buffer-overflow: 'buffer' has size 40 not 47. |
| test2.c:35:23:35:24 | 48 | Potential buffer-overflow: 'buffer' has size 40 not 48. |
| test.c:14:9:14:13 | access to array | Potential buffer-overflow: 'xs' has size 5 but 'xs[5]' is accessed here. |
| test.c:15:9:15:13 | access to array | Potential buffer-overflow: 'xs' has size 5 but 'xs[6]' is accessed here. |
| test.c:20:9:20:18 | access to array | Potential buffer-overflow: 'ys' has size 5 but 'ys[5]' is accessed here. |
| test.c:21:9:21:18 | access to array | Potential buffer-overflow: 'ys' has size 5 but 'ys[6]' is accessed here. |
| test.c:14:9:14:13 | access to array | Potential buffer-overflow: 'xs' has size 5 but 'xs[5]' may be accessed here. |
| test.c:15:9:15:13 | access to array | Potential buffer-overflow: 'xs' has size 5 but 'xs[6]' may be accessed here. |
| test.c:20:9:20:18 | access to array | Potential buffer-overflow: 'ys' has size 5 but 'ys[5]' may be accessed here. |
| test.c:21:9:21:18 | access to array | Potential buffer-overflow: 'ys' has size 5 but 'ys[6]' may be accessed here. |
| test.cpp:19:3:19:12 | access to array | Potential buffer-overflow: counter 'i' <= 3 but 'buffer1' has 3 elements. |
| test.cpp:20:3:20:12 | access to array | Potential buffer-overflow: counter 'i' <= 3 but 'buffer2' has 3 elements. |
| test.cpp:24:27:24:27 | 4 | Potential buffer-overflow: 'buffer1' has size 3 not 4. |

View File

@@ -27,3 +27,47 @@ void f(void) {
c = stru.zs[6]; // GOOD (zs is variable size)
}
void* malloc(long unsigned int);
void test_buffer_sentinal() {
struct { char len; char buf[1]; } *b = malloc(10); // len(buf.buffer) effectively 8
b->buf[0] = 0; // GOOD
b->buf[7] = 0; // GOOD
b->buf[8] = 0; // BAD [NOT DETECTED]
}
union u {
unsigned long value;
char ptr[1];
};
void union_test() {
union u u;
u.ptr[0] = 0; // GOOD
u.ptr[sizeof(u)-1] = 0; // GOOD
u.ptr[sizeof(u)] = 0; // BAD [NOT DETECTED]
}
void test_struct_union() {
struct { union u u; } v;
v.u.ptr[0] = 0; // GOOD
v.u.ptr[sizeof(union u)-1] = 0; // GOOD
v.u.ptr[sizeof(union u)] = 0; // BAD [NOT DETECTED]
}
void union_test2() {
union { char ptr[1]; unsigned long value; } u;
u.ptr[0] = 0; // GOOD
u.ptr[sizeof(u)-1] = 0; // GOOD
u.ptr[sizeof(u)] = 0; // BAD [NOT DETECTED]
}
typedef struct {
char len;
char buf[1];
} var_buf;
void test_alloc() {
// Special case of taking sizeof without any addition or multiplications
var_buf *b = malloc(sizeof(var_buf));
b->buf[1] = 0; // BAD [NOT DETECTED]
}

View File

@@ -46,3 +46,13 @@ void f2(char *src)
ptr = &(buffer[1]);
memcpy(ptr, src, 100); // BAD [NOT DETECTED]
}
void f3() {
int i;
char buffer[5];
for (i=0; i<10; i++) {
if (i < 5) {
buffer[i] = 0; // GOOD
}
}
}

View File

@@ -115,7 +115,7 @@ int twoReasons(int a, int b) {
if (a <= 0 && b > 5) {
return a < b;
}
if (a <= 100 && b > 105) {
if (a <= 100 && b > 105) { // BUG [Not detected - this clause is always false]
return a > b;
}
return 0;

View File

@@ -34,6 +34,7 @@ nodes
| test.cpp:88:21:88:22 | d2 | semmle.label | d2 |
| test.cpp:95:21:95:21 | d | semmle.label | d |
| test.cpp:96:21:96:23 | dss | semmle.label | dss |
subpaths
#select
| test.cpp:27:2:27:2 | b | test.cpp:57:19:57:19 | d | test.cpp:27:2:27:2 | b | Pointer arithmetic here may be done with the wrong type because of the cast $@. | test.cpp:57:19:57:19 | d | here |
| test.cpp:27:2:27:2 | b | test.cpp:74:19:74:21 | dss | test.cpp:27:2:27:2 | b | Pointer arithmetic here may be done with the wrong type because of the cast $@. | test.cpp:74:19:74:21 | dss | here |

View File

@@ -11,4 +11,17 @@
| test.cpp:130:14:130:19 | buffer | Variable $@ may not be null terminated. | test.cpp:127:7:127:12 | buffer | buffer |
| test.cpp:139:10:139:15 | buffer | Variable $@ may not be null terminated. | test.cpp:136:8:136:13 | buffer | buffer |
| test.cpp:147:14:147:19 | buffer | Variable $@ may not be null terminated. | test.cpp:143:8:143:13 | buffer | buffer |
| test.cpp:170:10:170:15 | buffer | Variable $@ may not be null terminated. | test.cpp:166:8:166:13 | buffer | buffer |
| test.cpp:182:10:182:15 | buffer | Variable $@ may not be null terminated. | test.cpp:178:8:178:13 | buffer | buffer |
| test.cpp:234:10:234:15 | buffer | Variable $@ may not be null terminated. | test.cpp:232:8:232:13 | buffer | buffer |
| test.cpp:262:10:262:15 | buffer | Variable $@ may not be null terminated. | test.cpp:259:8:259:13 | buffer | buffer |
| test.cpp:283:10:283:15 | buffer | Variable $@ may not be null terminated. | test.cpp:280:8:280:13 | buffer | buffer |
| test.cpp:300:10:300:16 | buffer2 | Variable $@ may not be null terminated. | test.cpp:295:8:295:14 | buffer2 | buffer2 |
| test.cpp:312:10:312:15 | buffer | Variable $@ may not be null terminated. | test.cpp:308:8:308:13 | buffer | buffer |
| test.cpp:327:18:327:23 | buffer | Variable $@ may not be null terminated. | test.cpp:326:8:326:13 | buffer | buffer |
| test.cpp:346:11:346:16 | buffer | Variable $@ may not be null terminated. | test.cpp:341:8:341:13 | buffer | buffer |
| test.cpp:355:11:355:16 | buffer | Variable $@ may not be null terminated. | test.cpp:350:8:350:13 | buffer | buffer |
| test.cpp:365:19:365:25 | buffer2 | Variable $@ may not be null terminated. | test.cpp:363:8:363:14 | buffer2 | buffer2 |
| test.cpp:392:17:392:22 | buffer | Variable $@ may not be null terminated. | test.cpp:390:8:390:13 | buffer | buffer |
| test.cpp:398:18:398:23 | buffer | Variable $@ may not be null terminated. | test.cpp:396:8:396:13 | buffer | buffer |
| test.cpp:444:10:444:15 | buffer | Variable $@ may not be null terminated. | test.cpp:442:8:442:13 | buffer | buffer |
| test.cpp:450:16:450:21 | buffer | Variable $@ may not be null terminated. | test.cpp:448:8:448:13 | buffer | buffer |

View File

@@ -0,0 +1,2 @@
| test.cpp:410:10:410:15 | buffer | $@ flows to here and may not be null terminated. | test.cpp:409:18:409:23 | buffer | User-provided value |
| test.cpp:425:10:425:15 | buffer | $@ flows to here and may not be null terminated. | test.cpp:424:9:424:14 | buffer | User-provided value |

View File

@@ -0,0 +1 @@
Security/CWE/CWE-170/ImproperNullTerminationTainted.ql

View File

@@ -1,16 +1,16 @@
typedef unsigned int size_t;
typedef signed int ssize_t;
typedef struct {} FILE;
size_t strlen(const char *s);
char *strcpy(char *s1, const char *s2);
char *strcat(char *s1, const char *s2);
char *strdup(const char *s1);
void *malloc(size_t size);
void *memset(void *s, int c, size_t n);
void *memcpy(void *s1, const void *s2, size_t n);
void read(int src, void *out, int num);
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
ssize_t readlink(const char *path, char *buffer, size_t buffer_size);
ssize_t readlinkat(int fd, const char *path, char *buffer, size_t buffer_size);
@@ -154,6 +154,18 @@ void test_readlink(int fd, const char *path, size_t sz)
strdup(buffer); // GOOD
}
{
char buffer[1024];
ssize_t len;
len = readlink(path, buffer, sizeof(buffer));
if (len >= 0)
{
buffer[len - 1] = 0;
strdup(buffer); // GOOD
}
}
{
char buffer[1024];
@@ -209,3 +221,248 @@ void test_readlink(int fd, const char *path, size_t sz)
strdup(buffer); // GOOD
}
}
void doNothing(char *data) { };
void doNothing2(const char *data);
void clearBuffer(char *data, size_t size);
void test_strcat()
{
{
char buffer[1024];
strcat(buffer, "content"); // BAD
}
{
char buffer[1024];
buffer[0] = 0;
strcat(buffer, "content"); // GOOD
}
{
char buffer[1024];
buffer[10] = 0;
strcat(buffer, "content"); // GOOD
}
{
char buffer[1024];
buffer[0] = '\0';
strcat(buffer, "content"); // GOOD
}
{
char buffer[1024];
buffer[0] = 'a';
strcat(buffer, "content"); // BAD
}
{
char buffer[1024];
*buffer = 0;
strcat(buffer, "content"); // GOOD
}
{
char buffer[1024];
strcpy(buffer, "con");
strcat(buffer, "tent"); // GOOD
}
{
char buffer[1024];
doNothing(buffer);
strcat(buffer, "content"); // BAD
}
{
char buffer[1024];
doNothing2(buffer);
strcat(buffer, "content"); // BAD [NOT DETECTED]
}
{
char buffer1[1024];
char buffer2[1024];
char *buffer_ptr = buffer1;
*buffer_ptr = 0;
strcat(buffer1, "content"); // GOOD
strcat(buffer2, "content"); // BAD
strcat(buffer_ptr, "content"); // GOOD
buffer_ptr = buffer2;
strcat(buffer_ptr, "content"); // BAD [NOT DETECTED]
}
{
char buffer[1024];
char *buffer_ptr = buffer;
*buffer_ptr = 'a';
strcat(buffer, "content"); // BAD
}
{
char buffer[1024];
clearBuffer(buffer, 1024);
strcat(buffer, "content"); // GOOD
}
}
void test_strlen(bool cond1, bool cond2)
{
{
char buffer[1024];
int i = strlen(buffer); // BAD
}
{
char buffer[1024] = {0};
int i = strlen(buffer); // GOOD
}
{
char *ptr = "content";
int i = strlen(ptr); // GOOD
}
{
char buffer[1024];
if (cond1)
buffer[0] = 0;
if (cond1)
strlen(buffer); // GOOD [FALSE POSITIVE]
}
{
char buffer[1024];
if (cond1)
buffer[0] = 0;
if (cond2)
strlen(buffer); // BAD
}
}
void test_strcpy()
{
{
char buffer1[1024];
char buffer2[1024];
strcpy(buffer1, buffer2); // BAD
}
{
char buffer1[1024];
char buffer2[1024];
strcpy(buffer2, "content"); // GOOD
strcpy(buffer1, buffer2); // GOOD
}
}
void strcatWrapper(char *data, const char *with)
{
strcat(data, with);
}
void strcatWrapper2(char *data, const char *with)
{
strcatWrapper(data, with);
}
void test_wrappers()
{
{
char buffer[1024];
strcatWrapper(buffer, "content"); // BAD
}
{
char buffer[1024];
strcatWrapper2(buffer, "content"); // BAD
}
}
void test_read_fread(int read_src, FILE *s)
{
const size_t buffer_size = 80;
{
char buffer[buffer_size];
read(read_src, buffer, buffer_size * sizeof(char));
strlen(buffer); // BAD
}
{
char buffer[buffer_size];
read(read_src, buffer, buffer_size * sizeof(char));
buffer[buffer_size - 1] = 0;
strlen(buffer); // GOOD
}
{
char buffer[buffer_size];
fread(buffer, sizeof(char), buffer_size, s);
strlen(buffer); // BAD
}
{
char buffer[buffer_size];
fread(buffer, sizeof(char), buffer_size, s);
buffer[buffer_size - 1] = 0;
strlen(buffer); // GOOD
}
}
int printf(const char *format, ...);
void test_printf(char *str)
{
{
char buffer[1024];
printf(buffer, ""); // BAD
}
{
char buffer[1024];
printf("%s", buffer); // BAD
}
{
size_t len = strlen(str);
char *copied_str = (char *)malloc(len);
memcpy(copied_str, str, len);
printf("%s", copied_str); // BAD [NOT DETECTED]
}
{
size_t len = strlen(str);
char *copied_str = (char *)malloc(len + 1);
memcpy(copied_str, str, len + 1);
printf("%s", copied_str); // GOOD
}
}

View File

@@ -0,0 +1,134 @@
/**
* This test case is closely based on CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp
* from the SAMATE Juliet test suite.
*/
#define NULL (0)
typedef unsigned long size_t;
typedef size_t time_t;
time_t time(time_t *timer);
typedef struct {} FILE;
extern FILE *stdin;
FILE *fopen(const char *filename, const char *mode);
int fclose(FILE *stream);
#define FILENAME_MAX (4096)
typedef unsigned long size_t;
size_t strlen(const char *s);
char *strcat(char *s1, const char *s2);
char *fgets(char *s, int n, FILE *stream);
int globalReturnsTrue()
{
return 1;
}
int globalReturnsFalse()
{
return 0;
}
void printLine(const char *str);
#define BASEPATH "c:\\temp\\"
#define FOPEN fopen
namespace CWE23_Relative_Path_Traversal__char_console_fopen_11
{
void bad()
{
char * data;
char dataBuffer[FILENAME_MAX] = BASEPATH;
data = dataBuffer;
if(globalReturnsTrue())
{
{
/* Read input from the console */
size_t dataLen = strlen(data);
/* if there is room in data, read into it from the console */
if (FILENAME_MAX-dataLen > 1)
{
/* POTENTIAL FLAW: Read data from the console */
if (fgets(data+dataLen, (int)(FILENAME_MAX-dataLen), stdin) != NULL)
{
/* The next few lines remove the carriage return from the string that is
* inserted by fgets() */
dataLen = strlen(data);
if (dataLen > 0 && data[dataLen-1] == '\n')
{
data[dataLen-1] = '\0';
}
}
else
{
printLine("fgets() failed");
/* Restore NUL terminator if fgets fails */
data[dataLen] = '\0';
}
}
}
}
{
FILE *pFile = NULL;
/* POTENTIAL FLAW: Possibly opening a file without validating the file name or path */
pFile = FOPEN(data, "wb+");
if (pFile != NULL)
{
fclose(pFile);
}
}
}
/* goodG2B1() - use goodsource and badsink by changing the globalReturnsTrue() to globalReturnsFalse() */
static void goodG2B1()
{
char * data;
char dataBuffer[FILENAME_MAX] = BASEPATH;
data = dataBuffer;
if(globalReturnsFalse())
{
/* INCIDENTAL: CWE 561 Dead Code, the code below will never run */
printLine("Benign, fixed string");
}
else
{
/* FIX: Use a fixed file name */
strcat(data, "file.txt");
}
{
FILE *pFile = NULL;
/* POTENTIAL FLAW: Possibly opening a file without validating the file name or path */
pFile = FOPEN(data, "wb+");
if (pFile != NULL)
{
fclose(pFile);
}
}
}
/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */
static void goodG2B2()
{
char * data;
char dataBuffer[FILENAME_MAX] = BASEPATH;
data = dataBuffer;
if(globalReturnsTrue())
{
/* FIX: Use a fixed file name */
strcat(data, "file.txt");
}
{
FILE *pFile = NULL;
/* POTENTIAL FLAW: Possibly opening a file without validating the file name or path */
pFile = FOPEN(data, "wb+");
if (pFile != NULL)
{
fclose(pFile);
}
}
}
}

View File

@@ -0,0 +1,18 @@
edges
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | ... + ... | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | (const char *)... |
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | ... + ... | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data |
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | ... + ... | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data indirection |
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | (const char *)... |
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data |
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data indirection |
subpaths
nodes
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | ... + ... | semmle.label | ... + ... |
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | semmle.label | fgets output argument |
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | (const char *)... | semmle.label | (const char *)... |
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | (const char *)... | semmle.label | (const char *)... |
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data | semmle.label | data |
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data indirection | semmle.label | data indirection |
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data indirection | semmle.label | data indirection |
#select
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | ... + ... | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | data | This argument to a file access function is derived from $@ and then passed to fopen(filename) | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | ... + ... | user input (fgets) |

View File

@@ -0,0 +1 @@
Security/CWE/CWE-022/TaintedPath.ql

View File

@@ -5,6 +5,7 @@ edges
| test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName |
| test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName indirection |
| test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName indirection |
subpaths
nodes
| test.c:9:23:9:26 | argv | semmle.label | argv |
| test.c:9:23:9:26 | argv | semmle.label | argv |

View File

@@ -0,0 +1 @@
| tests.cpp:53:16:53:19 | data | This argument to an OS command is derived from $@ and then passed to system(string) | tests.cpp:33:34:33:39 | call to getenv | user input (getenv) |

View File

@@ -0,0 +1 @@
Security/CWE/CWE-078/ExecTainted.ql

View File

@@ -0,0 +1,58 @@
//semmle-extractor-options: --edg --target --edg win64
// A selection of tests from the SAMATE Juliet framework for rule CWE-78.
// library types, functions etc
#define NULL (0)
typedef unsigned long size_t;
size_t strlen(const char *s);
char *strncat(char *s1, const char *s2, size_t n);
char *getenv(const char *name);
int system(const char *string);
void exit(int status);
#define FULL_COMMAND "dir "
#define ENV_VARIABLE "ADD"
#define GETENV getenv
#define SYSTEM system
void printLine(const char *str);
// ----------
/* The static variable below is used to drive control flow in the source function */
static int badStatic = 0;
static char * badSource(char * data)
{
if(badStatic)
{
{
/* Append input from an environment variable to data */
size_t dataLen = strlen(data);
char * environment = GETENV(ENV_VARIABLE);
/* If there is data in the environment variable */
if (environment != NULL)
{
/* POTENTIAL FLAW: Read data from an environment variable */
strncat(data+dataLen, environment, 100-dataLen-1);
}
}
}
return data;
}
void CWE78_OS_Command_Injection__char_environment_system_21_bad()
{
char * data;
char data_buf[100] = FULL_COMMAND;
data = data_buf;
badStatic = 1; /* true */
data = badSource(data);
/* POTENTIAL FLAW: Execute command in data possibly leading to command injection [NOT DETECTED] */
if (SYSTEM(data) != 0)
{
printLine("command execution failed!");
exit(1);
}
}

View File

@@ -24,6 +24,7 @@ edges
| search.c:55:17:55:25 | raw_query indirection | search.c:14:24:14:28 | *query |
| search.c:57:5:57:15 | raw_query | search.c:22:24:22:28 | query |
| search.c:57:17:57:25 | raw_query indirection | search.c:22:24:22:28 | *query |
subpaths
nodes
| search.c:14:24:14:28 | *query | semmle.label | *query |
| search.c:14:24:14:28 | query | semmle.label | query |

View File

@@ -5,6 +5,15 @@ edges
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 |
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 indirection |
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 indirection |
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | (const char *)... |
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | (const char *)... |
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array indirection |
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array indirection |
subpaths
nodes
| test.c:15:20:15:23 | argv | semmle.label | argv |
| test.c:15:20:15:23 | argv | semmle.label | argv |
@@ -13,5 +22,15 @@ nodes
| test.c:21:18:21:23 | query1 | semmle.label | query1 |
| test.c:21:18:21:23 | query1 indirection | semmle.label | query1 indirection |
| test.c:21:18:21:23 | query1 indirection | semmle.label | query1 indirection |
| test.cpp:43:27:43:30 | argv | semmle.label | argv |
| test.cpp:43:27:43:30 | argv | semmle.label | argv |
| test.cpp:43:27:43:33 | (const char *)... | semmle.label | (const char *)... |
| test.cpp:43:27:43:33 | (const char *)... | semmle.label | (const char *)... |
| test.cpp:43:27:43:33 | access to array | semmle.label | access to array |
| test.cpp:43:27:43:33 | access to array | semmle.label | access to array |
| test.cpp:43:27:43:33 | access to array | semmle.label | access to array |
| test.cpp:43:27:43:33 | access to array indirection | semmle.label | access to array indirection |
| test.cpp:43:27:43:33 | access to array indirection | semmle.label | access to array indirection |
#select
| test.c:21:18:21:23 | query1 | test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 | This argument to a SQL query function is derived from $@ and then passed to mysql_query(sqlArg) | test.c:15:20:15:23 | argv | user input (argv) |
| test.cpp:43:27:43:33 | access to array | test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array | This argument to a SQL query function is derived from $@ and then passed to pqxx::work::exec1((unnamed parameter 0)) | test.cpp:43:27:43:30 | argv | user input (argv) |

View File

@@ -0,0 +1,48 @@
int sprintf(char* str, const char* format, ...);
namespace std
{
template<class charT> struct char_traits;
template <class T> class allocator {
public:
allocator() throw();
};
template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
class basic_string {
public:
explicit basic_string(const Allocator& a = Allocator());
basic_string(const charT* s, const Allocator& a = Allocator());
const charT* c_str() const;
};
typedef basic_string<char> string;
}
namespace pqxx {
struct connection {};
struct row {};
struct result {};
struct work {
work(connection&);
row exec1(const char*);
result exec(const std::string&);
std::string quote(const char*);
};
}
int main(int argc, char** argv) {
pqxx::connection c;
pqxx::work w(c);
pqxx::row r = w.exec1(argv[1]); // BAD
pqxx::result r2 = w.exec(w.quote(argv[1])); // GOOD
return 0;
}

View File

@@ -0,0 +1,31 @@
edges
| test.cpp:37:73:37:76 | *data | test.cpp:43:32:43:35 | (LPCSTR)... |
| test.cpp:37:73:37:76 | *data | test.cpp:43:32:43:35 | data |
| test.cpp:37:73:37:76 | *data | test.cpp:43:32:43:35 | data indirection |
| test.cpp:37:73:37:76 | data | test.cpp:43:32:43:35 | (LPCSTR)... |
| test.cpp:37:73:37:76 | data | test.cpp:43:32:43:35 | data |
| test.cpp:37:73:37:76 | data | test.cpp:43:32:43:35 | data |
| test.cpp:37:73:37:76 | data | test.cpp:43:32:43:35 | data indirection |
| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:17:73:22 | data |
| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:17:73:22 | data |
| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:24:73:27 | data indirection |
| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:24:73:27 | data indirection |
| test.cpp:73:17:73:22 | data | test.cpp:37:73:37:76 | data |
| test.cpp:73:24:73:27 | data indirection | test.cpp:37:73:37:76 | *data |
subpaths
nodes
| test.cpp:37:73:37:76 | *data | semmle.label | *data |
| test.cpp:37:73:37:76 | data | semmle.label | data |
| test.cpp:43:32:43:35 | (LPCSTR)... | semmle.label | (LPCSTR)... |
| test.cpp:43:32:43:35 | (LPCSTR)... | semmle.label | (LPCSTR)... |
| test.cpp:43:32:43:35 | data | semmle.label | data |
| test.cpp:43:32:43:35 | data | semmle.label | data |
| test.cpp:43:32:43:35 | data | semmle.label | data |
| test.cpp:43:32:43:35 | data indirection | semmle.label | data indirection |
| test.cpp:43:32:43:35 | data indirection | semmle.label | data indirection |
| test.cpp:64:30:64:35 | call to getenv | semmle.label | call to getenv |
| test.cpp:64:30:64:35 | call to getenv | semmle.label | call to getenv |
| test.cpp:73:17:73:22 | data | semmle.label | data |
| test.cpp:73:24:73:27 | data indirection | semmle.label | data indirection |
#select
| test.cpp:43:32:43:35 | data | test.cpp:64:30:64:35 | call to getenv | test.cpp:43:32:43:35 | data | The value of this argument may come from $@ and is being passed to LoadLibraryA | test.cpp:64:30:64:35 | call to getenv | call to getenv |

View File

@@ -0,0 +1 @@
Security/CWE/CWE-114/UncontrolledProcessOperation.ql

View File

@@ -0,0 +1,132 @@
// Some SAMATE Juliet test cases for CWE-114.
typedef unsigned long size_t;
typedef unsigned int BOOL;
typedef const char *LPCSTR;
typedef void *HMODULE;
#define NULL (0)
size_t strlen(const char *s);
char *strncat(char *s1, const char *s2, size_t n);
HMODULE LoadLibraryA(LPCSTR libname);
BOOL FreeLibrary(HMODULE hModule);
char *getenv(const char *name);
#define GETENV getenv
#define ENV_VARIABLE "ADD"
void printLine(const char *msg);
// --- CWE114_Process_Control__w32_char_environment_82 ---
class CWE114_Process_Control__w32_char_environment_82_base
{
public:
/* pure virtual function */
virtual void action(char * data) = 0;
};
class CWE114_Process_Control__w32_char_environment_82_bad : public CWE114_Process_Control__w32_char_environment_82_base
{
public:
void action(char * data);
};
void CWE114_Process_Control__w32_char_environment_82_bad::action(char * data)
{
{
HMODULE hModule;
/* POTENTIAL FLAW: If the path to the library is not specified, an attacker may be able to
* replace his own file with the intended library */
hModule = LoadLibraryA(data);
if (hModule != NULL)
{
FreeLibrary(hModule);
printLine("Library loaded and freed successfully");
}
else
{
printLine("Unable to load library");
}
}
}
void bad()
{
char * data;
char dataBuffer[100] = "";
data = dataBuffer;
{
/* Append input from an environment variable to data */
size_t dataLen = strlen(data);
char * environment = GETENV(ENV_VARIABLE);
/* If there is data in the environment variable */
if (environment != NULL)
{
/* POTENTIAL FLAW: Read data from an environment variable */
strncat(data+dataLen, environment, 100-dataLen-1);
}
}
CWE114_Process_Control__w32_char_environment_82_base* baseObject = new CWE114_Process_Control__w32_char_environment_82_bad;
baseObject->action(data);
delete baseObject;
}
// --- CWE114_Process_Control__w32_char_console_33 ---
typedef struct {} FILE;
char *fgets(char *s, int n, FILE *stream);
FILE *stdin;
void CWE114_Process_Control__w32_char_console_33_bad()
{
char * data;
char * &dataRef = data;
char dataBuffer[100] = "";
data = dataBuffer;
{
/* Read input from the console */
size_t dataLen = strlen(data);
/* if there is room in data, read into it from the console */
if (100-dataLen > 1)
{
/* POTENTIAL FLAW: Read data from the console [NOT DETECTED] */
if (fgets(data+dataLen, (int)(100-dataLen), stdin) != NULL)
{
/* The next few lines remove the carriage return from the string that is
* inserted by fgets() */
dataLen = strlen(data);
if (dataLen > 0 && data[dataLen-1] == '\n')
{
data[dataLen-1] = '\0';
}
}
else
{
printLine("fgets() failed");
/* Restore NUL terminator if fgets fails */
data[dataLen] = '\0';
}
}
}
{
char * data = dataRef;
{
HMODULE hModule;
/* POTENTIAL FLAW: If the path to the library is not specified, an attacker may be able to
* replace his own file with the intended library */
hModule = LoadLibraryA(data);
if (hModule != NULL)
{
FreeLibrary(hModule);
printLine("Library loaded and freed successfully");
}
else
{
printLine("Unable to load library");
}
}
}
}

View File

@@ -47,6 +47,7 @@ edges
| test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | (const char *)... |
| test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | buffer |
| test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | buffer indirection |
subpaths
nodes
| test.cpp:24:30:24:36 | *command | semmle.label | *command |
| test.cpp:24:30:24:36 | command | semmle.label | command |

View File

@@ -0,0 +1,4 @@
| tests.cpp:350:13:350:19 | call to strncat | This 'call to strncat' operation is limited to 100 bytes but the destination is only 50 bytes. |
| tests.cpp:452:9:452:15 | call to wcsncpy | This 'call to wcsncpy' operation is limited to 396 bytes but the destination is only 200 bytes. |
| tests.cpp:481:9:481:16 | call to swprintf | This 'call to swprintf' operation is limited to 400 bytes but the destination is only 200 bytes. |
| tests.cpp:630:13:630:20 | call to swprintf | This 'call to swprintf' operation is limited to 400 bytes but the destination is only 200 bytes. |

View File

@@ -0,0 +1 @@
Security/CWE/CWE-120/BadlyBoundedWrite.ql

View File

@@ -0,0 +1 @@
Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql

View File

@@ -0,0 +1,19 @@
| tests.cpp:45:9:45:14 | call to memcpy | This 'memcpy' operation accesses 32 bytes but the $@ is only 16 bytes. | tests.cpp:32:10:32:18 | charFirst | destination buffer |
| tests.cpp:60:9:60:14 | call to memcpy | This 'memcpy' operation accesses 32 bytes but the $@ is only 16 bytes. | tests.cpp:32:10:32:18 | charFirst | destination buffer |
| tests.cpp:171:9:171:14 | call to memcpy | This 'memcpy' operation accesses 100 bytes but the $@ is only 50 bytes. | tests.cpp:164:20:164:25 | call to malloc | destination buffer |
| tests.cpp:172:9:172:19 | access to array | This array indexing operation accesses byte offset 99 but the $@ is only 50 bytes. | tests.cpp:164:20:164:25 | call to malloc | array |
| tests.cpp:192:9:192:14 | call to memcpy | This 'memcpy' operation accesses 100 bytes but the $@ is only 50 bytes. | tests.cpp:181:10:181:22 | dataBadBuffer | destination buffer |
| tests.cpp:192:9:192:14 | call to memcpy | This 'memcpy' operation accesses 100 bytes but the $@ is only 50 bytes. | tests.cpp:185:12:185:24 | dataBadBuffer | destination buffer |
| tests.cpp:193:9:193:19 | access to array | This array indexing operation accesses byte offset 99 but the $@ is only 50 bytes. | tests.cpp:181:10:181:22 | dataBadBuffer | array |
| tests.cpp:193:9:193:19 | access to array | This array indexing operation accesses byte offset 99 but the $@ is only 50 bytes. | tests.cpp:185:12:185:24 | dataBadBuffer | array |
| tests.cpp:212:9:212:14 | call to memcpy | This 'memcpy' operation accesses 100 bytes but the $@ is only 50 bytes. | tests.cpp:201:36:201:41 | call to alloca | destination buffer |
| tests.cpp:212:9:212:14 | call to memcpy | This 'memcpy' operation accesses 100 bytes but the $@ is only 50 bytes. | tests.cpp:205:12:205:24 | dataBadBuffer | destination buffer |
| tests.cpp:213:9:213:19 | access to array | This array indexing operation accesses byte offset 99 but the $@ is only 50 bytes. | tests.cpp:201:36:201:41 | call to alloca | array |
| tests.cpp:213:9:213:19 | access to array | This array indexing operation accesses byte offset 99 but the $@ is only 50 bytes. | tests.cpp:205:12:205:24 | dataBadBuffer | array |
| tests.cpp:237:9:237:19 | access to array | This array indexing operation accesses byte offset 99 but the $@ is only 50 bytes. | tests.cpp:221:36:221:41 | call to alloca | array |
| tests.cpp:237:9:237:19 | access to array | This array indexing operation accesses byte offset 99 but the $@ is only 50 bytes. | tests.cpp:225:12:225:24 | dataBadBuffer | array |
| tests.cpp:261:9:261:19 | access to array | This array indexing operation accesses byte offset 99 but the $@ is only 50 bytes. | tests.cpp:245:10:245:22 | dataBadBuffer | array |
| tests.cpp:261:9:261:19 | access to array | This array indexing operation accesses byte offset 99 but the $@ is only 50 bytes. | tests.cpp:249:12:249:24 | dataBadBuffer | array |
| tests.cpp:384:9:384:14 | call to memcpy | This 'memcpy' operation accesses 40 bytes but the $@ is only 10 bytes. | tests.cpp:380:19:380:24 | call to alloca | destination buffer |
| tests.cpp:434:9:434:19 | access to array | This array indexing operation accesses byte offset 399 but the $@ is only 200 bytes. | tests.cpp:422:12:422:26 | new[] | array |
| tests.cpp:453:9:453:19 | access to array | This array indexing operation accesses byte offset 399 but the $@ is only 200 bytes. | tests.cpp:445:12:445:26 | new[] | array |

View File

@@ -0,0 +1 @@
Security/CWE/CWE-119/OverflowBuffer.ql

Some files were not shown because too many files have changed in this diff Show More