Merge branch 'main' into import-refined

This commit is contained in:
Rasmus Wriedt Larsen
2023-03-06 11:22:56 +01:00
committed by GitHub
772 changed files with 36098 additions and 6454 deletions

View File

@@ -26,9 +26,8 @@ jobs:
shell: bash
run: |
EXIT_CODE=0
# TODO: remove the swift exception from the regex when we fix generated QLdoc
# TODO: remove the shared exception from the regex when coverage of qlpacks without dbschemes is supported
changed_lib_packs="$(git diff --name-only --diff-filter=ACMRT HEAD^ HEAD | { grep -Po '^(?!(swift|shared))[a-z]*/ql/lib' || true; } | sort -u)"
changed_lib_packs="$(git diff --name-only --diff-filter=ACMRT HEAD^ HEAD | { grep -Po '^(?!(shared))[a-z]*/ql/lib' || true; } | sort -u)"
for pack_dir in ${changed_lib_packs}; do
lang="${pack_dir%/ql/lib}"
codeql generate library-doc-coverage --output="${RUNNER_TEMP}/${lang}-current.txt" --dir="${pack_dir}"

View File

@@ -68,7 +68,9 @@ class Declaration extends Locatable, @declaration {
* Holds if this declaration has the fully-qualified name `qualifiedName`.
* See `getQualifiedName`.
*/
predicate hasQualifiedName(string qualifiedName) { this.getQualifiedName() = qualifiedName }
deprecated predicate hasQualifiedName(string qualifiedName) {
this.getQualifiedName() = qualifiedName
}
/**
* Holds if this declaration has a fully-qualified name with a name-space

View File

@@ -0,0 +1,7 @@
...
a = getc(f);
if (a < 123) ret = 123/a; // BAD
...
if (a != 0) ret = 123/a; // GOOD
...

View File

@@ -0,0 +1,23 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p> Possible cases of division by zero when using the return value from functions.</p>
</overview>
<example>
<p>The following example shows the use of a function with an error when using the return value and without an error.</p>
<sample src="DivideByZeroUsingReturnValue.cpp" />
</example>
<references>
<li>
CERT Coding Standard:
<a href="https://wiki.sei.cmu.edu/confluence/display/c/INT33-C.+Ensure+that+division+and+remainder+operations+do+not+result+in+divide-by-zero+errors">INT33-C. Ensure that division and remainder operations do not result in divide-by-zero errors - SEI CERT C Coding Standard - Confluence</a>.
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,274 @@
/**
* @name Divide by zero using return value
* @description Possible cases of division by zero when using the return value from functions.
* @kind problem
* @id cpp/divide-by-zero-using-return-value
* @problem.severity warning
* @precision medium
* @tags correctness
* security
* external/cwe/cwe-369
*/
import cpp
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
import semmle.code.cpp.controlflow.Guards
/** Holds if function `fn` can return a value equal to value `val` */
predicate mayBeReturnValue(Function fn, float val) {
exists(Expr tmpExp, ReturnStmt rs |
tmpExp.getValue().toFloat() = val and
rs.getEnclosingFunction() = fn and
(
globalValueNumber(rs.getExpr()) = globalValueNumber(tmpExp)
or
exists(AssignExpr ae |
ae.getLValue().(VariableAccess).getTarget() =
globalValueNumber(rs.getExpr()).getAnExpr().(VariableAccess).getTarget() and
globalValueNumber(ae.getRValue()) = globalValueNumber(tmpExp)
)
or
exists(Initializer it |
globalValueNumber(it.getExpr()) = globalValueNumber(tmpExp) and
it.getDeclaration().(Variable).getAnAccess().getTarget() =
globalValueNumber(rs.getExpr()).getAnExpr().(VariableAccess).getTarget()
)
)
)
}
/** Holds if function `fn` can return a value equal zero */
predicate mayBeReturnZero(Function fn) {
mayBeReturnValue(fn, 0)
or
fn.hasName([
"iswalpha", "iswlower", "iswprint", "iswspace", "iswblank", "iswupper", "iswcntrl",
"iswctype", "iswalnum", "iswgraph", "iswxdigit", "iswdigit", "iswpunct", "isblank", "isupper",
"isgraph", "isalnum", "ispunct", "islower", "isspace", "isprint", "isxdigit", "iscntrl",
"isdigit", "isalpha", "timespec_get", "feof", "atomic_is_lock_free",
"atomic_compare_exchange", "thrd_equal", "isfinite", "islessequal", "isnan", "isgreater",
"signbit", "isinf", "islessgreater", "isnormal", "isless", "isgreaterequal", "isunordered",
"ferror"
])
or
fn.hasName([
"thrd_sleep", "feenv", "feholdexcept", "feclearexcept", "feexceptflag", "feupdateenv",
"remove", "fflush", "setvbuf", "fgetpos", "fsetpos", "fclose", "rename", "fseek", "raise"
])
or
fn.hasName(["tss_get", "gets"])
or
fn.hasName(["getc", "atoi"])
}
/** Gets the Guard which compares the expression `bound` */
pragma[inline]
GuardCondition checkByValue(Expr bound, Expr val) {
exists(GuardCondition gc |
(
gc.ensuresEq(bound, val, _, _, _) or
gc.ensuresEq(val, bound, _, _, _) or
gc.ensuresLt(bound, val, _, _, _) or
gc.ensuresLt(val, bound, _, _, _) or
gc = globalValueNumber(bound).getAnExpr()
) and
result = gc
)
}
/** Holds if there are no comparisons between the value returned by possible function calls `compArg` and the value `valArg`, or when these comparisons do not exclude equality to the value `valArg`. */
pragma[inline]
predicate compareFunctionWithValue(Expr guardExp, Function compArg, Expr valArg) {
not exists(Expr exp |
exp.getAChild*() = globalValueNumber(compArg.getACallToThisFunction()).getAnExpr() and
checkByValue(exp, valArg).controls(guardExp.getBasicBlock(), _)
)
or
exists(GuardCondition gc |
(
gc.ensuresEq(globalValueNumber(compArg.getACallToThisFunction()).getAnExpr(), valArg, 0,
guardExp.getBasicBlock(), true)
or
gc.ensuresEq(valArg, globalValueNumber(compArg.getACallToThisFunction()).getAnExpr(), 0,
guardExp.getBasicBlock(), true)
or
gc.ensuresLt(globalValueNumber(compArg.getACallToThisFunction()).getAnExpr(), valArg, 0,
guardExp.getBasicBlock(), false)
or
gc.ensuresLt(valArg, globalValueNumber(compArg.getACallToThisFunction()).getAnExpr(), 0,
guardExp.getBasicBlock(), false)
)
or
exists(Expr exp |
exp.getValue().toFloat() > valArg.getValue().toFloat() and
gc.ensuresLt(globalValueNumber(compArg.getACallToThisFunction()).getAnExpr(), exp, 0,
guardExp.getBasicBlock(), true)
or
exp.getValue().toFloat() < valArg.getValue().toFloat() and
gc.ensuresLt(exp, globalValueNumber(compArg.getACallToThisFunction()).getAnExpr(), 0,
guardExp.getBasicBlock(), true)
)
)
or
valArg.getValue().toFloat() = 0 and
exists(NotExpr ne, IfStmt ifne |
ne.getOperand() = globalValueNumber(compArg.getACallToThisFunction()).getAnExpr() and
ifne.getCondition() = ne and
ifne.getThen().getAChild*() = guardExp
)
}
/** Wraping predicate for call `compareFunctionWithValue`. */
pragma[inline]
predicate checkConditions1(Expr div, Function fn, float changeInt) {
exists(Expr val |
val.getEnclosingFunction() = fn and
val.getValue().toFloat() = changeInt and
compareFunctionWithValue(div, fn, val)
)
}
/** Holds if there are no comparisons between the value `compArg` and the value `valArg`, or when these comparisons do not exclude equality to the value `valArg`. */
pragma[inline]
predicate compareExprWithValue(Expr guardExp, Expr compArg, Expr valArg) {
not exists(Expr exp |
exp.getAChild*() = globalValueNumber(compArg).getAnExpr() and
checkByValue(exp, valArg).controls(guardExp.getBasicBlock(), _)
)
or
exists(GuardCondition gc |
(
gc.ensuresEq(globalValueNumber(compArg).getAnExpr(), valArg, 0, guardExp.getBasicBlock(), true)
or
gc.ensuresEq(valArg, globalValueNumber(compArg).getAnExpr(), 0, guardExp.getBasicBlock(), true)
or
gc.ensuresLt(globalValueNumber(compArg).getAnExpr(), valArg, 0, guardExp.getBasicBlock(),
false)
or
gc.ensuresLt(valArg, globalValueNumber(compArg).getAnExpr(), 0, guardExp.getBasicBlock(),
false)
)
or
exists(Expr exp |
exp.getValue().toFloat() > valArg.getValue().toFloat() and
gc.ensuresLt(globalValueNumber(compArg).getAnExpr(), exp, 0, guardExp.getBasicBlock(), true)
or
exp.getValue().toFloat() < valArg.getValue().toFloat() and
gc.ensuresLt(exp, globalValueNumber(compArg).getAnExpr(), 0, guardExp.getBasicBlock(), true)
)
)
or
valArg.getValue().toFloat() = 0 and
exists(NotExpr ne, IfStmt ifne |
ne.getOperand() = globalValueNumber(compArg).getAnExpr() and
ifne.getCondition() = ne and
ifne.getThen().getAChild*() = guardExp
)
}
/** Wraping predicate for call `compareExprWithValue`. */
pragma[inline]
predicate checkConditions2(Expr div, Expr divVal, float changeInt2) {
exists(Expr val |
(
val.getEnclosingFunction() =
div.getEnclosingFunction().getACallToThisFunction().getEnclosingFunction() or
val.getEnclosingFunction() = div.getEnclosingFunction()
) and
val.getValue().toFloat() = changeInt2 and
compareExprWithValue(div, divVal, val)
)
}
/** Gets the value of the difference or summand from the expression `src`. */
float getValueOperand(Expr src, Expr e1, Expr e2) {
src.(SubExpr).hasOperands(e1, e2) and
result = e2.getValue().toFloat()
or
src.(AddExpr).hasOperands(e1, e2) and
result = -e2.getValue().toFloat()
}
/** Function the return of the expression `e1` and the multiplication operands, or the left operand of division if `e1` contains a multiplication or division, respectively. */
Expr getMulDivOperand(Expr e1) {
result = e1 or
result = e1.(MulExpr).getAnOperand() or
result = e1.(DivExpr).getLeftOperand()
}
/** The class that defines possible variants of the division expression or the search for the remainder. */
class MyDiv extends Expr {
MyDiv() {
this instanceof DivExpr or
this instanceof RemExpr or
this instanceof AssignDivExpr or
this instanceof AssignRemExpr
}
Expr getRV() {
result = this.(AssignArithmeticOperation).getRValue() or
result = this.(BinaryArithmeticOperation).getRightOperand()
}
}
from Expr exp, string msg, Function fn, GVN findVal, float changeInt, MyDiv div
where
findVal = globalValueNumber(fn.getACallToThisFunction()) and
(
// Look for divide-by-zero operations possible due to the return value of the function `fn`.
checkConditions1(div, fn, changeInt) and
(
// Function return value can be zero.
mayBeReturnZero(fn) and
getMulDivOperand(globalValueNumber(div.getRV()).getAnExpr()) = findVal.getAnExpr() and
changeInt = 0
or
// Denominator can be sum or difference.
changeInt = getValueOperand(div.getRV(), findVal.getAnExpr(), _) and
mayBeReturnValue(fn, changeInt)
) and
exp = div and
msg =
"Can lead to division by 0, since the function " + fn.getName() + " can return a value " +
changeInt.toString() + "."
or
// Search for situations where division by zero is possible inside the `divFn` function if the passed argument can be equal to a certain value.
exists(int posArg, Expr divVal, FunctionCall divFc, float changeInt2 |
// Division is associated with the function argument.
exists(Function divFn |
divFn.getParameter(posArg).getAnAccess() = divVal and
divVal.getEnclosingStmt() = div.getEnclosingStmt() and
divFc = divFn.getACallToThisFunction()
) and
(
divVal = div.getRV() and
divFc.getArgument(posArg) != findVal.getAnExpr() and
(
// Function return value can be zero.
mayBeReturnZero(fn) and
getMulDivOperand(globalValueNumber(divFc.getArgument(posArg)).getAnExpr()) =
findVal.getAnExpr() and
changeInt = 0 and
changeInt2 = 0
or
// Denominator can be sum or difference.
changeInt = getValueOperand(divFc.getArgument(posArg), findVal.getAnExpr(), _) and
mayBeReturnValue(fn, changeInt) and
changeInt2 = 0
)
or
// Look for a situation where the difference or subtraction is considered as an argument, and it can be used in the same way.
changeInt = getValueOperand(div.getRV(), divVal, _) and
changeInt2 = changeInt and
mayBeReturnValue(fn, changeInt) and
divFc.getArgument(posArg) = findVal.getAnExpr()
) and
checkConditions2(div, divVal, changeInt2) and
checkConditions1(divFc, fn, changeInt) and
exp = divFc and
msg =
"Can lead to division by 0, since the function " + fn.getName() + " can return a value " +
changeInt.toString() + "."
)
)
select exp, msg

View File

@@ -0,0 +1,27 @@
| test.cpp:47:24:47:31 | ... / ... | Can lead to division by 0, since the function getSize can return a value 0. |
| test.cpp:48:15:48:34 | ... / ... | Can lead to division by 0, since the function getSize2 can return a value 0. |
| test.cpp:53:10:53:17 | ... / ... | Can lead to division by 0, since the function getSize can return a value 0. |
| test.cpp:65:15:65:22 | ... / ... | Can lead to division by 0, since the function getSize can return a value 0. |
| test.cpp:68:15:68:22 | ... / ... | Can lead to division by 0, since the function getSize can return a value 0. |
| test.cpp:71:9:71:16 | ... / ... | Can lead to division by 0, since the function getSize can return a value 0. |
| test.cpp:74:9:74:16 | ... / ... | Can lead to division by 0, since the function getSize can return a value 0. |
| test.cpp:77:21:77:28 | ... / ... | Can lead to division by 0, since the function getSize can return a value 0. |
| test.cpp:79:25:79:32 | ... / ... | Can lead to division by 0, since the function getSize can return a value 0. |
| test.cpp:81:24:81:31 | ... / ... | Can lead to division by 0, since the function getSize can return a value 0. |
| test.cpp:128:10:128:16 | ... / ... | Can lead to division by 0, since the function getSize can return a value 0. |
| test.cpp:135:10:135:16 | ... / ... | Can lead to division by 0, since the function getSize can return a value 0. |
| test.cpp:141:10:141:23 | ... / ... | Can lead to division by 0, since the function getSize can return a value 0. |
| test.cpp:153:12:153:19 | ... / ... | Can lead to division by 0, since the function getSize can return a value 0. |
| test.cpp:172:3:172:12 | ... /= ... | Can lead to division by 0, since the function getSize can return a value 0. |
| test.cpp:173:3:173:12 | ... %= ... | Can lead to division by 0, since the function getSize can return a value 0. |
| test.cpp:187:10:187:17 | ... / ... | Can lead to division by 0, since the function getSizeFloat can return a value 0. |
| test.cpp:199:12:199:25 | ... / ... | Can lead to division by 0, since the function getSize can return a value -1. |
| test.cpp:202:12:202:25 | ... / ... | Can lead to division by 0, since the function getSize can return a value 1. |
| test.cpp:205:10:205:23 | ... / ... | Can lead to division by 0, since the function getSize can return a value 1. |
| test.cpp:210:10:210:23 | ... / ... | Can lead to division by 0, since the function getSize can return a value 3. |
| test.cpp:258:3:258:10 | call to badMyDiv | Can lead to division by 0, since the function getSize can return a value 0. |
| test.cpp:259:3:259:10 | call to badMyDiv | Can lead to division by 0, since the function getSize can return a value 2. |
| test.cpp:260:3:260:13 | call to badMySubDiv | Can lead to division by 0, since the function getSize can return a value 3. |
| test.cpp:263:5:263:15 | call to badMySubDiv | Can lead to division by 0, since the function getSize can return a value 3. |
| test.cpp:273:5:273:12 | call to badMyDiv | Can lead to division by 0, since the function getSize can return a value 3. |
| test.cpp:275:5:275:12 | call to badMyDiv | Can lead to division by 0, since the function getSize can return a value -1. |

View File

@@ -0,0 +1 @@
experimental/Security/CWE/CWE-369/DivideByZeroUsingReturnValue.ql

View File

@@ -0,0 +1,278 @@
typedef struct {}
FILE;
int getc(FILE * stream);
int getSize(int type) {
int st;
switch (type) {
case 1:
st = 1;
break;
case 2:
st = 2;
break;
case 3:
st = 3;
break;
case 4:
st = -1;
break;
default:
st = 0;
break;
}
return st;
}
int getSize2(int type) {
int st = 0;
switch (type) {
case 1:
st = 1;
break;
case 2:
st = 2;
break;
case 3:
st = 3;
break;
case 4:
st = -1;
break;
}
return st;
}
int badTestf1(int type, int met) {
int is = getSize(type);
if (met == 1) return 123 / is; // BAD
else return 123 / getSize2(type); // BAD
}
int badTestf2(int type) {
int is;
is = getSize(type);
return 123 / is; // BAD
}
int badTestf3(int type, int met) {
int is;
is = getSize(type);
switch (met) {
case 1:
if (is >= 0) return 123 / is; // BAD [NOT DETECTED]
case 2:
if (0 == is) return 123 / is; // BAD [NOT DETECTED]
case 3:
if (!is & 123 / is) // BAD
return 123;
case 4:
if (!is | 123 / is) // BAD
return 123;
case 5:
if (123 / is || !is) // BAD
return 123;
case 6:
if (123 / is && !is) // BAD
return 123;
case 7:
if (!is) return 123 / is; // BAD
case 8:
if (is > -1) return 123 / is; // BAD
case 9:
if (is < 2) return 123 / is; // BAD
}
if (is != 0) return -1;
if (is == 0) type += 1;
return 123 / is; // BAD [NOT DETECTED]
}
int goodTestf3(int type, int met) {
int is = getSize(type);
if (is == 0) return -1;
switch (met) {
case 1:
if (is < 0) return 123 / is; // GOOD
case 2:
if (!is && 123 / is) // GOOD
return 123;
case 3:
if (!is || 123 / is) // GOOD
return 123;
case 8:
if (is < -1) return 123 / is; // GOOD
case 9:
if (is > 2) return 123 / is; // GOOD
}
return 123 / is;
}
int goodTestf3a(int type, int met) {
int is = getSize(type);
switch (met) {
case 1:
if (is < 0)
return 123 / is; // GOOD
case 2:
if (!is && 123 / is) // GOOD
return 123;
case 3:
if (!is || 123 / is) // GOOD
return 123;
}
return 1;
}
int badTestf4(int type) {
int is = getSize(type);
int d;
d = type * is;
return 123 / d; // BAD
}
int badTestf5(int type) {
int is = getSize(type);
int d;
d = is / type;
return 123 / d; // BAD
}
int badTestf6(int type) {
int is = getSize(type);
int d;
d = is / type;
return type * 123 / d; // BAD
}
int badTestf7(int type, int met) {
int is = getSize(type);
if (is == 0) goto quit;
switch (met) {
case 1:
if (is < 0)
return 123 / is; // GOOD
}
quit:
return 123 / is; // BAD
}
int goodTestf7(int type, int met) {
int is = getSize(type);
if (is == 0) goto quit2;
if (is == 0.) return -1;
switch (met) {
case 1:
if (is < 0.)
return 123 / is; // GOOD
}
return 123 / is; // GOOD
quit2:
return -1;
}
int badTestf8(int type) {
int is = getSize(type);
type /= is; // BAD
type %= is; // BAD
return type;
}
float getSizeFloat(float type) {
float st;
if (type)
st = 1.0;
else
st = 0.0;
return st;
}
float badTestf9(float type) {
float is = getSizeFloat(type);
return 123 / is; // BAD
}
float goodTestf9(float type) {
float is = getSizeFloat(type);
if (is == 0.0) return -1;
return 123 / is; // GOOD
}
int badTestf10(int type) {
int out = type;
int is = getSize(type);
if (is > -2) {
out /= 123 / (is + 1); // BAD
}
if (is > 0) {
return 123 / (is - 1); // BAD
}
if (is <= 0) return 0;
return 123 / (is - 1); // BAD
return 0;
}
int badTestf11(int type) {
int is = getSize(type);
return 123 / (is - 3); // BAD
}
int goodTestf11(int type) {
int is = getSize(type);
if (is > 1) {
return 123 / (is - 1); // GOOD
} else {
return 0;
}
}
int badTestf12(FILE * f) {
int a;
int ret = -1;
a = getc(f);
if (a == 0) ret = 123 / a; // BAD [NOT DETECTED]
return ret;
}
int goodTestf12(FILE * f) {
int a;
int ret = -1;
a = getc(f);
if (a != 0) ret = 123 / a; // GOOD
return ret;
}
int badMyDiv(int type, int is) {
type /= is;
type %= is;
return type;
}
int goodMyDiv(int type, int is) {
if (is == 0) return -1;
type /= is;
type %= is;
return type;
}
int badMySubDiv(int type, int is) {
type /= (is - 3);
type %= (is + 1);
return type;
}
void badTestf13(int type) {
int is = getSize(type);
badMyDiv(type, is); // BAD
badMyDiv(type, is - 2); // BAD
badMySubDiv(type, is); // BAD
goodMyDiv(type, is); // GOOD
if (is < 5)
badMySubDiv(type, is); // BAD
if (is < 0)
badMySubDiv(type, is); // BAD [NOT DETECTED]
if (is > 5)
badMySubDiv(type, is); // GOOD
if (is == 0)
badMyDiv(type, is); // BAD
if (is > 0)
badMyDiv(type, is); // GOOD
if (is < 5)
badMyDiv(type, is - 3); // BAD
if (is < 0)
badMyDiv(type, is + 1); // BAD
if (is > 5)
badMyDiv(type, is - 3); // GOOD
}

View File

@@ -10,6 +10,8 @@ namespace Semmle.Extraction.CSharp.Entities
private Conversion(Context cx, IMethodSymbol init)
: base(cx, init) { }
protected override MethodKind ExplicitlyImplementsKind => MethodKind.Conversion;
public static new Conversion Create(Context cx, IMethodSymbol symbol) =>
ConversionFactory.Instance.CreateEntityFromSymbol(cx, symbol);

View File

@@ -83,10 +83,12 @@ namespace Semmle.Extraction.CSharp.Entities
}
}
protected virtual MethodKind ExplicitlyImplementsKind => MethodKind.Ordinary;
public void Overrides(TextWriter trapFile)
{
foreach (var explicitInterface in Symbol.ExplicitInterfaceImplementations
.Where(sym => sym.MethodKind == MethodKind.Ordinary)
.Where(sym => sym.MethodKind == ExplicitlyImplementsKind)
.Select(impl => Type.Create(Context, impl.ContainingType)))
{
trapFile.explicitly_implements(this, explicitInterface.TypeRef);

View File

@@ -85,6 +85,9 @@ namespace Semmle.Extraction.CSharp.Entities
if (nt.IsRecord)
HasModifier(cx, trapFile, key, Modifiers.Record);
if (nt.IsFileLocal)
HasModifier(cx, trapFile, key, Modifiers.File);
if (nt.TypeKind == TypeKind.Struct)
{
if (nt.IsReadOnly)
@@ -97,7 +100,11 @@ namespace Semmle.Extraction.CSharp.Entities
public static void ExtractModifiers(Context cx, TextWriter trapFile, IEntity key, ISymbol symbol)
{
HasAccessibility(cx, trapFile, key, symbol.DeclaredAccessibility);
// A file scoped type has declared accessibility `internal` which we shouldn't extract.
// The file modifier is extracted as a source level modifier.
if (symbol.Kind != SymbolKind.NamedType || !((INamedTypeSymbol)symbol).IsFileLocal)
HasAccessibility(cx, trapFile, key, symbol.DeclaredAccessibility);
if (symbol.Kind == SymbolKind.ErrorType)
trapFile.has_modifiers(key, Modifier.Create(cx, Accessibility.Public));

View File

@@ -4,6 +4,7 @@ internal static class Modifiers
public const string Async = "async";
public const string Const = "const";
public const string Extern = "extern";
public const string File = "file";
public const string Internal = "internal";
public const string New = "new";
public const string Override = "override";

View File

@@ -11,6 +11,8 @@ namespace Semmle.Extraction.CSharp.Entities
protected UserOperator(Context cx, IMethodSymbol init)
: base(cx, init) { }
protected override MethodKind ExplicitlyImplementsKind => MethodKind.UserDefinedOperator;
public override void Populate(TextWriter trapFile)
{
PopulateMethod(trapFile);
@@ -37,6 +39,7 @@ namespace Semmle.Extraction.CSharp.Entities
}
ContainingType.PopulateGenerics();
Overrides(trapFile);
}
public override bool NeedsPopulation => Context.Defines(Symbol) || IsImplicitOperator(out _);

View File

@@ -282,54 +282,60 @@ namespace Semmle.Extraction.CSharp
public static IEnumerable<IFieldSymbol?> GetTupleElementsMaybeNull(this INamedTypeSymbol type) =>
type.TupleElements;
private static void BuildQualifierAndName(INamedTypeSymbol named, Context cx, EscapingTextWriter trapFile, ISymbol symbolBeingDefined)
{
if (named.ContainingType is not null)
{
named.ContainingType.BuildOrWriteId(cx, trapFile, symbolBeingDefined, constructUnderlyingTupleType: false);
trapFile.Write('.');
}
else if (named.ContainingNamespace is not null)
{
if (cx.ShouldAddAssemblyTrapPrefix && named.ContainingAssembly is not null)
BuildAssembly(named.ContainingAssembly, trapFile);
named.ContainingNamespace.BuildNamespace(cx, trapFile);
}
var name = named.IsFileLocal ? named.MetadataName : named.Name;
trapFile.Write(name);
}
private static void BuildTupleId(INamedTypeSymbol named, Context cx, EscapingTextWriter trapFile, ISymbol symbolBeingDefined)
{
trapFile.Write('(');
trapFile.BuildList(",", named.GetTupleElementsMaybeNull(),
(i, f) =>
{
if (f is null)
{
trapFile.Write($"null({i})");
}
else
{
trapFile.Write((f.CorrespondingTupleField ?? f).Name);
trapFile.Write(":");
f.Type.BuildOrWriteId(cx, trapFile, symbolBeingDefined, constructUnderlyingTupleType: false);
}
}
);
trapFile.Write(")");
}
private static void BuildNamedTypeId(this INamedTypeSymbol named, Context cx, EscapingTextWriter trapFile, ISymbol symbolBeingDefined, bool constructUnderlyingTupleType)
{
if (!constructUnderlyingTupleType && named.IsTupleType)
{
trapFile.Write('(');
trapFile.BuildList(",", named.GetTupleElementsMaybeNull(),
(i, f) =>
{
if (f is null)
{
trapFile.Write($"null({i})");
}
else
{
trapFile.Write((f.CorrespondingTupleField ?? f).Name);
trapFile.Write(":");
f.Type.BuildOrWriteId(cx, trapFile, symbolBeingDefined, constructUnderlyingTupleType: false);
}
}
);
trapFile.Write(")");
BuildTupleId(named, cx, trapFile, symbolBeingDefined);
return;
}
void AddContaining()
{
if (named.ContainingType is not null)
{
named.ContainingType.BuildOrWriteId(cx, trapFile, symbolBeingDefined, constructUnderlyingTupleType: false);
trapFile.Write('.');
}
else if (named.ContainingNamespace is not null)
{
if (cx.ShouldAddAssemblyTrapPrefix && named.ContainingAssembly is not null)
BuildAssembly(named.ContainingAssembly, trapFile);
named.ContainingNamespace.BuildNamespace(cx, trapFile);
}
}
if (named.TypeParameters.IsEmpty)
{
AddContaining();
trapFile.Write(named.Name);
BuildQualifierAndName(named, cx, trapFile, symbolBeingDefined);
}
else if (named.IsReallyUnbound())
{
AddContaining();
trapFile.Write(named.Name);
BuildQualifierAndName(named, cx, trapFile, symbolBeingDefined);
trapFile.Write("`");
trapFile.Write(named.TypeParameters.Length);
}

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* C# 11: Added extractor and library support for `file` scoped types.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* C# 11: Support for explicit interface member implementation of operators.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The query `cs/static-field-written-by-instance` is updated to handle properties.

View File

@@ -434,7 +434,7 @@ class Destructor extends DotNet::Destructor, Callable, Member, Attributable, @de
* Either a unary operator (`UnaryOperator`), a binary operator
* (`BinaryOperator`), or a conversion operator (`ConversionOperator`).
*/
class Operator extends Callable, Member, Attributable, @operator {
class Operator extends Callable, Member, Attributable, Overridable, @operator {
/**
* DEPRECATED: use `getFunctionName()` instead.
*

View File

@@ -93,6 +93,9 @@ class Modifiable extends Declaration, @modifiable {
/** Holds if this declaration has the modifier `required`. */
predicate isRequired() { this.hasModifier("required") }
/** Holds if this declaration is `file` local. */
predicate isFile() { this.hasModifier("file") }
/** Holds if this declaration is `unsafe`. */
predicate isUnsafe() {
this.hasModifier("unsafe") or
@@ -183,6 +186,8 @@ class Member extends DotNet::Member, Modifiable, @member {
override predicate isStatic() { Modifiable.super.isStatic() }
override predicate isRequired() { Modifiable.super.isRequired() }
override predicate isFile() { Modifiable.super.isFile() }
}
private class TOverridable = @virtualizable or @callable_accessor;

View File

@@ -137,6 +137,8 @@ private class RecordConstructorFlow extends SummarizedCallable {
preservesValue = true
)
}
override predicate hasProvenance(string provenance) { provenance = "manual" }
}
class RequiredSummaryComponentStack = Impl::Public::RequiredSummaryComponentStack;

View File

@@ -248,7 +248,9 @@ module Public {
/**
* Holds if all the summaries that apply to `this` are auto generated and not manually created.
*/
final predicate isAutoGenerated() { this.hasProvenance("generated") and not this.isManual() }
final predicate isAutoGenerated() {
this.hasProvenance(["generated", "ai-generated"]) and not this.isManual()
}
/**
* Holds if there exists a manual summary that applies to `this`.
@@ -268,7 +270,7 @@ module Public {
/**
* Holds if the neutral is auto generated.
*/
predicate isAutoGenerated() { neutralElement(this, "generated") }
predicate isAutoGenerated() { neutralElement(this, ["generated", "ai-generated"]) }
/**
* Holds if there exists a manual neutral that applies to `this`.
@@ -1202,11 +1204,11 @@ module Private {
}
private string renderProvenance(SummarizedCallable c) {
if c.isAutoGenerated() then result = "generated" else result = "manual"
if c.isManual() then result = "manual" else c.hasProvenance(result)
}
private string renderProvenanceNeutral(NeutralCallable c) {
if c.isAutoGenerated() then result = "generated" else result = "manual"
if c.isManual() then result = "manual" else c.hasProvenance(result)
}
/**

View File

@@ -86,6 +86,8 @@ module EntityFramework {
abstract class EFSummarizedCallable extends SummarizedCallable {
bindingset[this]
EFSummarizedCallable() { any() }
override predicate hasProvenance(string provenance) { provenance = "manual" }
}
private class DbSetAddOrUpdateRequiredSummaryComponentStack extends RequiredSummaryComponentStack {

View File

@@ -83,6 +83,9 @@ class Member extends Declaration, @dotnet_member {
/** Holds if this member is declared `required`. */
predicate isRequired() { none() }
/** Holds if this member is declared `file` local. */
predicate isFile() { none() }
/**
* Holds if this member has name `name` and is defined in type `type`
* with namespace `namespace`.

View File

@@ -1,6 +1,6 @@
/**
* @name Static field written by instance method
* @description Finds instance methods that write static fields.
* @description Finds instance methods and properties that write to static fields.
* This is tricky to get right if multiple instances are being manipulated,
* and generally bad practice.
* @kind problem
@@ -14,12 +14,12 @@
import csharp
from FieldWrite fw, Field f, Callable m
from FieldWrite fw, Field f, Callable c
where
fw.getTarget() = f and
f.isStatic() and
m = fw.getEnclosingCallable() and
not m.(Member).isStatic() and
f.getDeclaringType() = m.getDeclaringType() and
m.fromSource()
select fw.(VariableAccess), "Write to static field from instance method or constructor."
c = fw.getEnclosingCallable() and
not [c.(Member), c.(Accessor).getDeclaration()].isStatic() and
f.getDeclaringType() = c.getDeclaringType() and
c.fromSource()
select fw.(VariableAccess), "Write to static field from instance method, property, or constructor."

View File

@@ -0,0 +1,25 @@
file interface I1 { }
file interface I2 { }
file class C1 : I1 { }
public class C2 { }
public class C3 : I2 { }
file interface IC { }
file class C4<T> { }
file class C5<S> : C4<S> { }
file struct S1 { }
file enum E1 { }
file delegate void D1();
file record R1 { }
file record struct RS1 { }

View File

@@ -0,0 +1,23 @@
file interface I1 { }
public interface I2 { }
file class C1 { }
file class C2 : I2 { }
file class IC { }
file class C4<T> { }
file class C5<S> : C4<S> { }
file struct S1 { }
file enum E1 { }
file delegate void D1();
file record R1 { }
file record struct RS1 { }

View File

@@ -0,0 +1,7 @@
namespace TestFileScoped;
file interface I10 { }
file class C10 { }
public class C11 : I10 { }

View File

@@ -0,0 +1,7 @@
namespace TestFileScoped;
public interface I10 { }
file class C10 { }
file class C11 : I10 { }

View File

@@ -216,6 +216,103 @@ CheckedOperators.cs:
# 55| 0: [TypeMention] short
# 55| 1: [PropertyCall] access to property Value
# 55| -1: [ParameterAccess] access to parameter n
FileScoped1.cs:
# 1| [Interface] I1
# 3| [Interface] I2
# 5| [Class] C1
#-----| 3: (Base types)
# 5| 1: [TypeMention] I1
# 7| [Class] C2
# 9| [Class] C3
#-----| 3: (Base types)
# 9| 1: [TypeMention] I2
# 11| [Interface] IC
# 13| [Class] C4<>
#-----| 1: (Type parameters)
# 13| 0: [TypeParameter] T
# 15| [Class] C5<>
#-----| 1: (Type parameters)
# 15| 0: [TypeParameter] S
#-----| 3: (Base types)
# 15| 0: [TypeMention] C4<S>
# 15| 1: [TypeMention] S
# 17| [Struct] S1
# 19| [Enum] E1
# 21| [DelegateType] D1
# 23| [RecordClass] R1
# 23| 12: [NEOperator] !=
#-----| 2: (Parameters)
# 23| 0: [Parameter] left
# 23| 1: [Parameter] right
# 23| 13: [EQOperator] ==
#-----| 2: (Parameters)
# 23| 0: [Parameter] left
# 23| 1: [Parameter] right
# 23| 14: [Property] EqualityContract
# 23| 3: [Getter] get_EqualityContract
# 25| [RecordStruct] RS1
# 25| 10: [NEOperator] !=
#-----| 2: (Parameters)
# 25| 0: [Parameter] left
# 25| 1: [Parameter] right
# 25| 11: [EQOperator] ==
#-----| 2: (Parameters)
# 25| 0: [Parameter] left
# 25| 1: [Parameter] right
FileScoped2.cs:
# 1| [Interface] I1
# 3| [Interface] I2
# 5| [Class] C1
# 7| [Class] C2
#-----| 3: (Base types)
# 7| 1: [TypeMention] I2
# 9| [Class] IC
# 11| [Class] C4<>
#-----| 1: (Type parameters)
# 11| 0: [TypeParameter] T
# 13| [Class] C5<>
#-----| 1: (Type parameters)
# 13| 0: [TypeParameter] S
#-----| 3: (Base types)
# 13| 0: [TypeMention] C4<S>
# 13| 1: [TypeMention] S
# 15| [Struct] S1
# 17| [Enum] E1
# 19| [DelegateType] D1
# 21| [RecordClass] R1
# 21| 12: [NEOperator] !=
#-----| 2: (Parameters)
# 21| 0: [Parameter] left
# 21| 1: [Parameter] right
# 21| 13: [EQOperator] ==
#-----| 2: (Parameters)
# 21| 0: [Parameter] left
# 21| 1: [Parameter] right
# 21| 14: [Property] EqualityContract
# 21| 3: [Getter] get_EqualityContract
# 23| [RecordStruct] RS1
# 23| 10: [NEOperator] !=
#-----| 2: (Parameters)
# 23| 0: [Parameter] left
# 23| 1: [Parameter] right
# 23| 11: [EQOperator] ==
#-----| 2: (Parameters)
# 23| 0: [Parameter] left
# 23| 1: [Parameter] right
FileScoped3.cs:
# 1| [NamespaceDeclaration] namespace ... { ... }
# 3| 1: [Interface] I10
# 5| 2: [Class] C10
# 7| 3: [Class] C11
#-----| 3: (Base types)
# 7| 1: [TypeMention] I10
FileScoped4.cs:
# 1| [NamespaceDeclaration] namespace ... { ... }
# 3| 1: [Interface] I10
# 5| 2: [Class] C10
# 7| 3: [Class] C11
#-----| 3: (Base types)
# 7| 1: [TypeMention] I10
GenericAttribute.cs:
# 3| [GenericAssemblyAttribute] [assembly: MyGeneric<Int32>(...)]
# 3| 0: [TypeMention] MyGenericAttribute<int>
@@ -954,14 +1051,14 @@ StaticInterfaceMembers.cs:
# 5| 0: [Parameter] other
# 5| -1: [TypeMention] T
# 5| 4: [ParameterAccess] access to parameter other
# 7| 6: [Method] Add
# 7| 6: [AddOperator] +
# 7| -1: [TypeMention] T
#-----| 2: (Parameters)
# 7| 0: [Parameter] left
# 7| -1: [TypeMention] T
# 7| 1: [Parameter] right
# 7| -1: [TypeMention] T
# 9| 7: [Method] Subtract
# 9| 7: [SubOperator] -
# 9| -1: [TypeMention] T
#-----| 2: (Parameters)
# 9| 0: [Parameter] left
@@ -969,121 +1066,265 @@ StaticInterfaceMembers.cs:
# 9| 1: [Parameter] right
# 9| -1: [TypeMention] T
# 9| 4: [ParameterAccess] access to parameter left
# 11| 8: [Method] Zero
# 11| -1: [TypeMention] T
# 11| 4: [DefaultValueExpr] default(...)
# 11| 0: [TypeAccess] access to type T
# 11| 0: [TypeMention] T
# 14| [Class] Complex
# 11| 8: [ExplicitConversionOperator] explicit conversion
# 11| -1: [TypeMention] int
#-----| 2: (Parameters)
# 11| 0: [Parameter] n
# 11| -1: [TypeMention] T
# 13| 9: [ExplicitConversionOperator] explicit conversion
# 13| -1: [TypeMention] short
#-----| 2: (Parameters)
# 13| 0: [Parameter] n
# 13| -1: [TypeMention] T
# 15| 10: [Method] Inc
# 15| -1: [TypeMention] T
#-----| 2: (Parameters)
# 15| 0: [Parameter] other
# 15| -1: [TypeMention] T
# 17| 11: [Method] Dec
# 17| -1: [TypeMention] T
#-----| 2: (Parameters)
# 17| 0: [Parameter] other
# 17| -1: [TypeMention] T
# 17| 4: [ParameterAccess] access to parameter other
# 19| 12: [Method] Add
# 19| -1: [TypeMention] T
#-----| 2: (Parameters)
# 19| 0: [Parameter] left
# 19| -1: [TypeMention] T
# 19| 1: [Parameter] right
# 19| -1: [TypeMention] T
# 21| 13: [Method] Subtract
# 21| -1: [TypeMention] T
#-----| 2: (Parameters)
# 21| 0: [Parameter] left
# 21| -1: [TypeMention] T
# 21| 1: [Parameter] right
# 21| -1: [TypeMention] T
# 21| 4: [ParameterAccess] access to parameter left
# 23| 14: [Method] Zero
# 23| -1: [TypeMention] T
# 23| 4: [DefaultValueExpr] default(...)
# 23| 0: [TypeAccess] access to type T
# 23| 0: [TypeMention] T
# 26| [Class] Complex
#-----| 3: (Base types)
# 16| 4: [Property] Real
# 16| -1: [TypeMention] double
# 16| 2: [AssignExpr] ... = ...
# 16| 0: [PropertyCall] access to property Real
# 16| 1: [DoubleLiteral] 0
# 16| 3: [Getter] get_Real
# 16| 4: [Setter] set_Real
# 28| 4: [Property] Real
# 28| -1: [TypeMention] double
# 28| 2: [AssignExpr] ... = ...
# 28| 0: [PropertyCall] access to property Real
# 28| 1: [DoubleLiteral] 0
# 28| 3: [Getter] get_Real
# 28| 4: [Setter] set_Real
#-----| 2: (Parameters)
# 16| 0: [Parameter] value
# 17| 5: [Property] Imaginary
# 17| -1: [TypeMention] double
# 17| 2: [AssignExpr] ... = ...
# 17| 0: [PropertyCall] access to property Imaginary
# 17| 1: [DoubleLiteral] 0
# 17| 3: [Getter] get_Imaginary
# 17| 4: [Setter] set_Imaginary
# 28| 0: [Parameter] value
# 29| 5: [Property] Imaginary
# 29| -1: [TypeMention] double
# 29| 2: [AssignExpr] ... = ...
# 29| 0: [PropertyCall] access to property Imaginary
# 29| 1: [DoubleLiteral] 0
# 29| 3: [Getter] get_Imaginary
# 29| 4: [Setter] set_Imaginary
#-----| 2: (Parameters)
# 17| 0: [Parameter] value
# 19| 6: [InstanceConstructor] Complex
# 19| 4: [BlockStmt] {...}
# 21| 7: [Method] Zero
# 21| -1: [TypeMention] Complex
# 21| 4: [ObjectCreation] object creation of type Complex
# 21| 0: [TypeMention] Complex
# 23| 8: [IncrementOperator] ++
# 23| -1: [TypeMention] Complex
#-----| 2: (Parameters)
# 23| 0: [Parameter] other
# 23| -1: [TypeMention] Complex
# 24| 4: [ObjectCreation] object creation of type Complex
# 24| -2: [TypeMention] Complex
# 24| -1: [ObjectInitializer] { ..., ... }
# 24| 0: [MemberInitializer] ... = ...
# 24| 0: [PropertyCall] access to property Real
# 24| 1: [AddExpr] ... + ...
# 24| 0: [PropertyCall] access to property Real
# 24| -1: [ParameterAccess] access to parameter other
# 24| 1: [DoubleLiteral] 1
# 24| 1: [MemberInitializer] ... = ...
# 24| 0: [PropertyCall] access to property Imaginary
# 24| 1: [PropertyCall] access to property Imaginary
# 24| -1: [ParameterAccess] access to parameter other
# 26| 9: [DecrementOperator] --
# 26| -1: [TypeMention] Complex
#-----| 2: (Parameters)
# 26| 0: [Parameter] other
# 26| -1: [TypeMention] Complex
# 27| 4: [ObjectCreation] object creation of type Complex
# 27| -2: [TypeMention] Complex
# 27| -1: [ObjectInitializer] { ..., ... }
# 27| 0: [MemberInitializer] ... = ...
# 27| 0: [PropertyCall] access to property Real
# 27| 1: [SubExpr] ... - ...
# 27| 0: [PropertyCall] access to property Real
# 27| -1: [ParameterAccess] access to parameter other
# 27| 1: [DoubleLiteral] 1
# 27| 1: [MemberInitializer] ... = ...
# 27| 0: [PropertyCall] access to property Imaginary
# 27| 1: [PropertyCall] access to property Imaginary
# 27| -1: [ParameterAccess] access to parameter other
# 29| 10: [Method] Add
# 29| -1: [TypeMention] Complex
#-----| 2: (Parameters)
# 29| 0: [Parameter] left
# 29| -1: [TypeMention] Complex
# 29| 1: [Parameter] right
# 29| -1: [TypeMention] Complex
# 30| 4: [ObjectCreation] object creation of type Complex
# 30| -2: [TypeMention] Complex
# 30| -1: [ObjectInitializer] { ..., ... }
# 30| 0: [MemberInitializer] ... = ...
# 30| 0: [PropertyCall] access to property Real
# 30| 1: [AddExpr] ... + ...
# 30| 0: [PropertyCall] access to property Real
# 30| -1: [ParameterAccess] access to parameter left
# 30| 1: [PropertyCall] access to property Real
# 30| -1: [ParameterAccess] access to parameter right
# 30| 1: [MemberInitializer] ... = ...
# 30| 0: [PropertyCall] access to property Imaginary
# 30| 1: [AddExpr] ... + ...
# 30| 0: [PropertyCall] access to property Imaginary
# 30| -1: [ParameterAccess] access to parameter left
# 30| 1: [PropertyCall] access to property Imaginary
# 30| -1: [ParameterAccess] access to parameter right
# 32| 11: [Method] Subtract
# 32| -1: [TypeMention] Complex
#-----| 2: (Parameters)
# 32| 0: [Parameter] left
# 32| -1: [TypeMention] Complex
# 32| 1: [Parameter] right
# 32| -1: [TypeMention] Complex
# 29| 0: [Parameter] value
# 31| 6: [InstanceConstructor] Complex
# 31| 4: [BlockStmt] {...}
# 33| 7: [Method] Zero
# 33| -1: [TypeMention] Complex
# 33| 4: [ObjectCreation] object creation of type Complex
# 33| -2: [TypeMention] Complex
# 33| -1: [ObjectInitializer] { ..., ... }
# 33| 0: [MemberInitializer] ... = ...
# 33| 0: [PropertyCall] access to property Real
# 33| 1: [SubExpr] ... - ...
# 33| 0: [PropertyCall] access to property Real
# 33| -1: [ParameterAccess] access to parameter left
# 33| 1: [PropertyCall] access to property Real
# 33| -1: [ParameterAccess] access to parameter right
# 33| 1: [MemberInitializer] ... = ...
# 33| 0: [PropertyCall] access to property Imaginary
# 33| 1: [SubExpr] ... - ...
# 33| 0: [PropertyCall] access to property Imaginary
# 33| -1: [ParameterAccess] access to parameter left
# 33| 1: [PropertyCall] access to property Imaginary
# 33| -1: [ParameterAccess] access to parameter right
# 33| 0: [TypeMention] Complex
# 35| 8: [IncrementOperator] ++
# 35| -1: [TypeMention] Complex
#-----| 2: (Parameters)
# 35| 0: [Parameter] other
# 35| -1: [TypeMention] Complex
# 36| 4: [ObjectCreation] object creation of type Complex
# 36| -2: [TypeMention] Complex
# 36| -1: [ObjectInitializer] { ..., ... }
# 36| 0: [MemberInitializer] ... = ...
# 36| 0: [PropertyCall] access to property Real
# 36| 1: [AddExpr] ... + ...
# 36| 0: [PropertyCall] access to property Real
# 36| -1: [ParameterAccess] access to parameter other
# 36| 1: [DoubleLiteral] 1
# 36| 1: [MemberInitializer] ... = ...
# 36| 0: [PropertyCall] access to property Imaginary
# 36| 1: [PropertyCall] access to property Imaginary
# 36| -1: [ParameterAccess] access to parameter other
# 38| 9: [DecrementOperator] --
# 38| -1: [TypeMention] Complex
#-----| 2: (Parameters)
# 38| 0: [Parameter] other
# 38| -1: [TypeMention] Complex
# 39| 4: [ObjectCreation] object creation of type Complex
# 39| -2: [TypeMention] Complex
# 39| -1: [ObjectInitializer] { ..., ... }
# 39| 0: [MemberInitializer] ... = ...
# 39| 0: [PropertyCall] access to property Real
# 39| 1: [SubExpr] ... - ...
# 39| 0: [PropertyCall] access to property Real
# 39| -1: [ParameterAccess] access to parameter other
# 39| 1: [DoubleLiteral] 1
# 39| 1: [MemberInitializer] ... = ...
# 39| 0: [PropertyCall] access to property Imaginary
# 39| 1: [PropertyCall] access to property Imaginary
# 39| -1: [ParameterAccess] access to parameter other
# 41| 10: [AddOperator] +
# 41| -1: [TypeMention] Complex
#-----| 2: (Parameters)
# 41| 0: [Parameter] left
# 41| -1: [TypeMention] Complex
# 41| 1: [Parameter] right
# 41| -1: [TypeMention] Complex
# 42| 4: [ObjectCreation] object creation of type Complex
# 42| -2: [TypeMention] Complex
# 42| -1: [ObjectInitializer] { ..., ... }
# 42| 0: [MemberInitializer] ... = ...
# 42| 0: [PropertyCall] access to property Real
# 42| 1: [AddExpr] ... + ...
# 42| 0: [PropertyCall] access to property Real
# 42| -1: [ParameterAccess] access to parameter left
# 42| 1: [PropertyCall] access to property Real
# 42| -1: [ParameterAccess] access to parameter right
# 42| 1: [MemberInitializer] ... = ...
# 42| 0: [PropertyCall] access to property Imaginary
# 42| 1: [AddExpr] ... + ...
# 42| 0: [PropertyCall] access to property Imaginary
# 42| -1: [ParameterAccess] access to parameter left
# 42| 1: [PropertyCall] access to property Imaginary
# 42| -1: [ParameterAccess] access to parameter right
# 44| 11: [SubOperator] -
# 44| -1: [TypeMention] Complex
#-----| 2: (Parameters)
# 44| 0: [Parameter] left
# 44| -1: [TypeMention] Complex
# 44| 1: [Parameter] right
# 44| -1: [TypeMention] Complex
# 45| 4: [ObjectCreation] object creation of type Complex
# 45| -2: [TypeMention] Complex
# 45| -1: [ObjectInitializer] { ..., ... }
# 45| 0: [MemberInitializer] ... = ...
# 45| 0: [PropertyCall] access to property Real
# 45| 1: [SubExpr] ... - ...
# 45| 0: [PropertyCall] access to property Real
# 45| -1: [ParameterAccess] access to parameter left
# 45| 1: [PropertyCall] access to property Real
# 45| -1: [ParameterAccess] access to parameter right
# 45| 1: [MemberInitializer] ... = ...
# 45| 0: [PropertyCall] access to property Imaginary
# 45| 1: [SubExpr] ... - ...
# 45| 0: [PropertyCall] access to property Imaginary
# 45| -1: [ParameterAccess] access to parameter left
# 45| 1: [PropertyCall] access to property Imaginary
# 45| -1: [ParameterAccess] access to parameter right
# 47| 12: [ExplicitConversionOperator] explicit conversion
# 47| -1: [TypeMention] int
#-----| 2: (Parameters)
# 47| 0: [Parameter] n
# 47| -1: [TypeMention] Complex
# 47| 4: [CastExpr] (...) ...
# 47| 0: [TypeAccess] access to type Int32
# 47| 0: [TypeMention] int
# 47| 1: [PropertyCall] access to property Real
# 47| -1: [ParameterAccess] access to parameter n
# 49| 13: [ExplicitConversionOperator] explicit conversion
# 49| -1: [TypeMention] short
#-----| 2: (Parameters)
# 49| 0: [Parameter] n
# 49| -1: [TypeMention] Complex
# 49| 4: [CastExpr] (...) ...
# 49| 0: [TypeAccess] access to type Int16
# 49| 0: [TypeMention] short
# 49| 1: [PropertyCall] access to property Real
# 49| -1: [ParameterAccess] access to parameter n
# 51| 14: [Method] Inc
# 51| -1: [TypeMention] Complex
# 51| -1: [TypeMention] INumber<Complex>
# 51| 1: [TypeMention] Complex
#-----| 2: (Parameters)
# 51| 0: [Parameter] other
# 51| -1: [TypeMention] Complex
# 52| 4: [ObjectCreation] object creation of type Complex
# 52| -2: [TypeMention] Complex
# 52| -1: [ObjectInitializer] { ..., ... }
# 52| 0: [MemberInitializer] ... = ...
# 52| 0: [PropertyCall] access to property Real
# 52| 1: [AddExpr] ... + ...
# 52| 0: [PropertyCall] access to property Real
# 52| -1: [ParameterAccess] access to parameter other
# 52| 1: [DoubleLiteral] 1
# 52| 1: [MemberInitializer] ... = ...
# 52| 0: [PropertyCall] access to property Imaginary
# 52| 1: [PropertyCall] access to property Imaginary
# 52| -1: [ParameterAccess] access to parameter other
# 54| 15: [Method] Dec
# 54| -1: [TypeMention] Complex
# 54| -1: [TypeMention] INumber<Complex>
# 54| 1: [TypeMention] Complex
#-----| 2: (Parameters)
# 54| 0: [Parameter] other
# 54| -1: [TypeMention] Complex
# 55| 4: [ObjectCreation] object creation of type Complex
# 55| -2: [TypeMention] Complex
# 55| -1: [ObjectInitializer] { ..., ... }
# 55| 0: [MemberInitializer] ... = ...
# 55| 0: [PropertyCall] access to property Real
# 55| 1: [SubExpr] ... - ...
# 55| 0: [PropertyCall] access to property Real
# 55| -1: [ParameterAccess] access to parameter other
# 55| 1: [DoubleLiteral] 1
# 55| 1: [MemberInitializer] ... = ...
# 55| 0: [PropertyCall] access to property Imaginary
# 55| 1: [PropertyCall] access to property Imaginary
# 55| -1: [ParameterAccess] access to parameter other
# 57| 16: [Method] Add
# 57| -1: [TypeMention] Complex
#-----| 2: (Parameters)
# 57| 0: [Parameter] left
# 57| -1: [TypeMention] Complex
# 57| 1: [Parameter] right
# 57| -1: [TypeMention] Complex
# 58| 4: [ObjectCreation] object creation of type Complex
# 58| -2: [TypeMention] Complex
# 58| -1: [ObjectInitializer] { ..., ... }
# 58| 0: [MemberInitializer] ... = ...
# 58| 0: [PropertyCall] access to property Real
# 58| 1: [AddExpr] ... + ...
# 58| 0: [PropertyCall] access to property Real
# 58| -1: [ParameterAccess] access to parameter left
# 58| 1: [PropertyCall] access to property Real
# 58| -1: [ParameterAccess] access to parameter right
# 58| 1: [MemberInitializer] ... = ...
# 58| 0: [PropertyCall] access to property Imaginary
# 58| 1: [AddExpr] ... + ...
# 58| 0: [PropertyCall] access to property Imaginary
# 58| -1: [ParameterAccess] access to parameter left
# 58| 1: [PropertyCall] access to property Imaginary
# 58| -1: [ParameterAccess] access to parameter right
# 60| 17: [Method] Subtract
# 60| -1: [TypeMention] Complex
#-----| 2: (Parameters)
# 60| 0: [Parameter] left
# 60| -1: [TypeMention] Complex
# 60| 1: [Parameter] right
# 60| -1: [TypeMention] Complex
# 61| 4: [ObjectCreation] object creation of type Complex
# 61| -2: [TypeMention] Complex
# 61| -1: [ObjectInitializer] { ..., ... }
# 61| 0: [MemberInitializer] ... = ...
# 61| 0: [PropertyCall] access to property Real
# 61| 1: [SubExpr] ... - ...
# 61| 0: [PropertyCall] access to property Real
# 61| -1: [ParameterAccess] access to parameter left
# 61| 1: [PropertyCall] access to property Real
# 61| -1: [ParameterAccess] access to parameter right
# 61| 1: [MemberInitializer] ... = ...
# 61| 0: [PropertyCall] access to property Imaginary
# 61| 1: [SubExpr] ... - ...
# 61| 0: [PropertyCall] access to property Imaginary
# 61| -1: [ParameterAccess] access to parameter left
# 61| 1: [PropertyCall] access to property Imaginary
# 61| -1: [ParameterAccess] access to parameter right
Strings.cs:
# 3| [Class] MyTestClass
# 5| 5: [Method] M1

View File

@@ -4,6 +4,18 @@ public interface INumber<T> where T : INumber<T>
static virtual T operator --(T other) => other;
static abstract T operator +(T left, T right);
static virtual T operator -(T left, T right) => left;
static abstract explicit operator int(T n);
static abstract explicit operator short(T n);
static abstract T Inc(T other);
static virtual T Dec(T other) => other;
static abstract T Add(T left, T right);
static virtual T Subtract(T left, T right) => left;
@@ -26,6 +38,22 @@ public class Complex : INumber<Complex>
public static Complex operator --(Complex other) =>
new Complex { Real = other.Real - 1.0, Imaginary = other.Imaginary };
static Complex INumber<Complex>.operator +(Complex left, Complex right) =>
new Complex { Real = left.Real + right.Real, Imaginary = left.Imaginary + right.Imaginary };
static Complex INumber<Complex>.operator -(Complex left, Complex right) =>
new Complex { Real = left.Real - right.Real, Imaginary = left.Imaginary - right.Imaginary };
public static explicit operator int(Complex n) => (int)n.Real;
static explicit INumber<Complex>.operator short(Complex n) => (short)n.Real;
static Complex INumber<Complex>.Inc(Complex other) =>
new Complex { Real = other.Real + 1.0, Imaginary = other.Imaginary };
static Complex INumber<Complex>.Dec(Complex other) =>
new Complex { Real = other.Real - 1.0, Imaginary = other.Imaginary };
public static Complex Add(Complex left, Complex right) =>
new Complex { Real = left.Real + right.Real, Imaginary = left.Imaginary + right.Imaginary };

View File

@@ -0,0 +1,116 @@
typemodifiers
| FileScoped1.cs:1:16:1:17 | I1 | file |
| FileScoped1.cs:3:16:3:17 | I2 | file |
| FileScoped1.cs:5:12:5:13 | C1 | file |
| FileScoped1.cs:7:14:7:15 | C2 | public |
| FileScoped1.cs:9:14:9:15 | C3 | public |
| FileScoped1.cs:11:16:11:17 | IC | file |
| FileScoped1.cs:13:12:13:16 | C4<> | file |
| FileScoped1.cs:13:12:13:16 | C4<S> | file |
| FileScoped1.cs:15:12:15:16 | C5<> | file |
| FileScoped1.cs:17:13:17:14 | S1 | file |
| FileScoped1.cs:17:13:17:14 | S1 | sealed |
| FileScoped1.cs:19:11:19:12 | E1 | file |
| FileScoped1.cs:19:11:19:12 | E1 | sealed |
| FileScoped1.cs:21:20:21:21 | D1 | file |
| FileScoped1.cs:21:20:21:21 | D1 | sealed |
| FileScoped1.cs:23:1:23:18 | R1 | file |
| FileScoped1.cs:23:1:23:18 | R1 | record |
| FileScoped1.cs:25:1:25:26 | RS1 | file |
| FileScoped1.cs:25:1:25:26 | RS1 | record |
| FileScoped1.cs:25:1:25:26 | RS1 | sealed |
| FileScoped2.cs:1:16:1:17 | I1 | file |
| FileScoped2.cs:3:18:3:19 | I2 | public |
| FileScoped2.cs:5:12:5:13 | C1 | file |
| FileScoped2.cs:7:12:7:13 | C2 | file |
| FileScoped2.cs:9:12:9:13 | IC | file |
| FileScoped2.cs:11:12:11:16 | C4<> | file |
| FileScoped2.cs:11:12:11:16 | C4<S> | file |
| FileScoped2.cs:13:12:13:16 | C5<> | file |
| FileScoped2.cs:15:13:15:14 | S1 | file |
| FileScoped2.cs:15:13:15:14 | S1 | sealed |
| FileScoped2.cs:17:11:17:12 | E1 | file |
| FileScoped2.cs:17:11:17:12 | E1 | sealed |
| FileScoped2.cs:19:20:19:21 | D1 | file |
| FileScoped2.cs:19:20:19:21 | D1 | sealed |
| FileScoped2.cs:21:1:21:18 | R1 | file |
| FileScoped2.cs:21:1:21:18 | R1 | record |
| FileScoped2.cs:23:1:23:26 | RS1 | file |
| FileScoped2.cs:23:1:23:26 | RS1 | record |
| FileScoped2.cs:23:1:23:26 | RS1 | sealed |
| FileScoped3.cs:3:16:3:18 | I10 | file |
| FileScoped3.cs:5:12:5:14 | C10 | file |
| FileScoped3.cs:7:14:7:16 | C11 | public |
| FileScoped4.cs:3:18:3:20 | I10 | public |
| FileScoped4.cs:5:12:5:14 | C10 | file |
| FileScoped4.cs:7:12:7:14 | C11 | file |
qualifiedtypes
| FileScoped1.cs:1:16:1:17 | I1 | I1 |
| FileScoped1.cs:3:16:3:17 | I2 | I2 |
| FileScoped1.cs:5:12:5:13 | C1 | C1 |
| FileScoped1.cs:7:14:7:15 | C2 | C2 |
| FileScoped1.cs:9:14:9:15 | C3 | C3 |
| FileScoped1.cs:11:16:11:17 | IC | IC |
| FileScoped1.cs:13:12:13:16 | C4<> | C4<> |
| FileScoped1.cs:13:12:13:16 | C4<S> | C4<S> |
| FileScoped1.cs:15:12:15:16 | C5<> | C5<> |
| FileScoped1.cs:17:13:17:14 | S1 | S1 |
| FileScoped1.cs:19:11:19:12 | E1 | E1 |
| FileScoped1.cs:21:20:21:21 | D1 | D1 |
| FileScoped1.cs:23:1:23:18 | R1 | R1 |
| FileScoped1.cs:25:1:25:26 | RS1 | RS1 |
| FileScoped2.cs:1:16:1:17 | I1 | I1 |
| FileScoped2.cs:3:18:3:19 | I2 | I2 |
| FileScoped2.cs:5:12:5:13 | C1 | C1 |
| FileScoped2.cs:7:12:7:13 | C2 | C2 |
| FileScoped2.cs:9:12:9:13 | IC | IC |
| FileScoped2.cs:11:12:11:16 | C4<> | C4<> |
| FileScoped2.cs:11:12:11:16 | C4<S> | C4<S> |
| FileScoped2.cs:13:12:13:16 | C5<> | C5<> |
| FileScoped2.cs:15:13:15:14 | S1 | S1 |
| FileScoped2.cs:17:11:17:12 | E1 | E1 |
| FileScoped2.cs:19:20:19:21 | D1 | D1 |
| FileScoped2.cs:21:1:21:18 | R1 | R1 |
| FileScoped2.cs:23:1:23:26 | RS1 | RS1 |
| FileScoped3.cs:3:16:3:18 | I10 | TestFileScoped.I10 |
| FileScoped3.cs:5:12:5:14 | C10 | TestFileScoped.C10 |
| FileScoped3.cs:7:14:7:16 | C11 | TestFileScoped.C11 |
| FileScoped4.cs:3:18:3:20 | I10 | TestFileScoped.I10 |
| FileScoped4.cs:5:12:5:14 | C10 | TestFileScoped.C10 |
| FileScoped4.cs:7:12:7:14 | C11 | TestFileScoped.C11 |
filetypes
| FileScoped1.cs:1:16:1:17 | I1 |
| FileScoped1.cs:3:16:3:17 | I2 |
| FileScoped1.cs:5:12:5:13 | C1 |
| FileScoped1.cs:11:16:11:17 | IC |
| FileScoped1.cs:13:12:13:16 | C4<> |
| FileScoped1.cs:13:12:13:16 | C4<S> |
| FileScoped1.cs:15:12:15:16 | C5<> |
| FileScoped1.cs:17:13:17:14 | S1 |
| FileScoped1.cs:19:11:19:12 | E1 |
| FileScoped1.cs:21:20:21:21 | D1 |
| FileScoped1.cs:23:1:23:18 | R1 |
| FileScoped1.cs:25:1:25:26 | RS1 |
| FileScoped2.cs:1:16:1:17 | I1 |
| FileScoped2.cs:5:12:5:13 | C1 |
| FileScoped2.cs:7:12:7:13 | C2 |
| FileScoped2.cs:9:12:9:13 | IC |
| FileScoped2.cs:11:12:11:16 | C4<> |
| FileScoped2.cs:11:12:11:16 | C4<S> |
| FileScoped2.cs:13:12:13:16 | C5<> |
| FileScoped2.cs:15:13:15:14 | S1 |
| FileScoped2.cs:17:11:17:12 | E1 |
| FileScoped2.cs:19:20:19:21 | D1 |
| FileScoped2.cs:21:1:21:18 | R1 |
| FileScoped2.cs:23:1:23:26 | RS1 |
| FileScoped3.cs:3:16:3:18 | I10 |
| FileScoped3.cs:5:12:5:14 | C10 |
| FileScoped4.cs:5:12:5:14 | C10 |
| FileScoped4.cs:7:12:7:14 | C11 |
internaltypes
publictypes
| FileScoped1.cs:7:14:7:15 | C2 |
| FileScoped1.cs:9:14:9:15 | C3 |
| FileScoped2.cs:3:18:3:19 | I2 |
| FileScoped3.cs:7:14:7:16 | C11 |
| FileScoped4.cs:3:18:3:20 | I10 |

View File

@@ -0,0 +1,42 @@
import csharp
private import semmle.code.csharp.commons.QualifiedName
private predicate isInteresting(Type t) {
(
t instanceof Class or
t instanceof Interface or
t instanceof Struct or
t instanceof Enum or
t instanceof DelegateType or
t instanceof RecordType
) and
t.getFile().getStem().matches("FileScoped%")
}
query predicate typemodifiers(Type t, string modifier) {
isInteresting(t) and
t.(Modifiable).hasModifier(modifier)
}
query predicate qualifiedtypes(Type t, string qualifiedName) {
isInteresting(t) and
exists(string qualifier, string name |
t.hasQualifiedName(qualifier, name) and
qualifiedName = getQualifiedName(qualifier, name)
)
}
query predicate filetypes(Type t) {
isInteresting(t) and
t.isFile()
}
query predicate internaltypes(Type t) {
isInteresting(t) and
t.isInternal()
}
query predicate publictypes(Type t) {
isInteresting(t) and
t.isPublic()
}

View File

@@ -5,16 +5,55 @@ interfacemembers
| INumber<> | StaticInterfaceMembers.cs:5:31:5:32 | -- | public |
| INumber<> | StaticInterfaceMembers.cs:5:31:5:32 | -- | static |
| INumber<> | StaticInterfaceMembers.cs:5:31:5:32 | -- | virtual |
| INumber<> | StaticInterfaceMembers.cs:7:23:7:25 | Add | abstract |
| INumber<> | StaticInterfaceMembers.cs:7:23:7:25 | Add | public |
| INumber<> | StaticInterfaceMembers.cs:7:23:7:25 | Add | static |
| INumber<> | StaticInterfaceMembers.cs:9:22:9:29 | Subtract | public |
| INumber<> | StaticInterfaceMembers.cs:9:22:9:29 | Subtract | static |
| INumber<> | StaticInterfaceMembers.cs:9:22:9:29 | Subtract | virtual |
| INumber<> | StaticInterfaceMembers.cs:11:14:11:17 | Zero | public |
| INumber<> | StaticInterfaceMembers.cs:11:14:11:17 | Zero | static |
| INumber<> | StaticInterfaceMembers.cs:7:32:7:32 | + | abstract |
| INumber<> | StaticInterfaceMembers.cs:7:32:7:32 | + | public |
| INumber<> | StaticInterfaceMembers.cs:7:32:7:32 | + | static |
| INumber<> | StaticInterfaceMembers.cs:9:31:9:31 | - | public |
| INumber<> | StaticInterfaceMembers.cs:9:31:9:31 | - | static |
| INumber<> | StaticInterfaceMembers.cs:9:31:9:31 | - | virtual |
| INumber<> | StaticInterfaceMembers.cs:11:30:11:37 | explicit conversion | abstract |
| INumber<> | StaticInterfaceMembers.cs:11:30:11:37 | explicit conversion | public |
| INumber<> | StaticInterfaceMembers.cs:11:30:11:37 | explicit conversion | static |
| INumber<> | StaticInterfaceMembers.cs:13:30:13:37 | explicit conversion | abstract |
| INumber<> | StaticInterfaceMembers.cs:13:30:13:37 | explicit conversion | public |
| INumber<> | StaticInterfaceMembers.cs:13:30:13:37 | explicit conversion | static |
| INumber<> | StaticInterfaceMembers.cs:15:23:15:25 | Inc | abstract |
| INumber<> | StaticInterfaceMembers.cs:15:23:15:25 | Inc | public |
| INumber<> | StaticInterfaceMembers.cs:15:23:15:25 | Inc | static |
| INumber<> | StaticInterfaceMembers.cs:17:22:17:24 | Dec | public |
| INumber<> | StaticInterfaceMembers.cs:17:22:17:24 | Dec | static |
| INumber<> | StaticInterfaceMembers.cs:17:22:17:24 | Dec | virtual |
| INumber<> | StaticInterfaceMembers.cs:19:23:19:25 | Add | abstract |
| INumber<> | StaticInterfaceMembers.cs:19:23:19:25 | Add | public |
| INumber<> | StaticInterfaceMembers.cs:19:23:19:25 | Add | static |
| INumber<> | StaticInterfaceMembers.cs:21:22:21:29 | Subtract | public |
| INumber<> | StaticInterfaceMembers.cs:21:22:21:29 | Subtract | static |
| INumber<> | StaticInterfaceMembers.cs:21:22:21:29 | Subtract | virtual |
| INumber<> | StaticInterfaceMembers.cs:23:14:23:17 | Zero | public |
| INumber<> | StaticInterfaceMembers.cs:23:14:23:17 | Zero | static |
implements
| StaticInterfaceMembers.cs:23:36:23:37 | ++ | StaticInterfaceMembers.cs:3:32:3:33 | ++ |
| StaticInterfaceMembers.cs:26:36:26:37 | -- | StaticInterfaceMembers.cs:5:31:5:32 | -- |
| StaticInterfaceMembers.cs:29:27:29:29 | Add | StaticInterfaceMembers.cs:7:23:7:25 | Add |
| StaticInterfaceMembers.cs:32:27:32:34 | Subtract | StaticInterfaceMembers.cs:9:22:9:29 | Subtract |
| StaticInterfaceMembers.cs:35:36:35:37 | ++ | StaticInterfaceMembers.cs:3:32:3:33 | ++ |
| StaticInterfaceMembers.cs:38:36:38:37 | -- | StaticInterfaceMembers.cs:5:31:5:32 | -- |
| StaticInterfaceMembers.cs:41:46:41:46 | + | StaticInterfaceMembers.cs:7:32:7:32 | + |
| StaticInterfaceMembers.cs:44:46:44:46 | - | StaticInterfaceMembers.cs:9:31:9:31 | - |
| StaticInterfaceMembers.cs:47:28:47:35 | explicit conversion | StaticInterfaceMembers.cs:11:30:11:37 | explicit conversion |
| StaticInterfaceMembers.cs:49:38:49:45 | explicit conversion | StaticInterfaceMembers.cs:13:30:13:37 | explicit conversion |
| StaticInterfaceMembers.cs:51:37:51:39 | Inc | StaticInterfaceMembers.cs:15:23:15:25 | Inc |
| StaticInterfaceMembers.cs:54:37:54:39 | Dec | StaticInterfaceMembers.cs:17:22:17:24 | Dec |
| StaticInterfaceMembers.cs:57:27:57:29 | Add | StaticInterfaceMembers.cs:19:23:19:25 | Add |
| StaticInterfaceMembers.cs:60:27:60:34 | Subtract | StaticInterfaceMembers.cs:21:22:21:29 | Subtract |
publicmembers
| StaticInterfaceMembers.cs:28:19:28:22 | Real |
| StaticInterfaceMembers.cs:29:19:29:27 | Imaginary |
| StaticInterfaceMembers.cs:31:12:31:18 | Complex |
| StaticInterfaceMembers.cs:33:27:33:30 | Zero |
| StaticInterfaceMembers.cs:35:36:35:37 | ++ |
| StaticInterfaceMembers.cs:38:36:38:37 | -- |
| StaticInterfaceMembers.cs:41:46:41:46 | + |
| StaticInterfaceMembers.cs:44:46:44:46 | - |
| StaticInterfaceMembers.cs:47:28:47:35 | explicit conversion |
| StaticInterfaceMembers.cs:49:38:49:45 | explicit conversion |
| StaticInterfaceMembers.cs:51:37:51:39 | Inc |
| StaticInterfaceMembers.cs:54:37:54:39 | Dec |
| StaticInterfaceMembers.cs:57:27:57:29 | Add |
| StaticInterfaceMembers.cs:60:27:60:34 | Subtract |

View File

@@ -16,3 +16,9 @@ query predicate implements(Overridable o, Virtualizable v) {
v.isStatic() and
v.getAnImplementor() = o
}
query predicate publicmembers(Member m) {
m.getFile().getStem() = "StaticInterfaceMembers" and
m.getDeclaringType().getName() = "Complex" and
m.isPublic()
}

View File

@@ -26,4 +26,21 @@ class StaticFields
staticField = 0; // BAD
instanceField = 0; // OK
}
static object backingField;
static object StaticProp
{
get
{
return backingField ?? (backingField = new object()); // OK
}
}
object Prop
{
get
{
return backingField ?? (backingField = new object()); // BAD
}
}
}

View File

@@ -1,2 +1,3 @@
| StaticFieldWrittenByInstance.cs:15:9:15:19 | access to field staticField | Write to static field from instance method or constructor. |
| StaticFieldWrittenByInstance.cs:26:9:26:19 | access to field staticField | Write to static field from instance method or constructor. |
| StaticFieldWrittenByInstance.cs:15:9:15:19 | access to field staticField | Write to static field from instance method, property, or constructor. |
| StaticFieldWrittenByInstance.cs:26:9:26:19 | access to field staticField | Write to static field from instance method, property, or constructor. |
| StaticFieldWrittenByInstance.cs:43:37:43:48 | access to field backingField | Write to static field from instance method, property, or constructor. |

View File

@@ -14,7 +14,7 @@ CodeQL for Visual Studio Code provides an easy way to run queries from the large
With these queries, or your own custom queries, you can analyze databases generated from source code to find errors and security vulnerabilities.
The Results view shows the flow of data through the results of path queries, which is essential for triaging security results.
The CodeQL extension also adds a **CodeQL** sidebar view to VS Code. This contains a list of databases, and an overview of the queries that you have run in the current session.
The CodeQL extension also adds a **CodeQL** sidebar view to VS Code. This contains a list of local CodeQL databases, an overview of the queries that you have run in the current session, and a variant analysis view for large scale analysis.
The extension provides standard `IntelliSense <https://code.visualstudio.com/docs/editor/intellisense>`__
features for query files (extension ``.ql``) and library files (extension ``.qll``) that you open in the Visual Studio Code editor.
@@ -36,4 +36,5 @@ Further reading
-------------------
- ":doc:`Setting up CodeQL in Visual Studio Code <setting-up-codeql-in-visual-studio-code>`"
- ":doc:`Analyzing your projects <analyzing-your-projects>`"
- ":doc:`Analyzing your projects <analyzing-your-projects>`"
- ":doc:`Running CodeQL queries at scale with multi-repository variant analysis <running-codeql-queries-at-scale-with-mrva>`"

View File

@@ -5,7 +5,7 @@
Analyzing your projects
=================================================
You can run queries on CodeQL databases and view the results in Visual Studio Code.
You can run queries on CodeQL databases and view the results in Visual Studio Code. This article explains how to get a CodeQL database and analyze it on your local machine. For information on running analysis at scale across many CodeQL databases, see ":ref:`Running CodeQL queries at scale with multi-repository variant analysis <running-codeql-queries-at-scale-with-mrva>`."
Choosing a database
------------------------
@@ -24,8 +24,8 @@ To analyze a project, you need to add a :ref:`CodeQL database <codeql-database>`
#. Once you've chosen a database, it is displayed in the Databases view. To see the menu options for interacting with a database, right-click an entry in the list. You can select multiple databases using **Ctrl/Cmd+click**.
Obtaining a local database
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Importing a local database
~~~~~~~~~~~~~~~~~~~~~~~~~~
If you have a CodeQL database saved locally, as an unarchived folder or as a ZIP file, you can add it to Visual Studio Code. There are several ways to obtain a local CodeQL database.
@@ -37,6 +37,9 @@ If you have a CodeQL database saved locally, as an unarchived folder or as a ZIP
For more information about running query tests, see "`Testing custom queries <https://docs.github.com/en/code-security/codeql-cli/using-the-codeql-cli/testing-custom-queries>`__" in the CodeQL CLI help.
Downloading a database from GitHub
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. include:: ../reusables/download-github-database.rst
Running a query

View File

@@ -25,6 +25,8 @@ Editing settings
3. Edit a setting. The new settings are saved automatically.
Alternatively, you can edit the settings in JSON format by opening the command palette and selecting **Preferences: Open User Settings (JSON)**.
Choosing a version of the CodeQL CLI
--------------------------------------
@@ -55,8 +57,8 @@ By default, items in the query history view are retained for 30 days. You can se
.. _configuring-settings-for-running-queries:
Configuring settings for running queries
-----------------------------------------
Configuring settings for running queries locally
------------------------------------------------
There are a number of settings for **Running Queries**. If your queries run too slowly and time out frequently, you may want to increase the memory.
@@ -64,8 +66,49 @@ There are a number of settings for **Running Queries**. If your queries run too
To save query server logs in a custom location, edit the **Running Queries: Custom Log Directory** setting. If you use a custom log directory, the extension saves the logs permanently, instead of deleting them automatically after each workspace session. This is useful if you want to investigate these logs to improve the performance of your queries.
Configuring settings for testing queries
-----------------------------------------
Configuring settings for variant analysis
------------------------------------------
You can define or edit lists of GitHub repositories for variant analysis, and change to a different controller repository using the **Variant analysis** settings.
For information on the purpose and requirements for a controller repository, see ":ref:`Setting up a controller repository for variant analysis <controller-repository>`."
You can also edit the items shown in the Variant Analysis Repositories panel by editing a file in your Visual Studio Code workspace called ``databases.json``. This file contains a JSON representation of all the items displayed in the panel. To open your ``databases.json`` file in an editor window, click the **{ }** icon in the top right of the Variant Analysis Repositories panel. You can then see a structured representation of the repos, orgs and lists in your panel. For example:
.. code-block:: json
{
"version": 1,
"databases": {
"variantAnalysis": {
"repositoryLists": [
{
"name": "My favorite JavaScript repos",
"repositories": [
"facebook/react",
"babel/babel",
"angular/angular"
]
}
],
"owners": [
"microsoft"
],
"repositories": [
"apache/hadoop"
]
}
},
"selected": {
"kind": "variantAnalysisSystemDefinedList",
"listName": "top_10"
}
}
You can change the items shown in the panel or add new items by directly editing this file.
Configuring settings for testing queries locally
------------------------------------------------
To increase the number of threads used for testing queries, you can update the **Running Tests > Number Of Threads** setting.

View File

@@ -3,7 +3,7 @@
.. _exploring-data-flow-with-path-queries:
Exploring data flow with path queries
=================================================
=====================================
You can run CodeQL queries in VS Code to help you track the flow of data through a program, highlighting areas that are potential security vulnerabilities.
@@ -20,8 +20,8 @@ You can also modify the existing queries to model data flow more precisely for t
To ensure that your path query uses the correct format and metadata, follow the instructions in ":ref:`Creating path queries <creating-path-queries>`."
This topic also contains detailed information about how to define new sources and sinks, as well as templates and examples of how to extend the CodeQL libraries to suit your analysis.
Running path queries in VS Code
-----------------------------------
Running path queries in VS Code locally
---------------------------------------
#. Open a path query in the editor.
#. Right-click in the query window and select **CodeQL: Run Query on Selected Database**. (Alternatively, run the command from the Command Palette.)
@@ -30,6 +30,8 @@ Running path queries in VS Code
#. Click each step to jump to it in the source code and investigate the problem further.
#. To navigate the results from your keyboard, you can bind shortcuts to the **CodeQL: Navigate Up/Down/Left/Right in Result Viewer** commands.
When you are ready to run a path query at scale, you can use the Variant Analysis Repositories panel to run the query against up to 1,000 repositories on GitHub.com. For information on running analysis at scale across many CodeQL databases, see ":ref:`Running CodeQL queries at scale with multi-repository variant analysis <running-codeql-queries-at-scale-with-mrva>`."
Further reading
-----------------

View File

@@ -27,6 +27,11 @@ The CodeQL extension for Visual Studio Code adds rich language support for CodeQ
VS Code to help you track the flow of data through a program, highlighting
areas that are potential security vulnerabilities.
- :doc:`Running CodeQL queries at scale with multi-repository variant analysis
<running-codeql-queries-at-scale-with-mrva>`: You can run queries against groups
of repositories on GitHub.com and view results in Visual Studio Code as each analysis
finishes.
- :doc:`Testing CodeQL queries in Visual Studio Code
<testing-codeql-queries-in-visual-studio-code>`: You can run unit tests for
CodeQL queries using the Visual Studio Code extension.
@@ -40,7 +45,13 @@ The CodeQL extension for Visual Studio Code adds rich language support for CodeQ
- :doc:`Troubleshooting CodeQL for Visual Studio Code
<troubleshooting-codeql-for-visual-studio-code>`: You can use the detailed
information written to the extension's log files if you need to troubleshoot problems.
information written to the extension's log files if you need to troubleshoot problems with
analysis of local CodeQL databases.
- :doc:`Troubleshooting variant analysis
<troubleshooting-variant-analysis>`: You can use the detailed
information written to workflow log files in your controller repository if you need to
troubleshoot problems with analysis of CodeQL databases stored on GitHub.com.
- :doc:`About telemetry in CodeQL for Visual Studio Code <about-telemetry-in-codeql-for-visual-studio-code>`: If you specifically opt in to permit GitHub to do so, GitHub will collect usage data and metrics for the purposes of helping the core developers to improve the CodeQL extension for VS Code.
@@ -53,8 +64,10 @@ The CodeQL extension for Visual Studio Code adds rich language support for CodeQ
analyzing-your-projects
exploring-the-structure-of-your-source-code
exploring-data-flow-with-path-queries
running-codeql-queries-at-scale-with-mrva
testing-codeql-queries-in-visual-studio-code
working-with-codeql-packs-in-visual-studio-code
customizing-settings
troubleshooting-codeql-for-visual-studio-code
troubleshooting-variant-analysis
about-telemetry-in-codeql-for-visual-studio-code

View File

@@ -0,0 +1,163 @@
:tocdepth: 1
.. _running-codeql-queries-at-scale-with-mrva:
Running CodeQL queries at scale with multi-repository variant analysis
======================================================================
.. include:: ../reusables/beta-note-mrva.rst
About multi-repository variant analysis
---------------------------------------
When you write a query to find variants of a security vulnerability and finish testing it locally, the next step is to run it on a large group of repositories. Multi-repository variant analysis (variant analysis) makes it easy run a query on up to 1000 repositories without leaving Visual Studio Code.
The core functionality of the CodeQL extension helps you write queries and run them locally against a CodeQL database. In contrast, variant analysis allows you to send your CodeQL query to GitHub.com to be tested against a list of repositories.
When you run variant analysis against a list of repositories, your query is run against each repository that has a CodeQL database available to analyze. GitHub creates and stores the latest CodeQL database for the default branch of thousands of public repositories, including every repository that runs code scanning using CodeQL.
If you want to run variant analysis on your repositories, you need to enable code scanning using CodeQL on GitHub.com before adding your repository to a list for analysis (either default setup, or advanced setup using the CodeQL action). For information about enabling code scanning using CodeQL, see "`Configuring code scanning automatically <https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning-for-a-repository#configuring-code-scanning-automatically>`__."
.. _controller-repository:
Setting a controller repository for variant analysis
----------------------------------------------------
When you run variant analysis, the analysis is run entirely using GitHub Actions. You don't need to create any workflows, but you must specify which GitHub repository the CodeQL extension should use as the "controller repository." Controller repositories can be empty, but they must have at least one commit. The ``GITHUB_TOKEN`` must also have "Read and write permissions" to run workflows in that repository. For more information, see "`Managing GitHub Actions settings for a repository <https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository#setting-the-permissions-of-the-github_token-for-your-repository>`__."
.. pull-quote::
Note
- The controller repository visibility can be "public" if you plan to analyze public repositories. The variant analysis will be free.
- The controller repository visibility must be "private" if you need to analyze any private or internal repositories. Any actions minutes used by variant analysis, above the free limit, will be charged to the repository owner. For more information about free minutes and billing, see "`About billing for GitHub Actions <https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions>`__."
You must define a controller repository before you can run your first variant analysis.
.. image:: ../images/codeql-for-visual-studio-code/controller-repository.png
:width: 350
:alt: Screenshot of the CodeQL extension in Visual Studio Code. The "Variant Analysis Repositories" section is expanded and the "Set up controller repository" button is highlighted with a dark orange outline.
#. In Visual Studio Code, click **QL** in the left sidebar to display the CodeQL extension.
#. Expand **Variant Analysis Repositories** and click **Set up controller repository** to display a field for the controller repository.
#. Type the owner and name of the repository on GitHub.com that you want to use as your controller repository and press the **Enter** key.
#. If you are prompted to authenticate with GitHub, follow the instructions and sign into your personal or organization account. When you have finished following the process, a prompt from GitHub Authentication may ask for permission to open a URI in Visual Studio Code, click **Open**.
The name of the controller repository is saved in your settings for the CodeQL extension. For information on how to edit the controller repository, see ":ref:`Customizing settings <customizing-settings>`."
Running a query at scale using variant analysis
-----------------------------------------------
#. Expand the **Variant Analysis Repositories** section, to show the default lists which include a selection of 10, 100, and 1,000 public repositories on GitHub.com for the language that you are analyzing.
#. Select which GitHub repository or repositories you want to run your query against. Click a row to highlight it, and then click **Select** to select that repository, organization, or list of repositories. If you want to add a new repository, organization, or list, use the options in the header panel. For information, see ":ref:`Creating custom lists of repositories <custom-lists>`", later in this article.
.. image:: ../images/codeql-for-visual-studio-code/variant-analysis-repo-lists.png
:width: 350
:alt: Screenshot of the CodeQL extension in Visual Studio Code. The "Variant Analysis Repositories" section is expanded. The "Top 10 repositories" item has a checkmark to show that it is currently selected for analysis. The user has clicked on the row for a single repository "octo-org/octo-repo" and it is highlighted blue. The "Select" button for that row is highlighted with a dark orange highlight.
#. Open the query you want to run, right-click in the query file, and select **CodeQL: Run Variant Analysis** to start variant analysis.
The CodeQL extension builds a CodeQL pack with your library and any library dependencies. The CodeQL pack and your selected repository list are posted to an API endpoint on GitHub.com which triggers a GitHub Actions dynamic workflow in your controller repository. The workflow spins up multiple parallel jobs to execute the CodeQL query against the repositories in the list, optimizing query execution. As each repository is analyzed, the results are processed and displayed in a Variant Analysis Results view in Visual Studio Code.
.. pull-quote::
Note
If you need to cancel the variant analysis run for any reason, click **Stop query** in the Variant Analysis Results view.
Exploring your results
----------------------
When you run variant analysis, as soon as a workflow to run your analysis on GitHub is running, a Variant Analysis Results view opens to display the results as they are ready. You can use this view to monitor progress, see any errors, and access the workflow logs in your controller repository.
.. image:: ../images/codeql-for-visual-studio-code/variant-analysis-results-view.png
:alt: Screenshot of the "Variant Analysis Results" view showing a partially complete run. Analysis of ``angular/angular`` is still running but all other results are displayed. ``facebook/create-react-app`` has three results for this query.
When your variant analysis run is scheduled, the results view automatically opens. Initially the view shows a list of every repository that was scheduled for analysis. As each repository is analyzed, the view is updated to show a summary of the number of results. To view the detailed results for a repository (including results paths), click the repository name.
For each repository, you can see:
- Number of results found by the query
- Visibility of the repository
- Whether analysis is still running (black, moving circle) or finished (green checkmark)
- Number of stars the repository has on GitHub
- When the repository was last updated
To see the results for a repository:
.. image:: ../images/codeql-for-visual-studio-code/variant-analysis-result.png
:alt: Screenshot of an example result in the "Variant Analysis Results" view. The result has blue links to the source files in GitHub so you can go straight to the repository to fix the problem. There is also a "Show paths" link because this is a data flow query.
#. Click the repository name to show a summary of each result.
#. Explore the information available for each result using links to the source files in GitHub.com and, for data flow queries, the **Show paths** link. For more information, see ":ref:`Exploring data flow with path queries <exploring-data-flow-with-path-queries>`."
Exporting your results
----------------------
You can export your results for further analysis or to discuss them with collaborators. In the results view, click **Export results** to export the results to a secret gist on GitHub.com or to a markdown file in your workspace.
.. _custom-lists:
Creating custom lists of repositories
-------------------------------------
After you have defined a controller repository, the Variant Analysis Repositories panel shows the lists of repositories that you can select for variant analysis. You can use the options in the panel header to add a specific repository or organization to the panel, and to create and manage custom lists of repositories for variant analysis.
.. pull-quote::
Note
CodeQL analysis always requires a CodeQL database to run queries against. When you run variant analysis against a list of repositories, your query will only be executed against the repositories that currently have a CodeQL database available to download. The best way to make a repository available for variant analysis is to enable code scanning with CodeQL. For information about enabling code scanning using CodeQL, see "`Configuring code scanning automatically <https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning-for-a-repository#configuring-code-scanning-automatically>`__."
Selecting a single GitHub repository or organization for analysis
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#. In the Variant Analysis Repositories panel, click the **+**, add new database, icon.
#. From the dropdown menu, click **From a GitHub repository** or **All repositories of GitHub org or owner**.
#. Type the identifier of the repository or organization that you want to use into the field.
.. image:: ../images/codeql-for-visual-studio-code/variant-analysis-repo-and-org.png
:width: 350
:alt: Screenshot of the CodeQL extension in Visual Studio Code. The "Variant Analysis Repositories" section is expanded to show a repository (octo-org/octo-repo) and an organization (octo-org). These items are highlighted with a dark orange outline.
Creating a custom list of repositories
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#. In the Variant Analysis Repositories panel, click the |add-list| icon.
#. Type a name for the new list and press **Enter**.
#. Select your list in the panel and then click **+**, to add a repository to your list.
You can manage and edit your custom lists by right-clicking on either the list name, or a repository name within the list, and selecting an option from the context menu.
The custom lists are stored in your workspace in a ``databases.json`` file. If you want to edit this file directly, you can open it by clicking **{ }** in the panel header.
For example, if you want to continue analyzing a set of repositories that had results for your query, click **Copy repository list** in the Variant Analysis Results view to add a list of only the repositories that have results to the clipboard as JSON. For example:
.. code-block:: json
{
"name": "new-repo-list",
"repositories": [
"facebook/create-react-app"
]
}
You can then insert the ``new-repo-list`` of repositories into your list of custom repository lists for easy access in the Variant Analysis Repositories panel.
Troubleshooting variant analysis
--------------------------------
For information on troubleshooting variant analysis, see
":ref:`Troubleshooting variant analysis <troubleshooting-variant-analysis>`."
.. |add-list| image:: ../images/codeql-for-visual-studio-code/variant-analysis-add-list.png
:height: 2ex

View File

@@ -5,7 +5,7 @@
Testing CodeQL queries in Visual Studio Code
============================================
You can run unit tests for CodeQL queries using the Visual Studio Code extension.
You can run unit tests for CodeQL queries using the Visual Studio Code extension. When you are sure that your query finds the results you want to identify, you can use variant analysis to run it at scale. For information on running analysis at scale across many CodeQL databases, see ":ref:`Running CodeQL queries at scale with multi-repository variant analysis <running-codeql-queries-at-scale-with-mrva>`."
About testing queries in VS Code
---------------------------------

View File

@@ -5,7 +5,12 @@
Troubleshooting CodeQL for Visual Studio Code
=============================================
You can use the detailed information written to the extension's log files if you need to troubleshoot problems.
This article explains how to debug problems with the analysis of CodeQL databases that are stored on your local
machine. For information on troubleshooting variant analysis, which runs on GitHub.com, see
":ref:`Troubleshooting variant analysis <troubleshooting-variant-analysis>`."
You can use the detailed information written to the extension's log files if you need to troubleshoot problems
analyzing CodeQL databases that are stored locally.
About the log files
--------------------

View File

@@ -0,0 +1,30 @@
:tocdepth: 1
.. _troubleshooting-variant-analysis:
Troubleshooting variant analysis
================================
.. include:: ../reusables/beta-note-mrva.rst
This article explains how to debug problems with variant analysis, that is, analysis run using GitHub Actions
and not locally on your machine.
For information on troubleshooting local analysis, see
":ref:`Troubleshooting CodeQL for Visual Studio Code <troubleshooting-codeql-for-visual-studio-code>`."
When you run variant analysis, there are two key places where errors and warnings are displayed:
#. **Visual Studio Code errors** - any problems with creating a CodeQL pack and sending the analysis to GitHub.com are reported as Visual Studio Code errors in the bottom right corner of the application. The problem information is also available in the **Problems** view.
#. **Variant Analysis Results** - any problems with the variant analysis run are reported in this view.
Variant analysis warning: Problem with controller repository
------------------------------------------------------------
If there are problems with the variant analysis run, you will see a warning banner at the top of the Variant Analysis Results tab. For example:
.. image:: ../images/codeql-for-visual-studio-code/variant-analysis-results-warning.png
:width: 600
:alt: Screenshot of the "Variant Analysis Results" view showing a warning banner with the text "warning: Problem with controller repository" and "Publicly visible controller repository can't be used to analyze private repositories. 1 private repository was not analyzed." The "Show logs" button is highlighted with a dark orange outline.
In this example, the user ran variant analysis on a custom list of two repositories. One of the repositories was a private repository and could not be analyzed because they had a public controller repository. Only the public repository was analyzed. To analyze both repositories, this user needs to edit their settings and update the controller repository to a private repository. For information on how to edit the controller repository, see ":ref:`Customizing settings <customizing-settings>`."

View File

@@ -31,16 +31,16 @@ following snippet demonstrates.
This query selects the API graph node corresponding to the ``re`` module. This node represents the fact that the ``re`` module has been imported rather than a specific location in the program where the import happens. Therefore, there will be at most one result per project, and it will not have a useful location, so you'll have to click `Show 1 non-source result` in order to see it.
To find where the ``re`` module is referenced in the program, you can use the ``getAUse`` method. The following query selects all references to the ``re`` module in the current database.
To find where the ``re`` module is referenced in the program, you can use the ``getAValueReachableFromSource`` method. The following query selects all references to the ``re`` module in the current database.
.. code-block:: ql
import python
import semmle.python.ApiGraphs
select API::moduleImport("re").getAUse()
select API::moduleImport("re").getAValueReachableFromSource()
Note that the ``getAUse`` method accounts for local flow, so that ``my_re_compile``
Note that the ``getAValueReachableFromSource`` method accounts for local flow, so that ``my_re_compile``
in the following snippet is
correctly recognized as a reference to the ``re.compile`` function.
@@ -53,7 +53,7 @@ correctly recognized as a reference to the ``re.compile`` function.
r = my_re_compile(".*")
If you only require immediate uses, without taking local flow into account, then you can use
the ``getAnImmediateUse`` method instead.
the ``asSource`` method instead.
Note that the given module name *must not* contain any dots. Thus, something like
``API::moduleImport("flask.views")`` will not do what you expect. Instead, this should be decomposed
@@ -71,7 +71,7 @@ the above ``re.compile`` example, you can now find references to ``re.compile``.
import python
import semmle.python.ApiGraphs
select API::moduleImport("re").getMember("compile").getAUse()
select API::moduleImport("re").getMember("compile").getAValueReachableFromSource()
In addition to ``getMember``, you can use the ``getUnknownMember`` method to find references to API
components where the name is not known statically. You can use the ``getAMember`` method to
@@ -89,12 +89,36 @@ where the return value of ``re.compile`` is used:
import python
import semmle.python.ApiGraphs
select API::moduleImport("re").getMember("compile").getReturn().getAUse()
select API::moduleImport("re").getMember("compile").getReturn().getAValueReachableFromSource()
Note that this includes all uses of the result of ``re.compile``, including those reachable via
local flow. To get just the *calls* to ``re.compile``, you can use ``getAnImmediateUse`` instead of
``getAUse``. As this is a common occurrence, you can use ``getACall`` instead of
``getReturn`` followed by ``getAnImmediateUse``.
local flow. To get just the *calls* to ``re.compile``, you can use ``asSource`` instead of
``getAValueReachableFromSource``. As this is a common occurrence, you can, instead of
``getReturn`` followed by ``asSource``, simply use ``getACall``. This will result in an
``API::CallNode``, which deserves a small description of its own.
``API::CallNode``s are not ``API::Node``s. Instead they are ``DataFlow::Node``s with some convenience
predicates that allows you to recover ``API::Node``s for the return value as well as for arguments
to the call. This enables you to constrain the call in various ways using the API graph. The following
snippet finds all calls to ``re.compile`` where the ``pattern`` argument comes from parsing a command
line argument using the ``argparse`` library.
.. code-block:: ql
import python
import semmle.python.ApiGraphs
from API::CallNode call
where
call = API::moduleImport("re").getMember("compile").getACall() and
call.getParameter(0, "pattern") =
API::moduleImport("argparse")
.getMember("ArgumentParser")
.getReturn()
.getMember("parse_args")
.getMember(_)
select call
Note that the API graph does not distinguish between class instantiations and function calls. As far
as it's concerned, both are simply places where an API graph node is called.
@@ -122,7 +146,7 @@ all subclasses of ``View``, you must explicitly include the subclasses of ``Meth
API::moduleImport("flask").getMember("views").getMember(["View", "MethodView"]).getASubclass*()
}
select viewClass().getAUse()
select viewClass().getAValueReachableFromSource()
Note the use of the set literal ``["View", "MethodView"]`` to match both classes simultaneously.

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

View File

@@ -0,0 +1,7 @@
.. pull-quote::
Note
Multi-repository variant analysis is currently available as a beta release and is subject to change. To use this feature, you must upgrade the CodeQL extension for Visual Studio Code to a minimum of version 1.8.0.
You can report your feedback in the community discussion for the beta release: https://gh.io/mrva-public-beta-discussion.

View File

@@ -248,7 +248,9 @@ module Public {
/**
* Holds if all the summaries that apply to `this` are auto generated and not manually created.
*/
final predicate isAutoGenerated() { this.hasProvenance("generated") and not this.isManual() }
final predicate isAutoGenerated() {
this.hasProvenance(["generated", "ai-generated"]) and not this.isManual()
}
/**
* Holds if there exists a manual summary that applies to `this`.
@@ -268,7 +270,7 @@ module Public {
/**
* Holds if the neutral is auto generated.
*/
predicate isAutoGenerated() { neutralElement(this, "generated") }
predicate isAutoGenerated() { neutralElement(this, ["generated", "ai-generated"]) }
/**
* Holds if there exists a manual neutral that applies to `this`.
@@ -1202,11 +1204,11 @@ module Private {
}
private string renderProvenance(SummarizedCallable c) {
if c.isAutoGenerated() then result = "generated" else result = "manual"
if c.isManual() then result = "manual" else c.hasProvenance(result)
}
private string renderProvenanceNeutral(NeutralCallable c) {
if c.isAutoGenerated() then result = "generated" else result = "manual"
if c.isManual() then result = "manual" else c.hasProvenance(result)
}
/**

View File

@@ -39,8 +39,8 @@ jakarta.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,,
jakarta.ws.rs.core,2,,149,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,94,55
java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
java.io,37,,42,,15,,,,,,,,,,,,,,,,,,,,,,,,,,,,22,,,,,,,,41,1
java.lang,13,,76,,,,,,,,,,,,8,,,,,,,4,,,1,,,,,,,,,,,,,,,,53,23
java.net,10,3,7,,,,,,,,,,,,,,,10,,,,,,,,,,,,,,,,,,,,,,3,7,
java.lang,14,,76,,,,,,,,,,,,8,,,,,1,,4,,,1,,,,,,,,,,,,,,,,53,23
java.net,10,3,9,,,,,,,,,,,,,,,10,,,,,,,,,,,,,,,,,,,,,,3,9,
java.nio,16,,16,,13,,,,,,,,,,,,,,,1,,,,,,,,,,,,,2,,,,,,,,16,
java.sql,11,,2,,,,,,,,4,,,,,,,,,,,,,,,,,,7,,,,,,,,,,,,1,1
java.util,44,,465,,,,,,,,,,,,34,,,,,,,,5,2,,1,2,,,,,,,,,,,,,,38,427
@@ -74,10 +74,12 @@ org.apache.commons.logging,6,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,
org.apache.commons.ognl,6,,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,,
org.apache.commons.text,,,272,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,220,52
org.apache.directory.ldap.client.api,1,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,
org.apache.hadoop.hive.metastore,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,,,,,,,,,,
org.apache.hc.core5.function,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,
org.apache.hc.core5.http,1,2,39,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,2,39,
org.apache.hc.core5.net,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,
org.apache.hc.core5.util,,,24,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18,6
org.apache.hive.hcatalog.templeton,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,
org.apache.http,27,3,70,,,,,,,,,,,,,,,25,,,,,,,,,,,,,,,,,,2,,,,3,62,8
org.apache.ibatis.jdbc,6,,57,,,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,,,57,
org.apache.log4j,11,,,,,,,,,,,,,,11,,,,,,,,,,,,,,,,,,,,,,,,,,,
1 package sink source summary sink:bean-validation sink:create-file sink:fragment-injection sink:groovy sink:header-splitting sink:information-leak sink:intent-start sink:jdbc-url sink:jexl sink:jndi-injection sink:ldap sink:logging sink:mvel sink:ognl-injection sink:open-url sink:pending-intent-sent sink:read-file sink:regex-use sink:regex-use[-1] sink:regex-use[0] sink:regex-use[] sink:regex-use[f-1] sink:regex-use[f1] sink:regex-use[f] sink:set-hostname-verifier sink:sql sink:ssti sink:url-open-stream sink:url-redirect sink:write-file sink:xpath sink:xslt sink:xss source:android-external-storage-dir source:android-widget source:contentprovider source:remote summary:taint summary:value
39 jakarta.ws.rs.core 2 149 2 94 55
40 java.beans 1 1
41 java.io 37 42 15 22 41 1
42 java.lang 13 14 76 8 1 4 1 53 23
43 java.net 10 3 7 9 10 3 7 9
44 java.nio 16 16 13 1 2 16
45 java.sql 11 2 4 7 1 1
46 java.util 44 465 34 5 2 1 2 38 427
74 org.apache.commons.ognl 6 6
75 org.apache.commons.text 272 220 52
76 org.apache.directory.ldap.client.api 1 1
77 org.apache.hadoop.hive.metastore 3 3
78 org.apache.hc.core5.function 1 1
79 org.apache.hc.core5.http 1 2 39 1 2 39
80 org.apache.hc.core5.net 2 2
81 org.apache.hc.core5.util 24 18 6
82 org.apache.hive.hcatalog.templeton 1 1
83 org.apache.http 27 3 70 25 2 3 62 8
84 org.apache.ibatis.jdbc 6 57 6 57
85 org.apache.log4j 11 11

View File

@@ -18,10 +18,10 @@ Java framework & library support
`Google Guava <https://guava.dev/>`_,``com.google.common.*``,,728,39,,6,,,,,
JBoss Logging,``org.jboss.logging``,,,324,,,,,,,
`JSON-java <https://github.com/stleary/JSON-java>`_,``org.json``,,236,,,,,,,,
Java Standard Library,``java.*``,3,609,131,28,,,7,,,10
Java Standard Library,``java.*``,3,611,132,28,,,7,,,10
Java extensions,"``javax.*``, ``jakarta.*``",63,609,32,,,4,,1,1,2
Kotlin Standard Library,``kotlin*``,,1835,12,10,,,,,,2
`Spring <https://spring.io/>`_,``org.springframework.*``,29,477,101,,,,19,14,,29
Others,"``cn.hutool.core.codec``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.hubspot.jinjava``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.util``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.apache.commons.codec``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.hibernate``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.mvel2``, ``org.scijava.log``, ``org.slf4j``, ``org.thymeleaf``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",60,300,269,,,,14,18,,3
Totals,,217,8456,1564,129,6,10,107,33,1,86
Others,"``cn.hutool.core.codec``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.hubspot.jinjava``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.util``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.apache.commons.codec``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.hibernate``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.mvel2``, ``org.scijava.log``, ``org.slf4j``, ``org.thymeleaf``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",60,300,273,,,,18,18,,3
Totals,,217,8458,1569,129,6,10,111,33,1,86

View File

@@ -1,5 +1,5 @@
{
"markdownMessage": "An Android build may have failed. Ensure the Code Scanning workflow installs required dependencies, and that the [Gradle and Android SDK versions are compatible](https://developer.android.com/studio/releases/gradle-plugin#updating-gradle). Suspicious output line: ` > Minimum supported Gradle version is 7.4. Current version is 7.3. If using the gradle wrapper, try editing the distributionUrl in <test-root-directory>/gradle/wrapper/gradle-wrapper.properties to gradle-7.4-all.zip`",
"markdownMessage": "An Android build may have failed. Ensure the Code Scanning workflow installs required dependencies, and that the [Gradle and Android SDK versions are compatible](https://developer.android.com/studio/releases/gradle-plugin#updating-gradle).\n\nSuspicious output line: ` > Minimum supported Gradle version is 7.4. Current version is 7.3. If using the gradle wrapper, try editing the distributionUrl in <test-root-directory>/gradle/wrapper/gradle-wrapper.properties to gradle-7.4-all.zip`",
"severity": "error",
"source": {
"extractorName": "java",
@@ -13,7 +13,7 @@
}
}
{
"markdownMessage": "An Android build may have failed. Ensure the Code Scanning workflow installs required dependencies, and that the [Gradle and Android SDK versions are compatible](https://developer.android.com/studio/releases/gradle-plugin#updating-gradle). Suspicious output line: `Caused by: java.lang.RuntimeException: Minimum supported Gradle version is 7.4. Current version is 7.3. If using the gradle wrapper, try editing the distributionUrl in <test-root-directory>/gradle/wrapper/gradle-wrapper.properties to gradle-7.4-all.zip`",
"markdownMessage": "An Android build may have failed. Ensure the Code Scanning workflow installs required dependencies, and that the [Gradle and Android SDK versions are compatible](https://developer.android.com/studio/releases/gradle-plugin#updating-gradle).\n\nSuspicious output line: `Caused by: java.lang.RuntimeException: Minimum supported Gradle version is 7.4. Current version is 7.3. If using the gradle wrapper, try editing the distributionUrl in <test-root-directory>/gradle/wrapper/gradle-wrapper.properties to gradle-7.4-all.zip`",
"severity": "error",
"source": {
"extractorName": "java",

View File

@@ -1,5 +1,5 @@
{
"markdownMessage": "A compilation error was observed while autobuilding your code. Check that your Code Scanning workflow installs the needed compiler version and dependencies. Suspicious output line: `[ERROR] COMPILATION ERROR : `",
"markdownMessage": "A compilation error was observed while autobuilding your code. Check that your Code Scanning workflow installs the needed compiler version and dependencies.\n\nSuspicious output line: `[ERROR] COMPILATION ERROR : `",
"severity": "error",
"source": {
"extractorName": "java",
@@ -13,7 +13,7 @@
}
}
{
"markdownMessage": "A compilation error was observed while autobuilding your code. Check that your Code Scanning workflow installs the needed compiler version and dependencies. Suspicious output line: `[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project maven-sample: Compilation failure`",
"markdownMessage": "A compilation error was observed while autobuilding your code. Check that your Code Scanning workflow installs the needed compiler version and dependencies.\n\nSuspicious output line: `[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project maven-sample: Compilation failure`",
"severity": "error",
"source": {
"extractorName": "java",
@@ -27,7 +27,7 @@
}
}
{
"markdownMessage": "A compilation error was observed while autobuilding your code. Check that your Code Scanning workflow installs the needed compiler version and dependencies. Suspicious output line: `org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project maven-sample: Compilation failure`",
"markdownMessage": "A compilation error was observed while autobuilding your code. Check that your Code Scanning workflow installs the needed compiler version and dependencies.\n\nSuspicious output line: `org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project maven-sample: Compilation failure`",
"severity": "error",
"source": {
"extractorName": "java",

View File

@@ -1,5 +1,5 @@
{
"markdownMessage": "A dependency failed to download. Check that all dependencies are available, and [supply credentials for any private dependencies](https://github.com/Azure/actions-workflow-samples/blob/master/assets/create-secrets-for-GitHub-workflows.md#set-up-secrets-in-github-action-workflows). Suspicious output line: `Caused by: org.eclipse.aether.transfer.ArtifactNotFoundException: Could not find artifact junit:junit-nonesuch:jar:4.11 in central (https://repo.maven.apache.org/maven2)`",
"markdownMessage": "A dependency failed to download. Check that all dependencies are available, and [supply credentials for any private dependencies](https://github.com/Azure/actions-workflow-samples/blob/master/assets/create-secrets-for-GitHub-workflows.md#set-up-secrets-in-github-action-workflows).\n\nSuspicious output line: `Caused by: org.eclipse.aether.transfer.ArtifactNotFoundException: Could not find artifact junit:junit-nonesuch:jar:4.11 in central (https://repo.maven.apache.org/maven2)`",
"severity": "error",
"source": {
"extractorName": "java",

View File

@@ -1,5 +1,5 @@
{
"markdownMessage": "Your project may need a different JDK version. Ensure your Code Scanning workflow file has [an appropriate `setup-java` step](https://github.com/actions/setup-java#eclipse-temurin). Suspicious output line: `> Could not target platform: 'Java SE 11' using tool chain: 'JDK 8 (1.8)'.`",
"markdownMessage": "Your project may need a different JDK version. Ensure your Code Scanning workflow file has [an appropriate `setup-java` step](https://github.com/actions/setup-java#eclipse-temurin).\n\nSuspicious output line: `> Could not target platform: 'Java SE 11' using tool chain: 'JDK 8 (1.8)'.`",
"severity": "error",
"source": {
"extractorName": "java",
@@ -13,7 +13,7 @@
}
}
{
"markdownMessage": "Your project may need a different JDK version. Ensure your Code Scanning workflow file has [an appropriate `setup-java` step](https://github.com/actions/setup-java#eclipse-temurin). Suspicious output line: `Caused by: java.lang.IllegalArgumentException: Could not target platform: 'Java SE 11' using tool chain: 'JDK 8 (1.8)'.`",
"markdownMessage": "Your project may need a different JDK version. Ensure your Code Scanning workflow file has [an appropriate `setup-java` step](https://github.com/actions/setup-java#eclipse-temurin).\n\nSuspicious output line: `Caused by: java.lang.IllegalArgumentException: Could not target platform: 'Java SE 11' using tool chain: 'JDK 8 (1.8)'.`",
"severity": "error",
"source": {
"extractorName": "java",

View File

@@ -1,5 +1,5 @@
{
"markdownMessage": "Building your code triggered an access to an insecure HTTP Maven repository. Allow access to insecure repositories, or [update your build to use HTTPS](https://maven.apache.org/docs/3.8.1/release-notes.html#how-to-fix-when-i-get-a-http-repository-blocked). Suspicious output line: `Caused by: org.eclipse.aether.resolution.ArtifactResolutionException: Could not transfer artifact junit-nonesuch:junit-nonesuch:pom:4.11 from/to maven-default-http-blocker (http://0.0.0.0/): Blocked mirror for repositories: [insecure (http://repo.maven.apache.org/maven2/, default, releases+snapshots)]`",
"markdownMessage": "Building your code triggered an access to an insecure HTTP Maven repository. Allow access to insecure repositories, or [update your build to use HTTPS](https://maven.apache.org/docs/3.8.1/release-notes.html#how-to-fix-when-i-get-a-http-repository-blocked).\n\nSuspicious output line: `Caused by: org.eclipse.aether.resolution.ArtifactResolutionException: Could not transfer artifact junit-nonesuch:junit-nonesuch:pom:4.11 from/to maven-default-http-blocker (http://0.0.0.0/): Blocked mirror for repositories: [insecure (http://repo.maven.apache.org/maven2/, default, releases+snapshots)]`",
"severity": "error",
"source": {
"extractorName": "java",
@@ -13,7 +13,7 @@
}
}
{
"markdownMessage": "Building your code triggered an access to an insecure HTTP Maven repository. Allow access to insecure repositories, or [update your build to use HTTPS](https://maven.apache.org/docs/3.8.1/release-notes.html#how-to-fix-when-i-get-a-http-repository-blocked). Suspicious output line: `Caused by: org.eclipse.aether.transfer.ArtifactTransferException: Could not transfer artifact junit-nonesuch:junit-nonesuch:pom:4.11 from/to maven-default-http-blocker (http://0.0.0.0/): Blocked mirror for repositories: [insecure (http://repo.maven.apache.org/maven2/, default, releases+snapshots)]`",
"markdownMessage": "Building your code triggered an access to an insecure HTTP Maven repository. Allow access to insecure repositories, or [update your build to use HTTPS](https://maven.apache.org/docs/3.8.1/release-notes.html#how-to-fix-when-i-get-a-http-repository-blocked).\n\nSuspicious output line: `Caused by: org.eclipse.aether.transfer.ArtifactTransferException: Could not transfer artifact junit-nonesuch:junit-nonesuch:pom:4.11 from/to maven-default-http-blocker (http://0.0.0.0/): Blocked mirror for repositories: [insecure (http://repo.maven.apache.org/maven2/, default, releases+snapshots)]`",
"severity": "error",
"source": {
"extractorName": "java",
@@ -27,7 +27,7 @@
}
}
{
"markdownMessage": "Building your code triggered an access to an insecure HTTP Maven repository. Allow access to insecure repositories, or [update your build to use HTTPS](https://maven.apache.org/docs/3.8.1/release-notes.html#how-to-fix-when-i-get-a-http-repository-blocked). Suspicious output line: `Caused by: org.eclipse.aether.transfer.NoRepositoryConnectorException: Blocked mirror for repositories: [insecure (http://repo.maven.apache.org/maven2/, default, releases+snapshots)]`",
"markdownMessage": "Building your code triggered an access to an insecure HTTP Maven repository. Allow access to insecure repositories, or [update your build to use HTTPS](https://maven.apache.org/docs/3.8.1/release-notes.html#how-to-fix-when-i-get-a-http-repository-blocked).\n\nSuspicious output line: `Caused by: org.eclipse.aether.transfer.NoRepositoryConnectorException: Blocked mirror for repositories: [insecure (http://repo.maven.apache.org/maven2/, default, releases+snapshots)]`",
"severity": "error",
"source": {
"extractorName": "java",
@@ -41,7 +41,7 @@
}
}
{
"markdownMessage": "Building your code triggered an access to an insecure HTTP Maven repository. Allow access to insecure repositories, or [update your build to use HTTPS](https://maven.apache.org/docs/3.8.1/release-notes.html#how-to-fix-when-i-get-a-http-repository-blocked). Suspicious output line: `[ERROR] Failed to execute goal on project maven-sample: Could not resolve dependencies for project com.example:maven-sample:jar:1.0-SNAPSHOT: Failed to collect dependencies at junit-nonesuch:junit-nonesuch:jar:4.11: Failed to read artifact descriptor for junit-nonesuch:junit-nonesuch:jar:4.11: Could not transfer artifact junit-nonesuch:junit-nonesuch:pom:4.11 from/to maven-default-http-blocker (http://0.0.0.0/): Blocked mirror for repositories: [insecure (http://repo.maven.apache.org/maven2/, default, releases+snapshots)] -> [Help 1]`",
"markdownMessage": "Building your code triggered an access to an insecure HTTP Maven repository. Allow access to insecure repositories, or [update your build to use HTTPS](https://maven.apache.org/docs/3.8.1/release-notes.html#how-to-fix-when-i-get-a-http-repository-blocked).\n\nSuspicious output line: `[ERROR] Failed to execute goal on project maven-sample: Could not resolve dependencies for project com.example:maven-sample:jar:1.0-SNAPSHOT: Failed to collect dependencies at junit-nonesuch:junit-nonesuch:jar:4.11: Failed to read artifact descriptor for junit-nonesuch:junit-nonesuch:jar:4.11: Could not transfer artifact junit-nonesuch:junit-nonesuch:pom:4.11 from/to maven-default-http-blocker (http://0.0.0.0/): Blocked mirror for repositories: [insecure (http://repo.maven.apache.org/maven2/, default, releases+snapshots)] -> [Help 1]`",
"severity": "error",
"source": {
"extractorName": "java",

View File

@@ -1,5 +1,5 @@
{
"markdownMessage": "Building using Maven was skipped because there were multiple sibling build directories containing build files: [./maven-project-1,./maven-project-2]. If you want to use one of these, please [manually supply a build command](https://docs.github.com/en/github-ae@latest/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-the-codeql-workflow-for-compiled-languages#adding-build-steps-for-a-compiled-language)",
"markdownMessage": "Building using Maven was skipped because there were multiple sibling build directories containing build files: [./maven-project-1,./maven-project-2]. If you want to use one of these, please [manually supply a build command](https://docs.github.com/en/github-ae@latest/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-the-codeql-workflow-for-compiled-languages#adding-build-steps-for-a-compiled-language).",
"severity": "warning",
"source": {
"extractorName": "java",
@@ -13,7 +13,7 @@
}
}
{
"markdownMessage": "If you want to use one of the candidate build systems and directories (see previous warnings), please [supply a manual a build command](https://docs.github.com/en/github-ae@latest/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-the-codeql-workflow-for-compiled-languages#adding-build-steps-for-a-compiled-language)",
"markdownMessage": "If you want to use one of the candidate build systems and directories (see previous warnings), please [supply a manual a build command](https://docs.github.com/en/github-ae@latest/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-the-codeql-workflow-for-compiled-languages#adding-build-steps-for-a-compiled-language).",
"severity": "error",
"source": {
"extractorName": "java",

View File

@@ -1,5 +1,5 @@
{
"markdownMessage": "Could not find a Gradle, Maven or Ant top-level project to build. Please [supply a manual build command](https://docs.github.com/en/github-ae@latest/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-the-codeql-workflow-for-compiled-languages#adding-build-steps-for-a-compiled-language)",
"markdownMessage": "Could not find a Gradle, Maven or Ant top-level project to build. Please [supply a manual build command](https://docs.github.com/en/github-ae@latest/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-the-codeql-workflow-for-compiled-languages#adding-build-steps-for-a-compiled-language).",
"severity": "error",
"source": {
"extractorName": "java",

View File

@@ -13,7 +13,7 @@
}
}
{
"markdownMessage": "Gradle project does not define a `testClasses` goal. [Supply a manual build command](https://docs.github.com/en/github-ae@latest/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-the-codeql-workflow-for-compiled-languages#adding-build-steps-for-a-compiled-language) that builds the code that should be analyzed. Suspicious output line: `org.gradle.execution.TaskSelectionException: Task 'testClasses' not found in root project 'no-gradle-test-classes'.`",
"markdownMessage": "Gradle project does not define a `testClasses` goal. [Supply a manual build command](https://docs.github.com/en/github-ae@latest/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-the-codeql-workflow-for-compiled-languages#adding-build-steps-for-a-compiled-language) that builds the code that should be analyzed.\n\nSuspicious output line: `org.gradle.execution.TaskSelectionException: Task 'testClasses' not found in root project 'no-gradle-test-classes'.`",
"severity": "error",
"source": {
"extractorName": "java",

View File

@@ -1,10 +1,10 @@
{
"markdownMessage": "The Kotlin version installed (`999.999.999`) is too recent for this version of CodeQL. Install a version lower than 1.8.30",
"markdownMessage": "The Kotlin version installed (`999.999.999`) is too recent for this version of CodeQL. Install a version lower than 1.8.30.",
"severity": "error",
"source": {
"extractorName": "java",
"id": "java/extractor-agent/kotlin-version-too-new",
"name": "Android build failure"
"name": "Kotlin version too new"
},
"visibility": {
"cliSummaryTable": true,

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Added new sinks for `java/hardcoded-credential-api-call` to identify the use of hardcoded secrets in the creation and verification of JWT tokens using `com.auth0.jwt`. These sinks are from [an experimental query submitted by @luchua](https://github.com/github/codeql/pull/9036).

View File

@@ -3,6 +3,8 @@ extensions:
pack: codeql/java-all
extensible: sinkModel
data:
- ["java.lang", "Module", True, "getResourceAsStream", "(String)", "", "Argument[0]", "read-file", "ai-generated"]
# suggested label is not supported: - ["java.lang", "ProcessBuilder", True, "ProcessBuilder", "(String[])", "", "Argument[0]", "command-injection", "ai-generated"]
- ["java.lang", "String", False, "matches", "(String)", "", "Argument[0]", "regex-use[f-1]", "manual"]
- ["java.lang", "String", False, "replaceAll", "(String,String)", "", "Argument[0]", "regex-use[-1]", "manual"]
- ["java.lang", "String", False, "replaceFirst", "(String,String)", "", "Argument[0]", "regex-use[-1]", "manual"]

View File

@@ -0,0 +1,7 @@
extensions:
- addsTo:
pack: codeql/java-all
extensible: sinkModel
data:
- ["org.apache.hadoop.hive.metastore.api", "DefaultConstraintsRequest", True, "DefaultConstraintsRequest", "(String,String,String)", "", "Argument[1]", "sql", "ai-generated"]

View File

@@ -0,0 +1,8 @@
extensions:
- addsTo:
pack: codeql/java-all
extensible: sinkModel
data:
- ["org.apache.hadoop.hive.metastore", "ObjectStore", True, "updatePartitionColumnStatistics", "(ColumnStatistics,List,String,long)", "", "Argument[0]", "sql", "ai-generated"]
- ["org.apache.hadoop.hive.metastore", "ObjectStore", True, "updatePartitionColumnStatistics", "(ColumnStatistics,List)", "", "Argument[0]", "sql", "ai-generated"]

View File

@@ -0,0 +1,7 @@
extensions:
- addsTo:
pack: codeql/java-all
extensible: sinkModel
data:
- ["org.apache.hive.hcatalog.templeton", "HcatDelegator", True, "addOneColumn", "(String,String,String,ColumnDesc)", "", "Argument[3]", "sql", "ai-generated"]

View File

@@ -67,9 +67,10 @@
* "taint" indicates a default additional taint step and "value" indicates a
* globally applicable value-preserving step.
* 9. The `provenance` column is a tag to indicate the origin of the summary.
* There are two supported values: "generated" and "manual". "generated" means that
* the model has been emitted by the model generator tool and "manual" means
* that the model has been written by hand.
* The supported values are: "manual", "generated" and "ai-generated". "manual"
* means that the model has been written by hand, "generated" means that
* the model has been emitted by the model generator tool and
* "ai-generated" means that the model has been AI generated (ATM project).
*/
import java
@@ -308,7 +309,7 @@ module ModelValidation {
not ext.regexpMatch("|Annotated") and
result = "Unrecognized extra API graph element \"" + ext + "\" in " + pred + " model."
or
not provenance = ["manual", "generated"] and
not provenance = ["manual", "generated", "ai-generated"] and
result = "Unrecognized provenance description \"" + provenance + "\" in " + pred + " model."
)
}

View File

@@ -248,7 +248,9 @@ module Public {
/**
* Holds if all the summaries that apply to `this` are auto generated and not manually created.
*/
final predicate isAutoGenerated() { this.hasProvenance("generated") and not this.isManual() }
final predicate isAutoGenerated() {
this.hasProvenance(["generated", "ai-generated"]) and not this.isManual()
}
/**
* Holds if there exists a manual summary that applies to `this`.
@@ -268,7 +270,7 @@ module Public {
/**
* Holds if the neutral is auto generated.
*/
predicate isAutoGenerated() { neutralElement(this, "generated") }
predicate isAutoGenerated() { neutralElement(this, ["generated", "ai-generated"]) }
/**
* Holds if there exists a manual neutral that applies to `this`.
@@ -1202,11 +1204,11 @@ module Private {
}
private string renderProvenance(SummarizedCallable c) {
if c.isAutoGenerated() then result = "generated" else result = "manual"
if c.isManual() then result = "manual" else c.hasProvenance(result)
}
private string renderProvenanceNeutral(NeutralCallable c) {
if c.isAutoGenerated() then result = "generated" else result = "manual"
if c.isManual() then result = "manual" else c.hasProvenance(result)
}
/**

View File

@@ -490,5 +490,11 @@ private predicate otherApiCallableCredentialParam(string s) {
"com.microsoft.sqlserver.jdbc.SQLServerDataSource;setPassword(String);0",
"com.microsoft.sqlserver.jdbc.SQLServerDataSource;getConnection(String, String);0",
"com.microsoft.sqlserver.jdbc.SQLServerDataSource;getConnection(String, String);1",
"com.auth0.jwt.algorithms.Algorithm;HMAC256(String);0",
"com.auth0.jwt.algorithms.Algorithm;HMAC256(byte[]);0",
"com.auth0.jwt.algorithms.Algorithm;HMAC384(String);0",
"com.auth0.jwt.algorithms.Algorithm;HMAC384(byte[]);0",
"com.auth0.jwt.algorithms.Algorithm;HMAC512(String);0",
"com.auth0.jwt.algorithms.Algorithm;HMAC512(byte[]);0"
]
}

View File

@@ -28,7 +28,7 @@ private int getNumMadModeledApis(string package, string provenance) {
or
sc.isManual() and
(
if sc.hasProvenance("generated")
if sc.hasProvenance(["generated", "ai-generated"])
then
// "both"
provenance = "both"

View File

@@ -1,26 +0,0 @@
// BAD: Get secret from hardcoded string then sign a JWT token
Algorithm algorithm = Algorithm.HMAC256("hardcoded_secret");
JWT.create()
.withClaim("username", username)
.sign(algorithm);
}
// BAD: Get secret from hardcoded string then verify a JWT token
JWTVerifier verifier = JWT.require(Algorithm.HMAC256("hardcoded_secret"))
.withIssuer(ISSUER)
.build();
verifier.verify(token);
// GOOD: Get secret from system configuration then sign a token
String tokenSecret = System.getenv("SECRET_KEY");
Algorithm algorithm = Algorithm.HMAC256(tokenSecret);
JWT.create()
.withClaim("username", username)
.sign(algorithm);
}
// GOOD: Get secret from environment variable then verify a JWT token
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(System.getenv("SECRET_KEY")))
.withIssuer(ISSUER)
.build();
verifier.verify(token);

View File

@@ -1,46 +0,0 @@
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
<qhelp>
<overview>
<p>
JWT (JSON Web Token) is an open standard (RFC 7519) that defines a way to provide information
within a JSON object between two parties. JWT is widely used for sharing security information
between two parties in web applications. Each JWT contains encoded JSON objects, including a
set of claims. JWTs are signed using a cryptographic algorithm to ensure that the claims cannot
be altered after the token is issued.
</p>
<p>
The most basic mistake is using hardcoded secrets for JWT generation/verification. This allows
an attacker to forge the token if the source code (and JWT secret in it) is publicly exposed or
leaked, which leads to authentication bypass or privilege escalation.
</p>
</overview>
<recommendation>
<p>
Generating a cryptographically secure secret key during application initialization and using this
generated key for JWT signing/verification requests can prevent this vulnerability. Or safely store
the secret key in a key vault that cannot be leaked in source code.
</p>
</recommendation>
<example>
<p>
The following examples show the bad case and the good case respectively. The <code>bad</code>
methods show a hardcoded secret key is used to sign and verify JWT tokens. In the <code>good</code>
method, the secret key is loaded from a system environment during application initialization.
</p>
<sample src="HardcodedJwtKey.java" />
</example>
<references>
<li>
Semgrep Blog:
<a href="https://r2c.dev/blog/2020/hardcoded-secrets-unverified-tokens-and-other-common-jwt-mistakes/">Hardcoded secrets, unverified tokens, and other common JWT mistakes</a>
</li>
<li>
CVE-2022-24860:
<a href="https://nvd.nist.gov/vuln/detail/CVE-2022-24860">Databasir 1.01 has Use of Hard-coded Cryptographic Key vulnerability.</a>
</li>
</references>
</qhelp>

View File

@@ -1,20 +0,0 @@
/**
* @name Use of a hardcoded key for signing JWT
* @description Using a hardcoded key for signing JWT can allow an attacker to compromise security.
* @kind path-problem
* @problem.severity error
* @id java/hardcoded-jwt-key
* @tags security
* experimental
* external/cwe/cwe-321
*/
import java
import HardcodedJwtKey
import semmle.code.java.dataflow.TaintTracking
import DataFlow::PathGraph
from DataFlow::PathNode source, DataFlow::PathNode sink, HardcodedJwtKeyConfiguration cfg
where cfg.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "$@ is used to sign a JWT token.", source.getNode(),
"Hardcoded String"

View File

@@ -1,131 +0,0 @@
/**
* Provides sources and sinks for detecting JWT token signing vulnerabilities.
*/
import java
private import semmle.code.java.dataflow.ExternalFlow
private import semmle.code.java.dataflow.FlowSources
private class ActivateModels extends ActiveExperimentalModels {
ActivateModels() { this = "hardcoded-jwt-key" }
}
/** The class `com.auth0.jwt.JWT`. */
class Jwt extends RefType {
Jwt() { this.hasQualifiedName("com.auth0.jwt", "JWT") }
}
/** The class `com.auth0.jwt.JWTCreator.Builder`. */
class JwtBuilder extends RefType {
JwtBuilder() { this.hasQualifiedName("com.auth0.jwt", "JWTCreator$Builder") }
}
/** The class `com.auth0.jwt.algorithms.Algorithm`. */
class JwtAlgorithm extends RefType {
JwtAlgorithm() { this.hasQualifiedName("com.auth0.jwt.algorithms", "Algorithm") }
}
/**
* The interface `com.auth0.jwt.interfaces.JWTVerifier` or its implementation
* `com.auth0.jwt.JWTVerifier`.
*/
class JwtVerifier extends RefType {
JwtVerifier() {
this.hasQualifiedName(["com.auth0.jwt", "com.auth0.jwt.interfaces"], "JWTVerifier")
}
}
/** A method that creates an instance of `com.auth0.jwt.algorithms.Algorithm`. */
class GetAlgorithmMethod extends Method {
GetAlgorithmMethod() {
this.getDeclaringType() instanceof JwtAlgorithm and
this.getName().matches(["HMAC%", "ECDSA%", "RSA%"])
}
}
/** The `require` method of `com.auth0.jwt.JWT`. */
class RequireMethod extends Method {
RequireMethod() {
this.getDeclaringType() instanceof Jwt and
this.hasName("require")
}
}
/** The `sign` method of `com.auth0.jwt.JWTCreator.Builder`. */
class SignTokenMethod extends Method {
SignTokenMethod() {
this.getDeclaringType() instanceof JwtBuilder and
this.hasName("sign")
}
}
/** The `verify` method of `com.auth0.jwt.interfaces.JWTVerifier`. */
class VerifyTokenMethod extends Method {
VerifyTokenMethod() {
this.getDeclaringType() instanceof JwtVerifier and
this.hasName("verify")
}
}
/**
* A data flow source for JWT token signing vulnerabilities.
*/
abstract class JwtKeySource extends DataFlow::Node { }
/**
* A data flow sink for JWT token signing vulnerabilities.
*/
abstract class JwtTokenSink extends DataFlow::Node { }
/**
* A hardcoded string literal as a source for JWT token signing vulnerabilities.
*/
class HardcodedKeyStringSource extends JwtKeySource {
HardcodedKeyStringSource() { exists(this.asExpr().(CompileTimeConstantExpr).getStringValue()) }
}
/**
* An expression used to sign JWT tokens as a sink of JWT token signing vulnerabilities.
*/
private class SignTokenSink extends JwtTokenSink {
SignTokenSink() {
exists(MethodAccess ma |
ma.getMethod() instanceof SignTokenMethod and
this.asExpr() = ma.getArgument(0)
)
}
}
/**
* An expression used to verify JWT tokens as a sink of JWT token signing vulnerabilities.
*/
private class VerifyTokenSink extends JwtTokenSink {
VerifyTokenSink() {
exists(MethodAccess ma |
ma.getMethod() instanceof VerifyTokenMethod and
this.asExpr() = ma.getQualifier()
)
}
}
/**
* A configuration depicting taint flow for checking JWT token signing vulnerabilities.
*/
class HardcodedJwtKeyConfiguration extends TaintTracking::Configuration {
HardcodedJwtKeyConfiguration() { this = "Hard-coded JWT Signing Key" }
override predicate isSource(DataFlow::Node source) { source instanceof JwtKeySource }
override predicate isSink(DataFlow::Node sink) { sink instanceof JwtTokenSink }
override predicate isAdditionalTaintStep(DataFlow::Node prev, DataFlow::Node succ) {
exists(MethodAccess ma |
(
ma.getMethod() instanceof GetAlgorithmMethod or
ma.getMethod() instanceof RequireMethod
) and
prev.asExpr() = ma.getArgument(0) and
succ.asExpr() = ma
)
}
}

View File

@@ -10,5 +10,5 @@ import semmle.code.java.dataflow.ExternalFlow
from string package, string type, string name, string signature, string provenance
where
neutralModel(package, type, name, signature, provenance) and
provenance != "generated"
provenance != ["generated", "ai-generated"]
select package, type, name, signature, provenance order by package, type, name, signature

View File

@@ -12,6 +12,6 @@ from
string input, string kind, string provenance
where
sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance) and
provenance != "generated"
provenance != ["generated", "ai-generated"]
select package, type, subtypes, name, signature, ext, input, kind, provenance order by
package, type, name, signature, input, kind

View File

@@ -12,6 +12,6 @@ from
string output, string kind, string provenance
where
sourceModel(package, type, subtypes, name, signature, ext, output, kind, provenance) and
provenance != "generated"
provenance != ["generated", "ai-generated"]
select package, type, subtypes, name, signature, ext, output, kind, provenance order by
package, type, name, signature, output, kind

View File

@@ -12,6 +12,6 @@ from
string input, string output, string kind, string provenance
where
summaryModel(package, type, subtypes, name, signature, ext, input, output, kind, provenance) and
provenance != "generated"
provenance != ["generated", "ai-generated"]
select package, type, subtypes, name, signature, ext, input, output, kind, provenance order by
package, type, name, signature, input, output, kind

View File

@@ -1,25 +0,0 @@
edges
| HardcodedJwtKey.java:15:33:15:38 | SECRET : String | HardcodedJwtKey.java:19:49:19:54 | SECRET : String |
| HardcodedJwtKey.java:15:33:15:38 | SECRET : String | HardcodedJwtKey.java:42:62:42:67 | SECRET : String |
| HardcodedJwtKey.java:15:42:15:59 | "hardcoded_secret" : String | HardcodedJwtKey.java:15:33:15:38 | SECRET : String |
| HardcodedJwtKey.java:19:49:19:54 | SECRET : String | HardcodedJwtKey.java:25:23:25:31 | algorithm |
| HardcodedJwtKey.java:42:32:42:69 | require(...) : Verification | HardcodedJwtKey.java:42:32:43:35 | withIssuer(...) : Verification |
| HardcodedJwtKey.java:42:32:43:35 | withIssuer(...) : Verification | HardcodedJwtKey.java:42:32:44:24 | build(...) : JWTVerifier |
| HardcodedJwtKey.java:42:32:44:24 | build(...) : JWTVerifier | HardcodedJwtKey.java:46:13:46:20 | verifier |
| HardcodedJwtKey.java:42:62:42:67 | SECRET : String | HardcodedJwtKey.java:42:32:42:69 | require(...) : Verification |
nodes
| HardcodedJwtKey.java:15:33:15:38 | SECRET : String | semmle.label | SECRET : String |
| HardcodedJwtKey.java:15:42:15:59 | "hardcoded_secret" : String | semmle.label | "hardcoded_secret" : String |
| HardcodedJwtKey.java:19:49:19:54 | SECRET : String | semmle.label | SECRET : String |
| HardcodedJwtKey.java:25:23:25:31 | algorithm | semmle.label | algorithm |
| HardcodedJwtKey.java:42:32:42:69 | require(...) : Verification | semmle.label | require(...) : Verification |
| HardcodedJwtKey.java:42:32:43:35 | withIssuer(...) : Verification | semmle.label | withIssuer(...) : Verification |
| HardcodedJwtKey.java:42:32:44:24 | build(...) : JWTVerifier | semmle.label | build(...) : JWTVerifier |
| HardcodedJwtKey.java:42:62:42:67 | SECRET : String | semmle.label | SECRET : String |
| HardcodedJwtKey.java:46:13:46:20 | verifier | semmle.label | verifier |
subpaths
#select
| HardcodedJwtKey.java:25:23:25:31 | algorithm | HardcodedJwtKey.java:15:42:15:59 | "hardcoded_secret" : String | HardcodedJwtKey.java:25:23:25:31 | algorithm | $@ is used to sign a JWT token. | HardcodedJwtKey.java:15:42:15:59 | "hardcoded_secret" | Hardcoded String |
| HardcodedJwtKey.java:25:23:25:31 | algorithm | HardcodedJwtKey.java:19:49:19:54 | SECRET : String | HardcodedJwtKey.java:25:23:25:31 | algorithm | $@ is used to sign a JWT token. | HardcodedJwtKey.java:19:49:19:54 | SECRET | Hardcoded String |
| HardcodedJwtKey.java:46:13:46:20 | verifier | HardcodedJwtKey.java:15:42:15:59 | "hardcoded_secret" : String | HardcodedJwtKey.java:46:13:46:20 | verifier | $@ is used to sign a JWT token. | HardcodedJwtKey.java:15:42:15:59 | "hardcoded_secret" | Hardcoded String |
| HardcodedJwtKey.java:46:13:46:20 | verifier | HardcodedJwtKey.java:42:62:42:67 | SECRET : String | HardcodedJwtKey.java:46:13:46:20 | verifier | $@ is used to sign a JWT token. | HardcodedJwtKey.java:42:62:42:67 | SECRET | Hardcoded String |

View File

@@ -1 +0,0 @@
experimental/Security/CWE/CWE-321/HardcodedJwtKey.ql

View File

@@ -1 +0,0 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/auth0-jwt-2.3

View File

@@ -14,6 +14,7 @@ edges
| Test.java:95:14:95:34 | getHostName(...) : String | Test.java:99:12:99:33 | new URI(...) |
| Test.java:95:14:95:34 | getHostName(...) : String | Test.java:100:12:100:45 | new URI(...) |
| Test.java:95:14:95:34 | getHostName(...) : String | Test.java:101:12:101:54 | new URI(...) |
| Test.java:105:14:105:34 | getHostName(...) : String | Test.java:107:46:107:46 | t |
nodes
| Test.java:19:18:19:38 | getHostName(...) : String | semmle.label | getHostName(...) : String |
| Test.java:24:20:24:23 | temp | semmle.label | temp |
@@ -34,6 +35,8 @@ nodes
| Test.java:99:12:99:33 | new URI(...) | semmle.label | new URI(...) |
| Test.java:100:12:100:45 | new URI(...) | semmle.label | new URI(...) |
| Test.java:101:12:101:54 | new URI(...) | semmle.label | new URI(...) |
| Test.java:105:14:105:34 | getHostName(...) : String | semmle.label | getHostName(...) : String |
| Test.java:107:46:107:46 | t | semmle.label | t |
subpaths
#select
| Test.java:24:11:24:24 | new File(...) | Test.java:19:18:19:38 | getHostName(...) : String | Test.java:24:20:24:23 | temp | This path depends on a $@. | Test.java:19:18:19:38 | getHostName(...) | user-provided value |
@@ -47,3 +50,4 @@ subpaths
| Test.java:99:3:99:34 | new File(...) | Test.java:95:14:95:34 | getHostName(...) : String | Test.java:99:12:99:33 | new URI(...) | This path depends on a $@. | Test.java:95:14:95:34 | getHostName(...) | user-provided value |
| Test.java:100:3:100:46 | new File(...) | Test.java:95:14:95:34 | getHostName(...) : String | Test.java:100:12:100:45 | new URI(...) | This path depends on a $@. | Test.java:95:14:95:34 | getHostName(...) | user-provided value |
| Test.java:101:3:101:55 | new File(...) | Test.java:95:14:95:34 | getHostName(...) : String | Test.java:101:12:101:54 | new URI(...) | This path depends on a $@. | Test.java:95:14:95:34 | getHostName(...) | user-provided value |
| Test.java:107:46:107:46 | t | Test.java:105:14:105:34 | getHostName(...) : String | Test.java:107:46:107:46 | t | This path depends on a $@. | Test.java:105:14:105:34 | getHostName(...) | user-provided value |

View File

@@ -100,4 +100,10 @@ class Test {
new File(new URI(null, null, t, null, null));
new File(new URI(null, null, null, 0, t, null, null));
}
void doGet6(InetAddress address) throws IOException {
String t = address.getHostName();
// BAD: accessing local resource with user input
getClass().getModule().getResourceAsStream(t);
}
}

View File

@@ -0,0 +1,29 @@
import org.apache.hadoop.hive.metastore.api.ColumnStatistics;
import org.apache.hadoop.hive.metastore.api.DefaultConstraintsRequest;
import org.apache.hadoop.hive.metastore.ObjectStore;
import org.apache.hive.hcatalog.templeton.ColumnDesc;
import org.apache.hive.hcatalog.templeton.HcatDelegator;
import java.util.List;
public class Hive {
public static Object source() {
return null;
}
public void test(ObjectStore objStore, HcatDelegator hcatDel) throws Exception {
{
String taint = (String) source();
new DefaultConstraintsRequest("", taint, ""); // $ sqlInjection
}
{
ColumnStatistics taint = (ColumnStatistics) source();
//objStore.updatePartitionColumnStatistics(taint, (List<String>) null, (String) null, 0L); // $ sqlInjection
objStore.updatePartitionColumnStatistics(taint, (List<String>) null); // $ sqlInjection
}
{
ColumnDesc taint = (ColumnDesc) source();
hcatDel.addOneColumn(null, null, null, taint); // $ sqlInjection
}
}
}

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/mongodbClient:${testdir}/../../../../../stubs/springframework-5.3.8
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/mongodbClient:${testdir}/../../../../../stubs/springframework-5.3.8:${testdir}/../../../../../stubs/apache-hive

View File

@@ -16,7 +16,7 @@ public class HardcodedJwtKey {
// BAD: Get secret from hardcoded string then sign a JWT token
public String accessTokenBad(String username) {
Algorithm algorithm = Algorithm.HMAC256(SECRET);
Algorithm algorithm = Algorithm.HMAC256(SECRET); // $ HardcodedCredentialsApiCall
return JWT.create()
.withExpiresAt(new Date(new Date().getTime() + ACCESS_EXPIRE_TIME))
@@ -39,7 +39,7 @@ public class HardcodedJwtKey {
// BAD: Get secret from hardcoded string then verify a JWT token
public boolean verifyTokenBad(String token) {
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET))
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)) // $ HardcodedCredentialsApiCall
.withIssuer(ISSUER)
.build();
try {
@@ -62,4 +62,49 @@ public class HardcodedJwtKey {
return false;
}
}
public String accessTokenBad384(String username) {
Algorithm algorithm = Algorithm.HMAC384(SECRET); // $ HardcodedCredentialsApiCall
return JWT.create()
.withExpiresAt(new Date(new Date().getTime() + ACCESS_EXPIRE_TIME))
.withIssuer(ISSUER)
.withClaim("username", username)
.sign(algorithm);
}
// GOOD: Get secret from system configuration then sign a token
public String accessTokenGood384(String username) {
String tokenSecret = System.getenv("SECRET_KEY");
Algorithm algorithm = Algorithm.HMAC384(tokenSecret);
return JWT.create()
.withExpiresAt(new Date(new Date().getTime() + ACCESS_EXPIRE_TIME))
.withIssuer(ISSUER)
.withClaim("username", username)
.sign(algorithm);
}
public String accessTokenBad512(String username) {
Algorithm algorithm = Algorithm.HMAC512(SECRET); // $ HardcodedCredentialsApiCall
return JWT.create()
.withExpiresAt(new Date(new Date().getTime() + ACCESS_EXPIRE_TIME))
.withIssuer(ISSUER)
.withClaim("username", username)
.sign(algorithm);
}
// GOOD: Get secret from system configuration then sign a token
public String accessTokenGood512(String username) {
String tokenSecret = System.getenv("SECRET_KEY");
Algorithm algorithm = Algorithm.HMAC512(tokenSecret);
return JWT.create()
.withExpiresAt(new Date(new Date().getTime() + ACCESS_EXPIRE_TIME))
.withIssuer(ISSUER)
.withClaim("username", username)
.sign(algorithm);
}
}

View File

@@ -1 +1 @@
// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/amazon-aws-sdk-1.11.700:${testdir}/../../../../../stubs/azure-sdk-for-java:${testdir}/../../../../../stubs/shiro-core-1.4.0:${testdir}/../../../../../stubs/jsch-0.1.55:${testdir}/../../../../../stubs/ganymed-ssh-2-260:${testdir}/../../../../../stubs/apache-mina-sshd-2.8.0:${testdir}/../../../../../stubs/sshj-0.33.0:${testdir}/../../../../../stubs/j2ssh-1.5.5:${testdir}/../../../../../stubs/trilead-ssh2-212:${testdir}/../../../../../stubs/apache-commons-net-3.8.0:${testdir}/../../../../../stubs/mongodbClient:${testdir}/../../../../../stubs/mssql-jdbc-12.2.0
// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/amazon-aws-sdk-1.11.700:${testdir}/../../../../../stubs/azure-sdk-for-java:${testdir}/../../../../../stubs/shiro-core-1.4.0:${testdir}/../../../../../stubs/jsch-0.1.55:${testdir}/../../../../../stubs/ganymed-ssh-2-260:${testdir}/../../../../../stubs/apache-mina-sshd-2.8.0:${testdir}/../../../../../stubs/sshj-0.33.0:${testdir}/../../../../../stubs/j2ssh-1.5.5:${testdir}/../../../../../stubs/trilead-ssh2-212:${testdir}/../../../../../stubs/apache-commons-net-3.8.0:${testdir}/../../../../../stubs/mongodbClient:${testdir}/../../../../../stubs/mssql-jdbc-12.2.0:${testdir}/../../../../../stubs/auth0-jwt-2.3

View File

@@ -0,0 +1,59 @@
// Generated automatically from com.google.protobuf.AbstractMessage for testing purposes
package com.google.protobuf;
import com.google.protobuf.AbstractMessageLite;
import com.google.protobuf.ByteString;
import com.google.protobuf.CodedInputStream;
import com.google.protobuf.CodedOutputStream;
import com.google.protobuf.Descriptors;
import com.google.protobuf.ExtensionRegistryLite;
import com.google.protobuf.Internal;
import com.google.protobuf.Message;
import com.google.protobuf.UninitializedMessageException;
import com.google.protobuf.UnknownFieldSet;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
abstract public class AbstractMessage extends AbstractMessageLite implements Message
{
abstract static public class Builder<BuilderType extends AbstractMessage.Builder> extends AbstractMessageLite.Builder<BuilderType> implements Message.Builder
{
protected static UninitializedMessageException newUninitializedMessageException(Message p0){ return null; }
public Builder(){}
public BuilderType clear(){ return null; }
public BuilderType mergeFrom(ByteString p0){ return null; }
public BuilderType mergeFrom(ByteString p0, ExtensionRegistryLite p1){ return null; }
public BuilderType mergeFrom(CodedInputStream p0){ return null; }
public BuilderType mergeFrom(CodedInputStream p0, ExtensionRegistryLite p1){ return null; }
public BuilderType mergeFrom(InputStream p0){ return null; }
public BuilderType mergeFrom(InputStream p0, ExtensionRegistryLite p1){ return null; }
public BuilderType mergeFrom(Message p0){ return null; }
public BuilderType mergeFrom(byte[] p0){ return null; }
public BuilderType mergeFrom(byte[] p0, ExtensionRegistryLite p1){ return null; }
public BuilderType mergeFrom(byte[] p0, int p1, int p2){ return null; }
public BuilderType mergeFrom(byte[] p0, int p1, int p2, ExtensionRegistryLite p3){ return null; }
public BuilderType mergeUnknownFields(UnknownFieldSet p0){ return null; }
public List<String> findInitializationErrors(){ return null; }
public Message.Builder getFieldBuilder(Descriptors.FieldDescriptor p0){ return null; }
public String getInitializationErrorString(){ return null; }
public abstract BuilderType clone();
public boolean mergeDelimitedFrom(InputStream p0){ return false; }
public boolean mergeDelimitedFrom(InputStream p0, ExtensionRegistryLite p1){ return false; }
}
protected int hashFields(int p0, Map<Descriptors.FieldDescriptor, Object> p1){ return 0; }
protected static int hashBoolean(boolean p0){ return 0; }
protected static int hashEnum(Internal.EnumLite p0){ return 0; }
protected static int hashEnumList(List<? extends Internal.EnumLite> p0){ return 0; }
protected static int hashLong(long p0){ return 0; }
public AbstractMessage(){}
public List<String> findInitializationErrors(){ return null; }
public String getInitializationErrorString(){ return null; }
public boolean equals(Object p0){ return false; }
public boolean isInitialized(){ return false; }
public final String toString(){ return null; }
public int getSerializedSize(){ return 0; }
public int hashCode(){ return 0; }
public void writeTo(CodedOutputStream p0){}
}

View File

@@ -0,0 +1,40 @@
// Generated automatically from com.google.protobuf.AbstractMessageLite for testing purposes
package com.google.protobuf;
import com.google.protobuf.ByteString;
import com.google.protobuf.CodedInputStream;
import com.google.protobuf.ExtensionRegistryLite;
import com.google.protobuf.MessageLite;
import com.google.protobuf.UninitializedMessageException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
abstract public class AbstractMessageLite implements MessageLite
{
abstract static public class Builder<BuilderType extends AbstractMessageLite.Builder> implements MessageLite.Builder
{
protected static <T> void addAll(java.lang.Iterable<T> p0, Collection<? super T> p1){}
protected static UninitializedMessageException newUninitializedMessageException(MessageLite p0){ return null; }
public Builder(){}
public BuilderType mergeFrom(ByteString p0){ return null; }
public BuilderType mergeFrom(ByteString p0, ExtensionRegistryLite p1){ return null; }
public BuilderType mergeFrom(CodedInputStream p0){ return null; }
public BuilderType mergeFrom(InputStream p0){ return null; }
public BuilderType mergeFrom(InputStream p0, ExtensionRegistryLite p1){ return null; }
public BuilderType mergeFrom(byte[] p0){ return null; }
public BuilderType mergeFrom(byte[] p0, ExtensionRegistryLite p1){ return null; }
public BuilderType mergeFrom(byte[] p0, int p1, int p2){ return null; }
public BuilderType mergeFrom(byte[] p0, int p1, int p2, ExtensionRegistryLite p3){ return null; }
public abstract BuilderType clone();
public abstract BuilderType mergeFrom(CodedInputStream p0, ExtensionRegistryLite p1);
public boolean mergeDelimitedFrom(InputStream p0){ return false; }
public boolean mergeDelimitedFrom(InputStream p0, ExtensionRegistryLite p1){ return false; }
}
public AbstractMessageLite(){}
public ByteString toByteString(){ return null; }
public byte[] toByteArray(){ return null; }
public void writeDelimitedTo(OutputStream p0){}
public void writeTo(OutputStream p0){}
}

View File

@@ -0,0 +1,38 @@
// Generated automatically from com.google.protobuf.AbstractParser for testing purposes
package com.google.protobuf;
import com.google.protobuf.ByteString;
import com.google.protobuf.CodedInputStream;
import com.google.protobuf.ExtensionRegistryLite;
import com.google.protobuf.MessageLite;
import com.google.protobuf.Parser;
import java.io.InputStream;
abstract public class AbstractParser<MessageType extends MessageLite> implements Parser<MessageType>
{
public AbstractParser(){}
public MessageType parseDelimitedFrom(InputStream p0){ return null; }
public MessageType parseDelimitedFrom(InputStream p0, ExtensionRegistryLite p1){ return null; }
public MessageType parseFrom(ByteString p0){ return null; }
public MessageType parseFrom(ByteString p0, ExtensionRegistryLite p1){ return null; }
public MessageType parseFrom(CodedInputStream p0){ return null; }
public MessageType parseFrom(CodedInputStream p0, ExtensionRegistryLite p1){ return null; }
public MessageType parseFrom(InputStream p0){ return null; }
public MessageType parseFrom(InputStream p0, ExtensionRegistryLite p1){ return null; }
public MessageType parseFrom(byte[] p0){ return null; }
public MessageType parseFrom(byte[] p0, ExtensionRegistryLite p1){ return null; }
public MessageType parseFrom(byte[] p0, int p1, int p2){ return null; }
public MessageType parseFrom(byte[] p0, int p1, int p2, ExtensionRegistryLite p3){ return null; }
public MessageType parsePartialDelimitedFrom(InputStream p0){ return null; }
public MessageType parsePartialDelimitedFrom(InputStream p0, ExtensionRegistryLite p1){ return null; }
public MessageType parsePartialFrom(ByteString p0){ return null; }
public MessageType parsePartialFrom(ByteString p0, ExtensionRegistryLite p1){ return null; }
public MessageType parsePartialFrom(CodedInputStream p0){ return null; }
public MessageType parsePartialFrom(InputStream p0){ return null; }
public MessageType parsePartialFrom(InputStream p0, ExtensionRegistryLite p1){ return null; }
public MessageType parsePartialFrom(byte[] p0){ return null; }
public MessageType parsePartialFrom(byte[] p0, ExtensionRegistryLite p1){ return null; }
public MessageType parsePartialFrom(byte[] p0, int p1, int p2){ return null; }
public MessageType parsePartialFrom(byte[] p0, int p1, int p2, ExtensionRegistryLite p3){ return null; }
}

View File

@@ -0,0 +1,72 @@
// Generated automatically from com.google.protobuf.ByteString for testing purposes
package com.google.protobuf;
import com.google.protobuf.CodedInputStream;
import com.google.protobuf.CodedOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.Iterator;
import java.util.List;
abstract public class ByteString implements Iterable<Byte>
{
protected abstract boolean isBalanced();
protected abstract int getTreeDepth();
protected abstract int partialHash(int p0, int p1, int p2);
protected abstract int partialIsValidUtf8(int p0, int p1, int p2);
protected abstract int peekCachedHashCode();
protected abstract void copyToInternal(byte[] p0, int p1, int p2, int p3);
public ByteString concat(ByteString p0){ return null; }
public ByteString substring(int p0){ return null; }
public String toString(){ return null; }
public String toStringUtf8(){ return null; }
public abstract ByteBuffer asReadOnlyByteBuffer();
public abstract ByteString substring(int p0, int p1);
public abstract ByteString.ByteIterator iterator();
public abstract CodedInputStream newCodedInput();
public abstract InputStream newInput();
public abstract List<ByteBuffer> asReadOnlyByteBufferList();
public abstract String toString(String p0);
public abstract boolean equals(Object p0);
public abstract boolean isValidUtf8();
public abstract byte byteAt(int p0);
public abstract int hashCode();
public abstract int size();
public abstract void copyTo(ByteBuffer p0);
public abstract void writeTo(OutputStream p0);
public boolean isEmpty(){ return false; }
public boolean startsWith(ByteString p0){ return false; }
public byte[] toByteArray(){ return null; }
public static ByteString EMPTY = null;
public static ByteString copyFrom(ByteBuffer p0){ return null; }
public static ByteString copyFrom(ByteBuffer p0, int p1){ return null; }
public static ByteString copyFrom(Iterable<ByteString> p0){ return null; }
public static ByteString copyFrom(String p0, String p1){ return null; }
public static ByteString copyFrom(byte[] p0){ return null; }
public static ByteString copyFrom(byte[] p0, int p1, int p2){ return null; }
public static ByteString copyFromUtf8(String p0){ return null; }
public static ByteString readFrom(InputStream p0){ return null; }
public static ByteString readFrom(InputStream p0, int p1){ return null; }
public static ByteString readFrom(InputStream p0, int p1, int p2){ return null; }
public static ByteString.Output newOutput(){ return null; }
public static ByteString.Output newOutput(int p0){ return null; }
public void copyTo(byte[] p0, int p1){}
public void copyTo(byte[] p0, int p1, int p2, int p3){}
static public class Output extends OutputStream
{
protected Output() {}
public ByteString toByteString(){ return null; }
public String toString(){ return null; }
public int size(){ return 0; }
public void reset(){}
public void write(byte[] p0, int p1, int p2){}
public void write(int p0){}
public void writeTo(OutputStream p0){}
}
static public interface ByteIterator extends Iterator<Byte>
{
byte nextByte();
}
}

View File

@@ -0,0 +1,60 @@
// Generated automatically from com.google.protobuf.CodedInputStream for testing purposes
package com.google.protobuf;
import com.google.protobuf.ByteString;
import com.google.protobuf.ExtensionRegistryLite;
import com.google.protobuf.MessageLite;
import com.google.protobuf.Parser;
import java.io.InputStream;
public class CodedInputStream
{
protected CodedInputStream() {}
public <T extends MessageLite> T readGroup(int p0, com.google.protobuf.Parser<T> p1, ExtensionRegistryLite p2){ return null; }
public <T extends MessageLite> T readMessage(com.google.protobuf.Parser<T> p0, ExtensionRegistryLite p1){ return null; }
public ByteString readBytes(){ return null; }
public String readString(){ return null; }
public boolean isAtEnd(){ return false; }
public boolean readBool(){ return false; }
public boolean skipField(int p0){ return false; }
public byte readRawByte(){ return 0; }
public byte[] readRawBytes(int p0){ return null; }
public double readDouble(){ return 0; }
public float readFloat(){ return 0; }
public int getBytesUntilLimit(){ return 0; }
public int getTotalBytesRead(){ return 0; }
public int pushLimit(int p0){ return 0; }
public int readEnum(){ return 0; }
public int readFixed32(){ return 0; }
public int readInt32(){ return 0; }
public int readRawLittleEndian32(){ return 0; }
public int readRawVarint32(){ return 0; }
public int readSFixed32(){ return 0; }
public int readSInt32(){ return 0; }
public int readTag(){ return 0; }
public int readUInt32(){ return 0; }
public int setRecursionLimit(int p0){ return 0; }
public int setSizeLimit(int p0){ return 0; }
public long readFixed64(){ return 0; }
public long readInt64(){ return 0; }
public long readRawLittleEndian64(){ return 0; }
public long readRawVarint64(){ return 0; }
public long readSFixed64(){ return 0; }
public long readSInt64(){ return 0; }
public long readUInt64(){ return 0; }
public static CodedInputStream newInstance(InputStream p0){ return null; }
public static CodedInputStream newInstance(byte[] p0){ return null; }
public static CodedInputStream newInstance(byte[] p0, int p1, int p2){ return null; }
public static int decodeZigZag32(int p0){ return 0; }
public static int readRawVarint32(int p0, InputStream p1){ return 0; }
public static long decodeZigZag64(long p0){ return 0; }
public void checkLastTagWas(int p0){}
public void popLimit(int p0){}
public void readGroup(int p0, MessageLite.Builder p1, ExtensionRegistryLite p2){}
public void readMessage(MessageLite.Builder p0, ExtensionRegistryLite p1){}
public void readUnknownGroup(int p0, MessageLite.Builder p1){}
public void resetSizeCounter(){}
public void skipMessage(){}
public void skipRawBytes(int p0){}
}

View File

@@ -0,0 +1,122 @@
// Generated automatically from com.google.protobuf.CodedOutputStream for testing purposes
package com.google.protobuf;
import com.google.protobuf.ByteString;
import com.google.protobuf.LazyField;
import com.google.protobuf.MessageLite;
import java.io.OutputStream;
public class CodedOutputStream
{
protected CodedOutputStream() {}
public int spaceLeft(){ return 0; }
public static CodedOutputStream newInstance(OutputStream p0){ return null; }
public static CodedOutputStream newInstance(OutputStream p0, int p1){ return null; }
public static CodedOutputStream newInstance(byte[] p0){ return null; }
public static CodedOutputStream newInstance(byte[] p0, int p1, int p2){ return null; }
public static int DEFAULT_BUFFER_SIZE = 0;
public static int LITTLE_ENDIAN_32_SIZE = 0;
public static int LITTLE_ENDIAN_64_SIZE = 0;
public static int computeBoolSize(int p0, boolean p1){ return 0; }
public static int computeBoolSizeNoTag(boolean p0){ return 0; }
public static int computeBytesSize(int p0, ByteString p1){ return 0; }
public static int computeBytesSizeNoTag(ByteString p0){ return 0; }
public static int computeDoubleSize(int p0, double p1){ return 0; }
public static int computeDoubleSizeNoTag(double p0){ return 0; }
public static int computeEnumSize(int p0, int p1){ return 0; }
public static int computeEnumSizeNoTag(int p0){ return 0; }
public static int computeFixed32Size(int p0, int p1){ return 0; }
public static int computeFixed32SizeNoTag(int p0){ return 0; }
public static int computeFixed64Size(int p0, long p1){ return 0; }
public static int computeFixed64SizeNoTag(long p0){ return 0; }
public static int computeFloatSize(int p0, float p1){ return 0; }
public static int computeFloatSizeNoTag(float p0){ return 0; }
public static int computeGroupSize(int p0, MessageLite p1){ return 0; }
public static int computeGroupSizeNoTag(MessageLite p0){ return 0; }
public static int computeInt32Size(int p0, int p1){ return 0; }
public static int computeInt32SizeNoTag(int p0){ return 0; }
public static int computeInt64Size(int p0, long p1){ return 0; }
public static int computeInt64SizeNoTag(long p0){ return 0; }
public static int computeLazyFieldMessageSetExtensionSize(int p0, LazyField p1){ return 0; }
public static int computeLazyFieldSize(int p0, LazyField p1){ return 0; }
public static int computeLazyFieldSizeNoTag(LazyField p0){ return 0; }
public static int computeMessageSetExtensionSize(int p0, MessageLite p1){ return 0; }
public static int computeMessageSize(int p0, MessageLite p1){ return 0; }
public static int computeMessageSizeNoTag(MessageLite p0){ return 0; }
public static int computeRawMessageSetExtensionSize(int p0, ByteString p1){ return 0; }
public static int computeRawVarint32Size(int p0){ return 0; }
public static int computeRawVarint64Size(long p0){ return 0; }
public static int computeSFixed32Size(int p0, int p1){ return 0; }
public static int computeSFixed32SizeNoTag(int p0){ return 0; }
public static int computeSFixed64Size(int p0, long p1){ return 0; }
public static int computeSFixed64SizeNoTag(long p0){ return 0; }
public static int computeSInt32Size(int p0, int p1){ return 0; }
public static int computeSInt32SizeNoTag(int p0){ return 0; }
public static int computeSInt64Size(int p0, long p1){ return 0; }
public static int computeSInt64SizeNoTag(long p0){ return 0; }
public static int computeStringSize(int p0, String p1){ return 0; }
public static int computeStringSizeNoTag(String p0){ return 0; }
public static int computeTagSize(int p0){ return 0; }
public static int computeUInt32Size(int p0, int p1){ return 0; }
public static int computeUInt32SizeNoTag(int p0){ return 0; }
public static int computeUInt64Size(int p0, long p1){ return 0; }
public static int computeUInt64SizeNoTag(long p0){ return 0; }
public static int computeUnknownGroupSize(int p0, MessageLite p1){ return 0; }
public static int computeUnknownGroupSizeNoTag(MessageLite p0){ return 0; }
public static int encodeZigZag32(int p0){ return 0; }
public static long encodeZigZag64(long p0){ return 0; }
public void checkNoSpaceLeft(){}
public void flush(){}
public void writeBool(int p0, boolean p1){}
public void writeBoolNoTag(boolean p0){}
public void writeBytes(int p0, ByteString p1){}
public void writeBytesNoTag(ByteString p0){}
public void writeDouble(int p0, double p1){}
public void writeDoubleNoTag(double p0){}
public void writeEnum(int p0, int p1){}
public void writeEnumNoTag(int p0){}
public void writeFixed32(int p0, int p1){}
public void writeFixed32NoTag(int p0){}
public void writeFixed64(int p0, long p1){}
public void writeFixed64NoTag(long p0){}
public void writeFloat(int p0, float p1){}
public void writeFloatNoTag(float p0){}
public void writeGroup(int p0, MessageLite p1){}
public void writeGroupNoTag(MessageLite p0){}
public void writeInt32(int p0, int p1){}
public void writeInt32NoTag(int p0){}
public void writeInt64(int p0, long p1){}
public void writeInt64NoTag(long p0){}
public void writeMessage(int p0, MessageLite p1){}
public void writeMessageNoTag(MessageLite p0){}
public void writeMessageSetExtension(int p0, MessageLite p1){}
public void writeRawByte(byte p0){}
public void writeRawByte(int p0){}
public void writeRawBytes(ByteString p0){}
public void writeRawBytes(ByteString p0, int p1, int p2){}
public void writeRawBytes(byte[] p0){}
public void writeRawBytes(byte[] p0, int p1, int p2){}
public void writeRawLittleEndian32(int p0){}
public void writeRawLittleEndian64(long p0){}
public void writeRawMessageSetExtension(int p0, ByteString p1){}
public void writeRawVarint32(int p0){}
public void writeRawVarint64(long p0){}
public void writeSFixed32(int p0, int p1){}
public void writeSFixed32NoTag(int p0){}
public void writeSFixed64(int p0, long p1){}
public void writeSFixed64NoTag(long p0){}
public void writeSInt32(int p0, int p1){}
public void writeSInt32NoTag(int p0){}
public void writeSInt64(int p0, long p1){}
public void writeSInt64NoTag(long p0){}
public void writeString(int p0, String p1){}
public void writeStringNoTag(String p0){}
public void writeTag(int p0, int p1){}
public void writeUInt32(int p0, int p1){}
public void writeUInt32NoTag(int p0){}
public void writeUInt64(int p0, long p1){}
public void writeUInt64NoTag(long p0){}
public void writeUnknownGroup(int p0, MessageLite p1){}
public void writeUnknownGroupNoTag(MessageLite p0){}
}

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More