diff --git a/java/ql/lib/change-notes/2022-03-03-char-literal-in-compile-time-constant.md b/java/ql/lib/change-notes/2022-03-03-char-literal-in-compile-time-constant.md new file mode 100644 index 000000000000..1ee68add8b14 --- /dev/null +++ b/java/ql/lib/change-notes/2022-03-03-char-literal-in-compile-time-constant.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- + * Add support for `CharacterLiteral` in `CompileTimeConstantExpr.getStringValue()` diff --git a/java/ql/lib/semmle/code/java/Expr.qll b/java/ql/lib/semmle/code/java/Expr.qll index 5a991d8814c6..d98cdbb6b0e6 100755 --- a/java/ql/lib/semmle/code/java/Expr.qll +++ b/java/ql/lib/semmle/code/java/Expr.qll @@ -168,6 +168,8 @@ class CompileTimeConstantExpr extends Expr { string getStringValue() { result = this.(StringLiteral).getValue() or + result = this.(CharacterLiteral).getValue() + or result = this.(AddExpr).getLeftOperand().(CompileTimeConstantExpr).getStringValue() + this.(AddExpr).getRightOperand().(CompileTimeConstantExpr).getStringValue() diff --git a/java/ql/test/library-tests/constants/CompileTimeConstantExpr.expected b/java/ql/test/library-tests/constants/CompileTimeConstantExpr.expected index f5e508b4a3c3..21331c4c32d5 100644 --- a/java/ql/test/library-tests/constants/CompileTimeConstantExpr.expected +++ b/java/ql/test/library-tests/constants/CompileTimeConstantExpr.expected @@ -15,3 +15,4 @@ | constants/Constants.java:20:22:20:22 | 5 | | constants/Constants.java:20:27:20:27 | 1 | | constants/Constants.java:20:31:20:31 | 2 | +| constants/Constants.java:21:22:21:24 | 'a' | diff --git a/java/ql/test/library-tests/constants/PrintAst.expected b/java/ql/test/library-tests/constants/PrintAst.expected index 241d837ea3cf..2ecc471d9811 100644 --- a/java/ql/test/library-tests/constants/PrintAst.expected +++ b/java/ql/test/library-tests/constants/PrintAst.expected @@ -66,7 +66,11 @@ constants/Constants.java: # 20| 1: [IntegerLiteral] 5 # 20| 1: [IntegerLiteral] 1 # 20| 2: [IntegerLiteral] 2 -# 22| 11: [ReturnStmt] return ... +# 21| 11: [LocalVariableDeclStmt] var ...; +# 21| 0: [TypeAccess] char +# 21| 1: [LocalVariableDeclExpr] charLiteral +# 21| 0: [CharacterLiteral] 'a' +# 23| 12: [ReturnStmt] return ... constants/Initializers.java: # 0| [CompilationUnit] Initializers # 3| 1: [Class] Initializers @@ -512,3 +516,13 @@ constants/Values.java: # 90| 0: [TypeAccess] int # 90| 1: [LocalVariableDeclExpr] var_nonfinald_local # 90| 0: [VarAccess] var_field +# 91| 68: [LocalVariableDeclStmt] var ...; +# 91| 0: [TypeAccess] String +# 91| 1: [LocalVariableDeclExpr] concatenatedString +# 91| 0: [StringLiteral] "a" + "b" +# 92| 69: [LocalVariableDeclStmt] var ...; +# 92| 0: [TypeAccess] String +# 92| 1: [LocalVariableDeclExpr] concatenatedChar +# 92| 0: [AddExpr] ... + ... +# 92| 0: [StringLiteral] "ab" +# 92| 1: [CharacterLiteral] 'c' diff --git a/java/ql/test/library-tests/constants/constants/Constants.java b/java/ql/test/library-tests/constants/constants/Constants.java index fb0a2c910918..af4ae6c2466c 100644 --- a/java/ql/test/library-tests/constants/constants/Constants.java +++ b/java/ql/test/library-tests/constants/constants/Constants.java @@ -18,6 +18,7 @@ void constants(final int notConstant) { int paren = (12); String string = "a string"; int ternary = (3 < 5) ? 1 : 2; + char charLiteral = 'a'; return; } diff --git a/java/ql/test/library-tests/constants/constants/Values.java b/java/ql/test/library-tests/constants/constants/Values.java index 7cf88fb9ad82..b59672f96e75 100644 --- a/java/ql/test/library-tests/constants/constants/Values.java +++ b/java/ql/test/library-tests/constants/constants/Values.java @@ -88,5 +88,7 @@ void values(final int notConstant) { int var_local = final_local; //42 int var_param = notConstant; //Not constant int var_nonfinald_local = var_field; //Not constant + String concatenatedString = "a" + "b"; //ab + String concatenatedChar = "ab" + 'c'; //abc } } diff --git a/java/ql/test/library-tests/constants/getBooleanValue.ql b/java/ql/test/library-tests/constants/getBooleanValue.ql index 2b10d95ff9be..460af42d3c30 100644 --- a/java/ql/test/library-tests/constants/getBooleanValue.ql +++ b/java/ql/test/library-tests/constants/getBooleanValue.ql @@ -1,9 +1,9 @@ import semmle.code.java.Variable -from Variable v, Expr init, RefType enclosing, boolean constant +from Variable v, CompileTimeConstantExpr init, RefType enclosing, boolean constant where v.getInitializer() = init and init.getEnclosingCallable().getDeclaringType() = enclosing and enclosing.hasQualifiedName("constants", "Values") and - constant = init.(CompileTimeConstantExpr).getBooleanValue() + constant = init.getBooleanValue() select init, constant diff --git a/java/ql/test/library-tests/constants/getIntValue.ql b/java/ql/test/library-tests/constants/getIntValue.ql index dbb2c5bd9670..5fc5b108032f 100644 --- a/java/ql/test/library-tests/constants/getIntValue.ql +++ b/java/ql/test/library-tests/constants/getIntValue.ql @@ -1,9 +1,9 @@ import semmle.code.java.Variable -from Variable v, Expr init, RefType enclosing, int constant +from Variable v, CompileTimeConstantExpr init, RefType enclosing, int constant where v.getInitializer() = init and init.getEnclosingCallable().getDeclaringType() = enclosing and enclosing.hasQualifiedName("constants", "Values") and - constant = init.(CompileTimeConstantExpr).getIntValue() + constant = init.getIntValue() select init, constant diff --git a/java/ql/test/library-tests/constants/getStringValue.expected b/java/ql/test/library-tests/constants/getStringValue.expected new file mode 100644 index 000000000000..b6afeb8052eb --- /dev/null +++ b/java/ql/test/library-tests/constants/getStringValue.expected @@ -0,0 +1,3 @@ +| constants/Values.java:19:29:19:31 | '*' | * | +| constants/Values.java:91:37:91:45 | "a" + "b" | ab | +| constants/Values.java:92:35:92:44 | ... + ... | abc | diff --git a/java/ql/test/library-tests/constants/getStringValue.ql b/java/ql/test/library-tests/constants/getStringValue.ql new file mode 100644 index 000000000000..bbf7cd8b51e9 --- /dev/null +++ b/java/ql/test/library-tests/constants/getStringValue.ql @@ -0,0 +1,9 @@ +import semmle.code.java.Variable + +from Variable v, CompileTimeConstantExpr init, RefType enclosing, string constant +where + v.getInitializer() = init and + init.getEnclosingCallable().getDeclaringType() = enclosing and + enclosing.hasQualifiedName("constants", "Values") and + constant = init.getStringValue() +select init, constant