Merge branch 'github:main' into jorgectf/python/deserialization

This commit is contained in:
Jorge
2022-02-04 16:32:01 +01:00
committed by GitHub
407 changed files with 156489 additions and 10102 deletions

View File

@@ -1,6 +0,0 @@
description: Add new statements and expressions for the match syntax.
compatibility: backwards
py_exprs.rel: run py_exprs.qlo
py_stmts.rel: run py_stmts.qlo
py_patterns.rel: delete
py_patterns_lists.rel: delete

View File

@@ -1,42 +0,0 @@
// First we need to wrap some database types
class Location extends @location {
/** Gets the start line of this location */
int getStartLine() {
locations_default(this, _, result, _, _, _) or
locations_ast(this, _, result, _, _, _)
}
string toString() { result = "<some file>" + ":" + this.getStartLine().toString() }
}
class Expr_ extends @py_expr {
string toString() { result = "Expr" }
Location getLocation() { py_locations(result, this) }
}
class ExprParent_ extends @py_expr_parent {
string toString() { result = "ExprParent" }
}
/**
* New kinds have been inserted such that
* `@py_Name` which used to have index 18 now has index 19.
* Entries with lower indices are unchanged.
*/
bindingset[new_index]
int old_index(int new_index) {
if new_index < 18 then result = new_index else result + (19 - 18) = new_index
}
// The schema for py_exprs is:
//
// py_exprs(unique int id : @py_expr,
// int kind: int ref,
// int parent : @py_expr_parent ref,
// int idx : int ref);
from Expr_ expr, int new_kind, ExprParent_ parent, int idx, int old_kind
where
py_exprs(expr, new_kind, parent, idx) and
old_kind = old_index(new_kind)
select expr, old_kind, parent, idx

View File

@@ -1,42 +0,0 @@
// First we need to wrap some database types
class Location extends @location {
/** Gets the start line of this location */
int getStartLine() {
locations_default(this, _, result, _, _, _) or
locations_ast(this, _, result, _, _, _)
}
string toString() { result = "<some file>" + ":" + this.getStartLine().toString() }
}
class Stmt_ extends @py_stmt {
string toString() { result = "Stmt" }
Location getLocation() { py_locations(result, this) }
}
class StmtList_ extends @py_stmt_list {
string toString() { result = "StmtList" }
}
/**
* New kinds have been inserted such that
* `@py_Nonlocal` which used to have index 14 now has index 16.
* Entries with lower indices are unchanged.
*/
bindingset[new_index]
int old_index(int new_index) {
if new_index < 14 then result = new_index else result + (16 - 14) = new_index
}
// The schema for py_stmts is:
//
// py_stmts(unique int id : @py_stmt,
// int kind: int ref,
// int parent : @py_stmt_list ref,
// int idx : int ref);
from Stmt_ expr, int new_kind, StmtList_ parent, int idx, int old_kind
where
py_stmts(expr, new_kind, parent, idx) and
old_kind = old_index(new_kind)
select expr, old_kind, parent, idx

View File

@@ -1,994 +0,0 @@
/*
* This dbscheme is auto-generated by 'semmle/dbscheme_gen.py'.
* WARNING: Any modifications to this file will be lost.
* Relations can be changed by modifying master.py or
* by adding rules to dbscheme.template
*/
/* This is a dummy line to alter the dbscheme, so we can make a database upgrade
* without actually changing any of the dbscheme predicates. It contains a date
* to allow for such updates in the future as well.
*
* 2020-07-02
*
* DO NOT remove this comment carelessly, since it can revert the dbscheme back to a
* previously seen state (matching a previously seen SHA), which would make the upgrade
* mechanism not work properly.
*/
/*
* External artifacts
*/
externalDefects(
unique int id : @externalDefect,
varchar(900) queryPath : string ref,
int location : @location ref,
varchar(900) message : string ref,
float severity : float ref
);
externalMetrics(
unique int id : @externalMetric,
varchar(900) queryPath : string ref,
int location : @location ref,
float value : float ref
);
externalData(
int id : @externalDataElement,
varchar(900) queryPath : string ref,
int column: int ref,
varchar(900) data : string ref
);
snapshotDate(unique date snapshotDate : date ref);
sourceLocationPrefix(varchar(900) prefix : string ref);
/*
* Duplicate code
*/
duplicateCode(
unique int id : @duplication,
varchar(900) relativePath : string ref,
int equivClass : int ref);
similarCode(
unique int id : @similarity,
varchar(900) relativePath : string ref,
int equivClass : int ref);
@duplication_or_similarity = @duplication | @similarity
tokens(
int id : @duplication_or_similarity ref,
int offset : int ref,
int beginLine : int ref,
int beginColumn : int ref,
int endLine : int ref,
int endColumn : int ref);
/*
* Line metrics
*/
py_codelines(int id : @py_scope ref,
int count : int ref);
py_commentlines(int id : @py_scope ref,
int count : int ref);
py_docstringlines(int id : @py_scope ref,
int count : int ref);
py_alllines(int id : @py_scope ref,
int count : int ref);
/*
* Version history
*/
svnentries(
int id : @svnentry,
varchar(500) revision : string ref,
varchar(500) author : string ref,
date revisionDate : date ref,
int changeSize : int ref
)
svnaffectedfiles(
int id : @svnentry ref,
int file : @file ref,
varchar(500) action : string ref
)
svnentrymsg(
int id : @svnentry ref,
varchar(500) message : string ref
)
svnchurn(
int commit : @svnentry ref,
int file : @file ref,
int addedLines : int ref,
int deletedLines : int ref
)
/****************************
Python dbscheme
****************************/
files(unique int id: @file,
varchar(900) name: string ref);
folders(unique int id: @folder,
varchar(900) name: string ref);
@container = @folder | @file;
containerparent(int parent: @container ref,
unique int child: @container ref);
@sourceline = @file | @py_Module | @xmllocatable;
numlines(int element_id: @sourceline ref,
int num_lines: int ref,
int num_code: int ref,
int num_comment: int ref
);
@location = @location_ast | @location_default ;
locations_default(unique int id: @location_default,
int file: @file ref,
int beginLine: int ref,
int beginColumn: int ref,
int endLine: int ref,
int endColumn: int ref);
locations_ast(unique int id: @location_ast,
int module: @py_Module ref,
int beginLine: int ref,
int beginColumn: int ref,
int endLine: int ref,
int endColumn: int ref);
file_contents(unique int file: @file ref, string contents: string ref);
py_module_path(int module: @py_Module ref, int file: @container ref);
variable(unique int id : @py_variable,
int scope : @py_scope ref,
varchar(1) name : string ref);
py_line_lengths(unique int id : @py_line,
int file: @py_Module ref,
int line : int ref,
int length : int ref);
py_extracted_version(int module : @py_Module ref,
varchar(1) version : string ref);
/* AUTO GENERATED PART STARTS HERE */
/* <Field> AnnAssign.location = 0, location */
/* <Field> AnnAssign.value = 1, expr */
/* <Field> AnnAssign.annotation = 2, expr */
/* <Field> AnnAssign.target = 3, expr */
/* <Field> Assert.location = 0, location */
/* <Field> Assert.test = 1, expr */
/* <Field> Assert.msg = 2, expr */
/* <Field> Assign.location = 0, location */
/* <Field> Assign.value = 1, expr */
/* <Field> Assign.targets = 2, expr_list */
/* <Field> AssignExpr.location = 0, location */
/* <Field> AssignExpr.parenthesised = 1, bool */
/* <Field> AssignExpr.value = 2, expr */
/* <Field> AssignExpr.target = 3, expr */
/* <Field> Attribute.location = 0, location */
/* <Field> Attribute.parenthesised = 1, bool */
/* <Field> Attribute.value = 2, expr */
/* <Field> Attribute.attr = 3, str */
/* <Field> Attribute.ctx = 4, expr_context */
/* <Field> AugAssign.location = 0, location */
/* <Field> AugAssign.operation = 1, BinOp */
/* <Field> Await.location = 0, location */
/* <Field> Await.parenthesised = 1, bool */
/* <Field> Await.value = 2, expr */
/* <Field> BinaryExpr.location = 0, location */
/* <Field> BinaryExpr.parenthesised = 1, bool */
/* <Field> BinaryExpr.left = 2, expr */
/* <Field> BinaryExpr.op = 3, operator */
/* <Field> BinaryExpr.right = 4, expr */
/* <Parent> BinaryExpr = AugAssign */
/* <Field> BoolExpr.location = 0, location */
/* <Field> BoolExpr.parenthesised = 1, bool */
/* <Field> BoolExpr.op = 2, boolop */
/* <Field> BoolExpr.values = 3, expr_list */
/* <Field> Break.location = 0, location */
/* <Field> Bytes.location = 0, location */
/* <Field> Bytes.parenthesised = 1, bool */
/* <Field> Bytes.s = 2, bytes */
/* <Field> Bytes.prefix = 3, bytes */
/* <Field> Bytes.implicitly_concatenated_parts = 4, StringPart_list */
/* <Field> Call.location = 0, location */
/* <Field> Call.parenthesised = 1, bool */
/* <Field> Call.func = 2, expr */
/* <Field> Call.positional_args = 3, expr_list */
/* <Field> Call.named_args = 4, dict_item_list */
/* <Field> Class.name = 0, str */
/* <Field> Class.body = 1, stmt_list */
/* <Parent> Class = ClassExpr */
/* <Field> ClassExpr.location = 0, location */
/* <Field> ClassExpr.parenthesised = 1, bool */
/* <Field> ClassExpr.name = 2, str */
/* <Field> ClassExpr.bases = 3, expr_list */
/* <Field> ClassExpr.keywords = 4, dict_item_list */
/* <Field> ClassExpr.inner_scope = 5, Class */
/* <Field> Compare.location = 0, location */
/* <Field> Compare.parenthesised = 1, bool */
/* <Field> Compare.left = 2, expr */
/* <Field> Compare.ops = 3, cmpop_list */
/* <Field> Compare.comparators = 4, expr_list */
/* <Field> Continue.location = 0, location */
/* <Field> Delete.location = 0, location */
/* <Field> Delete.targets = 1, expr_list */
/* <Field> Dict.location = 0, location */
/* <Field> Dict.parenthesised = 1, bool */
/* <Field> Dict.items = 2, dict_item_list */
/* <Field> DictComp.location = 0, location */
/* <Field> DictComp.parenthesised = 1, bool */
/* <Field> DictComp.function = 2, Function */
/* <Field> DictComp.iterable = 3, expr */
/* <Field> DictUnpacking.location = 0, location */
/* <Field> DictUnpacking.value = 1, expr */
/* <Field> Ellipsis.location = 0, location */
/* <Field> Ellipsis.parenthesised = 1, bool */
/* <Field> ExceptStmt.location = 0, location */
/* <Field> ExceptStmt.type = 1, expr */
/* <Field> ExceptStmt.name = 2, expr */
/* <Field> ExceptStmt.body = 3, stmt_list */
/* <Field> Exec.location = 0, location */
/* <Field> Exec.body = 1, expr */
/* <Field> Exec.globals = 2, expr */
/* <Field> Exec.locals = 3, expr */
/* <Field> ExprStmt.location = 0, location */
/* <Field> ExprStmt.value = 1, expr */
/* <Field> Filter.location = 0, location */
/* <Field> Filter.parenthesised = 1, bool */
/* <Field> Filter.value = 2, expr */
/* <Field> Filter.filter = 3, expr */
/* <Field> For.location = 0, location */
/* <Field> For.target = 1, expr */
/* <Field> For.iter = 2, expr */
/* <Field> For.body = 3, stmt_list */
/* <Field> For.orelse = 4, stmt_list */
/* <Field> For.is_async = 5, bool */
/* <Field> FormattedValue.location = 0, location */
/* <Field> FormattedValue.parenthesised = 1, bool */
/* <Field> FormattedValue.value = 2, expr */
/* <Field> FormattedValue.conversion = 3, str */
/* <Field> FormattedValue.format_spec = 4, JoinedStr */
/* <Field> Function.name = 0, str */
/* <Field> Function.args = 1, parameter_list */
/* <Field> Function.vararg = 2, expr */
/* <Field> Function.kwonlyargs = 3, expr_list */
/* <Field> Function.kwarg = 4, expr */
/* <Field> Function.body = 5, stmt_list */
/* <Field> Function.is_async = 6, bool */
/* <Parent> Function = FunctionParent */
/* <Field> FunctionExpr.location = 0, location */
/* <Field> FunctionExpr.parenthesised = 1, bool */
/* <Field> FunctionExpr.name = 2, str */
/* <Field> FunctionExpr.args = 3, arguments */
/* <Field> FunctionExpr.returns = 4, expr */
/* <Field> FunctionExpr.inner_scope = 5, Function */
/* <Field> GeneratorExp.location = 0, location */
/* <Field> GeneratorExp.parenthesised = 1, bool */
/* <Field> GeneratorExp.function = 2, Function */
/* <Field> GeneratorExp.iterable = 3, expr */
/* <Field> Global.location = 0, location */
/* <Field> Global.names = 1, str_list */
/* <Field> If.location = 0, location */
/* <Field> If.test = 1, expr */
/* <Field> If.body = 2, stmt_list */
/* <Field> If.orelse = 3, stmt_list */
/* <Field> IfExp.location = 0, location */
/* <Field> IfExp.parenthesised = 1, bool */
/* <Field> IfExp.test = 2, expr */
/* <Field> IfExp.body = 3, expr */
/* <Field> IfExp.orelse = 4, expr */
/* <Field> Import.location = 0, location */
/* <Field> Import.names = 1, alias_list */
/* <Field> ImportExpr.location = 0, location */
/* <Field> ImportExpr.parenthesised = 1, bool */
/* <Field> ImportExpr.level = 2, int */
/* <Field> ImportExpr.name = 3, str */
/* <Field> ImportExpr.top = 4, bool */
/* <Field> ImportStar.location = 0, location */
/* <Field> ImportStar.module = 1, expr */
/* <Field> ImportMember.location = 0, location */
/* <Field> ImportMember.parenthesised = 1, bool */
/* <Field> ImportMember.module = 2, expr */
/* <Field> ImportMember.name = 3, str */
/* <Field> Fstring.location = 0, location */
/* <Field> Fstring.parenthesised = 1, bool */
/* <Field> Fstring.values = 2, expr_list */
/* <Parent> Fstring = FormattedValue */
/* <Field> KeyValuePair.location = 0, location */
/* <Field> KeyValuePair.value = 1, expr */
/* <Field> KeyValuePair.key = 2, expr */
/* <Field> Lambda.location = 0, location */
/* <Field> Lambda.parenthesised = 1, bool */
/* <Field> Lambda.args = 2, arguments */
/* <Field> Lambda.inner_scope = 3, Function */
/* <Field> List.location = 0, location */
/* <Field> List.parenthesised = 1, bool */
/* <Field> List.elts = 2, expr_list */
/* <Field> List.ctx = 3, expr_context */
/* <Field> ListComp.location = 0, location */
/* <Field> ListComp.parenthesised = 1, bool */
/* <Field> ListComp.function = 2, Function */
/* <Field> ListComp.iterable = 3, expr */
/* <Field> ListComp.generators = 4, comprehension_list */
/* <Field> ListComp.elt = 5, expr */
/* <Field> Module.name = 0, str */
/* <Field> Module.hash = 1, str */
/* <Field> Module.body = 2, stmt_list */
/* <Field> Module.kind = 3, str */
/* <Field> Name.location = 0, location */
/* <Field> Name.parenthesised = 1, bool */
/* <Field> Name.variable = 2, variable */
/* <Field> Name.ctx = 3, expr_context */
/* <Parent> Name = ParameterList */
/* <Field> Nonlocal.location = 0, location */
/* <Field> Nonlocal.names = 1, str_list */
/* <Field> Num.location = 0, location */
/* <Field> Num.parenthesised = 1, bool */
/* <Field> Num.n = 2, number */
/* <Field> Num.text = 3, number */
/* <Field> Pass.location = 0, location */
/* <Field> PlaceHolder.location = 0, location */
/* <Field> PlaceHolder.parenthesised = 1, bool */
/* <Field> PlaceHolder.variable = 2, variable */
/* <Field> PlaceHolder.ctx = 3, expr_context */
/* <Field> Print.location = 0, location */
/* <Field> Print.dest = 1, expr */
/* <Field> Print.values = 2, expr_list */
/* <Field> Print.nl = 3, bool */
/* <Field> Raise.location = 0, location */
/* <Field> Raise.exc = 1, expr */
/* <Field> Raise.cause = 2, expr */
/* <Field> Raise.type = 3, expr */
/* <Field> Raise.inst = 4, expr */
/* <Field> Raise.tback = 5, expr */
/* <Field> Repr.location = 0, location */
/* <Field> Repr.parenthesised = 1, bool */
/* <Field> Repr.value = 2, expr */
/* <Field> Return.location = 0, location */
/* <Field> Return.value = 1, expr */
/* <Field> Set.location = 0, location */
/* <Field> Set.parenthesised = 1, bool */
/* <Field> Set.elts = 2, expr_list */
/* <Field> SetComp.location = 0, location */
/* <Field> SetComp.parenthesised = 1, bool */
/* <Field> SetComp.function = 2, Function */
/* <Field> SetComp.iterable = 3, expr */
/* <Field> Slice.location = 0, location */
/* <Field> Slice.parenthesised = 1, bool */
/* <Field> Slice.start = 2, expr */
/* <Field> Slice.stop = 3, expr */
/* <Field> Slice.step = 4, expr */
/* <Field> SpecialOperation.location = 0, location */
/* <Field> SpecialOperation.parenthesised = 1, bool */
/* <Field> SpecialOperation.name = 2, str */
/* <Field> SpecialOperation.arguments = 3, expr_list */
/* <Field> Starred.location = 0, location */
/* <Field> Starred.parenthesised = 1, bool */
/* <Field> Starred.value = 2, expr */
/* <Field> Starred.ctx = 3, expr_context */
/* <Field> Str.location = 0, location */
/* <Field> Str.parenthesised = 1, bool */
/* <Field> Str.s = 2, str */
/* <Field> Str.prefix = 3, str */
/* <Field> Str.implicitly_concatenated_parts = 4, StringPart_list */
/* <Field> StringPart.text = 0, str */
/* <Field> StringPart.location = 1, location */
/* <Parent> StringPart = StringPartList */
/* <Parent> StringPartList = BytesOrStr */
/* <Field> Subscript.location = 0, location */
/* <Field> Subscript.parenthesised = 1, bool */
/* <Field> Subscript.value = 2, expr */
/* <Field> Subscript.index = 3, expr */
/* <Field> Subscript.ctx = 4, expr_context */
/* <Field> TemplateDottedNotation.location = 0, location */
/* <Field> TemplateDottedNotation.parenthesised = 1, bool */
/* <Field> TemplateDottedNotation.value = 2, expr */
/* <Field> TemplateDottedNotation.attr = 3, str */
/* <Field> TemplateDottedNotation.ctx = 4, expr_context */
/* <Field> TemplateWrite.location = 0, location */
/* <Field> TemplateWrite.value = 1, expr */
/* <Field> Try.location = 0, location */
/* <Field> Try.body = 1, stmt_list */
/* <Field> Try.orelse = 2, stmt_list */
/* <Field> Try.handlers = 3, stmt_list */
/* <Field> Try.finalbody = 4, stmt_list */
/* <Field> Tuple.location = 0, location */
/* <Field> Tuple.parenthesised = 1, bool */
/* <Field> Tuple.elts = 2, expr_list */
/* <Field> Tuple.ctx = 3, expr_context */
/* <Parent> Tuple = ParameterList */
/* <Field> UnaryExpr.location = 0, location */
/* <Field> UnaryExpr.parenthesised = 1, bool */
/* <Field> UnaryExpr.op = 2, unaryop */
/* <Field> UnaryExpr.operand = 3, expr */
/* <Field> While.location = 0, location */
/* <Field> While.test = 1, expr */
/* <Field> While.body = 2, stmt_list */
/* <Field> While.orelse = 3, stmt_list */
/* <Field> With.location = 0, location */
/* <Field> With.context_expr = 1, expr */
/* <Field> With.optional_vars = 2, expr */
/* <Field> With.body = 3, stmt_list */
/* <Field> With.is_async = 4, bool */
/* <Field> Yield.location = 0, location */
/* <Field> Yield.parenthesised = 1, bool */
/* <Field> Yield.value = 2, expr */
/* <Field> YieldFrom.location = 0, location */
/* <Field> YieldFrom.parenthesised = 1, bool */
/* <Field> YieldFrom.value = 2, expr */
/* <Field> Alias.value = 0, expr */
/* <Field> Alias.asname = 1, expr */
/* <Parent> Alias = AliasList */
/* <Parent> AliasList = Import */
/* <Field> Arguments.kw_defaults = 0, expr_list */
/* <Field> Arguments.defaults = 1, expr_list */
/* <Field> Arguments.annotations = 2, expr_list */
/* <Field> Arguments.varargannotation = 3, expr */
/* <Field> Arguments.kwargannotation = 4, expr */
/* <Field> Arguments.kw_annotations = 5, expr_list */
/* <Parent> Arguments = ArgumentsParent */
/* <Parent> boolean = BoolParent */
/* <Parent> Boolop = BoolExpr */
/* <Parent> string = Bytes */
/* <Parent> Cmpop = CmpopList */
/* <Parent> CmpopList = Compare */
/* <Field> Comprehension.location = 0, location */
/* <Field> Comprehension.iter = 1, expr */
/* <Field> Comprehension.target = 2, expr */
/* <Field> Comprehension.ifs = 3, expr_list */
/* <Parent> Comprehension = ComprehensionList */
/* <Parent> ComprehensionList = ListComp */
/* <Parent> DictItem = DictItemList */
/* <Parent> DictItemList = DictItemListParent */
/* <Field> Expr.location = 0, location */
/* <Field> Expr.parenthesised = 1, bool */
/* <Parent> Expr = ExprParent */
/* <Parent> ExprContext = ExprContextParent */
/* <Parent> ExprList = ExprListParent */
/* <Parent> int = ImportExpr */
/* <Field> Keyword.location = 0, location */
/* <Field> Keyword.value = 1, expr */
/* <Field> Keyword.arg = 2, str */
/* <Parent> Location = LocationParent */
/* <Parent> string = Num */
/* <Parent> Operator = BinaryExpr */
/* <Parent> ParameterList = Function */
/* <Field> Stmt.location = 0, location */
/* <Parent> Stmt = StmtList */
/* <Parent> StmtList = StmtListParent */
/* <Parent> string = StrParent */
/* <Parent> StringList = StrListParent */
/* <Parent> Unaryop = UnaryExpr */
/* <Parent> Variable = VariableParent */
py_Classes(unique int id : @py_Class,
unique int parent : @py_ClassExpr ref);
py_Functions(unique int id : @py_Function,
unique int parent : @py_Function_parent ref);
py_Modules(unique int id : @py_Module);
py_StringParts(unique int id : @py_StringPart,
int parent : @py_StringPart_list ref,
int idx : int ref);
py_StringPart_lists(unique int id : @py_StringPart_list,
unique int parent : @py_Bytes_or_Str ref);
py_aliases(unique int id : @py_alias,
int parent : @py_alias_list ref,
int idx : int ref);
py_alias_lists(unique int id : @py_alias_list,
unique int parent : @py_Import ref);
py_arguments(unique int id : @py_arguments,
unique int parent : @py_arguments_parent ref);
py_bools(int parent : @py_bool_parent ref,
int idx : int ref);
py_boolops(unique int id : @py_boolop,
int kind: int ref,
unique int parent : @py_BoolExpr ref);
py_bytes(varchar(1) id : string ref,
int parent : @py_Bytes ref,
int idx : int ref);
py_cmpops(unique int id : @py_cmpop,
int kind: int ref,
int parent : @py_cmpop_list ref,
int idx : int ref);
py_cmpop_lists(unique int id : @py_cmpop_list,
unique int parent : @py_Compare ref);
py_comprehensions(unique int id : @py_comprehension,
int parent : @py_comprehension_list ref,
int idx : int ref);
py_comprehension_lists(unique int id : @py_comprehension_list,
unique int parent : @py_ListComp ref);
py_dict_items(unique int id : @py_dict_item,
int kind: int ref,
int parent : @py_dict_item_list ref,
int idx : int ref);
py_dict_item_lists(unique int id : @py_dict_item_list,
unique int parent : @py_dict_item_list_parent ref);
py_exprs(unique int id : @py_expr,
int kind: int ref,
int parent : @py_expr_parent ref,
int idx : int ref);
py_expr_contexts(unique int id : @py_expr_context,
int kind: int ref,
unique int parent : @py_expr_context_parent ref);
py_expr_lists(unique int id : @py_expr_list,
int parent : @py_expr_list_parent ref,
int idx : int ref);
py_ints(int id : int ref,
unique int parent : @py_ImportExpr ref);
py_locations(unique int id : @location ref,
unique int parent : @py_location_parent ref);
py_numbers(varchar(1) id : string ref,
int parent : @py_Num ref,
int idx : int ref);
py_operators(unique int id : @py_operator,
int kind: int ref,
unique int parent : @py_BinaryExpr ref);
py_parameter_lists(unique int id : @py_parameter_list,
unique int parent : @py_Function ref);
py_stmts(unique int id : @py_stmt,
int kind: int ref,
int parent : @py_stmt_list ref,
int idx : int ref);
py_stmt_lists(unique int id : @py_stmt_list,
int parent : @py_stmt_list_parent ref,
int idx : int ref);
py_strs(varchar(1) id : string ref,
int parent : @py_str_parent ref,
int idx : int ref);
py_str_lists(unique int id : @py_str_list,
unique int parent : @py_str_list_parent ref);
py_unaryops(unique int id : @py_unaryop,
int kind: int ref,
unique int parent : @py_UnaryExpr ref);
py_variables(int id : @py_variable ref,
unique int parent : @py_variable_parent ref);
case @py_boolop.kind of
0 = @py_And
| 1 = @py_Or;
case @py_cmpop.kind of
0 = @py_Eq
| 1 = @py_Gt
| 2 = @py_GtE
| 3 = @py_In
| 4 = @py_Is
| 5 = @py_IsNot
| 6 = @py_Lt
| 7 = @py_LtE
| 8 = @py_NotEq
| 9 = @py_NotIn;
case @py_dict_item.kind of
0 = @py_DictUnpacking
| 1 = @py_KeyValuePair
| 2 = @py_keyword;
case @py_expr.kind of
0 = @py_Attribute
| 1 = @py_BinaryExpr
| 2 = @py_BoolExpr
| 3 = @py_Bytes
| 4 = @py_Call
| 5 = @py_ClassExpr
| 6 = @py_Compare
| 7 = @py_Dict
| 8 = @py_DictComp
| 9 = @py_Ellipsis
| 10 = @py_FunctionExpr
| 11 = @py_GeneratorExp
| 12 = @py_IfExp
| 13 = @py_ImportExpr
| 14 = @py_ImportMember
| 15 = @py_Lambda
| 16 = @py_List
| 17 = @py_ListComp
| 18 = @py_Name
| 19 = @py_Num
| 20 = @py_Repr
| 21 = @py_Set
| 22 = @py_SetComp
| 23 = @py_Slice
| 24 = @py_Starred
| 25 = @py_Str
| 26 = @py_Subscript
| 27 = @py_Tuple
| 28 = @py_UnaryExpr
| 29 = @py_Yield
| 30 = @py_YieldFrom
| 31 = @py_TemplateDottedNotation
| 32 = @py_Filter
| 33 = @py_PlaceHolder
| 34 = @py_Await
| 35 = @py_Fstring
| 36 = @py_FormattedValue
| 37 = @py_AssignExpr
| 38 = @py_SpecialOperation;
case @py_expr_context.kind of
0 = @py_AugLoad
| 1 = @py_AugStore
| 2 = @py_Del
| 3 = @py_Load
| 4 = @py_Param
| 5 = @py_Store;
case @py_operator.kind of
0 = @py_Add
| 1 = @py_BitAnd
| 2 = @py_BitOr
| 3 = @py_BitXor
| 4 = @py_Div
| 5 = @py_FloorDiv
| 6 = @py_LShift
| 7 = @py_Mod
| 8 = @py_Mult
| 9 = @py_Pow
| 10 = @py_RShift
| 11 = @py_Sub
| 12 = @py_MatMult;
case @py_stmt.kind of
0 = @py_Assert
| 1 = @py_Assign
| 2 = @py_AugAssign
| 3 = @py_Break
| 4 = @py_Continue
| 5 = @py_Delete
| 6 = @py_ExceptStmt
| 7 = @py_Exec
| 8 = @py_Expr_stmt
| 9 = @py_For
| 10 = @py_Global
| 11 = @py_If
| 12 = @py_Import
| 13 = @py_ImportStar
| 14 = @py_Nonlocal
| 15 = @py_Pass
| 16 = @py_Print
| 17 = @py_Raise
| 18 = @py_Return
| 19 = @py_Try
| 20 = @py_While
| 21 = @py_With
| 22 = @py_TemplateWrite
| 23 = @py_AnnAssign;
case @py_unaryop.kind of
0 = @py_Invert
| 1 = @py_Not
| 2 = @py_UAdd
| 3 = @py_USub;
@py_Bytes_or_Str = @py_Bytes | @py_Str;
@py_Function_parent = @py_DictComp | @py_FunctionExpr | @py_GeneratorExp | @py_Lambda | @py_ListComp | @py_SetComp;
@py_arguments_parent = @py_FunctionExpr | @py_Lambda;
@py_ast_node = @py_Class | @py_Function | @py_Module | @py_StringPart | @py_comprehension | @py_dict_item | @py_expr | @py_stmt;
@py_bool_parent = @py_For | @py_Function | @py_Print | @py_With | @py_expr;
@py_dict_item_list_parent = @py_Call | @py_ClassExpr | @py_Dict;
@py_expr_context_parent = @py_Attribute | @py_List | @py_Name | @py_PlaceHolder | @py_Starred | @py_Subscript | @py_TemplateDottedNotation | @py_Tuple;
@py_expr_list_parent = @py_Assign | @py_BoolExpr | @py_Call | @py_ClassExpr | @py_Compare | @py_Delete | @py_Fstring | @py_Function | @py_List | @py_Print | @py_Set | @py_SpecialOperation | @py_Tuple | @py_arguments | @py_comprehension;
@py_expr_or_stmt = @py_expr | @py_stmt;
@py_expr_parent = @py_AnnAssign | @py_Assert | @py_Assign | @py_AssignExpr | @py_Attribute | @py_AugAssign | @py_Await | @py_BinaryExpr | @py_Call | @py_Compare | @py_DictComp | @py_DictUnpacking | @py_ExceptStmt | @py_Exec | @py_Expr_stmt | @py_Filter | @py_For | @py_FormattedValue | @py_Function | @py_FunctionExpr | @py_GeneratorExp | @py_If | @py_IfExp | @py_ImportMember | @py_ImportStar | @py_KeyValuePair | @py_ListComp | @py_Print | @py_Raise | @py_Repr | @py_Return | @py_SetComp | @py_Slice | @py_Starred | @py_Subscript | @py_TemplateDottedNotation | @py_TemplateWrite | @py_UnaryExpr | @py_While | @py_With | @py_Yield | @py_YieldFrom | @py_alias | @py_arguments | @py_comprehension | @py_expr_list | @py_keyword | @py_parameter_list;
@py_location_parent = @py_DictUnpacking | @py_KeyValuePair | @py_StringPart | @py_comprehension | @py_expr | @py_keyword | @py_stmt;
@py_parameter = @py_Name | @py_Tuple;
@py_scope = @py_Class | @py_Function | @py_Module;
@py_stmt_list_parent = @py_Class | @py_ExceptStmt | @py_For | @py_Function | @py_If | @py_Module | @py_Try | @py_While | @py_With;
@py_str_list_parent = @py_Global | @py_Nonlocal;
@py_str_parent = @py_Attribute | @py_Class | @py_ClassExpr | @py_FormattedValue | @py_Function | @py_FunctionExpr | @py_ImportExpr | @py_ImportMember | @py_Module | @py_SpecialOperation | @py_Str | @py_StringPart | @py_TemplateDottedNotation | @py_keyword | @py_str_list;
@py_variable_parent = @py_Name | @py_PlaceHolder;
/*
* End of auto-generated part
*/
/* Map relative names to absolute names for imports */
py_absolute_names(int module : @py_Module ref,
varchar(1) relname : string ref,
varchar(1) absname : string ref);
py_exports(int id : @py_Module ref,
varchar(1) name : string ref);
/* Successor information */
py_successors(int predecessor : @py_flow_node ref,
int successor : @py_flow_node ref);
py_true_successors(int predecessor : @py_flow_node ref,
int successor : @py_flow_node ref);
py_exception_successors(int predecessor : @py_flow_node ref,
int successor : @py_flow_node ref);
py_false_successors(int predecessor : @py_flow_node ref,
int successor : @py_flow_node ref);
py_flow_bb_node(unique int flownode : @py_flow_node,
int realnode : @py_ast_node ref,
int basicblock : @py_flow_node ref,
int index : int ref);
py_scope_flow(int flow : @py_flow_node ref,
int scope : @py_scope ref,
int kind : int ref);
py_idoms(unique int node : @py_flow_node ref,
int immediate_dominator : @py_flow_node ref);
py_ssa_phi(int phi : @py_ssa_var ref,
int arg: @py_ssa_var ref);
py_ssa_var(unique int id : @py_ssa_var,
int var : @py_variable ref);
py_ssa_use(int node: @py_flow_node ref,
int var : @py_ssa_var ref);
py_ssa_defn(unique int id : @py_ssa_var ref,
int node: @py_flow_node ref);
@py_base_var = @py_variable | @py_ssa_var;
py_scopes(unique int node : @py_expr_or_stmt ref,
int scope : @py_scope ref);
py_scope_location(unique int id : @location ref,
unique int scope : @py_scope ref);
py_flags_versioned(varchar(1) name : string ref,
varchar(1) value : string ref,
varchar(1) version : string ref);
py_syntax_error_versioned(unique int id : @location ref,
varchar(1) message : string ref,
varchar(1) version : string ref);
py_comments(unique int id : @py_comment,
varchar(1) text : string ref,
unique int location : @location ref);
/* Type information support */
py_cobjects(unique int obj : @py_cobject);
py_cobjecttypes(unique int obj : @py_cobject ref,
int typeof : @py_cobject ref);
py_cobjectnames(unique int obj : @py_cobject ref,
varchar(1) name : string ref);
/* Kind should be 0 for introspection, > 0 from source, as follows:
1 from C extension source
*/
py_cobject_sources(int obj : @py_cobject ref,
int kind : int ref);
py_cmembers_versioned(int object : @py_cobject ref,
varchar(1) name : string ref,
int member : @py_cobject ref,
varchar(1) version : string ref);
py_citems(int object : @py_cobject ref,
int index : int ref,
int member : @py_cobject ref);
ext_argtype(int funcid : @py_object ref,
int arg : int ref,
int typeid : @py_object ref);
ext_rettype(int funcid : @py_object ref,
int typeid : @py_object ref);
ext_proptype(int propid : @py_object ref,
int typeid : @py_object ref);
ext_argreturn(int funcid : @py_object ref,
int arg : int ref);
py_special_objects(unique int obj : @py_cobject ref,
unique varchar(1) name : string ref);
py_decorated_object(int object : @py_object ref,
int level: int ref);
@py_object = @py_cobject | @py_flow_node;
@py_source_element = @py_ast_node | @container;
/* XML Files */
xmlEncoding (unique int id: @file ref, varchar(900) encoding: string ref);
xmlDTDs (unique int id: @xmldtd,
varchar(900) root: string ref,
varchar(900) publicId: string ref,
varchar(900) systemId: string ref,
int fileid: @file ref);
xmlElements (unique int id: @xmlelement,
varchar(900) name: string ref,
int parentid: @xmlparent ref,
int idx: int ref,
int fileid: @file ref);
xmlAttrs (unique int id: @xmlattribute,
int elementid: @xmlelement ref,
varchar(900) name: string ref,
varchar(3600) value: string ref,
int idx: int ref,
int fileid: @file ref);
xmlNs (int id: @xmlnamespace,
varchar(900) prefixName: string ref,
varchar(900) URI: string ref,
int fileid: @file ref);
xmlHasNs (int elementId: @xmlnamespaceable ref,
int nsId: @xmlnamespace ref,
int fileid: @file ref);
xmlComments (unique int id: @xmlcomment,
varchar(3600) text: string ref,
int parentid: @xmlparent ref,
int fileid: @file ref);
xmlChars (unique int id: @xmlcharacters,
varchar(3600) text: string ref,
int parentid: @xmlparent ref,
int idx: int ref,
int isCDATA: int ref,
int fileid: @file ref);
@xmlparent = @file | @xmlelement;
@xmlnamespaceable = @xmlelement | @xmlattribute;
xmllocations(int xmlElement: @xmllocatable ref,
int location: @location_default ref);
@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace;

View File

@@ -114,13 +114,13 @@ module API {
* Gets a node such that there is an edge in the API graph between this node and the other
* one, and that edge is labeled with `lbl`.
*/
Node getASuccessor(string lbl) { Impl::edge(this, lbl, result) }
Node getASuccessor(Label::ApiLabel lbl) { Impl::edge(this, lbl, result) }
/**
* Gets a node such that there is an edge in the API graph between that other node and
* this one, and that edge is labeled with `lbl`
*/
Node getAPredecessor(string lbl) { this = result.getASuccessor(lbl) }
Node getAPredecessor(Label::ApiLabel lbl) { this = result.getASuccessor(lbl) }
/**
* Gets a node such that there is an edge in the API graph between this node and the other
@@ -174,9 +174,8 @@ module API {
length = 0 and
result = ""
or
exists(Node pred, string lbl, string predpath |
exists(Node pred, Label::ApiLabel lbl, string predpath |
Impl::edge(pred, lbl, this) and
lbl != "" and
predpath = pred.getAPath(length - 1) and
exists(string dot | if length = 1 then dot = "" else dot = "." |
result = predpath + dot + lbl and
@@ -335,7 +334,8 @@ module API {
*
* For instance, `prefix_member("foo.bar", "baz", "foo.bar.baz")` would hold.
*/
private predicate prefix_member(TApiNode base, string member, TApiNode sub) {
cached
predicate prefix_member(TApiNode base, string member, TApiNode sub) {
exists(string sub_str, string regexp |
regexp = "(.+)[.]([^.]+)" and
base = MkModuleImport(sub_str.regexpCapture(regexp, 1)) and
@@ -386,7 +386,7 @@ module API {
* `lbl` in the API graph.
*/
cached
predicate use(TApiNode base, string lbl, DataFlow::Node ref) {
predicate use(TApiNode base, Label::ApiLabel lbl, DataFlow::Node ref) {
exists(DataFlow::LocalSourceNode src, DataFlow::LocalSourceNode pred |
// First, we find a predecessor of the node `ref` that we want to determine. The predecessor
// is any node that is a type-tracked use of a data flow node (`src`), which is itself a
@@ -481,7 +481,7 @@ module API {
* Holds if there is an edge from `pred` to `succ` in the API graph that is labeled with `lbl`.
*/
cached
predicate edge(TApiNode pred, string lbl, TApiNode succ) {
predicate edge(TApiNode pred, Label::ApiLabel lbl, TApiNode succ) {
/* There's an edge from the root node for each imported module. */
exists(string m |
pred = MkRoot() and
@@ -514,36 +514,126 @@ module API {
cached
int distanceFromRoot(TApiNode nd) = shortestDistances(MkRoot/0, edge/2)(_, nd, result)
}
}
private module Label {
/** Gets the edge label for the module `m`. */
bindingset[m]
bindingset[result]
string mod(string m) { result = "moduleImport(\"" + m + "\")" }
/** Provides classes modeling the various edges (labels) in the API graph. */
module Label {
/** A label in the API-graph */
class ApiLabel extends TLabel {
/** Gets a string representation of this label. */
string toString() { result = "???" }
}
/** Gets the `member` edge label for member `m`. */
bindingset[m]
bindingset[result]
string member(string m) { result = "getMember(\"" + m + "\")" }
private import LabelImpl
/** Gets the `member` edge label for the unknown member. */
string unknownMember() { result = "getUnknownMember()" }
private module LabelImpl {
private import semmle.python.dataflow.new.internal.Builtins
private import semmle.python.dataflow.new.internal.ImportStar
/** Gets the `member` edge label for the given attribute reference. */
string memberFromRef(DataFlow::AttrRef pr) {
result = member(pr.getAttributeName())
or
not exists(pr.getAttributeName()) and
result = unknownMember()
newtype TLabel =
MkLabelModule(string mod) { exists(Impl::MkModuleImport(mod)) } or
MkLabelMember(string member) {
member = any(DataFlow::AttrRef pr).getAttributeName() or
exists(Builtins::likelyBuiltin(member)) or
ImportStar::namePossiblyDefinedInImportStar(_, member, _) or
Impl::prefix_member(_, member, _)
} or
MkLabelUnknownMember() or
MkLabelParameter(int i) {
none() // TODO: Fill in when adding def nodes
} or
MkLabelReturn() or
MkLabelSubclass() or
MkLabelAwait()
/** A label for a module. */
class LabelModule extends ApiLabel {
string mod;
LabelModule() { this = MkLabelModule(mod) }
/** Gets the module associated with this label. */
string getMod() { result = mod }
override string toString() { result = "moduleImport(\"" + mod + "\")" }
}
/** A label for the member named `prop`. */
class LabelMember extends ApiLabel {
string member;
LabelMember() { this = MkLabelMember(member) }
/** Gets the property associated with this label. */
string getMember() { result = member }
override string toString() { result = "getMember(\"" + member + "\")" }
}
/** A label for a member with an unknown name. */
class LabelUnknownMember extends ApiLabel {
LabelUnknownMember() { this = MkLabelUnknownMember() }
override string toString() { result = "getUnknownMember()" }
}
/** A label for parameter `i`. */
class LabelParameter extends ApiLabel {
int i;
LabelParameter() { this = MkLabelParameter(i) }
override string toString() { result = "getParameter(" + i + ")" }
/** Gets the index of the parameter for this label. */
int getIndex() { result = i }
}
/** A label that gets the return value of a function. */
class LabelReturn extends ApiLabel {
LabelReturn() { this = MkLabelReturn() }
override string toString() { result = "getReturn()" }
}
/** A label that gets the subclass of a class. */
class LabelSubclass extends ApiLabel {
LabelSubclass() { this = MkLabelSubclass() }
override string toString() { result = "getASubclass()" }
}
/** A label for awaited values. */
class LabelAwait extends ApiLabel {
LabelAwait() { this = MkLabelAwait() }
override string toString() { result = "getAwaited()" }
}
}
/** Gets the edge label for the module `m`. */
LabelModule mod(string m) { result.getMod() = m }
/** Gets the `member` edge label for member `m`. */
LabelMember member(string m) { result.getMember() = m }
/** Gets the `member` edge label for the unknown member. */
LabelUnknownMember unknownMember() { any() }
/** Gets the `member` edge label for the given attribute reference. */
ApiLabel memberFromRef(DataFlow::AttrRef pr) {
result = member(pr.getAttributeName())
or
not exists(pr.getAttributeName()) and
result = unknownMember()
}
/** Gets the `return` edge label. */
LabelReturn return() { any() }
/** Gets the `subclass` edge label. */
LabelSubclass subclass() { any() }
/** Gets the `await` edge label. */
LabelAwait await() { any() }
}
/** Gets the `return` edge label. */
string return() { result = "getReturn()" }
/** Gets the `subclass` edge label. */
string subclass() { result = "getASubclass()" }
/** Gets the `await` edge label. */
string await() { result = "getAwaited()" }
}

View File

@@ -62,33 +62,33 @@ abstract class AstNode extends AstNode_ {
/* Parents */
/** Internal implementation class */
library class FunctionParent extends FunctionParent_ { }
class FunctionParent extends FunctionParent_ { }
/** Internal implementation class */
library class ArgumentsParent extends ArgumentsParent_ { }
class ArgumentsParent extends ArgumentsParent_ { }
/** Internal implementation class */
library class ExprListParent extends ExprListParent_ { }
class ExprListParent extends ExprListParent_ { }
/** Internal implementation class */
library class ExprContextParent extends ExprContextParent_ { }
class ExprContextParent extends ExprContextParent_ { }
/** Internal implementation class */
library class StmtListParent extends StmtListParent_ { }
class StmtListParent extends StmtListParent_ { }
/** Internal implementation class */
library class StrListParent extends StrListParent_ { }
class StrListParent extends StrListParent_ { }
/** Internal implementation class */
library class ExprParent extends ExprParent_ { }
class ExprParent extends ExprParent_ { }
/** Internal implementation class */
class PatternListParent extends PatternListParent_ { }
/** Internal implementation class */
library class PatternParent extends PatternParent_ { }
class PatternParent extends PatternParent_ { }
library class DictItem extends DictItem_, AstNode {
class DictItem extends DictItem_, AstNode {
override string toString() { result = DictItem_.super.toString() }
override AstNode getAChildNode() { none() }
@@ -171,9 +171,9 @@ class ExprList extends ExprList_ {
/** A list of patterns */
class PatternList extends PatternList_ { }
library class DictItemList extends DictItemList_ { }
class DictItemList extends DictItemList_ { }
library class DictItemListParent extends DictItemListParent_ { }
class DictItemListParent extends DictItemListParent_ { }
/** A list of strings (the primitive type string not Bytes or Unicode) */
class StringList extends StringList_ { }

File diff suppressed because it is too large Load Diff

View File

@@ -115,6 +115,9 @@ module Path {
PathNormalization::Range range;
PathNormalization() { this = range }
/** Gets an argument to this path normalization that is interpreted as a path. */
DataFlow::Node getPathArg() { result = range.getPathArg() }
}
/** Provides a class for modeling new path normalization APIs. */
@@ -123,7 +126,10 @@ module Path {
* A data-flow node that performs path normalization. This is often needed in order
* to safely access paths.
*/
abstract class Range extends DataFlow::Node { }
abstract class Range extends DataFlow::Node {
/** Gets an argument to this path normalization that is interpreted as a path. */
abstract DataFlow::Node getPathArg();
}
}
/** A data-flow node that checks that a path is safe to access. */

View File

@@ -53,9 +53,6 @@ private newtype TPrintAstNode =
shouldPrint(list.getAnItem(), _) and
not list = any(Module mod).getBody() and
not forall(AstNode child | child = list.getAnItem() | isNotNeeded(child))
} or
TRegExpTermNode(RegExpTerm term) {
exists(StrConst str | term.getRootTerm() = getParsedRegExp(str) and shouldPrint(str, _))
}
/**
@@ -430,32 +427,6 @@ class ParameterNode extends AstElementNode {
*/
class StrConstNode extends AstElementNode {
override StrConst element;
override PrintAstNode getChild(int childIndex) {
childIndex = 0 and result.(RegExpTermNode).getTerm() = getParsedRegExp(element)
}
}
/**
* A print node for a regular expression term.
*/
class RegExpTermNode extends TRegExpTermNode, PrintAstNode {
RegExpTerm term;
RegExpTermNode() { this = TRegExpTermNode(term) }
/** Gets the `RegExpTerm` for this node. */
RegExpTerm getTerm() { result = term }
override PrintAstNode getChild(int childIndex) {
result.(RegExpTermNode).getTerm() = term.getChild(childIndex)
}
override string toString() {
result = "[" + strictconcat(term.getPrimaryQLClass(), " | ") + "] " + term.toString()
}
override Location getLocation() { result = term.getLocation() }
}
/**

View File

@@ -1290,7 +1290,7 @@ class DataFlowCallOption extends TDataFlowCallOption {
}
}
/** Content tagged with the type of a containing object. */
/** A `Content` tagged with the type of a containing object. */
class TypedContent extends MkTypedContent {
private Content c;
private DataFlowType t;

View File

@@ -15,6 +15,7 @@ predicate localFlowStep(Node nodeFrom, Node nodeTo) { simpleLocalFlowStep(nodeFr
* Holds if data flows from `source` to `sink` in zero or more local
* (intra-procedural) steps.
*/
pragma[inline]
predicate localFlow(Node source, Node sink) { localFlowStep*(source, sink) }
/**

View File

@@ -14,12 +14,14 @@ private import semmle.python.Frameworks
* Holds if taint propagates from `source` to `sink` in zero or more local
* (intra-procedural) steps.
*/
pragma[inline]
predicate localTaint(DataFlow::Node source, DataFlow::Node sink) { localTaintStep*(source, sink) }
/**
* Holds if taint can flow from `e1` to `e2` in zero or more local (intra-procedural)
* steps.
*/
pragma[inline]
predicate localExprTaint(Expr e1, Expr e2) {
localTaint(DataFlow::exprNode(e1), DataFlow::exprNode(e2))
}

View File

@@ -3,7 +3,7 @@
private import TypeTrackerSpecific
/**
* Any string that may appear as the name of a piece of content. This will usually include things like:
* A string that may appear as the name of a piece of content. This will usually include things like:
* - Attribute names (in Python)
* - Property names (in JavaScript)
*
@@ -18,7 +18,7 @@ class ContentName extends string {
ContentName() { this = getPossibleContentName() }
}
/** Either a content name, or the empty string (representing no content). */
/** A content name, or the empty string (representing no content). */
class OptionalContentName extends string {
OptionalContentName() { this instanceof ContentName or this = "" }
}
@@ -200,7 +200,7 @@ module StepSummary {
private newtype TTypeTracker = MkTypeTracker(Boolean hasCall, OptionalContentName content)
/**
* Summary of the steps needed to track a value to a given dataflow node.
* A summary of the steps needed to track a value to a given dataflow node.
*
* This can be used to track objects that implement a certain API in order to
* recognize calls to that API. Note that type-tracking does not by itself provide a
@@ -347,7 +347,7 @@ module TypeTracker {
private newtype TTypeBackTracker = MkTypeBackTracker(Boolean hasReturn, OptionalContentName content)
/**
* Summary of the steps needed to back-track a use of a value to a given dataflow node.
* A summary of the steps needed to back-track a use of a value to a given dataflow node.
*
* This can for example be used to track callbacks that are passed to a certain API,
* so we can model specific parameters of that callback as having a certain type.

View File

@@ -970,7 +970,7 @@ private module StdlibPrivate {
private class OsPathNormpathCall extends Path::PathNormalization::Range, DataFlow::CallCfgNode {
OsPathNormpathCall() { this = os::path().getMember("normpath").getACall() }
DataFlow::Node getPathArg() { result in [this.getArg(0), this.getArgByName("path")] }
override DataFlow::Node getPathArg() { result in [this.getArg(0), this.getArgByName("path")] }
}
/**
@@ -980,7 +980,7 @@ private module StdlibPrivate {
private class OsPathAbspathCall extends Path::PathNormalization::Range, DataFlow::CallCfgNode {
OsPathAbspathCall() { this = os::path().getMember("abspath").getACall() }
DataFlow::Node getPathArg() { result in [this.getArg(0), this.getArgByName("path")] }
override DataFlow::Node getPathArg() { result in [this.getArg(0), this.getArgByName("path")] }
}
/**
@@ -990,7 +990,7 @@ private module StdlibPrivate {
private class OsPathRealpathCall extends Path::PathNormalization::Range, DataFlow::CallCfgNode {
OsPathRealpathCall() { this = os::path().getMember("realpath").getACall() }
DataFlow::Node getPathArg() { result in [this.getArg(0), this.getArgByName("path")] }
override DataFlow::Node getPathArg() { result in [this.getArg(0), this.getArgByName("path")] }
}
/**

View File

@@ -150,8 +150,10 @@ newtype TObject =
TBuiltinTuple(Builtin bltn) { bltn.getClass() = Builtin::special("tuple") } or
/** Represents a tuple in the Python source */
TPythonTuple(TupleNode origin, PointsToContext context) {
origin.isLoad() and
context.appliesTo(origin)
exists(Scope s |
context.appliesToScope(s) and
scope_loads_tuplenode(s, origin)
)
} or
/** Varargs tuple */
TVarargsTuple(CallNode call, PointsToContext context, int offset, int length) {
@@ -201,6 +203,13 @@ newtype TObject =
Expressions::subscriptPartsPointsTo(_, _, generic, index)
}
/** Join-order helper for TPythonTuple */
pragma[nomagic]
private predicate scope_loads_tuplenode(Scope s, TupleNode origin) {
origin.isLoad() and
origin.getScope() = s
}
/** Holds if the object `t` is a type. */
predicate isType(ObjectInternal t) {
t.isClass() = true

View File

@@ -198,14 +198,11 @@ abstract class RegexString extends Expr {
/** Whether there is a character class, between start (inclusive) and end (exclusive) */
predicate charSet(int start, int end) {
exists(int inner_start, int inner_end |
exists(int inner_start |
this.char_set_start(start, inner_start) and
not this.char_set_start(_, start)
|
end = inner_end + 1 and
inner_end > inner_start and
this.nonEscapedCharAt(inner_end) = "]" and
not exists(int mid | this.nonEscapedCharAt(mid) = "]" | mid > inner_start and mid < inner_end)
end - 1 = min(int i | this.nonEscapedCharAt(i) = "]" and inner_start < i)
)
}
@@ -344,9 +341,7 @@ abstract class RegexString extends Expr {
this.escapingChar(start) and
this.getChar(start + 1) = "N" and
this.getChar(start + 2) = "{" and
this.getChar(end - 1) = "}" and
end > start and
not exists(int i | start + 2 < i and i < end - 1 | this.getChar(i) = "}")
end - 1 = min(int i | start + 2 < i and this.getChar(i) = "}")
}
/**

View File

@@ -1,4 +1,6 @@
/**
* DEPRECATED -- use flow state instead
*
* This defines a `PathGraph` where sinks from `TaintTracking::Configuration`s are identified with
* sources from `TaintTracking2::Configuration`s if they represent the same `ControlFlowNode`.
*
@@ -28,9 +30,11 @@ private newtype TCustomPathNode =
CrossoverNode(DataFlow::Node node) { crossoverNode(node) }
/**
* DEPRECATED: Use flow state instead
*
* A class representing the set of all the path nodes in either config.
*/
class CustomPathNode extends TCustomPathNode {
deprecated class CustomPathNode extends TCustomPathNode {
/** Gets the PathNode if it is in Config1. */
DataFlow::PathNode asNode1() {
this = Config1Node(result) or this = CrossoverNode(result.getNode())
@@ -64,8 +68,12 @@ class CustomPathNode extends TCustomPathNode {
}
}
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
query predicate edges(CustomPathNode a, CustomPathNode b) {
/**
* DEPRECATED: Use flow state instead
*
* Holds if `(a,b)` is an edge in the graph of data flow path explanations.
*/
deprecated query predicate edges(CustomPathNode a, CustomPathNode b) {
// Edge is in Config1 graph
DataFlow::PathGraph::edges(a.asNode1(), b.asNode1())
or
@@ -73,8 +81,12 @@ query predicate edges(CustomPathNode a, CustomPathNode b) {
DataFlow2::PathGraph::edges(a.asNode2(), b.asNode2())
}
/** Holds if `n` is a node in the graph of data flow path explanations. */
query predicate nodes(CustomPathNode n, string key, string val) {
/**
* DEPRECATED: Use flow state instead
*
* Holds if `n` is a node in the graph of data flow path explanations.
*/
deprecated query predicate nodes(CustomPathNode n, string key, string val) {
// Node is in Config1 graph
DataFlow::PathGraph::nodes(n.asNode1(), key, val)
or

View File

@@ -2,24 +2,102 @@
* Provides taint-tracking configurations for detecting "path injection" vulnerabilities.
*
* Note, for performance reasons: only import this file if
* the Configurations or the `pathInjection` predicate are needed, otherwise
* `PathInjection::Configuration` is needed, otherwise
* `PathInjectionCustomizations` should be imported instead.
*/
private import python
private import semmle.python.Concepts
private import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.TaintTracking
/**
* Provides a taint-tracking configuration for detecting "path injection" vulnerabilities.
*/
module PathInjection {
import PathInjectionCustomizations::PathInjection
/**
* A taint-tracking configuration for detecting "path injection" vulnerabilities.
*
* This configuration uses two flow states, `NotNormalized` and `NormalizedUnchecked`,
* to track the requirement that a file path must be first normalized and then checked
* before it is safe to use.
*
* At sources, paths are assumed not normalized. At normalization points, they change
* state to `NormalizedUnchecked` after which they can be made safe by an appropriate
* check of the prefix.
*
* Such checks are ineffective in the `NotNormalized` state.
*/
class Configuration extends TaintTracking::Configuration {
Configuration() { this = "PathInjection" }
override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) {
source instanceof Source and state instanceof NotNormalized
}
override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) {
sink instanceof Sink and
(
state instanceof NotNormalized or
state instanceof NormalizedUnchecked
)
}
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) {
// Block `NotNormalized` paths here, since they change state to `NormalizedUnchecked`
node instanceof Path::PathNormalization and
state instanceof NotNormalized
or
node = any(Path::SafeAccessCheck c).getAGuardedNode() and
state instanceof NormalizedUnchecked
}
override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) {
guard instanceof SanitizerGuard
}
override predicate isAdditionalFlowStep(
DataFlow::Node nodeFrom, DataFlow::FlowState stateFrom, DataFlow::Node nodeTo,
DataFlow::FlowState stateTo
) {
nodeFrom = nodeTo.(Path::PathNormalization).getPathArg() and
stateFrom instanceof NotNormalized and
stateTo instanceof NormalizedUnchecked
}
}
/** A state signifying that the file path has not been normalized. */
class NotNormalized extends DataFlow::FlowState {
NotNormalized() { this = "NotNormalized" }
}
/** A state signifying that the file path has been normalized, but not checked. */
class NormalizedUnchecked extends DataFlow::FlowState {
NormalizedUnchecked() { this = "NormalizedUnchecked" }
}
}
// ---------------------------------------------------------------------------
// Old, deprecated code
// ---------------------------------------------------------------------------
private import semmle.python.dataflow.new.DataFlow2
private import semmle.python.dataflow.new.TaintTracking
private import semmle.python.dataflow.new.TaintTracking2
import ChainedConfigs12
private import ChainedConfigs12
import PathInjectionCustomizations::PathInjection
// ---------------------------------------------------------------------------
// Case 1. The path is never normalized.
// ---------------------------------------------------------------------------
/** Configuration to find paths from sources to sinks that contain no normalization. */
class PathNotNormalizedConfiguration extends TaintTracking::Configuration {
/**
* DEPRECATED: Use `PathInjection::Configuration` instead
*
* Configuration to find paths from sources to sinks that contain no normalization.
*/
deprecated class PathNotNormalizedConfiguration extends TaintTracking::Configuration {
PathNotNormalizedConfiguration() { this = "PathNotNormalizedConfiguration" }
override predicate isSource(DataFlow::Node source) { source instanceof Source }
@@ -38,18 +116,24 @@ class PathNotNormalizedConfiguration extends TaintTracking::Configuration {
}
/**
* DEPRECATED: Use `PathInjection::Configuration` instead
*
* Holds if there is a path injection from source to sink, where the (python) path is
* not normalized.
*/
predicate pathNotNormalized(CustomPathNode source, CustomPathNode sink) {
deprecated predicate pathNotNormalized(CustomPathNode source, CustomPathNode sink) {
any(PathNotNormalizedConfiguration config).hasFlowPath(source.asNode1(), sink.asNode1())
}
// ---------------------------------------------------------------------------
// Case 2. The path is normalized at least once, but never checked afterwards.
// ---------------------------------------------------------------------------
/** Configuration to find paths from sources to normalizations that contain no prior normalizations. */
class FirstNormalizationConfiguration extends TaintTracking::Configuration {
/**
* DEPRECATED: Use `PathInjection::Configuration` instead
*
* Configuration to find paths from sources to normalizations that contain no prior normalizations.
*/
deprecated class FirstNormalizationConfiguration extends TaintTracking::Configuration {
FirstNormalizationConfiguration() { this = "FirstNormalizationConfiguration" }
override predicate isSource(DataFlow::Node source) { source instanceof Source }
@@ -65,8 +149,12 @@ class FirstNormalizationConfiguration extends TaintTracking::Configuration {
}
}
/** Configuration to find paths from normalizations to sinks that do not go through a check. */
class NormalizedPathNotCheckedConfiguration extends TaintTracking2::Configuration {
/**
* DEPRECATED: Use `PathInjection::Configuration` instead
*
* Configuration to find paths from normalizations to sinks that do not go through a check.
*/
deprecated class NormalizedPathNotCheckedConfiguration extends TaintTracking2::Configuration {
NormalizedPathNotCheckedConfiguration() { this = "NormalizedPathNotCheckedConfiguration" }
override predicate isSource(DataFlow::Node source) { source instanceof Path::PathNormalization }
@@ -83,10 +171,12 @@ class NormalizedPathNotCheckedConfiguration extends TaintTracking2::Configuratio
}
/**
* DEPRECATED: Use `PathInjection::Configuration` instead
*
* Holds if there is a path injection from source to sink, where the (python) path is
* normalized at least once, but never checked afterwards.
*/
predicate pathNotCheckedAfterNormalization(CustomPathNode source, CustomPathNode sink) {
deprecated predicate pathNotCheckedAfterNormalization(CustomPathNode source, CustomPathNode sink) {
exists(
FirstNormalizationConfiguration config, DataFlow::PathNode mid1, DataFlow2::PathNode mid2,
NormalizedPathNotCheckedConfiguration config2
@@ -100,8 +190,12 @@ predicate pathNotCheckedAfterNormalization(CustomPathNode source, CustomPathNode
// ---------------------------------------------------------------------------
// Query: Either case 1 or case 2.
// ---------------------------------------------------------------------------
/** Holds if there is a path injection from source to sink */
predicate pathInjection(CustomPathNode source, CustomPathNode sink) {
/**
* DEPRECATED: Use `PathInjection::Configuration` instead
*
* Holds if there is a path injection from source to sink
*/
deprecated predicate pathInjection(CustomPathNode source, CustomPathNode sink) {
pathNotNormalized(source, sink)
or
pathNotCheckedAfterNormalization(source, sink)

View File

@@ -1052,13 +1052,13 @@ private module SuffixConstruction {
*/
pragma[noinline]
private string relevant(RegExpRoot root) {
exists(ascii(result))
exists(ascii(result)) and exists(root)
or
exists(InputSymbol s | belongsTo(s, root) | result = intersect(s, _))
or
// The characters from `hasSimpleRejectEdge`. Only `\n` is really needed (as `\n` is not in the `ascii` relation).
// The three chars must be kept in sync with `hasSimpleRejectEdge`.
result = ["|", "\n", "Z"]
result = ["|", "\n", "Z"] and exists(root)
}
/**

View File

@@ -6,122 +6,22 @@
*/
class Person extends string {
Person() {
this = "Ronil" or
this = "Dina" or
this = "Ravi" or
this = "Bruce" or
this = "Jo" or
this = "Aida" or
this = "Esme" or
this = "Charlie" or
this = "Fred" or
this = "Meera" or
this = "Maya" or
this = "Chad" or
this = "Tiana" or
this = "Laura" or
this = "George" or
this = "Will" or
this = "Mary" or
this = "Almira" or
this = "Susannah" or
this = "Rhoda" or
this = "Cynthia" or
this = "Eunice" or
this = "Olive" or
this = "Virginia" or
this = "Angeline" or
this = "Helen" or
this = "Cornelia" or
this = "Harriet" or
this = "Mahala" or
this = "Abby" or
this = "Margaret" or
this = "Deb" or
this = "Minerva" or
this = "Severus" or
this = "Lavina" or
this = "Adeline" or
this = "Cath" or
this = "Elisa" or
this = "Lucretia" or
this = "Anne" or
this = "Eleanor" or
this = "Joanna" or
this = "Adam" or
this = "Agnes" or
this = "Rosanna" or
this = "Clara" or
this = "Melissa" or
this = "Amy" or
this = "Isabel" or
this = "Jemima" or
this = "Cordelia" or
this = "Melinda" or
this = "Delila" or
this = "Jeremiah" or
this = "Elijah" or
this = "Hester" or
this = "Walter" or
this = "Oliver" or
this = "Hugh" or
this = "Aaron" or
this = "Reuben" or
this = "Eli" or
this = "Amos" or
this = "Augustus" or
this = "Theodore" or
this = "Ira" or
this = "Timothy" or
this = "Cyrus" or
this = "Horace" or
this = "Simon" or
this = "Asa" or
this = "Frank" or
this = "Nelson" or
this = "Leonard" or
this = "Harrison" or
this = "Anthony" or
this = "Louis" or
this = "Milton" or
this = "Noah" or
this = "Cornelius" or
this = "Abdul" or
this = "Warren" or
this = "Harvey" or
this = "Dennis" or
this = "Wesley" or
this = "Sylvester" or
this = "Gilbert" or
this = "Sullivan" or
this = "Edmund" or
this = "Wilson" or
this = "Perry" or
this = "Matthew" or
this = "Simba" or
this = "Nala" or
this = "Rafiki" or
this = "Shenzi" or
this = "Ernest" or
this = "Gertrude" or
this = "Oscar" or
this = "Lilian" or
this = "Raymond" or
this = "Elgar" or
this = "Elmer" or
this = "Herbert" or
this = "Maude" or
this = "Mae" or
this = "Otto" or
this = "Edwin" or
this = "Ophelia" or
this = "Parsley" or
this = "Sage" or
this = "Rosemary" or
this = "Thyme" or
this = "Garfunkel" or
this = "King Basil" or
this = "Stephen"
this =
[
"Ronil", "Dina", "Ravi", "Bruce", "Jo", "Aida", "Esme", "Charlie", "Fred", "Meera", "Maya",
"Chad", "Tiana", "Laura", "George", "Will", "Mary", "Almira", "Susannah", "Rhoda",
"Cynthia", "Eunice", "Olive", "Virginia", "Angeline", "Helen", "Cornelia", "Harriet",
"Mahala", "Abby", "Margaret", "Deb", "Minerva", "Severus", "Lavina", "Adeline", "Cath",
"Elisa", "Lucretia", "Anne", "Eleanor", "Joanna", "Adam", "Agnes", "Rosanna", "Clara",
"Melissa", "Amy", "Isabel", "Jemima", "Cordelia", "Melinda", "Delila", "Jeremiah", "Elijah",
"Hester", "Walter", "Oliver", "Hugh", "Aaron", "Reuben", "Eli", "Amos", "Augustus",
"Theodore", "Ira", "Timothy", "Cyrus", "Horace", "Simon", "Asa", "Frank", "Nelson",
"Leonard", "Harrison", "Anthony", "Louis", "Milton", "Noah", "Cornelius", "Abdul", "Warren",
"Harvey", "Dennis", "Wesley", "Sylvester", "Gilbert", "Sullivan", "Edmund", "Wilson",
"Perry", "Matthew", "Simba", "Nala", "Rafiki", "Shenzi", "Ernest", "Gertrude", "Oscar",
"Lilian", "Raymond", "Elgar", "Elmer", "Herbert", "Maude", "Mae", "Otto", "Edwin",
"Ophelia", "Parsley", "Sage", "Rosemary", "Thyme", "Garfunkel", "King Basil", "Stephen"
]
}
/** Gets the hair color of the person. If the person is bald, there is no result. */
@@ -936,25 +836,12 @@ class Person extends string {
/** Holds if the person is deceased. */
predicate isDeceased() {
this = "Ernest" or
this = "Gertrude" or
this = "Oscar" or
this = "Lilian" or
this = "Edwin" or
this = "Raymond" or
this = "Elgar" or
this = "Elmer" or
this = "Herbert" or
this = "Maude" or
this = "Mae" or
this = "Otto" or
this = "Ophelia" or
this = "Parsley" or
this = "Sage" or
this = "Rosemary" or
this = "Thyme" or
this = "Garfunkel" or
this = "King Basil"
this =
[
"Ernest", "Gertrude", "Oscar", "Lilian", "Edwin", "Raymond", "Elgar", "Elmer", "Herbert",
"Maude", "Mae", "Otto", "Ophelia", "Parsley", "Sage", "Rosemary", "Thyme", "Garfunkel",
"King Basil"
]
}
/** Gets a parent of the person (alive or deceased). */
@@ -1195,12 +1082,7 @@ class Person extends string {
}
/** Holds if the person is allowed in the region. Initially, all villagers are allowed in every region. */
predicate isAllowedIn(string region) {
region = "north" or
region = "south" or
region = "east" or
region = "west"
}
predicate isAllowedIn(string region) { region = ["north", "south", "east", "west"] }
}
/** Returns a parent of the person. */

View File

@@ -18,7 +18,9 @@
import python
import semmle.python.security.dataflow.PathInjection
import DataFlow::PathGraph
from CustomPathNode source, CustomPathNode sink
where pathInjection(source, sink)
select sink, source, sink, "This path depends on $@.", source, "a user-provided value"
from PathInjection::Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "This path depends on $@.", source.getNode(),
"a user-provided value"

View File

@@ -0,0 +1,4 @@
---
category: fix
---
* The [View AST functionality](https://codeql.github.com/docs/codeql-for-visual-studio-code/exploring-the-structure-of-your-source-code/) no longer prints detailed information about regular expressions, greatly improving performance.

View File

@@ -11,8 +11,9 @@
import python
import experimental.semmle.python.security.injection.NoSQLInjection
import DataFlow::PathGraph
from CustomPathNode source, CustomPathNode sink
where noSQLInjectionFlow(source, sink)
from NoSQLInjection::Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select sink, source, sink, "$@ NoSQL query contains an unsanitized $@", sink, "This", source,
"user-provided value"

View File

@@ -1,57 +1,54 @@
import python
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.DataFlow2
import semmle.python.dataflow.new.TaintTracking
import semmle.python.dataflow.new.TaintTracking2
import semmle.python.dataflow.new.RemoteFlowSources
import semmle.python.security.dataflow.ChainedConfigs12
import experimental.semmle.python.Concepts
import semmle.python.Concepts
/**
* A taint-tracking configuration for detecting string-to-dict conversions.
*/
class RFSToDictConfig extends TaintTracking::Configuration {
RFSToDictConfig() { this = "RFSToDictConfig" }
module NoSQLInjection {
class Configuration extends TaintTracking::Configuration {
Configuration() { this = "NoSQLInjection" }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) {
source instanceof RemoteFlowSource and
state instanceof RemoteInput
}
override predicate isSink(DataFlow::Node sink) {
exists(Decoding decoding | decoding.getFormat() = "JSON" and sink = decoding.getOutput())
override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) {
sink = any(NoSQLQuery noSQLQuery).getQuery() and
state instanceof ConvertedToDict
}
override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) {
// Block `RemoteInput` paths here, since they change state to `ConvertedToDict`
exists(Decoding decoding | decoding.getFormat() = "JSON" and node = decoding.getOutput()) and
state instanceof RemoteInput
}
override predicate isAdditionalFlowStep(
DataFlow::Node nodeFrom, DataFlow::FlowState stateFrom, DataFlow::Node nodeTo,
DataFlow::FlowState stateTo
) {
exists(Decoding decoding | decoding.getFormat() = "JSON" |
nodeFrom = decoding.getAnInput() and
nodeTo = decoding.getOutput()
) and
stateFrom instanceof RemoteInput and
stateTo instanceof ConvertedToDict
}
override predicate isSanitizer(DataFlow::Node sanitizer) {
sanitizer = any(NoSQLSanitizer noSQLSanitizer).getAnInput()
}
}
override predicate isSanitizer(DataFlow::Node sanitizer) {
sanitizer = any(NoSQLSanitizer noSQLSanitizer).getAnInput()
/** A flow state signifying remote input. */
class RemoteInput extends DataFlow::FlowState {
RemoteInput() { this = "RemoteInput" }
}
/** A flow state signifying remote input converted to a dictionary. */
class ConvertedToDict extends DataFlow::FlowState {
ConvertedToDict() { this = "ConvertedToDict" }
}
}
/**
* A taint-tracking configuration for detecting NoSQL injections (previously converted to a dict).
*/
class FromDataDictToSink extends TaintTracking2::Configuration {
FromDataDictToSink() { this = "FromDataDictToSink" }
override predicate isSource(DataFlow::Node source) {
exists(Decoding decoding | decoding.getFormat() = "JSON" and source = decoding.getOutput())
}
override predicate isSink(DataFlow::Node sink) { sink = any(NoSQLQuery noSQLQuery).getQuery() }
override predicate isSanitizer(DataFlow::Node sanitizer) {
sanitizer = any(NoSQLSanitizer noSQLSanitizer).getAnInput()
}
}
/**
* A predicate checking string-to-dict conversion and its arrival to a NoSQL injection sink.
*/
predicate noSQLInjectionFlow(CustomPathNode source, CustomPathNode sink) {
exists(
RFSToDictConfig config, DataFlow::PathNode mid1, DataFlow2::PathNode mid2,
FromDataDictToSink config2
|
config.hasFlowPath(source.asNode1(), mid1) and
config2.hasFlowPath(mid2, sink.asNode2()) and
mid1.getNode().asCfgNode() = mid2.getNode().asCfgNode()
)
}

View File

@@ -93,7 +93,7 @@
private import InlineExpectationsTestPrivate
/**
* Base class for tests with inline expectations. The test extends this class to provide the actual
* The base class for tests with inline expectations. The test extends this class to provide the actual
* results of the query, which are then compared with the expected results in comments to produce a
* list of failure messages that point out where the actual results differ from the expected
* results.
@@ -123,6 +123,15 @@ abstract class InlineExpectationsTest extends string {
*/
abstract predicate hasActualResult(Location location, string element, string tag, string value);
/**
* Like `hasActualResult`, but returns results that do not require a matching annotation.
* A failure will still arise if there is an annotation that does not match any results, but not vice versa.
* Override this predicate to specify optional results.
*/
predicate hasOptionalResult(Location location, string element, string tag, string value) {
none()
}
final predicate hasFailureMessage(FailureLocatable element, string message) {
exists(ActualResult actualResult |
actualResult.getTest() = this and
@@ -134,7 +143,8 @@ abstract class InlineExpectationsTest extends string {
)
or
not exists(ValidExpectation expectation | expectation.matchesActualResult(actualResult)) and
message = "Unexpected result: " + actualResult.getExpectationText()
message = "Unexpected result: " + actualResult.getExpectationText() and
not actualResult.isOptional()
)
)
or
@@ -243,9 +253,13 @@ private string expectationPattern() {
private newtype TFailureLocatable =
TActualResult(
InlineExpectationsTest test, Location location, string element, string tag, string value
InlineExpectationsTest test, Location location, string element, string tag, string value,
boolean optional
) {
test.hasActualResult(location, element, tag, value)
test.hasActualResult(location, element, tag, value) and
optional = false
or
test.hasOptionalResult(location, element, tag, value) and optional = true
} or
TValidExpectation(ExpectationComment comment, string tag, string value, string knownFailure) {
exists(TColumn column, string tags |
@@ -277,8 +291,9 @@ class ActualResult extends FailureLocatable, TActualResult {
string element;
string tag;
string value;
boolean optional;
ActualResult() { this = TActualResult(test, location, element, tag, value) }
ActualResult() { this = TActualResult(test, location, element, tag, value, optional) }
override string toString() { result = element }
@@ -289,6 +304,8 @@ class ActualResult extends FailureLocatable, TActualResult {
override string getTag() { result = tag }
override string getValue() { result = value }
predicate isOptional() { optional = true }
}
abstract private class Expectation extends FailureLocatable {

View File

@@ -1,123 +1,76 @@
edges
| flask_mongoengine_bad.py:19:21:19:27 | ControlFlowNode for request | flask_mongoengine_bad.py:19:21:19:32 | ControlFlowNode for Attribute |
| flask_mongoengine_bad.py:19:21:19:32 | ControlFlowNode for Attribute | flask_mongoengine_bad.py:19:21:19:42 | ControlFlowNode for Subscript |
| flask_mongoengine_bad.py:19:21:19:42 | ControlFlowNode for Subscript | flask_mongoengine_bad.py:20:19:20:43 | ControlFlowNode for Attribute() |
| flask_mongoengine_bad.py:20:19:20:43 | ControlFlowNode for Attribute() | flask_mongoengine_bad.py:22:34:22:44 | ControlFlowNode for json_search |
| flask_mongoengine_bad.py:19:21:19:42 | ControlFlowNode for Subscript | flask_mongoengine_bad.py:22:34:22:44 | ControlFlowNode for json_search |
| flask_mongoengine_bad.py:26:21:26:27 | ControlFlowNode for request | flask_mongoengine_bad.py:26:21:26:32 | ControlFlowNode for Attribute |
| flask_mongoengine_bad.py:26:21:26:32 | ControlFlowNode for Attribute | flask_mongoengine_bad.py:26:21:26:42 | ControlFlowNode for Subscript |
| flask_mongoengine_bad.py:26:21:26:42 | ControlFlowNode for Subscript | flask_mongoengine_bad.py:27:19:27:43 | ControlFlowNode for Attribute() |
| flask_mongoengine_bad.py:27:19:27:43 | ControlFlowNode for Attribute() | flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict |
| flask_mongoengine_good.py:20:21:20:27 | ControlFlowNode for request | flask_mongoengine_good.py:20:21:20:32 | ControlFlowNode for Attribute |
| flask_mongoengine_good.py:20:21:20:32 | ControlFlowNode for Attribute | flask_mongoengine_good.py:20:21:20:42 | ControlFlowNode for Subscript |
| flask_mongoengine_good.py:20:21:20:42 | ControlFlowNode for Subscript | flask_mongoengine_good.py:21:19:21:43 | ControlFlowNode for Attribute() |
| flask_mongoengine_bad.py:26:21:26:42 | ControlFlowNode for Subscript | flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict |
| flask_pymongo_bad.py:11:21:11:27 | ControlFlowNode for request | flask_pymongo_bad.py:11:21:11:32 | ControlFlowNode for Attribute |
| flask_pymongo_bad.py:11:21:11:32 | ControlFlowNode for Attribute | flask_pymongo_bad.py:11:21:11:42 | ControlFlowNode for Subscript |
| flask_pymongo_bad.py:11:21:11:42 | ControlFlowNode for Subscript | flask_pymongo_bad.py:12:19:12:43 | ControlFlowNode for Attribute() |
| flask_pymongo_bad.py:12:19:12:43 | ControlFlowNode for Attribute() | flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict |
| flask_pymongo_good.py:12:21:12:27 | ControlFlowNode for request | flask_pymongo_good.py:12:21:12:32 | ControlFlowNode for Attribute |
| flask_pymongo_good.py:12:21:12:32 | ControlFlowNode for Attribute | flask_pymongo_good.py:12:21:12:42 | ControlFlowNode for Subscript |
| flask_pymongo_good.py:12:21:12:42 | ControlFlowNode for Subscript | flask_pymongo_good.py:13:19:13:43 | ControlFlowNode for Attribute() |
| flask_pymongo_bad.py:11:21:11:42 | ControlFlowNode for Subscript | flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict |
| mongoengine_bad.py:18:21:18:27 | ControlFlowNode for request | mongoengine_bad.py:18:21:18:32 | ControlFlowNode for Attribute |
| mongoengine_bad.py:18:21:18:32 | ControlFlowNode for Attribute | mongoengine_bad.py:18:21:18:42 | ControlFlowNode for Subscript |
| mongoengine_bad.py:18:21:18:42 | ControlFlowNode for Subscript | mongoengine_bad.py:19:19:19:43 | ControlFlowNode for Attribute() |
| mongoengine_bad.py:19:19:19:43 | ControlFlowNode for Attribute() | mongoengine_bad.py:22:26:22:46 | ControlFlowNode for Dict |
| mongoengine_bad.py:18:21:18:42 | ControlFlowNode for Subscript | mongoengine_bad.py:22:26:22:46 | ControlFlowNode for Dict |
| mongoengine_bad.py:26:21:26:27 | ControlFlowNode for request | mongoengine_bad.py:26:21:26:32 | ControlFlowNode for Attribute |
| mongoengine_bad.py:26:21:26:32 | ControlFlowNode for Attribute | mongoengine_bad.py:26:21:26:42 | ControlFlowNode for Subscript |
| mongoengine_bad.py:26:21:26:42 | ControlFlowNode for Subscript | mongoengine_bad.py:27:19:27:43 | ControlFlowNode for Attribute() |
| mongoengine_bad.py:27:19:27:43 | ControlFlowNode for Attribute() | mongoengine_bad.py:30:26:30:46 | ControlFlowNode for Dict |
| mongoengine_bad.py:26:21:26:42 | ControlFlowNode for Subscript | mongoengine_bad.py:30:26:30:46 | ControlFlowNode for Dict |
| mongoengine_bad.py:34:21:34:27 | ControlFlowNode for request | mongoengine_bad.py:34:21:34:32 | ControlFlowNode for Attribute |
| mongoengine_bad.py:34:21:34:32 | ControlFlowNode for Attribute | mongoengine_bad.py:34:21:34:42 | ControlFlowNode for Subscript |
| mongoengine_bad.py:34:21:34:42 | ControlFlowNode for Subscript | mongoengine_bad.py:35:19:35:43 | ControlFlowNode for Attribute() |
| mongoengine_bad.py:35:19:35:43 | ControlFlowNode for Attribute() | mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict |
| mongoengine_bad.py:34:21:34:42 | ControlFlowNode for Subscript | mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict |
| mongoengine_bad.py:42:21:42:27 | ControlFlowNode for request | mongoengine_bad.py:42:21:42:32 | ControlFlowNode for Attribute |
| mongoengine_bad.py:42:21:42:32 | ControlFlowNode for Attribute | mongoengine_bad.py:42:21:42:42 | ControlFlowNode for Subscript |
| mongoengine_bad.py:42:21:42:42 | ControlFlowNode for Subscript | mongoengine_bad.py:43:19:43:43 | ControlFlowNode for Attribute() |
| mongoengine_bad.py:43:19:43:43 | ControlFlowNode for Attribute() | mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict |
| mongoengine_bad.py:42:21:42:42 | ControlFlowNode for Subscript | mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict |
| mongoengine_bad.py:50:21:50:27 | ControlFlowNode for request | mongoengine_bad.py:50:21:50:32 | ControlFlowNode for Attribute |
| mongoengine_bad.py:50:21:50:32 | ControlFlowNode for Attribute | mongoengine_bad.py:50:21:50:42 | ControlFlowNode for Subscript |
| mongoengine_bad.py:50:21:50:42 | ControlFlowNode for Subscript | mongoengine_bad.py:51:19:51:43 | ControlFlowNode for Attribute() |
| mongoengine_bad.py:51:19:51:43 | ControlFlowNode for Attribute() | mongoengine_bad.py:53:34:53:44 | ControlFlowNode for json_search |
| mongoengine_bad.py:50:21:50:42 | ControlFlowNode for Subscript | mongoengine_bad.py:53:34:53:44 | ControlFlowNode for json_search |
| mongoengine_bad.py:57:21:57:27 | ControlFlowNode for request | mongoengine_bad.py:57:21:57:32 | ControlFlowNode for Attribute |
| mongoengine_bad.py:57:21:57:32 | ControlFlowNode for Attribute | mongoengine_bad.py:57:21:57:42 | ControlFlowNode for Subscript |
| mongoengine_bad.py:57:21:57:42 | ControlFlowNode for Subscript | mongoengine_bad.py:58:19:58:43 | ControlFlowNode for Attribute() |
| mongoengine_bad.py:58:19:58:43 | ControlFlowNode for Attribute() | mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict |
| mongoengine_good.py:19:21:19:27 | ControlFlowNode for request | mongoengine_good.py:19:21:19:32 | ControlFlowNode for Attribute |
| mongoengine_good.py:19:21:19:32 | ControlFlowNode for Attribute | mongoengine_good.py:19:21:19:42 | ControlFlowNode for Subscript |
| mongoengine_good.py:19:21:19:42 | ControlFlowNode for Subscript | mongoengine_good.py:20:19:20:43 | ControlFlowNode for Attribute() |
| mongoengine_bad.py:57:21:57:42 | ControlFlowNode for Subscript | mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict |
| pymongo_bad.py:11:21:11:27 | ControlFlowNode for request | pymongo_bad.py:11:21:11:32 | ControlFlowNode for Attribute |
| pymongo_bad.py:11:21:11:32 | ControlFlowNode for Attribute | pymongo_bad.py:11:21:11:42 | ControlFlowNode for Subscript |
| pymongo_bad.py:11:21:11:42 | ControlFlowNode for Subscript | pymongo_bad.py:12:19:12:43 | ControlFlowNode for Attribute() |
| pymongo_bad.py:12:19:12:43 | ControlFlowNode for Attribute() | pymongo_bad.py:14:42:14:62 | ControlFlowNode for Dict |
| pymongo_good.py:12:21:12:27 | ControlFlowNode for request | pymongo_good.py:12:21:12:32 | ControlFlowNode for Attribute |
| pymongo_good.py:12:21:12:32 | ControlFlowNode for Attribute | pymongo_good.py:12:21:12:42 | ControlFlowNode for Subscript |
| pymongo_good.py:12:21:12:42 | ControlFlowNode for Subscript | pymongo_good.py:13:19:13:43 | ControlFlowNode for Attribute() |
| pymongo_bad.py:11:21:11:42 | ControlFlowNode for Subscript | pymongo_bad.py:14:42:14:62 | ControlFlowNode for Dict |
nodes
| flask_mongoengine_bad.py:19:21:19:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| flask_mongoengine_bad.py:19:21:19:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| flask_mongoengine_bad.py:19:21:19:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| flask_mongoengine_bad.py:20:19:20:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| flask_mongoengine_bad.py:22:34:22:44 | ControlFlowNode for json_search | semmle.label | ControlFlowNode for json_search |
| flask_mongoengine_bad.py:26:21:26:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| flask_mongoengine_bad.py:26:21:26:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| flask_mongoengine_bad.py:26:21:26:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| flask_mongoengine_bad.py:27:19:27:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict |
| flask_mongoengine_good.py:20:21:20:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| flask_mongoengine_good.py:20:21:20:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| flask_mongoengine_good.py:20:21:20:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| flask_mongoengine_good.py:21:19:21:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| flask_pymongo_bad.py:11:21:11:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| flask_pymongo_bad.py:11:21:11:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| flask_pymongo_bad.py:11:21:11:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| flask_pymongo_bad.py:12:19:12:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| flask_pymongo_bad.py:14:31:14:51 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict |
| flask_pymongo_good.py:12:21:12:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| flask_pymongo_good.py:12:21:12:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| flask_pymongo_good.py:12:21:12:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| flask_pymongo_good.py:13:19:13:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| mongoengine_bad.py:18:21:18:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| mongoengine_bad.py:18:21:18:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| mongoengine_bad.py:18:21:18:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| mongoengine_bad.py:19:19:19:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| mongoengine_bad.py:22:26:22:46 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict |
| mongoengine_bad.py:26:21:26:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| mongoengine_bad.py:26:21:26:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| mongoengine_bad.py:26:21:26:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| mongoengine_bad.py:27:19:27:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| mongoengine_bad.py:30:26:30:46 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict |
| mongoengine_bad.py:34:21:34:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| mongoengine_bad.py:34:21:34:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| mongoengine_bad.py:34:21:34:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| mongoengine_bad.py:35:19:35:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| mongoengine_bad.py:38:26:38:46 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict |
| mongoengine_bad.py:42:21:42:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| mongoengine_bad.py:42:21:42:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| mongoengine_bad.py:42:21:42:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| mongoengine_bad.py:43:19:43:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| mongoengine_bad.py:46:26:46:46 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict |
| mongoengine_bad.py:50:21:50:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| mongoengine_bad.py:50:21:50:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| mongoengine_bad.py:50:21:50:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| mongoengine_bad.py:51:19:51:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| mongoengine_bad.py:53:34:53:44 | ControlFlowNode for json_search | semmle.label | ControlFlowNode for json_search |
| mongoengine_bad.py:57:21:57:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| mongoengine_bad.py:57:21:57:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| mongoengine_bad.py:57:21:57:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| mongoengine_bad.py:58:19:58:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| mongoengine_bad.py:61:29:61:49 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict |
| mongoengine_good.py:19:21:19:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| mongoengine_good.py:19:21:19:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| mongoengine_good.py:19:21:19:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| mongoengine_good.py:20:19:20:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| pymongo_bad.py:11:21:11:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| pymongo_bad.py:11:21:11:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| pymongo_bad.py:11:21:11:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| pymongo_bad.py:12:19:12:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| pymongo_bad.py:14:42:14:62 | ControlFlowNode for Dict | semmle.label | ControlFlowNode for Dict |
| pymongo_good.py:12:21:12:27 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| pymongo_good.py:12:21:12:32 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| pymongo_good.py:12:21:12:42 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript |
| pymongo_good.py:13:19:13:43 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
subpaths
#select
| flask_mongoengine_bad.py:22:34:22:44 | ControlFlowNode for json_search | flask_mongoengine_bad.py:19:21:19:27 | ControlFlowNode for request | flask_mongoengine_bad.py:22:34:22:44 | ControlFlowNode for json_search | $@ NoSQL query contains an unsanitized $@ | flask_mongoengine_bad.py:22:34:22:44 | ControlFlowNode for json_search | This | flask_mongoengine_bad.py:19:21:19:27 | ControlFlowNode for request | user-provided value |
| flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict | flask_mongoengine_bad.py:26:21:26:27 | ControlFlowNode for request | flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict | $@ NoSQL query contains an unsanitized $@ | flask_mongoengine_bad.py:30:39:30:59 | ControlFlowNode for Dict | This | flask_mongoengine_bad.py:26:21:26:27 | ControlFlowNode for request | user-provided value |

View File

@@ -1,92 +1,134 @@
edges
| flask_path_injection.py:19:15:19:21 | ControlFlowNode for request | flask_path_injection.py:19:15:19:26 | ControlFlowNode for Attribute |
| flask_path_injection.py:19:15:19:21 | ControlFlowNode for request | flask_path_injection.py:19:15:19:26 | ControlFlowNode for Attribute |
| flask_path_injection.py:19:15:19:26 | ControlFlowNode for Attribute | flask_path_injection.py:21:32:21:38 | ControlFlowNode for dirname |
| flask_path_injection.py:19:15:19:26 | ControlFlowNode for Attribute | flask_path_injection.py:21:32:21:38 | ControlFlowNode for dirname |
| path_injection.py:12:16:12:22 | ControlFlowNode for request | path_injection.py:12:16:12:27 | ControlFlowNode for Attribute |
| path_injection.py:12:16:12:22 | ControlFlowNode for request | path_injection.py:12:16:12:27 | ControlFlowNode for Attribute |
| path_injection.py:12:16:12:27 | ControlFlowNode for Attribute | path_injection.py:13:14:13:47 | ControlFlowNode for Attribute() |
| path_injection.py:12:16:12:27 | ControlFlowNode for Attribute | path_injection.py:13:14:13:47 | ControlFlowNode for Attribute() |
| path_injection.py:19:16:19:22 | ControlFlowNode for request | path_injection.py:19:16:19:27 | ControlFlowNode for Attribute |
| path_injection.py:19:16:19:22 | ControlFlowNode for request | path_injection.py:19:16:19:27 | ControlFlowNode for Attribute |
| path_injection.py:19:16:19:27 | ControlFlowNode for Attribute | path_injection.py:20:13:20:64 | ControlFlowNode for Attribute() |
| path_injection.py:20:13:20:64 | ControlFlowNode for Attribute() | path_injection.py:21:14:21:18 | ControlFlowNode for npath |
| path_injection.py:19:16:19:27 | ControlFlowNode for Attribute | path_injection.py:21:14:21:18 | ControlFlowNode for npath |
| path_injection.py:27:16:27:22 | ControlFlowNode for request | path_injection.py:27:16:27:27 | ControlFlowNode for Attribute |
| path_injection.py:27:16:27:22 | ControlFlowNode for request | path_injection.py:27:16:27:27 | ControlFlowNode for Attribute |
| path_injection.py:27:16:27:27 | ControlFlowNode for Attribute | path_injection.py:28:13:28:64 | ControlFlowNode for Attribute() |
| path_injection.py:28:13:28:64 | ControlFlowNode for Attribute() | path_injection.py:31:14:31:18 | ControlFlowNode for npath |
| path_injection.py:27:16:27:27 | ControlFlowNode for Attribute | path_injection.py:31:14:31:18 | ControlFlowNode for npath |
| path_injection.py:37:16:37:22 | ControlFlowNode for request | path_injection.py:37:16:37:27 | ControlFlowNode for Attribute |
| path_injection.py:37:16:37:27 | ControlFlowNode for Attribute | path_injection.py:38:13:38:64 | ControlFlowNode for Attribute() |
| path_injection.py:46:16:46:22 | ControlFlowNode for request | path_injection.py:46:16:46:27 | ControlFlowNode for Attribute |
| path_injection.py:46:16:46:22 | ControlFlowNode for request | path_injection.py:46:16:46:27 | ControlFlowNode for Attribute |
| path_injection.py:46:16:46:27 | ControlFlowNode for Attribute | path_injection.py:47:13:47:64 | ControlFlowNode for Attribute() |
| path_injection.py:47:13:47:64 | ControlFlowNode for Attribute() | path_injection.py:48:14:48:18 | ControlFlowNode for npath |
| path_injection.py:46:16:46:27 | ControlFlowNode for Attribute | path_injection.py:48:14:48:18 | ControlFlowNode for npath |
| path_injection.py:54:16:54:22 | ControlFlowNode for request | path_injection.py:54:16:54:27 | ControlFlowNode for Attribute |
| path_injection.py:54:16:54:27 | ControlFlowNode for Attribute | path_injection.py:55:13:55:64 | ControlFlowNode for Attribute() |
| path_injection.py:63:16:63:22 | ControlFlowNode for request | path_injection.py:63:16:63:27 | ControlFlowNode for Attribute |
| path_injection.py:63:16:63:22 | ControlFlowNode for request | path_injection.py:63:16:63:27 | ControlFlowNode for Attribute |
| path_injection.py:63:16:63:27 | ControlFlowNode for Attribute | path_injection.py:64:13:64:63 | ControlFlowNode for Attribute() |
| path_injection.py:64:13:64:63 | ControlFlowNode for Attribute() | path_injection.py:65:14:65:18 | ControlFlowNode for npath |
| path_injection.py:63:16:63:27 | ControlFlowNode for Attribute | path_injection.py:65:14:65:18 | ControlFlowNode for npath |
| path_injection.py:71:16:71:22 | ControlFlowNode for request | path_injection.py:71:16:71:27 | ControlFlowNode for Attribute |
| path_injection.py:71:16:71:27 | ControlFlowNode for Attribute | path_injection.py:72:13:72:63 | ControlFlowNode for Attribute() |
| path_injection.py:84:16:84:22 | ControlFlowNode for request | path_injection.py:84:16:84:27 | ControlFlowNode for Attribute |
| path_injection.py:84:16:84:22 | ControlFlowNode for request | path_injection.py:84:16:84:27 | ControlFlowNode for Attribute |
| path_injection.py:84:16:84:22 | ControlFlowNode for request | path_injection.py:84:16:84:27 | ControlFlowNode for Attribute |
| path_injection.py:84:16:84:27 | ControlFlowNode for Attribute | path_injection.py:86:8:86:44 | ControlFlowNode for Attribute() |
| path_injection.py:84:16:84:27 | ControlFlowNode for Attribute | path_injection.py:87:18:87:37 | ControlFlowNode for possibly_unsafe_path |
| path_injection.py:84:16:84:27 | ControlFlowNode for Attribute | path_injection.py:87:18:87:37 | ControlFlowNode for possibly_unsafe_path |
| path_injection.py:91:20:91:25 | ControlFlowNode for foo_id | path_injection.py:94:14:94:17 | ControlFlowNode for path |
| path_injection.py:91:20:91:25 | ControlFlowNode for foo_id | path_injection.py:94:14:94:17 | ControlFlowNode for path |
| path_injection.py:98:20:98:22 | ControlFlowNode for foo | path_injection.py:102:14:102:17 | ControlFlowNode for path |
| path_injection.py:98:20:98:22 | ControlFlowNode for foo | path_injection.py:102:14:102:17 | ControlFlowNode for path |
| path_injection.py:107:16:107:22 | ControlFlowNode for request | path_injection.py:107:16:107:27 | ControlFlowNode for Attribute |
| path_injection.py:107:16:107:22 | ControlFlowNode for request | path_injection.py:107:16:107:27 | ControlFlowNode for Attribute |
| path_injection.py:107:16:107:27 | ControlFlowNode for Attribute | path_injection.py:113:14:113:17 | ControlFlowNode for path |
| path_injection.py:107:16:107:27 | ControlFlowNode for Attribute | path_injection.py:113:14:113:17 | ControlFlowNode for path |
| path_injection.py:118:16:118:22 | ControlFlowNode for request | path_injection.py:118:16:118:27 | ControlFlowNode for Attribute |
| path_injection.py:118:16:118:22 | ControlFlowNode for request | path_injection.py:118:16:118:27 | ControlFlowNode for Attribute |
| path_injection.py:118:16:118:27 | ControlFlowNode for Attribute | path_injection.py:124:14:124:17 | ControlFlowNode for path |
| path_injection.py:118:16:118:27 | ControlFlowNode for Attribute | path_injection.py:124:14:124:17 | ControlFlowNode for path |
| path_injection.py:129:16:129:22 | ControlFlowNode for request | path_injection.py:129:16:129:27 | ControlFlowNode for Attribute |
| path_injection.py:129:16:129:22 | ControlFlowNode for request | path_injection.py:129:16:129:27 | ControlFlowNode for Attribute |
| path_injection.py:129:16:129:27 | ControlFlowNode for Attribute | path_injection.py:132:14:132:22 | ControlFlowNode for sanitized |
| path_injection.py:129:16:129:27 | ControlFlowNode for Attribute | path_injection.py:132:14:132:22 | ControlFlowNode for sanitized |
| path_injection.py:138:16:138:22 | ControlFlowNode for request | path_injection.py:138:16:138:27 | ControlFlowNode for Attribute |
| path_injection.py:138:16:138:22 | ControlFlowNode for request | path_injection.py:138:16:138:27 | ControlFlowNode for Attribute |
| path_injection.py:138:16:138:22 | ControlFlowNode for request | path_injection.py:138:16:138:27 | ControlFlowNode for Attribute |
| path_injection.py:138:16:138:27 | ControlFlowNode for Attribute | path_injection.py:140:30:140:51 | ControlFlowNode for Attribute() |
| path_injection.py:138:16:138:27 | ControlFlowNode for Attribute | path_injection.py:142:14:142:17 | ControlFlowNode for path |
| path_injection.py:138:16:138:27 | ControlFlowNode for Attribute | path_injection.py:142:14:142:17 | ControlFlowNode for path |
| path_injection.py:149:16:149:22 | ControlFlowNode for request | path_injection.py:149:16:149:27 | ControlFlowNode for Attribute |
| path_injection.py:149:16:149:22 | ControlFlowNode for request | path_injection.py:149:16:149:27 | ControlFlowNode for Attribute |
| path_injection.py:149:16:149:27 | ControlFlowNode for Attribute | path_injection.py:152:18:152:21 | ControlFlowNode for path |
| path_injection.py:149:16:149:27 | ControlFlowNode for Attribute | path_injection.py:152:18:152:21 | ControlFlowNode for path |
| test.py:9:12:9:18 | ControlFlowNode for request | test.py:9:12:9:23 | ControlFlowNode for Attribute |
| test.py:9:12:9:18 | ControlFlowNode for request | test.py:9:12:9:23 | ControlFlowNode for Attribute |
| test.py:9:12:9:18 | ControlFlowNode for request | test.py:9:12:9:23 | ControlFlowNode for Attribute |
| test.py:9:12:9:23 | ControlFlowNode for Attribute | test.py:9:12:9:39 | ControlFlowNode for Attribute() |
| test.py:9:12:9:23 | ControlFlowNode for Attribute | test.py:9:12:9:39 | ControlFlowNode for Attribute() |
| test.py:9:12:9:23 | ControlFlowNode for Attribute | test.py:9:12:9:39 | ControlFlowNode for Attribute() |
| test.py:9:12:9:39 | ControlFlowNode for Attribute() | test.py:18:9:18:16 | ControlFlowNode for source() |
| test.py:9:12:9:39 | ControlFlowNode for Attribute() | test.py:18:9:18:16 | ControlFlowNode for source() |
| test.py:9:12:9:39 | ControlFlowNode for Attribute() | test.py:24:9:24:16 | ControlFlowNode for source() |
| test.py:9:12:9:39 | ControlFlowNode for Attribute() | test.py:24:9:24:16 | ControlFlowNode for source() |
| test.py:9:12:9:39 | ControlFlowNode for Attribute() | test.py:31:9:31:16 | ControlFlowNode for source() |
| test.py:9:12:9:39 | ControlFlowNode for Attribute() | test.py:31:9:31:16 | ControlFlowNode for source() |
| test.py:9:12:9:39 | ControlFlowNode for Attribute() | test.py:38:9:38:16 | ControlFlowNode for source() |
| test.py:9:12:9:39 | ControlFlowNode for Attribute() | test.py:46:9:46:16 | ControlFlowNode for source() |
| test.py:9:12:9:39 | ControlFlowNode for Attribute() | test.py:46:9:46:16 | ControlFlowNode for source() |
| test.py:12:15:12:15 | ControlFlowNode for x | test.py:13:12:13:30 | ControlFlowNode for Attribute() |
| test.py:12:15:12:15 | ControlFlowNode for x | test.py:13:12:13:30 | ControlFlowNode for Attribute() |
| test.py:13:12:13:30 | ControlFlowNode for Attribute() | test.py:25:9:25:20 | ControlFlowNode for normalize() |
| test.py:13:12:13:30 | ControlFlowNode for Attribute() | test.py:48:13:48:24 | ControlFlowNode for normalize() |
| test.py:18:9:18:16 | ControlFlowNode for source() | test.py:19:10:19:10 | ControlFlowNode for x |
| test.py:18:9:18:16 | ControlFlowNode for source() | test.py:19:10:19:10 | ControlFlowNode for x |
| test.py:24:9:24:16 | ControlFlowNode for source() | test.py:25:19:25:19 | ControlFlowNode for x |
| test.py:24:9:24:16 | ControlFlowNode for source() | test.py:25:19:25:19 | ControlFlowNode for x |
| test.py:25:9:25:20 | ControlFlowNode for normalize() | test.py:26:10:26:10 | ControlFlowNode for y |
| test.py:25:19:25:19 | ControlFlowNode for x | test.py:12:15:12:15 | ControlFlowNode for x |
| test.py:25:19:25:19 | ControlFlowNode for x | test.py:12:15:12:15 | ControlFlowNode for x |
| test.py:25:19:25:19 | ControlFlowNode for x | test.py:25:9:25:20 | ControlFlowNode for normalize() |
| test.py:31:9:31:16 | ControlFlowNode for source() | test.py:33:14:33:14 | ControlFlowNode for x |
| test.py:31:9:31:16 | ControlFlowNode for source() | test.py:33:14:33:14 | ControlFlowNode for x |
| test.py:38:9:38:16 | ControlFlowNode for source() | test.py:39:19:39:19 | ControlFlowNode for x |
| test.py:39:19:39:19 | ControlFlowNode for x | test.py:12:15:12:15 | ControlFlowNode for x |
| test.py:46:9:46:16 | ControlFlowNode for source() | test.py:48:23:48:23 | ControlFlowNode for x |
| test.py:46:9:46:16 | ControlFlowNode for source() | test.py:48:23:48:23 | ControlFlowNode for x |
| test.py:48:13:48:24 | ControlFlowNode for normalize() | test.py:49:14:49:14 | ControlFlowNode for y |
| test.py:48:23:48:23 | ControlFlowNode for x | test.py:12:15:12:15 | ControlFlowNode for x |
| test.py:48:23:48:23 | ControlFlowNode for x | test.py:12:15:12:15 | ControlFlowNode for x |
| test.py:48:23:48:23 | ControlFlowNode for x | test.py:48:13:48:24 | ControlFlowNode for normalize() |
| test_chaining.py:9:12:9:18 | ControlFlowNode for request | test_chaining.py:9:12:9:23 | ControlFlowNode for Attribute |
| test_chaining.py:9:12:9:23 | ControlFlowNode for Attribute | test_chaining.py:9:12:9:39 | ControlFlowNode for Attribute() |
| test_chaining.py:9:12:9:39 | ControlFlowNode for Attribute() | test_chaining.py:20:9:20:16 | ControlFlowNode for source() |
| test_chaining.py:9:12:9:39 | ControlFlowNode for Attribute() | test_chaining.py:28:9:28:16 | ControlFlowNode for source() |
| test_chaining.py:9:12:9:39 | ControlFlowNode for Attribute() | test_chaining.py:41:9:41:16 | ControlFlowNode for source() |
| test_chaining.py:14:15:14:15 | ControlFlowNode for x | test_chaining.py:15:12:15:30 | ControlFlowNode for Attribute() |
| test_chaining.py:15:12:15:30 | ControlFlowNode for Attribute() | test_chaining.py:31:13:31:24 | ControlFlowNode for normalize() |
| test_chaining.py:20:9:20:16 | ControlFlowNode for source() | test_chaining.py:21:19:21:19 | ControlFlowNode for x |
| test_chaining.py:21:19:21:19 | ControlFlowNode for x | test_chaining.py:14:15:14:15 | ControlFlowNode for x |
| test_chaining.py:28:9:28:16 | ControlFlowNode for source() | test_chaining.py:29:19:29:19 | ControlFlowNode for x |
| test_chaining.py:29:19:29:19 | ControlFlowNode for x | test_chaining.py:14:15:14:15 | ControlFlowNode for x |
| test_chaining.py:31:13:31:24 | ControlFlowNode for normalize() | test_chaining.py:32:14:32:14 | ControlFlowNode for z |
| test_chaining.py:41:9:41:16 | ControlFlowNode for source() | test_chaining.py:42:9:42:19 | ControlFlowNode for normpath() |
| test_chaining.py:44:13:44:23 | ControlFlowNode for normpath() | test_chaining.py:45:14:45:14 | ControlFlowNode for z |
nodes
| flask_path_injection.py:19:15:19:21 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| flask_path_injection.py:19:15:19:21 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| flask_path_injection.py:19:15:19:26 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| flask_path_injection.py:19:15:19:26 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| flask_path_injection.py:21:32:21:38 | ControlFlowNode for dirname | semmle.label | ControlFlowNode for dirname |
| flask_path_injection.py:21:32:21:38 | ControlFlowNode for dirname | semmle.label | ControlFlowNode for dirname |
| path_injection.py:12:16:12:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| path_injection.py:12:16:12:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| path_injection.py:12:16:12:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| path_injection.py:12:16:12:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| path_injection.py:13:14:13:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| path_injection.py:13:14:13:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| path_injection.py:19:16:19:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| path_injection.py:19:16:19:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| path_injection.py:19:16:19:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| path_injection.py:19:16:19:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| path_injection.py:20:13:20:64 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| path_injection.py:21:14:21:18 | ControlFlowNode for npath | semmle.label | ControlFlowNode for npath |
| path_injection.py:27:16:27:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| path_injection.py:27:16:27:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| path_injection.py:27:16:27:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| path_injection.py:27:16:27:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| path_injection.py:28:13:28:64 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| path_injection.py:31:14:31:18 | ControlFlowNode for npath | semmle.label | ControlFlowNode for npath |
@@ -94,6 +136,8 @@ nodes
| path_injection.py:37:16:37:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| path_injection.py:38:13:38:64 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| path_injection.py:46:16:46:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| path_injection.py:46:16:46:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| path_injection.py:46:16:46:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| path_injection.py:46:16:46:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| path_injection.py:47:13:47:64 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| path_injection.py:48:14:48:18 | ControlFlowNode for npath | semmle.label | ControlFlowNode for npath |
@@ -101,6 +145,8 @@ nodes
| path_injection.py:54:16:54:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| path_injection.py:55:13:55:64 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| path_injection.py:63:16:63:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| path_injection.py:63:16:63:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| path_injection.py:63:16:63:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| path_injection.py:63:16:63:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| path_injection.py:64:13:64:63 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| path_injection.py:65:14:65:18 | ControlFlowNode for npath | semmle.label | ControlFlowNode for npath |
@@ -109,53 +155,88 @@ nodes
| path_injection.py:72:13:72:63 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| path_injection.py:84:16:84:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| path_injection.py:84:16:84:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| path_injection.py:84:16:84:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| path_injection.py:84:16:84:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| path_injection.py:84:16:84:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| path_injection.py:84:16:84:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| path_injection.py:86:8:86:44 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| path_injection.py:87:18:87:37 | ControlFlowNode for possibly_unsafe_path | semmle.label | ControlFlowNode for possibly_unsafe_path |
| path_injection.py:87:18:87:37 | ControlFlowNode for possibly_unsafe_path | semmle.label | ControlFlowNode for possibly_unsafe_path |
| path_injection.py:91:20:91:25 | ControlFlowNode for foo_id | semmle.label | ControlFlowNode for foo_id |
| path_injection.py:91:20:91:25 | ControlFlowNode for foo_id | semmle.label | ControlFlowNode for foo_id |
| path_injection.py:94:14:94:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path |
| path_injection.py:94:14:94:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path |
| path_injection.py:98:20:98:22 | ControlFlowNode for foo | semmle.label | ControlFlowNode for foo |
| path_injection.py:98:20:98:22 | ControlFlowNode for foo | semmle.label | ControlFlowNode for foo |
| path_injection.py:102:14:102:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path |
| path_injection.py:102:14:102:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path |
| path_injection.py:107:16:107:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| path_injection.py:107:16:107:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| path_injection.py:107:16:107:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| path_injection.py:107:16:107:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| path_injection.py:113:14:113:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path |
| path_injection.py:113:14:113:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path |
| path_injection.py:118:16:118:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| path_injection.py:118:16:118:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| path_injection.py:118:16:118:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| path_injection.py:118:16:118:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| path_injection.py:124:14:124:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path |
| path_injection.py:124:14:124:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path |
| path_injection.py:129:16:129:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| path_injection.py:129:16:129:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| path_injection.py:129:16:129:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| path_injection.py:129:16:129:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| path_injection.py:132:14:132:22 | ControlFlowNode for sanitized | semmle.label | ControlFlowNode for sanitized |
| path_injection.py:132:14:132:22 | ControlFlowNode for sanitized | semmle.label | ControlFlowNode for sanitized |
| path_injection.py:138:16:138:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| path_injection.py:138:16:138:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| path_injection.py:138:16:138:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| path_injection.py:138:16:138:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| path_injection.py:138:16:138:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| path_injection.py:138:16:138:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| path_injection.py:140:30:140:51 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| path_injection.py:142:14:142:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path |
| path_injection.py:142:14:142:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path |
| path_injection.py:149:16:149:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| path_injection.py:149:16:149:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| path_injection.py:149:16:149:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| path_injection.py:149:16:149:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| path_injection.py:152:18:152:21 | ControlFlowNode for path | semmle.label | ControlFlowNode for path |
| path_injection.py:152:18:152:21 | ControlFlowNode for path | semmle.label | ControlFlowNode for path |
| test.py:9:12:9:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| test.py:9:12:9:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| test.py:9:12:9:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| test.py:9:12:9:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| test.py:9:12:9:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| test.py:9:12:9:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
| test.py:9:12:9:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| test.py:9:12:9:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| test.py:9:12:9:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| test.py:12:15:12:15 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:12:15:12:15 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:13:12:13:30 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| test.py:13:12:13:30 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| test.py:18:9:18:16 | ControlFlowNode for source() | semmle.label | ControlFlowNode for source() |
| test.py:18:9:18:16 | ControlFlowNode for source() | semmle.label | ControlFlowNode for source() |
| test.py:19:10:19:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:19:10:19:10 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:24:9:24:16 | ControlFlowNode for source() | semmle.label | ControlFlowNode for source() |
| test.py:24:9:24:16 | ControlFlowNode for source() | semmle.label | ControlFlowNode for source() |
| test.py:25:9:25:20 | ControlFlowNode for normalize() | semmle.label | ControlFlowNode for normalize() |
| test.py:25:19:25:19 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:25:19:25:19 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:26:10:26:10 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
| test.py:31:9:31:16 | ControlFlowNode for source() | semmle.label | ControlFlowNode for source() |
| test.py:31:9:31:16 | ControlFlowNode for source() | semmle.label | ControlFlowNode for source() |
| test.py:33:14:33:14 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:33:14:33:14 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:38:9:38:16 | ControlFlowNode for source() | semmle.label | ControlFlowNode for source() |
| test.py:39:19:39:19 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:46:9:46:16 | ControlFlowNode for source() | semmle.label | ControlFlowNode for source() |
| test.py:46:9:46:16 | ControlFlowNode for source() | semmle.label | ControlFlowNode for source() |
| test.py:48:13:48:24 | ControlFlowNode for normalize() | semmle.label | ControlFlowNode for normalize() |
| test.py:48:23:48:23 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:48:23:48:23 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test.py:49:14:49:14 | ControlFlowNode for y | semmle.label | ControlFlowNode for y |
| test_chaining.py:9:12:9:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| test_chaining.py:9:12:9:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
@@ -166,12 +247,11 @@ nodes
| test_chaining.py:21:19:21:19 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test_chaining.py:28:9:28:16 | ControlFlowNode for source() | semmle.label | ControlFlowNode for source() |
| test_chaining.py:29:19:29:19 | ControlFlowNode for x | semmle.label | ControlFlowNode for x |
| test_chaining.py:31:13:31:24 | ControlFlowNode for normalize() | semmle.label | ControlFlowNode for normalize() |
| test_chaining.py:32:14:32:14 | ControlFlowNode for z | semmle.label | ControlFlowNode for z |
| test_chaining.py:41:9:41:16 | ControlFlowNode for source() | semmle.label | ControlFlowNode for source() |
| test_chaining.py:42:9:42:19 | ControlFlowNode for normpath() | semmle.label | ControlFlowNode for normpath() |
| test_chaining.py:44:13:44:23 | ControlFlowNode for normpath() | semmle.label | ControlFlowNode for normpath() |
| test_chaining.py:45:14:45:14 | ControlFlowNode for z | semmle.label | ControlFlowNode for z |
subpaths
| test.py:25:19:25:19 | ControlFlowNode for x | test.py:12:15:12:15 | ControlFlowNode for x | test.py:13:12:13:30 | ControlFlowNode for Attribute() | test.py:25:9:25:20 | ControlFlowNode for normalize() |
| test.py:48:23:48:23 | ControlFlowNode for x | test.py:12:15:12:15 | ControlFlowNode for x | test.py:13:12:13:30 | ControlFlowNode for Attribute() | test.py:48:13:48:24 | ControlFlowNode for normalize() |
#select
| flask_path_injection.py:21:32:21:38 | ControlFlowNode for dirname | flask_path_injection.py:19:15:19:21 | ControlFlowNode for request | flask_path_injection.py:21:32:21:38 | ControlFlowNode for dirname | This path depends on $@. | flask_path_injection.py:19:15:19:21 | ControlFlowNode for request | a user-provided value |
| path_injection.py:13:14:13:47 | ControlFlowNode for Attribute() | path_injection.py:12:16:12:22 | ControlFlowNode for request | path_injection.py:13:14:13:47 | ControlFlowNode for Attribute() | This path depends on $@. | path_injection.py:12:16:12:22 | ControlFlowNode for request | a user-provided value |
@@ -191,4 +271,3 @@ nodes
| test.py:26:10:26:10 | ControlFlowNode for y | test.py:9:12:9:18 | ControlFlowNode for request | test.py:26:10:26:10 | ControlFlowNode for y | This path depends on $@. | test.py:9:12:9:18 | ControlFlowNode for request | a user-provided value |
| test.py:33:14:33:14 | ControlFlowNode for x | test.py:9:12:9:18 | ControlFlowNode for request | test.py:33:14:33:14 | ControlFlowNode for x | This path depends on $@. | test.py:9:12:9:18 | ControlFlowNode for request | a user-provided value |
| test.py:49:14:49:14 | ControlFlowNode for y | test.py:9:12:9:18 | ControlFlowNode for request | test.py:49:14:49:14 | ControlFlowNode for y | This path depends on $@. | test.py:9:12:9:18 | ControlFlowNode for request | a user-provided value |
| test_chaining.py:32:14:32:14 | ControlFlowNode for z | test_chaining.py:9:12:9:18 | ControlFlowNode for request | test_chaining.py:32:14:32:14 | ControlFlowNode for z | This path depends on $@. | test_chaining.py:9:12:9:18 | ControlFlowNode for request | a user-provided value |