Compare commits

...

5 Commits

Author SHA1 Message Date
Philip Ginsbach
9c7879325a add test for sorted test postprocess result 2024-07-16 15:34:36 +01:00
Philip Ginsbach
fba8ebe28b add test for extensible predicate in postprocess 2024-07-16 14:56:27 +01:00
Philip Ginsbach
c86e008b28 JavaInlineExpectations: remove actualLines() 2024-07-08 14:08:15 +01:00
Philip Ginsbach
7370a2e658 add '@kind test-postprocess' to postprocess queries 2024-07-08 13:43:03 +01:00
Philip Ginsbach
65655db77b java inline expectations prototype with tests 2024-07-05 11:21:05 +01:00
53 changed files with 394 additions and 0 deletions

View File

@@ -0,0 +1,81 @@
/**
* @kind test-postprocess
*/
import java
external predicate queryResults(string relation, int row, int column, string data);
predicate parsedExpectedResults(string filename, int line, string content) {
exists(Javadoc doc |
isEolComment(doc) and
filename = doc.getLocation().getFile().getBaseName() and
line = doc.getLocation().getStartLine() and
line = doc.getLocation().getEndLine() and
content = doc.getChild(0).getText().trim()
)
}
predicate expectError(string filename, int line) {
exists(string content |
parsedExpectedResults(filename, line, content) and content.indexOf("NOT OK") = 0
)
}
predicate expectPass(string filename, int line) {
exists(string content |
parsedExpectedResults(filename, line, content) and content.indexOf("OK") = 0
)
}
predicate parsedActualResults(string filename, int line, int colStart, int colEnd, string content) {
exists(int i, string posString, string lineString |
queryResults("#select", i, 0, posString) and
filename = posString.substring(0, posString.indexOf(":", 0, 0)) and
lineString = posString.substring(posString.indexOf(":", 0, 0) + 1, posString.indexOf(":", 1, 0)) and
lineString = posString.substring(posString.indexOf(":", 2, 0) + 1, posString.indexOf(":", 3, 0)) and
colStart =
posString.substring(posString.indexOf(":", 1, 0) + 1, posString.indexOf(":", 2, 0)).toInt() and
colEnd = posString.substring(posString.indexOf(":", 3, 0) + 1, posString.length()).toInt() and
line = lineString.toInt() and
queryResults("#select", i, 2, content)
)
}
predicate actualExpectedDiff(string type, string position, string error) {
exists(string filename, int line, int colStart, int colEnd |
parsedActualResults(filename, line, colStart, colEnd, error) and
expectPass(filename, line) and
type = "unexpected alert" and
position = filename + ":" + line + ":" + colStart + ":" + line + ":" + colEnd
)
or
exists(string filename, int line |
expectError(filename, line) and
not parsedActualResults(filename, line, _, _, _) and
type = "expected alert" and
position = filename + ":" + line and
parsedExpectedResults(filename, line, error)
)
or
exists(string filename, int line, string content |
parsedExpectedResults(filename, line, content) and
not expectPass(filename, line) and
not expectError(filename, line) and
type = "invalid inline expectation" and
position = filename + ":" + line and
error = content
)
}
from int line, string position, int column, string content
where
position = rank[line](string p | actualExpectedDiff(_, p, _) | p) and
(
column = 0 and content = position
or
column = 1 and actualExpectedDiff(content, position, _)
or
column = 2 and actualExpectedDiff(_, position, content)
)
select "#select", line, column, content

View File

@@ -0,0 +1,6 @@
/**
* @kind test-postprocess
*/
module;
query predicate resultRelations(string name) { name = "#select" }

View File

@@ -0,0 +1,8 @@
/**
* @kind test-postprocess
*/
module;
query predicate learnEdits(string name) { none() }
select "#select", 1, 1, "foo"

View File

@@ -0,0 +1,8 @@
/**
* @kind test-postprocess
*/
module;
query predicate extraQuery(string name) { none() }
select "#select", 1, 1, "foo"

View File

@@ -0,0 +1,8 @@
/**
* @kind test-postprocess
*/
module;
query predicate resultRelations(string name, int arity) { name = "#select" and arity = 5 }
select "#select", 1, 1, "foo"

View File

@@ -0,0 +1,5 @@
/**
* @kind test-postprocess
*/
select "#select", "1", 1, "foo"

View File

@@ -0,0 +1,5 @@
/**
* @kind test-postprocess
*/
select "#select", 1, 1, ["foo", "bar"]

View File

@@ -0,0 +1,10 @@
/**
* @kind test-postprocess
*/
from int i, int j
where
i in [1, 2] and
j in [1, 2] and
not (i = 2 and j = 2)
select "#select", i, j, "foo"

View File

@@ -0,0 +1 @@
select "#select", 1, 1, "foo"

View File

@@ -0,0 +1,17 @@
/**
* @kind test-postprocess
*/
import semmle.code.java.dataflow.ExternalFlow
string sinkModuleNamespaceRoots() {
exists(string namespace, int dotIdx |
sinkModel(namespace, _, _, _, _, _, _, _, _, _) and
dotIdx = namespace.indexOf(".", 0, 0) and
result = namespace.substring(0, dotIdx)
)
}
from int line, string content
where content = rank[line](string c | c = sinkModuleNamespaceRoots() | c)
select "#select", line, 0, content

View File

@@ -0,0 +1,8 @@
/**
* @kind test-postprocess
*/
query predicate resultRelations(string name) { name in ["B", "D", "F"] }
from int line, string name
where name = rank[line](string n | n in ["A", "C", "E"] | n)
select name, 0, 0, "empty"

View File

@@ -0,0 +1,2 @@
query: Security/CWE/CWE-020/OverlyLargeRange.ql
postprocess: TestUtilities/TestResultSorting.ql

View File

@@ -0,0 +1,19 @@
| android |
| androidx |
| ch |
| com |
| freemarker |
| groovy |
| hudson |
| io |
| jakarta |
| java |
| javafx |
| javax |
| kotlin |
| liquibase |
| net |
| ognl |
| org |
| play |
| sun |

View File

@@ -0,0 +1,2 @@
query: Security/CWE/CWE-020/OverlyLargeRange.ql
postprocess: TestUtilities/SinkModelNamespaceRoots.ql

View File

@@ -0,0 +1,2 @@
query: Security/CWE/CWE-020/OverlyLargeRange.ql
postprocess: TestUtilities/JavaInlineExpectations.ql

View File

@@ -0,0 +1,37 @@
import java.util.regex.Pattern;
class SuspiciousRegexpRange {
void test() {
Pattern overlap1 = Pattern.compile("^[0-93-5]*$"); // NOT OK
Pattern overlap2 = Pattern.compile("[A-ZA-z]*"); // OK
Pattern isEmpty = Pattern.compile("^[z-a]*$"); // NOT OK
Pattern isAscii = Pattern.compile("^[\\x00-\\x7F]*$"); // NOT OK
Pattern printable = Pattern.compile("[!-~]*"); // OK - used to select most printable ASCII characters
Pattern codePoints = Pattern.compile("[^\\x21-\\x7E]|[[\\](){}<>/%]*"); // OK
Pattern NON_ALPHANUMERIC_REGEXP = Pattern.compile("([^\\#-~| |!])*"); // OK
Pattern smallOverlap = Pattern.compile("[0-9a-fA-f]*"); // NOT OK
Pattern weirdRange = Pattern.compile("[$-`]*"); // NOT OK
Pattern keywordOperator = Pattern.compile("[!\\~\\*\\/%+-<>\\^|=&]*"); // NOT OK
Pattern notYoutube = Pattern.compile("youtu.be/[a-z1-9.-_]+"); // NOT OK
Pattern numberToLetter = Pattern.compile("[7-F]*"); // NOT OK
Pattern overlapsWithClass1 = Pattern.compile("[0-9\\d]*"); // NOT OK
Pattern overlapsWithClass2 = Pattern.compile("[\\w,.-?:*+]*"); // NOT OK
Pattern nested = Pattern.compile("[[A-Za-z_][A-Za-z0-9._-]]*"); // OK, the dash it at the end
Pattern octal = Pattern.compile("[\000-\037\040-\045]*"); // OK
}
}

View File

@@ -0,0 +1,2 @@
query: Security/CWE/CWE-020/OverlyLargeRange.ql
postprocess: TestUtilities/JavaInlineExpectations.ql

View File

@@ -0,0 +1,37 @@
import java.util.regex.Pattern;
class SuspiciousRegexpRange {
void test() {
Pattern overlap1 = Pattern.compile("^[0-93-5]*$"); // NOT OK
Pattern overlap2 = Pattern.compile("[A-ZA-z]*"); // NOT OK
Pattern isEmpty = Pattern.compile("^[z-a]*$"); // NOT OK
Pattern isAscii = Pattern.compile("^[\\x00-\\x7F]*$"); // OK
Pattern printable = Pattern.compile("[!-~]*"); // OK - used to select most printable ASCII characters
Pattern codePoints = Pattern.compile("[^\\x21-\\x7E]|[[\\](){}<>/%]*"); // OK
Pattern NON_ALPHANUMERIC_REGEXP = Pattern.compile("([^\\#-~| |!])*"); // OK
Pattern smallOverlap = Pattern.compile("[0-9a-fA-f]*"); // NOT OK
Pattern weirdRange = Pattern.compile("[$-`]*"); // NOT OK
Pattern keywordOperator = Pattern.compile("[!\\~\\*\\/%+-<>\\^|=&]*"); // NOT OK
Pattern notYoutube = Pattern.compile("youtu.be/[a-z1-9.-_]+"); // NOT OK
Pattern numberToLetter = Pattern.compile("[7-F]*"); // NOT OK
Pattern overlapsWithClass1 = Pattern.compile("[0-9\\d]*"); // NOT OK
Pattern overlapsWithClass2 = Pattern.compile("[\\w,.-?:*+]*"); // NOT OK
Pattern nested = Pattern.compile("[[A-Za-z_][A-Za-z0-9._-]]*"); // OK, the dash it at the end
Pattern octal = Pattern.compile("[\000-\037\040-\045]*"); // OK
}
}

View File

@@ -0,0 +1,2 @@
| SuspiciousRegexpRange.java:11 | expected alert | NOT OK |
| SuspiciousRegexpRange.java:7:49:7:51 | unexpected alert | Suspicious character range that overlaps with A-Z in the same character class, and is equivalent to [A-Z\\[\\\\\\]^_`a-z]. |

View File

@@ -0,0 +1,2 @@
query: Security/CWE/CWE-020/OverlyLargeRange.ql
postprocess: TestUtilities/JavaInlineExpectations.ql

View File

@@ -0,0 +1,37 @@
import java.util.regex.Pattern;
class SuspiciousRegexpRange {
void test() {
Pattern overlap1 = Pattern.compile("^[0-93-5]*$"); // NOT OK
Pattern overlap2 = Pattern.compile("[A-ZA-z]*"); // OK
Pattern isEmpty = Pattern.compile("^[z-a]*$"); // NOT OK
Pattern isAscii = Pattern.compile("^[\\x00-\\x7F]*$"); // NOT OK
Pattern printable = Pattern.compile("[!-~]*"); // OK - used to select most printable ASCII characters
Pattern codePoints = Pattern.compile("[^\\x21-\\x7E]|[[\\](){}<>/%]*"); // OK
Pattern NON_ALPHANUMERIC_REGEXP = Pattern.compile("([^\\#-~| |!])*"); // OK
Pattern smallOverlap = Pattern.compile("[0-9a-fA-f]*"); // NOT OK
Pattern weirdRange = Pattern.compile("[$-`]*"); // NOT OK
Pattern keywordOperator = Pattern.compile("[!\\~\\*\\/%+-<>\\^|=&]*"); // NOT OK
Pattern notYoutube = Pattern.compile("youtu.be/[a-z1-9.-_]+"); // NOT OK
Pattern numberToLetter = Pattern.compile("[7-F]*"); // NOT OK
Pattern overlapsWithClass1 = Pattern.compile("[0-9\\d]*"); // NOT OK
Pattern overlapsWithClass2 = Pattern.compile("[\\w,.-?:*+]*"); // NOT OK
Pattern nested = Pattern.compile("[[A-Za-z_][A-Za-z0-9._-]]*"); // OK, the dash it at the end
Pattern octal = Pattern.compile("[\000-\037\040-\045]*"); // OK
}
}

View File

@@ -0,0 +1 @@
| SuspiciousRegexpRange.java:13 | invalid inline expectation | IS OK - used to select most printable ASCII characters |

View File

@@ -0,0 +1,2 @@
query: Security/CWE/CWE-020/OverlyLargeRange.ql
postprocess: TestUtilities/JavaInlineExpectations.ql

View File

@@ -0,0 +1,37 @@
import java.util.regex.Pattern;
class SuspiciousRegexpRange {
void test() {
Pattern overlap1 = Pattern.compile("^[0-93-5]*$"); // NOT OK
Pattern overlap2 = Pattern.compile("[A-ZA-z]*"); // NOT OK
Pattern isEmpty = Pattern.compile("^[z-a]*$"); // NOT OK
Pattern isAscii = Pattern.compile("^[\\x00-\\x7F]*$"); // OK
Pattern printable = Pattern.compile("[!-~]*"); // IS OK - used to select most printable ASCII characters
Pattern codePoints = Pattern.compile("[^\\x21-\\x7E]|[[\\](){}<>/%]*"); // OK
Pattern NON_ALPHANUMERIC_REGEXP = Pattern.compile("([^\\#-~| |!])*"); // OK
Pattern smallOverlap = Pattern.compile("[0-9a-fA-f]*"); // NOT OK
Pattern weirdRange = Pattern.compile("[$-`]*"); // NOT OK
Pattern keywordOperator = Pattern.compile("[!\\~\\*\\/%+-<>\\^|=&]*"); // NOT OK
Pattern notYoutube = Pattern.compile("youtu.be/[a-z1-9.-_]+"); // NOT OK
Pattern numberToLetter = Pattern.compile("[7-F]*"); // NOT OK
Pattern overlapsWithClass1 = Pattern.compile("[0-9\\d]*"); // NOT OK
Pattern overlapsWithClass2 = Pattern.compile("[\\w,.-?:*+]*"); // NOT OK
Pattern nested = Pattern.compile("[[A-Za-z_][A-Za-z0-9._-]]*"); // OK, the dash it at the end
Pattern octal = Pattern.compile("[\000-\037\040-\045]*"); // OK
}
}

View File

@@ -0,0 +1,2 @@
query: Security/CWE/CWE-020/OverlyLargeRange.ql
postprocess: TestUtilities/ProblematicJavaInlineExpectations1.ql

View File

@@ -0,0 +1,2 @@
query: Security/CWE/CWE-020/OverlyLargeRange.ql
postprocess: TestUtilities/ProblematicJavaInlineExpectations2.ql

View File

@@ -0,0 +1,2 @@
query: Security/CWE/CWE-020/OverlyLargeRange.ql
postprocess: TestUtilities/ProblematicJavaInlineExpectations3.ql

View File

@@ -0,0 +1,2 @@
query: Security/CWE/CWE-020/OverlyLargeRange.ql
postprocess: TestUtilities/ProblematicJavaInlineExpectations4.ql

View File

@@ -0,0 +1,2 @@
query: Security/CWE/CWE-020/OverlyLargeRange.ql
postprocess: TestUtilities/ProblematicJavaInlineExpectations5.ql

View File

@@ -0,0 +1,2 @@
query: Security/CWE/CWE-020/OverlyLargeRange.ql
postprocess: TestUtilities/ProblematicJavaInlineExpectations6.ql

View File

@@ -0,0 +1,2 @@
query: Security/CWE/CWE-020/OverlyLargeRange.ql
postprocess: TestUtilities/ProblematicJavaInlineExpectations7.ql

View File

@@ -0,0 +1,2 @@
query: Security/CWE/CWE-020/OverlyLargeRange.ql
postprocess: TestUtilities/ProblematicJavaInlineExpectations8.ql

View File

@@ -0,0 +1,2 @@
query: Security/CWE/CWE-020/OverlyLargeRange.ql
postprocess: TestUtilities/JavaInlineExpectations.ql

View File

@@ -0,0 +1,37 @@
import java.util.regex.Pattern;
class SuspiciousRegexpRange {
void test() {
Pattern overlap1 = Pattern.compile("^[0-93-5]*$"); // NOT OK
Pattern overlap2 = Pattern.compile("[A-ZA-z]*"); // NOT OK
Pattern isEmpty = Pattern.compile("^[z-a]*$"); // NOT OK
Pattern isAscii = Pattern.compile("^[\\x00-\\x7F]*$"); // OK
Pattern printable = Pattern.compile("[!-~]*"); // IS OK - used to select most printable ASCII characters
Pattern codePoints = Pattern.compile("[^\\x21-\\x7E]|[[\\](){}<>/%]*"); // OK
Pattern NON_ALPHANUMERIC_REGEXP = Pattern.compile("([^\\#-~| |!])*"); // OK
Pattern smallOverlap = Pattern.compile("[0-9a-fA-f]*"); // NOT OK
Pattern weirdRange = Pattern.compile("[$-`]*"); // NOT OK
Pattern keywordOperator = Pattern.compile("[!\\~\\*\\/%+-<>\\^|=&]*"); // NOT OK
Pattern notYoutube = Pattern.compile("youtu.be/[a-z1-9.-_]+"); // NOT OK
Pattern numberToLetter = Pattern.compile("[7-F]*"); // NOT OK
Pattern overlapsWithClass1 = Pattern.compile("[0-9\\d]*"); // NOT OK
Pattern overlapsWithClass2 = Pattern.compile("[\\w,.-?:*+]*"); // NOT OK
Pattern nested = Pattern.compile("[[A-Za-z_][A-Za-z0-9._-]]*"); // OK, the dash it at the end
Pattern octal = Pattern.compile("[\000-\037\040-\045]*"); // OK
}
}