From dfa371c65b32ce587f942350525318100e5b2b8c Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Thu, 29 Aug 2019 15:00:02 +0100 Subject: [PATCH] Java: Add missing SQL query APIs. * executeLargeUpdate * prepareCall --- .../src/semmle/code/java/frameworks/Jdbc.qll | 18 ++ .../semmle/examples/SqlTaintedLocal.expected | 28 ++-- .../semmle/examples/SqlUnescaped.expected | 15 +- .../CWE-089/semmle/examples/Test.java | 25 ++- .../examples/ValidatedVariable.expected | 2 +- .../semmle/examples/controlledString.expected | 157 ++++++++++-------- .../semmle/examples/endsInQuote.expected | 37 +++-- .../semmle/examples/getAnAppend.expected | 18 +- .../semmle/examples/getToStringCall.expected | 6 +- .../CWE-089/semmle/examples/sbQuery.expected | 6 +- .../semmle/examples/taintedString.expected | 82 ++++++--- 11 files changed, 252 insertions(+), 142 deletions(-) diff --git a/java/ql/src/semmle/code/java/frameworks/Jdbc.qll b/java/ql/src/semmle/code/java/frameworks/Jdbc.qll index 733c4d1898e..c0681305756 100644 --- a/java/ql/src/semmle/code/java/frameworks/Jdbc.qll +++ b/java/ql/src/semmle/code/java/frameworks/Jdbc.qll @@ -34,6 +34,14 @@ class ConnectionPrepareStatement extends Method { } } +/** A method with the name `prepareCall` declared in `java.sql.Connection`. */ +class ConnectionPrepareCall extends Method { + ConnectionPrepareCall() { + getDeclaringType() instanceof TypeConnection and + hasName("prepareCall") + } +} + /** A method with the name `executeQuery` declared in `java.sql.Statement`. */ class StatementExecuteQuery extends Method { StatementExecuteQuery() { @@ -58,6 +66,14 @@ class MethodStatementExecuteUpdate extends Method { } } +/** A method with the name `executeLargeUpdate` declared in `java.sql.Statement`. */ +class MethodStatementExecuteLargeUpdate extends Method { + MethodStatementExecuteLargeUpdate() { + getDeclaringType() instanceof TypeStatement and + hasName("executeLargeUpdate") + } +} + /** A method with the name `addBatch` declared in `java.sql.Statement`. */ class MethodStatementAddBatch extends Method { MethodStatementAddBatch() { @@ -87,9 +103,11 @@ class SqlExpr extends Expr { method = call.getMethod() and ( method instanceof ConnectionPrepareStatement or + method instanceof ConnectionPrepareCall or method instanceof StatementExecuteQuery or method instanceof MethodStatementExecute or method instanceof MethodStatementExecuteUpdate or + method instanceof MethodStatementExecuteLargeUpdate or method instanceof MethodStatementAddBatch ) ) diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/SqlTaintedLocal.expected b/java/ql/test/query-tests/security/CWE-089/semmle/examples/SqlTaintedLocal.expected index 7fc66dfe541..1df73668175 100644 --- a/java/ql/test/query-tests/security/CWE-089/semmle/examples/SqlTaintedLocal.expected +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/SqlTaintedLocal.expected @@ -1,14 +1,20 @@ edges | Test.java:29:30:29:42 | args [String[]] | Test.java:36:47:36:52 | query1 | -| Test.java:29:30:29:42 | args [String[]] | Test.java:44:62:44:67 | query3 | -| Test.java:29:30:29:42 | args [String[]] | Test.java:56:47:56:61 | querySbToString | -| Test.java:160:33:160:45 | args [String[]] | Test.java:186:47:186:68 | queryWithUserTableName | -| Test.java:190:26:190:38 | args [String[]] | Test.java:191:11:191:14 | args [String[]] | -| Test.java:190:26:190:38 | args [String[]] | Test.java:195:14:195:17 | args [String[]] | -| Test.java:191:11:191:14 | args [String[]] | Test.java:29:30:29:42 | args [String[]] | -| Test.java:195:14:195:17 | args [String[]] | Test.java:160:33:160:45 | args [String[]] | +| Test.java:29:30:29:42 | args [String[]] | Test.java:42:57:42:62 | query2 | +| Test.java:29:30:29:42 | args [String[]] | Test.java:50:62:50:67 | query3 | +| Test.java:29:30:29:42 | args [String[]] | Test.java:62:47:62:61 | querySbToString | +| Test.java:29:30:29:42 | args [String[]] | Test.java:70:40:70:44 | query | +| Test.java:29:30:29:42 | args [String[]] | Test.java:78:46:78:50 | query | +| Test.java:183:33:183:45 | args [String[]] | Test.java:209:47:209:68 | queryWithUserTableName | +| Test.java:213:26:213:38 | args [String[]] | Test.java:214:11:214:14 | args [String[]] | +| Test.java:213:26:213:38 | args [String[]] | Test.java:218:14:218:17 | args [String[]] | +| Test.java:214:11:214:14 | args [String[]] | Test.java:29:30:29:42 | args [String[]] | +| Test.java:218:14:218:17 | args [String[]] | Test.java:183:33:183:45 | args [String[]] | #select -| Test.java:36:47:36:52 | query1 | Test.java:190:26:190:38 | args [String[]] | Test.java:36:47:36:52 | query1 | Query might include code from $@. | Test.java:190:26:190:38 | args | this user input | -| Test.java:44:62:44:67 | query3 | Test.java:190:26:190:38 | args [String[]] | Test.java:44:62:44:67 | query3 | Query might include code from $@. | Test.java:190:26:190:38 | args | this user input | -| Test.java:56:47:56:61 | querySbToString | Test.java:190:26:190:38 | args [String[]] | Test.java:56:47:56:61 | querySbToString | Query might include code from $@. | Test.java:190:26:190:38 | args | this user input | -| Test.java:186:47:186:68 | queryWithUserTableName | Test.java:190:26:190:38 | args [String[]] | Test.java:186:47:186:68 | queryWithUserTableName | Query might include code from $@. | Test.java:190:26:190:38 | args | this user input | +| Test.java:36:47:36:52 | query1 | Test.java:213:26:213:38 | args [String[]] | Test.java:36:47:36:52 | query1 | Query might include code from $@. | Test.java:213:26:213:38 | args | this user input | +| Test.java:42:57:42:62 | query2 | Test.java:213:26:213:38 | args [String[]] | Test.java:42:57:42:62 | query2 | Query might include code from $@. | Test.java:213:26:213:38 | args | this user input | +| Test.java:50:62:50:67 | query3 | Test.java:213:26:213:38 | args [String[]] | Test.java:50:62:50:67 | query3 | Query might include code from $@. | Test.java:213:26:213:38 | args | this user input | +| Test.java:62:47:62:61 | querySbToString | Test.java:213:26:213:38 | args [String[]] | Test.java:62:47:62:61 | querySbToString | Query might include code from $@. | Test.java:213:26:213:38 | args | this user input | +| Test.java:70:40:70:44 | query | Test.java:213:26:213:38 | args [String[]] | Test.java:70:40:70:44 | query | Query might include code from $@. | Test.java:213:26:213:38 | args | this user input | +| Test.java:78:46:78:50 | query | Test.java:213:26:213:38 | args [String[]] | Test.java:78:46:78:50 | query | Query might include code from $@. | Test.java:213:26:213:38 | args | this user input | +| Test.java:209:47:209:68 | queryWithUserTableName | Test.java:213:26:213:38 | args [String[]] | Test.java:209:47:209:68 | queryWithUserTableName | Query might include code from $@. | Test.java:213:26:213:38 | args | this user input | diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/SqlUnescaped.expected b/java/ql/test/query-tests/security/CWE-089/semmle/examples/SqlUnescaped.expected index 747b73c431e..cce9506d74e 100644 --- a/java/ql/test/query-tests/security/CWE-089/semmle/examples/SqlUnescaped.expected +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/SqlUnescaped.expected @@ -1,6 +1,11 @@ | Test.java:36:47:36:52 | query1 | Query might not neutralize special characters in $@. | Test.java:35:8:35:15 | category | this expression | -| Test.java:44:62:44:67 | query3 | Query might not neutralize special characters in $@. | Test.java:43:8:43:15 | category | this expression | -| Test.java:56:47:56:61 | querySbToString | Query might not neutralize special characters in $@. | Test.java:52:19:52:26 | category | this expression | -| Test.java:75:47:75:60 | queryFromField | Query might not neutralize special characters in $@. | Test.java:74:8:74:19 | categoryName | this expression | -| Test.java:85:47:85:61 | querySbToString | Query might not neutralize special characters in $@. | Test.java:81:19:81:30 | categoryName | this expression | -| Test.java:95:47:95:62 | querySb2ToString | Query might not neutralize special characters in $@. | Test.java:91:46:91:57 | categoryName | this expression | +| Test.java:42:57:42:62 | query2 | Query might not neutralize special characters in $@. | Test.java:41:51:41:52 | id | this expression | +| Test.java:50:62:50:67 | query3 | Query might not neutralize special characters in $@. | Test.java:49:8:49:15 | category | this expression | +| Test.java:62:47:62:61 | querySbToString | Query might not neutralize special characters in $@. | Test.java:58:19:58:26 | category | this expression | +| Test.java:70:40:70:44 | query | Query might not neutralize special characters in $@. | Test.java:69:50:69:54 | price | this expression | +| Test.java:70:40:70:44 | query | Query might not neutralize special characters in $@. | Test.java:69:77:69:80 | item | this expression | +| Test.java:78:46:78:50 | query | Query might not neutralize special characters in $@. | Test.java:77:50:77:54 | price | this expression | +| Test.java:78:46:78:50 | query | Query might not neutralize special characters in $@. | Test.java:77:77:77:80 | item | this expression | +| Test.java:98:47:98:60 | queryFromField | Query might not neutralize special characters in $@. | Test.java:97:8:97:19 | categoryName | this expression | +| Test.java:108:47:108:61 | querySbToString | Query might not neutralize special characters in $@. | Test.java:104:19:104:30 | categoryName | this expression | +| Test.java:118:47:118:62 | querySb2ToString | Query might not neutralize special characters in $@. | Test.java:114:46:114:57 | categoryName | this expression | diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/Test.java b/java/ql/test/query-tests/security/CWE-089/semmle/examples/Test.java index 89663fd4ca8..f6e4ff61dc4 100644 --- a/java/ql/test/query-tests/security/CWE-089/semmle/examples/Test.java +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/Test.java @@ -35,7 +35,13 @@ abstract class Test { + category + "' ORDER BY PRICE"; ResultSet results = statement.executeQuery(query1); } - + // BAD: don't use user input when building a prepared call + { + String id = args[1]; + String query2 = "{ call get_product_by_id('" + id + "',?,?,?) }"; + PreparedStatement statement = connection.prepareCall(query2); + ResultSet results = statement.executeQuery(); + } // BAD: don't use user input when building a prepared query { String category = args[1]; @@ -55,6 +61,23 @@ abstract class Test { Statement statement = connection.createStatement(); ResultSet results = statement.executeQuery(querySbToString); } + // BAD: executeUpdate + { + String item = args[1]; + String price = args[2]; + Statement statement = connection.createStatement(); + String query = "UPDATE PRODUCT SET PRICE='" + price + "' WHERE ITEM='" + item + "'"; + int count = statement.executeUpdate(query); + } + // BAD: executeUpdate + { + String item = args[1]; + String price = args[2]; + Statement statement = connection.createStatement(); + String query = "UPDATE PRODUCT SET PRICE='" + price + "' WHERE ITEM='" + item + "'"; + long count = statement.executeLargeUpdate(query); + } + // OK: validate the input first { String category = args[1]; diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/ValidatedVariable.expected b/java/ql/test/query-tests/security/CWE-089/semmle/examples/ValidatedVariable.expected index b839d98d387..110da77f9f3 100644 --- a/java/ql/test/query-tests/security/CWE-089/semmle/examples/ValidatedVariable.expected +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/ValidatedVariable.expected @@ -1 +1 @@ -| Test.java:64:8:64:15 | category | +| Test.java:87:8:87:15 | category | diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/controlledString.expected b/java/ql/test/query-tests/security/CWE-089/semmle/examples/controlledString.expected index b5e717e5734..04494b9b570 100644 --- a/java/ql/test/query-tests/security/CWE-089/semmle/examples/controlledString.expected +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/controlledString.expected @@ -15,76 +15,93 @@ | checkIdentifier | 3 | Validation.java:9:9:9:29 | isLetter(...) | | checkIdentifier | 3 | Validation.java:9:28:9:28 | c | | checkIdentifier | 4 | Validation.java:10:32:10:53 | "Invalid identifier: " | -| controlledStrings | 4 | Test.java:114:26:114:79 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | -| controlledStrings | 4 | Test.java:114:26:115:17 | ... + ... | -| controlledStrings | 4 | Test.java:114:26:115:38 | ... + ... | -| controlledStrings | 5 | Test.java:115:8:115:17 | categoryId | -| controlledStrings | 5 | Test.java:115:21:115:38 | "' ORDER BY PRICE" | -| controlledStrings | 6 | Test.java:116:47:116:58 | queryWithInt | -| controlledStrings | 12 | Test.java:122:27:122:80 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | -| controlledStrings | 12 | Test.java:122:27:123:23 | ... + ... | -| controlledStrings | 12 | Test.java:122:27:123:44 | ... + ... | -| controlledStrings | 13 | Test.java:123:8:123:23 | Category.Topping | -| controlledStrings | 13 | Test.java:123:27:123:44 | "' ORDER BY PRICE" | -| controlledStrings | 14 | Test.java:124:47:124:59 | queryWithEnum | -| controlledStrings | 20 | Test.java:130:35:130:88 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | -| controlledStrings | 20 | Test.java:130:35:131:34 | ... + ... | -| controlledStrings | 20 | Test.java:130:35:131:55 | ... + ... | -| controlledStrings | 21 | Test.java:131:8:131:23 | Category.Topping | -| controlledStrings | 21 | Test.java:131:8:131:34 | toString(...) | -| controlledStrings | 21 | Test.java:131:38:131:55 | "' ORDER BY PRICE" | -| controlledStrings | 22 | Test.java:132:47:132:67 | queryWithEnumToString | -| controlledStrings | 28 | Test.java:138:32:138:85 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | -| controlledStrings | 28 | Test.java:138:32:139:27 | ... + ... | -| controlledStrings | 28 | Test.java:138:32:139:48 | ... + ... | -| controlledStrings | 29 | Test.java:139:8:139:27 | getName(...) | -| controlledStrings | 29 | Test.java:139:31:139:48 | "' ORDER BY PRICE" | -| controlledStrings | 30 | Test.java:140:47:140:64 | queryWithClassName | -| controlledStrings | 36 | Test.java:146:38:146:91 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | -| controlledStrings | 36 | Test.java:146:38:147:33 | ... + ... | -| controlledStrings | 36 | Test.java:146:38:147:54 | ... + ... | -| controlledStrings | 37 | Test.java:147:8:147:33 | getSimpleName(...) | -| controlledStrings | 37 | Test.java:147:37:147:54 | "' ORDER BY PRICE" | -| controlledStrings | 39 | Test.java:149:20:149:43 | queryWithClassSimpleName | -| controlledStrings | 44 | Test.java:154:37:154:90 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | -| controlledStrings | 44 | Test.java:154:37:155:34 | ... + ... | -| controlledStrings | 44 | Test.java:154:37:155:55 | ... + ... | -| controlledStrings | 45 | Test.java:155:8:155:34 | toString(...) | -| controlledStrings | 45 | Test.java:155:24:155:33 | categoryId | -| controlledStrings | 45 | Test.java:155:38:155:55 | "' ORDER BY PRICE" | -| controlledStrings | 46 | Test.java:156:47:156:69 | queryWithDoubleToString | -| good | 3 | Test.java:102:27:102:27 | 1 | -| good | 4 | Test.java:103:20:103:88 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=? ORDER BY PRICE" | -| good | 5 | Test.java:104:62:104:67 | query2 | -| good | 6 | Test.java:105:24:105:24 | 1 | -| tableNames | 4 | Test.java:164:32:164:56 | "SELECT ITEM,PRICE FROM " | -| tableNames | 5 | Test.java:165:8:165:55 | " WHERE ITEM_CATEGORY='Biscuits' ORDER BY PRICE" | -| tableNames | 10 | Test.java:170:33:170:57 | "SELECT ITEM,PRICE FROM " | -| tableNames | 15 | Test.java:175:33:175:62 | "SELECT ITEM,PRICE" + " FROM " | -| tableNames | 21 | Test.java:181:30:181:30 | 1 | -| tableNames | 23 | Test.java:183:36:183:60 | "SELECT ITEM,PRICE FROM " | -| tableNames | 25 | Test.java:185:8:185:55 | " WHERE ITEM_CATEGORY='Biscuits' ORDER BY PRICE" | +| controlledStrings | 4 | Test.java:137:26:137:79 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | +| controlledStrings | 4 | Test.java:137:26:138:17 | ... + ... | +| controlledStrings | 4 | Test.java:137:26:138:38 | ... + ... | +| controlledStrings | 5 | Test.java:138:8:138:17 | categoryId | +| controlledStrings | 5 | Test.java:138:21:138:38 | "' ORDER BY PRICE" | +| controlledStrings | 6 | Test.java:139:47:139:58 | queryWithInt | +| controlledStrings | 12 | Test.java:145:27:145:80 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | +| controlledStrings | 12 | Test.java:145:27:146:23 | ... + ... | +| controlledStrings | 12 | Test.java:145:27:146:44 | ... + ... | +| controlledStrings | 13 | Test.java:146:8:146:23 | Category.Topping | +| controlledStrings | 13 | Test.java:146:27:146:44 | "' ORDER BY PRICE" | +| controlledStrings | 14 | Test.java:147:47:147:59 | queryWithEnum | +| controlledStrings | 20 | Test.java:153:35:153:88 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | +| controlledStrings | 20 | Test.java:153:35:154:34 | ... + ... | +| controlledStrings | 20 | Test.java:153:35:154:55 | ... + ... | +| controlledStrings | 21 | Test.java:154:8:154:23 | Category.Topping | +| controlledStrings | 21 | Test.java:154:8:154:34 | toString(...) | +| controlledStrings | 21 | Test.java:154:38:154:55 | "' ORDER BY PRICE" | +| controlledStrings | 22 | Test.java:155:47:155:67 | queryWithEnumToString | +| controlledStrings | 28 | Test.java:161:32:161:85 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | +| controlledStrings | 28 | Test.java:161:32:162:27 | ... + ... | +| controlledStrings | 28 | Test.java:161:32:162:48 | ... + ... | +| controlledStrings | 29 | Test.java:162:8:162:27 | getName(...) | +| controlledStrings | 29 | Test.java:162:31:162:48 | "' ORDER BY PRICE" | +| controlledStrings | 30 | Test.java:163:47:163:64 | queryWithClassName | +| controlledStrings | 36 | Test.java:169:38:169:91 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | +| controlledStrings | 36 | Test.java:169:38:170:33 | ... + ... | +| controlledStrings | 36 | Test.java:169:38:170:54 | ... + ... | +| controlledStrings | 37 | Test.java:170:8:170:33 | getSimpleName(...) | +| controlledStrings | 37 | Test.java:170:37:170:54 | "' ORDER BY PRICE" | +| controlledStrings | 39 | Test.java:172:20:172:43 | queryWithClassSimpleName | +| controlledStrings | 44 | Test.java:177:37:177:90 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | +| controlledStrings | 44 | Test.java:177:37:178:34 | ... + ... | +| controlledStrings | 44 | Test.java:177:37:178:55 | ... + ... | +| controlledStrings | 45 | Test.java:178:8:178:34 | toString(...) | +| controlledStrings | 45 | Test.java:178:24:178:33 | categoryId | +| controlledStrings | 45 | Test.java:178:38:178:55 | "' ORDER BY PRICE" | +| controlledStrings | 46 | Test.java:179:47:179:69 | queryWithDoubleToString | +| good | 3 | Test.java:125:27:125:27 | 1 | +| good | 4 | Test.java:126:20:126:88 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY=? ORDER BY PRICE" | +| good | 5 | Test.java:127:62:127:67 | query2 | +| good | 6 | Test.java:128:24:128:24 | 1 | +| tableNames | 4 | Test.java:187:32:187:56 | "SELECT ITEM,PRICE FROM " | +| tableNames | 5 | Test.java:188:8:188:55 | " WHERE ITEM_CATEGORY='Biscuits' ORDER BY PRICE" | +| tableNames | 10 | Test.java:193:33:193:57 | "SELECT ITEM,PRICE FROM " | +| tableNames | 15 | Test.java:198:33:198:62 | "SELECT ITEM,PRICE" + " FROM " | +| tableNames | 21 | Test.java:204:30:204:30 | 1 | +| tableNames | 23 | Test.java:206:36:206:60 | "SELECT ITEM,PRICE FROM " | +| tableNames | 25 | Test.java:208:8:208:55 | " WHERE ITEM_CATEGORY='Biscuits' ORDER BY PRICE" | | tainted | 3 | Test.java:32:27:32:27 | 1 | | tainted | 5 | Test.java:34:20:34:73 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | | tainted | 6 | Test.java:35:19:35:36 | "' ORDER BY PRICE" | -| tainted | 12 | Test.java:41:27:41:27 | 1 | -| tainted | 13 | Test.java:42:20:42:73 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | -| tainted | 14 | Test.java:43:19:43:36 | "' ORDER BY PRICE" | -| tainted | 20 | Test.java:49:27:49:27 | 1 | -| tainted | 22 | Test.java:51:19:51:72 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | -| tainted | 24 | Test.java:53:19:53:36 | "' ORDER BY PRICE" | -| tainted | 31 | Test.java:60:27:60:27 | 1 | -| tainted | 34 | Test.java:63:20:63:73 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | -| tainted | 34 | Test.java:63:20:64:15 | ... + ... | -| tainted | 34 | Test.java:63:20:64:36 | ... + ... | -| tainted | 35 | Test.java:64:8:64:15 | category | -| tainted | 35 | Test.java:64:19:64:36 | "' ORDER BY PRICE" | -| tainted | 36 | Test.java:65:47:65:52 | query1 | -| unescaped | 4 | Test.java:73:28:73:81 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | -| unescaped | 5 | Test.java:74:23:74:40 | "' ORDER BY PRICE" | -| unescaped | 11 | Test.java:80:19:80:72 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | -| unescaped | 13 | Test.java:82:19:82:36 | "' ORDER BY PRICE" | -| unescaped | 21 | Test.java:90:20:90:52 | "SELECT ITEM,PRICE FROM PRODUCT " | -| unescaped | 22 | Test.java:91:20:91:42 | "WHERE ITEM_CATEGORY='" | -| unescaped | 22 | Test.java:91:61:91:64 | "' " | -| unescaped | 23 | Test.java:92:20:92:35 | "ORDER BY PRICE" | +| tainted | 11 | Test.java:40:21:40:21 | 1 | +| tainted | 12 | Test.java:41:20:41:47 | "{ call get_product_by_id('" | +| tainted | 12 | Test.java:41:56:41:67 | "',?,?,?) }" | +| tainted | 18 | Test.java:47:27:47:27 | 1 | +| tainted | 19 | Test.java:48:20:48:73 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | +| tainted | 20 | Test.java:49:19:49:36 | "' ORDER BY PRICE" | +| tainted | 26 | Test.java:55:27:55:27 | 1 | +| tainted | 28 | Test.java:57:19:57:72 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | +| tainted | 30 | Test.java:59:19:59:36 | "' ORDER BY PRICE" | +| tainted | 37 | Test.java:66:23:66:23 | 1 | +| tainted | 38 | Test.java:67:24:67:24 | 2 | +| tainted | 40 | Test.java:69:19:69:46 | "UPDATE PRODUCT SET PRICE='" | +| tainted | 40 | Test.java:69:58:69:73 | "' WHERE ITEM='" | +| tainted | 40 | Test.java:69:84:69:86 | "'" | +| tainted | 41 | Test.java:70:8:70:45 | count | +| tainted | 41 | Test.java:70:16:70:45 | executeUpdate(...) | +| tainted | 45 | Test.java:74:23:74:23 | 1 | +| tainted | 46 | Test.java:75:24:75:24 | 2 | +| tainted | 48 | Test.java:77:19:77:46 | "UPDATE PRODUCT SET PRICE='" | +| tainted | 48 | Test.java:77:58:77:73 | "' WHERE ITEM='" | +| tainted | 48 | Test.java:77:84:77:86 | "'" | +| tainted | 49 | Test.java:78:9:78:51 | count | +| tainted | 49 | Test.java:78:17:78:51 | executeLargeUpdate(...) | +| tainted | 54 | Test.java:83:27:83:27 | 1 | +| tainted | 57 | Test.java:86:20:86:73 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | +| tainted | 57 | Test.java:86:20:87:15 | ... + ... | +| tainted | 57 | Test.java:86:20:87:36 | ... + ... | +| tainted | 58 | Test.java:87:8:87:15 | category | +| tainted | 58 | Test.java:87:19:87:36 | "' ORDER BY PRICE" | +| tainted | 59 | Test.java:88:47:88:52 | query1 | +| unescaped | 4 | Test.java:96:28:96:81 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | +| unescaped | 5 | Test.java:97:23:97:40 | "' ORDER BY PRICE" | +| unescaped | 11 | Test.java:103:19:103:72 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | +| unescaped | 13 | Test.java:105:19:105:36 | "' ORDER BY PRICE" | +| unescaped | 21 | Test.java:113:20:113:52 | "SELECT ITEM,PRICE FROM PRODUCT " | +| unescaped | 22 | Test.java:114:20:114:42 | "WHERE ITEM_CATEGORY='" | +| unescaped | 22 | Test.java:114:61:114:64 | "' " | +| unescaped | 23 | Test.java:115:20:115:35 | "ORDER BY PRICE" | diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/endsInQuote.expected b/java/ql/test/query-tests/security/CWE-089/semmle/examples/endsInQuote.expected index a1ea11bbd6d..2b6d12b426d 100644 --- a/java/ql/test/query-tests/security/CWE-089/semmle/examples/endsInQuote.expected +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/endsInQuote.expected @@ -1,13 +1,26 @@ -| controlledStrings | 4 | Test.java:114:26:114:79 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | -| controlledStrings | 12 | Test.java:122:27:122:80 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | -| controlledStrings | 20 | Test.java:130:35:130:88 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | -| controlledStrings | 28 | Test.java:138:32:138:85 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | -| controlledStrings | 36 | Test.java:146:38:146:91 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | -| controlledStrings | 44 | Test.java:154:37:154:90 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | +| controlledStrings | 4 | Test.java:137:26:137:79 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | +| controlledStrings | 12 | Test.java:145:27:145:80 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | +| controlledStrings | 20 | Test.java:153:35:153:88 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | +| controlledStrings | 28 | Test.java:161:32:161:85 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | +| controlledStrings | 36 | Test.java:169:38:169:91 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | +| controlledStrings | 44 | Test.java:177:37:177:90 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | | tainted | 5 | Test.java:34:20:34:73 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | -| tainted | 13 | Test.java:42:20:42:73 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | -| tainted | 22 | Test.java:51:19:51:72 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | -| tainted | 34 | Test.java:63:20:63:73 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | -| unescaped | 4 | Test.java:73:28:73:81 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | -| unescaped | 11 | Test.java:80:19:80:72 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | -| unescaped | 22 | Test.java:91:20:91:42 | "WHERE ITEM_CATEGORY='" | +| tainted | 12 | Test.java:41:20:41:47 | "{ call get_product_by_id('" | +| tainted | 19 | Test.java:48:20:48:73 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | +| tainted | 28 | Test.java:57:19:57:72 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | +| tainted | 40 | Test.java:69:19:69:46 | "UPDATE PRODUCT SET PRICE='" | +| tainted | 40 | Test.java:69:19:69:73 | ... + ... | +| tainted | 40 | Test.java:69:19:69:86 | ... + ... | +| tainted | 40 | Test.java:69:58:69:73 | "' WHERE ITEM='" | +| tainted | 40 | Test.java:69:84:69:86 | "'" | +| tainted | 41 | Test.java:70:40:70:44 | query | +| tainted | 48 | Test.java:77:19:77:46 | "UPDATE PRODUCT SET PRICE='" | +| tainted | 48 | Test.java:77:19:77:73 | ... + ... | +| tainted | 48 | Test.java:77:19:77:86 | ... + ... | +| tainted | 48 | Test.java:77:58:77:73 | "' WHERE ITEM='" | +| tainted | 48 | Test.java:77:84:77:86 | "'" | +| tainted | 49 | Test.java:78:46:78:50 | query | +| tainted | 57 | Test.java:86:20:86:73 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | +| unescaped | 4 | Test.java:96:28:96:81 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | +| unescaped | 11 | Test.java:103:19:103:72 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | +| unescaped | 22 | Test.java:114:20:114:42 | "WHERE ITEM_CATEGORY='" | diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/getAnAppend.expected b/java/ql/test/query-tests/security/CWE-089/semmle/examples/getAnAppend.expected index 0921227e58b..c5a6cf55ac0 100644 --- a/java/ql/test/query-tests/security/CWE-089/semmle/examples/getAnAppend.expected +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/getAnAppend.expected @@ -1,9 +1,9 @@ -| tainted | 21 | Test.java:50:4:50:47 | StringBuilder querySb | 22 | Test.java:51:4:51:73 | append(...) | Test.java:51:19:51:72 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | -| tainted | 21 | Test.java:50:4:50:47 | StringBuilder querySb | 23 | Test.java:52:4:52:27 | append(...) | Test.java:52:19:52:26 | category | -| tainted | 21 | Test.java:50:4:50:47 | StringBuilder querySb | 24 | Test.java:53:4:53:37 | append(...) | Test.java:53:19:53:36 | "' ORDER BY PRICE" | -| unescaped | 10 | Test.java:79:4:79:47 | StringBuilder querySb | 11 | Test.java:80:4:80:73 | append(...) | Test.java:80:19:80:72 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | -| unescaped | 10 | Test.java:79:4:79:47 | StringBuilder querySb | 12 | Test.java:81:4:81:31 | append(...) | Test.java:81:19:81:30 | categoryName | -| unescaped | 10 | Test.java:79:4:79:47 | StringBuilder querySb | 13 | Test.java:82:4:82:37 | append(...) | Test.java:82:19:82:36 | "' ORDER BY PRICE" | -| unescaped | 20 | Test.java:89:4:89:48 | StringBuilder querySb2 | 21 | Test.java:90:4:90:53 | append(...) | Test.java:90:20:90:52 | "SELECT ITEM,PRICE FROM PRODUCT " | -| unescaped | 20 | Test.java:89:4:89:48 | StringBuilder querySb2 | 22 | Test.java:91:4:91:65 | append(...) | Test.java:91:20:91:64 | ... + ... | -| unescaped | 20 | Test.java:89:4:89:48 | StringBuilder querySb2 | 23 | Test.java:92:4:92:36 | append(...) | Test.java:92:20:92:35 | "ORDER BY PRICE" | +| tainted | 27 | Test.java:56:4:56:47 | StringBuilder querySb | 28 | Test.java:57:4:57:73 | append(...) | Test.java:57:19:57:72 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | +| tainted | 27 | Test.java:56:4:56:47 | StringBuilder querySb | 29 | Test.java:58:4:58:27 | append(...) | Test.java:58:19:58:26 | category | +| tainted | 27 | Test.java:56:4:56:47 | StringBuilder querySb | 30 | Test.java:59:4:59:37 | append(...) | Test.java:59:19:59:36 | "' ORDER BY PRICE" | +| unescaped | 10 | Test.java:102:4:102:47 | StringBuilder querySb | 11 | Test.java:103:4:103:73 | append(...) | Test.java:103:19:103:72 | "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" | +| unescaped | 10 | Test.java:102:4:102:47 | StringBuilder querySb | 12 | Test.java:104:4:104:31 | append(...) | Test.java:104:19:104:30 | categoryName | +| unescaped | 10 | Test.java:102:4:102:47 | StringBuilder querySb | 13 | Test.java:105:4:105:37 | append(...) | Test.java:105:19:105:36 | "' ORDER BY PRICE" | +| unescaped | 20 | Test.java:112:4:112:48 | StringBuilder querySb2 | 21 | Test.java:113:4:113:53 | append(...) | Test.java:113:20:113:52 | "SELECT ITEM,PRICE FROM PRODUCT " | +| unescaped | 20 | Test.java:112:4:112:48 | StringBuilder querySb2 | 22 | Test.java:114:4:114:65 | append(...) | Test.java:114:20:114:64 | ... + ... | +| unescaped | 20 | Test.java:112:4:112:48 | StringBuilder querySb2 | 23 | Test.java:115:4:115:36 | append(...) | Test.java:115:20:115:35 | "ORDER BY PRICE" | diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/getToStringCall.expected b/java/ql/test/query-tests/security/CWE-089/semmle/examples/getToStringCall.expected index 9fb29d97973..f5892ca62fb 100644 --- a/java/ql/test/query-tests/security/CWE-089/semmle/examples/getToStringCall.expected +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/getToStringCall.expected @@ -1,3 +1,3 @@ -| tainted | 21 | Test.java:50:4:50:47 | StringBuilder querySb | 25 | Test.java:54:29:54:46 | toString(...) | -| unescaped | 10 | Test.java:79:4:79:47 | StringBuilder querySb | 14 | Test.java:83:29:83:46 | toString(...) | -| unescaped | 20 | Test.java:89:4:89:48 | StringBuilder querySb2 | 24 | Test.java:93:30:93:48 | toString(...) | +| tainted | 27 | Test.java:56:4:56:47 | StringBuilder querySb | 31 | Test.java:60:29:60:46 | toString(...) | +| unescaped | 10 | Test.java:102:4:102:47 | StringBuilder querySb | 14 | Test.java:106:29:106:46 | toString(...) | +| unescaped | 20 | Test.java:112:4:112:48 | StringBuilder querySb2 | 24 | Test.java:116:30:116:48 | toString(...) | diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/sbQuery.expected b/java/ql/test/query-tests/security/CWE-089/semmle/examples/sbQuery.expected index 4a1560f8aff..3cc8265e945 100644 --- a/java/ql/test/query-tests/security/CWE-089/semmle/examples/sbQuery.expected +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/sbQuery.expected @@ -1,3 +1,3 @@ -| tainted | 21 | Test.java:50:4:50:47 | StringBuilder querySb | 23 | Test.java:52:19:52:26 | category | -| unescaped | 10 | Test.java:79:4:79:47 | StringBuilder querySb | 12 | Test.java:81:19:81:30 | categoryName | -| unescaped | 20 | Test.java:89:4:89:48 | StringBuilder querySb2 | 22 | Test.java:91:46:91:57 | categoryName | +| tainted | 27 | Test.java:56:4:56:47 | StringBuilder querySb | 29 | Test.java:58:19:58:26 | category | +| unescaped | 10 | Test.java:102:4:102:47 | StringBuilder querySb | 12 | Test.java:104:19:104:30 | categoryName | +| unescaped | 20 | Test.java:112:4:112:48 | StringBuilder querySb2 | 22 | Test.java:114:46:114:57 | categoryName | diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/taintedString.expected b/java/ql/test/query-tests/security/CWE-089/semmle/examples/taintedString.expected index 8cd4a301637..dd220440707 100644 --- a/java/ql/test/query-tests/security/CWE-089/semmle/examples/taintedString.expected +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/taintedString.expected @@ -4,33 +4,61 @@ | Test.java:29:22:29:28 | tainted | 5 | Test.java:34:20:35:36 | ... + ... | | Test.java:29:22:29:28 | tainted | 6 | Test.java:35:8:35:15 | category | | Test.java:29:22:29:28 | tainted | 7 | Test.java:36:47:36:52 | query1 | -| Test.java:29:22:29:28 | tainted | 12 | Test.java:41:22:41:25 | args | -| Test.java:29:22:29:28 | tainted | 12 | Test.java:41:22:41:28 | ...[...] | -| Test.java:29:22:29:28 | tainted | 13 | Test.java:42:20:43:15 | ... + ... | -| Test.java:29:22:29:28 | tainted | 13 | Test.java:42:20:43:36 | ... + ... | -| Test.java:29:22:29:28 | tainted | 14 | Test.java:43:8:43:15 | category | -| Test.java:29:22:29:28 | tainted | 15 | Test.java:44:62:44:67 | query3 | -| Test.java:29:22:29:28 | tainted | 20 | Test.java:49:22:49:25 | args | -| Test.java:29:22:29:28 | tainted | 20 | Test.java:49:22:49:28 | ...[...] | -| Test.java:29:22:29:28 | tainted | 23 | Test.java:52:4:52:27 | append(...) | -| Test.java:29:22:29:28 | tainted | 23 | Test.java:52:19:52:26 | category | -| Test.java:29:22:29:28 | tainted | 25 | Test.java:54:29:54:46 | toString(...) | -| Test.java:29:22:29:28 | tainted | 27 | Test.java:56:47:56:61 | querySbToString | -| Test.java:29:22:29:28 | tainted | 31 | Test.java:60:22:60:25 | args | -| Test.java:29:22:29:28 | tainted | 31 | Test.java:60:22:60:28 | ...[...] | -| Test.java:29:22:29:28 | tainted | 32 | Test.java:61:31:61:38 | category | -| Test.java:99:22:99:25 | good | 3 | Test.java:102:22:102:25 | args | -| Test.java:99:22:99:25 | good | 3 | Test.java:102:22:102:28 | ...[...] | -| Test.java:99:22:99:25 | good | 6 | Test.java:105:27:105:34 | category | -| Test.java:160:22:160:31 | tableNames | 21 | Test.java:181:25:181:28 | args | -| Test.java:160:22:160:31 | tableNames | 21 | Test.java:181:25:181:31 | ...[...] | -| Test.java:160:22:160:31 | tableNames | 23 | Test.java:183:36:184:18 | ... + ... | -| Test.java:160:22:160:31 | tableNames | 23 | Test.java:183:36:185:55 | ... + ... | -| Test.java:160:22:160:31 | tableNames | 24 | Test.java:184:8:184:18 | userTabName | -| Test.java:160:22:160:31 | tableNames | 26 | Test.java:186:47:186:68 | queryWithUserTableName | -| Test.java:190:21:190:24 | main | 1 | Test.java:191:11:191:14 | args | -| Test.java:190:21:190:24 | main | 3 | Test.java:193:8:193:11 | args | -| Test.java:190:21:190:24 | main | 5 | Test.java:195:14:195:17 | args | +| Test.java:29:22:29:28 | tainted | 11 | Test.java:40:16:40:19 | args | +| Test.java:29:22:29:28 | tainted | 11 | Test.java:40:16:40:22 | ...[...] | +| Test.java:29:22:29:28 | tainted | 12 | Test.java:41:20:41:52 | ... + ... | +| Test.java:29:22:29:28 | tainted | 12 | Test.java:41:20:41:67 | ... + ... | +| Test.java:29:22:29:28 | tainted | 12 | Test.java:41:51:41:52 | id | +| Test.java:29:22:29:28 | tainted | 13 | Test.java:42:57:42:62 | query2 | +| Test.java:29:22:29:28 | tainted | 18 | Test.java:47:22:47:25 | args | +| Test.java:29:22:29:28 | tainted | 18 | Test.java:47:22:47:28 | ...[...] | +| Test.java:29:22:29:28 | tainted | 19 | Test.java:48:20:49:15 | ... + ... | +| Test.java:29:22:29:28 | tainted | 19 | Test.java:48:20:49:36 | ... + ... | +| Test.java:29:22:29:28 | tainted | 20 | Test.java:49:8:49:15 | category | +| Test.java:29:22:29:28 | tainted | 21 | Test.java:50:62:50:67 | query3 | +| Test.java:29:22:29:28 | tainted | 26 | Test.java:55:22:55:25 | args | +| Test.java:29:22:29:28 | tainted | 26 | Test.java:55:22:55:28 | ...[...] | +| Test.java:29:22:29:28 | tainted | 29 | Test.java:58:4:58:27 | append(...) | +| Test.java:29:22:29:28 | tainted | 29 | Test.java:58:19:58:26 | category | +| Test.java:29:22:29:28 | tainted | 31 | Test.java:60:29:60:46 | toString(...) | +| Test.java:29:22:29:28 | tainted | 33 | Test.java:62:47:62:61 | querySbToString | +| Test.java:29:22:29:28 | tainted | 37 | Test.java:66:18:66:21 | args | +| Test.java:29:22:29:28 | tainted | 37 | Test.java:66:18:66:24 | ...[...] | +| Test.java:29:22:29:28 | tainted | 38 | Test.java:67:19:67:22 | args | +| Test.java:29:22:29:28 | tainted | 38 | Test.java:67:19:67:25 | ...[...] | +| Test.java:29:22:29:28 | tainted | 40 | Test.java:69:19:69:54 | ... + ... | +| Test.java:29:22:29:28 | tainted | 40 | Test.java:69:19:69:73 | ... + ... | +| Test.java:29:22:29:28 | tainted | 40 | Test.java:69:19:69:80 | ... + ... | +| Test.java:29:22:29:28 | tainted | 40 | Test.java:69:19:69:86 | ... + ... | +| Test.java:29:22:29:28 | tainted | 40 | Test.java:69:50:69:54 | price | +| Test.java:29:22:29:28 | tainted | 40 | Test.java:69:77:69:80 | item | +| Test.java:29:22:29:28 | tainted | 41 | Test.java:70:40:70:44 | query | +| Test.java:29:22:29:28 | tainted | 45 | Test.java:74:18:74:21 | args | +| Test.java:29:22:29:28 | tainted | 45 | Test.java:74:18:74:24 | ...[...] | +| Test.java:29:22:29:28 | tainted | 46 | Test.java:75:19:75:22 | args | +| Test.java:29:22:29:28 | tainted | 46 | Test.java:75:19:75:25 | ...[...] | +| Test.java:29:22:29:28 | tainted | 48 | Test.java:77:19:77:54 | ... + ... | +| Test.java:29:22:29:28 | tainted | 48 | Test.java:77:19:77:73 | ... + ... | +| Test.java:29:22:29:28 | tainted | 48 | Test.java:77:19:77:80 | ... + ... | +| Test.java:29:22:29:28 | tainted | 48 | Test.java:77:19:77:86 | ... + ... | +| Test.java:29:22:29:28 | tainted | 48 | Test.java:77:50:77:54 | price | +| Test.java:29:22:29:28 | tainted | 48 | Test.java:77:77:77:80 | item | +| Test.java:29:22:29:28 | tainted | 49 | Test.java:78:46:78:50 | query | +| Test.java:29:22:29:28 | tainted | 54 | Test.java:83:22:83:25 | args | +| Test.java:29:22:29:28 | tainted | 54 | Test.java:83:22:83:28 | ...[...] | +| Test.java:29:22:29:28 | tainted | 55 | Test.java:84:31:84:38 | category | +| Test.java:122:22:122:25 | good | 3 | Test.java:125:22:125:25 | args | +| Test.java:122:22:122:25 | good | 3 | Test.java:125:22:125:28 | ...[...] | +| Test.java:122:22:122:25 | good | 6 | Test.java:128:27:128:34 | category | +| Test.java:183:22:183:31 | tableNames | 21 | Test.java:204:25:204:28 | args | +| Test.java:183:22:183:31 | tableNames | 21 | Test.java:204:25:204:31 | ...[...] | +| Test.java:183:22:183:31 | tableNames | 23 | Test.java:206:36:207:18 | ... + ... | +| Test.java:183:22:183:31 | tableNames | 23 | Test.java:206:36:208:55 | ... + ... | +| Test.java:183:22:183:31 | tableNames | 24 | Test.java:207:8:207:18 | userTabName | +| Test.java:183:22:183:31 | tableNames | 26 | Test.java:209:47:209:68 | queryWithUserTableName | +| Test.java:213:21:213:24 | main | 1 | Test.java:214:11:214:14 | args | +| Test.java:213:21:213:24 | main | 3 | Test.java:216:8:216:11 | args | +| Test.java:213:21:213:24 | main | 5 | Test.java:218:14:218:17 | args | | Validation.java:6:21:6:35 | checkIdentifier | 1 | Validation.java:7:23:7:24 | id | | Validation.java:6:21:6:35 | checkIdentifier | 2 | Validation.java:8:13:8:14 | id | | Validation.java:6:21:6:35 | checkIdentifier | 4 | Validation.java:10:32:10:58 | ... + ... |