зеркало из https://github.com/github/codeql.git
Merge pull request #1406 from taus-semmle/mergeback-rc/1.21
Merge `rc/1.21` into `master`
This commit is contained in:
Коммит
e11406ca90
|
@ -13,6 +13,10 @@
|
|||
* The following C# 8 features are now extracted:
|
||||
- Range expressions
|
||||
- Recursive patterns
|
||||
- Using declaration statements
|
||||
- `static` modifiers on local functions
|
||||
- Null-coalescing assignment expressions
|
||||
|
||||
* The `unmanaged` type parameter constraint is now extracted.
|
||||
|
||||
## Changes to QL libraries
|
||||
|
@ -20,6 +24,7 @@
|
|||
* The class `Attribute` has two new predicates: `getConstructorArgument()` and `getNamedArgument()`. The first predicate returns arguments to the underlying constructor call and the latter returns named arguments for initializing fields and properties.
|
||||
* The class `TypeParameterConstraints` has a new predicate `hasUnmanagedTypeConstraint()`, indicating that the type parameter has the `unmanaged` constraint.
|
||||
* The following QL classes have been added to model C# 8 features:
|
||||
- Class `AssignCoalesceExpr` models null-coalescing assignment, for example `x ??= y`
|
||||
- Class `IndexExpr` models from-end index expressions, for example `^1`
|
||||
- Class `PatternExpr` is an `Expr` that appears in a pattern. It has the new subclasses `DiscardPatternExpr`, `LabeledPatternExpr`, `RecursivePatternExpr`, `TypeAccessPatternExpr`, `TypePatternExpr`, and `VariablePatternExpr`.
|
||||
- Class `PatternMatch` models a pattern being matched. It has the subclasses `Case` and `IsExpr`.
|
||||
|
@ -31,5 +36,6 @@
|
|||
- Classes `IsConstantExpr`, `IsTypeExpr` and `IsPatternExpr` are deprecated in favour of `IsExpr`
|
||||
- Class `Switch` models both `SwitchExpr` and `SwitchStmt`
|
||||
- Class `Case` models both `CaseStmt` and `SwitchCaseExpr`
|
||||
- Class `UsingStmt` models both `UsingBlockStmt` and `UsingDeclStmt`
|
||||
|
||||
## Changes to autobuilder
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
| Expression has no effect | Fewer false-positive results | This rule now treats uses of `Object.defineProperty` more conservatively. |
|
||||
| Incomplete regular expression for hostnames | More results | This rule now tracks regular expressions for host names further. |
|
||||
| Incomplete string escaping or encoding | More results | This rule now considers the flow of regular expressions literals, and it no longer flags the removal of trailing newlines. |
|
||||
| Password in configuration file | Fewer false positive results | This query now excludes passwords that are inserted into the configuration file using a templating mechanism or read from environment variables. |
|
||||
| Password in configuration file | Fewer false positive results | This query now excludes passwords that are inserted into the configuration file using a templating mechanism or read from environment variables. Results are no longer shown on LGTM by default. |
|
||||
| Replacement of a substring with itself | More results | This rule now considers the flow of regular expressions literals. |
|
||||
| Server-side URL redirect | Fewer false-positive results | This rule now treats URLs as safe in more cases where the hostname cannot be tampered with. |
|
||||
| Type confusion through parameter tampering | Fewer false-positive results | This rule now recognizes additional emptiness checks. |
|
||||
|
|
|
@ -71,6 +71,8 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
|||
return ExprKind.ASSIGN_LSHIFT;
|
||||
case SyntaxKind.GreaterThanGreaterThanEqualsToken:
|
||||
return ExprKind.ASSIGN_RSHIFT;
|
||||
case SyntaxKind.QuestionQuestionEqualsToken:
|
||||
return ExprKind.ASSIGN_COALESCE;
|
||||
default:
|
||||
cx.ModelError(syntax, "Unrecognised assignment type " + GetKind(cx, syntax));
|
||||
return ExprKind.UNKNOWN;
|
||||
|
@ -142,6 +144,8 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
|||
return ExprKind.SUB;
|
||||
case ExprKind.ASSIGN_XOR:
|
||||
return ExprKind.BIT_XOR;
|
||||
case ExprKind.ASSIGN_COALESCE:
|
||||
return ExprKind.NULL_COALESCING;
|
||||
default:
|
||||
cx.ModelError(Syntax, "Couldn't unfold assignment of type " + kind);
|
||||
return ExprKind.UNKNOWN;
|
||||
|
|
|
@ -80,6 +80,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
|||
case SyntaxKind.RightShiftAssignmentExpression:
|
||||
case SyntaxKind.DivideAssignmentExpression:
|
||||
case SyntaxKind.ModuloAssignmentExpression:
|
||||
case SyntaxKind.CoalesceAssignmentExpression:
|
||||
return Assignment.Create(info);
|
||||
|
||||
case SyntaxKind.ObjectCreationExpression:
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using System.Linq;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
|
@ -39,6 +41,18 @@ namespace Semmle.Extraction.CSharp.Entities
|
|||
public override void Populate()
|
||||
{
|
||||
PopulateMethod();
|
||||
|
||||
// There is a "bug" in Roslyn whereby the IMethodSymbol associated with the local function symbol
|
||||
// is always static, so we need to go to the syntax reference of the local function to see whether
|
||||
// the "static" modifier is present.
|
||||
if (symbol.DeclaringSyntaxReferences.SingleOrDefault().GetSyntax() is LocalFunctionStatementSyntax fn)
|
||||
{
|
||||
foreach(var modifier in fn.Modifiers)
|
||||
{
|
||||
Modifier.HasModifier(Context, this, modifier.Text);
|
||||
}
|
||||
}
|
||||
|
||||
var originalDefinition = IsSourceDeclaration ? this : Create(Context, symbol.OriginalDefinition);
|
||||
var returnType = Type.Create(Context, symbol.ReturnType);
|
||||
Context.Emit(Tuples.local_functions(this, symbol.Name, returnType, originalDefinition));
|
||||
|
|
|
@ -6,8 +6,19 @@ namespace Semmle.Extraction.CSharp.Entities.Statements
|
|||
{
|
||||
class LocalDeclaration : Statement<LocalDeclarationStatementSyntax>
|
||||
{
|
||||
static StmtKind GetKind(LocalDeclarationStatementSyntax declStmt)
|
||||
{
|
||||
if (declStmt.UsingKeyword.RawKind != 0)
|
||||
return StmtKind.USING_DECL;
|
||||
|
||||
if (declStmt.IsConst)
|
||||
return StmtKind.CONST_DECL;
|
||||
|
||||
return StmtKind.VAR_DECL;
|
||||
}
|
||||
|
||||
LocalDeclaration(Context cx, LocalDeclarationStatementSyntax declStmt, IStatementParentEntity parent, int child)
|
||||
: base(cx, declStmt, declStmt.IsConst ? StmtKind.CONST_DECL : StmtKind.VAR_DECL, parent, child) { }
|
||||
: base(cx, declStmt, GetKind(declStmt), parent, child) { }
|
||||
|
||||
public static LocalDeclaration Create(Context cx, LocalDeclarationStatementSyntax node, IStatementParentEntity parent, int child)
|
||||
{
|
||||
|
|
|
@ -112,6 +112,7 @@ namespace Semmle.Extraction.Kinds
|
|||
RECURSIVE_PATTERN = 115,
|
||||
PROPERTY_PATTERN = 116,
|
||||
POSITIONAL_PATTERN = 117,
|
||||
SWITCH_CASE = 118
|
||||
SWITCH_CASE = 118,
|
||||
ASSIGN_COALESCE = 119
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ namespace Semmle.Extraction.Kinds // lgtm[cs/similar-file]
|
|||
LABEL = 27,
|
||||
CATCH = 28,
|
||||
CASE = 29,
|
||||
LOCAL_FUNCTION = 30
|
||||
LOCAL_FUNCTION = 30,
|
||||
USING_DECL = 31
|
||||
}
|
||||
}
|
||||
|
|
|
@ -903,7 +903,7 @@ class ExplicitConversionOperator extends ConversionOperator {
|
|||
* }
|
||||
* ```
|
||||
*/
|
||||
class LocalFunction extends Callable, @local_function {
|
||||
class LocalFunction extends Callable, Modifiable, @local_function {
|
||||
override string getName() { local_functions(this, result, _, _) }
|
||||
|
||||
override LocalFunction getSourceDeclaration() { local_functions(this, _, _, result) }
|
||||
|
|
|
@ -1115,40 +1115,16 @@ class LockStmt extends Stmt, @lock_stmt {
|
|||
}
|
||||
|
||||
/**
|
||||
* A `using` statement, for example
|
||||
*
|
||||
* ```
|
||||
* using (FileStream f = File.Open("settings.xml")) {
|
||||
* ...
|
||||
* }
|
||||
* ```
|
||||
* A using block or declaration. Either a using declaration (`UsingDeclStmt`) or
|
||||
* a using block (`UsingBlockStmt`).
|
||||
*/
|
||||
class UsingStmt extends Stmt, @using_stmt {
|
||||
/** Gets the `i`th local variable of this `using` statement. */
|
||||
LocalVariable getVariable(int i) { result = this.getVariableDeclExpr(i).getVariable() }
|
||||
|
||||
/** Gets a local variable of this `using` statement. */
|
||||
LocalVariable getAVariable() { result = this.getVariable(_) }
|
||||
|
||||
/** Gets the `i`th local variable declaration of this `using` statement. */
|
||||
LocalVariableDeclExpr getVariableDeclExpr(int i) { result = this.getChild(-i - 1) }
|
||||
LocalVariableDeclExpr getVariableDeclExpr(int i) { none() }
|
||||
|
||||
/** Gets a local variable declaration of this `using` statement. */
|
||||
LocalVariableDeclExpr getAVariableDeclExpr() { result = this.getVariableDeclExpr(_) }
|
||||
|
||||
/**
|
||||
* Gets the expression directly used by this `using` statement, if any. For
|
||||
* example, `f` on line 2 in
|
||||
*
|
||||
* ```
|
||||
* var f = File.Open("settings.xml");
|
||||
* using (f) {
|
||||
* ...
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
Expr getExpr() { result = this.getChild(0) }
|
||||
|
||||
/**
|
||||
* Gets an expression that is used in this `using` statement. Either an
|
||||
* expression assigned to a variable, for example `File.Open("settings.xml")`
|
||||
|
@ -1169,14 +1145,69 @@ class UsingStmt extends Stmt, @using_stmt {
|
|||
* }
|
||||
* ```
|
||||
*/
|
||||
Expr getAnExpr() {
|
||||
Expr getAnExpr() { none() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use UsingBlockStmt.getExpr() instead.
|
||||
* Gets the expression directly used by this `using` statement, if any. For
|
||||
* example, `f` on line 2 in
|
||||
*
|
||||
* ```
|
||||
* var f = File.Open("settings.xml");
|
||||
* using (f) {
|
||||
* ...
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
deprecated Expr getExpr() { none() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use UsingBlockStmt.getBody() instead.
|
||||
* Gets the body of this `using` statement.
|
||||
*/
|
||||
deprecated Stmt getBody() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A `using` block statement, for example
|
||||
*
|
||||
* ```
|
||||
* using (FileStream f = File.Open("settings.xml")) {
|
||||
* ...
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class UsingBlockStmt extends UsingStmt, @using_block_stmt {
|
||||
/** Gets the `i`th local variable of this `using` statement. */
|
||||
LocalVariable getVariable(int i) { result = this.getVariableDeclExpr(i).getVariable() }
|
||||
|
||||
/** Gets a local variable of this `using` statement. */
|
||||
LocalVariable getAVariable() { result = this.getVariable(_) }
|
||||
|
||||
/** Gets the `i`th local variable declaration of this `using` statement. */
|
||||
override LocalVariableDeclExpr getVariableDeclExpr(int i) { result = this.getChild(-i - 1) }
|
||||
|
||||
/**
|
||||
* Gets the expression directly used by this `using` statement, if any. For
|
||||
* example, `f` on line 2 in
|
||||
*
|
||||
* ```
|
||||
* var f = File.Open("settings.xml");
|
||||
* using (f) {
|
||||
* ...
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
override Expr getExpr() { result = this.getChild(0) }
|
||||
|
||||
override Expr getAnExpr() {
|
||||
result = this.getAVariableDeclExpr().getInitializer()
|
||||
or
|
||||
result = this.getExpr()
|
||||
}
|
||||
|
||||
/** Gets the body of this `using` statement. */
|
||||
Stmt getBody() { result.getParent() = this }
|
||||
override Stmt getBody() { result.getParent() = this }
|
||||
|
||||
override string toString() { result = "using (...) {...}" }
|
||||
}
|
||||
|
@ -1254,6 +1285,29 @@ class LocalConstantDeclStmt extends LocalVariableDeclStmt, @const_decl_stmt {
|
|||
override string toString() { result = "const ... ...;" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A `using` declaration statement, for example
|
||||
*
|
||||
* ```
|
||||
* using FileStream f = File.Open("settings.xml");
|
||||
* ```
|
||||
*/
|
||||
class UsingDeclStmt extends LocalVariableDeclStmt, UsingStmt, @using_decl_stmt {
|
||||
override string toString() { result = "using ... ...;" }
|
||||
|
||||
override LocalVariableDeclExpr getAVariableDeclExpr() {
|
||||
result = LocalVariableDeclStmt.super.getAVariableDeclExpr()
|
||||
}
|
||||
|
||||
override LocalVariableDeclExpr getVariableDeclExpr(int n) {
|
||||
result = LocalVariableDeclStmt.super.getVariableDeclExpr(n)
|
||||
}
|
||||
|
||||
override Expr getAnExpr() {
|
||||
result = this.getAVariableDeclExpr().getInitializer()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An empty statement, for example line 2 in
|
||||
*
|
||||
|
|
|
@ -468,7 +468,7 @@ module ControlFlow {
|
|||
override ControlFlowElement getChildElement(int i) {
|
||||
not this instanceof GeneralCatchClause and
|
||||
not this instanceof FixedStmt and
|
||||
not this instanceof UsingStmt and
|
||||
not this instanceof UsingBlockStmt and
|
||||
result = this.getChild(i)
|
||||
or
|
||||
this = any(GeneralCatchClause gcc | i = 0 and result = gcc.getBlock())
|
||||
|
@ -480,7 +480,7 @@ module ControlFlow {
|
|||
i = max(int j | exists(fs.getVariableDeclExpr(j))) + 1
|
||||
)
|
||||
or
|
||||
this = any(UsingStmt us |
|
||||
this = any(UsingBlockStmt us |
|
||||
if exists(us.getExpr())
|
||||
then (
|
||||
result = us.getExpr() and
|
||||
|
|
|
@ -230,3 +230,10 @@ class AddEventExpr extends AddOrRemoveEventExpr, @add_event_expr {
|
|||
class RemoveEventExpr extends AddOrRemoveEventExpr, @remove_event_expr {
|
||||
override string toString() { result = "... -= ..." }
|
||||
}
|
||||
|
||||
/**
|
||||
* A null-coalescing assignment operation, for example `x ??= y`.
|
||||
*/
|
||||
class AssignCoalesceExpr extends AssignOperation, @assign_coalesce_expr {
|
||||
override string toString() { result = "... ??= ..." }
|
||||
}
|
||||
|
|
|
@ -526,7 +526,7 @@ specific_type_parameter_constraints(
|
|||
|
||||
@modifiable = @modifiable_direct | @event_accessor;
|
||||
|
||||
@modifiable_direct = @member | @accessor;
|
||||
@modifiable_direct = @member | @accessor | @local_function;
|
||||
|
||||
modifiers(
|
||||
unique int id: @modifier,
|
||||
|
@ -798,7 +798,7 @@ case @stmt.kind of
|
|||
| 18 = @checked_stmt
|
||||
| 19 = @unchecked_stmt
|
||||
| 20 = @lock_stmt
|
||||
| 21 = @using_stmt
|
||||
| 21 = @using_block_stmt
|
||||
| 22 = @var_decl_stmt
|
||||
| 23 = @const_decl_stmt
|
||||
| 24 = @empty_stmt
|
||||
|
@ -808,11 +808,14 @@ case @stmt.kind of
|
|||
| 28 = @catch
|
||||
| 29 = @case_stmt
|
||||
| 30 = @local_function_stmt
|
||||
| 31 = @using_decl_stmt
|
||||
;
|
||||
|
||||
@using_stmt = @using_block_stmt | @using_decl_stmt;
|
||||
|
||||
@labeled_stmt = @label_stmt | @case;
|
||||
|
||||
@decl_stmt = @var_decl_stmt | @const_decl_stmt;
|
||||
@decl_stmt = @var_decl_stmt | @const_decl_stmt | @using_decl_stmt;
|
||||
|
||||
@cond_stmt = @if_stmt | @switch_stmt;
|
||||
|
||||
|
@ -983,6 +986,7 @@ case @expr.kind of
|
|||
| 116 = @property_pattern_expr
|
||||
| 117 = @positional_pattern_expr
|
||||
| 118 = @switch_case_expr
|
||||
| 119 = @assign_coalesce_expr
|
||||
;
|
||||
|
||||
@switch = @switch_stmt | @switch_expr;
|
||||
|
@ -995,7 +999,7 @@ case @expr.kind of
|
|||
| @string_literal_expr | @null_literal_expr;
|
||||
|
||||
@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr;
|
||||
@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr;
|
||||
@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr;
|
||||
@assign_event_expr = @add_event_expr | @remove_event_expr;
|
||||
|
||||
@assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr
|
||||
|
|
|
@ -360,10 +360,14 @@
|
|||
<v>1854</v>
|
||||
</e>
|
||||
<e>
|
||||
<k>@using_stmt</k>
|
||||
<k>@using_block_stmt</k>
|
||||
<v>5815</v>
|
||||
</e>
|
||||
<e>
|
||||
<k>@using_decl_stmt</k>
|
||||
<v>1000</v>
|
||||
</e>
|
||||
<e>
|
||||
<k>@var_decl_stmt</k>
|
||||
<v>243866</v>
|
||||
</e>
|
||||
|
@ -688,6 +692,10 @@
|
|||
<v>116</v>
|
||||
</e>
|
||||
<e>
|
||||
<k>@assign_coalesce_expr</k>
|
||||
<v>116</v>
|
||||
</e>
|
||||
<e>
|
||||
<k>@object_init_expr</k>
|
||||
<v>5320</v>
|
||||
</e>
|
||||
|
|
|
@ -104,6 +104,7 @@
|
|||
| Assignables.cs:133:15:133:15 | access to local variable x | Assignables.cs:132:13:132:13 | x | read |
|
||||
| Assignables.cs:133:15:133:15 | access to local variable x | Assignables.cs:132:13:132:13 | x | write |
|
||||
| Assignables.cs:133:29:133:29 | String s | Assignables.cs:133:29:133:29 | s | write |
|
||||
| Assignables.cs:138:19:138:19 | access to local variable x | Assignables.cs:138:19:138:19 | x | write |
|
||||
| Discards.cs:7:9:7:9 | access to parameter x | Discards.cs:5:30:5:30 | x | write |
|
||||
| Discards.cs:20:32:20:32 | Boolean z | Discards.cs:20:32:20:32 | z | write |
|
||||
| Discards.cs:25:27:25:30 | access to parameter args | Discards.cs:23:27:23:30 | args | read |
|
||||
|
|
|
@ -87,6 +87,7 @@
|
|||
| Assignables.cs:132:13:132:13 | x | Assignables.cs:132:13:132:17 | Int32 x = ... | Assignables.cs:132:13:132:13 | access to local variable x | Assignables.cs:132:17:132:17 | 0 | certain |
|
||||
| Assignables.cs:132:13:132:13 | x | Assignables.cs:133:15:133:15 | access to local variable x | Assignables.cs:133:15:133:15 | access to local variable x | Assignables.cs:133:15:133:15 | <none> | certain |
|
||||
| Assignables.cs:133:29:133:29 | s | Assignables.cs:133:29:133:29 | String s | Assignables.cs:133:29:133:29 | String s | Assignables.cs:133:29:133:29 | <none> | certain |
|
||||
| Assignables.cs:138:19:138:19 | x | Assignables.cs:138:19:138:50 | MemoryStream x = ... | Assignables.cs:138:19:138:19 | access to local variable x | Assignables.cs:138:23:138:50 | object creation of type MemoryStream | certain |
|
||||
| Discards.cs:5:30:5:30 | x | Discards.cs:5:30:5:30 | x | Discards.cs:5:30:5:30 | <none> | Discards.cs:5:30:5:30 | <none> | certain |
|
||||
| Discards.cs:5:30:5:30 | x | Discards.cs:7:9:7:17 | ... = ... | Discards.cs:7:9:7:9 | access to parameter x | Discards.cs:7:13:7:17 | false | certain |
|
||||
| Discards.cs:19:14:19:14 | x | Discards.cs:19:9:19:29 | ... = ... | Discards.cs:19:9:19:29 | <none> | Discards.cs:19:9:19:29 | <none> | certain |
|
||||
|
|
|
@ -86,6 +86,7 @@
|
|||
| Assignables.cs:132:13:132:17 | Int32 x = ... | Assignables.cs:132:13:132:17 | Int32 x = ... |
|
||||
| Assignables.cs:133:15:133:15 | access to local variable x | Assignables.cs:133:9:133:30 | delegate call |
|
||||
| Assignables.cs:133:29:133:29 | String s | Assignables.cs:133:9:133:30 | delegate call |
|
||||
| Assignables.cs:138:19:138:50 | MemoryStream x = ... | Assignables.cs:138:19:138:50 | MemoryStream x = ... |
|
||||
| Discards.cs:5:30:5:30 | x | Discards.cs:5:19:5:19 | enter f |
|
||||
| Discards.cs:7:9:7:17 | ... = ... | Discards.cs:7:9:7:17 | ... = ... |
|
||||
| Discards.cs:13:9:13:20 | ... = ... | Discards.cs:13:9:13:20 | ... = ... |
|
||||
|
|
|
@ -132,4 +132,11 @@ class Assignables
|
|||
var x = 0;
|
||||
d(ref x, out string s);
|
||||
}
|
||||
|
||||
void UsingDeclarations()
|
||||
{
|
||||
using var x = new System.IO.MemoryStream();
|
||||
}
|
||||
}
|
||||
|
||||
// semmle-extractor-options: /langversion:8.0
|
||||
|
|
|
@ -95,6 +95,7 @@
|
|||
| Assignables.cs:130:31:130:31 | d |
|
||||
| Assignables.cs:132:13:132:13 | x |
|
||||
| Assignables.cs:133:29:133:29 | s |
|
||||
| Assignables.cs:138:19:138:19 | x |
|
||||
| Discards.cs:5:6:5:8 | Item1 |
|
||||
| Discards.cs:5:11:5:16 | Item2 |
|
||||
| Discards.cs:5:30:5:30 | x |
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
| Assignables.cs:125:13:125:13 | s | Assignables.cs:125:17:125:25 | nameof(...) |
|
||||
| Assignables.cs:125:13:125:13 | s | Assignables.cs:126:13:126:30 | nameof(...) |
|
||||
| Assignables.cs:132:13:132:13 | x | Assignables.cs:132:17:132:17 | 0 |
|
||||
| Assignables.cs:138:19:138:19 | x | Assignables.cs:138:23:138:50 | object creation of type MemoryStream |
|
||||
| Discards.cs:5:30:5:30 | x | Discards.cs:7:13:7:17 | false |
|
||||
| Finally.cs:7:13:7:13 | i | Finally.cs:7:17:7:17 | 0 |
|
||||
| Finally.cs:7:13:7:13 | i | Finally.cs:15:17:15:17 | 1 |
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
|
||||
class NullCoalescingAssignment
|
||||
{
|
||||
void NullCoalescing()
|
||||
{
|
||||
object o = null;
|
||||
o ??= this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
nullcoalescing
|
||||
| NullCoalescingAssignment.cs:8:9:8:18 | ... ?? ... |
|
||||
assignments
|
||||
| NullCoalescingAssignment.cs:8:9:8:18 | ... ??= ... | NullCoalescingAssignment.cs:8:9:8:18 | ... = ... |
|
|
@ -0,0 +1,7 @@
|
|||
import csharp
|
||||
|
||||
query predicate nullcoalescing(NullCoalescingExpr expr) { any() }
|
||||
|
||||
query predicate assignments(AssignCoalesceExpr expr, Expr expanded) {
|
||||
expanded = expr.getExpandedAssignment()
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
| NullCoalescingAssignment.cs:5:10:5:23 | enter NullCoalescing | NullCoalescingAssignment.cs:6:5:9:5 | {...} | semmle.label | successor |
|
||||
| NullCoalescingAssignment.cs:6:5:9:5 | {...} | NullCoalescingAssignment.cs:7:9:7:24 | ... ...; | semmle.label | successor |
|
||||
| NullCoalescingAssignment.cs:7:9:7:24 | ... ...; | NullCoalescingAssignment.cs:7:20:7:23 | null | semmle.label | successor |
|
||||
| NullCoalescingAssignment.cs:7:16:7:23 | Object o = ... | NullCoalescingAssignment.cs:8:9:8:19 | ...; | semmle.label | successor |
|
||||
| NullCoalescingAssignment.cs:7:20:7:23 | null | NullCoalescingAssignment.cs:7:16:7:23 | Object o = ... | semmle.label | successor |
|
||||
| NullCoalescingAssignment.cs:8:9:8:9 | access to local variable o | NullCoalescingAssignment.cs:8:9:8:18 | ... = ... | semmle.label | non-null |
|
||||
| NullCoalescingAssignment.cs:8:9:8:9 | access to local variable o | NullCoalescingAssignment.cs:8:15:8:18 | this access | semmle.label | null |
|
||||
| NullCoalescingAssignment.cs:8:9:8:18 | ... = ... | NullCoalescingAssignment.cs:5:10:5:23 | exit NullCoalescing | semmle.label | successor |
|
||||
| NullCoalescingAssignment.cs:8:9:8:18 | ... ?? ... | NullCoalescingAssignment.cs:8:9:8:9 | access to local variable o | semmle.label | successor |
|
||||
| NullCoalescingAssignment.cs:8:9:8:19 | ...; | NullCoalescingAssignment.cs:8:9:8:18 | ... ?? ... | semmle.label | successor |
|
||||
| NullCoalescingAssignment.cs:8:15:8:18 | this access | NullCoalescingAssignment.cs:8:9:8:18 | ... = ... | semmle.label | successor |
|
|
@ -0,0 +1,10 @@
|
|||
import csharp
|
||||
import semmle.code.csharp.controlflow.ControlFlowGraph
|
||||
|
||||
query predicate edges(ControlFlow::Node node1, ControlFlow::Node node2, string label, string value) {
|
||||
label = "semmle.label" and
|
||||
exists(ControlFlow::SuccessorType t |
|
||||
node2 = node1.getASuccessorByType(t) and value = t.toString()
|
||||
)
|
||||
and node1.getEnclosingCallable().hasName("NullCoalescing")
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
using System;
|
||||
|
||||
class StaticLocalFunction
|
||||
{
|
||||
int F()
|
||||
{
|
||||
static int G(int x) => x;
|
||||
return G(12);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
// semmle-extractor-options: /langversion:8.0
|
||||
|
||||
using System;
|
||||
|
||||
class StaticLocalFunctions
|
||||
{
|
||||
int Fn(int x)
|
||||
{
|
||||
static int I(int y) => y;
|
||||
int J(int y) => x+y;
|
||||
return I(x) + J(x);
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
| StaticLocalFunctions.cs:9:9:9:33 | I | static |
|
|
@ -0,0 +1,5 @@
|
|||
import csharp
|
||||
|
||||
from LocalFunction fn, string modifier
|
||||
where fn.hasModifier(modifier)
|
||||
select fn, modifier
|
|
@ -0,0 +1,26 @@
|
|||
| UsingDeclarations.cs:6:10:6:30 | enter TestUsingDeclarations | UsingDeclarations.cs:7:5:16:5 | {...} | semmle.label | successor |
|
||||
| UsingDeclarations.cs:7:5:16:5 | {...} | UsingDeclarations.cs:8:9:8:116 | using ... ...; | semmle.label | successor |
|
||||
| UsingDeclarations.cs:8:9:8:116 | using ... ...; | UsingDeclarations.cs:8:49:8:53 | "..." | semmle.label | successor |
|
||||
| UsingDeclarations.cs:8:26:8:69 | FileStream file1 = ... | UsingDeclarations.cs:8:95:8:99 | "..." | semmle.label | successor |
|
||||
| UsingDeclarations.cs:8:34:8:69 | object creation of type FileStream | UsingDeclarations.cs:8:26:8:69 | FileStream file1 = ... | semmle.label | successor |
|
||||
| UsingDeclarations.cs:8:49:8:53 | "..." | UsingDeclarations.cs:8:56:8:68 | access to constant Open | semmle.label | successor |
|
||||
| UsingDeclarations.cs:8:56:8:68 | access to constant Open | UsingDeclarations.cs:8:34:8:69 | object creation of type FileStream | semmle.label | successor |
|
||||
| UsingDeclarations.cs:8:72:8:115 | FileStream file2 = ... | UsingDeclarations.cs:10:9:12:9 | using (...) {...} | semmle.label | successor |
|
||||
| UsingDeclarations.cs:8:80:8:115 | object creation of type FileStream | UsingDeclarations.cs:8:72:8:115 | FileStream file2 = ... | semmle.label | successor |
|
||||
| UsingDeclarations.cs:8:95:8:99 | "..." | UsingDeclarations.cs:8:102:8:114 | access to constant Open | semmle.label | successor |
|
||||
| UsingDeclarations.cs:8:102:8:114 | access to constant Open | UsingDeclarations.cs:8:80:8:115 | object creation of type FileStream | semmle.label | successor |
|
||||
| UsingDeclarations.cs:10:9:12:9 | using (...) {...} | UsingDeclarations.cs:10:49:10:53 | "..." | semmle.label | successor |
|
||||
| UsingDeclarations.cs:10:26:10:69 | FileStream file3 = ... | UsingDeclarations.cs:10:95:10:99 | "..." | semmle.label | successor |
|
||||
| UsingDeclarations.cs:10:34:10:69 | object creation of type FileStream | UsingDeclarations.cs:10:26:10:69 | FileStream file3 = ... | semmle.label | successor |
|
||||
| UsingDeclarations.cs:10:49:10:53 | "..." | UsingDeclarations.cs:10:56:10:68 | access to constant Open | semmle.label | successor |
|
||||
| UsingDeclarations.cs:10:56:10:68 | access to constant Open | UsingDeclarations.cs:10:34:10:69 | object creation of type FileStream | semmle.label | successor |
|
||||
| UsingDeclarations.cs:10:72:10:115 | FileStream file4 = ... | UsingDeclarations.cs:11:9:12:9 | {...} | semmle.label | successor |
|
||||
| UsingDeclarations.cs:10:80:10:115 | object creation of type FileStream | UsingDeclarations.cs:10:72:10:115 | FileStream file4 = ... | semmle.label | successor |
|
||||
| UsingDeclarations.cs:10:95:10:99 | "..." | UsingDeclarations.cs:10:102:10:114 | access to constant Open | semmle.label | successor |
|
||||
| UsingDeclarations.cs:10:102:10:114 | access to constant Open | UsingDeclarations.cs:10:80:10:115 | object creation of type FileStream | semmle.label | successor |
|
||||
| UsingDeclarations.cs:11:9:12:9 | {...} | UsingDeclarations.cs:14:9:15:13 | using (...) {...} | semmle.label | successor |
|
||||
| UsingDeclarations.cs:14:9:15:13 | using (...) {...} | UsingDeclarations.cs:14:30:14:34 | "..." | semmle.label | successor |
|
||||
| UsingDeclarations.cs:14:15:14:50 | object creation of type FileStream | UsingDeclarations.cs:15:13:15:13 | ; | semmle.label | successor |
|
||||
| UsingDeclarations.cs:14:30:14:34 | "..." | UsingDeclarations.cs:14:37:14:49 | access to constant Open | semmle.label | successor |
|
||||
| UsingDeclarations.cs:14:37:14:49 | access to constant Open | UsingDeclarations.cs:14:15:14:50 | object creation of type FileStream | semmle.label | successor |
|
||||
| UsingDeclarations.cs:15:13:15:13 | ; | UsingDeclarations.cs:6:10:6:30 | exit TestUsingDeclarations | semmle.label | successor |
|
|
@ -0,0 +1,10 @@
|
|||
import csharp
|
||||
import semmle.code.csharp.controlflow.ControlFlowGraph
|
||||
|
||||
query predicate edges(ControlFlow::Node node1, ControlFlow::Node node2, string label, string value) {
|
||||
label = "semmle.label" and
|
||||
exists(ControlFlow::SuccessorType t |
|
||||
node2 = node1.getASuccessorByType(t) and value = t.toString()
|
||||
)
|
||||
and node1.getEnclosingCallable().hasName("TestUsingDeclarations")
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
class UsingDeclarations
|
||||
{
|
||||
void TestUsingDeclarations()
|
||||
{
|
||||
using FileStream file1 = new FileStream("...", FileMode.Open), file2 = new FileStream("...", FileMode.Open);
|
||||
|
||||
using(FileStream file3 = new FileStream("...", FileMode.Open), file4 = new FileStream("...", FileMode.Open))
|
||||
{
|
||||
}
|
||||
|
||||
using(new FileStream("...", FileMode.Open))
|
||||
;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
localVars
|
||||
| UsingDeclarations.cs:8:26:8:30 | file1 |
|
||||
| UsingDeclarations.cs:8:72:8:76 | file2 |
|
||||
| UsingDeclarations.cs:10:26:10:30 | file3 |
|
||||
| UsingDeclarations.cs:10:72:10:76 | file4 |
|
||||
localVariableDeclarations
|
||||
| UsingDeclarations.cs:8:9:8:116 | using ... ...; | 0 | UsingDeclarations.cs:8:26:8:69 | FileStream file1 = ... |
|
||||
| UsingDeclarations.cs:8:9:8:116 | using ... ...; | 1 | UsingDeclarations.cs:8:72:8:115 | FileStream file2 = ... |
|
||||
usingStmts1
|
||||
| UsingDeclarations.cs:8:9:8:116 | using ... ...; |
|
||||
| UsingDeclarations.cs:10:9:12:9 | using (...) {...} |
|
||||
| UsingDeclarations.cs:14:9:15:13 | using (...) {...} |
|
||||
usingStmts
|
||||
| UsingDeclarations.cs:8:9:8:116 | using ... ...; | 0 | UsingDeclarations.cs:8:26:8:69 | FileStream file1 = ... |
|
||||
| UsingDeclarations.cs:8:9:8:116 | using ... ...; | 1 | UsingDeclarations.cs:8:72:8:115 | FileStream file2 = ... |
|
||||
| UsingDeclarations.cs:10:9:12:9 | using (...) {...} | 0 | UsingDeclarations.cs:10:26:10:69 | FileStream file3 = ... |
|
||||
| UsingDeclarations.cs:10:9:12:9 | using (...) {...} | 1 | UsingDeclarations.cs:10:72:10:115 | FileStream file4 = ... |
|
||||
usingDecls
|
||||
| UsingDeclarations.cs:8:9:8:116 | using ... ...; | 0 | UsingDeclarations.cs:8:26:8:69 | FileStream file1 = ... |
|
||||
| UsingDeclarations.cs:8:9:8:116 | using ... ...; | 1 | UsingDeclarations.cs:8:72:8:115 | FileStream file2 = ... |
|
||||
usingExprs
|
||||
| UsingDeclarations.cs:8:9:8:116 | using ... ...; | UsingDeclarations.cs:8:34:8:69 | object creation of type FileStream |
|
||||
| UsingDeclarations.cs:8:9:8:116 | using ... ...; | UsingDeclarations.cs:8:80:8:115 | object creation of type FileStream |
|
||||
| UsingDeclarations.cs:10:9:12:9 | using (...) {...} | UsingDeclarations.cs:10:34:10:69 | object creation of type FileStream |
|
||||
| UsingDeclarations.cs:10:9:12:9 | using (...) {...} | UsingDeclarations.cs:10:80:10:115 | object creation of type FileStream |
|
||||
| UsingDeclarations.cs:14:9:15:13 | using (...) {...} | UsingDeclarations.cs:14:15:14:50 | object creation of type FileStream |
|
|
@ -0,0 +1,22 @@
|
|||
import csharp
|
||||
|
||||
query predicate localVars(LocalVariable decl) {
|
||||
decl.getEnclosingCallable().hasName("TestUsingDeclarations")
|
||||
}
|
||||
|
||||
query predicate localVariableDeclarations(
|
||||
LocalVariableDeclStmt stmt, int i, LocalVariableDeclExpr decl
|
||||
) {
|
||||
decl.getEnclosingCallable().hasName("TestUsingDeclarations") and
|
||||
decl = stmt.getVariableDeclExpr(i)
|
||||
}
|
||||
|
||||
query predicate usingStmts1(UsingStmt stmt) { any() }
|
||||
|
||||
query predicate usingStmts(UsingStmt stmt, int i, LocalVariableDeclExpr decl) {
|
||||
decl = stmt.getVariableDeclExpr(i)
|
||||
}
|
||||
|
||||
query predicate usingDecls(UsingDeclStmt stmt, int i, Expr e) { e = stmt.getChild(i) }
|
||||
|
||||
query predicate usingExprs(UsingStmt stmt, Expr e) { e = stmt.getAnExpr() }
|
|
@ -5,7 +5,7 @@
|
|||
import csharp
|
||||
|
||||
where
|
||||
forall(UsingStmt s |
|
||||
forall(UsingBlockStmt s |
|
||||
exists(s.getAnExpr()) and
|
||||
exists(s.getBody())
|
||||
)
|
||||
|
|
|
@ -58,6 +58,10 @@ class Test
|
|||
SqlConnection c1f = new SqlConnection();
|
||||
Throw2(c1f);
|
||||
c1f.Dispose();
|
||||
|
||||
// GOOD: using declaration
|
||||
using SqlConnection c2 = new SqlConnection("");
|
||||
c2.Open();
|
||||
}
|
||||
|
||||
void Throw1(SqlConnection sc)
|
||||
|
@ -71,3 +75,5 @@ class Test
|
|||
return sc == null ? throw new Exception() : sc;
|
||||
}
|
||||
}
|
||||
|
||||
// semmle-extractor-options: /langversion:8.0
|
||||
|
|
|
@ -78,6 +78,9 @@ class Test
|
|||
// GOOD: Passed to a library. This is only detected in CIL.
|
||||
Console.SetOut(new StreamWriter("output.txt"));
|
||||
|
||||
// GOOD: Disposed automatically.
|
||||
using var c2 = new Timer(TimerProc);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -88,3 +91,5 @@ class Test
|
|||
{
|
||||
}
|
||||
}
|
||||
|
||||
// semmle-extractor-options: /langversion:8.0
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,2 @@
|
|||
description: Support for null-coalescing assignment, static local functions, and using declarations.
|
||||
compatibility: backwards
|
|
@ -423,6 +423,14 @@ class SwitchCase extends Stmt, @case {
|
|||
*/
|
||||
SwitchExpr getSwitchExpr() { result.getACase() = this }
|
||||
|
||||
/**
|
||||
* Gets the expression of the surrounding switch that this case is compared
|
||||
* against.
|
||||
*/
|
||||
Expr getSelectorExpr() {
|
||||
result = this.getSwitch().getExpr() or result = this.getSwitchExpr().getExpr()
|
||||
}
|
||||
|
||||
/**
|
||||
* PREVIEW FEATURE in Java 12. Subject to removal in a future release.
|
||||
*
|
||||
|
@ -625,7 +633,10 @@ class BreakStmt extends Stmt, @breakstmt {
|
|||
override string pp() {
|
||||
if this.hasLabel()
|
||||
then result = "break " + this.getLabel()
|
||||
else if this.hasValue() then result = "break ..." else result = "break"
|
||||
else
|
||||
if this.hasValue()
|
||||
then result = "break ..."
|
||||
else result = "break"
|
||||
}
|
||||
|
||||
/** This statement's Halstead ID (used to compute Halstead metrics). */
|
||||
|
|
|
@ -93,7 +93,8 @@ class Guard extends ExprParent {
|
|||
/** Gets the statement containing this guard. */
|
||||
Stmt getEnclosingStmt() {
|
||||
result = this.(Expr).getEnclosingStmt() or
|
||||
result = this.(SwitchCase).getSwitch()
|
||||
result = this.(SwitchCase).getSwitch() or
|
||||
result = this.(SwitchCase).getSwitchExpr().getEnclosingStmt()
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -126,7 +127,7 @@ class Guard extends ExprParent {
|
|||
branch = true and
|
||||
bb2.getFirstNode() = sc.getControlFlowNode() and
|
||||
pred = sc.getControlFlowNode().getAPredecessor() and
|
||||
pred.(Expr).getParent*() = sc.getSwitch().getExpr() and
|
||||
pred.(Expr).getParent*() = sc.getSelectorExpr() and
|
||||
bb1 = pred.getBasicBlock()
|
||||
)
|
||||
or
|
||||
|
@ -160,12 +161,12 @@ class Guard extends ExprParent {
|
|||
}
|
||||
|
||||
private predicate switchCaseControls(SwitchCase sc, BasicBlock bb) {
|
||||
exists(BasicBlock caseblock, SwitchStmt ss |
|
||||
ss.getACase() = sc and
|
||||
exists(BasicBlock caseblock, Expr selector |
|
||||
selector = sc.getSelectorExpr() and
|
||||
caseblock.getFirstNode() = sc.getControlFlowNode() and
|
||||
caseblock.bbDominates(bb) and
|
||||
forall(ControlFlowNode pred | pred = sc.getControlFlowNode().getAPredecessor() |
|
||||
pred.(Expr).getParent*() = ss.getExpr()
|
||||
pred.(Expr).getParent*() = selector
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -254,7 +255,8 @@ private predicate equalityGuard(Guard g, Expr e1, Expr e2, boolean polarity) {
|
|||
exists(ConstCase cc |
|
||||
cc = g and
|
||||
polarity = true and
|
||||
cc.getSwitch().getExpr().getProperExpr() = e1 and
|
||||
cc.getValue() = e2
|
||||
cc.getSelectorExpr().getProperExpr() = e1 and
|
||||
cc.getValue() = e2 and
|
||||
strictcount(cc.getValue(_)) = 1
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
class Test {
|
||||
void foo(String s) {
|
||||
int x = switch(s) {
|
||||
case "a", "b" -> 1;
|
||||
case "c" -> 2;
|
||||
default -> 3;
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
| Test.java:5:7:5:17 | stmt | Test.java:3:20:3:20 | s | Test.java:5:12:5:14 | "c" | true | true | Test.java:5:7:5:17 | stmt |
|
|
@ -0,0 +1,8 @@
|
|||
import java
|
||||
import semmle.code.java.controlflow.Guards
|
||||
|
||||
from Guard g, BasicBlock bb, boolean branch, VarAccess e1, Expr e2, boolean pol
|
||||
where
|
||||
g.controls(bb, branch) and
|
||||
g.isEquality(e1, e2, pol)
|
||||
select g, e1, e2, pol, branch, bb
|
|
@ -0,0 +1 @@
|
|||
//semmle-extractor-options: --javac-args --enable-preview -source 12 -target 12
|
|
@ -3,7 +3,7 @@
|
|||
* @description Storing unencrypted passwords in configuration files is unsafe.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @precision high
|
||||
* @precision medium
|
||||
* @id js/password-in-configuration-file
|
||||
* @tags security
|
||||
* external/cwe/cwe-256
|
||||
|
@ -12,6 +12,7 @@
|
|||
*/
|
||||
|
||||
import javascript
|
||||
import semmle.javascript.RestrictedLocations
|
||||
|
||||
/**
|
||||
* Holds if some JSON or YAML file contains a property with name `key`
|
||||
|
@ -45,7 +46,7 @@ predicate exclude(File f) {
|
|||
f.getExtension().toLowerCase() = "raml"
|
||||
}
|
||||
|
||||
from string key, string val, Locatable valElement
|
||||
from string key, string val, Locatable valElement, string pwd
|
||||
where
|
||||
config(key, val, valElement) and
|
||||
val != "" and
|
||||
|
@ -53,13 +54,14 @@ where
|
|||
not val.regexpMatch(Templating::getDelimiterMatchingRegexp()) and
|
||||
(
|
||||
key.toLowerCase() = "password" and
|
||||
pwd = val and
|
||||
// exclude interpolations of environment variables
|
||||
not val.regexpMatch("\\$.*|%.*%")
|
||||
or
|
||||
key.toLowerCase() != "readme" and
|
||||
// look for `password=...`, but exclude `password=;`, `password="$(...)"`,
|
||||
// `password=%s` and `password==`
|
||||
val.regexpMatch("(?is).*password\\s*=(?!\\s*;)(?!\"?[$`])(?!%s)(?!=).*")
|
||||
pwd = val.regexpCapture("(?is).*password\\s*=\\s*(?!;|\"?[$`]|%s|=)(\\S+).*", 1)
|
||||
) and
|
||||
not exclude(valElement.getFile())
|
||||
select valElement, "Avoid plaintext passwords in configuration files."
|
||||
select (FirstLineOf)valElement, "Hard-coded password '" + pwd + "' in configuration file."
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* @description Only keep results in non-framework code
|
||||
* @kind treemap
|
||||
* @id js/not-framework-file-metric-filter
|
||||
* @metricType file
|
||||
*/
|
||||
|
||||
import FilterFrameworks
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* mapping comment.
|
||||
* @kind treemap
|
||||
* @id js/not-generated-file-metric-filter
|
||||
* @metricType file
|
||||
*/
|
||||
|
||||
import semmle.javascript.GeneratedCode
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* @description Only keep results from files that are not minified.
|
||||
* @kind treemap
|
||||
* @id js/not-minified-file-metric-filter
|
||||
* @metricType file
|
||||
*/
|
||||
|
||||
import javascript
|
||||
|
|
|
@ -37,6 +37,6 @@ module Templating {
|
|||
* storing it in its first (and only) capture group.
|
||||
*/
|
||||
string getDelimiterMatchingRegexp() {
|
||||
result = ".*(" + concat("\\Q" + getADelimiter() + "\\E", "|") + ").*"
|
||||
result = "(?s).*(" + concat("\\Q" + getADelimiter() + "\\E", "|") + ").*"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
| mysql-config.json:4:16:4:23 | "secret" | Avoid plaintext passwords in configuration files. |
|
||||
| tst4.json:2:10:2:38 | "script ... ecret'" | Avoid plaintext passwords in configuration files. |
|
||||
| mysql-config.json:4:16:4:23 | "secret" | Hard-coded password 'secret' in configuration file. |
|
||||
| tst4.json:2:10:2:38 | "script ... ecret'" | Hard-coded password ''secret'' in configuration file. |
|
||||
| tst7.yml:2:9:2:6 | \| | Hard-coded password 'abc' in configuration file. |
|
||||
|
|
|
@ -1 +1,7 @@
|
|||
password: $$SOME_VAR
|
||||
config: |
|
||||
[mail]
|
||||
host = smtp.mydomain.com
|
||||
port = 25
|
||||
username = sample_admin@mydomain.com
|
||||
password = abc
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
config: |
|
||||
[mail]
|
||||
host = smtp.mydomain.com
|
||||
port = 25
|
||||
username = {{username}}
|
||||
password = {{pwd}}
|
|
@ -57,15 +57,37 @@ predicate ok_to_fail(ImportExpr ie) {
|
|||
os_specific_import(ie) != get_os()
|
||||
}
|
||||
|
||||
|
||||
class VersionTest extends @py_flow_node {
|
||||
|
||||
VersionTest() {
|
||||
exists(string name |
|
||||
name.matches("%version%") and
|
||||
this.(CompareNode).getAChild+().pointsTo(Module::named("sys").attr(name))
|
||||
)
|
||||
}
|
||||
|
||||
string toString() {
|
||||
result = "VersionTest"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** A guard on the version of the Python interpreter */
|
||||
class VersionGuard extends ConditionBlock {
|
||||
|
||||
VersionGuard() {
|
||||
this.getLastNode() instanceof VersionTest
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
from ImportExpr ie
|
||||
where not ie.refersTo(_) and
|
||||
exists(Context c | c.appliesTo(ie.getAFlowNode())) and
|
||||
not ok_to_fail(ie) and
|
||||
not exists(VersionGuard guard |
|
||||
if guard.isTrue() then
|
||||
guard.controls(ie.getAFlowNode().getBasicBlock(), false)
|
||||
else
|
||||
guard.controls(ie.getAFlowNode().getBasicBlock(), true)
|
||||
guard.controls(ie.getAFlowNode().getBasicBlock(), _)
|
||||
)
|
||||
|
||||
select ie, "Unable to resolve import of '" + ie.getImportedModuleName() + "'."
|
||||
|
|
Загрузка…
Ссылка в новой задаче