Merge branch 'main' into no-more-flow-into-read-side-effect

This commit is contained in:
Mathias Vorreiter Pedersen
2020-10-05 11:03:42 +02:00
93 changed files with 1786 additions and 1360 deletions

View File

@@ -3,8 +3,8 @@
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"github.vscode-codeql"
"GitHub.vscode-codeql"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": []
}
}

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name External dependencies
* @description Count the number of dependencies a C/C++ source file has on external libraries.
* @kind treemap

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name External dependency source links
* @kind source-link
* @metricType externalDependency

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Duplicated lines in files
* @description The number of lines in a file, including code, comment
* and whitespace lines, which are duplicated in at least

View File

@@ -9,10 +9,7 @@
tags contain:
- ide-contextual-queries/local-definitions
- ide-contextual-queries/local-references
- query: Metrics/Dependencies/ExternalDependencies.ql
- query: Metrics/Dependencies/ExternalDependenciesSourceLinks.ql
- query: Metrics/Files/FLinesOfCode.ql
- query: Metrics/Files/FLinesOfCommentedOutCode.ql
- query: Metrics/Files/FLinesOfComments.ql
- query: Metrics/Files/FLinesOfDuplicatedCode.ql
- query: Metrics/Files/FNumberOfTests.ql

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Duplicate code
* @description This block of code is duplicated elsewhere. If possible, the shared code should be refactored so there is only one occurrence left. It may not always be possible to address these issues; other duplicate code checks (such as duplicate function, duplicate class) give subsets of the results with higher confidence.
* @kind problem

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Duplicate function
* @description There is another identical implementation of this function. Extract the code to a common file or superclass or delegate to improve sharing.
* @kind problem

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Mostly duplicate class
* @description More than 80% of the methods in this class are duplicated in another class. Create a common supertype to improve code sharing.
* @kind problem

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Mostly duplicate file
* @description There is another file that shares a lot of the code with this file. Merge the two files to improve maintainability.
* @kind problem

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Mostly duplicate function
* @description There is another function that shares a lot of the code with this one. Extract the code to a common file/superclass or delegate to improve sharing.
* @kind problem

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Mostly similar file
* @description There is another file that shares a lot of the code with this file. Notice that names of variables and types may have been changed. Merge the two files to improve maintainability.
* @kind problem

View File

@@ -37,15 +37,15 @@ public:
};
void test_typedefs(int_iterator_by_typedefs source1) {
sink(*source1);
sink(*(source1++));
sink(*(++source1));
sink(*source1); // tainted
sink(*(source1++)); // tainted
sink(*(++source1)); // tainted
}
void test_trait(int_iterator_by_trait source1) {
sink(*source1);
sink(*(source1++));
sink(*(++source1));
sink(*source1); // tainted
sink(*(source1++)); // tainted
sink(*(++source1)); // tainted
}
void test_non_iterator(non_iterator source1) {

View File

@@ -18,6 +18,7 @@ void sink(const char *s);
void sink(const std::string &s);
void sink(const char *filename, const char *mode);
void sink(char);
void sink(std::string::iterator);
void test_string()
{
@@ -349,6 +350,7 @@ void test_string_data_more()
sink(str); // tainted
sink(str.data()); // tainted
}
void test_string_iterators() {
// string append
{
@@ -389,7 +391,7 @@ void test_string_iterators() {
string::iterator i1 = s1.begin();
string::iterator i2 = s2.begin();
string::iterator i3, i4, i5, i6, i7, i8, i9;
string::iterator i3, i4, i5, i6, i7, i8, i9, i10, i11;
sink(*(i2+1)); //tainted
sink(*(i2-1)); // tainted
@@ -411,6 +413,13 @@ void test_string_iterators() {
i9 = s2.end();
--i9;
sink(*i9); // tainted
i10 = i2;
sink(*(i10++)); // tainted
sink(i10); // tainted
i11 = i2;
sink(*(i11--)); // tainted
sink(i11); // tainted
}
}
@@ -428,8 +437,6 @@ void test_string_insert_more()
sink(s2); // tainted
}
void sink(std::string::iterator);
void test_string_iterator_methods()
{
{

View File

@@ -52,119 +52,123 @@
| standalone_iterators.cpp:46:10:46:10 | call to operator* | standalone_iterators.cpp:45:39:45:45 | source1 |
| standalone_iterators.cpp:47:10:47:10 | call to operator* | standalone_iterators.cpp:45:39:45:45 | source1 |
| standalone_iterators.cpp:48:10:48:10 | call to operator* | standalone_iterators.cpp:45:39:45:45 | source1 |
| string.cpp:28:7:28:7 | a | string.cpp:24:12:24:17 | call to source |
| string.cpp:30:7:30:7 | c | string.cpp:26:16:26:21 | call to source |
| string.cpp:32:9:32:13 | call to c_str | string.cpp:26:16:26:21 | call to source |
| string.cpp:38:13:38:17 | call to c_str | string.cpp:14:10:14:15 | call to source |
| string.cpp:42:13:42:17 | call to c_str | string.cpp:14:10:14:15 | call to source |
| string.cpp:45:13:45:17 | call to c_str | string.cpp:14:10:14:15 | call to source |
| string.cpp:55:7:55:8 | cs | string.cpp:50:19:50:24 | call to source |
| string.cpp:56:7:56:8 | ss | string.cpp:50:19:50:24 | call to source |
| string.cpp:69:7:69:8 | cs | string.cpp:61:19:61:24 | call to source |
| string.cpp:70:7:70:8 | ss | string.cpp:61:19:61:24 | call to source |
| string.cpp:92:8:92:9 | s1 | string.cpp:87:18:87:23 | call to source |
| string.cpp:93:8:93:9 | s2 | string.cpp:88:20:88:25 | call to source |
| string.cpp:94:8:94:9 | s3 | string.cpp:90:8:90:13 | call to source |
| string.cpp:113:8:113:9 | s1 | string.cpp:109:32:109:37 | call to source |
| string.cpp:114:8:114:9 | s2 | string.cpp:111:20:111:25 | call to source |
| string.cpp:121:8:121:8 | c | string.cpp:119:16:119:21 | call to source |
| string.cpp:125:8:125:8 | call to operator* | string.cpp:119:16:119:21 | call to source |
| string.cpp:129:8:129:8 | c | string.cpp:119:16:119:21 | call to source |
| string.cpp:134:8:134:8 | c | string.cpp:132:28:132:33 | call to source |
| string.cpp:144:11:144:11 | call to operator+ | string.cpp:141:18:141:23 | call to source |
| string.cpp:145:11:145:11 | call to operator+ | string.cpp:141:18:141:23 | call to source |
| string.cpp:146:11:146:11 | call to operator+ | string.cpp:141:18:141:23 | call to source |
| string.cpp:149:11:149:11 | call to operator+ | string.cpp:149:13:149:18 | call to source |
| string.cpp:158:8:158:9 | s5 | string.cpp:154:18:154:23 | call to source |
| string.cpp:161:11:161:11 | call to operator+= | string.cpp:154:18:154:23 | call to source |
| string.cpp:162:8:162:9 | s6 | string.cpp:154:18:154:23 | call to source |
| string.cpp:165:11:165:11 | call to operator+= | string.cpp:165:14:165:19 | call to source |
| string.cpp:166:11:166:11 | call to operator+= | string.cpp:165:14:165:19 | call to source |
| string.cpp:167:8:167:9 | s7 | string.cpp:165:14:165:19 | call to source |
| string.cpp:171:8:171:9 | s8 | string.cpp:154:18:154:23 | call to source |
| string.cpp:176:8:176:9 | s9 | string.cpp:174:13:174:18 | call to source |
| string.cpp:184:8:184:10 | s10 | string.cpp:181:12:181:26 | call to source |
| string.cpp:198:10:198:15 | call to assign | string.cpp:190:17:190:22 | call to source |
| string.cpp:199:7:199:8 | s4 | string.cpp:190:17:190:22 | call to source |
| string.cpp:201:10:201:15 | call to assign | string.cpp:191:11:191:25 | call to source |
| string.cpp:202:7:202:8 | s5 | string.cpp:191:11:191:25 | call to source |
| string.cpp:205:7:205:8 | s6 | string.cpp:193:17:193:22 | call to source |
| string.cpp:219:10:219:15 | call to insert | string.cpp:210:17:210:22 | call to source |
| string.cpp:220:7:220:8 | s4 | string.cpp:210:17:210:22 | call to source |
| string.cpp:223:10:223:15 | call to insert | string.cpp:210:17:210:22 | call to source |
| string.cpp:224:7:224:8 | s5 | string.cpp:210:17:210:22 | call to source |
| string.cpp:227:10:227:15 | call to insert | string.cpp:211:11:211:25 | call to source |
| string.cpp:228:7:228:8 | s6 | string.cpp:211:11:211:25 | call to source |
| string.cpp:242:10:242:16 | call to replace | string.cpp:233:17:233:22 | call to source |
| string.cpp:243:7:243:8 | s4 | string.cpp:233:17:233:22 | call to source |
| string.cpp:246:10:246:16 | call to replace | string.cpp:233:17:233:22 | call to source |
| string.cpp:247:7:247:8 | s5 | string.cpp:233:17:233:22 | call to source |
| string.cpp:250:10:250:16 | call to replace | string.cpp:234:11:234:25 | call to source |
| string.cpp:251:7:251:8 | s6 | string.cpp:234:11:234:25 | call to source |
| string.cpp:264:7:264:8 | b2 | string.cpp:258:17:258:22 | call to source |
| string.cpp:274:7:274:8 | s2 | string.cpp:269:17:269:22 | call to source |
| string.cpp:276:7:276:8 | s4 | string.cpp:271:17:271:22 | call to source |
| string.cpp:281:7:281:8 | s1 | string.cpp:269:17:269:22 | call to source |
| string.cpp:282:7:282:8 | s2 | string.cpp:269:17:269:22 | call to source |
| string.cpp:283:7:283:8 | s3 | string.cpp:271:17:271:22 | call to source |
| string.cpp:284:7:284:8 | s4 | string.cpp:271:17:271:22 | call to source |
| string.cpp:292:7:292:8 | s1 | string.cpp:288:17:288:22 | call to source |
| string.cpp:293:7:293:8 | s2 | string.cpp:289:17:289:22 | call to source |
| string.cpp:294:7:294:8 | s3 | string.cpp:290:17:290:22 | call to source |
| string.cpp:300:7:300:8 | s1 | string.cpp:288:17:288:22 | call to source |
| string.cpp:302:7:302:8 | s3 | string.cpp:290:17:290:22 | call to source |
| string.cpp:311:9:311:12 | call to data | string.cpp:308:16:308:21 | call to source |
| string.cpp:322:9:322:14 | call to substr | string.cpp:319:16:319:21 | call to source |
| string.cpp:339:7:339:7 | a | string.cpp:335:9:335:23 | call to source |
| string.cpp:340:7:340:7 | b | string.cpp:336:12:336:26 | call to source |
| string.cpp:341:7:341:7 | c | string.cpp:335:9:335:23 | call to source |
| string.cpp:349:7:349:9 | str | string.cpp:348:18:348:32 | call to source |
| string.cpp:350:11:350:14 | call to data | string.cpp:348:18:348:32 | call to source |
| string.cpp:361:11:361:16 | call to append | string.cpp:356:18:356:23 | call to source |
| string.cpp:362:8:362:9 | s1 | string.cpp:356:18:356:23 | call to source |
| string.cpp:380:8:380:8 | call to operator* | string.cpp:372:18:372:23 | call to source |
| string.cpp:381:13:381:13 | call to operator[] | string.cpp:372:18:372:23 | call to source |
| string.cpp:394:8:394:8 | call to operator* | string.cpp:387:18:387:23 | call to source |
| string.cpp:395:8:395:8 | call to operator* | string.cpp:387:18:387:23 | call to source |
| string.cpp:397:8:397:8 | call to operator* | string.cpp:387:18:387:23 | call to source |
| string.cpp:399:8:399:8 | call to operator* | string.cpp:387:18:387:23 | call to source |
| string.cpp:402:8:402:8 | call to operator* | string.cpp:387:18:387:23 | call to source |
| string.cpp:405:8:405:8 | call to operator* | string.cpp:387:18:387:23 | call to source |
| string.cpp:407:8:407:8 | call to operator* | string.cpp:387:18:387:23 | call to source |
| string.cpp:409:8:409:8 | call to operator* | string.cpp:387:18:387:23 | call to source |
| string.cpp:413:8:413:8 | call to operator* | string.cpp:387:18:387:23 | call to source |
| string.cpp:427:10:427:15 | call to insert | string.cpp:422:14:422:19 | call to source |
| string.cpp:428:7:428:8 | s2 | string.cpp:422:14:422:19 | call to source |
| string.cpp:442:10:442:15 | call to insert | string.cpp:442:32:442:46 | call to source |
| string.cpp:443:8:443:8 | b | string.cpp:442:32:442:46 | call to source |
| string.cpp:455:10:455:15 | call to insert | string.cpp:450:18:450:23 | call to source |
| string.cpp:456:8:456:8 | d | string.cpp:450:18:450:23 | call to source |
| string.cpp:458:11:458:16 | call to insert | string.cpp:450:18:450:23 | call to source |
| string.cpp:459:8:459:9 | s2 | string.cpp:450:18:450:23 | call to source |
| string.cpp:471:10:471:15 | call to append | string.cpp:466:18:466:23 | call to source |
| string.cpp:472:8:472:8 | f | string.cpp:466:18:466:23 | call to source |
| string.cpp:474:11:474:16 | call to append | string.cpp:466:18:466:23 | call to source |
| string.cpp:475:8:475:9 | s4 | string.cpp:466:18:466:23 | call to source |
| string.cpp:487:10:487:15 | call to assign | string.cpp:482:18:482:23 | call to source |
| string.cpp:488:8:488:8 | h | string.cpp:482:18:482:23 | call to source |
| string.cpp:491:8:491:9 | s6 | string.cpp:482:18:482:23 | call to source |
| string.cpp:504:7:504:8 | s2 | string.cpp:497:14:497:19 | call to source |
| string.cpp:506:7:506:8 | s4 | string.cpp:497:14:497:19 | call to source |
| string.cpp:515:9:515:13 | call to front | string.cpp:514:14:514:28 | call to source |
| string.cpp:516:9:516:12 | call to back | string.cpp:514:14:514:28 | call to source |
| string.cpp:529:11:529:11 | call to operator+= | string.cpp:529:20:529:25 | call to source |
| string.cpp:530:21:530:21 | call to operator+= | string.cpp:530:24:530:29 | call to source |
| string.cpp:531:25:531:25 | call to operator+= | string.cpp:531:15:531:20 | call to source |
| string.cpp:534:8:534:8 | c | string.cpp:529:20:529:25 | call to source |
| string.cpp:535:8:535:8 | d | string.cpp:529:20:529:25 | call to source |
| string.cpp:536:8:536:8 | e | string.cpp:530:24:530:29 | call to source |
| string.cpp:537:8:537:8 | f | string.cpp:531:15:531:20 | call to source |
| string.cpp:549:11:549:16 | call to assign | string.cpp:549:27:549:32 | call to source |
| string.cpp:550:24:550:29 | call to assign | string.cpp:550:31:550:36 | call to source |
| string.cpp:554:8:554:8 | c | string.cpp:549:27:549:32 | call to source |
| string.cpp:555:8:555:8 | d | string.cpp:549:27:549:32 | call to source |
| string.cpp:556:8:556:8 | e | string.cpp:550:31:550:36 | call to source |
| string.cpp:557:8:557:8 | f | string.cpp:551:18:551:23 | call to source |
| string.cpp:29:7:29:7 | a | string.cpp:25:12:25:17 | call to source |
| string.cpp:31:7:31:7 | c | string.cpp:27:16:27:21 | call to source |
| string.cpp:33:9:33:13 | call to c_str | string.cpp:27:16:27:21 | call to source |
| string.cpp:39:13:39:17 | call to c_str | string.cpp:14:10:14:15 | call to source |
| string.cpp:43:13:43:17 | call to c_str | string.cpp:14:10:14:15 | call to source |
| string.cpp:46:13:46:17 | call to c_str | string.cpp:14:10:14:15 | call to source |
| string.cpp:56:7:56:8 | cs | string.cpp:51:19:51:24 | call to source |
| string.cpp:57:7:57:8 | ss | string.cpp:51:19:51:24 | call to source |
| string.cpp:70:7:70:8 | cs | string.cpp:62:19:62:24 | call to source |
| string.cpp:71:7:71:8 | ss | string.cpp:62:19:62:24 | call to source |
| string.cpp:93:8:93:9 | s1 | string.cpp:88:18:88:23 | call to source |
| string.cpp:94:8:94:9 | s2 | string.cpp:89:20:89:25 | call to source |
| string.cpp:95:8:95:9 | s3 | string.cpp:91:8:91:13 | call to source |
| string.cpp:114:8:114:9 | s1 | string.cpp:110:32:110:37 | call to source |
| string.cpp:115:8:115:9 | s2 | string.cpp:112:20:112:25 | call to source |
| string.cpp:122:8:122:8 | c | string.cpp:120:16:120:21 | call to source |
| string.cpp:126:8:126:8 | call to operator* | string.cpp:120:16:120:21 | call to source |
| string.cpp:130:8:130:8 | c | string.cpp:120:16:120:21 | call to source |
| string.cpp:135:8:135:8 | c | string.cpp:133:28:133:33 | call to source |
| string.cpp:145:11:145:11 | call to operator+ | string.cpp:142:18:142:23 | call to source |
| string.cpp:146:11:146:11 | call to operator+ | string.cpp:142:18:142:23 | call to source |
| string.cpp:147:11:147:11 | call to operator+ | string.cpp:142:18:142:23 | call to source |
| string.cpp:150:11:150:11 | call to operator+ | string.cpp:150:13:150:18 | call to source |
| string.cpp:159:8:159:9 | s5 | string.cpp:155:18:155:23 | call to source |
| string.cpp:162:11:162:11 | call to operator+= | string.cpp:155:18:155:23 | call to source |
| string.cpp:163:8:163:9 | s6 | string.cpp:155:18:155:23 | call to source |
| string.cpp:166:11:166:11 | call to operator+= | string.cpp:166:14:166:19 | call to source |
| string.cpp:167:11:167:11 | call to operator+= | string.cpp:166:14:166:19 | call to source |
| string.cpp:168:8:168:9 | s7 | string.cpp:166:14:166:19 | call to source |
| string.cpp:172:8:172:9 | s8 | string.cpp:155:18:155:23 | call to source |
| string.cpp:177:8:177:9 | s9 | string.cpp:175:13:175:18 | call to source |
| string.cpp:185:8:185:10 | s10 | string.cpp:182:12:182:26 | call to source |
| string.cpp:199:10:199:15 | call to assign | string.cpp:191:17:191:22 | call to source |
| string.cpp:200:7:200:8 | s4 | string.cpp:191:17:191:22 | call to source |
| string.cpp:202:10:202:15 | call to assign | string.cpp:192:11:192:25 | call to source |
| string.cpp:203:7:203:8 | s5 | string.cpp:192:11:192:25 | call to source |
| string.cpp:206:7:206:8 | s6 | string.cpp:194:17:194:22 | call to source |
| string.cpp:220:10:220:15 | call to insert | string.cpp:211:17:211:22 | call to source |
| string.cpp:221:7:221:8 | s4 | string.cpp:211:17:211:22 | call to source |
| string.cpp:224:10:224:15 | call to insert | string.cpp:211:17:211:22 | call to source |
| string.cpp:225:7:225:8 | s5 | string.cpp:211:17:211:22 | call to source |
| string.cpp:228:10:228:15 | call to insert | string.cpp:212:11:212:25 | call to source |
| string.cpp:229:7:229:8 | s6 | string.cpp:212:11:212:25 | call to source |
| string.cpp:243:10:243:16 | call to replace | string.cpp:234:17:234:22 | call to source |
| string.cpp:244:7:244:8 | s4 | string.cpp:234:17:234:22 | call to source |
| string.cpp:247:10:247:16 | call to replace | string.cpp:234:17:234:22 | call to source |
| string.cpp:248:7:248:8 | s5 | string.cpp:234:17:234:22 | call to source |
| string.cpp:251:10:251:16 | call to replace | string.cpp:235:11:235:25 | call to source |
| string.cpp:252:7:252:8 | s6 | string.cpp:235:11:235:25 | call to source |
| string.cpp:265:7:265:8 | b2 | string.cpp:259:17:259:22 | call to source |
| string.cpp:275:7:275:8 | s2 | string.cpp:270:17:270:22 | call to source |
| string.cpp:277:7:277:8 | s4 | string.cpp:272:17:272:22 | call to source |
| string.cpp:282:7:282:8 | s1 | string.cpp:270:17:270:22 | call to source |
| string.cpp:283:7:283:8 | s2 | string.cpp:270:17:270:22 | call to source |
| string.cpp:284:7:284:8 | s3 | string.cpp:272:17:272:22 | call to source |
| string.cpp:285:7:285:8 | s4 | string.cpp:272:17:272:22 | call to source |
| string.cpp:293:7:293:8 | s1 | string.cpp:289:17:289:22 | call to source |
| string.cpp:294:7:294:8 | s2 | string.cpp:290:17:290:22 | call to source |
| string.cpp:295:7:295:8 | s3 | string.cpp:291:17:291:22 | call to source |
| string.cpp:301:7:301:8 | s1 | string.cpp:289:17:289:22 | call to source |
| string.cpp:303:7:303:8 | s3 | string.cpp:291:17:291:22 | call to source |
| string.cpp:312:9:312:12 | call to data | string.cpp:309:16:309:21 | call to source |
| string.cpp:323:9:323:14 | call to substr | string.cpp:320:16:320:21 | call to source |
| string.cpp:340:7:340:7 | a | string.cpp:336:9:336:23 | call to source |
| string.cpp:341:7:341:7 | b | string.cpp:337:12:337:26 | call to source |
| string.cpp:342:7:342:7 | c | string.cpp:336:9:336:23 | call to source |
| string.cpp:350:7:350:9 | str | string.cpp:349:18:349:32 | call to source |
| string.cpp:351:11:351:14 | call to data | string.cpp:349:18:349:32 | call to source |
| string.cpp:363:11:363:16 | call to append | string.cpp:358:18:358:23 | call to source |
| string.cpp:364:8:364:9 | s1 | string.cpp:358:18:358:23 | call to source |
| string.cpp:382:8:382:8 | call to operator* | string.cpp:374:18:374:23 | call to source |
| string.cpp:383:13:383:13 | call to operator[] | string.cpp:374:18:374:23 | call to source |
| string.cpp:396:8:396:8 | call to operator* | string.cpp:389:18:389:23 | call to source |
| string.cpp:397:8:397:8 | call to operator* | string.cpp:389:18:389:23 | call to source |
| string.cpp:399:8:399:8 | call to operator* | string.cpp:389:18:389:23 | call to source |
| string.cpp:401:8:401:8 | call to operator* | string.cpp:389:18:389:23 | call to source |
| string.cpp:404:8:404:8 | call to operator* | string.cpp:389:18:389:23 | call to source |
| string.cpp:407:8:407:8 | call to operator* | string.cpp:389:18:389:23 | call to source |
| string.cpp:409:8:409:8 | call to operator* | string.cpp:389:18:389:23 | call to source |
| string.cpp:411:8:411:8 | call to operator* | string.cpp:389:18:389:23 | call to source |
| string.cpp:415:8:415:8 | call to operator* | string.cpp:389:18:389:23 | call to source |
| string.cpp:418:8:418:8 | call to operator* | string.cpp:389:18:389:23 | call to source |
| string.cpp:419:8:419:10 | call to iterator | string.cpp:389:18:389:23 | call to source |
| string.cpp:421:8:421:8 | call to operator* | string.cpp:389:18:389:23 | call to source |
| string.cpp:422:8:422:10 | call to iterator | string.cpp:389:18:389:23 | call to source |
| string.cpp:436:10:436:15 | call to insert | string.cpp:431:14:431:19 | call to source |
| string.cpp:437:7:437:8 | s2 | string.cpp:431:14:431:19 | call to source |
| string.cpp:449:10:449:15 | call to insert | string.cpp:449:32:449:46 | call to source |
| string.cpp:450:8:450:8 | b | string.cpp:449:32:449:46 | call to source |
| string.cpp:462:10:462:15 | call to insert | string.cpp:457:18:457:23 | call to source |
| string.cpp:463:8:463:8 | d | string.cpp:457:18:457:23 | call to source |
| string.cpp:465:11:465:16 | call to insert | string.cpp:457:18:457:23 | call to source |
| string.cpp:466:8:466:9 | s2 | string.cpp:457:18:457:23 | call to source |
| string.cpp:478:10:478:15 | call to append | string.cpp:473:18:473:23 | call to source |
| string.cpp:479:8:479:8 | f | string.cpp:473:18:473:23 | call to source |
| string.cpp:481:11:481:16 | call to append | string.cpp:473:18:473:23 | call to source |
| string.cpp:482:8:482:9 | s4 | string.cpp:473:18:473:23 | call to source |
| string.cpp:494:10:494:15 | call to assign | string.cpp:489:18:489:23 | call to source |
| string.cpp:495:8:495:8 | h | string.cpp:489:18:489:23 | call to source |
| string.cpp:498:8:498:9 | s6 | string.cpp:489:18:489:23 | call to source |
| string.cpp:511:7:511:8 | s2 | string.cpp:504:14:504:19 | call to source |
| string.cpp:513:7:513:8 | s4 | string.cpp:504:14:504:19 | call to source |
| string.cpp:522:9:522:13 | call to front | string.cpp:521:14:521:28 | call to source |
| string.cpp:523:9:523:12 | call to back | string.cpp:521:14:521:28 | call to source |
| string.cpp:536:11:536:11 | call to operator+= | string.cpp:536:20:536:25 | call to source |
| string.cpp:537:21:537:21 | call to operator+= | string.cpp:537:24:537:29 | call to source |
| string.cpp:538:25:538:25 | call to operator+= | string.cpp:538:15:538:20 | call to source |
| string.cpp:541:8:541:8 | c | string.cpp:536:20:536:25 | call to source |
| string.cpp:542:8:542:8 | d | string.cpp:536:20:536:25 | call to source |
| string.cpp:543:8:543:8 | e | string.cpp:537:24:537:29 | call to source |
| string.cpp:544:8:544:8 | f | string.cpp:538:15:538:20 | call to source |
| string.cpp:556:11:556:16 | call to assign | string.cpp:556:27:556:32 | call to source |
| string.cpp:557:24:557:29 | call to assign | string.cpp:557:31:557:36 | call to source |
| string.cpp:561:8:561:8 | c | string.cpp:556:27:556:32 | call to source |
| string.cpp:562:8:562:8 | d | string.cpp:556:27:556:32 | call to source |
| string.cpp:563:8:563:8 | e | string.cpp:557:31:557:36 | call to source |
| string.cpp:564:8:564:8 | f | string.cpp:558:18:558:23 | call to source |
| stringstream.cpp:32:11:32:11 | call to operator<< | stringstream.cpp:32:14:32:19 | call to source |
| stringstream.cpp:33:20:33:20 | call to operator<< | stringstream.cpp:33:23:33:28 | call to source |
| stringstream.cpp:34:23:34:23 | call to operator<< | stringstream.cpp:34:14:34:19 | call to source |

View File

@@ -25,59 +25,63 @@
| standalone_iterators.cpp:42:10:42:10 | standalone_iterators.cpp:39:45:39:51 | AST only |
| standalone_iterators.cpp:47:10:47:10 | standalone_iterators.cpp:45:39:45:45 | AST only |
| standalone_iterators.cpp:48:10:48:10 | standalone_iterators.cpp:45:39:45:45 | AST only |
| string.cpp:32:9:32:13 | string.cpp:26:16:26:21 | AST only |
| string.cpp:38:13:38:17 | string.cpp:14:10:14:15 | AST only |
| string.cpp:42:13:42:17 | string.cpp:14:10:14:15 | AST only |
| string.cpp:45:13:45:17 | string.cpp:14:10:14:15 | AST only |
| string.cpp:69:7:69:8 | string.cpp:61:19:61:24 | AST only |
| string.cpp:125:8:125:11 | string.cpp:119:16:119:21 | IR only |
| string.cpp:161:11:161:11 | string.cpp:154:18:154:23 | AST only |
| string.cpp:165:11:165:11 | string.cpp:165:14:165:19 | AST only |
| string.cpp:166:11:166:11 | string.cpp:165:14:165:19 | AST only |
| string.cpp:198:10:198:15 | string.cpp:190:17:190:22 | AST only |
| string.cpp:201:10:201:15 | string.cpp:191:11:191:25 | AST only |
| string.cpp:219:10:219:15 | string.cpp:210:17:210:22 | AST only |
| string.cpp:223:10:223:15 | string.cpp:210:17:210:22 | AST only |
| string.cpp:227:10:227:15 | string.cpp:211:11:211:25 | AST only |
| string.cpp:242:10:242:16 | string.cpp:233:17:233:22 | AST only |
| string.cpp:246:10:246:16 | string.cpp:233:17:233:22 | AST only |
| string.cpp:250:10:250:16 | string.cpp:234:11:234:25 | AST only |
| string.cpp:311:9:311:12 | string.cpp:308:16:308:21 | AST only |
| string.cpp:339:7:339:7 | string.cpp:335:9:335:23 | AST only |
| string.cpp:340:7:340:7 | string.cpp:336:12:336:26 | AST only |
| string.cpp:341:7:341:7 | string.cpp:335:9:335:23 | AST only |
| string.cpp:349:7:349:9 | string.cpp:348:18:348:32 | AST only |
| string.cpp:350:11:350:14 | string.cpp:348:18:348:32 | AST only |
| string.cpp:361:11:361:16 | string.cpp:356:18:356:23 | AST only |
| string.cpp:380:8:380:14 | string.cpp:372:18:372:23 | IR only |
| string.cpp:381:13:381:15 | string.cpp:372:18:372:23 | IR only |
| string.cpp:394:8:394:8 | string.cpp:387:18:387:23 | AST only |
| string.cpp:395:8:395:8 | string.cpp:387:18:387:23 | AST only |
| string.cpp:397:8:397:8 | string.cpp:387:18:387:23 | AST only |
| string.cpp:399:8:399:8 | string.cpp:387:18:387:23 | AST only |
| string.cpp:402:8:402:11 | string.cpp:387:18:387:23 | IR only |
| string.cpp:405:8:405:11 | string.cpp:387:18:387:23 | IR only |
| string.cpp:407:8:407:8 | string.cpp:387:18:387:23 | AST only |
| string.cpp:409:8:409:8 | string.cpp:387:18:387:23 | AST only |
| string.cpp:413:8:413:11 | string.cpp:387:18:387:23 | IR only |
| string.cpp:427:10:427:15 | string.cpp:422:14:422:19 | AST only |
| string.cpp:442:10:442:15 | string.cpp:442:32:442:46 | AST only |
| string.cpp:455:10:455:15 | string.cpp:450:18:450:23 | AST only |
| string.cpp:458:11:458:16 | string.cpp:450:18:450:23 | AST only |
| string.cpp:471:10:471:15 | string.cpp:466:18:466:23 | AST only |
| string.cpp:474:11:474:16 | string.cpp:466:18:466:23 | AST only |
| string.cpp:487:10:487:15 | string.cpp:482:18:482:23 | AST only |
| string.cpp:515:9:515:13 | string.cpp:514:14:514:28 | AST only |
| string.cpp:516:9:516:12 | string.cpp:514:14:514:28 | AST only |
| string.cpp:529:11:529:11 | string.cpp:529:20:529:25 | AST only |
| string.cpp:530:21:530:21 | string.cpp:530:24:530:29 | AST only |
| string.cpp:531:25:531:25 | string.cpp:531:15:531:20 | AST only |
| string.cpp:534:8:534:8 | string.cpp:529:20:529:25 | AST only |
| string.cpp:536:8:536:8 | string.cpp:530:24:530:29 | AST only |
| string.cpp:549:11:549:16 | string.cpp:549:27:549:32 | AST only |
| string.cpp:550:24:550:29 | string.cpp:550:31:550:36 | AST only |
| string.cpp:554:8:554:8 | string.cpp:549:27:549:32 | AST only |
| string.cpp:556:8:556:8 | string.cpp:550:31:550:36 | AST only |
| string.cpp:33:9:33:13 | string.cpp:27:16:27:21 | AST only |
| string.cpp:39:13:39:17 | string.cpp:14:10:14:15 | AST only |
| string.cpp:43:13:43:17 | string.cpp:14:10:14:15 | AST only |
| string.cpp:46:13:46:17 | string.cpp:14:10:14:15 | AST only |
| string.cpp:70:7:70:8 | string.cpp:62:19:62:24 | AST only |
| string.cpp:126:8:126:11 | string.cpp:120:16:120:21 | IR only |
| string.cpp:162:11:162:11 | string.cpp:155:18:155:23 | AST only |
| string.cpp:166:11:166:11 | string.cpp:166:14:166:19 | AST only |
| string.cpp:167:11:167:11 | string.cpp:166:14:166:19 | AST only |
| string.cpp:199:10:199:15 | string.cpp:191:17:191:22 | AST only |
| string.cpp:202:10:202:15 | string.cpp:192:11:192:25 | AST only |
| string.cpp:220:10:220:15 | string.cpp:211:17:211:22 | AST only |
| string.cpp:224:10:224:15 | string.cpp:211:17:211:22 | AST only |
| string.cpp:228:10:228:15 | string.cpp:212:11:212:25 | AST only |
| string.cpp:243:10:243:16 | string.cpp:234:17:234:22 | AST only |
| string.cpp:247:10:247:16 | string.cpp:234:17:234:22 | AST only |
| string.cpp:251:10:251:16 | string.cpp:235:11:235:25 | AST only |
| string.cpp:312:9:312:12 | string.cpp:309:16:309:21 | AST only |
| string.cpp:340:7:340:7 | string.cpp:336:9:336:23 | AST only |
| string.cpp:341:7:341:7 | string.cpp:337:12:337:26 | AST only |
| string.cpp:342:7:342:7 | string.cpp:336:9:336:23 | AST only |
| string.cpp:350:7:350:9 | string.cpp:349:18:349:32 | AST only |
| string.cpp:351:11:351:14 | string.cpp:349:18:349:32 | AST only |
| string.cpp:363:11:363:16 | string.cpp:358:18:358:23 | AST only |
| string.cpp:382:8:382:14 | string.cpp:374:18:374:23 | IR only |
| string.cpp:383:13:383:15 | string.cpp:374:18:374:23 | IR only |
| string.cpp:396:8:396:8 | string.cpp:389:18:389:23 | AST only |
| string.cpp:397:8:397:8 | string.cpp:389:18:389:23 | AST only |
| string.cpp:399:8:399:8 | string.cpp:389:18:389:23 | AST only |
| string.cpp:401:8:401:8 | string.cpp:389:18:389:23 | AST only |
| string.cpp:404:8:404:11 | string.cpp:389:18:389:23 | IR only |
| string.cpp:407:8:407:11 | string.cpp:389:18:389:23 | IR only |
| string.cpp:409:8:409:8 | string.cpp:389:18:389:23 | AST only |
| string.cpp:411:8:411:8 | string.cpp:389:18:389:23 | AST only |
| string.cpp:415:8:415:11 | string.cpp:389:18:389:23 | IR only |
| string.cpp:418:8:418:8 | string.cpp:389:18:389:23 | AST only |
| string.cpp:419:8:419:10 | string.cpp:389:18:389:23 | AST only |
| string.cpp:421:8:421:8 | string.cpp:389:18:389:23 | AST only |
| string.cpp:422:8:422:10 | string.cpp:389:18:389:23 | AST only |
| string.cpp:436:10:436:15 | string.cpp:431:14:431:19 | AST only |
| string.cpp:449:10:449:15 | string.cpp:449:32:449:46 | AST only |
| string.cpp:462:10:462:15 | string.cpp:457:18:457:23 | AST only |
| string.cpp:465:11:465:16 | string.cpp:457:18:457:23 | AST only |
| string.cpp:478:10:478:15 | string.cpp:473:18:473:23 | AST only |
| string.cpp:481:11:481:16 | string.cpp:473:18:473:23 | AST only |
| string.cpp:494:10:494:15 | string.cpp:489:18:489:23 | AST only |
| string.cpp:522:9:522:13 | string.cpp:521:14:521:28 | AST only |
| string.cpp:523:9:523:12 | string.cpp:521:14:521:28 | AST only |
| string.cpp:536:11:536:11 | string.cpp:536:20:536:25 | AST only |
| string.cpp:537:21:537:21 | string.cpp:537:24:537:29 | AST only |
| string.cpp:538:25:538:25 | string.cpp:538:15:538:20 | AST only |
| string.cpp:541:8:541:8 | string.cpp:536:20:536:25 | AST only |
| string.cpp:543:8:543:8 | string.cpp:537:24:537:29 | AST only |
| string.cpp:556:11:556:16 | string.cpp:556:27:556:32 | AST only |
| string.cpp:557:24:557:29 | string.cpp:557:31:557:36 | AST only |
| string.cpp:561:8:561:8 | string.cpp:556:27:556:32 | AST only |
| string.cpp:563:8:563:8 | string.cpp:557:31:557:36 | AST only |
| stringstream.cpp:32:11:32:22 | stringstream.cpp:32:14:32:19 | IR only |
| stringstream.cpp:33:20:33:31 | stringstream.cpp:33:23:33:28 | IR only |
| stringstream.cpp:34:23:34:31 | stringstream.cpp:34:14:34:19 | IR only |

View File

@@ -55,80 +55,80 @@
| smart_pointer.cpp:57:12:57:14 | call to get | smart_pointer.cpp:56:52:56:57 | call to source |
| standalone_iterators.cpp:40:10:40:10 | call to operator* | standalone_iterators.cpp:39:45:39:51 | source1 |
| standalone_iterators.cpp:46:10:46:10 | call to operator* | standalone_iterators.cpp:45:39:45:45 | source1 |
| string.cpp:28:7:28:7 | a | string.cpp:24:12:24:17 | call to source |
| string.cpp:30:7:30:7 | Argument 0 indirection | string.cpp:26:16:26:21 | call to source |
| string.cpp:55:7:55:8 | cs | string.cpp:50:19:50:24 | call to source |
| string.cpp:56:7:56:8 | Argument 0 indirection | string.cpp:50:19:50:24 | call to source |
| string.cpp:70:7:70:8 | Argument 0 indirection | string.cpp:61:19:61:24 | call to source |
| string.cpp:92:8:92:9 | Argument 0 indirection | string.cpp:87:18:87:23 | call to source |
| string.cpp:93:8:93:9 | Argument 0 indirection | string.cpp:88:20:88:25 | call to source |
| string.cpp:94:8:94:9 | Argument 0 indirection | string.cpp:90:8:90:13 | call to source |
| string.cpp:113:8:113:9 | Argument 0 indirection | string.cpp:109:32:109:37 | call to source |
| string.cpp:114:8:114:9 | Argument 0 indirection | string.cpp:111:20:111:25 | call to source |
| string.cpp:121:8:121:8 | c | string.cpp:119:16:119:21 | call to source |
| string.cpp:125:8:125:8 | call to operator* | string.cpp:119:16:119:21 | call to source |
| string.cpp:125:8:125:11 | (reference dereference) | string.cpp:119:16:119:21 | call to source |
| string.cpp:129:8:129:8 | (reference dereference) | string.cpp:119:16:119:21 | call to source |
| string.cpp:129:8:129:8 | c | string.cpp:119:16:119:21 | call to source |
| string.cpp:134:8:134:8 | (reference dereference) | string.cpp:132:28:132:33 | call to source |
| string.cpp:134:8:134:8 | c | string.cpp:132:28:132:33 | call to source |
| string.cpp:144:11:144:11 | call to operator+ | string.cpp:141:18:141:23 | call to source |
| string.cpp:145:11:145:11 | call to operator+ | string.cpp:141:18:141:23 | call to source |
| string.cpp:146:11:146:11 | call to operator+ | string.cpp:141:18:141:23 | call to source |
| string.cpp:149:11:149:11 | call to operator+ | string.cpp:149:13:149:18 | call to source |
| string.cpp:158:8:158:9 | Argument 0 indirection | string.cpp:154:18:154:23 | call to source |
| string.cpp:162:8:162:9 | Argument 0 indirection | string.cpp:154:18:154:23 | call to source |
| string.cpp:167:8:167:9 | Argument 0 indirection | string.cpp:165:14:165:19 | call to source |
| string.cpp:171:8:171:9 | Argument 0 indirection | string.cpp:154:18:154:23 | call to source |
| string.cpp:176:8:176:9 | Argument 0 indirection | string.cpp:174:13:174:18 | call to source |
| string.cpp:184:8:184:10 | Argument 0 indirection | string.cpp:181:12:181:26 | call to source |
| string.cpp:199:7:199:8 | Argument 0 indirection | string.cpp:190:17:190:22 | call to source |
| string.cpp:202:7:202:8 | Argument 0 indirection | string.cpp:191:11:191:25 | call to source |
| string.cpp:205:7:205:8 | Argument 0 indirection | string.cpp:193:17:193:22 | call to source |
| string.cpp:220:7:220:8 | Argument 0 indirection | string.cpp:210:17:210:22 | call to source |
| string.cpp:224:7:224:8 | Argument 0 indirection | string.cpp:210:17:210:22 | call to source |
| string.cpp:228:7:228:8 | Argument 0 indirection | string.cpp:211:11:211:25 | call to source |
| string.cpp:243:7:243:8 | Argument 0 indirection | string.cpp:233:17:233:22 | call to source |
| string.cpp:247:7:247:8 | Argument 0 indirection | string.cpp:233:17:233:22 | call to source |
| string.cpp:251:7:251:8 | Argument 0 indirection | string.cpp:234:11:234:25 | call to source |
| string.cpp:264:7:264:8 | Argument 0 indirection | string.cpp:258:17:258:22 | call to source |
| string.cpp:274:7:274:8 | Argument 0 indirection | string.cpp:269:17:269:22 | call to source |
| string.cpp:276:7:276:8 | Argument 0 indirection | string.cpp:271:17:271:22 | call to source |
| string.cpp:281:7:281:8 | Argument 0 indirection | string.cpp:269:17:269:22 | call to source |
| string.cpp:282:7:282:8 | Argument 0 indirection | string.cpp:269:17:269:22 | call to source |
| string.cpp:283:7:283:8 | Argument 0 indirection | string.cpp:271:17:271:22 | call to source |
| string.cpp:284:7:284:8 | Argument 0 indirection | string.cpp:271:17:271:22 | call to source |
| string.cpp:292:7:292:8 | Argument 0 indirection | string.cpp:288:17:288:22 | call to source |
| string.cpp:29:7:29:7 | a | string.cpp:25:12:25:17 | call to source |
| string.cpp:31:7:31:7 | Argument 0 indirection | string.cpp:27:16:27:21 | call to source |
| string.cpp:56:7:56:8 | cs | string.cpp:51:19:51:24 | call to source |
| string.cpp:57:7:57:8 | Argument 0 indirection | string.cpp:51:19:51:24 | call to source |
| string.cpp:71:7:71:8 | Argument 0 indirection | string.cpp:62:19:62:24 | call to source |
| string.cpp:93:8:93:9 | Argument 0 indirection | string.cpp:88:18:88:23 | call to source |
| string.cpp:94:8:94:9 | Argument 0 indirection | string.cpp:89:20:89:25 | call to source |
| string.cpp:95:8:95:9 | Argument 0 indirection | string.cpp:91:8:91:13 | call to source |
| string.cpp:114:8:114:9 | Argument 0 indirection | string.cpp:110:32:110:37 | call to source |
| string.cpp:115:8:115:9 | Argument 0 indirection | string.cpp:112:20:112:25 | call to source |
| string.cpp:122:8:122:8 | c | string.cpp:120:16:120:21 | call to source |
| string.cpp:126:8:126:8 | call to operator* | string.cpp:120:16:120:21 | call to source |
| string.cpp:126:8:126:11 | (reference dereference) | string.cpp:120:16:120:21 | call to source |
| string.cpp:130:8:130:8 | (reference dereference) | string.cpp:120:16:120:21 | call to source |
| string.cpp:130:8:130:8 | c | string.cpp:120:16:120:21 | call to source |
| string.cpp:135:8:135:8 | (reference dereference) | string.cpp:133:28:133:33 | call to source |
| string.cpp:135:8:135:8 | c | string.cpp:133:28:133:33 | call to source |
| string.cpp:145:11:145:11 | call to operator+ | string.cpp:142:18:142:23 | call to source |
| string.cpp:146:11:146:11 | call to operator+ | string.cpp:142:18:142:23 | call to source |
| string.cpp:147:11:147:11 | call to operator+ | string.cpp:142:18:142:23 | call to source |
| string.cpp:150:11:150:11 | call to operator+ | string.cpp:150:13:150:18 | call to source |
| string.cpp:159:8:159:9 | Argument 0 indirection | string.cpp:155:18:155:23 | call to source |
| string.cpp:163:8:163:9 | Argument 0 indirection | string.cpp:155:18:155:23 | call to source |
| string.cpp:168:8:168:9 | Argument 0 indirection | string.cpp:166:14:166:19 | call to source |
| string.cpp:172:8:172:9 | Argument 0 indirection | string.cpp:155:18:155:23 | call to source |
| string.cpp:177:8:177:9 | Argument 0 indirection | string.cpp:175:13:175:18 | call to source |
| string.cpp:185:8:185:10 | Argument 0 indirection | string.cpp:182:12:182:26 | call to source |
| string.cpp:200:7:200:8 | Argument 0 indirection | string.cpp:191:17:191:22 | call to source |
| string.cpp:203:7:203:8 | Argument 0 indirection | string.cpp:192:11:192:25 | call to source |
| string.cpp:206:7:206:8 | Argument 0 indirection | string.cpp:194:17:194:22 | call to source |
| string.cpp:221:7:221:8 | Argument 0 indirection | string.cpp:211:17:211:22 | call to source |
| string.cpp:225:7:225:8 | Argument 0 indirection | string.cpp:211:17:211:22 | call to source |
| string.cpp:229:7:229:8 | Argument 0 indirection | string.cpp:212:11:212:25 | call to source |
| string.cpp:244:7:244:8 | Argument 0 indirection | string.cpp:234:17:234:22 | call to source |
| string.cpp:248:7:248:8 | Argument 0 indirection | string.cpp:234:17:234:22 | call to source |
| string.cpp:252:7:252:8 | Argument 0 indirection | string.cpp:235:11:235:25 | call to source |
| string.cpp:265:7:265:8 | Argument 0 indirection | string.cpp:259:17:259:22 | call to source |
| string.cpp:275:7:275:8 | Argument 0 indirection | string.cpp:270:17:270:22 | call to source |
| string.cpp:277:7:277:8 | Argument 0 indirection | string.cpp:272:17:272:22 | call to source |
| string.cpp:282:7:282:8 | Argument 0 indirection | string.cpp:270:17:270:22 | call to source |
| string.cpp:283:7:283:8 | Argument 0 indirection | string.cpp:270:17:270:22 | call to source |
| string.cpp:284:7:284:8 | Argument 0 indirection | string.cpp:272:17:272:22 | call to source |
| string.cpp:285:7:285:8 | Argument 0 indirection | string.cpp:272:17:272:22 | call to source |
| string.cpp:293:7:293:8 | Argument 0 indirection | string.cpp:289:17:289:22 | call to source |
| string.cpp:294:7:294:8 | Argument 0 indirection | string.cpp:290:17:290:22 | call to source |
| string.cpp:300:7:300:8 | Argument 0 indirection | string.cpp:288:17:288:22 | call to source |
| string.cpp:302:7:302:8 | Argument 0 indirection | string.cpp:290:17:290:22 | call to source |
| string.cpp:322:9:322:14 | call to substr | string.cpp:319:16:319:21 | call to source |
| string.cpp:362:8:362:9 | Argument 0 indirection | string.cpp:356:18:356:23 | call to source |
| string.cpp:380:8:380:8 | call to operator* | string.cpp:372:18:372:23 | call to source |
| string.cpp:380:8:380:14 | (reference dereference) | string.cpp:372:18:372:23 | call to source |
| string.cpp:381:13:381:13 | call to operator[] | string.cpp:372:18:372:23 | call to source |
| string.cpp:381:13:381:15 | (reference dereference) | string.cpp:372:18:372:23 | call to source |
| string.cpp:402:8:402:8 | call to operator* | string.cpp:387:18:387:23 | call to source |
| string.cpp:402:8:402:11 | (reference dereference) | string.cpp:387:18:387:23 | call to source |
| string.cpp:405:8:405:8 | call to operator* | string.cpp:387:18:387:23 | call to source |
| string.cpp:405:8:405:11 | (reference dereference) | string.cpp:387:18:387:23 | call to source |
| string.cpp:413:8:413:8 | call to operator* | string.cpp:387:18:387:23 | call to source |
| string.cpp:413:8:413:11 | (reference dereference) | string.cpp:387:18:387:23 | call to source |
| string.cpp:428:7:428:8 | Argument 0 indirection | string.cpp:422:14:422:19 | call to source |
| string.cpp:443:8:443:8 | Argument 0 indirection | string.cpp:442:32:442:46 | call to source |
| string.cpp:456:8:456:8 | Argument 0 indirection | string.cpp:450:18:450:23 | call to source |
| string.cpp:459:8:459:9 | Argument 0 indirection | string.cpp:450:18:450:23 | call to source |
| string.cpp:472:8:472:8 | Argument 0 indirection | string.cpp:466:18:466:23 | call to source |
| string.cpp:475:8:475:9 | Argument 0 indirection | string.cpp:466:18:466:23 | call to source |
| string.cpp:488:8:488:8 | Argument 0 indirection | string.cpp:482:18:482:23 | call to source |
| string.cpp:491:8:491:9 | Argument 0 indirection | string.cpp:482:18:482:23 | call to source |
| string.cpp:504:7:504:8 | Argument 0 indirection | string.cpp:497:14:497:19 | call to source |
| string.cpp:506:7:506:8 | Argument 0 indirection | string.cpp:497:14:497:19 | call to source |
| string.cpp:535:8:535:8 | Argument 0 indirection | string.cpp:529:20:529:25 | call to source |
| string.cpp:537:8:537:8 | Argument 0 indirection | string.cpp:531:15:531:20 | call to source |
| string.cpp:555:8:555:8 | Argument 0 indirection | string.cpp:549:27:549:32 | call to source |
| string.cpp:557:8:557:8 | Argument 0 indirection | string.cpp:551:18:551:23 | call to source |
| string.cpp:295:7:295:8 | Argument 0 indirection | string.cpp:291:17:291:22 | call to source |
| string.cpp:301:7:301:8 | Argument 0 indirection | string.cpp:289:17:289:22 | call to source |
| string.cpp:303:7:303:8 | Argument 0 indirection | string.cpp:291:17:291:22 | call to source |
| string.cpp:323:9:323:14 | call to substr | string.cpp:320:16:320:21 | call to source |
| string.cpp:364:8:364:9 | Argument 0 indirection | string.cpp:358:18:358:23 | call to source |
| string.cpp:382:8:382:8 | call to operator* | string.cpp:374:18:374:23 | call to source |
| string.cpp:382:8:382:14 | (reference dereference) | string.cpp:374:18:374:23 | call to source |
| string.cpp:383:13:383:13 | call to operator[] | string.cpp:374:18:374:23 | call to source |
| string.cpp:383:13:383:15 | (reference dereference) | string.cpp:374:18:374:23 | call to source |
| string.cpp:404:8:404:8 | call to operator* | string.cpp:389:18:389:23 | call to source |
| string.cpp:404:8:404:11 | (reference dereference) | string.cpp:389:18:389:23 | call to source |
| string.cpp:407:8:407:8 | call to operator* | string.cpp:389:18:389:23 | call to source |
| string.cpp:407:8:407:11 | (reference dereference) | string.cpp:389:18:389:23 | call to source |
| string.cpp:415:8:415:8 | call to operator* | string.cpp:389:18:389:23 | call to source |
| string.cpp:415:8:415:11 | (reference dereference) | string.cpp:389:18:389:23 | call to source |
| string.cpp:437:7:437:8 | Argument 0 indirection | string.cpp:431:14:431:19 | call to source |
| string.cpp:450:8:450:8 | Argument 0 indirection | string.cpp:449:32:449:46 | call to source |
| string.cpp:463:8:463:8 | Argument 0 indirection | string.cpp:457:18:457:23 | call to source |
| string.cpp:466:8:466:9 | Argument 0 indirection | string.cpp:457:18:457:23 | call to source |
| string.cpp:479:8:479:8 | Argument 0 indirection | string.cpp:473:18:473:23 | call to source |
| string.cpp:482:8:482:9 | Argument 0 indirection | string.cpp:473:18:473:23 | call to source |
| string.cpp:495:8:495:8 | Argument 0 indirection | string.cpp:489:18:489:23 | call to source |
| string.cpp:498:8:498:9 | Argument 0 indirection | string.cpp:489:18:489:23 | call to source |
| string.cpp:511:7:511:8 | Argument 0 indirection | string.cpp:504:14:504:19 | call to source |
| string.cpp:513:7:513:8 | Argument 0 indirection | string.cpp:504:14:504:19 | call to source |
| string.cpp:542:8:542:8 | Argument 0 indirection | string.cpp:536:20:536:25 | call to source |
| string.cpp:544:8:544:8 | Argument 0 indirection | string.cpp:538:15:538:20 | call to source |
| string.cpp:562:8:562:8 | Argument 0 indirection | string.cpp:556:27:556:32 | call to source |
| string.cpp:564:8:564:8 | Argument 0 indirection | string.cpp:558:18:558:23 | call to source |
| stringstream.cpp:32:11:32:11 | call to operator<< | stringstream.cpp:32:14:32:19 | call to source |
| stringstream.cpp:32:11:32:22 | (reference dereference) | stringstream.cpp:32:14:32:19 | call to source |
| stringstream.cpp:33:20:33:20 | call to operator<< | stringstream.cpp:33:23:33:28 | call to source |

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name External dependencies
* @description Count the number of dependencies a C# source file has on assembly files.
* @kind treemap

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name External dependency source links
* @kind source-link
* @metricType externalDependency

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Duplicated lines in files
* @description The number of lines in a file, including code, comment and whitespace lines,
* which are duplicated in at least one other place.

View File

@@ -7,10 +7,7 @@
tags contain:
- ide-contextual-queries/local-definitions
- ide-contextual-queries/local-references
- query: Metrics/Dependencies/ExternalDependencies.ql
- query: Metrics/Dependencies/ExternalDependenciesSourceLinks.ql
- query: Metrics/Files/FLinesOfCode.ql
- query: Metrics/Files/FLinesOfCommentedCode.ql
- query: Metrics/Files/FLinesOfComment.ql
- query: Metrics/Files/FLinesOfDuplicatedCode.ql
- query: Metrics/Files/FNumberOfTests.ql

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Duplicate method
* @description There is another identical implementation of this method. Extract the code to a common superclass or delegate to improve sharing.
* @kind problem

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Duplicate class
* @description More than 80% of the methods in this class are duplicated in another class. Create a common supertype to improve code sharing.
* @kind problem

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Mostly duplicate file
* @description There is another file that shares a lot of the code with this file. Merge the two files to improve maintainability.
* @kind problem

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Mostly duplicate method
* @description There is another method that shares a lot of the code with this method. Extract the code to a common superclass or delegate to improve sharing.
* @kind problem

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Mostly similar file
* @description There is another file that shares a lot of the code with this file. Notice that names of variables and types may have been changed. Merge the two files to improve maintainability.
* @kind problem

View File

@@ -1,11 +0,0 @@
/**
* @name Edit the value of a metric
* @description Add 10 to a metric's value
* @deprecated
*/
import csharp
import external.MetricFilter
from MetricResult res
select res, res.getValue() + 10

View File

@@ -1,11 +0,0 @@
/**
* @name Edit the message of a query
* @description Change the string in the select to edit the message
* @deprecated
*/
import csharp
import external.DefectFilter
from DefectResult res
select res, "Filtered query result: " + res.getMessage()

View File

@@ -1,14 +0,0 @@
/**
* @name Filter: removed results from generated code
* @description Shows how to exclude certain files or folders from results.
* @deprecated
*/
import csharp
import external.DefectFilter
predicate generatedFile(File f) { f.getAbsolutePath().matches("%generated%") }
from DefectResult res
where not generatedFile(res.getFile())
select res, res.getMessage()

View File

@@ -1,12 +0,0 @@
/**
* @name Filter: only keep results from source
* @description Shows how to filter for only certain files
* @deprecated
*/
import csharp
import external.DefectFilter
from DefectResult res
where res.getFile().fromSource()
select res, res.getMessage()

View File

@@ -1,19 +0,0 @@
/**
* @name Defect from external data
* @description Insert description here...
* @kind problem
* @problem.severity warning
* @deprecated
*/
import csharp
import external.ExternalArtifact
// custom://[FileUtil][2011-01-02][false][1.1][6][Message 2]
from ExternalData d, File u
where
d.getQueryPath() = "external-data.ql" and
u.getStem() = d.getField(0)
select u,
d.getField(5) + ", " + d.getFieldAsDate(1) + ", " + d.getField(2) + ", " + d.getFieldAsFloat(3) +
", " + d.getFieldAsInt(4) + ": " + d.getNumFields()

View File

@@ -1,17 +0,0 @@
/**
* @name Defect from external defect
* @description Create a defect from external data
* @kind problem
* @problem.severity warning
* @deprecated
*/
import csharp
import external.ExternalArtifact
class DuplicateCode extends ExternalDefect {
DuplicateCode() { getQueryPath() = "duplicate-code/duplicateCode.ql" }
}
from DuplicateCode d
select d, "External Defect " + d.getMessage()

View File

@@ -1,17 +0,0 @@
/**
* @name Defect from external metric
* @description Create a defect from external data
* @kind problem
* @problem.severity warning
* @deprecated
*/
import csharp
import external.ExternalArtifact
from ExternalMetric m, File f
where
m.getQueryPath() = "filesBuilt.ql" and
m.getValue() = 1.0 and
m.getFile() = f
select f, "File is built"

View File

@@ -1,13 +0,0 @@
/**
* @name Metric filter
* @description Only include results in large files (200) lines of code.
* @kind treemap
* @deprecated
*/
import csharp
import external.MetricFilter
from MetricResult res
where res.getFile().getNumberOfLinesOfCode() > 200
select res, res.getValue()

View File

@@ -1,21 +0,0 @@
/**
* @name Metric from external defect
* @description Find number of duplicate code entries in a file
* @treemap.warnOn lowValues
* @metricType file
* @kind treemap
* @deprecated
*/
import csharp
import external.ExternalArtifact
class DuplicateCode extends ExternalDefect {
DuplicateCode() { getQueryPath() = "duplicate-code/duplicateCode.ql" }
}
predicate numDuplicateEntries(File f, int i) { i = count(DuplicateCode d | d.getFile() = f) }
from File f, int i
where numDuplicateEntries(f, i)
select f, i

View File

@@ -1,27 +0,0 @@
/**
* @name Metric from external metric
* @description Each file in a folder gets as metric value the number of files built in that folder
* @treemap.warnOn lowValues
* @metricType file
* @kind treemap
* @deprecated
*/
import csharp
import external.ExternalArtifact
predicate numBuiltFiles(Folder fold, int i) {
i =
count(File f |
exists(ExternalMetric m |
m.getQueryPath() = "filesBuilt.ql" and
m.getValue() = 1.0 and
m.getFile() = f
) and
f.getParentContainer() = fold
)
}
from File f, int i
where numBuiltFiles(f.getParentContainer(), i)
select f, i

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name External dependencies
* @description Count the number of dependencies a Java source file has on jar files.
* @kind treemap

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name External dependency source links
* @kind source-link
* @metricType externalDependency

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Duplicated lines in files
* @description The number of lines in a file, including code, comment and whitespace lines,
* which are duplicated in at least one other place.

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Similar lines in files
* @description The number of lines in a file, including code, comment and whitespace lines,
* which are similar to lines in at least one other place.

View File

@@ -7,10 +7,7 @@
tags contain:
- ide-contextual-queries/local-definitions
- ide-contextual-queries/local-references
- query: Metrics/Dependencies/ExternalDependencies.ql
- query: Metrics/Dependencies/ExternalDependenciesSourceLinks.ql
- query: Metrics/Files/FLinesOfCode.ql
- query: Metrics/Files/FLinesOfCommentedCode.ql
- query: Metrics/Files/FLinesOfComment.ql
- query: Metrics/Files/FLinesOfDuplicatedCode.ql
- query: Metrics/Files/FNumberOfTests.ql

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Duplicate anonymous class
* @description Duplicated anonymous classes indicate that refactoring is necessary.
* @kind problem

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Duplicate code
* @description This block of code is duplicated elsewhere. If possible, the shared code should be refactored so there is only one occurrence left. It may not always be possible to address these issues; other duplicate code checks (such as duplicate function, duplicate class) give subsets of the results with higher confidence.
* @kind problem

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Duplicate method
* @description Duplicated methods make code more difficult to understand and introduce a risk of
* changes being made to only one copy.

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Mostly duplicate class
* @description Classes in which most of the methods are duplicated in another class make code more
* difficult to understand and introduce a risk of changes being made to only one copy.

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Mostly duplicate file
* @description Files in which most of the lines are duplicated in another file make code more
* difficult to understand and introduce a risk of changes being made to only one copy.

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Mostly duplicate method
* @description Methods in which most of the lines are duplicated in another method make code more
* difficult to understand and introduce a risk of changes being made to only one copy.

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Mostly similar file
* @description Files in which most of the lines are similar to those in another file make code more
* difficult to understand and introduce a risk of changes being made to only one copy.

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name External dependencies
* @description Count the number of dependencies a JavaScript source file has on
* NPM packages or framework libraries.

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name External dependency source links
* @kind source-link
* @metricType externalDependency

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Duplicated lines in files
* @description The number of lines in a file (including code, comment and whitespace lines)
* occurring in a block of lines that is duplicated at least once somewhere else.

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Similar lines in files
* @description The number of lines in a file (including code, comment and whitespace lines)
* occurring in a block of lines that is similar to a block of lines seen

View File

@@ -8,10 +8,6 @@
- ide-contextual-queries/local-definitions
- ide-contextual-queries/local-references
- query: Comments/FCommentedOutCode.ql
- query: Metrics/Dependencies/ExternalDependencies.ql
- query: Metrics/Dependencies/ExternalDependenciesSourceLinks.ql
- query: Metrics/FLinesOfCode.ql
- query: Metrics/FLinesOfComment.ql
- query: Metrics/FLinesOfDuplicatedCode.ql
- query: Metrics/FLinesOfSimilarCode.ql
- query: Metrics/FNumberOfTests.ql

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Duplicate function
* @description There is another function that shares a lot of code with this function.
* Extract the common parts to a shared utility function to improve maintainability.

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Duplicate script
* @description There is another script that shares a lot of code with this script. Consider combining the
* two scripts to improve maintainability.

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Similar function
* @description There is another function that shares a lot of code with this function.
* Extract the common parts to a shared utility function to improve maintainability.

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Similar script
* @description There is another script that shares a lot of code with this script.
* Extract the common parts to a new script to improve maintainability..

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name External dependencies
* @description Count the number of dependencies that a Python source file has on external packages.
* @kind treemap

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name External dependency source links
* @kind source-link
* @metricType externalDependency

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Duplicated lines in files
* @description The number of lines in a file, including code, comment and whitespace lines,
* which are duplicated in at least one other place.

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Similar lines in files
* @description The number of lines in a file, including code, comment and whitespace lines,
* which are similar in at least one other place.

View File

@@ -8,10 +8,6 @@
- ide-contextual-queries/local-definitions
- ide-contextual-queries/local-references
- query: Lexical/FCommentedOutCode.ql
- query: Metrics/Dependencies/ExternalDependencies.ql
- query: Metrics/Dependencies/ExternalDependenciesSourceLinks.ql
- query: Metrics/FLinesOfCode.ql
- query: Metrics/FLinesOfComments.ql
- query: Metrics/FLinesOfDuplicatedCode.ql
- query: Metrics/FLinesOfSimilarCode.ql
- query: Metrics/FNumberOfTests.ql

View File

@@ -27,7 +27,34 @@ class CommandInjectionConfiguration extends TaintTracking::Configuration {
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) {
sink = any(SystemCommandExecution e).getCommand()
sink = any(SystemCommandExecution e).getCommand() and
// Since the implementation of standard library functions such `os.popen` looks like
// ```py
// def popen(cmd, mode="r", buffering=-1):
// ...
// proc = subprocess.Popen(cmd, ...)
// ```
// any time we would report flow to the `os.popen` sink, we can ALSO report the flow
// from the `cmd` parameter to the `subprocess.Popen` sink -- obviously we don't
// want that.
//
// However, simply removing taint edges out of a sink is not a good enough solution,
// since we would only flag one of the `os.system` calls in the following example
// due to use-use flow
// ```py
// os.system(cmd)
// os.system(cmd)
// ```
//
// Best solution I could come up with is to exclude all sinks inside the `os` and
// `subprocess` modules. This does have a downside: If we have overlooked a function
// in any of these, that internally runs a command, we no longer give an alert :|
//
// This does not only affect `os.popen`, but also the helper functions in
// `subprocess`. See:
// https://github.com/python/cpython/blob/fa7ce080175f65d678a7d5756c94f82887fc9803/Lib/os.py#L974
// https://github.com/python/cpython/blob/fa7ce080175f65d678a7d5756c94f82887fc9803/Lib/subprocess.py#L341
not sink.getScope().getEnclosingModule().getName() in ["os", "subprocess"]
}
}

View File

@@ -11,8 +11,11 @@ private import experimental.semmle.python.Concepts
/** Provides models for the Python standard library. */
private module Stdlib {
// ---------------------------------------------------------------------------
// os
// ---------------------------------------------------------------------------
/** Gets a reference to the `os` module. */
DataFlow::Node os(DataFlow::TypeTracker t) {
private DataFlow::Node os(DataFlow::TypeTracker t) {
t.start() and
result = DataFlow::importModule("os")
or
@@ -22,53 +25,60 @@ private module Stdlib {
/** Gets a reference to the `os` module. */
DataFlow::Node os() { result = os(DataFlow::TypeTracker::end()) }
/**
* Gets a reference to the attribute `attr_name` of the `os` module.
* WARNING: Only holds for a few predefined attributes.
*
* For example, using `attr_name = "system"` will get all uses of `os.system`.
*/
private DataFlow::Node os_attr(DataFlow::TypeTracker t, string attr_name) {
attr_name in ["system", "popen",
// exec
"execl", "execle", "execlp", "execlpe", "execv", "execve", "execvp", "execvpe",
// spawn
"spawnl", "spawnle", "spawnlp", "spawnlpe", "spawnv", "spawnve", "spawnvp", "spawnvpe",
"posix_spawn", "posix_spawnp",
// modules
"path"] and
(
t.start() and
result = DataFlow::importMember("os", attr_name)
or
t.startInAttr(attr_name) and
result = DataFlow::importModule("os")
)
or
// Due to bad performance when using normal setup with `os_attr(t2, attr_name).track(t2, t)`
// we have inlined that code and forced a join
exists(DataFlow::TypeTracker t2 |
exists(DataFlow::StepSummary summary |
os_attr_first_join(t2, attr_name, result, summary) and
t = t2.append(summary)
)
)
}
pragma[nomagic]
private predicate os_attr_first_join(
DataFlow::TypeTracker t2, string attr_name, DataFlow::Node res, DataFlow::StepSummary summary
) {
DataFlow::StepSummary::step(os_attr(t2, attr_name), res, summary)
}
/**
* Gets a reference to the attribute `attr_name` of the `os` module.
* WARNING: Only holds for a few predefined attributes.
*
* For example, using `"system"` will get all uses of `os.system`.
*/
private DataFlow::Node os_attr(string attr_name) {
result = os_attr(DataFlow::TypeTracker::end(), attr_name)
}
/** Provides models for the `os` module. */
module os {
/** Gets a reference to the `os.system` function. */
DataFlow::Node system(DataFlow::TypeTracker t) {
t.start() and
result = DataFlow::importMember("os", "system")
or
t.startInAttr("system") and
result = os()
or
exists(DataFlow::TypeTracker t2 | result = os::system(t2).track(t2, t))
}
/** Gets a reference to the `os.system` function. */
DataFlow::Node system() { result = os::system(DataFlow::TypeTracker::end()) }
/** Gets a reference to the `os.popen` function. */
DataFlow::Node popen(DataFlow::TypeTracker t) {
t.start() and
result = DataFlow::importMember("os", "popen")
or
t.startInAttr("popen") and
result = os()
or
exists(DataFlow::TypeTracker t2 | result = os::popen(t2).track(t2, t))
}
/** Gets a reference to the `os.popen` function. */
DataFlow::Node popen() { result = os::popen(DataFlow::TypeTracker::end()) }
/** Gets a reference to the `os.path` module. */
private DataFlow::Node path(DataFlow::TypeTracker t) {
t.start() and
(
result = DataFlow::importMember("os", "path")
or
result = DataFlow::importModule("os.path")
)
or
t.startInAttr("path") and
result = os()
or
exists(DataFlow::TypeTracker t2 | result = path(t2).track(t2, t))
}
/** Gets a reference to the `os.path` module. */
DataFlow::Node path() { result = path(DataFlow::TypeTracker::end()) }
DataFlow::Node path() { result = os_attr("path") }
/** Provides models for the `os.path` module */
module path {
@@ -83,7 +93,7 @@ private module Stdlib {
exists(DataFlow::TypeTracker t2 | result = join(t2).track(t2, t))
}
/** Gets a reference to the `os.join` module. */
/** Gets a reference to the `os.path.join` function. */
DataFlow::Node join() { result = join(DataFlow::TypeTracker::end()) }
}
}
@@ -93,7 +103,7 @@ private module Stdlib {
* See https://docs.python.org/3/library/os.html#os.system
*/
private class OsSystemCall extends SystemCommandExecution::Range {
OsSystemCall() { this.asCfgNode().(CallNode).getFunction() = os::system().asCfgNode() }
OsSystemCall() { this.asCfgNode().(CallNode).getFunction() = os_attr("system").asCfgNode() }
override DataFlow::Node getCommand() {
result.asCfgNode() = this.asCfgNode().(CallNode).getArg(0)
@@ -105,7 +115,57 @@ private module Stdlib {
* See https://docs.python.org/3/library/os.html#os.popen
*/
private class OsPopenCall extends SystemCommandExecution::Range {
OsPopenCall() { this.asCfgNode().(CallNode).getFunction() = os::popen().asCfgNode() }
OsPopenCall() { this.asCfgNode().(CallNode).getFunction() = os_attr("popen").asCfgNode() }
override DataFlow::Node getCommand() {
result.asCfgNode() = this.asCfgNode().(CallNode).getArg(0)
}
}
/**
* A call to any of the `os.exec*` functions
* See https://docs.python.org/3.8/library/os.html#os.execl
*/
private class OsExecCall extends SystemCommandExecution::Range {
OsExecCall() {
exists(string name |
name in ["execl", "execle", "execlp", "execlpe", "execv", "execve", "execvp", "execvpe"] and
this.asCfgNode().(CallNode).getFunction() = os_attr(name).asCfgNode()
)
}
override DataFlow::Node getCommand() {
result.asCfgNode() = this.asCfgNode().(CallNode).getArg(0)
}
}
/**
* A call to any of the `os.spawn*` functions
* See https://docs.python.org/3.8/library/os.html#os.spawnl
*/
private class OsSpawnCall extends SystemCommandExecution::Range {
OsSpawnCall() {
exists(string name |
name in ["spawnl", "spawnle", "spawnlp", "spawnlpe", "spawnv", "spawnve", "spawnvp",
"spawnvpe"] and
this.asCfgNode().(CallNode).getFunction() = os_attr(name).asCfgNode()
)
}
override DataFlow::Node getCommand() {
result.asCfgNode() = this.asCfgNode().(CallNode).getArg(1)
}
}
/**
* A call to any of the `os.posix_spawn*` functions
* See https://docs.python.org/3.8/library/os.html#os.posix_spawn
*/
private class OsPosixSpawnCall extends SystemCommandExecution::Range {
OsPosixSpawnCall() {
this.asCfgNode().(CallNode).getFunction() =
os_attr(["posix_spawn", "posix_spawnp"]).asCfgNode()
}
override DataFlow::Node getCommand() {
result.asCfgNode() = this.asCfgNode().(CallNode).getArg(0)
@@ -123,4 +183,148 @@ private module Stdlib {
// TODO: Handle pathlib (like we do for os.path.join)
}
}
// ---------------------------------------------------------------------------
// subprocess
// ---------------------------------------------------------------------------
/** Gets a reference to the `subprocess` module. */
private DataFlow::Node subprocess(DataFlow::TypeTracker t) {
t.start() and
result = DataFlow::importModule("subprocess")
or
exists(DataFlow::TypeTracker t2 | result = subprocess(t2).track(t2, t))
}
/** Gets a reference to the `subprocess` module. */
DataFlow::Node subprocess() { result = subprocess(DataFlow::TypeTracker::end()) }
/**
* Gets a reference to the attribute `attr_name` of the `subprocess` module.
* WARNING: Only holds for a few predefined attributes.
*
* For example, using `attr_name = "Popen"` will get all uses of `subprocess.Popen`.
*/
private DataFlow::Node subprocess_attr(DataFlow::TypeTracker t, string attr_name) {
attr_name in ["Popen", "call", "check_call", "check_output", "run"] and
(
t.start() and
result = DataFlow::importMember("subprocess", attr_name)
or
t.startInAttr(attr_name) and
result = DataFlow::importModule("subprocess")
)
or
// Due to bad performance when using normal setup with `subprocess_attr(t2, attr_name).track(t2, t)`
// we have inlined that code and forced a join
exists(DataFlow::TypeTracker t2 |
exists(DataFlow::StepSummary summary |
subprocess_attr_first_join(t2, attr_name, result, summary) and
t = t2.append(summary)
)
)
}
pragma[nomagic]
private predicate subprocess_attr_first_join(
DataFlow::TypeTracker t2, string attr_name, DataFlow::Node res, DataFlow::StepSummary summary
) {
DataFlow::StepSummary::step(subprocess_attr(t2, attr_name), res, summary)
}
/**
* Gets a reference to the attribute `attr_name` of the `subprocess` module.
* WARNING: Only holds for a few predefined attributes.
*
* For example, using `attr_name = "Popen"` will get all uses of `subprocess.Popen`.
*/
private DataFlow::Node subprocess_attr(string attr_name) {
result = subprocess_attr(DataFlow::TypeTracker::end(), attr_name)
}
/**
* A call to `subprocess.Popen` or helper functions (call, check_call, check_output, run)
* See https://docs.python.org/3.8/library/subprocess.html#subprocess.Popen
*/
private class SubprocessPopenCall extends SystemCommandExecution::Range {
CallNode call;
SubprocessPopenCall() {
call = this.asCfgNode() and
exists(string name |
name in ["Popen", "call", "check_call", "check_output", "run"] and
call.getFunction() = subprocess_attr(name).asCfgNode()
)
}
/** Gets the ControlFlowNode for the `args` argument, if any. */
private ControlFlowNode get_args_arg() {
result = call.getArg(0)
or
result = call.getArgByName("args")
}
/** Gets the ControlFlowNode for the `shell` argument, if any. */
private ControlFlowNode get_shell_arg() {
result = call.getArg(8)
or
result = call.getArgByName("shell")
}
private boolean get_shell_arg_value() {
not exists(this.get_shell_arg()) and
result = false
or
exists(ControlFlowNode shell_arg | shell_arg = this.get_shell_arg() |
result = shell_arg.getNode().(ImmutableLiteral).booleanValue()
or
// TODO: Track the "shell" argument to determine possible values
not shell_arg.getNode() instanceof ImmutableLiteral and
(
result = true
or
result = false
)
)
}
/** Gets the ControlFlowNode for the `executable` argument, if any. */
private ControlFlowNode get_executable_arg() {
result = call.getArg(2)
or
result = call.getArgByName("executable")
}
override DataFlow::Node getCommand() {
// TODO: Track arguments ("args" and "shell")
// TODO: Handle using `args=["sh", "-c", <user-input>]`
result.asCfgNode() = this.get_executable_arg()
or
exists(ControlFlowNode arg_args, boolean shell |
arg_args = get_args_arg() and
shell = get_shell_arg_value()
|
// When "executable" argument is set, and "shell" argument is `False`, the
// "args" argument will only be used to set the program name and arguments to
// the program, so we should not consider any of them as command execution.
not (
exists(this.get_executable_arg()) and
shell = false
) and
(
// When the "args" argument is an iterable, first element is the command to
// run, so if we're able to, we only mark the first element as the command
// (and not the arguments to the command).
//
result.asCfgNode() = arg_args.(SequenceNode).getElement(0)
or
// Either the "args" argument is not a sequence (which is valid) or we where
// just not able to figure it out. Simply mark the "args" argument as the
// command.
//
not arg_args instanceof SequenceNode and
result.asCfgNode() = arg_args
)
)
}
}
}

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Duplicate function
* @description There is another identical implementation of this function. Extract the code to a common file or superclass to improve sharing.
* @kind problem

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Mostly duplicate class
* @description More than 80% of the methods in this class are duplicated in another class. Create a common supertype to improve code sharing.
* @kind problem

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Mostly duplicate module
* @description There is another file that shares a lot of the code with this file. Merge the two files to improve maintainability.
* @kind problem

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Mostly similar module
* @description There is another module that shares a lot of the code with this module. Notice that names of variables and types may have been changed. Merge the two modules to improve maintainability.
* @kind problem

View File

@@ -1,4 +1,5 @@
/**
* @deprecated
* @name Similar function
* @description There is another function that is very similar this one. Extract the common code to a common function to improve sharing.
* @kind problem

View File

@@ -415,6 +415,12 @@ class Location extends @location {
locations_ast(this, m, startline, startcolumn, endline, endcolumn)
)
)
or
// Packages have no suitable filepath, so we use just the path instead.
exists(Module m | not exists(m.getFile()) |
filepath = m.getPath().getAbsolutePath() and
locations_ast(this, m, startline, startcolumn, endline, endcolumn)
)
}
}

View File

@@ -0,0 +1,6 @@
debug_missingAnnotationForCallable
debug_nonUniqueAnnotationForCallable
debug_missingAnnotationForCall
expectedCallEdgeNotFound
| example.py:19:1:19:7 | afunc() | foo/bar/a.py:2:1:2:12 | Function afunc |
unexpectedCallEdgeFound

View File

@@ -0,0 +1 @@
../CallGraph/PointsTo.ql

View File

@@ -0,0 +1,6 @@
debug_missingAnnotationForCallable
debug_nonUniqueAnnotationForCallable
debug_missingAnnotationForCall
pointsTo_found_typeTracker_notFound
| example.py:22:1:22:16 | explicit_afunc() | foo_explicit/bar/a.py:2:1:2:21 | Function explicit_afunc |
pointsTo_notFound_typeTracker_found

View File

@@ -0,0 +1 @@
../CallGraph/Relative.ql

View File

@@ -0,0 +1,7 @@
debug_missingAnnotationForCallable
debug_nonUniqueAnnotationForCallable
debug_missingAnnotationForCall
expectedCallEdgeNotFound
| example.py:19:1:19:7 | afunc() | foo/bar/a.py:2:1:2:12 | Function afunc |
| example.py:22:1:22:16 | explicit_afunc() | foo_explicit/bar/a.py:2:1:2:21 | Function explicit_afunc |
unexpectedCallEdgeFound

View File

@@ -0,0 +1 @@
../CallGraph/TypeTracker.ql

View File

@@ -0,0 +1,22 @@
"""
Test that we can resolve callables correctly without using explicit __init__.py files
This is not included in the standard `CallGraph/code` folder, since we're testing our
understanding import work properly, so it's better to have a clean test setup that is
obviously correct (the other one isn't in regards to imports).
Technically this is part of PEP 420 -- Implicit Namespace Packages, but does use the
*real* namespace package feature of allowing source code for a single package to reside
in multiple places.
Since PEP 420 was accepted in Python 3, this test is Python 3 only.
"""
from foo.bar.a import afunc
from foo_explicit.bar.a import explicit_afunc
# calls:afunc
afunc()
# calls:explicit_afunc
explicit_afunc()

View File

@@ -0,0 +1,4 @@
# name:afunc
def afunc():
print("afunc called")
return 1

View File

@@ -0,0 +1,4 @@
# name:explicit_afunc
def explicit_afunc():
print("explicit_afunc called")
return 1

View File

@@ -0,0 +1 @@
semmle-extractor-options: --max-import-depth=1 --lang=3

View File

@@ -1 +0,0 @@
semmle-extractor-options:

View File

@@ -1 +1,3 @@
# This import will only import code/__init__.py -- BUT we still analyse the other python
# files inside code/ which is what we want.
from code import *

View File

@@ -0,0 +1,2 @@
import python
import experimental.meta.ConceptsTest

View File

@@ -0,0 +1,141 @@
# Note: Some of these commands will technically not allow an attacker to execute
# arbitrary system commands, but only specify the program to be executed. The general
# consensus was that even this is still a high security risk, so we also treat them as
# system command executions.
#
# As an example, executing `subprocess.Popen(["rm -rf /"])` will result in
# `FileNotFoundError: [Errno 2] No such file or directory: 'rm -rf /'`
########################################
import os
# can't use a string literal with spaces in the tags of an InlineExpectationsTest, so using variables :|
os.popen("cmd1; cmd2") # $getCommand="cmd1; cmd2"
os.system("cmd1; cmd2") # $getCommand="cmd1; cmd2"
def os_members():
# hmm, it's kinda annoying to check that we handle this import correctly for
# everything. It's quite useful since I messed it up initially and didn't have a
# test for it, but in the long run it's just cumbersome to duplicate all the tests
# :|
from os import popen, system
popen("cmd1; cmd2") # $getCommand="cmd1; cmd2"
system("cmd1; cmd2") # $getCommand="cmd1; cmd2"
########################################
# https://docs.python.org/3.8/library/os.html#os.execl
#
# VS Code extension will ignore rest of program if encountering one of these, which we
# don't want. We could use `if False`, but just to be 100% sure we don't do anything too
# clever in our analysis that discards that code, I used `if UNKNOWN` instead
if UNKNOWN:
env = {"FOO": "foo"}
os.execl("executable", "<progname>", "arg0") # $getCommand="executable"
os.execle("executable", "<progname>", "arg0", env) # $getCommand="executable"
os.execlp("executable", "<progname>", "arg0") # $getCommand="executable"
os.execlpe("executable", "<progname>", "arg0", env) # $getCommand="executable"
os.execv("executable", ["<progname>", "arg0"]) # $getCommand="executable"
os.execve("executable", ["<progname>", "arg0"], env) # $getCommand="executable"
os.execvp("executable", ["<progname>", "arg0"]) # $getCommand="executable"
os.execvpe("executable", ["<progname>", "arg0"], env) # $getCommand="executable"
########################################
# https://docs.python.org/3.8/library/os.html#os.spawnl
env = {"FOO": "foo"}
os.spawnl(os.P_WAIT, "executable", "<progname>", "arg0") # $getCommand="executable"
os.spawnle(os.P_WAIT, "executable", "<progname>", "arg0", env) # $getCommand="executable"
os.spawnlp(os.P_WAIT, "executable", "<progname>", "arg0") # $getCommand="executable"
os.spawnlpe(os.P_WAIT, "executable", "<progname>", "arg0", env) # $getCommand="executable"
os.spawnv(os.P_WAIT, "executable", ["<progname>", "arg0"]) # $getCommand="executable"
os.spawnve(os.P_WAIT, "executable", ["<progname>", "arg0"], env) # $getCommand="executable"
os.spawnvp(os.P_WAIT, "executable", ["<progname>", "arg0"]) # $getCommand="executable"
os.spawnvpe(os.P_WAIT, "executable", ["<progname>", "arg0"], env) # $getCommand="executable"
# Added in Python 3.8
os.posix_spawn("executable", ["<progname>", "arg0"], env) # $getCommand="executable"
os.posix_spawnp("executable", ["<progname>", "arg0"], env) # $getCommand="executable"
########################################
import subprocess
subprocess.Popen("cmd1; cmd2", shell=True) # $getCommand="cmd1; cmd2"
subprocess.Popen("cmd1; cmd2", shell="truthy string") # $getCommand="cmd1; cmd2"
subprocess.Popen(["cmd1; cmd2", "shell-arg"], shell=True) # $getCommand="cmd1; cmd2"
subprocess.Popen("cmd1; cmd2", shell=True, executable="/bin/bash") # $getCommand="cmd1; cmd2" $getCommand="/bin/bash"
subprocess.Popen("executable") # $getCommand="executable"
subprocess.Popen(["executable", "arg0"]) # $getCommand="executable"
subprocess.Popen("<progname>", executable="executable") # $getCommand="executable"
subprocess.Popen(["<progname>", "arg0"], executable="executable") # $getCommand="executable"
# call/check_call/check_output/run all work like Popen from a command execution point of view
subprocess.call(["executable", "arg0"]) # $getCommand="executable"
subprocess.check_call(["executable", "arg0"]) # $getCommand="executable"
subprocess.check_output(["executable", "arg0"]) # $getCommand="executable"
subprocess.run(["executable", "arg0"]) # $getCommand="executable"
########################################
# actively using known shell as the executable
subprocess.Popen(["/bin/sh", "-c", "vuln"]) # $getCommand="/bin/sh" $f-:getCommand="vuln"
subprocess.Popen(["/bin/bash", "-c", "vuln"]) # $getCommand="/bin/bash" $f-:getCommand="vuln"
subprocess.Popen(["/bin/dash", "-c", "vuln"]) # $getCommand="/bin/dash" $f-:getCommand="vuln"
subprocess.Popen(["/bin/zsh", "-c", "vuln"]) # $getCommand="/bin/zsh" $f-:getCommand="vuln"
subprocess.Popen(["sh", "-c", "vuln"]) # $getCommand="sh" $f-:getCommand="vuln"
subprocess.Popen(["bash", "-c", "vuln"]) # $getCommand="bash" $f-:getCommand="vuln"
subprocess.Popen(["dash", "-c", "vuln"]) # $getCommand="dash" $f-:getCommand="vuln"
subprocess.Popen(["zsh", "-c", "vuln"]) # $getCommand="zsh" $f-:getCommand="vuln"
# Check that we don't consider ANY argument a command injection sink
subprocess.Popen(["sh", "/bin/python"]) # $getCommand="sh"
subprocess.Popen(["cmd.exe", "/c", "vuln"]) # $getCommand="cmd.exe" $f-:getCommand="vuln"
subprocess.Popen(["cmd.exe", "/C", "vuln"]) # $getCommand="cmd.exe" $f-:getCommand="vuln"
subprocess.Popen(["cmd", "/c", "vuln"]) # $getCommand="cmd" $f-:getCommand="vuln"
subprocess.Popen(["cmd", "/C", "vuln"]) # $getCommand="cmd" $f-:getCommand="vuln"
subprocess.Popen(["<progname>", "-c", "vuln"], executable="/bin/bash") # $getCommand="/bin/bash" $f-:getCommand="vuln"
if UNKNOWN:
os.execl("/bin/sh", "<progname>", "-c", "vuln") # $getCommand="/bin/sh" $f-:getCommand="vuln"
os.spawnl(os.P_WAIT, "/bin/sh", "<progname>", "-c", "vuln") # $getCommand="/bin/sh" $f-:getCommand="vuln"
########################################
# Passing arguments by reference
args = ["/bin/sh", "-c", "vuln"]
subprocess.Popen(args) # $getCommand=args
args = "<progname>"
use_shell = False
exe = "executable"
subprocess.Popen(args, shell=use_shell, executable=exe) # $f+:getCommand=args $getCommand=exe
################################################################################
# Taint related
import shlex
cmd = shlex.join(["echo", tainted])
args = shlex.split(tainted)
# will handle tainted = 'foo; rm -rf /'
safe_cmd = "ls {}".format(shlex.quote(tainted))
# not how you are supposed to use shlex.quote
wrong_use = shlex.quote("ls {}".format(tainted))
# still dangerous, for example
cmd = "sh -c " + wrong_use

View File

@@ -0,0 +1,34 @@
import python
import experimental.dataflow.DataFlow
import experimental.semmle.python.Concepts
import TestUtilities.InlineExpectationsTest
string value_from_expr(Expr e) {
// TODO: This one is starting to look like `repr` predicate from TestTaintLib
result =
e.(StrConst).getPrefix() + e.(StrConst).getText() +
e.(StrConst).getPrefix().regexpReplaceAll("[a-zA-Z]+", "")
or
result = e.(Name).getId()
or
not e instanceof StrConst and
not e instanceof Name and
result = e.toString()
}
class SystemCommandExecutionTest extends InlineExpectationsTest {
SystemCommandExecutionTest() { this = "SystemCommandExecutionTest" }
override string getARelevantTag() { result = "getCommand" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(SystemCommandExecution sce, DataFlow::Node command |
exists(location.getFile().getRelativePath()) and
command = sce.getCommand() and
location = command.getLocation() and
element = command.toString() and
value = value_from_expr(command.asExpr()) and
tag = "getCommand"
)
}
}

View File

@@ -1,11 +1,42 @@
edges
| command_injection.py:10:13:10:24 | ControlFlowNode for Attribute | command_injection.py:12:15:12:27 | ControlFlowNode for BinaryExpr |
| command_injection.py:17:13:17:24 | ControlFlowNode for Attribute | command_injection.py:19:22:19:34 | ControlFlowNode for BinaryExpr |
| command_injection.py:24:11:24:22 | ControlFlowNode for Attribute | command_injection.py:25:23:25:25 | ControlFlowNode for cmd |
| command_injection.py:30:13:30:24 | ControlFlowNode for Attribute | command_injection.py:32:14:32:26 | ControlFlowNode for BinaryExpr |
| command_injection.py:36:15:36:26 | ControlFlowNode for Attribute | command_injection.py:39:15:39:21 | ControlFlowNode for command |
| command_injection.py:36:15:36:26 | ControlFlowNode for Attribute | command_injection.py:40:15:40:21 | ControlFlowNode for command |
| command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | command_injection.py:53:15:53:21 | ControlFlowNode for command |
| command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | command_injection.py:54:14:54:20 | ControlFlowNode for command |
| command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | command_injection.py:55:21:55:27 | ControlFlowNode for command |
| command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | command_injection.py:56:27:56:33 | ControlFlowNode for command |
| command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | command_injection.py:57:20:57:26 | ControlFlowNode for command |
nodes
| command_injection.py:10:13:10:24 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| command_injection.py:12:15:12:27 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
| command_injection.py:17:13:17:24 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| command_injection.py:19:22:19:34 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
| command_injection.py:24:11:24:22 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| command_injection.py:25:23:25:25 | ControlFlowNode for cmd | semmle.label | ControlFlowNode for cmd |
| command_injection.py:30:13:30:24 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| command_injection.py:32:14:32:26 | ControlFlowNode for BinaryExpr | semmle.label | ControlFlowNode for BinaryExpr |
| command_injection.py:36:15:36:26 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| command_injection.py:39:15:39:21 | ControlFlowNode for command | semmle.label | ControlFlowNode for command |
| command_injection.py:40:15:40:21 | ControlFlowNode for command | semmle.label | ControlFlowNode for command |
| command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| command_injection.py:53:15:53:21 | ControlFlowNode for command | semmle.label | ControlFlowNode for command |
| command_injection.py:54:14:54:20 | ControlFlowNode for command | semmle.label | ControlFlowNode for command |
| command_injection.py:55:21:55:27 | ControlFlowNode for command | semmle.label | ControlFlowNode for command |
| command_injection.py:56:27:56:33 | ControlFlowNode for command | semmle.label | ControlFlowNode for command |
| command_injection.py:57:20:57:26 | ControlFlowNode for command | semmle.label | ControlFlowNode for command |
#select
| command_injection.py:12:15:12:27 | ControlFlowNode for BinaryExpr | command_injection.py:10:13:10:24 | ControlFlowNode for Attribute | command_injection.py:12:15:12:27 | ControlFlowNode for BinaryExpr | This command depends on $@. | command_injection.py:10:13:10:24 | ControlFlowNode for Attribute | a user-provided value |
| command_injection.py:19:22:19:34 | ControlFlowNode for BinaryExpr | command_injection.py:17:13:17:24 | ControlFlowNode for Attribute | command_injection.py:19:22:19:34 | ControlFlowNode for BinaryExpr | This command depends on $@. | command_injection.py:17:13:17:24 | ControlFlowNode for Attribute | a user-provided value |
| command_injection.py:25:23:25:25 | ControlFlowNode for cmd | command_injection.py:24:11:24:22 | ControlFlowNode for Attribute | command_injection.py:25:23:25:25 | ControlFlowNode for cmd | This command depends on $@. | command_injection.py:24:11:24:22 | ControlFlowNode for Attribute | a user-provided value |
| command_injection.py:32:14:32:26 | ControlFlowNode for BinaryExpr | command_injection.py:30:13:30:24 | ControlFlowNode for Attribute | command_injection.py:32:14:32:26 | ControlFlowNode for BinaryExpr | This command depends on $@. | command_injection.py:30:13:30:24 | ControlFlowNode for Attribute | a user-provided value |
| command_injection.py:39:15:39:21 | ControlFlowNode for command | command_injection.py:36:15:36:26 | ControlFlowNode for Attribute | command_injection.py:39:15:39:21 | ControlFlowNode for command | This command depends on $@. | command_injection.py:36:15:36:26 | ControlFlowNode for Attribute | a user-provided value |
| command_injection.py:40:15:40:21 | ControlFlowNode for command | command_injection.py:36:15:36:26 | ControlFlowNode for Attribute | command_injection.py:40:15:40:21 | ControlFlowNode for command | This command depends on $@. | command_injection.py:36:15:36:26 | ControlFlowNode for Attribute | a user-provided value |
| command_injection.py:53:15:53:21 | ControlFlowNode for command | command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | command_injection.py:53:15:53:21 | ControlFlowNode for command | This command depends on $@. | command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | a user-provided value |
| command_injection.py:54:14:54:20 | ControlFlowNode for command | command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | command_injection.py:54:14:54:20 | ControlFlowNode for command | This command depends on $@. | command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | a user-provided value |
| command_injection.py:55:21:55:27 | ControlFlowNode for command | command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | command_injection.py:55:21:55:27 | ControlFlowNode for command | This command depends on $@. | command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | a user-provided value |
| command_injection.py:56:27:56:33 | ControlFlowNode for command | command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | command_injection.py:56:27:56:33 | ControlFlowNode for command | This command depends on $@. | command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | a user-provided value |
| command_injection.py:57:20:57:26 | ControlFlowNode for command | command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | command_injection.py:57:20:57:26 | ControlFlowNode for command | This command depends on $@. | command_injection.py:52:15:52:26 | ControlFlowNode for Attribute | a user-provided value |

View File

@@ -16,7 +16,7 @@ def command_injection1():
def command_injection2():
files = request.args.get('files', '')
# Don't let files be `; rm -rf /`
subprocess.Popen(["ls", files], shell = True)
subprocess.Popen("ls " + files, shell=True)
@app.route("/command3")
@@ -31,5 +31,31 @@ def others():
# Don't let files be `; rm -rf /`
os.popen("ls " + files)
@app.route("/multiple")
def multiple():
command = request.args.get('command', '')
# We should mark flow to both calls here, which conflicts with removing flow out of
# a sink due to use-use flow.
os.system(command)
os.system(command)
@app.route("/not-into-sink-impl")
def not_into_sink_impl():
"""When there is flow to a sink such as `os.popen(cmd)`, we don't want to highlight that there is also
flow through the actual `popen` function to the internal call to `subprocess.Popen` -- we would usually
see that flow since we extract the `os.py` file from the standard library.
os.popen implementation: https://github.com/python/cpython/blob/fa7ce080175f65d678a7d5756c94f82887fc9803/Lib/os.py#L974
subprocess.call implementation: https://github.com/python/cpython/blob/fa7ce080175f65d678a7d5756c94f82887fc9803/Lib/subprocess.py#L341
"""
command = request.args.get('command', '')
os.system(command)
os.popen(command)
subprocess.call(command)
subprocess.check_call(command)
subprocess.run(command)
# TODO: popen2 module for Python 2 only https://devdocs.io/python~2.7/library/popen2
# (deprecated since Python 2.6, but still functional in Python 2.7.17)

View File

@@ -1,4 +1,4 @@
| nested/__init__.py:1:6:1:12 | ControlFlowNode for ImportExpr | import | nested/nested.py:0:0:0:0 | Module nested.nested |
| nested/nested.py:1:1:1:13 | ControlFlowNode for FunctionExpr | import | nested/nested.py:1:1:1:13 | Function nested |
| test.py:1:6:1:11 | ControlFlowNode for ImportExpr | import | file://:0:0:0:0 | Package nested |
| test.py:1:6:1:11 | ControlFlowNode for ImportExpr | import | nested:0:0:0:0 | Package nested |
| test.py:2:1:2:6 | ControlFlowNode for nested | import | nested/nested.py:1:1:1:13 | Function nested |

View File

@@ -7,10 +7,10 @@ edges
| command_injection.py:12:23:12:27 | externally controlled string | command_injection.py:12:15:12:27 | externally controlled string |
| command_injection.py:17:13:17:24 | dict of externally controlled string | command_injection.py:17:13:17:41 | externally controlled string |
| command_injection.py:17:13:17:24 | dict of externally controlled string | command_injection.py:17:13:17:41 | externally controlled string |
| command_injection.py:17:13:17:41 | externally controlled string | command_injection.py:19:29:19:33 | externally controlled string |
| command_injection.py:17:13:17:41 | externally controlled string | command_injection.py:19:29:19:33 | externally controlled string |
| command_injection.py:19:29:19:33 | externally controlled string | command_injection.py:19:22:19:34 | sequence of externally controlled string |
| command_injection.py:19:29:19:33 | externally controlled string | command_injection.py:19:22:19:34 | sequence of externally controlled string |
| command_injection.py:17:13:17:41 | externally controlled string | command_injection.py:19:30:19:34 | externally controlled string |
| command_injection.py:17:13:17:41 | externally controlled string | command_injection.py:19:30:19:34 | externally controlled string |
| command_injection.py:19:30:19:34 | externally controlled string | command_injection.py:19:22:19:34 | externally controlled string |
| command_injection.py:19:30:19:34 | externally controlled string | command_injection.py:19:22:19:34 | externally controlled string |
| command_injection.py:24:11:24:22 | dict of externally controlled string | command_injection.py:24:11:24:37 | externally controlled string |
| command_injection.py:24:11:24:22 | dict of externally controlled string | command_injection.py:24:11:24:37 | externally controlled string |
| command_injection.py:24:11:24:37 | externally controlled string | command_injection.py:25:23:25:25 | externally controlled string |
@@ -25,6 +25,6 @@ edges
| command_injection.py:32:22:32:26 | externally controlled string | command_injection.py:32:14:32:26 | externally controlled string |
#select
| command_injection.py:12:15:12:27 | BinaryExpr | command_injection.py:10:13:10:24 | dict of externally controlled string | command_injection.py:12:15:12:27 | externally controlled string | This command depends on $@. | command_injection.py:10:13:10:24 | Attribute | a user-provided value |
| command_injection.py:19:22:19:34 | List | command_injection.py:17:13:17:24 | dict of externally controlled string | command_injection.py:19:22:19:34 | sequence of externally controlled string | This command depends on $@. | command_injection.py:17:13:17:24 | Attribute | a user-provided value |
| command_injection.py:19:22:19:34 | BinaryExpr | command_injection.py:17:13:17:24 | dict of externally controlled string | command_injection.py:19:22:19:34 | externally controlled string | This command depends on $@. | command_injection.py:17:13:17:24 | Attribute | a user-provided value |
| command_injection.py:25:22:25:36 | List | command_injection.py:24:11:24:22 | dict of externally controlled string | command_injection.py:25:22:25:36 | first item in sequence of externally controlled string | This command depends on $@. | command_injection.py:24:11:24:22 | Attribute | a user-provided value |
| command_injection.py:32:14:32:26 | BinaryExpr | command_injection.py:30:13:30:24 | dict of externally controlled string | command_injection.py:32:14:32:26 | externally controlled string | This command depends on $@. | command_injection.py:30:13:30:24 | Attribute | a user-provided value |

View File

@@ -16,7 +16,7 @@ def command_injection1():
def command_injection2():
files = request.args.get('files', '')
# Don't let files be `; rm -rf /`
subprocess.Popen(["ls", files], shell = True)
subprocess.Popen("ls " + files, shell=True)
@app.route("/command3")