-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Java: Add Guard Classes for checking OS
- Loading branch information
1 parent
9c79a17
commit a31231f
Showing
9 changed files
with
168 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
/** | ||
* Provides classes and predicates for reasoning about checking characterizations about strings. | ||
*/ | ||
|
||
import java | ||
|
||
/** | ||
* Holds if `ma` is a call to a method that checks a partial string match. | ||
*/ | ||
predicate isStringPartialMatch(MethodAccess ma) { | ||
ma.getMethod().getDeclaringType() instanceof TypeString and | ||
ma.getMethod().getName() = | ||
["contains", "startsWith", "matches", "regionMatches", "indexOf", "lastIndexOf"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
/** | ||
* Provides classes and predicates for guards that check for the current OS. | ||
*/ | ||
|
||
import java | ||
import semmle.code.java.controlflow.Guards | ||
private import semmle.code.java.frameworks.apache.Lang | ||
private import semmle.code.java.dataflow.DataFlow | ||
private import semmle.code.java.StringCheck | ||
|
||
/** | ||
* A complimentatry guard that checks if the current platform is Windows. | ||
*/ | ||
abstract class IsWindowsGuard extends Guard { } | ||
|
||
/** | ||
* A complimentatry guard that checks if the current platform is unix or unix-like. | ||
*/ | ||
abstract class IsUnixGuard extends Guard { } | ||
|
||
/** | ||
* Holds when the MethodAccess is a call to check the current OS using either the upper case `osUpperCase` or lower case `osLowerCase` string constants. | ||
*/ | ||
bindingset[osUpperCase, osLowerCase] | ||
private predicate isOsFromSystemProp(MethodAccess ma, string osUpperCase, string osLowerCase) { | ||
exists(MethodAccessSystemGetProperty sgpMa | | ||
sgpMa.hasCompileTimeConstantGetPropertyName("os.name") | ||
| | ||
DataFlow::localExprFlow(sgpMa, ma.getQualifier()) and // Call from System.getProperty to some partial match method | ||
ma.getAnArgument().(CompileTimeConstantExpr).getStringValue().matches(osUpperCase) | ||
or | ||
exists(MethodAccess toLowerCaseMa | | ||
toLowerCaseMa.getMethod() = | ||
any(Method m | m.getDeclaringType() instanceof TypeString and m.hasName("toLowerCase")) | ||
| | ||
DataFlow::localExprFlow(sgpMa, toLowerCaseMa.getQualifier()) and // Call from System.getProperty to toLowerCase | ||
DataFlow::localExprFlow(toLowerCaseMa, ma.getQualifier()) and // Call from toLowerCase to some partial match method | ||
ma.getAnArgument().(CompileTimeConstantExpr).getStringValue().matches(osLowerCase) | ||
) | ||
) and | ||
isStringPartialMatch(ma) | ||
} | ||
|
||
private class IsWindowsFromSystemProp extends IsWindowsGuard instanceof MethodAccess { | ||
IsWindowsFromSystemProp() { isOsFromSystemProp(this, "Window%", "window%") } | ||
} | ||
|
||
private class IsUnixFromSystemProp extends IsUnixGuard instanceof MethodAccess { | ||
IsUnixFromSystemProp() { | ||
isOsFromSystemProp(this, ["Mac%", "Linux%", "LINUX%"], ["mac%", "linux%"]) | ||
} | ||
} | ||
|
||
private predicate isOsFromApacheCommons(FieldAccess fa, string fieldName) { | ||
exists(Field f | f = fa.getField() | | ||
f.getDeclaringType() instanceof ApacheSystemUtilis and | ||
f.hasName(fieldName) | ||
) | ||
} | ||
|
||
private class IsWindowsFromApacheCommons extends IsWindowsGuard instanceof FieldAccess { | ||
IsWindowsFromApacheCommons() { isOsFromApacheCommons(this, "IS_OS_WINDOWS%") } | ||
} | ||
|
||
private class IsUnixFromApacheCommons extends IsUnixGuard instanceof FieldAccess { | ||
IsUnixFromApacheCommons() { isOsFromApacheCommons(this, ["IS_OS_UNIX"]) } | ||
} | ||
|
||
/** | ||
* A guard that checks if the `java.nio.file.FileSystem` supports posix file permissions. | ||
* This is often used to infer if the OS is unix-based. | ||
* Looks for calls to `contains("poxix")` on the `supportedFileAttributeViews` method returned by `FileSystem`. | ||
*/ | ||
private class IsUnixFromPosixFromFileSystem extends IsUnixGuard instanceof MethodAccess { | ||
IsUnixFromPosixFromFileSystem() { | ||
exists(Method m | m = this.getMethod() | | ||
m.getDeclaringType() | ||
.getASupertype*() | ||
.getSourceDeclaration() | ||
.hasQualifiedName("java.util", "Set") and | ||
m.hasName("contains") | ||
) and | ||
this.getArgument(0).(CompileTimeConstantExpr).getStringValue() = "posix" and | ||
exists(Method supportedFileAttribtueViewsMethod | | ||
supportedFileAttribtueViewsMethod.hasName("supportedFileAttributeViews") and | ||
supportedFileAttribtueViewsMethod.getDeclaringType() instanceof TypeFileSystem | ||
| | ||
DataFlow::localExprFlow(any(MethodAccess ma | | ||
ma.getMethod() = supportedFileAttribtueViewsMethod | ||
), super.getQualifier()) | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import java.nio.file.FileSystems; | ||
import java.nio.file.Path; | ||
|
||
public class Test { | ||
void test() { | ||
if (System.getProperty("os.name").contains("Windows")) { | ||
|
||
} | ||
|
||
if (System.getProperty("os.name").toLowerCase().contains("windows")) { | ||
|
||
} | ||
|
||
if (System.getProperty("os.name").contains("Linux")) { | ||
|
||
} | ||
|
||
if (System.getProperty("os.name").contains("Mac OS X")) { | ||
|
||
} | ||
|
||
if (System.getProperty("os.name").toLowerCase().contains("mac")) { | ||
|
||
} | ||
|
||
if (Path.of("whatever").getFileSystem().supportedFileAttributeViews().contains("posix")) { | ||
|
||
} | ||
|
||
if (FileSystems.getDefault().supportedFileAttributeViews().contains("posix")) { | ||
|
||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
| Test.java:14:13:14:59 | contains(...) | | ||
| Test.java:18:13:18:62 | contains(...) | | ||
| Test.java:22:13:22:71 | contains(...) | | ||
| Test.java:26:13:26:95 | contains(...) | | ||
| Test.java:30:13:30:84 | contains(...) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import default | ||
import semmle.code.java.os.OSCheck | ||
|
||
from IsUnixGuard isUnix | ||
select isUnix |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
| Test.java:6:13:6:61 | contains(...) | | ||
| Test.java:10:13:10:75 | contains(...) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import default | ||
import semmle.code.java.os.OSCheck | ||
|
||
from IsWindowsGuard isWindows | ||
select isWindows |